diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15b5c8b..501c71a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,6 @@ on: options: - lint-and-test - docs-deploy - - release description: Choose the workflow to run default: lint-and-test permissions: @@ -54,10 +53,7 @@ jobs: python-docs-deploy: if: > github.event_name == 'push' - || ( - github.event_name == 'workflow_dispatch' - && (inputs.workflow == 'docs-deploy' || inputs.workflow == 'release') - ) + || (github.event_name == 'workflow_dispatch' && inputs.workflow == 'docs-deploy') permissions: contents: write uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-mkdocs-gh-deploy.yml@main # zizmor: ignore[unpinned-uses] @@ -69,19 +65,15 @@ jobs: python-package-release: if: > github.event_name == 'push' - || ( - github.event_name == 'workflow_dispatch' - && (inputs.workflow == 'release' || inputs.workflow == 'lint-and-test') - ) + || (github.event_name == 'workflow_dispatch' && inputs.workflow == 'lint-and-test') permissions: contents: write id-token: write uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-release-on-pypi-and-github.yml@main # zizmor: ignore[unpinned-uses] with: package-path: . - create-releases: ${{ github.event_name == 'workflow_dispatch' && inputs.workflow == 'release' }} + create-releases: false secrets: - PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} dependabot-auto-merge: if: > diff --git a/.github/workflows/claude-code.yml b/.github/workflows/claude.yml similarity index 97% rename from .github/workflows/claude-code.yml rename to .github/workflows/claude.yml index 40bc1e6..d355cf7 100644 --- a/.github/workflows/claude-code.yml +++ b/.github/workflows/claude.yml @@ -26,7 +26,7 @@ jobs: claude-code-review: if: > github.event_name == 'pull_request' - && github.event.pull_request.draft == false + && (! github.event.pull_request.draft) && (! startsWith(github.head_ref, 'dependabot/')) && (! startsWith(github.head_ref, 'renovate/')) permissions: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e069c34 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,94 @@ +--- +name: Release +on: + workflow_dispatch: +permissions: + contents: read +defaults: + run: + shell: bash -euo pipefail {0} + working-directory: . +jobs: + build: + permissions: + contents: write + id-token: write + uses: dceoy/gh-actions-for-devops/.github/workflows/python-package-release-on-pypi-and-github.yml@main # zizmor: ignore[unpinned-uses] + with: + package-path: . + create-releases: false + secrets: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + github-release: + name: Sign the Python 🐍 distribution 📦 with Sigstore and upload them to GitHub Release + if: > + startsWith(github.ref, 'refs/tags/') + needs: + - build + runs-on: ubuntu-latest + permissions: + contents: write # IMPORTANT: mandatory for making GitHub Releases + id-token: write # IMPORTANT: mandatory for sigstore + steps: + - name: Download all the dists + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ needs.build.outputs.distribution-artifact-name }} + path: dist/ + - name: Validate the version-tag consistency + env: + TAG_NAME: ${{ github.ref_name }} + NEEDS_BUILD_OUTPUTS_PROJECT_NAME: ${{ needs.build.outputs.project-name }} + run: | + v="$( \ + find dist -type f -name "${NEEDS_BUILD_OUTPUTS_PROJECT_NAME}-*" -exec basename {} \; \ + | head -n 1 \ + | cut -d '-' -f 2 \ + )" + v="${v%.tar.gz}" + if [[ "${TAG_NAME}" != "${v}" ]] && [[ "${TAG_NAME}" != "v${v}" ]]; then + echo "The tag (${TAG_NAME}) is inconsistent with the version (${v})." && exit 1 + fi + - name: Sign the dists with Sigstore + uses: sigstore/gh-action-sigstore-python@04cffa1d795717b140764e8b640de88853c92acc # v3.3.0 + with: + inputs: >- + ./dist/*.whl + - name: Create GitHub Release + env: + REPOSITORY: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }} # zizmor: ignore[secrets-outside-env] caller-provided secret + run: | + gh release create "${GITHUB_REF_NAME}" --repo "${REPOSITORY}" --generate-notes --verify-tag + - name: Upload artifact signatures to GitHub Release + env: + REPOSITORY: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }} # zizmor: ignore[secrets-outside-env] caller-provided secret + # Upload to GitHub Release using the `gh` CLI. + # `dist/` contains the built packages, and the + # sigstore-produced signatures and certificates. + run: | + gh release upload "${GITHUB_REF_NAME}" dist/** --repo "${REPOSITORY}" + publish-to-pypi: + name: Publish the Python 🐍 distribution 📦 to PyPI + if: > + startsWith(github.ref, 'refs/tags/') + needs: + - build + - github-release + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/${{ needs.build.outputs.project-name }} + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + steps: + - name: Download all the dists + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ needs.build.outputs.distribution-artifact-name }} + path: dist/ + - name: Publish distribution 📦 to PyPI + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + with: + verbose: true