-
Notifications
You must be signed in to change notification settings - Fork 0
운영 릴리즈 버전관리 자동화 #611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
운영 릴리즈 버전관리 자동화 #611
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # ZERO-ONE Version Management Rule - Frontend Repository | ||
|
|
||
| Source of truth for this repository: `ops/version-management.md`. | ||
|
|
||
| This rule is a version-management rule, not a frontend coding-style rule. Do not duplicate the full rule body here; keep the durable policy in `ops/version-management.md` so Claude/Codex/project agents share the same repository-level source of truth. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| --- | ||
| name: zeroone-version-management | ||
| description: Use when working on ZERO-ONE production release records, PR release intent labels/body, main-branch production deploy workflow, rollback metadata, or releases/prod-*.yaml in study-platform-client. | ||
| --- | ||
|
|
||
| # ZERO-ONE Version Management Wrapper for Claude | ||
|
|
||
| Source of truth: `ops/agent-skills/zeroone-version-management.md`. | ||
|
|
||
| Immediately read that file and follow it. Do not duplicate or reinterpret the rule in this wrapper. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| --- | ||
| name: zeroone-version-management | ||
| description: Use when working on ZERO-ONE production release records, PR release intent labels/body, main-branch production deploy workflow, rollback metadata, or releases/prod-*.yaml in study-platform-client. | ||
| --- | ||
|
|
||
| # ZERO-ONE Version Management Wrapper for Codex | ||
|
|
||
| Source of truth: `ops/agent-skills/zeroone-version-management.md`. | ||
|
|
||
| Immediately read that file and follow it. Do not duplicate or reinterpret the rule in this wrapper. |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| # 백엔드 prod 배포 fact(repository_dispatch)를 받아 프론트 레포 releases/에 최종 atomic release record를 남긴다. | ||
|
|
||
| name: Record Backend Production Release | ||
|
|
||
| on: | ||
| repository_dispatch: | ||
| types: | ||
| - backend-prod-deployed | ||
| workflow_dispatch: | ||
| inputs: | ||
| backend_payload_json: | ||
| description: 'Backend dispatch wrapper or client_payload JSON for validation/dry-run' | ||
| required: true | ||
| dry_run: | ||
| description: 'true면 record 생성/검증만 하고 commit/push하지 않는다' | ||
| required: true | ||
| default: 'true' | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| concurrency: | ||
| group: prod-release-record | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| record-backend-release: | ||
| runs-on: ubuntu-latest | ||
| env: | ||
| BACKEND_RELEASE_PAYLOAD_JSON: ${{ github.event_name == 'workflow_dispatch' && inputs.backend_payload_json || toJSON(github.event.client_payload) }} | ||
| BACKEND_RELEASE_DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || 'false' }} | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Setup Node | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| cache: 'yarn' | ||
|
|
||
| - name: Generate backend release record | ||
| run: | | ||
| set -euo pipefail | ||
| RECORD_PATH="$(node scripts/release/generate-backend-prod-release-record.mjs)" | ||
| node scripts/release/validate-release-record.mjs "$RECORD_PATH" | ||
| echo "RECORD_PATH=$RECORD_PATH" >> "$GITHUB_ENV" | ||
| echo "Generated $RECORD_PATH" | ||
| sed -n '1,220p' "$RECORD_PATH" | ||
|
|
||
| - name: Upload dry-run release record | ||
| if: ${{ env.BACKEND_RELEASE_DRY_RUN == 'true' }} | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: backend-release-record-dry-run | ||
| path: ${{ env.RECORD_PATH }} | ||
| if-no-files-found: error | ||
|
|
||
| - name: Commit release record | ||
| if: ${{ env.BACKEND_RELEASE_DRY_RUN != 'true' }} | ||
| run: | | ||
| set -euo pipefail | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git add "$RECORD_PATH" | ||
| git commit -m "chore(release): record backend prod release [release-record]" | ||
| git pull --rebase origin main | ||
| git push origin HEAD:main | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| name: Release Record Check | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - 'releases/**/*.yaml' | ||
| - 'scripts/release/**' | ||
| - 'ops/**' | ||
| - '.github/workflows/deploy-prod.yml' | ||
| - '.github/workflows/release-record-check.yml' | ||
| workflow_dispatch: | ||
|
|
||
| jobs: | ||
| validate-release-records: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Node | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
|
|
||
| - name: Validate release records | ||
| run: node scripts/release/validate-release-record.mjs releases |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # ZERO-ONE Version Management Agent Skill SSOT | ||
|
|
||
| Use this skill when working on production release records, release intent labels/body, `main` production deployment workflow, rollback metadata, or `releases/prod-*.yaml` in `study-platform-client`. | ||
|
|
||
| This file is the shared skill source of truth. Codex and Claude wrappers must stay thin and point here instead of duplicating the workflow. | ||
|
|
||
| ## Required reading order | ||
|
|
||
| 1. `ops/release-record-shared-contract.md` - FE/BE shared payload and final record contract. | ||
| 2. `ops/version-management.md` - frontend repository rule and release-record policy. | ||
| 3. `ops/release-intent.md` - human usage for PR labels/body and bootstrap. | ||
| 4. `ops/deploy-checklist.md` or `ops/rollback.md` only when deploying or rolling back. | ||
| 5. Relevant scripts/workflows only after the docs above: | ||
| - `.github/workflows/deploy-prod.yml` | ||
| - `.github/workflows/release-record-check.yml` | ||
| - `scripts/release/resolve-prod-release-intent.mjs` | ||
| - `scripts/release/generate-prod-release-record.mjs` | ||
| - `scripts/release/generate-backend-prod-release-record.mjs` | ||
| - `scripts/release/validate-release-record.mjs` | ||
| - `ops/backend-release-dispatch.md` | ||
| - `ops/release-record-shared-contract.md` | ||
|
|
||
| ## Non-negotiable rules | ||
|
|
||
| - This skill applies to `main` production releases only. Do not change `develop` deployment behavior unless the user explicitly asks. | ||
| - `ops/release-record-shared-contract.md` is the shared FE/BE contract; `releases/` is the frontend repository source of truth for successful production FE/BE/DB/rollback combinations. | ||
| - Frontend repo owns only the frontend version-management rule. Do not add the backend repository rule here. | ||
| - Production version metadata comes from PR intent or backend dispatch payload, not per-release repository variables. | ||
| - Exactly one release intent is allowed: `release:major`, `release:minor`, or `release:patch`. Use `N/A` for no DB migration version. | ||
| - If multiple `release:*` labels are present, or label intent conflicts with body `release`, fail instead of guessing. | ||
| - First recorded frontend production release requires explicit bootstrap approval metadata in the PR body: `bootstrap: approved`, `base_version` or `version`, backend image/commit/version, and rollback frontend/backend fixed image tags. | ||
| - `prod` and `latest-prod` are pointer tags only. They are never valid rollback targets and must fail if used as inherited or supplied backend/rollback images. | ||
| - Image dates belong in `release_id`, not image tags. | ||
|
|
||
| ## Implementation workflow for agents | ||
|
|
||
| 1. Inspect current branch and changed files. | ||
| 2. Read the docs in the required reading order. | ||
| 3. For workflow/script changes, add deterministic checks for: | ||
| - first-release bootstrap without accidental defaulting, | ||
| - duplicate release label failure, | ||
| - pointer-tag rejection, | ||
| - docs/examples matching supported script keys, | ||
| - backend dispatch schema validation, | ||
| - duplicate `metadata.backend_deploy_id` rejection. | ||
| 4. Validate with targeted commands first: | ||
| - `node --check scripts/release/resolve-prod-release-intent.mjs` | ||
| - local resolver smoke cases for bootstrap, duplicate labels, pointer tags, and normal latest-release inheritance. | ||
| - `node scripts/release/validate-release-record.mjs releases` | ||
| 5. Then run repository checks required by the project for the changed scope. | ||
|
|
||
| ## Human handoff format | ||
|
|
||
| Report: | ||
|
|
||
| - changed files, | ||
| - what happens on `main` merge, | ||
| - what the PR author must put in labels/body, | ||
| - verification commands and results, | ||
| - any remaining manual setup such as optional `PROD_E2E_BASE_URL`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| # Backend Production Release Dispatch Contract | ||
|
|
||
| This is the frontend repository contract for backend production deployments. Backend automation is the producer of backend deploy facts. The frontend repository is the final release-record writer. | ||
|
|
||
| This document follows the shared FE/BE contract in `ops/release-record-shared-contract.md`. | ||
|
|
||
| ## Trigger | ||
|
|
||
| Backend production deploy success must call the frontend repository with `repository_dispatch` or an equivalent API trigger. | ||
|
|
||
| ```json | ||
| { | ||
| "event_type": "backend-prod-deployed", | ||
| "client_payload": {} | ||
| } | ||
|
Comment on lines
+9
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 트리거 예시의 Line 9-13 예시를 그대로 따르면 빈 payload가 전송되어, 같은 문서의 Required payload/fields 규칙을 즉시 위반합니다. 트리거 예시는 최소한 “필수 필드를 포함한 payload” 형태로 맞춰야 계약 오해를 막을 수 있습니다. 제안 diff {
"event_type": "backend-prod-deployed",
- "client_payload": {}
+ "client_payload": {
+ "release_id": "prod-YYYYMMDD-HHmm",
+ "env": "prod",
+ "backend": {
+ "image": "zeroone-backend:vMAJOR.MINOR.PATCH-shortCommit",
+ "commit": "shortCommit",
+ "version": "vMAJOR.MINOR.PATCH",
+ "changed": true
+ },
+ "database": {
+ "changed": false,
+ "migration_version": "none",
+ "migration_files": []
+ },
+ "rollback": {
+ "backend": "zeroone-backend:vMAJOR.MINOR.PATCH-shortCommit"
+ },
+ "metadata": {
+ "release_intent": "patch",
+ "bootstrap_mode": false,
+ "backend_deploy_id": "backend-prod-unique-id"
+ }
+ }
}Also applies to: 22-55 🤖 Prompt for AI Agents |
||
| ``` | ||
|
|
||
| The frontend workflow that receives this event is: | ||
|
|
||
| ```txt | ||
| .github/workflows/record-backend-prod-release.yml | ||
| ``` | ||
|
|
||
| ## Required payload | ||
|
|
||
| ```json | ||
| { | ||
| "release_id": "prod-20260517-2100", | ||
| "env": "prod", | ||
| "summary": "backend patch release", | ||
| "backend": { | ||
| "repo": "study-platform-mvp", | ||
| "image": "zeroone-backend:v1.4.3-b7c8d9e", | ||
| "commit": "b7c8d9e", | ||
| "version": "v1.4.3", | ||
| "changed": true | ||
| }, | ||
| "database": { | ||
| "changed": true, | ||
| "migration_version": "V45", | ||
| "migration_files": [ | ||
| "src/main/resources/db/migration/V45__create_course_refund.sql" | ||
| ] | ||
| }, | ||
| "rollback": { | ||
| "backend": "zeroone-backend:v1.4.2-a1b2c3d" | ||
| }, | ||
| "metadata": { | ||
| "release_intent": "patch", | ||
| "bootstrap_mode": false, | ||
| "previous_deploy_image": "zeroone-backend:v1.4.2-a1b2c3d", | ||
| "pull_request_number": 1234, | ||
| "pull_request_labels": ["release:patch", "db:backup-confirmed"], | ||
| "backend_deploy_id": "backend-prod-123" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Required fields | ||
|
|
||
| - `release_id` - `prod-YYYYMMDD-HHmm` | ||
| - `env` - must be `prod` | ||
| - `backend.image` - fixed immutable backend image tag | ||
| - `backend.commit` - backend short commit | ||
| - `backend.version` - `vMAJOR.MINOR.PATCH` | ||
| - `backend.changed` - must be `true` | ||
| - `database.changed` - boolean | ||
| - `database.migration_version` - migration version or `N/A` | ||
| - `database.migration_files` - array | ||
| - `rollback.backend` - fixed immutable backend rollback image tag | ||
| - `metadata.release_intent` - `patch`, `minor`, or `major` | ||
| - `metadata.bootstrap_mode` - boolean | ||
| - `metadata.backend_deploy_id` - unique backend deployment id | ||
|
|
||
| ## Optional fields | ||
|
|
||
| - `summary` | ||
| - `metadata.previous_deploy_image` | ||
| - `metadata.pull_request_number` | ||
| - `metadata.pull_request_labels` | ||
|
|
||
| ## Frontend behavior | ||
|
|
||
| When the dispatch arrives, the frontend repository workflow: | ||
|
|
||
| 1. validates the payload strictly, | ||
| 2. reads the latest `releases/prod-*.yaml` to identify current frontend production state, | ||
| 3. creates a new release record with `frontend.changed=false` and `backend.changed=true`, | ||
| 4. writes `metadata.backend_deploy_id`, | ||
| 5. fails if the same `backend_deploy_id` is already recorded, | ||
| 6. fails if image tags use `prod`, `latest-prod`, dates, or non-canonical versions. | ||
|
|
||
| The workflow does not deploy frontend code. It only records the new atomic production combination `FE(current) + BE(new)`. | ||
|
|
||
| ## Failure principle | ||
|
|
||
| Do not guess. If the payload is missing, invalid, duplicated, or the frontend repository has no previous release record to identify current frontend production state, the workflow must fail instead of writing a wrong release record. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # Production Deploy Checklist | ||
|
|
||
| This checklist applies to `main` production deployments only. `develop` test-server deployment keeps the existing lightweight pointer-tag flow. | ||
|
|
||
| This document follows the shared FE/BE contract in `ops/release-record-shared-contract.md`. | ||
|
|
||
| ## Before production deploy | ||
|
|
||
| - Confirm PR CI is green before merging to `main`. | ||
| - Confirm the PR has exactly one release intent: `release:patch`, `release:minor`, `release:major`, or a `release: ...` line in the PR body. | ||
| - Confirm `ops/release-intent.md` bootstrap approval fields are present if this is the first recorded frontend production release. | ||
| - For frontend-only deploys, confirm latest `releases/` backend image matches current production backend; if not, record the backend dispatch first. | ||
| - Confirm rollback targets and inherited/supplied backend images are fixed image tags, not `prod` or `latest-prod`. | ||
|
|
||
| ## Deployment order | ||
|
|
||
| 1. DB migration | ||
| 2. Backend | ||
| 3. Backend health check | ||
| 4. Frontend | ||
| 5. E2E/smoke check | ||
|
|
||
| ## After production deploy | ||
|
|
||
| - Confirm frontend container is running with the fixed frontend image tag. | ||
| - Confirm backend health/API compatibility. | ||
| - Confirm `releases/prod-YYYYMMDD-HHmm.yaml` was committed to `main`. | ||
| - Confirm the release record includes frontend, backend, database, rollback, deploy order, deployed time, actor, and `status: success`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
체크아웃 브랜치를
main으로 명시 고정하세요.현재는
repository_dispatch실행 시점의 기본 브랜치 기준으로 체크아웃될 수 있어, 커밋/푸시 대상(main)과 작업 베이스가 어긋날 위험이 있습니다.수정 제안
- name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 + ref: mainBased on learnings: Main-branch production deployments must follow
ops/version-management.md(ZERO-ONE Version Management Rule - Frontend Repository).🤖 Prompt for AI Agents