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
18 changes: 13 additions & 5 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,23 @@ This directory contains GitHub Actions workflows for the HASTE project, focused
`training_image_tag`, and `imageprep_image_tag` on the PR.

Stable releases create `hastegeo-vX.Y.Z` tags, making reruns of the same source
commit a no-op. Stable publication additionally requires repository variables
`HASTEGEO_PUBLISH_ENABLED=true` and
`HASTEGEO_RELEASE_APPROVAL_CONFIGURED=true`.
commit a no-op. Stable publication is automatic: merging a PR into `main` that
touches `hastelib/` publishes the next **patch** wheel, because the review
required to land that commit is the release approval. Set
`HASTEGEO_PUBLISH_ENABLED=true` to enable it; set it to anything else to halt
stable publication.

Minor and major stable releases have no automated path today. The publisher only
accepts `push` and same-repository `pull_request` upstream events, so a
`workflow_dispatch` build is not published even though `hastegeo-build.yml`
accepts `bump` and `set_version` inputs.

RC publication is automatic unless `HASTEGEO_RC_PUBLISH_ENABLED=false`.
Fork PRs remain build-only. The RC image environment is selected through
`HASTEGEO_RC_ENVIRONMENT`, keeping environment names out of the workflow.
Before enabling stable publication, repository administrators must configure a
protected release environment with required reviewers and self-review disabled.
The protected `hastegeo-release` environment and the
`HASTEGEO_RELEASE_APPROVAL_CONFIGURED` variable still gate the destructive RC
deletion job in `rc-cleanup.yml`.

## Docker Build and Push Workflow

Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/hastegeo-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,21 @@ jobs:
--channel rc \
--source-sha "${{ needs.prepare.outputs.source_sha }}"

# Stable publication is automatic on merge to the default branch: the PR
# review required to land the commit there is the release approval. A second
# per-release sign-off would re-approve an already-reviewed commit.
# HASTEGEO_PUBLISH_ENABLED remains the kill switch.
#
# HASTEGEO_RELEASE_APPROVAL_CONFIGURED is deliberately NOT read here. It still
# gates the destructive RC deletion job in rc-cleanup.yml, which keeps the
# protected hastegeo-release environment.
Comment thread
jQuinRivero marked this conversation as resolved.
publish-stable:
needs: prepare
if: >-
needs.prepare.outputs.channel == 'release' &&
needs.prepare.outputs.already_published != 'true' &&
vars.HASTEGEO_PUBLISH_ENABLED == 'true' &&
vars.HASTEGEO_RELEASE_APPROVAL_CONFIGURED == 'true'
vars.HASTEGEO_PUBLISH_ENABLED == 'true'
runs-on: ubuntu-latest
environment: hastegeo-release
permissions:
actions: read
contents: write
Expand Down
6 changes: 4 additions & 2 deletions hastelib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ version when it builds an RC or stable wheel.

`hatch build` is build-only. GitHub Actions resolves the version, builds and
tests without write credentials, then passes the wheel to a separate trusted
publisher behind the protected `hastegeo-release` environment. Stable releases
create a `hastegeo-vX.Y.Z` source tag so reruns are idempotent.
publisher that runs from the default branch. Merging a PR into `main` that
touches `hastelib/` publishes the next stable patch wheel — the review required
to land the commit is the release approval. Stable releases create a
`hastegeo-vX.Y.Z` source tag so reruns are idempotent.

## License

Expand Down
12 changes: 9 additions & 3 deletions hastelib/tests/build/test_release_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def test_privileged_publisher_is_default_branch_workflow_run(self):
self.assertIn("PR head changed after the wheel build", workflow)
self.assertIn("PR #$PR_NUMBER is not open", workflow)

def test_rc_is_automatic_but_stable_is_approval_gated(self):
def test_rc_and_stable_are_both_automatic_but_kill_switched(self):
workflow = (
REPO_ROOT / ".github/workflows/hastegeo-publish.yml"
).read_text(encoding="utf-8")
Expand All @@ -107,8 +107,14 @@ def test_rc_is_automatic_but_stable_is_approval_gated(self):
)[0]
self.assertNotIn("environment:", rc_block)
self.assertIn("HASTEGEO_RC_PUBLISH_ENABLED", rc_block)
self.assertIn("environment: hastegeo-release", stable_block)
self.assertIn("environment: hastegeo-release", workflow)
# Merging to the default branch is the release approval, so stable
# publication carries no protected environment.
# HASTEGEO_PUBLISH_ENABLED stays as the kill switch.
self.assertNotIn("environment:", stable_block)
self.assertIn("HASTEGEO_PUBLISH_ENABLED", stable_block)
self.assertNotIn(
"HASTEGEO_RELEASE_APPROVAL_CONFIGURED", stable_block
)
self.assertIn("contents: write", workflow)
self.assertNotIn("--clobber", publisher)

Expand Down
4 changes: 3 additions & 1 deletion spec/features/hastegeo-ci-pipeline/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,7 @@ Function deployments can be reported as successful.
| Stable source tags | Main workflow reruns are idempotent |
| PEP 440 `rcN` | `rc01` is normalized to `rc1` by Python packaging |
| Automatic trusted RC publication | Fast dev/test handoff without exposing PR jobs to credentials |
| Protected stable environment | Human approval limits stable-release blast radius |
| Stable publishes on merge to `main` | The branch ruleset's required review is the release approval; a second per-release sign-off re-approves an already-reviewed commit |
| `HASTEGEO_PUBLISH_ENABLED` kill switch | Stable publication can be halted without a code change |
| Protected environment retained for RC deletion | Human approval limits destructive-automation blast radius |
| Scheduled cleanup is report-only | Destructive automation is deferred until observed safely |
13 changes: 7 additions & 6 deletions spec/features/hastegeo-ci-pipeline/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
The pipeline separates untrusted source execution from trusted repository and
Azure mutations. A read-only job builds and validates the wheel, passes it as
an Actions artifact, and a trusted default-branch workflow validates and
automatically publishes same-repository PR RCs. Stable releases remain
approval-gated.
automatically publishes same-repository PR RCs. Stable releases publish
automatically on merge to `main`, gated only by the `HASTEGEO_PUBLISH_ENABLED`
kill switch — the branch ruleset's required PR review is the release approval.

## Architecture

Expand Down Expand Up @@ -36,7 +37,7 @@ Trusted publish job [contents:write, trusted base ref only]
+--> deploy workflow uses the same wheel + both image tags

Stable push:
protected hastegeo-release approval
HASTEGEO_PUBLISH_ENABLED kill switch
-> publish X.Y.Z + create/reconcile hastegeo-vX.Y.Z tag
```

Expand Down Expand Up @@ -140,8 +141,8 @@ retain file must exist, and any GitHub query/delete failure aborts the run.
|---|---|
| `HASTEGEO_RC_ENVIRONMENT` repository variable | Selects the environment providing RC ACR OIDC/secrets |
| `HASTEGEO_RC_PUBLISH_ENABLED` repository variable | RC kill switch (`false` disables; absent enables) |
| `hastegeo-release` environment | Required reviewer approval for stable releases |
| `HASTEGEO_PUBLISH_ENABLED` repository variable | Stable publication enablement |
| `HASTEGEO_RELEASE_APPROVAL_CONFIGURED` repository variable | Admin confirmation that required reviewers are active |
| `hastegeo-release` environment | Required reviewer approval for destructive RC deletion (`rc-cleanup.yml`) |
| `HASTEGEO_PUBLISH_ENABLED` repository variable | Stable publication enablement / kill switch |
| `HASTEGEO_RELEASE_APPROVAL_CONFIGURED` repository variable | Admin confirmation that required reviewers are active; gates RC deletion only |
| `HASTE_BUMP` | Patch(default), minor, or major target |
| `HASTE_SET_VERSION` | Exact version override |
23 changes: 16 additions & 7 deletions spec/features/hastegeo-ci-pipeline/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
| 2 | Add trusted wheel validator/publisher | `backend-dev` | complete |
| 3 | Split read-only build and trusted publish workflow jobs | `backend-dev` | complete |
| 3 | Add automatic trusted RC publication | `backend-dev` | in-progress |
| 3 | Keep protected environment gate for stable releases | `backend-dev` | blocked: repository admin required |
| 3 | Publish stable automatically on merge to `main` | `backend-dev` | complete |
| 4 | Connect RC publication to coherent ACR image tags | `backend-dev` | complete |
| 4 | Harden Function wheel resolution and deployment failure handling | `backend-dev` | complete |
| 5 | Make cleanup report-only and fail-closed | `backend-dev` | complete |
Expand All @@ -27,14 +27,23 @@

## Rollout Gate

Stable publication jobs use `HASTEGEO_PUBLISH_ENABLED == 'true'` and the
protected `hastegeo-release` environment. They also require
`HASTEGEO_RELEASE_APPROVAL_CONFIGURED == 'true'`, which an administrator sets
only after required reviewers are active. Merge with publication disabled,
inspect the first build artifacts, configure required reviewers, then enable
and manually approve the first release.
Stable publication is gated solely by `HASTEGEO_PUBLISH_ENABLED == 'true'`.
Merging a PR into `main` is the release approval: the branch ruleset is active
with no bypass actors and requires an approving review plus passing status
checks, so no commit reaches `main` unreviewed.

Superseded: stable publication originally also required
`HASTEGEO_RELEASE_APPROVAL_CONFIGURED == 'true'` and the protected
`hastegeo-release` environment. That was a bring-up gate — merge with
publication disabled, inspect artifacts, then enable — and it was never turned
on, so no stable wheel published for the pipeline's whole life. Both controls
remain in force for the destructive RC deletion job in `rc-cleanup.yml`.

Same-repository PR RCs publish automatically from trusted `workflow_run` code
and build final development ACR images once. The target environment is selected
by `HASTEGEO_RC_ENVIRONMENT`. Set
`HASTEGEO_RC_PUBLISH_ENABLED=false` only as an emergency kill switch.

Known gap: minor and major stable releases have no automated path. The publisher
accepts only `push` and same-repository `pull_request` upstream events, so a
`workflow_dispatch` build carrying `bump` or `set_version` is never published.
3 changes: 2 additions & 1 deletion spec/features/hastegeo-ci-pipeline/test-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
- Build job permissions are `contents: read`.
- Build checkout sets `persist-credentials: false`.
- Build job receives no `GH_TOKEN`, Azure secrets, or OIDC permission.
- Publish job uses `contents: write`, protected environment, and no PR checkout.
- Publish job uses `contents: write` and no PR checkout. Stable publication
carries no protected environment; the destructive RC deletion job does.
- Image job executes trusted inline Azure commands rather than PR shell scripts.
- Fork PR condition skips publish and image jobs.
- Every external action is pinned to a full SHA.
Expand Down
Loading