Skip to content

Instrument Input

Instrument Input #31

# SPDX-License-Identifier: LGPL-2.1-or-later
# SPDX-FileNotice: Part of the FreeCAD project.
#
# Update constraints files inside Data/Python/Constraints on a per Python
# version basis when the Data/Python/Allowed-Packages file is changed.
#
#
# 𝗡𝗼𝘁𝗲
# Current the CI will fail if any package is not
# available for a particular version of Python.
#
################################################################################
name : Update Constraints
################################################################################
on:
pull_request_target:
types : [ opened , synchronize , reopened ]
paths:
- 'Data/Python/*/Allowed-Packages'
- 'Data/Python/*/constraints.txt'
schedule:
- cron : '0 6 * * 1'
workflow_dispatch:
################################################################################
permissions:
pull-requests : write
contents : write
################################################################################
env:
#
# Explicitly allow-list packages that can be compiled
# from source and do not require a binary wheel.
#
# These packages will be allowed to compile from source.
#
# Native extension compilation is a code-execution vector.
#
# Compilers, linkers, and build scripts are invoked;
# a hostile setup.py/backend can run shell commands freely.
#
# Only add packages to this list if absolutely necessary.
#
# Behavior on user systems depends on the system
ALLOW_SDIST_NATIVE : 'scikit-sparse'
# Comma-separated list
ALLOW_SDIST_PURE : 'hausdorff,pydot3k,tinynumpy'
#
# Excluded Packages:
#
# 1. When this CI script was written, the "ocp" package
# had an error in their wheel's metadata that prevented
# the constraints.txt generation from working properly.
#
# Its wheel metadata appears to use a marker that compares
# a "version" field to x86_64, which makes pip's marker
# evaluator try to parse x86_64 as a version.
#
# For expediency, just exclude it from consideration.
#
# Comma-separated list
EXCLUDE_PACKAGES : 'ocp'
################################################################################
jobs:
Build:
runs-on : ubuntu-latest
name : Build
strategy:
fail-fast: false
matrix:
#
# The Addon Manager currently supports the following
# versions of Python - provide a constraints each.
#
py : [ '3.10' , '3.11' , '3.12' , '3.13' , '3.14' ]
steps:
- name : Checkout Pull Request
uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with :
repository : ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth : 0
submodules : false
lfs : false
################################################################
- name : Validate Allowed-Packages
shell : bash
run : '.github/workflows/Update-Constraints/Validate-Allowed-Packages.sh "${{ matrix.py }}"'
################################################################
- name : Exclude Wheel-less Packages
if : ${{ matrix.py == '3.13' || matrix.py == '3.14' }}
run : echo "EXCLUDE_PACKAGES=${EXCLUDE_PACKAGES},openexr,pyoptools" >> "$GITHUB_ENV"
################################################################
# https://github.com/marketplace/actions/setup-python
- name : Setup Python ${{ matrix.py }}
uses : actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with :
python-version : ${{ matrix.py }}
################################################################
- name : Build & Freeze VEnv
shell : bash
run : '.github/workflows/Update-Constraints/Build-And-Freeze-VEnv.sh'
################################################################
# https://github.com/marketplace/actions/upload-a-build-artifact
- name : Upload Artifacts
uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with :
# constraints.txt
name : ${{ env.ARTIFACT_NAME }}
# Data/Python/3.xx/constraints.txt
path : ${{ env.ARTIFACT_PATH }}
if-no-files-found : error
retention-days : 7
############################################################################
Commit:
runs-on : ubuntu-latest
needs : Build
name : Commit
if : ${{ github.event_name == 'pull_request_target' }}
steps:
# https://github.com/marketplace/actions/checkout
- name : Checkout Pull Request
uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with :
repository : ${{ github.event.pull_request.head.repo.full_name }}
ref : ${{ github.event.pull_request.head.sha }}
fetch-depth : 0
submodules : false
lfs : false
################################################################
# https://github.com/marketplace/actions/download-a-build-artifact
- name : Download Artifacts
uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with :
pattern : 'constraints-*.txt'
path : 'artifacts'
################################################################
- name : Place Constraints
shell : bash
run : |
for dir in artifacts/constraints-*.txt; do
version="${dir#artifacts/constraints-}"
version="${version%.txt}"
cp "$dir/constraints.txt" "Data/Python/${version}/constraints.txt"
done
################################################################
- name : Commit Constraints
shell : bash
run : '.github/workflows/Update-Constraints/Commit-Constraints.sh'
env:
BOT_PUSH_TOKEN : ${{ secrets.BOT_PUSH_TOKEN }}
PR_REPO : ${{ github.event.pull_request.head.repo.full_name }}
PR_REF : ${{ github.event.pull_request.head.ref }}
################################################################
# https://github.com/marketplace/actions/github-script
- name : Comment Pull Request
uses : actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
if : ${{ success() }}
with:
script: |
github.rest.issues.createComment({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
issue_number: context.payload.pull_request.number,
body: "🤖 Constraints Bot: regenerated the constraints files and added a commit with the changes"
})
############################################################################
Create-PR:
runs-on : ubuntu-latest
needs : Build
name : Create PR
if : ${{ github.event_name != 'pull_request_target' }}
steps:
# https://github.com/marketplace/actions/checkout
- name : Checkout Repository
uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with :
fetch-depth : 0
submodules : false
lfs : false
################################################################
# https://github.com/marketplace/actions/download-a-build-artifact
- name : Download Artifacts
uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with :
pattern : 'constraints-*.txt'
path : 'artifacts'
################################################################
- name : Create PR with Updated Constraints
shell : bash
env :
GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
run : |
for dir in artifacts/constraints-*.txt; do
version="${dir#artifacts/constraints-}"
version="${version%.txt}"
cp "$dir/constraints.txt" "Data/Python/${version}/constraints.txt"
done
git add Data/Python/*/constraints.txt || true
if git diff --staged --quiet; then
echo "No changes to constraints files; nothing to do."
exit 0
fi
branch="update-constraints/$(date +%Y-%m-%d-%H%M%S)"
git config user.name "freecad-constraints-bot"
git config user.email "freecad-constraints-bot@users.noreply.github.com"
git checkout -b "$branch"
git commit -m "Update Python package constraints"
git push origin "$branch"
gh pr create \
--title "Update Python package constraints" \
--body "🤖 Constraints Bot: automated update of constraints files triggered via workflow dispatch." \
--base main