Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ on:
required: false
type: boolean
default: false
waive_v178_qualification:
description: "Owner-authorized qualification waiver for the retained v1.7.8 candidate only"
required: false
type: boolean
default: false

permissions:
contents: read
Expand Down Expand Up @@ -964,16 +969,21 @@ jobs:
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
- name: Enforce and record the v1.7.6-only qualification waiver
if: inputs.waive_v176_qualification
- name: Enforce and record the release-specific qualification waiver
if: inputs.waive_v176_qualification || inputs.waive_v178_qualification
env:
RELEASE_TAG: ${{ inputs.release_tag }}
WAIVE_V176: ${{ inputs.waive_v176_qualification }}
WAIVE_V178: ${{ inputs.waive_v178_qualification }}
GH_ACTOR: ${{ github.actor }}
GH_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
shell: bash
run: |
set -euo pipefail
test "$RELEASE_TAG" = "v1.7.6"
case "$WAIVE_V176:$WAIVE_V178:$RELEASE_TAG" in
true:false:v1.7.6|false:true:v1.7.8) ;;
*) printf 'Waiver must select exactly one authorized release.\n' >&2; exit 1 ;;
esac
{
printf '# Release qualification waiver\n\n'
printf 'Tag: `%s`\n' "$RELEASE_TAG"
Expand Down Expand Up @@ -1125,7 +1135,7 @@ jobs:
cp dist/*.whl dist/*.tar.gz verified-dist/

- name: Require signed full-product qualification before PyPI repair
if: ${{ !inputs.waive_v176_qualification }}
if: ${{ !inputs.waive_v176_qualification && !inputs.waive_v178_qualification }}
env:
RELEASE_TAG: ${{ inputs.release_tag }}
ENGRAPHIS_RELEASE_QUALIFICATION: ${{ secrets.ENGRAPHIS_RELEASE_QUALIFICATION }}
Expand All @@ -1140,18 +1150,23 @@ jobs:
--commit "$ENGRAPHIS_REPAIR_COMMIT" --tag "$RELEASE_TAG"

- name: Disclose the qualification waiver before PyPI repair
if: inputs.waive_v176_qualification
if: inputs.waive_v176_qualification || inputs.waive_v178_qualification
env:
WAIVE_V176: ${{ inputs.waive_v176_qualification }}
WAIVE_V178: ${{ inputs.waive_v178_qualification }}
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
RELEASE_TAG: ${{ inputs.release_tag }}
GH_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
shell: bash
run: |
set -euo pipefail
test "$RELEASE_TAG" = "v1.7.6"
# The exception covers this retained candidate, not future reuse of its tag.
test "$ENGRAPHIS_REPAIR_COMMIT" = "6a441a75c8dd159607fa3933da83f600864b9146"
# Each exception covers one retained candidate, not future reuse of its tag.
case "$WAIVE_V176:$WAIVE_V178:$RELEASE_TAG:$ENGRAPHIS_REPAIR_COMMIT" in
true:false:v1.7.6:6a441a75c8dd159607fa3933da83f600864b9146|\
false:true:v1.7.8:dce68e1602e580cd51b71e26db2ab04238df7df4) ;;
*) printf 'Waiver does not match an authorized source candidate.\n' >&2; exit 1 ;;
esac
{
printf '## Release qualification\n\n'
printf 'The owner waived full-product qualification for this release. Mandatory full-product gates are not represented as passed.\n\n'
Expand All @@ -1175,6 +1190,8 @@ jobs:
--generate-notes --notes-file "$RUNNER_TEMP/release-waiver.md" \
--title "Engraphis ${RELEASE_TAG#v}" --latest=false
fi
# Editing notes on an existing draft does not make the notice public.
test "$(gh release view "$RELEASE_TAG" --repo "$GH_REPO" --json isDraft --jq .isDraft)" = "false"

- name: Publish only missing verified distributions
uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
Expand All @@ -1190,7 +1207,7 @@ jobs:
--version "${RELEASE_TAG#v}" --retries 18 --delay 10

- name: Require signed full-product qualification before GitHub repair
if: ${{ !inputs.waive_v176_qualification }}
if: ${{ !inputs.waive_v176_qualification && !inputs.waive_v178_qualification }}
env:
RELEASE_TAG: ${{ inputs.release_tag }}
ENGRAPHIS_RELEASE_QUALIFICATION: ${{ secrets.ENGRAPHIS_RELEASE_QUALIFICATION }}
Expand All @@ -1208,7 +1225,7 @@ jobs:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
RELEASE_TAG: ${{ inputs.release_tag }}
WAIVE_QUALIFICATION: ${{ inputs.waive_v176_qualification }}
WAIVE_QUALIFICATION: ${{ inputs.waive_v176_qualification || inputs.waive_v178_qualification }}
GH_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
shell: bash
run: |
Expand Down
37 changes: 26 additions & 11 deletions docs/RELEASE_QUALIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Every ordinary PyPI publication, GitHub release write, and repair requires a val
full-product qualification. Passing the public build jobs is necessary but does
not replace the mandatory private readiness evidence. The workflow fails closed
when qualification configuration is missing, malformed, expired or inconsistent
with the selected source and distribution bytes. The owner-authorized v1.7.6
repair waiver is the one-time exception documented below.
with the selected source and distribution bytes. The owner-authorized repair
waivers for the retained v1.7.6 and v1.7.8 candidates are documented below.

The public verifier is `scripts/verify_release_qualification.py`. It verifies
Ed25519 signatures using `cryptography==50.0.0` in release jobs. It contains no
Expand Down Expand Up @@ -107,16 +107,31 @@ a matching historical push run and verifies its exact public distribution/eviden
hashes, then checks the current owner approval before both repair writes. It uses
the peeled release tag commit, never the repair workflow's `main` checkout commit.

For the existing `v1.7.6` release only, the repository owner explicitly directed a
qualification waiver on 2026-09-27. The `workflow_dispatch` input
`waive_v176_qualification` skips the owner qualification verifier only when repairing
`v1.7.6` at commit `6a441a75c8dd159607fa3933da83f600864b9146`. Reusing that
tag for another commit cannot use this exception. The workflow records the actor
On 2026-09-27, the repository owner explicitly authorized qualification waivers
for these retained release candidates:

| Dispatch input | Release tag | Required source commit |
| --- | --- | --- |
| `waive_v176_qualification` | `v1.7.6` | `6a441a75c8dd159607fa3933da83f600864b9146` |
| `waive_v178_qualification` | `v1.7.8` | `dce68e1602e580cd51b71e26db2ab04238df7df4` |

Select exactly one waiver input together with its matching `release_tag`. Both
inputs default to false. Combining them, selecting the wrong version, or reusing
a tag for another commit fails before any public write. The v1.7.8 waiver follows
the owner's explicit instruction to remove publication blockers after integrating
and reviewing the beneficial local work. It reuses the distributions and evidence
from the successful automated validations of that tagged source.

The protected environment approval, exact distribution/evidence verification,
and PyPI file identity checks remain required. The workflow records the actor
and run URL, and publishes the waiver in GitHub Release notes before the first
PyPI write. A failed disclosure prevents publication; a later repair failure
leaves the public disclosure in place. This is not a qualification and
does not mark any unverified gate as passing. All ordinary tag publications and
repairs for other versions still require a valid owner-signed qualification.
PyPI write. An existing draft must already be public before publication can
proceed; a successful notes edit alone is insufficient. A failed disclosure
prevents publication; a later repair failure
leaves the public disclosure in place. These waivers are not qualifications and
do not mark any unverified gate as passing. All ordinary tag publications and
repairs outside these exact candidates still require a valid owner-signed
qualification.

## Public installed evidence

Expand Down
6 changes: 3 additions & 3 deletions docs/RELEASE_READINESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ engine checkout; `--require-leadership` requires both decisions. All modes retai
Actual publication additionally requires the protected, owner-signed approval in
[RELEASE_QUALIFICATION.md](RELEASE_QUALIFICATION.md), verified immediately before each
normal or repair write. Its environment, authority and approval remain owner setup;
this source change does not configure or issue them. The owner-authorized v1.7.6
repair waiver documented there is an explicit exception and does not establish
full-product readiness or change any gate status.
this source change does not configure or issue them. The owner-authorized repair
waivers for the exact v1.7.6 and v1.7.8 candidates documented there are explicit
exceptions and do not establish full-product readiness or change any gate status.

Planner experiments remain off by default. To require their existing optimization gate:

Expand Down
Loading
Loading