Release #117
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_run: | |
| workflows: ["CI"] | |
| types: [completed] | |
| jobs: | |
| gate: | |
| if: >- | |
| github.event.workflow_run.conclusion == 'success' && | |
| github.event.workflow_run.event == 'push' && | |
| github.event.workflow_run.head_branch == github.event.repository.default_branch | |
| runs-on: ubuntu-latest | |
| permissions: {} | |
| outputs: | |
| should_release: ${{ steps.tip.outputs.should_release }} | |
| steps: | |
| - name: Verify tested commit is still the tip of the default branch | |
| id: tip | |
| env: | |
| EXPECTED_SHA: ${{ github.event.workflow_run.head_sha }} | |
| DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} | |
| REPOSITORY: ${{ github.repository }} | |
| run: | | |
| ACTUAL_SHA=$(git ls-remote "https://github.com/$REPOSITORY" "refs/heads/$DEFAULT_BRANCH" | cut -f1) | |
| if [ "$ACTUAL_SHA" = "$EXPECTED_SHA" ]; then | |
| echo "should_release=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "should_release=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| release: | |
| needs: gate | |
| if: needs.gate.outputs.should_release == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # for creating tags | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.repository.default_branch }} | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.x" | |
| - name: Extract version | |
| id: version | |
| run: | | |
| VERSION=$(python -c "import re, pathlib; print(re.search(r'__version__\s*=\s*\"(.+?)\"', pathlib.Path('src/pycyphal2/__init__.py').read_text()).group(1))") | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Check if tag exists | |
| id: tag_check | |
| run: | | |
| if git ls-remote --tags origin "refs/tags/${{ steps.version.outputs.version }}" | grep -q .; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Create tag | |
| if: steps.tag_check.outputs.exists == 'false' | |
| run: | | |
| git tag "${{ steps.version.outputs.version }}" | |
| git push origin "${{ steps.version.outputs.version }}" | |
| - name: Check if version is on PyPI | |
| id: pypi_check | |
| env: | |
| VERSION: ${{ steps.version.outputs.version }} | |
| run: | | |
| if python - <<'PY' | |
| from __future__ import annotations | |
| import json | |
| import os | |
| import urllib.error | |
| import urllib.request | |
| version = os.environ["VERSION"] | |
| try: | |
| with urllib.request.urlopen("https://pypi.org/pypi/pycyphal2/json", timeout=20) as response: | |
| data = json.load(response) | |
| except urllib.error.HTTPError as ex: | |
| if ex.code == 404: | |
| raise SystemExit(1) | |
| raise | |
| raise SystemExit(0 if version in data.get("releases", {}) else 1) | |
| PY | |
| then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Verify PyPI token is configured | |
| if: steps.pypi_check.outputs.exists == 'false' | |
| env: | |
| PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN_GLOBAL || secrets.PYPI_API_TOKEN_PYCYPHAL }} | |
| run: | | |
| if [ -z "$PYPI_API_TOKEN" ]; then | |
| echo "::error::Missing PyPI token secret (expected PYPI_API_TOKEN_GLOBAL or PYPI_API_TOKEN_PYCYPHAL)." | |
| exit 1 | |
| fi | |
| - name: Build package | |
| if: steps.pypi_check.outputs.exists == 'false' | |
| run: | | |
| pip install build | |
| python -m build | |
| - name: Publish to PyPI | |
| if: steps.pypi_check.outputs.exists == 'false' | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| password: ${{ secrets.PYPI_API_TOKEN_GLOBAL || secrets.PYPI_API_TOKEN_PYCYPHAL }} | |
| attestations: false |