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
47 changes: 18 additions & 29 deletions .github/workflows/exact-artifact-sbom-attestation-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ on:
- "tests/test_exact_artifact_sbom_attestation_contract.py"
- "tests/test_exact_artifact_sbom_review_regressions.py"
- "tests/test_verify_exact_artifact_sbom_handoff.py"
- "tests/test_exact_artifact_quality_single_runner.py"
- "docs/doctoring/exact-artifact-sbom-attestation.md"
- "docs/doctoring/exact-artifact-sbom-quality-runner-consolidation-20260903.md"
- "CHANGELOG.md"
- "CHANGELOG.d/20260903-exact-artifact-quality-runner-consolidation.md"
push:
branches: [main]
paths:
Expand All @@ -21,21 +24,24 @@ on:
- "tests/test_exact_artifact_sbom_attestation_contract.py"
- "tests/test_exact_artifact_sbom_review_regressions.py"
- "tests/test_verify_exact_artifact_sbom_handoff.py"
- "tests/test_exact_artifact_quality_single_runner.py"
- "docs/doctoring/exact-artifact-sbom-attestation.md"
- "docs/doctoring/exact-artifact-sbom-quality-runner-consolidation-20260903.md"
- "CHANGELOG.md"
- "CHANGELOG.d/20260903-exact-artifact-quality-runner-consolidation.md"

concurrency:
group: exact-artifact-sbom-attestation-quality-${{ github.event.pull_request.number || github.ref }}
group: exact-artifact-sbom-attestation-quality-${{ github.repository }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
minimum-python-contract:
name: Python 3.10 contract
exact_artifact_quality:
name: Python 3.10 and 3.14 exact artifact contract
runs-on: ubuntu-24.04
timeout-minutes: 10
timeout-minutes: 20
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
Expand Down Expand Up @@ -64,28 +70,8 @@ jobs:
scripts/ci/verify_exact_artifact_sbom_handoff.py \
tests/test_exact_artifact_sbom_attestation_contract.py \
tests/test_exact_artifact_sbom_review_regressions.py \
tests/test_verify_exact_artifact_sbom_handoff.py

exact-contract:
name: Python 3.14 exact contract and complete coverage
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit

- name: Checkout exact contributor head
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha || github.sha }}

- name: Verify exact workflow source checkout
env:
EXPECTED_SOURCE_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: test "$(git rev-parse HEAD)" = "$EXPECTED_SOURCE_SHA"
tests/test_verify_exact_artifact_sbom_handoff.py \
tests/test_exact_artifact_quality_single_runner.py

- name: Set up current stable Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
Expand All @@ -103,17 +89,20 @@ jobs:
python -m coverage run --branch -m pytest -q \
tests/test_exact_artifact_sbom_attestation_contract.py \
tests/test_exact_artifact_sbom_review_regressions.py \
tests/test_verify_exact_artifact_sbom_handoff.py
tests/test_verify_exact_artifact_sbom_handoff.py \
tests/test_exact_artifact_quality_single_runner.py
python -m coverage report \
--include=scripts/ci/verify_exact_artifact_sbom_handoff.py \
--show-missing \
--fail-under=100
python -m interrogate --fail-under=100 scripts/ci/verify_exact_artifact_sbom_handoff.py

- name: Compile production and contract files
- name: Compile production and contract files on Python 3.14
run: |
python -m compileall -q \
scripts/ci/verify_exact_artifact_sbom_handoff.py \
tests/test_exact_artifact_sbom_attestation_contract.py \
tests/test_exact_artifact_sbom_review_regressions.py \
tests/test_verify_exact_artifact_sbom_handoff.py
tests/test_verify_exact_artifact_sbom_handoff.py \
tests/test_exact_artifact_quality_single_runner.py
git diff --check
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## Changed

- Exact Artifact SBOM Attestation 품질 검증의 Python 3.10 compile job과 Python 3.14
coverage job을 한 exact-head runner로 통합했습니다.
- runner 부팅·harden-runner·checkout을 실행당 2회에서 1회로 줄이고 최소 Python
호환성, branch coverage 100%, docstring 100% 계약은 보존했습니다.
- PR concurrency를
`exact-artifact-sbom-attestation-quality-{repository}-{PR번호}`와
`cancel-in-progress: true`로 고정했습니다.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Exact Artifact SBOM 품질 runner 통합

- 기준: `ContextualWisdomLab/.github@5afbf58cc62c8ff12a57c60d426d1352307fcd04`
- 확인 시점: 2026-09-03 KST
- 상태: 구현 및 current-head 검증 대상

## 문제

`Exact Artifact SBOM Attestation Quality`는 동일 source revision을 검증하기 위해
Python 3.10 compile job과 Python 3.14 coverage job을 별도 runner에 배치했다. 그 결과
한 workflow run마다 runner 부팅, harden-runner, checkout, exact-head 검증이 두 번
수행됐다.

Python 3.10 경로는 compile만 수행하며 Python 3.14 경로와 병렬 결과를 합성하지 않는다.
따라서 두 job 사이에 독립 장애 격리나 병렬 계산상 이점이 없고, 60-job ceiling에서는
별도 runner가 queue slot과 boot 시간을 추가 소비한다.

## 선택

두 Python 검증을 하나의 `exact_artifact_quality` job에서 순차 실행한다.

1. runner hardening, checkout, exact-head 검증은 한 번만 수행한다.
2. Python 3.10을 설치해 production과 contract 파일을 compile한다.
3. 같은 runner에서 Python 3.14를 활성화해 hash-locked tooling을 설치한다.
4. 기존 세 contract suite와 새 workflow regression을 실행한다.
5. verifier branch coverage 100%, docstring 100%, Python 3.14 compile을 그대로 보존한다.
6. PR concurrency는
`exact-artifact-sbom-attestation-quality-{repository}-{PR번호}`를 사용하고
`cancel-in-progress: true`로 같은 PR의 구형 품질 실행만 취소한다.
7. push 검증에서는 PR 번호 대신 ref를 사용해 default-branch revision별 품질 검증을
이어간다.
8. API polling, runner-held sleep, manual dispatch를 두지 않는다.

## RED와 GREEN 계약

`tests/test_exact_artifact_quality_single_runner.py`는 다음을 고정한다.

- `runs-on`, harden-runner, checkout이 각각 정확히 1회
- Python 3.10과 3.14 setup이 각각 1회
- 3.10 compile이 3.14 coverage보다 먼저 실행
- concurrency group에 workflow 이름, repository, PR 번호가 포함
- `cancel-in-progress: true`
- predecessor의 production 및 contract 파일 전부 보존
- branch coverage·docstring threshold 100% 보존
- `gh api`, `sleep`, `workflow_dispatch` 없음

## 효과

한 workflow run의 runner job 수는 2개에서 1개로 50% 줄어든다. hardening과 checkout도
각각 2회에서 1회로 줄어든다. Python runtime setup은 최소 지원 버전과 현재 버전을
실제로 검증해야 하므로 2회를 유지하지만, 두 setup은 동일 runner에서 수행된다.

이 변경은 SBOM publication workflow나 attestation mutation을 취소하지 않는다. 오직
품질 검증 workflow만 stale-run cancellation 대상이다.

## Rollback

문제가 발견되면 이 commit 전체를 revert해 두 job 구조와 기존 context를 함께 복원한다.
Python 3.10 compile 또는 Python 3.14 coverage 중 하나만 제거하는 부분 rollback은 하지
않는다.
99 changes: 99 additions & 0 deletions tests/test_exact_artifact_quality_single_runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"""Contracts for the single-runner exact artifact quality workflow."""

from __future__ import annotations

import re
from pathlib import Path


REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
WORKFLOW_PATH = (
REPOSITORY_ROOT
/ ".github"
/ "workflows"
/ "exact-artifact-sbom-attestation-quality.yml"
)


def _workflow_text() -> str:
"""Return the exact artifact quality workflow source."""

return WORKFLOW_PATH.read_text(encoding="utf-8")


def test_exact_artifact_quality_uses_one_runner_boot() -> None:
"""Compile both supported Python versions without a second runner job."""

workflow = _workflow_text()

assert workflow.count("runs-on:") == 1
assert workflow.count("step-security/harden-runner@") == 1
assert workflow.count("actions/checkout@") == 1
assert workflow.count('python-version: "3.10"') == 1
assert workflow.count('python-version: "3.14"') == 1


def test_minimum_python_compile_precedes_current_python_contracts() -> None:
"""Keep the Python 3.10 syntax gate before the Python 3.14 test suite."""

workflow = _workflow_text()

minimum_setup = workflow.index("- name: Set up minimum supported Python")
minimum_compile = workflow.index(
"- name: Compile production and contracts on Python 3.10"
)
current_setup = workflow.index("- name: Set up current stable Python")
current_contract = workflow.index(
"- name: Run exact contracts with complete verifier branch coverage"
)

assert minimum_setup < minimum_compile < current_setup < current_contract


def test_pr_concurrency_uses_workflow_repository_and_pr_identity() -> None:
"""Cancel only an older run of this workflow for the same repository and PR."""

workflow = _workflow_text()
concurrency = workflow.split("concurrency:", 1)[1].split(
"permissions:", 1
)[0]

assert (
"group: exact-artifact-sbom-attestation-quality-"
"${{ github.repository }}-"
"${{ github.event.pull_request.number || github.ref }}"
in concurrency
)
assert "cancel-in-progress: true" in concurrency
assert "github.sha" not in concurrency
assert "pull_request.head.sha" not in concurrency


def test_successor_preserves_all_exact_artifact_contracts() -> None:
"""Retain every predecessor test, coverage, docstring, and syntax gate."""

workflow = _workflow_text()

for required_path in (
"scripts/ci/verify_exact_artifact_sbom_handoff.py",
"tests/test_exact_artifact_sbom_attestation_contract.py",
"tests/test_exact_artifact_sbom_review_regressions.py",
"tests/test_verify_exact_artifact_sbom_handoff.py",
"tests/test_exact_artifact_quality_single_runner.py",
):
assert required_path in workflow

assert "coverage run --branch" in workflow
assert "--fail-under=100" in workflow
assert "interrogate --fail-under=100" in workflow
assert workflow.count("compileall -q") == 2


def test_quality_runner_has_no_polling_or_runner_held_sleep() -> None:
"""Keep the quality lane deterministic and free of API polling waits."""

workflow = _workflow_text()

assert "gh api" not in workflow
assert re.search(r"(?m)^[ \t]*sleep[ \t]+", workflow) is None
assert "workflow_dispatch:" not in workflow
Loading