From: ModeSevenIndustrialSolutions Date: Wed, 10 Sep 2025 08:02:24 +0000 (+0100) Subject: CI: Update lftools release workflow X-Git-Tag: v0.37.14~4 X-Git-Url: https://gerrit.linuxfoundation.org/infra/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F29%2F73629%2F2;p=releng%2Flftools.git CI: Update lftools release workflow Change-Id: I652bc530e9bac63f47dff7482c49484480bf87dc Signed-off-by: ModeSevenIndustrialSolutions --- diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index d3901a0a..2df16449 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,64 +1,264 @@ --- -name: PyPI release +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2025 The Linux Foundation + +# Runs on a new pull request, performs build and runs tests +name: 'Python Build/Test/Release' # yamllint disable-line rule:truthy -on: push +on: + # Trigger on tag push events + push: + tags: + - '**' permissions: {} jobs: - publish: - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') - runs-on: ubuntu-latest + tag-validate: + name: 'Validate Tag Push' + runs-on: 'ubuntu-latest' + permissions: + contents: read + timeout-minutes: 1 + outputs: + tag: "${{ steps.tag-validate.outputs.tag }}" + steps: + # Harden the runner used by this workflow + # yamllint disable-line rule:line-length + - uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: 'audit' + + - name: 'Verify Pushed Tag' + id: 'tag-validate' + # yamllint disable-line rule:line-length + uses: lfreleng-actions/tag-push-verify-action@80e2bdbbb9ee7b67557a31705892b75e75d2859e # v0.1.1 + with: + versioning: 'semver' + + - name: 'Reject Development Tags' + if: steps.tag-validate.outputs.dev_version == 'true' + shell: bash + run: | + # Reject Development Tags + echo "Development tag pushed; aborting release workflow 🛑" + echo "Development tag pushed; aborting release workflow 🛑" \ + >> "$GITHUB_STEP_SUMMARY" + exit 1 + + python-build: + name: 'Python Build' + needs: 'tag-validate' + runs-on: 'ubuntu-latest' + outputs: + matrix_json: "${{ steps.python-build.outputs.matrix_json }}" + artefact_name: "${{ steps.python-build.outputs.artefact_name }}" + artefact_path: "${{ steps.python-build.outputs.artefact_path }}" + permissions: + contents: read + id-token: write # Needed for attestations + attestations: write # Needed for attestations + timeout-minutes: 12 env: GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + steps: + # Harden the runner used by this workflow + # yamllint disable-line rule:line-length + - uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: 'audit' + + # yamllint disable-line rule:line-length + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: 'Build Python project' + id: 'python-build' + # yamllint disable-line rule:line-length + uses: lfreleng-actions/python-build-action@48381cece78a990a6ba93bd5924bcd40bf0d1a7d # v0.1.20 + with: + sigstore_sign: true + attestations: true + + python-tests: + name: 'Python Tests' + runs-on: 'ubuntu-latest' + needs: 'python-build' + # Matrix job + strategy: + fail-fast: false + matrix: "${{ fromJson(needs.python-build.outputs.matrix_json) }}" permissions: - contents: write + contents: read + timeout-minutes: 12 steps: - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Configure Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 - with: - python-version: "3.8" - - name: Build package distribution files - run: >- - pipx run tox -e clean,build - - name: Configure TWINE - run: | - echo "TWINE_USERNAME=__token__" >> "$GITHUB_ENV" - echo "TWINE_PASSWORD=${{ secrets.PYPI_API_TOKEN }}" >> "$GITHUB_ENV" - - name: Publish to PyPI - run: >- - pipx run tox -e publish -- --repository pypi - - name: Get tag - id: tag - uses: devops-actions/action-get-tag@v1.0.2 - - name: Convert tag - run: | - VER=$(echo "${{ steps.tag.outputs.tag }}" | tr . -) - echo "ANCHOR=${VER}" >> "$GITHUB_ENV" - - name: Generate reno report - run: | - # fetch last 30 changes - git fetch --depth=30 - pipx run tox -e reno -- report \ - --version "${{ steps.tag.outputs.tag }}" \ - 2>/dev/null > reno-notes.md || true - if grep -q 'reno: FAIL' reno-notes.md - then - touch modified-reno-notes.md - else - sed '/^\.pkg.*$/d' reno-notes.md | - sed '/^reno:.*$/d' | - sed '/^\.\. .*$/d' | - sed '$d' | - sed '$d' | - sed '1d' > modified-reno-notes.md - fi - - name: Create Release Notes - run: | - gh release create ${{ steps.tag.outputs.tag }} --generate-notes \ - -F modified-reno-notes.md + # Harden the runner used by this workflow + # yamllint disable-line rule:line-length + - uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: 'audit' + + # yamllint disable-line rule:line-length + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: 'Test Python project [PYTEST]' + # yamllint disable-line rule:line-length + uses: lfreleng-actions/python-test-action@bdde9e4e6221e858359f9036bd4f41ab3b1af90e # v0.1.11 + with: + python_version: "${{ matrix.python-version }}" + + python-audit: + name: 'Python Audit' + runs-on: 'ubuntu-latest' + needs: 'python-build' + # Matrix job + strategy: + fail-fast: false + matrix: "${{ fromJson(needs.python-build.outputs.matrix_json) }}" + permissions: + contents: read + timeout-minutes: 10 + steps: + # Harden the runner used by this workflow + # yamllint disable-line rule:line-length + - uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: 'audit' + + # yamllint disable-line rule:line-length + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: 'Audit Python project' + # yamllint disable-line rule:line-length + uses: lfreleng-actions/python-audit-action@bab5316468c108870eb759ef0de622bae9239aad # v0.2.2 + with: + python_version: "${{ matrix.python-version }}" + + test-pypi: + name: 'Test PyPI Publishing' + runs-on: 'ubuntu-latest' + needs: + - 'tag-validate' + - 'python-tests' + - 'python-audit' + environment: + name: 'development' + permissions: + contents: read + id-token: write # IMPORTANT: mandatory for trusted publishing + timeout-minutes: 5 + steps: + # Harden the runner used by this workflow + # yamllint disable-line rule:line-length + - uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: 'audit' + + # yamllint disable-line rule:line-length + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: 'Test PyPI publishing' + # yamllint disable-line rule:line-length + uses: lfreleng-actions/pypi-publish-action@81a056957ed050f8305760055b1fd8103a916989 # v0.1.1 + with: + environment: 'development' + tag: "${{ needs.tag-validate.outputs.tag }}" + + pypi: + name: 'Release PyPI Package' + runs-on: 'ubuntu-latest' + needs: + - 'tag-validate' + - 'test-pypi' + environment: + name: 'production' + permissions: + contents: read + id-token: write # IMPORTANT: mandatory for trusted publishing + timeout-minutes: 5 + steps: + # Harden the runner used by this workflow + # yamllint disable-line rule:line-length + - uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: 'audit' + + # yamllint disable-line rule:line-length + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: 'PyPI release' + # yamllint disable-line rule:line-length + uses: lfreleng-actions/pypi-publish-action@81a056957ed050f8305760055b1fd8103a916989 # v0.1.1 + with: + environment: 'production' + attestations: true + tag: "${{ needs.tag-validate.outputs.tag }}" + + promote-release: + name: 'Promote Draft Release' + # yamllint disable-line rule:line-length + if: startsWith(github.ref, 'refs/tags/') + needs: + - 'tag-validate' + - 'pypi' + runs-on: 'ubuntu-latest' + permissions: + contents: write # IMPORTANT: needed to edit a draft release and promote it + timeout-minutes: 2 + outputs: + release_url: "${{ steps.promote-release.outputs.release_url }}" + steps: + # Harden the runner used by this workflow + # yamllint disable-line rule:line-length + - uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: 'audit' + + # yamllint disable-line rule:line-length + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: 'Promote draft release' + id: 'promote-release' + # yamllint disable-line rule:line-length + uses: lfreleng-actions/draft-release-promote-action@d7e7df12e32fa26b28dbc2f18a12766482785399 # v0.1.2 + with: + token: "${{ secrets.GITHUB_TOKEN }}" + tag: "${{ needs.tag-validate.outputs.tag }}" + latest: true + + # Need to attach build artefacts to the release + # This step could potentially be moved + # (May be better to when/where the release is still in draft state) + attach-artefacts: + name: 'Attach Artefacts to Release' + runs-on: 'ubuntu-latest' + needs: + - 'tag-validate' + - 'python-build' + - 'promote-release' + permissions: + contents: write # IMPORTANT: needed to edit release, attach artefacts + timeout-minutes: 5 + steps: + # Harden the runner used by this workflow + # yamllint disable-line rule:line-length + - uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: 'audit' + + # Note: no need for a checkout step in this job + + - name: '⬇ Download build artefacts' + # yamllint disable-line rule:line-length + uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + with: + name: "${{ needs.python-build.outputs.artefact_name }}" + path: "${{ needs.python-build.outputs.artefact_path }}" + + - name: 'Attach build artefacts to release' + # yamllint disable-line rule:line-length + uses: alexellis/upload-assets@13926a61cdb2cb35f5fdef1c06b8b591523236d3 # 0.4.1 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: "${{ github.token }}" + with: + asset_paths: '["${{ needs.python-build.outputs.artefact_path }}/**"]'