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
35 changes: 35 additions & 0 deletions .github/scripts/verify_main_ci_success.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euo pipefail

workflow="${CI_WORKFLOW:-ci.yml}"
branch="${VERIFY_BRANCH:-main}"
repository="${GITHUB_REPOSITORY:?GITHUB_REPOSITORY is required}"

if ! command -v gh >/dev/null 2>&1; then
echo "gh CLI is required to verify main CI before publish." >&2
exit 1
fi

if [ -z "${GH_TOKEN:-}" ] && [ -z "${GITHUB_TOKEN:-}" ]; then
echo "GH_TOKEN or GITHUB_TOKEN is required to verify main CI before publish." >&2
exit 1
fi

export GH_TOKEN="${GH_TOKEN:-${GITHUB_TOKEN}}"

read -r status conclusion <<EOF
$(gh run list \
--repo "${repository}" \
--workflow "${workflow}" \
--branch "${branch}" \
--limit 1 \
--json status,conclusion \
--jq '.[0] | "\(.status // "") \(.conclusion // "")"' 2>/dev/null || echo " missing")
EOF

if [ "${status}" != "completed" ] || [ "${conclusion}" != "success" ]; then
echo "Latest ${branch} CI (${workflow}) must be completed with success before publish; got status=${status:-unknown} conclusion=${conclusion:-unknown}." >&2
exit 1
fi

echo "Verified latest ${branch} ${workflow} run succeeded."
7 changes: 7 additions & 0 deletions .github/workflows/publish-hk-snapshot-artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 60
permissions:
actions: read
contents: read
id-token: write
env:
Expand Down Expand Up @@ -136,6 +137,12 @@ jobs:
- name: Checkout
uses: actions/checkout@v6

- name: Verify main CI succeeded before publish
if: github.event_name == 'workflow_dispatch' && inputs.execute_publish == true
env:
GH_TOKEN: ${{ github.token }}
run: bash .github/scripts/verify_main_ci_success.sh

- name: Set up Python
uses: actions/setup-python@v6
with:
Expand Down
28 changes: 28 additions & 0 deletions tests/test_publish_workflow_ci_gate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Workflow config tests for publish CI gating."""

from __future__ import annotations

from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
PUBLISH_WORKFLOW = ROOT / ".github/workflows/publish-hk-snapshot-artifacts.yml"
VERIFY_SCRIPT = ROOT / ".github/scripts/verify_main_ci_success.sh"


def test_publish_hk_snapshot_artifacts_requires_main_ci_before_live_publish() -> None:
workflow = PUBLISH_WORKFLOW.read_text(encoding="utf-8")

assert "actions: read" in workflow
assert "Verify main CI succeeded before publish" in workflow
assert "bash .github/scripts/verify_main_ci_success.sh" in workflow
assert "inputs.execute_publish == true" in workflow


def test_verify_main_ci_success_script_checks_latest_main_run() -> None:
script = VERIFY_SCRIPT.read_text(encoding="utf-8")

assert 'workflow="${CI_WORKFLOW:-ci.yml}"' in script
assert 'branch="${VERIFY_BRANCH:-main}"' in script
assert "gh run list" in script
assert 'conclusion}" != "success"' in script