9e5b6633db
실제 레포명은 hardened-containers인데 이관 커밋 이후 문서·워크플로·차트 주석에 잘못된 이름 security-images가 남아 있었다. 텍스트 참조 전체를 정정하고 doc/migrations/의 이관 핸드오프 문서도 파일명까지 리네임했다. env var/secret 이름(SECURITY_IMAGES_REPO, SECURITY_IMAGES_DISPATCH_TOKEN)은 GitHub Secret 재등록이 필요한 별도 운영 작업이라 이번 텍스트 정정 범위에서 제외했다. 덧붙여 scripts/build/patch-catalog-tag.py의 docstring이 삭제된 build-image.yml을 호출자로 여전히 가리키고 있던 것도 실제 호출 경로(check-rebuild-needed.py / apply-published-tags.py → catalog-tag-update.yml)로 고쳤다. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
84 lines
3.8 KiB
YAML
84 lines
3.8 KiB
YAML
name: self-build-drift-check
|
|
|
|
# 배포 중인 자체 빌드 이미지(hardened-containers 레포가 만든 것)가 새 CVE 로 규정을 벗어났는지
|
|
# 이 카탈로그가 스스로 스캔해 판정한다. "무엇이 배포 중인가"는 이 카탈로그만 안다 —
|
|
# hardened-containers 는 자기 스스로 이 판단을 하지 않는다
|
|
# (hardened-containers 레포 docs/image-authoring.md "재빌드는 이 레포가 스스로 트리거하지 않는다").
|
|
#
|
|
# 판정(scripts/build/check-rebuild-needed.py)이 재빌드 대상이라고 하면 hardened-containers 의
|
|
# `build-image.yml` 을 `workflow_dispatch` 로 부른다. 그 워크플로가 실제 빌드·검증·게이트·
|
|
# push·`published.json` 갱신을 한다 — 이 워크플로는 트리거만 한다.
|
|
#
|
|
# 레지스트리 push 와 카탈로그 반영은 이 워크플로가 하지 않는다. `catalog-tag-update.yml` 이
|
|
# `published.json` 을 읽어가는 별도 경로로 반영한다.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
schedule:
|
|
- cron: '0 2 * * 1' # 매주 월요일 02:00 UTC
|
|
|
|
env:
|
|
SECURITY_IMAGES_REPO: paasup/hardened-containers
|
|
|
|
jobs:
|
|
drift-check:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: trivy 설치
|
|
run: |
|
|
curl -fsSL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
|
|
| sh -s -- -b /usr/local/bin
|
|
trivy --version | head -1
|
|
|
|
- name: 배포 중인 자체 빌드 이미지 스캔
|
|
id: scan
|
|
run: |
|
|
set -uo pipefail
|
|
mkdir -p /tmp/drift-reports
|
|
python3 scripts/build/check-rebuild-needed.py --list-refs > /tmp/refs.tsv
|
|
while IFS=$'\t' read -r img ref fname; do
|
|
[ -n "${fname:-}" ] || continue
|
|
echo "스캔: $ref"
|
|
trivy image --quiet --scanners vuln \
|
|
--severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL \
|
|
--format json "$ref" > "/tmp/drift-reports/$fname" \
|
|
|| { echo "::warning::$img: 스캔 실패 ($ref) — 이 이미지는 판정에서 빠진다"
|
|
rm -f "/tmp/drift-reports/$fname"; }
|
|
done < /tmp/refs.tsv
|
|
|
|
python3 scripts/build/check-rebuild-needed.py \
|
|
--reports /tmp/drift-reports \
|
|
--summary-md /tmp/drift.md \
|
|
--json-out /tmp/drift.json
|
|
cat /tmp/drift.md >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
python3 - <<'PY' >> "$GITHUB_OUTPUT"
|
|
import json
|
|
rows = json.load(open("/tmp/drift.json"))
|
|
print("images=" + json.dumps([r["image"] for r in rows if r["status"] == "rebuild"]))
|
|
PY
|
|
|
|
- name: hardened-containers 재빌드 트리거
|
|
if: steps.scan.outputs.images != '' && steps.scan.outputs.images != '[]'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.SECURITY_IMAGES_DISPATCH_TOKEN }}
|
|
run: |
|
|
set -euo pipefail
|
|
[ -n "$GH_TOKEN" ] || { echo "::error::SECURITY_IMAGES_DISPATCH_TOKEN 시크릿 없음 — ${SECURITY_IMAGES_REPO} 에 workflow_dispatch 를 걸 권한이 있는 PAT 필요"; exit 1; }
|
|
python3 -c "import json,sys; print('\n'.join(json.loads(sys.argv[1])))" '${{ steps.scan.outputs.images }}' | \
|
|
while read -r img; do
|
|
[ -n "$img" ] || continue
|
|
echo "재빌드 트리거: $img"
|
|
gh workflow run self-build-image --repo "$SECURITY_IMAGES_REPO" -f "image=$img"
|
|
done
|
|
{
|
|
echo
|
|
echo "재빌드를 트리거했다: ${{ steps.scan.outputs.images }}"
|
|
echo "진행 상황: https://github.com/${SECURITY_IMAGES_REPO}/actions/workflows/self-build-image.yml"
|
|
echo
|
|
echo "게이트 PASS + push 성공 시 그 레포의 \`published.json\` 이 갱신되고,"
|
|
echo "\`catalog-tag-update.yml\` 이 다음 실행에서 카탈로그에 반영한다."
|
|
} >> "$GITHUB_STEP_SUMMARY"
|