ci(release): release-guard — 수동 릴리스·태그 오지정 탐지 가드 - #30
Merged
Conversation
Validation script (.github/scripts/release-guard.sh) checks, at the tag: - build.gradle.kts source version == tag version (the v1.4.0 incident: tag on a commit whose source still said 1.3.0) - maven-plugin/pom.xml <version> AND <pjacoco.agent.version> == tag version (the 1.2.0 incident: agent version missed on bump) - the release carries the full release.yml asset set: agent + 4 testkit + maven-plugin jars, a .sha256 per jar, no orphans, no stray assets; the deprecated jacocoagent-parallel alias stays optional so its planned removal after v1.4.x needs no guard change Wired in two paths, because events created with GITHUB_TOKEN do not trigger other workflows: - release.yml runs the script as a self-check right after publishing (covers every workflow-produced release) - the standalone release-guard workflow fires on human/PAT-created v* tag pushes and release publish/edit — exactly the manual-release case being guarded — plus workflow_dispatch for re-validation Hardening from review: whole-string [[ =~ ]] tag validation (grep -E is line-based and a multi-line value could smuggle a second GITHUB_OUTPUT key into the checkout ref), gh api 404 vs auth/network failure split so outages can't silently pass the asset check, release.yml version input tightened to semver so the two workflows share one tag contract. GitHub cannot block release creation, so this is a detective control: a bad release turns into a red run instead of shipping silently. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FavJfhdcNAHZKWvmSBVLYZ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
배경
v1.4.0 릴리즈 사고:
gh release create로 수동 생성되어 자산이 14개 중 1개뿐이었고, 태그는 소스 버전이 1.3.0인(기능도 없는) 커밋을 가리켰다. 이 PR은 그 유형의 사고를 자동 탐지하는 가드를 추가한다.변경 내용
.github/scripts/release-guard.sh(신규) — 태그 체크아웃 기준 검증:build.gradle.kts소스 버전 == 태그 버전 (v1.4.0 사고 유형)maven-plugin/pom.xml의<version>+<pjacoco.agent.version>== 태그 버전 (1.2.0 사고 유형).sha256, 고아/정체불명 자산 없음 (deprecated alias는 선택 — v1.4.x 이후 제거 계획과 정합).github/workflows/release-guard.yml(신규) — 사람/PAT이 만든v*태그 push, release publish/edit에 반응 + workflow_dispatch 재검증. GITHUB_TOKEN이 만든 이벤트는 워크플로를 발화시키지 않으므로 이 경로는 정확히 "수동 릴리스" 탐지망..github/workflows/release.yml— ① 릴리즈 생성 직후 같은 스크립트를 자체 검증 단계로 실행(정상 경로 커버), ② version 입력 regex를 semver로 강화(가드와 태그 계약 일치), ③ 멀티라인 입력 방지용[[ =~ ]]전체 문자열 매칭.docs/RELEASING.md— 가드 2경로 문서화.검증
ghshim):.github/+ docs만) — 프로젝트 테스트 스위트에 영향 없음released중복 이벤트 등), 2건 근거와 함께 거절(alias 필수화 — release.yml 자체 개수 가드가 이미 강제; CI에 bats 추가 — 별도 스코프)한계
GitHub에는 릴리스 생성을 차단하는 수단이 없어 이 가드는 탐지 컨트롤이다 — 위반은 빨간 Actions 실행으로 드러난다.
🤖 Generated with Claude Code
https://claude.ai/code/session_01FavJfhdcNAHZKWvmSBVLYZ