Skip to content

Merge pull request #69 from keelapi/prepare-v3.14.0 #43

Merge pull request #69 from keelapi/prepare-v3.14.0

Merge pull request #69 from keelapi/prepare-v3.14.0 #43

Workflow file for this run

name: Release
on:
push:
tags:
- "v*.*.*"
permissions:
id-token: write
contents: write
attestations: write
jobs:
release:
name: Build and sign release artifacts
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Checkout released Permit contract
uses: actions/checkout@v6
with:
repository: keelapi/keel-permit
path: keel-permit
ref: v1.13.0
- uses: actions/setup-python@v6
with:
python-version: "3.12"
cache: pip
cache-dependency-path: requirements.txt
- name: Install release dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade build twine cyclonedx-bom
python -m pip install -e ".[dev]"
- name: Gate GitHub trust-root publication
run: python scripts/check_release_trust_root.py --source github
- name: Gate historical compatibility corpus
run: python scripts/check_historical_compatibility_corpus.py --run
- name: Generate embedded release manifest
run: python scripts/generate_release_manifest.py embedded --tag "${GITHUB_REF_NAME}"
- name: Build wheel and source distribution
run: python -m build
- name: Check distributions
run: python -m twine check dist/*
- name: Generate CycloneDX SBOM
run: cyclonedx-py environment --output-format JSON --output-file sbom.cyclonedx.json
- uses: sigstore/cosign-installer@v3
- name: Capture cosign version
run: |
COSIGN_VERSION="$(
cosign version --json | python -c 'import json, sys; data = json.load(sys.stdin); print(data.get("gitVersion") or data.get("GitVersion") or data.get("version") or "unknown")'
)"
echo "COSIGN_VERSION=${COSIGN_VERSION}" >> "${GITHUB_ENV}"
- name: Sign wheel and source distribution
run: |
VERSION="${GITHUB_REF_NAME#v}"
WHEEL="keel_verifier-${VERSION}-py3-none-any.whl"
SDIST="keel_verifier-${VERSION}.tar.gz"
# --new-bundle-format produces Sigstore Bundle Format v0.3, which
# sigstore-python's Bundle.from_json() reads natively. Without the
# flag, cosign emits the legacy bundle format (base64Signature +
# cert + rekorBundle) that sigstore-python cannot parse, breaking
# `keel-verify self-check` against released artifacts.
cosign sign-blob --yes --new-bundle-format --bundle "dist/${WHEEL}.sigstore" "dist/${WHEEL}"
cosign sign-blob --yes --new-bundle-format --bundle "dist/${SDIST}.sigstore" "dist/${SDIST}"
- name: Attest CycloneDX SBOM against wheel
run: |
VERSION="${GITHUB_REF_NAME#v}"
WHEEL="keel_verifier-${VERSION}-py3-none-any.whl"
cosign attest-blob \
--yes \
--predicate sbom.cyclonedx.json \
--type cyclonedx \
--bundle "dist/keel_verifier-${VERSION}-sbom.intoto.jsonl" \
"dist/${WHEEL}"
- name: Generate release manifest
run: |
python scripts/generate_release_manifest.py release \
--tag "${GITHUB_REF_NAME}" \
--python-version "$(python -c 'import platform; print(platform.python_version())')" \
--cosign-version "${COSIGN_VERSION}"
- name: Sign release manifest
run: cosign sign-blob --yes --new-bundle-format --bundle manifest.json.sigstore manifest.json
- name: Timestamp release manifest with DigiCert and GlobalSign
run: python scripts/generate_tsa_witness.py --manifest manifest.json --output manifest.json.tsa.json
- name: Upload release artifacts
uses: softprops/action-gh-release@v2
with:
fail_on_unmatched_files: true
generate_release_notes: true
files: |
dist/*.whl
dist/*.tar.gz
dist/*.sigstore
dist/*.intoto.jsonl
sbom.cyclonedx.json
manifest.json
manifest.json.sigstore
manifest.json.tsa.json
publish-to-pypi:
name: Publish release distributions to PyPI
needs: release
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
environment:
name: pypi
url: https://pypi.org/p/keel-verifier
steps:
- name: Download GitHub Release distributions
env:
GH_TOKEN: ${{ github.token }}
run: |
mkdir -p dist
gh release download "${GITHUB_REF_NAME}" \
--repo "${GITHUB_REPOSITORY}" \
--pattern "*.whl" \
--pattern "*.tar.gz" \
--dir dist
- name: Publish distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1