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
59 changes: 18 additions & 41 deletions .github/workflows/codex-linux-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
workflow_dispatch:
push:
tags:
- v1.1.0-codex.1
- v1.1.0-codex.2

concurrency:
group: codex-linux-release-${{ github.ref }}
Expand All @@ -16,11 +16,11 @@ permissions:
contents: read

env:
RELEASE_TAG: v1.1.0-codex.1
ARTIFACT_NAME: agentcookie_1.1.0-codex.1_linux_amd64
SBOM_NAME: agentcookie_1.1.0-codex.1_linux_amd64.cdx.json
PROVENANCE_BUNDLE_NAME: agentcookie_1.1.0-codex.1_linux_amd64.provenance.json
SBOM_ATTESTATION_BUNDLE_NAME: agentcookie_1.1.0-codex.1_linux_amd64.sbom-attestation.json
RELEASE_TAG: v1.1.0-codex.2
ARTIFACT_NAME: agentcookie_1.1.0-codex.2_linux_amd64
SBOM_NAME: agentcookie_1.1.0-codex.2_linux_amd64.cdx.json
PROVENANCE_BUNDLE_NAME: agentcookie_1.1.0-codex.2_linux_amd64.provenance.json
SBOM_ATTESTATION_BUNDLE_NAME: agentcookie_1.1.0-codex.2_linux_amd64.sbom-attestation.json
SIGNER_WORKFLOW: chrisl10/agentcookie/.github/workflows/codex-linux-release.yml
# actions/checkout writes safe.directory into a temporary HOME that is
# removed before later container steps. Keep Git trust scoped to this exact
Expand Down Expand Up @@ -154,55 +154,40 @@ jobs:
retention-days: 14

release-preflight:
name: prove merged tag and runtime release controls
name: prove merged tag before release approval
needs: promote
if: github.event_name == 'push' && github.ref == 'refs/tags/v1.1.0-codex.1'
if: github.event_name == 'push' && github.ref == 'refs/tags/v1.1.0-codex.2'
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
actions: read
contents: read
deployments: read
steps:
- name: Checkout the exact release tag
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
persist-credentials: false

# The reviewer rule is repository runtime state and cannot be declared
# in workflow YAML. Fail closed unless the API proves it exists.
- name: Verify merged-tag and external release controls
env:
GH_TOKEN: ${{ github.token }}
- name: Verify merged tag
run: |
test "${GITHUB_REPOSITORY}" = 'chrisl10/agentcookie'
test "${GITHUB_REF}" = "refs/tags/${RELEASE_TAG}"
test "${GITHUB_SHA}" = "$(git rev-list -n 1 "refs/tags/${RELEASE_TAG}")"
git fetch --no-tags --prune origin \
'+refs/heads/main:refs/remotes/origin/main'
git merge-base --is-ancestor "${GITHUB_SHA}" refs/remotes/origin/main
reviewer_count="$(gh api \
"repos/${GITHUB_REPOSITORY}/environments/prd005-release" \
--jq '[.protection_rules[]? | select(.type == "required_reviewers") | .reviewers[]?] | length')"
test "$reviewer_count" -ge 1
immutable="$(gh api \
-H 'X-GitHub-Api-Version: 2026-03-10' \
"repos/${GITHUB_REPOSITORY}/immutable-releases" \
--jq .enabled)"
test "$immutable" = true
{
echo '### PRD-005 release preflight'
echo "- Candidate commit: ${GITHUB_SHA}"
echo '- Candidate is merged into current origin/main: yes'
echo "- prd005-release required reviewers: ${reviewer_count}"
echo "- Immutable releases enabled: ${immutable}"
echo '- Protected-environment approval: required before publication'
echo '- Immutable-release status: verified after release creation'
} >> "$GITHUB_STEP_SUMMARY"

attest:
name: attest exact tag assets
needs: [promote, release-preflight]
if: github.event_name == 'push' && github.ref == 'refs/tags/v1.1.0-codex.1'
if: github.event_name == 'push' && github.ref == 'refs/tags/v1.1.0-codex.2'
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
Expand All @@ -222,17 +207,17 @@ jobs:
uses: actions/attest@c32b4b8b198b65d0bd9d63490e847ff7b53989d4 # v4.0.0
with:
subject-path: |
dist/agentcookie_1.1.0-codex.1_linux_amd64
dist/agentcookie_1.1.0-codex.1_linux_amd64.cdx.json
dist/agentcookie_1.1.0-codex.2_linux_amd64
dist/agentcookie_1.1.0-codex.2_linux_amd64.cdx.json
dist/LICENSE
dist/BUILD-PROVENANCE.txt

- name: Attest binary with CycloneDX SBOM
id: sbom_attestation
uses: actions/attest@c32b4b8b198b65d0bd9d63490e847ff7b53989d4 # v4.0.0
with:
subject-path: dist/agentcookie_1.1.0-codex.1_linux_amd64
sbom-path: dist/agentcookie_1.1.0-codex.1_linux_amd64.cdx.json
subject-path: dist/agentcookie_1.1.0-codex.2_linux_amd64
sbom-path: dist/agentcookie_1.1.0-codex.2_linux_amd64.cdx.json

- name: Stage canonical offline attestation bundles
run: |
Expand All @@ -256,7 +241,7 @@ jobs:
publish:
name: publish approved immutable release
needs: attest
if: github.event_name == 'push' && github.ref == 'refs/tags/v1.1.0-codex.1'
if: github.event_name == 'push' && github.ref == 'refs/tags/v1.1.0-codex.2'
environment: prd005-release
runs-on: ubuntu-24.04
timeout-minutes: 10
Expand All @@ -272,7 +257,7 @@ jobs:
fetch-depth: 0
persist-credentials: false

- name: Reverify merged tag and external release controls
- name: Reverify merged tag after protected approval
env:
GH_TOKEN: ${{ github.token }}
run: |
Expand All @@ -282,14 +267,6 @@ jobs:
git fetch --no-tags --prune origin \
'+refs/heads/main:refs/remotes/origin/main'
git merge-base --is-ancestor "${GITHUB_SHA}" refs/remotes/origin/main
reviewer_count="$(gh api \
"repos/${GITHUB_REPOSITORY}/environments/prd005-release" \
--jq '[.protection_rules[]? | select(.type == "required_reviewers") | .reviewers[]?] | length')"
test "$reviewer_count" -ge 1
test "$(gh api \
-H 'X-GitHub-Api-Version: 2026-03-10' \
"repos/${GITHUB_REPOSITORY}/immutable-releases" \
--jq .enabled)" = true
if gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "release already exists: ${RELEASE_TAG}" >&2
exit 1
Expand Down
12 changes: 6 additions & 6 deletions release/codex-linux-release.env
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Reviewed release locks for the ReachLynk hardened Linux sink.
# This file is sourced by scripts/codex-linux-release.sh.

CODEX_RELEASE_VERSION="1.1.0-codex.1"
CODEX_RELEASE_TAG="v1.1.0-codex.1"
CODEX_ARTIFACT_NAME="agentcookie_1.1.0-codex.1_linux_amd64"
CODEX_SBOM_NAME="agentcookie_1.1.0-codex.1_linux_amd64.cdx.json"
CODEX_PROVENANCE_BUNDLE_NAME="agentcookie_1.1.0-codex.1_linux_amd64.provenance.json"
CODEX_SBOM_ATTESTATION_BUNDLE_NAME="agentcookie_1.1.0-codex.1_linux_amd64.sbom-attestation.json"
CODEX_RELEASE_VERSION="1.1.0-codex.2"
CODEX_RELEASE_TAG="v1.1.0-codex.2"
CODEX_ARTIFACT_NAME="agentcookie_1.1.0-codex.2_linux_amd64"
CODEX_SBOM_NAME="agentcookie_1.1.0-codex.2_linux_amd64.cdx.json"
CODEX_PROVENANCE_BUNDLE_NAME="agentcookie_1.1.0-codex.2_linux_amd64.provenance.json"
CODEX_SBOM_ATTESTATION_BUNDLE_NAME="agentcookie_1.1.0-codex.2_linux_amd64.sbom-attestation.json"
CODEX_SIGNER_WORKFLOW="chrisl10/agentcookie/.github/workflows/codex-linux-release.yml"

CODEX_UPSTREAM_REPOSITORY="https://github.com/mvanhorn/agentcookie.git"
Expand Down
18 changes: 10 additions & 8 deletions scripts/codex-linux-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ check_candidate_delta() {

check_locks() {
cd "$REPO_ROOT"
[[ "$CODEX_RELEASE_VERSION" == "1.1.0-codex.1" ]] || die "unexpected release version"
[[ "$CODEX_RELEASE_VERSION" == "1.1.0-codex.2" ]] || die "unexpected release version"
[[ "$CODEX_RELEASE_TAG" == "v${CODEX_RELEASE_VERSION}" ]] || die "release tag/version mismatch"
[[ "$CODEX_ARTIFACT_NAME" == "agentcookie_${CODEX_RELEASE_VERSION}_linux_amd64" ]] || die "artifact name mismatch"
[[ "$CODEX_SBOM_NAME" == "${CODEX_ARTIFACT_NAME}.cdx.json" ]] || die "SBOM asset name mismatch"
Expand Down Expand Up @@ -207,17 +207,19 @@ check_locks() {
# shellcheck disable=SC2016 # Match the literal Actions expression syntax.
! grep -Fq 'if: ${{ secrets.' .github/workflows/release.yml \
|| die "upstream release workflow contains invalid direct secret conditions"
grep -Fq 'environment: prd005-release' "$WORKFLOW_FILE" \
[[ "$(grep -Fxc ' environment: prd005-release' "$WORKFLOW_FILE")" -eq 1 ]] \
|| die "workflow protected release environment is absent"
# shellcheck disable=SC2016 # Verify the literal Actions runtime expression.
grep -Fq 'git merge-base --is-ancestor "${GITHUB_SHA}" refs/remotes/origin/main' "$WORKFLOW_FILE" \
|| die "workflow does not prove the release commit is merged into origin/main"
grep -Fq 'environments/prd005-release' "$WORKFLOW_FILE" \
|| die "workflow does not inspect the runtime release environment"
grep -Fq 'required_reviewers' "$WORKFLOW_FILE" \
|| die "workflow does not require runtime reviewer protection"
[[ "$(grep -Fxc ' actions: read' "$WORKFLOW_FILE")" -eq 2 ]] \
|| die "environment API jobs do not have the exact actions: read permission"
! grep -Fq 'environments/prd005-release' "$WORKFLOW_FILE" \
|| die "workflow attempts a repository-admin environment API read"
! grep -Fq 'required_reviewers' "$WORKFLOW_FILE" \
|| die "workflow attempts to infer protected-environment admission"
[[ "$(grep -Fxc ' actions: read' "$WORKFLOW_FILE")" -eq 1 ]] \
|| die "publisher does not have the exact artifact-read permission"
grep -Fq -- '--json isImmutable --jq .isImmutable' "$WORKFLOW_FILE" \
|| die "publisher does not prove the created release is immutable"
[[ "$(grep -Fc 'outputs.bundle-path' "$WORKFLOW_FILE")" -eq 2 ]] \
|| die "workflow does not retain both offline attestation bundles"
# shellcheck disable=SC2016 # Verify the literal Actions shell expansion.
Expand Down
Loading