Skip to content

Release

Release #1

Workflow file for this run

name: Release
on:
workflow_run:
workflows: ["CI"]
types: [completed]
branches: [main]
jobs:
release:
if: >-
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'push'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.event.workflow_run.head_sha }}
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Extract version
id: version
run: |
python -m pip install --no-deps .
python - <<'PY' >> "$GITHUB_OUTPUT"
from importlib.metadata import version
print(f"version={version('cyphal-cynic')}")
PY
- name: Check PyPI
id: pypi
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
python - <<'PY'
import json
import os
import sys
import urllib.error
import urllib.request
version = os.environ["VERSION"]
url = "https://pypi.org/simple/cyphal-cynic/"
request = urllib.request.Request(url, headers={"Accept": "application/vnd.pypi.simple.v1+json"})
try:
with urllib.request.urlopen(request, timeout=30) as response:
payload = json.load(response)
except urllib.error.HTTPError as ex:
if ex.code == 404:
exists = False
else:
print(f"::error::PyPI returned HTTP {ex.code}", file=sys.stderr)
raise SystemExit(1) from ex
except urllib.error.URLError as ex:
print(f"::error::PyPI request failed: {ex.reason}", file=sys.stderr)
raise SystemExit(1) from ex
except json.JSONDecodeError as ex:
print(f"::error::PyPI returned invalid JSON: {ex}", file=sys.stderr)
raise SystemExit(1) from ex
else:
if not isinstance(payload, dict):
print("::error::PyPI returned an unexpected Simple API response.", file=sys.stderr)
raise SystemExit(1)
versions = payload.get("versions")
if not isinstance(versions, list) or not all(isinstance(v, str) for v in versions):
print("::error::PyPI returned an unexpected Simple API response.", file=sys.stderr)
raise SystemExit(1)
exists = version in versions
if exists:
print(f"PyPI already has cyphal-cynic {version}.")
else:
print(f"PyPI does not have cyphal-cynic {version}; publishing.")
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as out:
print(f"exists={str(exists).lower()}", file=out)
PY
- name: Build package
if: steps.pypi.outputs.exists == 'false'
run: |
python -m pip install build
python -m build
- name: Ensure tag
if: steps.pypi.outputs.exists == 'false'
env:
EXPECTED_SHA: ${{ github.event.workflow_run.head_sha }}
VERSION: ${{ steps.version.outputs.version }}
run: |
set -e -o pipefail
TAG_SHA=$(git ls-remote --tags origin "refs/tags/$VERSION^{}" | cut -f1)
if [ -z "$TAG_SHA" ]; then
TAG_SHA=$(git ls-remote --tags origin "refs/tags/$VERSION" | cut -f1)
fi
if [ -z "$TAG_SHA" ]; then
echo "Creating tag $VERSION at $EXPECTED_SHA."
git push origin "HEAD:refs/tags/$VERSION"
elif [ "$TAG_SHA" = "$EXPECTED_SHA" ]; then
echo "Tag $VERSION already points to $EXPECTED_SHA."
else
echo "::error::Tag $VERSION points to $TAG_SHA, expected $EXPECTED_SHA."
exit 1
fi
- name: Publish to PyPI
if: steps.pypi.outputs.exists == 'false'
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
attestations: false