docs(release): harden resumable release workflow
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: gitea-release
|
name: gitea-release
|
||||||
description: 승인된 Gitea 버전을 준비·태깅하고 산출물을 게시한다.
|
description: 승인된 Gitea 버전을 준비·태깅하고 산출물을 게시한다.
|
||||||
version: 0.3.0
|
version: 0.3.1
|
||||||
author: genichin, Hermes Agent
|
author: genichin, Hermes Agent
|
||||||
license: MIT
|
license: MIT
|
||||||
platforms: [linux]
|
platforms: [linux]
|
||||||
@@ -21,7 +21,7 @@ Gitea repository cache를 사용해 버전 준비, 검증, 태깅과 프로젝
|
|||||||
- 준비된 commit을 태깅하고 승인된 산출물을 게시하도록 요청받았을 때
|
- 준비된 commit을 태깅하고 승인된 산출물을 게시하도록 요청받았을 때
|
||||||
- 기존 릴리즈의 tag, commit과 게시 산출물을 검증할 때
|
- 기존 릴리즈의 tag, commit과 게시 산출물을 검증할 때
|
||||||
|
|
||||||
Issue 구현, PR merge, 임의 버전 선택, 기존 tag 이동, artifact 덮어쓰기 또는 deployment에는 사용하지 않는다.
|
Issue 구현, 기존 tag 이동, artifact 덮어쓰기 또는 deployment에는 사용하지 않는다. 버전이 생략됐고 사용자가 이 작업 유형에 대해 다음 버전 결정을 위임했다면 authoritative tag·release·version source와 변경 범위를 근거로 다음 버전을 선택한다. 근거가 충돌하거나 tag convention이 확인되지 않으면 추측하지 않는다.
|
||||||
|
|
||||||
## 책임 분리
|
## 책임 분리
|
||||||
|
|
||||||
@@ -90,21 +90,21 @@ Contract를 읽은 exact bytes의 SHA-256, schema와 path를 `state.json`에 기
|
|||||||
버전 변경과 local commit을 시작하려면 다음이 필요하다.
|
버전 변경과 local commit을 시작하려면 다음이 필요하다.
|
||||||
|
|
||||||
- exact `owner/repository`
|
- exact `owner/repository`
|
||||||
- exact version과 tag
|
- exact version과 tag, 또는 버전 생략 시 다음 버전 결정을 위임한 승인
|
||||||
- 버전 파일 변경에 대한 명시적 승인
|
- contract-declared version source와 lockfile 변경에 대한 릴리즈 요청 범위
|
||||||
|
|
||||||
Agent는 버전을 선택, 증가, 정규화 또는 교체하지 않는다.
|
위임된 버전 선택은 기존 remote tag·release, 모든 version source·lockfile, tag template, 최신 release 이후 변경과 repository versioning 관례를 순서대로 조사한다. 선택한 version·tag와 근거를 `state.json`에 기록하고 publication gate에서 부재를 다시 확인한다. 명시된 version·tag는 그대로 보존하며 정규화하거나 교체하지 않는다.
|
||||||
|
|
||||||
### 게시 승인
|
### 게시 승인
|
||||||
|
|
||||||
Tag 또는 artifact를 외부에 게시하려면 다음이 필요하다.
|
Tag 또는 artifact를 외부에 게시하려면 다음이 필요하다.
|
||||||
|
|
||||||
- exact `owner/repository`
|
- exact `owner/repository`
|
||||||
- exact version과 tag
|
- exact version과 tag 또는 위임 규칙으로 확정해 기록한 version과 tag
|
||||||
- 준비된 full commit SHA
|
- 검증과 authoritative default-branch readback으로 확정한 prepared full commit SHA
|
||||||
- exact artifact와 게시 대상
|
- repository contract가 선언한 exact artifact와 게시 대상
|
||||||
|
|
||||||
브랜치명, 축약 SHA, `HEAD`, moving tag 또는 unstated default는 게시 승인이 아니다.
|
Repository 전체 릴리즈 요청은 contract-declared immutable tag와 artifact 게시까지 승인한다. 다만 mutation 직전에 full SHA, tag와 artifact target을 시스템이 확정·기록해야 한다. 브랜치명, 축약 SHA, `HEAD`, moving tag 또는 contract 밖의 unstated default는 게시 근거가 아니다.
|
||||||
|
|
||||||
## Release worktree 모델
|
## Release worktree 모델
|
||||||
|
|
||||||
@@ -126,6 +126,8 @@ Repository마다 동시에 하나의 release workflow만 허용한다.
|
|||||||
|
|
||||||
`state.json`에는 최소한 schema `gitea-agent.release-worktree/v1`, repository identity, base SHA, requested version·tag, prepared commit SHA, contract path·schema·SHA-256과 단계 상태를 기록한다. Credential 이름은 기록할 수 있지만 credential 값, PID 또는 secret 값은 기록하지 않는다.
|
`state.json`에는 최소한 schema `gitea-agent.release-worktree/v1`, repository identity, base SHA, requested version·tag, prepared commit SHA, contract path·schema·SHA-256과 단계 상태를 기록한다. Credential 이름은 기록할 수 있지만 credential 값, PID 또는 secret 값은 기록하지 않는다.
|
||||||
|
|
||||||
|
State는 선택 사항인 로그가 아니라 stage admission gate다. Worktree 생성 직후 원자적으로 만들고 version 결정, 준비 검증, prepared commit, PR merge readback, merged-SHA 재검증, tag readback, artifact readback마다 다음 external write 전에 갱신한다. 필수 field가 없거나 현재 worktree·remote state와 불일치하면 merge, tag 또는 artifact 게시를 시작하지 않는다. 성공 readback을 state에 durable하게 기록하기 전에는 worktree와 증거를 정리하지 않는다.
|
||||||
|
|
||||||
## 절차
|
## 절차
|
||||||
|
|
||||||
### 1. Target과 cache 확인
|
### 1. Target과 cache 확인
|
||||||
@@ -188,6 +190,8 @@ Repository마다 동시에 하나의 release workflow만 허용한다.
|
|||||||
|
|
||||||
하나라도 불명확하면 외부 상태를 변경하지 않는다.
|
하나라도 불명확하면 외부 상태를 변경하지 않는다.
|
||||||
|
|
||||||
|
Prepared 변경을 default branch에 전달해야 하면 publication gate 전에 explicit release branch로 push하고 PR의 exact base/head와 changed paths를 readback한 뒤 merge한다. Merge 후 authoritative default branch full SHA를 다시 읽고 mirror를 fetch한다. Candidate worktree를 없애고 다시 만드는 복합 shell command 대신 각 단계의 preflight, 단일 mutation과 readback을 분리한다. Clean candidate가 remote branch로 보존됐음을 확인한 다음 exact merged SHA의 detached worktree로 전환하고 source·contract·artifact smoke gate를 다시 실행한다. Pre-merge draft image는 게시하지 않는다.
|
||||||
|
|
||||||
### 6. Tag와 프로젝트별 게시
|
### 6. Tag와 프로젝트별 게시
|
||||||
|
|
||||||
1. 승인된 exact tag를 prepared commit에 생성한다.
|
1. 승인된 exact tag를 prepared commit에 생성한다.
|
||||||
@@ -234,6 +238,9 @@ Partial failure, dirty state, 미게시 commit 또는 불확실한 readback에
|
|||||||
- 기존 artifact를 덮어쓰거나 삭제하지 않는다.
|
- 기존 artifact를 덮어쓰거나 삭제하지 않는다.
|
||||||
- 실패한 build를 임의 변경으로 수리하지 않는다.
|
- 실패한 build를 임의 변경으로 수리하지 않는다.
|
||||||
- External write 실패를 blind retry하지 않는다.
|
- External write 실패를 blind retry하지 않는다.
|
||||||
|
- Registry push가 timeout 또는 응답 유실로 끝나면 모든 intended manifest tag와 pagination이 완료된 package-version collection을 먼저 readback한다. 전부 부재할 때만 동일 local image ID의 push를 재시도하고, 일부만 존재하면 digest reconciliation 없이는 재시도하지 않는다.
|
||||||
|
- Non-root container smoke에서 `--tmpfs`가 image의 `/data` ownership을 가린다는 점을 고려한다. Tmpfs를 쓰면 expected UID/GID/mode를 mount option에 명시하고, 그렇지 않으면 image 결함이 아닌 false permission failure로 판정될 수 있다.
|
||||||
|
- 승인 UI가 필요한 destructive command에 fetch, worktree 제거·생성, credential operation과 검증을 한 호출로 묶지 않는다. 승인 timeout 후에는 명령이 실행되지 않았다고 가정하지 말고 worktree registration, checkout HEAD와 mirror ref를 read-only로 reconcile한 뒤 사용자 승인으로 재개한다.
|
||||||
- 부분 성공 상태와 안전한 재개 지점을 보존하고 사용자 결정을 요청한다.
|
- 부분 성공 상태와 안전한 재개 지점을 보존하고 사용자 결정을 요청한다.
|
||||||
|
|
||||||
## 검증 및 보고
|
## 검증 및 보고
|
||||||
|
|||||||
Reference in New Issue
Block a user