From be82a2a9dbac40092a0c6af515bd3a4bfe505539 Mon Sep 17 00:00:00 2001 From: Zhi Ming Xu Date: Wed, 8 Oct 2025 01:35:18 -0400 Subject: [PATCH] chore: update build-wheel workflow file to match pdfgetx standards --- .../workflows/build-wheel-release-upload.yml | 163 ------------- .github/workflows/build-wheel-release.yml | 230 ++++++++++++++++++ 2 files changed, 230 insertions(+), 163 deletions(-) delete mode 100644 .github/workflows/build-wheel-release-upload.yml create mode 100644 .github/workflows/build-wheel-release.yml diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml deleted file mode 100644 index 3e78d1d..0000000 --- a/.github/workflows/build-wheel-release-upload.yml +++ /dev/null @@ -1,163 +0,0 @@ -name: Release on GitHub - -on: - workflow_call: - secrets: - PAT_TOKEN: - description: "GitHub Personal Access Token" - required: true - -env: - TAG: ${{ github.ref_name }} - -defaults: - run: - shell: bash {0} - -jobs: - prepare-release: - if: ${{ ! contains(github.ref, 'rc') }} - runs-on: ubuntu-latest - steps: - - name: Checkout the repository - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 - ref: main - - - name: Update CHANGELOG - run: | - wget https://raw.githubusercontent.com/scikit-package/release-scripts/v0/.github/workflows/update-changelog.py - python update-changelog.py "$TAG" - rm update-changelog.py - - - name: Commit updated CHANGELOG.rst - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add . - if ! git diff --cached --quiet; then - git commit -m "update changelog for $TAG" - git push origin main - else - echo "No CHANGELOG.rst changes" - fi - - - name: New tag - run: | - git fetch --tags - git tag -d "$TAG" 2>/dev/null || true - git push origin ":$TAG" 2>/dev/null || true - git tag "$TAG" - git push origin "$TAG" - - - name: Get CHANGELOG.txt - run: | - wget https://raw.githubusercontent.com/scikit-package/release-scripts/v0/.github/workflows/get-latest-changelog.py - python get-latest-changelog.py "$TAG" - rm get-latest-changelog.py - - - name: Upload changelog.txt - uses: actions/upload-artifact@v4 - with: - name: changelog - path: CHANGELOG.txt - - release: - needs: [prepare-release] - if: always() - runs-on: ubuntu-latest - env: - REPO_FULL: ${{ github.repository }} - PAT_TOKEN: ${{ secrets.PAT_TOKEN }} - steps: - - name: Check prepare release - run: | - if [[ ${{ needs.prepare-release.result }} != 'success' && "$TAG" != *rc* ]]; then - echo "::error::Skipping release job because prepare-release failed" - exit 78 - fi - echo "Continuing with release job" - - - name: Download built wheels - uses: actions/download-artifact@v4 - with: - path: dist/ - - - name: Download changelog - if: ${{ needs.prepare-release.result == 'success' }} - uses: actions/download-artifact@v4 - with: - name: changelog - path: . - - - name: Download instructions - uses: actions/download-artifact@v4 - with: - name: instructions - path: . - - - name: Zip wheels and instructions into dist/srxconfutils-$TAG-wheels.zip - run: | - mkdir -p dist - find dist -type f -name '*.whl' | zip -j dist/srxconfutils-"$TAG"-wheels.zip -@ - zip -j dist/srxconfutils-"$TAG"-wheels.zip INSTRUCTIONS.txt - - - name: Prepare release metadata - id: meta - run: | - if [[ "$TAG" == *rc* ]]; then - PRERELEASE=true - TITLE="Pre-release $TAG" - BODY_RAW="Changelog: https://github.com/$REPO_FULL/commits/$TAG" - else - PRERELEASE=false - TITLE="Release $TAG" - BODY_RAW=$( payload.json - - echo "Release metadata:" - cat payload.json - - - name: Create GitHub Release - id: create_release - run: | - set -euo pipefail - - HTTP_STATUS=$( - curl --silent --output resp.json --write-out "%{http_code}" \ - -X POST "https://api.github.com/repos/$REPO_FULL/releases" \ - -H "Accept: application/vnd.github+json" \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $PAT_TOKEN" \ - --data @payload.json - ) - if [[ "$HTTP_STATUS" -ne 201 ]]; then - echo "::error::Failed to create release (status $HTTP_STATUS)" - exit 1 - fi - - UPLOAD_URL=$(jq -r .upload_url resp.json | sed 's/{.*}//') - echo "upload_url=$UPLOAD_URL" >> $GITHUB_OUTPUT - - - name: Upload srxconfutils-$TAG-wheels.zip - if: steps.create_release.outputs.upload_url != '' - run: | - FILE=dist/srxconfutils-$TAG-wheels.zip - echo "Uploading asset: $FILE" - curl --silent --fail --data-binary @"$FILE" \ - -H "Content-Type: application/zip" \ - -H "Authorization: Bearer $PAT_TOKEN" \ - "${{ steps.create_release.outputs.upload_url }}?name=$(basename "$FILE")" diff --git a/.github/workflows/build-wheel-release.yml b/.github/workflows/build-wheel-release.yml new file mode 100644 index 0000000..8409857 --- /dev/null +++ b/.github/workflows/build-wheel-release.yml @@ -0,0 +1,230 @@ +name: Build Wheels and Release + +on: + workflow_dispatch: + push: + tags: + - "*" + +env: + PYTHON_VERSIONS: '["3.11","3.12","3.13"]' + +permissions: + contents: write + actions: read + packages: write + +concurrency: + group: build-wheels-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash {0} + +jobs: + get-python-versions: + runs-on: ubuntu-latest + outputs: + py_ver: ${{ steps.set.outputs.py_ver }} + py_last: ${{ steps.set.outputs.py_last }} + steps: + - id: set + run: | + echo py_ver=$PYTHON_VERSIONS >> $GITHUB_OUTPUT + echo "py_last=${{ fromJson(env.PYTHON_VERSIONS)[0] }}" >> $GITHUB_OUTPUT + + check-tag-on-main: + runs-on: ubuntu-latest + steps: + - name: Checkout repository with full history + uses: actions/checkout@v4 + with: + token: ${{ secrets.PAT_TOKEN }} + fetch-depth: 0 + + - name: Verify tag + run: | + git fetch origin main + TAG_COMMIT=$(git rev-parse ${{ github.ref_name }}) + if git merge-base --is-ancestor "$TAG_COMMIT" origin/main; then + echo "Tag ${{ github.ref_name }} ($TAG_COMMIT) is contained in main" + else + echo "::error::Tag ${{ github.ref_name }} ($TAG_COMMIT) is not found in main. Please release from the main branch." + exit 1 + fi + + check-tag-privilege: + # No third party actions used + uses: scikit-package/release-scripts/.github/workflows/_check-tag-privilege.yml@v0 + with: + maintainer_github_username: sbillinge + + build-sdist: + needs: [check-tag-privilege, get-python-versions, check-tag-on-main] + runs-on: ubuntu-latest + + steps: + - name: Checkout + # GitHub officially-maintained actions + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + # GitHub officially-maintained actions + uses: actions/setup-python@v5 + with: + python-version: ${{ needs.get-python-versions.outputs.py_last }} + + - name: Build docs and remove fonts that blow up the wheel size + run: | + python -m pip install Sphinx sphinx-rtd-theme sphinx-copybutton m2r + cd docs + make html + cd build/html/_static/css/fonts + find . -type f ! -name '*.ttf' -delete + cd ../.. + rm -rf fonts + cd .. + rm -rf _sources + cd .. + rm -rf doctrees + cd ../.. + + - name: Make sdist + run: | + python -m pip install --upgrade pip build cython setuptools setuptools-git-versioning + python -m build --sdist --no-isolation + + - name: Strip source codes + run: | + set -euo pipefail + tar xf dist/diffpy_srxconfutils-*.tar.gz + SRC_DIR=$(find . -maxdepth 1 -type d -name 'diffpy_srxconfutils-*' | head -n1) + find "$SRC_DIR" -type f -name '*.c' -print0 \ + | xargs -0 perl -i.bak -0777 -pe 's{/\*.*?\*/}{}gs' + find "$SRC_DIR" -type f -name '*.c.bak' -delete + tar czf dist/"${SRC_DIR#./}".tar.gz "$SRC_DIR" + rm -rf "$SRC_DIR" + + - name: Upload sdist + # GitHub officially-maintained actions + uses: actions/upload-artifact@v4 + with: + name: sdist + path: dist/ + retention-days: 1 + + - name: Upload INSTRUCTIONS.txt + uses: actions/upload-artifact@v4 + with: + name: instructions + path: INSTRUCTIONS.txt + + build-wheels: + needs: [build-sdist, get-python-versions] + + name: Build wheels ${{ matrix.python }}-${{ matrix.buildplat }} + runs-on: ${{ matrix.buildplat }} + strategy: + fail-fast: false + matrix: + buildplat: + - ubuntu-latest + - macos-14 + - windows-latest + python: ${{ fromJSON(needs.get-python-versions.outputs.py_ver) }} + steps: + - name: Download sdist + # GitHub officially-maintained actions + uses: actions/download-artifact@v4 + with: + name: sdist + path: dist/ + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Build wheels + run: | + # setuptools-git-versioning only look into .git and PKG-INFO in the top directory + which python; python --version + which pip; pip --version + python -m pip install --upgrade pip build cython setuptools setuptools-git-versioning + tar xf dist/diffpy_srxconfutils-*.tar.gz + cd diffpy_srxconfutils-* + python -m pip wheel . --no-deps --no-build-isolation --wheel-dir ./../dist + + - name: Upload wheels + uses: actions/upload-artifact@v4 + with: + name: wheels-${{ matrix.python }}-${{ matrix.buildplat }} + path: dist/*.whl + + test-wheels: + needs: [build-wheels, get-python-versions] + + name: Test wheels ${{ matrix.python }}-${{ matrix.buildplat }} + runs-on: ${{ matrix.buildplat }} + strategy: + fail-fast: false + matrix: + buildplat: + - ubuntu-latest + - macos-14 + - windows-latest + python: ${{ fromJson(needs.get-python-versions.outputs.py_ver) }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download wheels + uses: actions/download-artifact@v4 + with: + name: wheels-${{ matrix.python }}-${{ matrix.buildplat }} + path: dist/ + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install wheels + run: | + python -m pip install --upgrade pip pytest setuptools-git-versioning + python -m pip install dist/*.whl + + - name: Assert no source files in installed package + run: | + # For debugging + # touch $(python -c "import sysconfig, os; print(os.path.join(sysconfig.get_paths()['purelib'], 'diffpy/srxconfutils', 'fake.py'))") + python - << 'EOF' + import os, glob, sys, sysconfig + sp = sysconfig.get_paths()['purelib'] + pkg = os.path.join(sp, 'diffpy', 'srxconfutils') + patterns = [os.path.join(pkg, '*.py'), + os.path.join(pkg, '*.c')] + bad = [] + for p in patterns: + bad.extend(glob.glob(p)) + + if bad: + print("Found leftover source files in installed package:") + for f in bad: + print(" -", f) + sys.exit(1) + + print("No .py or .c files present in diffpy/srxconfutils/") + EOF + + - name: Run tests + run: python -m pytest + + release: + needs: [test-wheels] + uses: ./.github/workflows/release-github.yml + secrets: + PAT_TOKEN: ${{ secrets.PAT_TOKEN }}