6.1 KiB
6.1 KiB
title, source_type, status, related_branches, related_projects, tags, created, status_label
| title | source_type | status | related_branches | related_projects | tags | created | status_label | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| error / Gitea act job jq bootstrap 누락 | error-note | raw |
|
|
|
2026-06-23 | resolved |
error: Gitea act job jq bootstrap 누락
Layer:
raw/errors/— Gitea/act minimal job image에서 jq가 없어서 공급망 계약 테스트가 차단된 원인과 보완 기록.
Parent / 부모
증상 / Symptom
- 에러 메시지 (CI 로그 원문):
/workspace/donghyun.kang/ca-tmpl/.github/scripts/create-release-manifest.sh: line 52: jq: command not found exitcode '127': command not found, please refer to https://github.com/nektos/act/issues/107 for more information - 발생 컨텍스트:
ci-quality-gates/gate-matrix-lint에서 gate matrix와 D1-D13 정적 계약이 성공한 다음test-supply-chain-scripts.sh가 release manifest를 생성할 때 발생. - 발생 시점: 2026-06-21 05:38 UTC.
- 발생 환경: Gitea Actions
k8s-runner-1 v0.2.11, job imagenode:20-bullseye. - 재현 가능 여부:
always— jq가 없는 동일 job image에서 해당 스크립트를 실행하면 종료 코드 127.
재현 절차 / Reproduction
- Gitea/act runner에서
ubuntu-latest를 jq가 포함되지 않은node:20-bullseye로 매핑한다. .github/workflows/ci-quality-gates.yml의gate-matrix-lint를 실행한다.- 기대 결과는 공급망 behavior test 성공이지만, 실제 결과는
create-release-manifest.sh의 첫 jq 호출에서 종료 코드 127이다. - upstream
gate-matrix-lint실패를 받은release-gate는 release-blocking gate 실패로 정상 차단된다.
조사 단계 / Investigation log
- 2026-06-23 — 두 CI 로그를 대조했다. gate matrix와
verify-supply-chain-contract.sh는 성공했고, behavior test만 jq 부재로 실패했다.release-gate는 이 upstream failure를 정상적으로 전파했다. - 2026-06-23 — workflow와 간접 호출을 전수 대조해 jq가 필요한 job environment 6개를 확인했다:
gate-matrix-lint,contract,verify,promote,audit-retention,trivy-fs. - 2026-06-23 — 구현 전 정적 계약을 강화해 installer 부재, 6개 job 배선 누락, inline download 잔존을 합쳐 15개 위반으로 실패하는 RED를 확인했다.
- 2026-06-23 — jq 1.8.1 AMD64 asset을 job-local 경로에 다운로드하고 고정 SHA-256을 검증한 뒤 실행했다. 설치된 jq로 공급망 manifest/retention 양·음수 테스트가 성공했다.
- 2026-06-23 — 실패 로그와 동일한 third-party container에 private workspace를 mount하는 검증은 안전 정책으로 거부되어 중단했다. 우회하지 않고 실제 Gitea CI 재실행을 잔여 확인으로 남겼다.
근본 원인 / Root cause
- 직접 원인:
create-release-manifest.sh가 jq를 호출했지만 job의PATH에 jq executable이 없었다. - 근본 원인: workflow가 jq를 명시적 job dependency로 bootstrap하지 않고 hosted runner의 ambient tool에 의존했다. Gitea/act의 minimal image는 이 암묵적 전제를 만족하지 않았다.
- 트리거 조건: jq가 없는 job image에서 직접
jq를 호출하거나create-release-manifest.sh/audit-rollback-retention.sh를 간접 호출한다.
Sources / 근거
- jq 1.8.1 release — Linux AMD64/ARM64 release assets와 checksum 고정 기준.
- jq 1.8.1 release API — asset digest metadata 확인.
- raw/errors/gitea-act-action-tag-and-dependency-graph-2026-06-20 — 같은 runner에서 composite action의 CLI 설치 누락을 직접 CLI 설치로 전환한 선행 사례.
해결 / Resolution
- 적용한 조치:
.github/scripts/install-jq.sh에 jq 1.8.1, Linux AMD64/ARM64 asset, 공식 SHA-256을 고정했다.RUNNER_ARCH에 따라 asset을 선택하고RUNNER_TEMP아래 설치한 뒤GITHUB_PATH로 다음 step에 전달한다.- checksum mismatch, 다운로드 실패, 미지원 architecture는 fail-closed한다.
- jq 소비 job 6개가 같은 installer를 호출하도록 연결하고 dependency workflow의 inline jq 다운로드를 제거했다.
verify-supply-chain-contract.sh가 installer 불변식, job-level 호출, inline download 금지를 검사한다.
- 검증 방법:
- RED: 정적 계약 15개 예상 위반.
- GREEN: 공급망 정적 계약과 gate matrix lint 성공.
- 공식 AMD64 asset checksum 검증 및
jq-1.8.1실행 성공. - 설치된 jq로
test-supply-chain-scripts.sh성공. - 네 workflow YAML parse 성공.
- Gradle architecture, ArchUnit, full test,
check verifyPublicPathSnapshot성공.
- 잔여 위험 / 후속 작업: 변경 commit으로 실제 Gitea/act
gate-matrix-lint를 재실행해 설치와 behavior test 로그를 확인해야 한다. github.com egress가 없는 runner의 internal mirror 정책은 별도 운영 결정이다.
회고 / Lessons
- 빨리 감지하는 신호: 정적 계약은 성공했는데 behavior test가 종료 코드 127 또는
command not found로 실패하면 runner tool bootstrap 누락부터 확인한다. - 예방 체크리스트 항목 후보: shell script가 사용하는 외부 CLI를 호출 graph 기준으로 추적하고, 각 독립 job에 설치 step이 있는지 정적 계약으로 검사한다.
- wiki로 끌어올릴 가치가 있는 일반화된 교훈: runner ambient tool 대신 version/checksum이 고정된 job-local bootstrap을 사용하고, 설치 구현은 한 파일로 중앙화한다.
Related / 관련
- Parent: raw/branch-notes/feature-build-release-supply-chain-contract.
- 선행 유사 오류: raw/errors/gitea-act-action-tag-and-dependency-graph-2026-06-20.
- 별도 interview prep: 이번 보완에서는 신규 추출 없음. 기존 raw/interviews/digest-first-supply-chain-release-gates로 충분하다.
- 별도 blog topic: 이번 보완에서는 신규 추출 없음. 기존 raw/blog-topics/digest-first-java-release-pipeline-2026-06-21에 포함 가능한 하위 사례다.