Skip to content

fix(deploy): 게시 digest를 독립 runtime 배포까지 전달 - #1586

Draft
seonghobae wants to merge 2 commits into
fix/publish-independent-runtime-targetsfrom
codex/deploy-runtime-digests
Draft

fix(deploy): 게시 digest를 독립 runtime 배포까지 전달#1586
seonghobae wants to merge 2 commits into
fix/publish-independent-runtime-targetsfrom
codex/deploy-runtime-digests

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

목적과 경계

Refs #1022. 선행 #1365의 image 분리 delta를 유지하는 후속 stack입니다. 선행 base는 9b137f25f426743e18fc61125575ec7949d45db8, 현재 exact head는 a48aa3a3e81ba58b2fa55cd758e86b9272455b1a입니다. 기존 Linux 실행은 digest 없이 버전 tag로 manifest를 만들었습니다. 이번 변경은 게시 결과와 배포 대상 이미지의 동일성을 강제합니다.

변경

  • publisher가 backend/frontend digest를 SHA·attempt·component별 artifact로 전달합니다. matrix output 공유나 이전 실행 검색은 하지 않습니다.
  • 같은 실행에서 두 artifact를 분리 다운로드하고 무결성 불일치는 실패합니다. 하나라도 없으면 credential 설정 전에 중단합니다.
  • 최소 Bash renderer가 두 sha256·owner·version·두 placeholder를 먼저 검증하고 원본과 보안 설정을 보존한 채 image@sha256 manifest를 만듭니다. 실제 apply 경로까지 연결했습니다.
  • 후속 test commit은 source placeholder 누락/중복, invalid VERSION, 기존 output 재사용 시 모두 새 결과를 쓰기 전에 실패하고 기존 evidence를 보존하는 계약을 추가합니다.
  • AGENTS.md와 기존 doctoring에는 artifact identity와 재시도 경계를 기록했습니다.

검증된 로컬 계약

focused release-manifest/runtime/governance test, Ruff, actionlint, shellcheck, diff-check의 기존 로컬 GREEN은 source-level evidence로 유지합니다. 합성 digest는 unit 전용이며 실제 게시/배포 증거가 아닙니다. actions/download-artifact의 pinned v8 action contract도 digest-mismatch와 current-run default를 지원함을 upstream source로 재확인했습니다.

현재 blocker와 prerequisite

이 PR exact head에는 repository-owned PR workflow run이 실제로 0개입니다. Draft라서가 아니라 base가 fix/publish-independent-runtime-targets이고, protected Naruon의 Application CI, Bandit Security Scan, Dependency Review, Build and Publish Docker Imagespull_request.branches를 develop/master/release 계열로 제한하기 때문입니다. GitHub 공식 문서상 이 filter는 PR target branch에 적용됩니다.

이를 #1587 fix(ci): run repo-local validation on stacked PR bases에서 RED→최소 fix로 수리 중입니다. #1587이 protected develop에 정상 병합되면 #1365를 새 protected head에 non-force restack하고, 그 결과를 base로 둔 이 PR에서 동일 exact-head repo-local workflow가 실제 생성되는지 재검증합니다. 이 prerequisite가 착지하기 전에는 이 PR을 Ready/merge-ready로 승격하지 않습니다.

남은 조건

Draft 유지. 선행 보호 병합, #1587 prerequisite, exact-head repo-local/central checks, 독립 review, 실제 artifact 서비스 왕복, release 직렬화·환경 승인·readiness·rollback·실제 imageID·정상 인증 사용자 흐름은 미완료입니다. 현재 attempt에 두 artifact가 없으면 부분 재실행도 실패하므로 재시도는 검증된 source의 게시 matrix 전체를 포함해야 합니다. #1562 concurrency와 #1583 action pin의 유효 delta를 통합 시 보존합니다. 실제 배포는 실행하지 않았습니다.

근거와 상세 실험: docs/doctoring/runtime-image-boundary-verification.md, #1022. predecessor check/review evidence는 현재 head evidence로 이전하지 않습니다.

Co-Authored-By: Codex <noreply@openai.com>
Signed-off-by: Seongho Bae <me@seonghobae.me>
@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 55 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 512e05e1-6fdd-4088-947c-586807f4ead9

📥 Commits

Reviewing files that changed from the base of the PR and between 9b137f2 and a48aa3a.

📒 Files selected for processing (6)
  • .github/workflows/deploy.yml
  • .github/workflows/docker-publish.yml
  • AGENTS.md
  • backend/tests/test_release_manifest_digests.py
  • docs/doctoring/runtime-image-boundary-verification.md
  • scripts/render_release_manifests.sh

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae seonghobae added bug Something isn't working priority: medium Normal-priority or P2 work type: bug Defect or incorrect behavior labels Sep 7, 2026 — with ChatGPT Codex Connector
@seonghobae

Copy link
Copy Markdown
Contributor Author

Visual Inspection 기록: exact 531eb5817e1be4ddaf190a97f0e4845b7d7ae89c의 GitHub Preview를 실제 Edge에서 확인했습니다. AGENTS 새 배포 규칙과 doctoring 후속 절을 모바일 390px 및 desktop 1440×1000에서 직접 검사했습니다. 한글·긴 SHA·URL은 줄바꿈되고 문단 겹침은 없었습니다. 모바일 명령 code block은 GitHub의 가로 스크롤 영역이며 모든 명령이 한 화면에 보인다고 주장하지 않습니다. 원본은 Codex 작업 inline 스크린샷이고 별도 PNG 파일은 없습니다. viewport는 복원했습니다. 실제 인증 제품 UI와 배포 검증은 아닙니다.

별도 Agent의 production 세 파일 독립 읽기 검토에서 새 blocking finding은 없었습니다. 공식 승인이나 독립 테스트 실행을 뜻하지 않습니다. 부분 재실행의 attempt artifact 누락 제약은 문서에 명시했습니다. 동결 head의 57 passed/2.69s 및 Linux unit 계약 exit 0을 PR 본문에 남겼습니다.

Co-Authored-By: Codex <noreply@openai.com>
Signed-off-by: Seongho Bae <me@seonghobae.me>
@seonghobae

Copy link
Copy Markdown
Contributor Author

현재 head a48aa3a3e81ba58b2fa55cd758e86b9272455b1a에 테스트 30줄만 추가했습니다. backend/frontend placeholder 누락·중복, 잘못된 VERSION, 기존 출력 디렉터리 총 6사례에서 중단과 이전 manifest byte 보존을 실제 renderer 실행으로 확인합니다. 제품 코드·workflow·AGENTS·doctoring은 531eb에서 변경되지 않았습니다.

동결 head의 문서에 기재된 3개 테스트 파일 명령은 63 passed, 4.52s, exit 0; Ruff와 git diff --check도 exit 0입니다. 기존 57개 통과는 이전 head의 역사 근거입니다. 문서와 UI를 바꾸지 않았으므로 기존 시각 검수 범위를 그대로 구분하며 새 제품 VI를 주장하지 않습니다. 모든 로컬 검증 handle은 terminal 상태를 회수한 뒤 정상 push했습니다. Draft와 선행 보호 병합·배포 미완료 상태를 유지합니다.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

현재 exact head a48aa3a3e81ba58b2fa55cd758e86b9272455b1a를 base fix/publish-independent-runtime-targets@9b137f25f426743e18fc61125575ec7949d45db8 대비 독립 검토해 주세요. 특히 publish-matrix digest artifact identity, same-run/same-attempt binding, malformed/missing digest fail-closed, original manifest preservation, credential/cluster mutation 전 failure ordering을 확인해 주세요. #1587 prerequisite 때문에 hosted repo-local checks가 아직 없는 상태이므로 predecessor check/review evidence는 이 head 승인으로 이전하지 않습니다.

@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

base="9b137f25f426743e18fc61125575ec7949d45db8"
head="a48aa3a3e81ba58b2fa55cd758e86b9272455b1a"

echo '== Exact commits =='
git show -s --format='base %H%n%P%n%s' "$base"
git show -s --format='head %H%n%P%n%s' "$head"

echo '== Changed files and diffstat =='
git diff --stat "$base" "$head"
git diff --name-status "$base" "$head"

echo '== Candidate file outlines =='
git diff --name-only "$base" "$head" | while IFS= read -r file; do
  case "$file" in
    *.yml|*.yaml|*.sh|*.bash|*.py)
      echo "--- $file"
      ast-grep outline "$file" --items all 2>/dev/null || true
      ;;
  esac
done

echo '== Security-relevant diff =='
git diff --find-renames --find-copies --unified=80 "$base" "$head" -- \
  '*.yml' '*.yaml' '*.sh' '*.bash' '*.py' \
  'AGENTS.md' 'docs/doctoring/runtime-image-boundary-verification.md'

echo '== Relevant identifiers in changed files =='
git diff --name-only "$base" "$head" | while IFS= read -r file; do
  case "$file" in
    *.yml|*.yaml|*.sh|*.bash|*.py)
      echo "--- $file"
      rg -n -C 5 -e 'upload-artifact|download-artifact|digest|sha256|run_attempt|GITHUB_RUN_ATTEMPT|GITHUB_RUN_ID|credentials|kubectl|gcloud|aws|az|manifest|VERSION|placeholder' "$file" || true
      ;;
  esac
done

echo '== PR metadata and exact-head check runs =='
gh pr view 1586 --repo ContextualWisdomLab/naruon \
  --json number,state,isDraft,baseRefName,baseRefOid,headRefName,headRefOid,statusCheckRollup
gh api "repos/ContextualWisdomLab/naruon/commits/$head/check-runs?per_page=100" \
  --jq '.total_count, [.check_runs[] | {name, status, conclusion, app: .app.slug}]'

Length of output: 65358


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base="9b137f25f426743e18fc61125575ec7949d45db8"
head="a48aa3a3e81ba58b2fa55cd758e86b9272455b1a"

echo '== Head docker-publish workflow structure =='
nl -ba .github/workflows/docker-publish.yml | sed -n '1,440p'

echo '== Head reusable deploy workflow =='
nl -ba .github/workflows/deploy.yml | sed -n '1,180p'

echo '== Current source manifests =='
for file in k8s/backend-deployment.yaml k8s/frontend-deployment.yaml VERSION; do
  echo "--- $file"
  nl -ba "$file"
done

echo '== All deploy workflow invocations and references =='
rg -n -C 8 -F '.github/workflows/deploy.yml' . \
  -g '!node_modules/**' -g '!dist/**' -g '!build/**' || true
rg -n -C 5 -P '\bdeploy_to_aks\b|\bdeploy:\s*$|workflow_call:' .github/workflows \
  -g '*.yml' -g '*.yaml' || true

echo '== Base release workflow context =='
git show "$base:.github/workflows/docker-publish.yml" | nl -ba | sed -n '190,440p'
git show "$base:.github/workflows/deploy.yml" | nl -ba | sed -n '1,180p'

echo '== Repository workflow configuration =='
fd -a -t f -g 'action.yml' -g 'action.yaml' .github actions 2>/dev/null || true

Length of output: 1506


🤖 web_search executed:

In actions/download-artifactv8, whennameis specified butgithub-token, repository, and run-idare omitted, which workflow run is searched? Does the action support thedigest-mismatch: error input in this mode? Cite the pinned action documentation or source.

Length of output: 12993


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base="9b137f25f426743e18fc61125575ec7949d45db8"

echo '== Head docker-publish workflow structure =='
sed -n '=' .github/workflows/docker-publish.yml | tail -n 1
sed -n '1,440p' .github/workflows/docker-publish.yml

echo '== Head reusable deploy workflow =='
sed -n '=' .github/workflows/deploy.yml | tail -n 1
sed -n '1,180p' .github/workflows/deploy.yml

echo '== Current source manifests and version =='
for file in k8s/backend-deployment.yaml k8s/frontend-deployment.yaml VERSION; do
  echo "--- $file"
  sed -n '=' "$file" | tail -n 1
  sed -n '1,260p' "$file"
done

echo '== All deploy workflow references =='
rg -n -C 8 -F '.github/workflows/deploy.yml' . \
  -g '!node_modules/**' -g '!dist/**' -g '!build/**' || true

echo '== Workflow-call and deploy-job references =='
rg -n -C 5 -P 'workflow_call:|^\s{2}deploy_to_aks:|^\s{2}deploy:' .github/workflows \
  -g '*.yml' -g '*.yaml' || true

echo '== Base release workflow context =='
git show "$base:.github/workflows/docker-publish.yml" | sed -n '190,440p'
git show "$base:.github/workflows/deploy.yml" | sed -n '1,180p'

echo '== Workflow file inventory =='
find .github/workflows -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) -print | sort

Length of output: 45840


@seonghobae 독립 source-level 검토를 완료했습니다. 요청 범위에서 새 blocking finding은 없습니다.

검토 기준은 base 9b137f25f426743e18fc61125575ec7949d45db8와 head a48aa3a3e81ba58b2fa55cd758e86b9272455b1a입니다.

확인한 사항:

  • publish_images는 backend와 frontend의 steps.build.outputs.digest를 각각 별도 artifact로 업로드합니다.
  • artifact 이름은 github.sha, github.run_attempt, matrix.component를 포함합니다.
  • deploy_to_aks는 같은 docker-publish.yml workflow run에서 publish_images 완료 후에만 reusable deploy workflow를 호출합니다.
  • deploy workflow는 github-token, repository, run-id를 지정하지 않습니다. 따라서 actions/download-artifact v8은 current repository와 current workflow run만 조회합니다. 이전 실행 artifact 검색 경로는 없습니다.
  • backend와 frontend artifact는 별도로 다운로드됩니다. 두 단계 모두 digest-mismatch: error를 지정합니다.
  • artifact가 없거나 artifact file을 읽지 못하면 renderer 실행 전에 실패합니다.
  • renderer는 두 digest의 sha256: 형식과 소문자 64자리 hex를 검증합니다.
  • renderer는 VERSION, repository owner, backend placeholder, frontend placeholder를 모두 검증한 뒤에만 출력 디렉터리를 생성합니다.
  • renderer는 source manifest를 수정하지 않습니다. workflow는 $RUNNER_TEMP/release-manifests/*.yamlkubectl apply에 전달합니다.
  • digest download와 renderer는 Setup Kubeconfig보다 먼저 실행됩니다. 따라서 artifact 누락, 무결성 불일치, 잘못된 digest, 잘못된 source placeholder는 kubeconfig 설정 및 클러스터 변경 전에 실패합니다.
  • 추가 테스트는 malformed digest, artifact 누락, source placeholder 누락·중복, invalid VERSION, 기존 output directory를 다룹니다. 기존 output directory는 mkdir 실패로 보존됩니다.

actions/download-artifact v8 문서도 현재 run 기본 범위와 digest-mismatch: error 지원을 확인합니다: https://github.com/actions/download-artifact

제한 사항도 확인했습니다. 이 exact head의 GitHub check run은 현재 0개입니다. 따라서 hosted repository-local validation, 실제 artifact upload/download 왕복, 그리고 AKS apply 증거는 아직 없습니다. #1587 prerequisite 및 후속 protected-base restack 이후에 이 head의 새 실행 증거가 필요합니다. 이전 head의 check 또는 review 증거는 이 결론으로 이전하지 않습니다.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority: medium Normal-priority or P2 work type: bug Defect or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant