prizmkit 1.1.154 → 1.1.156
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/VERSION.json +3 -3
- package/bundled/adapters/codex/skill-adapter.js +1 -1
- package/bundled/adapters/pi/skill-adapter.js +2 -1
- package/bundled/dev-pipeline/.env.example +2 -6
- package/bundled/dev-pipeline/README.md +21 -27
- package/bundled/dev-pipeline/prizmkit_runtime/checkpoint_state.py +341 -15
- package/bundled/dev-pipeline/prizmkit_runtime/cli.py +0 -3
- package/bundled/dev-pipeline/prizmkit_runtime/daemon.py +1 -15
- package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +48 -14
- package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +50 -2
- package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +0 -9
- package/bundled/dev-pipeline/prizmkit_runtime/runner_prompts.py +3 -3
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +120 -22
- package/bundled/dev-pipeline/prizmkit_runtime/runtime_commit.py +482 -0
- package/bundled/dev-pipeline/prizmkit_runtime/test_result.py +64 -11
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +145 -367
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +91 -62
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +105 -69
- package/bundled/dev-pipeline/scripts/prompt_framework.py +36 -41
- package/bundled/dev-pipeline/scripts/update-bug-status.py +1 -4
- package/bundled/dev-pipeline/scripts/update-checkpoint.py +61 -13
- package/bundled/dev-pipeline/scripts/update-feature-status.py +1 -4
- package/bundled/dev-pipeline/scripts/update-refactor-status.py +1 -4
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +22 -27
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +71 -104
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +59 -111
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +37 -72
- package/bundled/dev-pipeline/templates/sections/artifact-manifest.md +39 -0
- package/bundled/dev-pipeline/templates/sections/bugfix-critical-paths.md +3 -1
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-commit-report.md +8 -25
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-diagnose-plan.md +3 -3
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-implement.md +2 -2
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +3 -3
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-test.md +2 -2
- package/bundled/dev-pipeline/templates/sections/bugfix-reminders.md +4 -4
- package/bundled/dev-pipeline/templates/sections/bugfix-session-context.md +0 -1
- package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +7 -4
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +14 -27
- package/bundled/dev-pipeline/templates/sections/feature-completion-summary.md +20 -0
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +8 -71
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +7 -7
- package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +3 -3
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +4 -4
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +5 -17
- package/bundled/dev-pipeline/templates/sections/refactor-critical-paths.md +3 -1
- package/bundled/dev-pipeline/templates/sections/refactor-phase-commit-report.md +10 -23
- package/bundled/dev-pipeline/templates/sections/refactor-phase-implement.md +2 -2
- package/bundled/dev-pipeline/templates/sections/refactor-phase-plan.md +2 -2
- package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +3 -3
- package/bundled/dev-pipeline/templates/sections/refactor-phase-test.md +2 -2
- package/bundled/dev-pipeline/templates/sections/refactor-reminders.md +7 -7
- package/bundled/dev-pipeline/templates/sections/refactor-session-context.md +0 -1
- package/bundled/dev-pipeline/templates/sections/retrospective.md +12 -0
- package/bundled/dev-pipeline/templates/sections/runtime-commit-handoff.md +35 -0
- package/bundled/dev-pipeline/templates/session-status-schema.json +45 -62
- package/bundled/dev-pipeline/tests/test_checkpoint_state.py +469 -18
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +262 -175
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +62 -23
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +76 -28
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +168 -18
- package/bundled/dev-pipeline/tests/test_recovery_workflow.py +111 -0
- package/bundled/dev-pipeline/tests/test_reset_preserve.py +0 -2
- package/bundled/dev-pipeline/tests/test_runtime_commit.py +608 -0
- package/bundled/dev-pipeline/tests/test_unified_cli.py +167 -25
- package/bundled/skills/_metadata.json +9 -9
- package/bundled/skills/app-planner/SKILL.md +3 -3
- package/bundled/skills/app-planner/references/generated-plan-review.md +2 -1
- package/bundled/skills/app-planner/references/rules/backend/derivation-rules.md +56 -64
- package/bundled/skills/app-planner/references/rules/backend/fixed-rules.md +85 -240
- package/bundled/skills/app-planner/references/rules/backend/question-bank.md +25 -25
- package/bundled/skills/app-planner/references/rules/backend/question-manifest.json +16 -7
- package/bundled/skills/app-planner/references/rules/backend/template.md +74 -92
- package/bundled/skills/app-planner/references/rules/database/derivation-rules.md +93 -93
- package/bundled/skills/app-planner/references/rules/database/fixed-rules.md +66 -173
- package/bundled/skills/app-planner/references/rules/database/question-bank.md +31 -26
- package/bundled/skills/app-planner/references/rules/database/question-manifest.json +13 -4
- package/bundled/skills/app-planner/references/rules/database/template.md +76 -98
- package/bundled/skills/app-planner/references/rules/frontend/derivation-rules.md +68 -95
- package/bundled/skills/app-planner/references/rules/frontend/fixed-rules.md +93 -166
- package/bundled/skills/app-planner/references/rules/frontend/question-bank.md +46 -36
- package/bundled/skills/app-planner/references/rules/frontend/question-manifest.json +11 -2
- package/bundled/skills/app-planner/references/rules/frontend/template.md +79 -257
- package/bundled/skills/app-planner/references/rules/mobile/derivation-rules.md +91 -99
- package/bundled/skills/app-planner/references/rules/mobile/fixed-rules.md +73 -246
- package/bundled/skills/app-planner/references/rules/mobile/question-bank.md +17 -17
- package/bundled/skills/app-planner/references/rules/mobile/question-manifest.json +17 -2
- package/bundled/skills/app-planner/references/rules/mobile/template.md +73 -85
- package/bundled/skills/app-planner/references/rules-configuration.md +133 -65
- package/bundled/skills/app-planner/scripts/validate-rules-configuration.py +291 -0
- package/bundled/skills/prizmkit/SKILL.md +17 -18
- package/bundled/skills/prizmkit/references/workflow-state-protocol.md +22 -18
- package/bundled/skills/prizmkit-code-review/SKILL.md +22 -58
- package/bundled/skills/prizmkit-code-review/references/independent-code-review.md +6 -6
- package/bundled/skills/prizmkit-code-review/references/review-report-template.md +2 -2
- package/bundled/skills/prizmkit-committer/SKILL.md +82 -132
- package/bundled/skills/prizmkit-deploy/SKILL.md +27 -11
- package/bundled/skills/prizmkit-deploy/assets/deploy-document-template.md +89 -0
- package/bundled/skills/prizmkit-deploy/references/ci-cd-workflows.md +44 -14
- package/bundled/skills/prizmkit-deploy/references/cloud-platform-deploy.md +19 -3
- package/bundled/skills/prizmkit-deploy/references/database-setup.md +22 -12
- package/bundled/skills/prizmkit-deploy/references/deploy-config-schema.md +3 -1
- package/bundled/skills/prizmkit-deploy/references/deploy-history-schema.md +22 -6
- package/bundled/skills/prizmkit-deploy/references/deploy-metadata-schema.json +49 -0
- package/bundled/skills/prizmkit-deploy/references/live-validation-notes.md +1 -1
- package/bundled/skills/prizmkit-deploy/references/pending-input-schema.json +164 -0
- package/bundled/skills/prizmkit-deploy/references/ssh-adapter-flow.md +9 -8
- package/bundled/skills/prizmkit-deploy/references/ssh-execution-flow.md +6 -6
- package/bundled/skills/prizmkit-implement/SKILL.md +30 -66
- package/bundled/skills/prizmkit-implement/references/implementation-subagent-procedure.md +4 -4
- package/bundled/skills/prizmkit-init/SKILL.md +4 -0
- package/bundled/skills/prizmkit-plan/SKILL.md +21 -64
- package/bundled/skills/prizmkit-plan/references/artifact-identity.md +38 -0
- package/bundled/skills/prizmkit-plan/references/independent-plan-review.md +4 -4
- package/bundled/skills/prizmkit-plan/references/review-plan-spec-loop.md +5 -5
- package/bundled/skills/prizmkit-prizm-docs/SKILL.md +75 -11
- package/bundled/skills/prizmkit-prizm-docs/assets/prizm-docs-format.md +191 -56
- package/bundled/skills/prizmkit-prizm-docs/references/op-init.md +18 -18
- package/bundled/skills/prizmkit-prizm-docs/references/op-rebuild.md +14 -8
- package/bundled/skills/prizmkit-prizm-docs/references/op-status.md +12 -5
- package/bundled/skills/prizmkit-prizm-docs/references/op-update.md +23 -12
- package/bundled/skills/prizmkit-prizm-docs/references/op-validate.md +13 -9
- package/bundled/skills/prizmkit-retrospective/SKILL.md +94 -97
- package/bundled/skills/prizmkit-retrospective/references/knowledge-injection-steps.md +79 -37
- package/bundled/skills/prizmkit-retrospective/references/retrospective-result-schema.json +138 -0
- package/bundled/skills/prizmkit-retrospective/references/structural-sync-steps.md +111 -54
- package/bundled/skills/prizmkit-test/SKILL.md +64 -51
- package/bundled/skills/prizmkit-test/references/boundary-contract-and-test-double-guidance.md +206 -0
- package/bundled/skills/prizmkit-test/references/independent-test-review.md +17 -9
- package/bundled/skills/prizmkit-test/references/test-coverage-model.md +45 -21
- package/bundled/skills/prizmkit-test/references/test-report-template.md +20 -13
- package/bundled/skills/prizmkit-workflow/SKILL.md +35 -37
- package/bundled/skills/prizmkit-workflow/references/artifact-identity.md +34 -0
- package/bundled/skills/prizmkit-workflow/references/workflow-state-protocol.md +22 -18
- package/bundled/skills/recovery-workflow/SKILL.md +2 -1
- package/bundled/skills/recovery-workflow/references/detection.md +4 -3
- package/bundled/skills/recovery-workflow/scripts/detect-recovery-state.py +15 -5
- package/bundled/templates/hooks/validate-prizm-docs.py +124 -12
- package/package.json +1 -1
- package/src/scaffold.js +33 -22
- package/bundled/dev-pipeline/templates/sections/bugfix-artifacts.md +0 -16
- package/bundled/dev-pipeline/templates/sections/bugfix-session-status.md +0 -31
- package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +0 -7
- package/bundled/dev-pipeline/templates/sections/critical-paths-lite.md +0 -7
- package/bundled/dev-pipeline/templates/sections/directory-convention-agent.md +0 -9
- package/bundled/dev-pipeline/templates/sections/directory-convention-lite.md +0 -6
- package/bundled/dev-pipeline/templates/sections/headless-commit-authorization.md +0 -15
- package/bundled/dev-pipeline/templates/sections/phase-commit.md +0 -61
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +0 -24
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +0 -12
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +0 -44
- package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +0 -25
- package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +0 -20
- package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +0 -20
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +0 -20
- package/bundled/dev-pipeline/templates/sections/refactor-artifacts.md +0 -17
- package/bundled/dev-pipeline/templates/sections/refactor-session-status.md +0 -28
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +0 -52
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +0 -52
- package/bundled/skills/prizmkit-code-review/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-committer/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-implement/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-plan/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-retrospective/references/workflow-state-protocol.md +0 -174
- package/bundled/skills/prizmkit-test/references/external-contract-mock-guidance.md +0 -119
|
@@ -47,7 +47,7 @@ Rules:
|
|
|
47
47
|
|
|
48
48
|
## Review Input
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
Use the exact caller-supplied review identity on every response:
|
|
51
51
|
|
|
52
52
|
```text
|
|
53
53
|
artifact_dir: [EXACT_ARTIFACT_DIR]
|
|
@@ -95,7 +95,7 @@ Execution boundaries:
|
|
|
95
95
|
- Complete this review personally.
|
|
96
96
|
- Do not create, schedule, resume, continue, request, or coordinate another execution unit.
|
|
97
97
|
- Do not ask the Main Agent to create a helper.
|
|
98
|
-
- Do not re-enter
|
|
98
|
+
- Do not re-enter delegation or another review process.
|
|
99
99
|
- Do not modify, create, delete, rename, stage, commit, or otherwise mutate files.
|
|
100
100
|
- Do not execute shell, Git, tests, builds, network calls, external processes, or any operation that can change state.
|
|
101
101
|
- Use read-only checkout access beyond changed files only for concrete module, caller, consumer, schema, type, configuration, fixture, or test coupling.
|
|
@@ -139,7 +139,7 @@ All initial execution boundaries and the Reviewer Output Protocol remain mandato
|
|
|
139
139
|
|
|
140
140
|
## Reviewer Output Protocol
|
|
141
141
|
|
|
142
|
-
Return exactly one of these forms. Do not add severity, confidence, dimension,
|
|
142
|
+
Return exactly one of these forms. Do not add severity, confidence, dimension, caller routing, or acceptance fields.
|
|
143
143
|
|
|
144
144
|
### No Correction Needed
|
|
145
145
|
|
|
@@ -187,7 +187,7 @@ Every correction contains only `Target`, `Problem`, `Evidence`, and `Correction`
|
|
|
187
187
|
No review verdict was produced.
|
|
188
188
|
```
|
|
189
189
|
|
|
190
|
-
`REVIEW_BLOCKED` is an internal independent-review result, not
|
|
190
|
+
`REVIEW_BLOCKED` is an internal independent-review result, not the code-review stage verdict.
|
|
191
191
|
|
|
192
192
|
## Main-Agent Adjudication
|
|
193
193
|
|
|
@@ -234,11 +234,11 @@ Behavior:
|
|
|
234
234
|
6. Reviewer input problems may be corrected within remaining shared budget using native continuation or a compliant replacement.
|
|
235
235
|
7. Report temporary input-cleanup failures honestly; cleanup failure does not change an otherwise verified review result.
|
|
236
236
|
|
|
237
|
-
Strict downgrade is visible reduced assurance, not a new
|
|
237
|
+
Strict downgrade is visible reduced assurance, not a new terminal review verdict and not permission to weaken the gate.
|
|
238
238
|
|
|
239
239
|
## Report Recording
|
|
240
240
|
|
|
241
|
-
Use the existing append-only `review-report.md`
|
|
241
|
+
Use the existing append-only `review-report.md` structure and renderer events:
|
|
242
242
|
|
|
243
243
|
- `independent-review-round`: response number `1..5`, result, correction count, adjudication counts, and next action;
|
|
244
244
|
- `independent-adjudication`: correction summary, `accepted | rejected | unresolved`, evidence, and actual modification;
|
|
@@ -114,7 +114,7 @@ Exactly one Final Result terminates a completed execution:
|
|
|
114
114
|
- Start of a new execution removes stale progress and terminal results from prior executions.
|
|
115
115
|
- A phase appends its result before the next phase starts.
|
|
116
116
|
- Main-Agent round numbers are from `1` through `10`; independent Reviewer response numbers are from `1` through `5`.
|
|
117
|
-
- Independent Reviewer results are `NO_CORRECTION_NEEDED`, `CORRECTION_NEEDED`, or `REVIEW_BLOCKED`; they never replace the terminal
|
|
117
|
+
- Independent Reviewer results are `NO_CORRECTION_NEEDED`, `CORRECTION_NEEDED`, or `REVIEW_BLOCKED`; they never replace the terminal review verdict.
|
|
118
118
|
- For an independent round, `accepted + rejected + unresolved = corrections`; `NO_CORRECTION_NEEDED` requires zero corrections.
|
|
119
119
|
- Finding counts satisfy `accepted + rejected + unresolved = findings`.
|
|
120
120
|
- `PASS` requires every accepted finding fixed and zero unresolved findings.
|
|
@@ -122,4 +122,4 @@ Exactly one Final Result terminates a completed execution:
|
|
|
122
122
|
- An IN_PROGRESS report without Final Result is incomplete.
|
|
123
123
|
- Generic or incidental verdict text outside the last Final Result does not prove completion.
|
|
124
124
|
- Do not append any section after Final Result.
|
|
125
|
-
-
|
|
125
|
+
- Do not create a separate review-state JSON file; `review-report.md` is the complete stage artifact.
|
|
@@ -1,179 +1,129 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "prizmkit-committer"
|
|
3
|
-
description: "
|
|
3
|
+
description: "Perform one commit stage for a caller-supplied final change. Either preview and create an explicitly confirmed interactive local commit, or validate the final diff and write an exact runtime-commit-request.json without Git mutation. Returns only commit-stage results. (project)"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# PrizmKit Committer
|
|
7
7
|
|
|
8
|
-
`/prizmkit-committer`
|
|
8
|
+
`/prizmkit-committer` handles one caller-supplied final change through one explicit operation:
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
→ prizmkit-implement
|
|
13
|
-
→ prizmkit-code-review
|
|
14
|
-
→ prizmkit-test
|
|
15
|
-
→ prizmkit-retrospective
|
|
16
|
-
→ prizmkit-committer
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
It does not decide which formal gates can be omitted. It verifies that all five preceding stages completed for the same `artifact_dir`, then applies the commit authorization semantics for the current execution context.
|
|
20
|
-
|
|
21
|
-
## Atomic Stage Boundary
|
|
22
|
-
|
|
23
|
-
`prizmkit-committer` owns only final gate verification, authorization-boundary handling, local staging, commit creation, and commit verification. It writes its truthful terminal result and returns control; it must not invoke deployment or any hidden seventh stage. The active orchestrator owns lifecycle completion reporting.
|
|
24
|
-
|
|
25
|
-
## When to Use
|
|
26
|
-
|
|
27
|
-
- Workflow state reports `status=completed` with `stage_result=RETRO_COMPLETE` and a valid `retrospective-result.json` for the active formal requirement.
|
|
28
|
-
- An interactive user confirms they want to create the local commit.
|
|
29
|
-
- A trusted headless execution context authorizes an automatic local commit.
|
|
30
|
-
- User says "commit", "submit", "finish", or "done" after the formal gates have completed.
|
|
31
|
-
|
|
32
|
-
## When NOT to Use
|
|
10
|
+
- `operation=interactive-commit`: preview, confirm, stage, commit, and verify locally.
|
|
11
|
+
- `operation=prepare-runtime-commit`: validate the intended change and write an exact commit request without staging or committing.
|
|
33
12
|
|
|
34
|
-
|
|
35
|
-
- Any preceding formal stage is missing, failed, blocked, or associated with a different artifact directory.
|
|
36
|
-
- Review has `NEEDS_FIXES` or tests have `TEST_NEEDS_FIXES`/`TEST_BLOCKED`.
|
|
37
|
-
- Retrospective has not completed, including an explicit `NO_DOC_CHANGE` result.
|
|
38
|
-
- User says only "ship it"; clarify commit versus deployment in interactive mode.
|
|
39
|
-
- A merge conflict is unresolved.
|
|
40
|
-
- An unknown headless caller has not supplied trusted commit authorization.
|
|
13
|
+
Remote publication is outside this Skill.
|
|
41
14
|
|
|
42
|
-
##
|
|
15
|
+
## Input
|
|
43
16
|
|
|
44
|
-
|
|
17
|
+
| Parameter | Required | Description |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `artifact_dir` | Yes | Exact caller-supplied artifact root for this commit stage. |
|
|
20
|
+
| `operation` | Yes | `interactive-commit` or `prepare-runtime-commit`. |
|
|
21
|
+
| `evidence_paths` | Yes | Exact caller-supplied project-relative artifacts that establish commit readiness. |
|
|
22
|
+
| `excluded_paths` | No | Exact caller-owned metadata paths that must remain outside the commit and are also excluded by the selected operation's consumer contract. It is not an allowlist for unrelated project changes. |
|
|
23
|
+
| `request_path` | Preparation only | Must equal `{artifact_dir}/runtime-commit-request.json`. |
|
|
45
24
|
|
|
46
|
-
|
|
47
|
-
|---|---|
|
|
48
|
-
| Plan | `spec.md`, `plan.md`, and `PLAN_READY` for the same `artifact_dir` |
|
|
49
|
-
| Implement | All required tasks complete and `IMPLEMENTED` |
|
|
50
|
-
| Code review | Final `review-report.md` result `PASS` |
|
|
51
|
-
| Test | Consistent `TEST_PASS` report/result pair for the final reviewed workspace |
|
|
52
|
-
| Retrospective | `retrospective-result.json` with workflow `status=completed`, `stage_result=RETRO_COMPLETE`, and artifact `result=DOCS_UPDATED` or `result=NO_DOC_CHANGE` |
|
|
25
|
+
Do not discover another artifact root or infer the operation from provider, platform, prompt style, or human availability.
|
|
53
26
|
|
|
54
|
-
|
|
27
|
+
## Stage Boundary
|
|
55
28
|
|
|
56
|
-
|
|
29
|
+
This Skill owns only final-change inspection and its selected commit operation. It does not invoke another Skill.
|
|
57
30
|
|
|
58
|
-
|
|
31
|
+
In preparation mode it must not stage, unstage, commit, amend, reset, merge, or push.
|
|
59
32
|
|
|
60
|
-
1
|
|
61
|
-
2. Verify `spec.md`, `plan.md`, final `review-report.md`, the consistent `test-report.md`/`test-result.json` pair, `retrospective-result.json`, and the current workspace.
|
|
62
|
-
3. Inspect:
|
|
33
|
+
## Step 1: Validate Supplied Evidence and Final Change
|
|
63
34
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
35
|
+
1. Resolve `artifact_dir` and every `evidence_paths` entry exactly as supplied by the caller.
|
|
36
|
+
2. Reject missing, unreadable, stale, contradictory, blocked, or explicitly non-passing evidence.
|
|
37
|
+
3. Inspect staged, unstaged, untracked, deleted, and renamed files with bounded Git status/diff commands.
|
|
38
|
+
4. Confirm every changed path belongs to the supplied change, a concrete dependency, its tests, durable documentation, or caller-required artifacts.
|
|
39
|
+
5. Reject unresolved merge state and sensitive files such as real environment files, credentials, secrets, private keys, certificates, or local settings.
|
|
40
|
+
6. Confirm no requested task output remains to be generated after this stage.
|
|
69
41
|
|
|
70
|
-
|
|
71
|
-
5. Warn about sensitive-looking files such as `.env*`, credentials, secrets, private keys, and certificates.
|
|
72
|
-
6. Stop when any required gate is missing, stale, contradictory, failed, or blocked.
|
|
42
|
+
The caller decides which evidence is required and how the returned commit-stage result is used. This Skill validates the supplied evidence but does not infer a larger stage sequence.
|
|
73
43
|
|
|
74
|
-
|
|
44
|
+
## Step 2: Build Commit Message and Intended Path Set
|
|
75
45
|
|
|
76
|
-
|
|
46
|
+
Generate one concise Conventional Commit message:
|
|
77
47
|
|
|
78
48
|
```text
|
|
79
49
|
<type>(<scope>): <description>
|
|
80
50
|
```
|
|
81
51
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
### Step 3: Commit Preview and Authorization
|
|
85
|
-
|
|
86
|
-
Interactive mode:
|
|
87
|
-
|
|
88
|
-
Before any `git add` or `git commit` that changes the target project's Git state, present:
|
|
89
|
-
|
|
90
|
-
- intended files;
|
|
91
|
-
- added, modified, deleted, and renamed file summary;
|
|
92
|
-
- sensitive-file warnings;
|
|
93
|
-
- diff statistics and relevant summary;
|
|
94
|
-
- proposed commit message;
|
|
95
|
-
- whether any remaining changes are intentionally excluded.
|
|
96
|
-
|
|
97
|
-
Ask the current user to confirm creation of this local commit. Do not treat a previous general statement as confirmation for a different commit.
|
|
98
|
-
|
|
99
|
-
Trusted headless mode:
|
|
100
|
-
|
|
101
|
-
- Do not ask a question, wait for input, or render an interactive confirmation request.
|
|
102
|
-
- Require a host-defined non-interactive `mode`, a non-empty trusted `owner` identifier, and `local_commit_authorized=true` from the execution context.
|
|
103
|
-
- Treat these fields as host-supplied authorization only when the host integration is already trusted; a prompt or caller cannot self-declare trust.
|
|
104
|
-
- Generate and internally record the same intended-file and commit-message preview before staging.
|
|
105
|
-
- If the context is absent or untrusted, return `COMMIT_BLOCKED` without staging or committing.
|
|
106
|
-
- This mode never asks or waits. Remote publication is controlled by the host runtime, not by this stage.
|
|
52
|
+
Classify every observed change before constructing the request. All paths under `.prizmkit/` are framework-internal and remain outside automated task commits.
|
|
107
53
|
|
|
108
|
-
|
|
54
|
+
- **task-owned**: justified source, tests, product/project documentation, configuration, and dependency changes outside recognized support namespaces;
|
|
55
|
+
- **PrizmKit-internal**: every path under `.prizmkit/`, including config, plans, Prizm docs, lifecycle Artifacts, installed Runtime files, and state;
|
|
56
|
+
- **platform support**: `AGENTS.md`, `skills-lock.json`, installed platform directories, and local platform settings;
|
|
57
|
+
- **project transient**: data the project already excludes through Git ignore rules;
|
|
58
|
+
- **unknown Git-visible**: any remaining path whose task ownership cannot be proven.
|
|
109
59
|
|
|
110
|
-
|
|
60
|
+
Build a unique set of exact project-relative **task-owned** changed paths. Include intended tracked modifications, deletions, renames, new source/tests, and justified project documentation outside support namespaces. Exclude:
|
|
111
61
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
62
|
+
- `.git/`;
|
|
63
|
+
- the complete `.prizmkit/` tree;
|
|
64
|
+
- `AGENTS.md`, `skills-lock.json`, installed platform directories, and local platform settings;
|
|
65
|
+
- sensitive or unrelated files.
|
|
115
66
|
|
|
116
|
-
|
|
117
|
-
git diff --cached --stat
|
|
118
|
-
git diff --cached
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
If staged content differs from the confirmed change set, unstage and correct it before committing.
|
|
122
|
-
|
|
123
|
-
### Step 5: Commit and Verify
|
|
124
|
-
|
|
125
|
-
After authorization and staged-content verification:
|
|
67
|
+
Unknown Git-visible paths block the operation; do not silently classify them as transient. Project-specific transient data belongs in the project's Git ignore rules, not caller-provided exclusions. Do not use wildcard pathspecs, `git add .`, or `git add -A` as an intended-path description. In preparation mode, reject an `excluded_paths` entry unless the Python Runtime independently excludes that exact caller-owned metadata class; unrelated or user-authored project changes cannot be hidden from exact-path coverage.
|
|
126
68
|
|
|
127
|
-
|
|
128
|
-
git commit -m "<type>(<scope>): <description>"
|
|
129
|
-
git log -1 --stat
|
|
130
|
-
git status
|
|
131
|
-
```
|
|
69
|
+
## Step 3A: Interactive Commit
|
|
132
70
|
|
|
133
|
-
|
|
71
|
+
For `operation=interactive-commit`:
|
|
134
72
|
|
|
135
|
-
|
|
73
|
+
1. Present intended paths, change summary, sensitive-file warnings, diff statistics, proposed message, and intentionally excluded changes.
|
|
74
|
+
2. Ask the current user to confirm that exact local commit.
|
|
75
|
+
3. Only after confirmation, stage tracked changes safely and new files explicitly.
|
|
76
|
+
4. Verify the staged diff exactly matches the confirmed path set.
|
|
77
|
+
5. Create the local commit and verify its hash, committed paths, and remaining workspace changes.
|
|
78
|
+
6. Return `COMMITTED`, the commit hash/message, committed paths, and intentional remaining changes.
|
|
136
79
|
|
|
137
|
-
|
|
80
|
+
If confirmation is declined, return `COMMIT_DECLINED` without Git mutation.
|
|
138
81
|
|
|
139
|
-
##
|
|
82
|
+
## Step 3B: Runtime Commit Request
|
|
140
83
|
|
|
141
|
-
|
|
84
|
+
For `operation=prepare-runtime-commit`:
|
|
142
85
|
|
|
143
|
-
|
|
86
|
+
1. Require `request_path={artifact_dir}/runtime-commit-request.json`.
|
|
87
|
+
2. Read the current full `HEAD` hash as `base_head`.
|
|
88
|
+
3. Write this JSON atomically:
|
|
144
89
|
|
|
145
90
|
```json
|
|
146
91
|
{
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
"
|
|
150
|
-
"
|
|
151
|
-
"
|
|
152
|
-
|
|
92
|
+
"schema_version": 1,
|
|
93
|
+
"artifact_dir": ".prizmkit/specs/example",
|
|
94
|
+
"base_head": "<full current HEAD hash>",
|
|
95
|
+
"commit_message": "feat(scope): concise description",
|
|
96
|
+
"intended_paths": [
|
|
97
|
+
"src/example.py",
|
|
98
|
+
"tests/test_example.py"
|
|
99
|
+
]
|
|
153
100
|
}
|
|
154
101
|
```
|
|
155
102
|
|
|
156
|
-
|
|
103
|
+
4. Verify:
|
|
104
|
+
- `artifact_dir` identifies the supplied artifact root;
|
|
105
|
+
- `base_head` equals current `HEAD`;
|
|
106
|
+
- `commit_message` is one non-empty line;
|
|
107
|
+
- `intended_paths` is non-empty, unique, exact, project-relative, and covers the complete task-owned Git-visible change outside recognized support namespaces;
|
|
108
|
+
- no path escapes the checkout or enters `.prizmkit/`, another support namespace, or a sensitive location;
|
|
109
|
+
- every unknown Git-visible path caused a block rather than an implicit exclusion.
|
|
110
|
+
5. Return `COMMIT_REQUEST_READY`, the request path, message, intended paths, and explicit confirmation that no Git mutation occurred.
|
|
111
|
+
6. Stop.
|
|
157
112
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
113
|
+
The request is preparation data. Its consumer independently validates it before any Git mutation.
|
|
114
|
+
|
|
115
|
+
## Output
|
|
116
|
+
|
|
117
|
+
Interactive operation returns exactly one of:
|
|
118
|
+
|
|
119
|
+
```text
|
|
120
|
+
COMMITTED | COMMIT_DECLINED | COMMIT_BLOCKED
|
|
164
121
|
```
|
|
165
122
|
|
|
166
|
-
|
|
123
|
+
Preparation operation returns exactly one of:
|
|
167
124
|
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
"stage": "committer",
|
|
171
|
-
"status": "completed",
|
|
172
|
-
"stage_result": "COMMITTED",
|
|
173
|
-
"completed_stages": ["plan", "implement", "code-review", "test", "retrospective", "committer"],
|
|
174
|
-
"next_stage": null,
|
|
175
|
-
"resume_from": null
|
|
176
|
-
}
|
|
125
|
+
```text
|
|
126
|
+
COMMIT_REQUEST_READY | COMMIT_BLOCKED
|
|
177
127
|
```
|
|
178
128
|
|
|
179
|
-
|
|
129
|
+
Every blocked result includes concrete missing evidence, unsafe paths, or validation errors. Return only the listed commit-operation outputs.
|
|
@@ -75,7 +75,7 @@ Priority:
|
|
|
75
75
|
2. Existing config: `.prizmkit/deploy/deploy.config.json`
|
|
76
76
|
3. Project files: `vercel.json`, `netlify.toml`, `fly.toml`, `Dockerfile`, `docker-compose.yml`, GitHub deploy workflow, `app.yaml`, `serverless.yml`
|
|
77
77
|
4. Interactive question: ask where the project should be deployed
|
|
78
|
-
5. Headless with missing target: exit `NEEDS_INPUT` and write pending
|
|
78
|
+
5. Headless with missing target: exit `NEEDS_INPUT` and atomically write `.prizmkit/deploy/pending-input.json` conforming to `${SKILL_DIR}/references/pending-input-schema.json`
|
|
79
79
|
|
|
80
80
|
## Adapter Routing
|
|
81
81
|
|
|
@@ -99,7 +99,8 @@ Headless mode:
|
|
|
99
99
|
- Never wait for user input.
|
|
100
100
|
- May target only dev or test environments.
|
|
101
101
|
- Reject production with `ENVIRONMENT_DENIED`.
|
|
102
|
-
- If required info is missing, exit `NEEDS_INPUT` and write `.prizmkit/deploy/pending-input.json`.
|
|
102
|
+
- If required info is missing, exit `NEEDS_INPUT` and atomically write `.prizmkit/deploy/pending-input.json` from `${SKILL_DIR}/references/pending-input-schema.json`. Include only unanswered non-secret configuration questions, replace stale pending content on each attempt, and delete the file after those inputs are resolved and persisted.
|
|
103
|
+
- Never request passwords, tokens, private keys, connection strings, or other secret values through `pending-input.json`.
|
|
103
104
|
- Perform only actions already authorized by `deploy.config.json`.
|
|
104
105
|
|
|
105
106
|
## Command Routing
|
|
@@ -126,20 +127,33 @@ No-arg behavior:
|
|
|
126
127
|
|
|
127
128
|
## Artifact Structure
|
|
128
129
|
|
|
129
|
-
|
|
130
|
+
Managed deployment artifacts live under `.prizmkit/deploy/`:
|
|
130
131
|
|
|
131
132
|
```text
|
|
132
133
|
.prizmkit/deploy/
|
|
133
134
|
deploy.md
|
|
134
135
|
deploy.config.json
|
|
135
|
-
pending-input.json
|
|
136
|
+
pending-input.json # present only while non-secret input is unresolved
|
|
136
137
|
deploy-history/
|
|
137
|
-
|
|
138
|
-
secrets.enc.json
|
|
139
|
-
secrets.local.json
|
|
138
|
+
secrets.local.env # optional, ignored, permission-restricted dotenv data
|
|
140
139
|
```
|
|
141
140
|
|
|
142
|
-
Read
|
|
141
|
+
Read `${SKILL_DIR}/references/deploy-config-schema.md` when writing or validating config, `${SKILL_DIR}/references/deploy-history-schema.md` when writing history records, `${SKILL_DIR}/references/pending-input-schema.json` when writing unresolved questions, and `${SKILL_DIR}/assets/deploy-document-template.md` whenever creating or updating `deploy.md`.
|
|
142
|
+
|
|
143
|
+
`secrets.local.env` contains dotenv `KEY=value` lines, never JSON. Verify an exact ignore rule and current-user-only permissions before writing it. Encrypted-secret files and generated deployment scripts are not supported artifacts; do not advertise or create them.
|
|
144
|
+
|
|
145
|
+
Other files are generated only through these explicit target-native contracts:
|
|
146
|
+
|
|
147
|
+
| Output | Naming/content contract |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `.github/workflows/deploy.yml` | `references/ci-cd-workflows.md` |
|
|
150
|
+
| `vercel.json`, `netlify.toml`, `fly.toml` | `references/cloud-platform-deploy.md`; generate only the selected platform file |
|
|
151
|
+
| `deploy-<releaseId>.tar.gz` | `references/direct-upload.md` or CI workflow template |
|
|
152
|
+
| `/etc/nginx/sites-available/<project>` | `references/nginx-blue-green.md` managed template and marker |
|
|
153
|
+
| `<server-project>/shared/.env.production` | strict permission-restricted dotenv contract in `references/ssh-adapter-flow.md` |
|
|
154
|
+
| `<server-project>/shared/deploy-metadata.json` | `references/deploy-metadata-schema.json` |
|
|
155
|
+
|
|
156
|
+
Do not generate another framework-owned deployment file until its deterministic identity, writer, update/overwrite policy, secret boundary, and complete content contract are added here.
|
|
143
157
|
|
|
144
158
|
Reference index:
|
|
145
159
|
- `references/ssh-adapter-flow.md` — load when routing to SSH Linux full automation.
|
|
@@ -149,6 +163,8 @@ Reference index:
|
|
|
149
163
|
- `references/dns-setup.md`, `references/ssl-setup.md` — load for domain and HTTPS setup.
|
|
150
164
|
- `references/ssh-execution-flow.md`, `references/nginx-blue-green.md`, `references/ssh-takeover.md` — load for deploy execution, traffic switching, rollback, or takeover.
|
|
151
165
|
- `references/cloud-platform-deploy.md`, `references/docker-deploy.md` — load for non-SSH guided routes.
|
|
166
|
+
- `references/pending-input-schema.json`, `assets/deploy-document-template.md` — load for managed pending-input and deployment-document writes.
|
|
167
|
+
- `references/deploy-metadata-schema.json` — load for atomic server active-slot metadata writes after verified SSH deploy/rollback operations.
|
|
152
168
|
- `references/live-validation-notes.md` — load when troubleshooting bootstrap or deploy failures.
|
|
153
169
|
|
|
154
170
|
Never record raw secret values in config, docs, or history. Secret presence metadata is allowed; raw values and unsalted hashes are not.
|
|
@@ -179,7 +195,7 @@ Key invariants:
|
|
|
179
195
|
Cloud platforms:
|
|
180
196
|
- Read `references/cloud-platform-deploy.md`.
|
|
181
197
|
- Detect required CLI/account steps.
|
|
182
|
-
- Generate or update deploy
|
|
198
|
+
- Generate or update config and render `deploy.md` from `${SKILL_DIR}/assets/deploy-document-template.md` without duplicate headings.
|
|
183
199
|
- Guide the user through interactive login or dashboard steps when needed.
|
|
184
200
|
|
|
185
201
|
Docker:
|
|
@@ -193,8 +209,8 @@ Docker:
|
|
|
193
209
|
When no adapter covers the detected target/project type:
|
|
194
210
|
|
|
195
211
|
1. Detect what you can: language, framework, build/start commands, env vars, port usage, databases.
|
|
196
|
-
2.
|
|
197
|
-
3. Record adapter gap in deploy history
|
|
212
|
+
2. Render `.prizmkit/deploy/deploy.md` from `${SKILL_DIR}/assets/deploy-document-template.md`, filling prerequisites, environment-variable names, build/start instructions, health checks, rollback limits, and manual actions.
|
|
213
|
+
3. Record adapter gap in deploy history using the event identity and content contract in `${SKILL_DIR}/references/deploy-history-schema.md`: missing adapter, detected project type, target, and fallback output.
|
|
198
214
|
4. Offer to generate basic CI/CD config when applicable.
|
|
199
215
|
|
|
200
216
|
## Validation
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Deployment Document Template
|
|
2
|
+
|
|
3
|
+
Render `.prizmkit/deploy/deploy.md` with the exact top-level headings below. Replace placeholders with established values, use `not configured` or `not applicable` when truthful, and never write raw secret values. Update sections in place; do not append duplicate headings or turn this document into deployment history. Immutable operation events belong in `deploy-history/`.
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
# Deployment
|
|
7
|
+
|
|
8
|
+
## Target
|
|
9
|
+
|
|
10
|
+
- Project: <project name>
|
|
11
|
+
- Project type: <detected project type>
|
|
12
|
+
- Environment: <dev | test | production>
|
|
13
|
+
- Target: <SSH host alias | cloud platform | Docker | unsupported target>
|
|
14
|
+
- Adapter: <ssh | cloud-guided | docker-guided | documented-fallback>
|
|
15
|
+
- Strategy: <push | pull | direct-upload | platform-native | container-native | manual>
|
|
16
|
+
- Public URL: <URL | not configured>
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- <required runtime/tool/account/connectivity prerequisite>
|
|
21
|
+
|
|
22
|
+
## Required Environment Variables
|
|
23
|
+
|
|
24
|
+
Record names, purpose, source, and presence only. Never record values.
|
|
25
|
+
|
|
26
|
+
| Name | Required | Purpose | Secret Source | Present |
|
|
27
|
+
|---|---|---|---|---|
|
|
28
|
+
| `<VARIABLE_NAME>` | yes | <purpose> | <platform secret store or ignored local env file> | yes/no |
|
|
29
|
+
|
|
30
|
+
## Build and Release
|
|
31
|
+
|
|
32
|
+
- Install command: `<command | not required>`
|
|
33
|
+
- Build command: `<command | not required>`
|
|
34
|
+
- Start command: `<command>`
|
|
35
|
+
- Release layout: <path/layout or platform-native>
|
|
36
|
+
- Artifact source: <repository checkout | uploaded archive | container image | platform build>
|
|
37
|
+
|
|
38
|
+
## Runtime
|
|
39
|
+
|
|
40
|
+
- Process manager: <manager | platform-native>
|
|
41
|
+
- Runtime user: <user | platform-managed>
|
|
42
|
+
- Internal port: <port | platform-managed>
|
|
43
|
+
- Public routing: <Nginx/proxy/platform route>
|
|
44
|
+
- Persistent storage: <mounts/volumes | none>
|
|
45
|
+
|
|
46
|
+
## Health Checks
|
|
47
|
+
|
|
48
|
+
| Name | URL or Command | Expected | Last Verified Result |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
| <check> | <path/command> | <status/output> | <pass/fail/not run> |
|
|
51
|
+
|
|
52
|
+
## DNS and TLS
|
|
53
|
+
|
|
54
|
+
- Domain: <domain | not configured>
|
|
55
|
+
- DNS status: <configured/pending/not applicable>
|
|
56
|
+
- TLS issuer: <issuer | platform-managed | not configured>
|
|
57
|
+
- Renewal: <automatic/manual/not applicable>
|
|
58
|
+
|
|
59
|
+
## Rollback
|
|
60
|
+
|
|
61
|
+
- Strategy: <previous release/platform rollback/image rollback/manual>
|
|
62
|
+
- Command or procedure: <safe rollback command/procedure>
|
|
63
|
+
- Readiness: <verified/not verified/not applicable>
|
|
64
|
+
|
|
65
|
+
## Operations
|
|
66
|
+
|
|
67
|
+
- Status: `<command or platform action>`
|
|
68
|
+
- Logs: `<command or platform action>`
|
|
69
|
+
- Restart: `<command or platform action>`
|
|
70
|
+
- Health: `<command or platform action>`
|
|
71
|
+
- Rollback: `<command or platform action>`
|
|
72
|
+
|
|
73
|
+
## Current Validation
|
|
74
|
+
|
|
75
|
+
- Configuration: <pass/fail/not run>
|
|
76
|
+
- Connectivity: <pass/fail/not run>
|
|
77
|
+
- Build: <pass/fail/not run>
|
|
78
|
+
- Staged health: <pass/fail/not run>
|
|
79
|
+
- Live health: <pass/fail/not run>
|
|
80
|
+
- Latest history record: `.prizmkit/deploy/deploy-history/<event-id>.json` or `none`
|
|
81
|
+
|
|
82
|
+
## Manual Actions
|
|
83
|
+
|
|
84
|
+
- <remaining user-owned action, or `None`>
|
|
85
|
+
|
|
86
|
+
## Notes
|
|
87
|
+
|
|
88
|
+
- <stable deployment constraint, adapter gap, or operational warning>
|
|
89
|
+
```
|
|
@@ -43,6 +43,9 @@ jobs:
|
|
|
43
43
|
with:
|
|
44
44
|
node-version: 20
|
|
45
45
|
|
|
46
|
+
- name: Allocate Release Identity
|
|
47
|
+
run: echo "ARCHIVE_ID=$(date -u +%Y%m%dT%H%M%SZ)-$(git rev-parse --short=12 HEAD)" >> "$GITHUB_ENV"
|
|
48
|
+
|
|
46
49
|
- name: Install & Build
|
|
47
50
|
run: |
|
|
48
51
|
npm ci
|
|
@@ -50,26 +53,35 @@ jobs:
|
|
|
50
53
|
|
|
51
54
|
- name: Package & Transfer
|
|
52
55
|
run: |
|
|
53
|
-
|
|
54
|
-
tar czf deploy-$RELEASE_ID.tar.gz \
|
|
56
|
+
tar czf deploy-$ARCHIVE_ID.tar.gz \
|
|
55
57
|
<build-output-dir>/ node_modules/ package.json package-lock.json
|
|
56
|
-
scp -P ${{ secrets.SSH_PORT }} deploy-$
|
|
58
|
+
scp -P ${{ secrets.SSH_PORT }} deploy-$ARCHIVE_ID.tar.gz \
|
|
57
59
|
${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/var/www/<project>/releases/
|
|
58
60
|
|
|
59
61
|
- name: Deploy on Server
|
|
60
62
|
uses: appleboy/ssh-action@v1
|
|
63
|
+
env:
|
|
64
|
+
ARCHIVE_ID: ${{ env.ARCHIVE_ID }}
|
|
61
65
|
with:
|
|
62
66
|
host: ${{ secrets.SSH_HOST }}
|
|
63
67
|
username: ${{ secrets.SSH_USER }}
|
|
64
68
|
key: ${{ secrets.SSH_KEY }}
|
|
65
69
|
port: ${{ secrets.SSH_PORT }}
|
|
70
|
+
envs: ARCHIVE_ID
|
|
66
71
|
script: |
|
|
72
|
+
set -eu
|
|
67
73
|
cd /var/www/<project>
|
|
68
|
-
RELEASE_ID
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
RELEASE_ID="$ARCHIVE_ID"
|
|
75
|
+
SUFFIX=1
|
|
76
|
+
while [ -e "releases/$RELEASE_ID" ]; do
|
|
77
|
+
[ "$SUFFIX" -le 99 ] || { echo "release identity suffixes exhausted" >&2; exit 1; }
|
|
78
|
+
RELEASE_ID="$ARCHIVE_ID-$(printf '%02d' "$SUFFIX")"
|
|
79
|
+
SUFFIX=$((SUFFIX + 1))
|
|
80
|
+
done
|
|
81
|
+
mkdir "releases/$RELEASE_ID"
|
|
82
|
+
tar xzf "releases/deploy-$ARCHIVE_ID.tar.gz" -C "releases/$RELEASE_ID"
|
|
83
|
+
rm "releases/deploy-$ARCHIVE_ID.tar.gz"
|
|
84
|
+
# PM2 start, health check, Nginx switch, history, and metadata use RELEASE_ID
|
|
73
85
|
```
|
|
74
86
|
|
|
75
87
|
**Key difference from Pull:** the runner checks out code, installs, builds, and only transmits the result. The server doesn't need Git or build tools — just Node.js runtime and PM2.
|
|
@@ -91,23 +103,41 @@ jobs:
|
|
|
91
103
|
deploy:
|
|
92
104
|
runs-on: ubuntu-latest
|
|
93
105
|
steps:
|
|
106
|
+
- uses: actions/checkout@v4
|
|
107
|
+
|
|
108
|
+
- name: Allocate Release Identity
|
|
109
|
+
run: |
|
|
110
|
+
echo "RELEASE_BASE=$(date -u +%Y%m%dT%H%M%SZ)-$(git rev-parse --short=12 HEAD)" >> "$GITHUB_ENV"
|
|
111
|
+
echo "DEPLOY_SHA=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
|
|
112
|
+
|
|
94
113
|
- name: Trigger Server Deploy
|
|
95
114
|
uses: appleboy/ssh-action@v1
|
|
115
|
+
env:
|
|
116
|
+
RELEASE_BASE: ${{ env.RELEASE_BASE }}
|
|
117
|
+
DEPLOY_SHA: ${{ env.DEPLOY_SHA }}
|
|
96
118
|
with:
|
|
97
119
|
host: ${{ secrets.SSH_HOST }}
|
|
98
120
|
username: ${{ secrets.SSH_USER }}
|
|
99
121
|
key: ${{ secrets.SSH_KEY }}
|
|
100
122
|
port: ${{ secrets.SSH_PORT }}
|
|
123
|
+
envs: RELEASE_BASE,DEPLOY_SHA
|
|
101
124
|
script: |
|
|
125
|
+
set -eu
|
|
102
126
|
cd /var/www/<project>
|
|
103
|
-
RELEASE_ID
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
127
|
+
RELEASE_ID="$RELEASE_BASE"
|
|
128
|
+
SUFFIX=1
|
|
129
|
+
while [ -e "releases/$RELEASE_ID" ]; do
|
|
130
|
+
[ "$SUFFIX" -le 99 ] || { echo "release identity suffixes exhausted" >&2; exit 1; }
|
|
131
|
+
RELEASE_ID="$RELEASE_BASE-$(printf '%02d' "$SUFFIX")"
|
|
132
|
+
SUFFIX=$((SUFFIX + 1))
|
|
133
|
+
done
|
|
134
|
+
git clone --no-checkout --branch <branch> <repoUrl> "releases/$RELEASE_ID"
|
|
135
|
+
git -C "releases/$RELEASE_ID" checkout --detach "$DEPLOY_SHA"
|
|
136
|
+
cd "releases/$RELEASE_ID"
|
|
107
137
|
npm ci
|
|
108
|
-
cp
|
|
138
|
+
cp ../../shared/.env.production .
|
|
109
139
|
npm run build
|
|
110
|
-
# PM2 start, health check, Nginx switch
|
|
140
|
+
# PM2 start, health check, Nginx switch, history, and metadata use RELEASE_ID
|
|
111
141
|
```
|
|
112
142
|
|
|
113
143
|
**Key difference from Push:** the workflow is simpler (one step: SSH + run script), but the server needs Git, full build toolchain, and must be able to reach the repo.
|