Skip to content

ci(compat): drop torch from 3.11/3.12 compat job; slim smoke-test to … #3

ci(compat): drop torch from 3.11/3.12 compat job; slim smoke-test to …

ci(compat): drop torch from 3.11/3.12 compat job; slim smoke-test to … #3

Workflow file for this run

name: Release (signed + provenance)

Check failure on line 1 in .github/workflows/release.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/release.yml

Invalid workflow file

(Line: 96, Col: 9): Unrecognized named-value: 'secrets'. Located at position 1 within expression: secrets.PYPI_API_TOKEN != ''
# Builds the Python distribution on a version tag, generates a SHA-256 manifest,
# produces a keyless SLSA build-provenance attestation (Sigstore via GitHub OIDC —
# no maintainer-managed signing keys), and publishes everything to a GitHub
# Release. This satisfies OpenSSF `signed_releases`: consumers can cryptographically
# verify an artifact came from this repo's CI with:
#
# gh attestation verify <artifact> --repo Gavin-Borges/SESTRAV
#
# See docs/releasing.md and SECURITY.md "Release Integrity & Verification".
on:
push:
tags:
- "v*"
permissions:
contents: read
jobs:
release:
name: Build, attest, and publish signed release
runs-on: ubuntu-latest
permissions:
contents: write # create the GitHub Release and upload assets
id-token: write # OIDC token for keyless Sigstore signing
attestations: write # store the build-provenance attestation
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
- name: Verify tag matches package version
# Fail fast (before building) if the pushed tag does not match
# pyproject.toml [project].version, so release artifacts can never be
# mislabelled. Bump pyproject before tagging (see docs/releasing.md).
run: |
PKG=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
TAG="${GITHUB_REF_NAME#v}"
if [ "$PKG" != "$TAG" ]; then
echo "::error::Tag '${GITHUB_REF_NAME}' (version '${TAG}') does not match pyproject.toml version '${PKG}'. Bump pyproject.toml before tagging."
exit 1
fi
echo "Version check OK: pyproject=${PKG} tag=${GITHUB_REF_NAME}"
- name: Build sdist and wheel
# setuptools build backend (see pyproject.toml [build-system]); building the
# source/wheel distribution does not import the heavy ML runtime deps.
# Hash-pinned (OpenSSF Scorecard Pinned-Dependencies). Regenerate with:
# pip-compile --generate-hashes environments/requirements-ci-build.in \
# --output-file environments/requirements-ci-build.txt --no-emit-index-url
run: |
pip install --require-hashes -r environments/requirements-ci-build.txt
python -m build --sdist --wheel --outdir dist/
- name: Generate SHA-256 checksum manifest
run: |
cd dist
sha256sum * > SHA256SUMS.txt
cat SHA256SUMS.txt
- name: Attest build provenance (keyless SLSA)
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: "dist/*.tar.gz,dist/*.whl"
- name: Publish GitHub Release with artifacts + checksums
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "${GITHUB_REF_NAME}" \
dist/*.tar.gz dist/*.whl dist/SHA256SUMS.txt \
--title "SESTRAV ${GITHUB_REF_NAME}" \
--generate-notes \
--verify-tag
- name: Upload dist artifacts for publish job
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist-${{ github.ref_name }}
path: dist/
retention-days: 1
publish:
name: Publish to PyPI
needs: release
runs-on: ubuntu-latest
# Only publish when PYPI_API_TOKEN secret is configured.
# New maintainers: register the package on PyPI, generate an API token
# scoped to 'sestrav', and add it as a repository secret named PYPI_API_TOKEN.
if: ${{ secrets.PYPI_API_TOKEN != '' }}
environment:
name: pypi
url: https://pypi.org/p/sestrav
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Download dist artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dist-${{ github.ref_name }}
path: dist/
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
- name: Install twine
run: pip install --require-hashes -r environments/requirements-ci-twine.txt
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: twine upload dist/*.tar.gz dist/*.whl
- name: Smoke-test installation from PyPI
# Wait briefly for PyPI index propagation then verify pip can resolve the new version.
run: |
pip install --no-deps "sestrav==${GITHUB_REF_NAME#v}" --index-url https://pypi.org/simple/
python -c "import sestrav; print('sestrav import OK')" || python -c "from src import features; print('import OK')"