fix(ci): use explicit Ubuntu 24.04 runners - #161
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (29)
📝 WalkthroughWalkthrough저장소 소유 품질 검증을 여러 워크플로에서 ChangesCI 검증 통합
Estimated code review effort: 4 (Complex) | ~45 minutes Merge Risk: 🟡 Moderate · up to The migration itself is correct, but its new regression guard does not reliably prevent workflows from returning to unsupported or dynamic runner selectors. Strengthen the test before merge. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (14 skipped: 14 unsupported.) ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Fresh owner-path revalidation on 2026-09-03: the previously failed exact-head Security Scan run |
|
@coderabbitai review Please review exact head |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
head='8a4e82ede3abd008362c6b126742ab476f11d3a1'
base='ef1b143368cb6249c9520ca8cae10ebe844a5aa1'
echo '== Checked-out HEAD and requested commit =='
git rev-parse HEAD
git cat-file -t "$head"
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$head"
echo
echo '== Parent ancestry and merge-base =='
git merge-base --is-ancestor "$base" "$head" && echo "base_is_ancestor=true" || echo "base_is_ancestor=false"
git merge-base "$head^1" "$head^2"
git diff --name-status "$base" "$head"
echo
echo '== Workflow files and runner selectors at requested head =='
git ls-tree -r --name-only "$head" | awk '/^\.github\/workflows\/.*\.(yml|yaml)$/'
git grep -nE '^[[:space:]]*runs-on:[[:space:]]*' "$head" -- .github/workflows || true
echo
echo '== Test and CI wiring related to runner-image validation =='
git ls-tree -r --name-only "$head" | grep -E '(^|/)(test_github_actions_runner_image\.py|.*foundation.*\.(yml|yaml))$' || true
git grep -nE 'test_github_actions_runner_image|github_actions_runner_image' "$head" -- ':!manifest.json' ':!recovery-manifest.json' || true
echo
echo '== Manifest entry names and hash verification candidates =='
git ls-tree -r --name-only "$head" | grep -E '(^|/)(recovery-)?manifest\.json$' || true
for f in manifest.json recovery-manifest.json; do
if git cat-file -e "$head:$f" 2>/dev/null; then
echo "-- $f --"
git show "$head:$f" | jq -r '
paths(scalars) as $p
| select(($p | map(tostring) | join("/") | test("\\.github/workflows/")))
| [$p | map(tostring) | join("/"), getpath($p)] | `@tsv`
' || true
fi
doneLength of output: 5483 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='ContextualWisdomLab/Orgmetra'
pr='161'
echo '== Pull request identity, refs, mergeability, and draft state =='
gh pr view "$pr" --repo "$repo" --json number,state,isDraft,mergeable,headRefName,headRefOid,baseRefName,baseRefOid,url
echo
echo '== Current checks for the PR head =='
gh pr checks "$pr" --repo "$repo" --json name,state,link,workflow,bucket 2>&1 || true
echo
echo '== Reviews and review threads summary =='
gh pr view "$pr" --repo "$repo" --json reviews,reviewDecision,comments
echo
echo '== Repository rulesets and branch protection for develop =='
gh api "repos/$repo/rulesets?includes_parents=true" --paginate 2>&1 || true
gh api "repos/$repo/branches/develop/protection" 2>&1 || trueLength of output: 15539 🏁 Script executed: #!/bin/bash
set -euo pipefail
head='8a4e82ede3abd008362c6b126742ab476f11d3a1'
echo '== Relevant file structure =='
ast-grep outline tests/test_github_actions_runner_image.py --items all
ast-grep outline .github/workflows/foundation-ci.yml --items all
echo
echo '== Runner-image regression test =='
git show "$head:tests/test_github_actions_runner_image.py" | nl -ba
echo
echo '== Foundation CI workflow =='
git show "$head:.github/workflows/foundation-ci.yml" | nl -ba
echo
echo '== Manifest schemas and changed sections =='
for f in manifest.json recovery-manifest.json; do
echo "-- $f: top-level type and keys --"
git show "$head:$f" > "/tmp/$f"
jq -r 'type, (if type == "object" then keys[] else empty end)' "/tmp/$f"
echo "-- workflow-related text --"
rg -n -i -C2 'workflow|sha256|digest|hash|\.github' "/tmp/$f" || true
echo "-- diff from first parent --"
git diff --unified=3 "$head^1" "$head" -- "$f"
done
echo
echo '== Merge-parent diffs and workflow-selector delta =='
echo '-- merge commit relative to first parent --'
git diff --stat "$head^1" "$head"
echo '-- merge commit relative to second parent --'
git diff --stat "$head^2" "$head"
echo '-- remaining ubuntu-latest selectors at head --'
git grep -n -i 'ubuntu-latest' "$head" -- .github/workflows || true
echo '-- changed runner selector lines, base to head --'
git diff --unified=1 "$head^2" "$head" -- .github/workflowsLength of output: 2185 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='ContextualWisdomLab/Orgmetra'
pr='161'
head='8a4e82ede3abd008362c6b126742ab476f11d3a1'
echo '== Head commit and parent commit API data =='
gh api "repos/$repo/commits/$head" --jq '{sha,parents:[.parents[].sha],verification,stats,files:[.files[].filename]}'
echo
echo '== Pull request commits in API order =='
gh api "repos/$repo/pulls/$pr/commits?per_page=100" --paginate --jq '.[] | {sha,parents:[.parents[].sha],message:.commit.message}'
echo
echo '== Head ref history events visible through repository events =='
gh api "repos/$repo/events?per_page=100" --paginate --jq --arg head "$head" '
.[] | select(.type == "PushEvent" and (.payload.head // "") == $head)
| {created_at,actor:.actor.login,ref:.payload.ref,before:.payload.before,head:.payload.head,forced:(.payload.forced // false)}
' 2>&1 || trueLength of output: 4159 🏁 Script executed: #!/bin/bash
set -euo pipefail
head='8a4e82ede3abd008362c6b126742ab476f11d3a1'
echo '== Runner-image regression test =='
git show "$head:tests/test_github_actions_runner_image.py" | sed -n '=' | sed 'N;s/\n/\t/'
echo
echo '== Foundation CI workflow =='
git show "$head:.github/workflows/foundation-ci.yml" | sed -n '=' | sed 'N;s/\n/\t/'
echo
echo '== Workflow selector and regression-test diff from protected base =='
git diff --unified=3 "$head^2" "$head" -- .github/workflows tests/test_github_actions_runner_image.py
echo
echo '== Manifest structures =='
for f in manifest.json recovery-manifest.json; do
echo "-- $f --"
git show "$head:$f" > "/tmp/${f}"
jq -C . "/tmp/${f}" | sed -n '1,240p'
done
echo
echo '== Verify SHA-256 entries that name repository files =='
python3 - <<'PY'
import hashlib
import json
import subprocess
head = "8a4e82ede3abd008362c6b126742ab476f11d3a1"
manifest_files = ("manifest.json", "recovery-manifest.json")
def git_bytes(path):
return subprocess.check_output(["git", "show", f"{head}:{path}"])
def walk(value, path=()):
if isinstance(value, dict):
for key, child in value.items():
yield from walk(child, path + (str(key),))
elif isinstance(value, list):
for index, child in enumerate(value):
yield from walk(child, path + (str(index),))
else:
yield path, value
for manifest_path in manifest_files:
doc = json.loads(git_bytes(manifest_path))
print(f"-- {manifest_path} --")
candidates = []
for json_path, value in walk(doc):
text_path = "/".join(json_path)
if isinstance(value, str) and len(value) == 64 and all(c in "0123456789abcdef" for c in value.lower()):
candidates.append((text_path, value))
print(f"sha256_scalar_count={len(candidates)}")
for text_path, expected in candidates:
possible_paths = [p for p in text_path.split("/") if p.endswith((".yml", ".yaml", ".py", ".sh", ".json"))]
print(f"entry={text_path} digest={expected} possible_file_components={possible_paths}")
PY
echo
echo '== All textual ubuntu-latest references under repository workflows =='
git grep -n -i 'ubuntu-latest' "$head" -- .github/workflows || true
echo '== All runs-on values under repository workflows =='
git grep -nE 'runs-on:|runs-on[[:space:]]*:' "$head" -- .github/workflows || trueLength of output: 40935 🏁 Script executed: #!/bin/bash
set -euo pipefail
repo='ContextualWisdomLab/Orgmetra'
head='8a4e82ede3abd008362c6b126742ab476f11d3a1'
echo '== Ref update events that are visible to this token =='
gh api "repos/$repo/events?per_page=100" \
--jq '.[] | select(.type == "PushEvent") | {created_at,actor:.actor.login,ref:.payload.ref,before:.payload.before,head:.payload.head,forced:(.payload.forced // false)}' \
2>&1 | grep -F -C2 "$head" || true
echo
echo '== Exact head commit comparison to both parents =='
gh api "repos/$repo/compare/${head}^1...$head" --jq '{status,ahead_by,behind_by,total_commits,files:[.files[] | {filename,status,additions,deletions}]}'
gh api "repos/$repo/compare/${head}^2...$head" --jq '{status,ahead_by,behind_by,total_commits,files:[.files[] | {filename,status,additions,deletions}]}'Length of output: 2777 🏁 Script executed: #!/bin/bash
set -euo pipefail
head='8a4e82ede3abd008362c6b126742ab476f11d3a1'
python3 - <<'PY'
import hashlib
import json
import subprocess
import sys
head = "8a4e82ede3abd008362c6b126742ab476f11d3a1"
manifest_paths = ("manifest.json", "recovery-manifest.json")
failures = []
for manifest_path in manifest_paths:
manifest = json.loads(subprocess.check_output(["git", "show", f"{head}:{manifest_path}"]))
records = manifest.get("files")
if not isinstance(records, list):
failures.append(f"{manifest_path}: 'files' is not a list")
continue
checked = 0
for index, record in enumerate(records):
where = f"{manifest_path}: files[{index}]"
if not isinstance(record, dict) or not all(key in record for key in ("path", "sha256", "bytes", "lines")):
failures.append(f"{where}: missing required record fields")
continue
path = record["path"]
try:
content = subprocess.check_output(["git", "show", f"{head}:{path}"])
except subprocess.CalledProcessError:
failures.append(f"{where}: missing exact-head file {path}")
continue
actual = {
"sha256": hashlib.sha256(content).hexdigest(),
"bytes": len(content),
"lines": content.count(b"\n"),
}
for field, actual_value in actual.items():
if record[field] != actual_value:
failures.append(
f"{where}: {path} {field} expected={record[field]!r} actual={actual_value!r}"
)
checked += 1
print(f"{manifest_path}: checked_records={checked}")
if failures:
print("manifest_verification=FAIL")
print("\n".join(failures))
sys.exit(1)
print("manifest_verification=PASS")
PY
echo '== Current exact-head check-state summary =='
gh pr checks 161 --repo ContextualWisdomLab/Orgmetra \
--json name,state,bucket,workflow \
--jq 'group_by(.bucket) | map({bucket: .[0].bucket, count: length, states: (group_by(.state) | map({state: .[0].state, count: length})), workflows: ([.[].workflow] | unique)})'Length of output: 3093 🏁 Script executed: #!/bin/bash
set -u
echo '== Current exact-head check-state summary =='
gh pr checks 161 --repo ContextualWisdomLab/Orgmetra \
--json name,state,bucket,workflow \
--jq 'group_by(.bucket) | map({bucket: .[0].bucket, count: length, states: (group_by(.state) | map({state: .[0].state, count: length})), workflows: ([.[].workflow] | unique)})' \
2>&1 || true
echo '== Foundation CI run identity and status =='
gh api 'repos/ContextualWisdomLab/Orgmetra/actions/runs/33723646906' \
--jq '{id,head_sha,event,status,conclusion,run_attempt,workflow_id,created_at,updated_at}' \
2>&1 || trueLength of output: 1905
Finding
Verified
Current evidence Foundation CI run
|
Preserve the complete governed test-portability delta from 60ad07a while adopting protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f using GitHub's conflict-free exact merge tree. Preserve #161 repository-workflow consolidation and require fresh exact-head acceptance. No force-push, gate weakening, foreign-owner source copy, or release claim.
Preserve the complete governed compensation-change review delta from b9e487c while adopting protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f using GitHub's conflict-free exact merge tree. Preserve #161 repository-workflow consolidation and reacquire every applicable exact-head gate. No force-push, gate weakening, foreign-owner source copy, or release claim.
Preserve the complete governed candidate-offer response evidence delta from a72463a while adopting protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f using GitHub's conflict-free exact merge tree. Preserve #161 repository-workflow consolidation and keep dependency-first child #108 unmerged until this parent integrates normally. No force-push, gate weakening, foreign-owner source copy, or release claim.
Exact hosted Foundation run 34005848591 exposed a semantic protected-parent adoption defect: the feature branch retained the package-specific compensation review workflow even though protected #161 had consolidated local quality admission into Foundation CI. That extra leaf workflow violated the explicit runner/workflow inventory before validation or package tests could run. Retire the leaf workflow, run the compensation-review suite directly from canonical Foundation CI, preserve the package's exact 100% statement/branch coverage contract, add a regression against leaf-workflow resurrection, update traceability/changelog, and reseal the Foundation manifest entry for the final bytes. No production compensation logic, database contract, HR domain truth, coverage threshold, or required central gate is weakened.
Preserve the People API telemetry delta while adopting protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f. Keep #161 repository-owned workflow consolidation intact; no retired package-local quality workflow is reintroduced.
Adopt current protected develop without force-pushing or changing the validated request-budget delta. Preserve the protected #161 workflow consolidation and retain the bounded pre-authentication metadata contracts. Signed-off-by: Seongho Bae <me@seonghobae.me>
Outcome\n\nThis PR remains the existing repository-owner lane for the explicit Ubuntu 24.04 runner repair and now also removes the structural GitHub Actions admission bottleneck without weakening required gates.\n\n- Compared repository workflows with ContextualWisdomLab/.github@7696915.\n- Preserved organization-owned PR Governance, Dependency Review, Close Empty, CodeQL, Security, SAST, Strix, OpenCode, and Noema coverage; no repository-local duplicate remains.\n- Disabled 91 stale workflow registrations whose files no longer exist on the default branch, reducing active registrations from 106 to 15 while preserving the 12 then-current files and three dynamic workflows.\n- Consolidated ten repository-owned domain quality workflows into the single Foundation CI job. The separately owned recovery rehearsal remains path-scoped.\n- Reduced repository workflow files from 12 to 2: foundation-ci.yml and recovery-rehearsal-quality.yml.\n\n## Concurrency and trigger contract\n\nBoth remaining workflows use a fixed workflow name, repository, and pull-request number group, with a unique run-id fallback outside pull requests. Cancellation is enabled only for pull_request runs; push and manual runs are never cancelled. No build, publish, release, deploy, or migration executor is cancelled.\n\nFoundation CI now runs only for pull requests to develop, pushes to develop, and manual dispatch. Recovery remains limited to its workflow, script, migrations, traceability document, manifest, and test.\n\n## Preserved gates and P1 repairs\n\nFoundation CI still checks out the exact candidate, compiles owned Python, validates the foundation pack, enforces hash-locked test dependencies, runs all ten Python package/service suites, and executes every PostgreSQL contract.\n\nThe PostgreSQL sequence now:\n\n1. Starts a fresh digest-pinned PostgreSQL container for each of 13 base contracts.\n2. Publishes a loopback-only dynamic port, resolves the actual host port, and proves host connectivity with SELECT 1.\n3. Runs the job-analysis snapshot contract and schema-hardening contract against the same container, database URL, and dynamic port.\n\nThis retains 14 PostgreSQL checks while replacing the old 13-way job matrix with sequential isolated execution in one Foundation CI job.\n\n## Exact authority and local verification\n\n- Protected base: develop@ef1b143368cb6249c9520ca8cae10ebe844a5aa1\n- Current head: 0cc583f\n- Commit parent / prior remote head: f795f66\n- Push: ordinary non-force fast-forward\n\nFresh verification after the final independent-review correction:\n\n- PostgreSQL: 14/14 passed; snapshot and schema-hardening shared one container and port.\n- Python 3.14.6: 819 passed; every owned package/service retained 100% statement and branch coverage.\n- npm run validate: 55/55 passed.\n- Runner/concurrency contracts: 7/7 passed.\n- Foundation dependency hygiene: passed.\n- actionlint 1.7.12: passed with zero findings.\n- Official manifest regeneration and exact diff: passed.\n- git diff --check: passed.\n\nA separate read-only Codex review found one inaccurate changelog job-count phrase; it was removed before the single consolidation commit and the complete verification set above was rerun. No no-op commit or synthetic second push was used.\n\nHosted checks and independent approval on the new exact head remain authoritative. No self-approval, force push, review dismissal, required-gate weakening, or admin bypass was used.
Summary by CodeRabbit
변경 사항
문서
테스트