its-magic 0.1.2-9 → 0.1.2
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/README.md +1602 -755
- package/bin/its-magic.js +121 -11
- package/bin/postinstall.js +21 -0
- package/installer.ps1 +759 -0
- package/installer.py +981 -0
- package/installer.sh +649 -0
- package/package.json +18 -14
- package/scripts/check_intake_template_parity.py +284 -0
- package/scripts/doc_profile_lib.py +415 -0
- package/scripts/guard_installer_publish.py +88 -0
- package/scripts/intake_bug_routing_guard.py +67 -0
- package/scripts/intake_evidence_lib.py +802 -0
- package/scripts/intake_evidence_validate.py +73 -0
- package/scripts/materialize_codebase_map.py +184 -0
- package/scripts/remote_config_summary.py +243 -0
- package/template/.cursor/agents/curator.mdc +35 -0
- package/template/.cursor/agents/dev.mdc +29 -0
- package/template/.cursor/agents/po.mdc +141 -0
- package/template/.cursor/agents/qa.mdc +28 -0
- package/template/.cursor/agents/release.mdc +28 -0
- package/template/.cursor/agents/security.mdc +98 -0
- package/template/.cursor/agents/tech-lead.mdc +57 -0
- package/template/.cursor/commands/architecture.md +127 -0
- package/template/.cursor/commands/ask.md +55 -0
- package/template/.cursor/commands/auto.md +533 -0
- package/template/.cursor/commands/discovery.md +47 -0
- package/template/.cursor/commands/execute.md +343 -0
- package/template/.cursor/commands/intake.md +323 -0
- package/template/.cursor/commands/map-codebase.md +46 -0
- package/template/.cursor/commands/memory-audit.md +175 -0
- package/template/.cursor/commands/milestone-complete.md +51 -0
- package/template/.cursor/commands/milestone-start.md +59 -0
- package/template/.cursor/commands/pause.md +64 -0
- package/{.cursor/commands/gsd-phase-context.md → template/.cursor/commands/phase-context.md} +6 -2
- package/template/.cursor/commands/plan-verify.md +34 -0
- package/template/.cursor/commands/qa.md +226 -0
- package/template/.cursor/commands/quick.md +41 -0
- package/template/.cursor/commands/refresh-context.md +82 -0
- package/template/.cursor/commands/release.md +505 -0
- package/template/.cursor/commands/research.md +49 -0
- package/template/.cursor/commands/resume.md +67 -0
- package/template/.cursor/commands/security-review.md +81 -0
- package/template/.cursor/commands/sprint-plan.md +103 -0
- package/template/.cursor/commands/status-reconcile.md +95 -0
- package/template/.cursor/commands/verify-work.md +152 -0
- package/template/.cursor/dev-environment.json.example +22 -0
- package/{.cursor → template/.cursor}/hooks/README.md +3 -2
- package/{.cursor/hooks/gsd-hook.py → template/.cursor/hooks/hook.py} +15 -6
- package/template/.cursor/hooks.json +26 -0
- package/template/.cursor/remote.json +31 -0
- package/template/.cursor/rules/caveman.mdc +184 -0
- package/template/.cursor/rules/coding-standards.mdc +39 -0
- package/template/.cursor/rules/core.mdc +111 -0
- package/template/.cursor/rules/handoffs.mdc +27 -0
- package/template/.cursor/rules/quality.mdc +49 -0
- package/template/.cursor/scratchpad.local.example.md +323 -0
- package/template/.cursor/scratchpad.md +324 -0
- package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/SKILL.md +2 -2
- package/template/.cursorignore +6 -0
- package/template/.env.example +28 -0
- package/template/.github/workflows/ci.yml +194 -0
- package/{.github → template/.github}/workflows/deploy.yml +5 -2
- package/template/.its-magic-version +1 -0
- package/template/README.md +1602 -0
- package/template/decisions/DEC-0001.md +11 -0
- package/template/decisions/DEC-0002.md +11 -0
- package/template/docs/developer/README.md +44 -0
- package/template/docs/engineering/architecture.md +9 -0
- package/template/docs/engineering/artifact-ordering-policy.md +48 -0
- package/template/docs/engineering/artifact-ownership-policy.md +57 -0
- package/template/docs/engineering/auto-orchestration-reference.md +1211 -0
- package/{docs → template/docs}/engineering/codebase-map.md +0 -5
- package/template/docs/engineering/compatibility-report.md +20 -0
- package/template/docs/engineering/compatibility-signals.md +7 -0
- package/template/docs/engineering/component-scope-report.md +16 -0
- package/template/docs/engineering/component-scope.md +19 -0
- package/template/docs/engineering/context/installer-owned-paths.manifest +96 -0
- package/template/docs/engineering/context/readme-section-affinity.json +30 -0
- package/template/docs/engineering/decisions.md +16 -0
- package/template/docs/engineering/legacy-drift-audit.md +21 -0
- package/template/docs/engineering/manifests/components/api-gateway.manifest.yaml +12 -0
- package/template/docs/engineering/manifests/registry.manifest.yaml +20 -0
- package/template/docs/engineering/manifests/repo.manifest.yaml +11 -0
- package/template/docs/engineering/phase-context.md +16 -0
- package/template/docs/engineering/release-targets.json +123 -0
- package/template/docs/engineering/research.md +29 -0
- package/template/docs/engineering/runbook.md +2320 -0
- package/template/docs/engineering/runtime-connectivity.md +81 -0
- package/template/docs/engineering/security-review.md +33 -0
- package/template/docs/engineering/spec-pack/README.md +20 -0
- package/template/docs/engineering/state-archive/README.md +15 -0
- package/template/docs/engineering/state.md +20 -0
- package/template/docs/engineering/status-normalization-report.md +19 -0
- package/template/docs/engineering/token-cost-parity-manifest.md +16 -0
- package/template/docs/engineering/us-0084-remote-e2e.md +44 -0
- package/template/docs/product/acceptance.md +1 -0
- package/template/docs/product/backlog.md +5 -0
- package/template/docs/product/vision.md +11 -0
- package/template/docs/user-guides/README.md +40 -0
- package/{handoffs → template/handoffs}/dev_to_qa.md +0 -3
- package/{handoffs → template/handoffs}/po_to_tl.md +0 -3
- package/{handoffs → template/handoffs}/qa_to_dev.md +1 -2
- package/template/handoffs/release_notes.md +51 -0
- package/template/handoffs/release_queue.md +47 -0
- package/template/handoffs/release_to_dev.md +31 -0
- package/template/handoffs/releases/Sxxxx-release-notes.md +62 -0
- package/template/handoffs/resume_brief.md +14 -0
- package/{handoffs → template/handoffs}/tl_to_dev.md +0 -2
- package/template/handoffs/token_cost_runs/README.md +26 -0
- package/template/its_magic/.its-magic-version +1 -0
- package/template/its_magic/README.md +9 -0
- package/template/scripts/auto_outer_driver.py +521 -0
- package/template/scripts/caveman_compress_input.py +903 -0
- package/template/scripts/check_downstream_ci_guard.py +67 -0
- package/template/scripts/check_intake_template_parity.py +284 -0
- package/template/scripts/check_token_cost_parity.py +69 -0
- package/template/scripts/dev_environment_lib.py +463 -0
- package/template/scripts/doc_profile_lib.py +415 -0
- package/template/scripts/downstream_ci_guard_lib.py +222 -0
- package/template/scripts/enforce-triad-hot-surface.py +753 -0
- package/template/scripts/guard_installer_publish.py +88 -0
- package/template/scripts/intake_bug_resume_brief_refresh.py +303 -0
- package/template/scripts/intake_bug_routing_guard.py +67 -0
- package/template/scripts/intake_evidence_lib.py +802 -0
- package/template/scripts/intake_evidence_validate.py +73 -0
- package/template/scripts/materialize_codebase_map.py +184 -0
- package/template/scripts/pack_json_validate.py +130 -0
- package/template/scripts/project_readme_coverage_lib.py +417 -0
- package/template/scripts/readme_feature_coverage_lib.py +608 -0
- package/template/scripts/remote_config_summary.py +243 -0
- package/template/scripts/sync_push_gates.py +198 -0
- package/template/scripts/token_cost_compare.py +40 -0
- package/template/scripts/token_cost_lib.py +108 -0
- package/template/scripts/uat_probe_lib.py +868 -0
- package/template/scripts/validate-and-push.ps1 +280 -0
- package/template/scripts/validate-and-push.sh +243 -0
- package/template/scripts/validate_doc_profile.py +103 -0
- package/template/scripts/validate_project_readme_coverage.py +151 -0
- package/template/scripts/validate_readme_feature_coverage.py +140 -0
- package/template/sprints/S0001/progress.md +1 -0
- package/template/sprints/S0001/qa-findings.md +9 -0
- package/template/sprints/S0001/release-findings.md +24 -0
- package/template/sprints/S0001/sprint.md +9 -0
- package/template/sprints/S0001/summary.md +7 -0
- package/template/sprints/S0001/tasks.md +1 -0
- package/template/sprints/S0001/uat.json +6 -0
- package/template/sprints/S0001/uat.md +5 -0
- package/template/sprints/quick/Q0001/summary.md +1 -0
- package/{sprints → template/sprints}/quick/Q0001/task.json +0 -1
- package/.cursor/agents/curator.mdc +0 -21
- package/.cursor/agents/dev.mdc +0 -20
- package/.cursor/agents/po.mdc +0 -19
- package/.cursor/agents/qa.mdc +0 -19
- package/.cursor/agents/release.mdc +0 -19
- package/.cursor/agents/tech-lead.mdc +0 -21
- package/.cursor/commands/gsd-architecture.md +0 -29
- package/.cursor/commands/gsd-auto.md +0 -27
- package/.cursor/commands/gsd-discovery.md +0 -27
- package/.cursor/commands/gsd-execute.md +0 -32
- package/.cursor/commands/gsd-intake.md +0 -28
- package/.cursor/commands/gsd-map-codebase.md +0 -25
- package/.cursor/commands/gsd-milestone-complete.md +0 -24
- package/.cursor/commands/gsd-milestone-start.md +0 -26
- package/.cursor/commands/gsd-pause.md +0 -25
- package/.cursor/commands/gsd-plan-verify.md +0 -26
- package/.cursor/commands/gsd-qa.md +0 -28
- package/.cursor/commands/gsd-quick.md +0 -24
- package/.cursor/commands/gsd-refresh-context.md +0 -26
- package/.cursor/commands/gsd-release.md +0 -29
- package/.cursor/commands/gsd-research.md +0 -28
- package/.cursor/commands/gsd-resume.md +0 -26
- package/.cursor/commands/gsd-sprint-plan.md +0 -30
- package/.cursor/commands/gsd-verify-work.md +0 -25
- package/.cursor/hooks.json +0 -26
- package/.cursor/plans/cursor-gsd-team-kit_8cfee9b8.plan.md +0 -57
- package/.cursor/remote.json +0 -18
- package/.cursor/rules/gsd-core.mdc +0 -18
- package/.cursor/rules/gsd-handoffs.mdc +0 -10
- package/.cursor/rules/gsd-quality.mdc +0 -15
- package/.cursor/scratchpad.md +0 -34
- package/.github/workflows/ci.yml +0 -47
- package/decisions/DEC-0001.md +0 -21
- package/decisions/DEC-0002.md +0 -21
- package/docs/engineering/architecture.md +0 -354
- package/docs/engineering/decisions.md +0 -6
- package/docs/engineering/research.md +0 -11
- package/docs/engineering/runbook.md +0 -32
- package/docs/engineering/state.md +0 -33
- package/docs/product/acceptance.md +0 -6
- package/docs/product/backlog.md +0 -7
- package/docs/product/vision.md +0 -46
- package/gsd-installer.ps1 +0 -189
- package/gsd-installer.py +0 -195
- package/gsd-installer.sh +0 -201
- package/handoffs/release_notes.md +0 -14
- package/handoffs/resume_brief.md +0 -8
- package/milestones/M0001/milestone.json +0 -7
- package/milestones/M0001/phases.json +0 -9
- package/milestones/M0001/progress.md +0 -3
- package/milestones/M0001/summary.md +0 -3
- package/scripts/generate-release-notes.ps1 +0 -74
- package/scripts/generate-release-notes.sh +0 -63
- package/scripts/release-all.ps1 +0 -423
- package/scripts/release-all.sh +0 -226
- package/sprints/S0001/progress.md +0 -4
- package/sprints/S0001/qa-findings.md +0 -113
- package/sprints/S0001/sprint.md +0 -70
- package/sprints/S0001/summary.md +0 -46
- package/sprints/S0001/tasks.md +0 -35
- package/sprints/S0001/uat.json +0 -8
- package/sprints/S0001/uat.md +0 -8
- package/sprints/quick/Q0001/summary.md +0 -3
- /package/{.cursor/rules/gsd-escalation.mdc → template/.cursor/rules/escalation.mdc} +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/acceptance.json +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/acceptance.md +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/architecture.json +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/architecture.md +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/decision.json +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/decision.md +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/handoff.json +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/handoff.md +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/milestone.json +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/phase-context.json +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/plan-verify.json +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/sprint.json +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/sprint.md +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/story.json +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/story.md +0 -0
- /package/{.cursor/skills/gsd-team → template/.cursor/skills/its-magic}/templates/uat.json +0 -0
- /package/{docs → template/docs}/engineering/context/phase-template.json +0 -0
- /package/{docs → template/docs}/engineering/dependencies.json +0 -0
- /package/{sprints → template/sprints}/S0001/plan-verify.json +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# .env.example — operator-local secret values (US-0085 / DEC-0071)
|
|
2
|
+
# Copy to .env, fill in values, source before remote/SSH/release ops.
|
|
3
|
+
# .env is gitignored and must NEVER be committed.
|
|
4
|
+
# This file lists names only — no secret values.
|
|
5
|
+
|
|
6
|
+
# ── From template/.cursor/remote.json (Cursor dev/remote targets) ──
|
|
7
|
+
REMOTE_DOCKER_TOKEN=
|
|
8
|
+
REMOTE_SSH_USER=
|
|
9
|
+
REMOTE_SSH_KEY_PATH=
|
|
10
|
+
|
|
11
|
+
# ── From docs/engineering/release-targets.json (release/QA targets) ──
|
|
12
|
+
PUBLIC_DOMAIN=
|
|
13
|
+
CHOCO_API_KEY=
|
|
14
|
+
GITHUB_TOKEN=
|
|
15
|
+
DOCKER_TOKEN=
|
|
16
|
+
DOCKER_RUNTIME_HOST=
|
|
17
|
+
AWS_PROFILE=
|
|
18
|
+
APP_DOMAIN=
|
|
19
|
+
APP_IP=
|
|
20
|
+
CUSTOM_DOMAIN=
|
|
21
|
+
CUSTOM_IP=
|
|
22
|
+
SSH_HOST=
|
|
23
|
+
SSH_USER=
|
|
24
|
+
SSH_PRIVATE_KEY=
|
|
25
|
+
RUNTIME_DOMAIN=
|
|
26
|
+
RUNTIME_IP=
|
|
27
|
+
DOCKER_HOST=
|
|
28
|
+
DOCKER_CONTEXT=
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
retry_count:
|
|
10
|
+
description: "Internal retry counter (do not set manually)"
|
|
11
|
+
required: false
|
|
12
|
+
default: "0"
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
pull-requests: write
|
|
17
|
+
|
|
18
|
+
env:
|
|
19
|
+
MAX_CI_RETRIES: 3
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
# ── Unit / structure tests (from runbook) ──────────────────────────
|
|
23
|
+
checks:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
outputs:
|
|
26
|
+
test_result: ${{ steps.test.outcome }}
|
|
27
|
+
lint_result: ${{ steps.lint.outcome }}
|
|
28
|
+
ci_auto_fix: ${{ steps.runbook.outputs.CI_AUTO_FIX }}
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
with:
|
|
32
|
+
ref: ${{ github.head_ref || github.ref_name }}
|
|
33
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
34
|
+
|
|
35
|
+
- id: runbook
|
|
36
|
+
name: Read runbook commands
|
|
37
|
+
run: |
|
|
38
|
+
python3 - <<'PY'
|
|
39
|
+
import os, pathlib, re
|
|
40
|
+
text = pathlib.Path("docs/engineering/runbook.md").read_text(encoding="utf-8")
|
|
41
|
+
command_section = text.split("## Notes", 1)[0]
|
|
42
|
+
def get(key):
|
|
43
|
+
m = re.search(rf"^{re.escape(key)}:[ \t]*(.*)$", command_section, re.M)
|
|
44
|
+
if not m:
|
|
45
|
+
return ""
|
|
46
|
+
val = m.group(1).strip()
|
|
47
|
+
if val in ("", "...", "<...>", "TODO", key, f"{key}:"):
|
|
48
|
+
return ""
|
|
49
|
+
if val.startswith(f"{key}:"):
|
|
50
|
+
return ""
|
|
51
|
+
return val
|
|
52
|
+
keys = ["TEST_COMMAND", "LINT_COMMAND", "TYPECHECK_COMMAND", "CI_AUTO_FIX"]
|
|
53
|
+
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
|
54
|
+
for key in keys:
|
|
55
|
+
val = get(key)
|
|
56
|
+
if val:
|
|
57
|
+
f.write(f"{key}={val}\n")
|
|
58
|
+
print(f" {key} = '{val}'")
|
|
59
|
+
else:
|
|
60
|
+
print(f" {key} = (skipped, empty)")
|
|
61
|
+
PY
|
|
62
|
+
|
|
63
|
+
- name: Test
|
|
64
|
+
id: test
|
|
65
|
+
if: ${{ steps.runbook.outputs.TEST_COMMAND != '' }}
|
|
66
|
+
continue-on-error: true
|
|
67
|
+
run: ${{ steps.runbook.outputs.TEST_COMMAND }}
|
|
68
|
+
|
|
69
|
+
- name: Lint
|
|
70
|
+
id: lint
|
|
71
|
+
if: ${{ steps.runbook.outputs.LINT_COMMAND != '' }}
|
|
72
|
+
continue-on-error: true
|
|
73
|
+
run: ${{ steps.runbook.outputs.LINT_COMMAND }}
|
|
74
|
+
|
|
75
|
+
- name: Typecheck
|
|
76
|
+
id: typecheck
|
|
77
|
+
if: ${{ steps.runbook.outputs.TYPECHECK_COMMAND != '' }}
|
|
78
|
+
run: ${{ steps.runbook.outputs.TYPECHECK_COMMAND }}
|
|
79
|
+
|
|
80
|
+
- name: No commands set
|
|
81
|
+
if: ${{ steps.runbook.outputs.TEST_COMMAND == '' && steps.runbook.outputs.LINT_COMMAND == '' && steps.runbook.outputs.TYPECHECK_COMMAND == '' }}
|
|
82
|
+
run: echo "no tests configured yet"
|
|
83
|
+
|
|
84
|
+
- name: Summarise results
|
|
85
|
+
if: always()
|
|
86
|
+
run: |
|
|
87
|
+
echo "### CI Results" >> "$GITHUB_STEP_SUMMARY"
|
|
88
|
+
if [ "${{ steps.runbook.outputs.TEST_COMMAND }}" = "" ] && [ "${{ steps.runbook.outputs.LINT_COMMAND }}" = "" ] && [ "${{ steps.runbook.outputs.TYPECHECK_COMMAND }}" = "" ]; then
|
|
89
|
+
echo "**no tests configured yet**" >> "$GITHUB_STEP_SUMMARY"
|
|
90
|
+
fi
|
|
91
|
+
echo "| Step | Result |" >> "$GITHUB_STEP_SUMMARY"
|
|
92
|
+
echo "|------|--------|" >> "$GITHUB_STEP_SUMMARY"
|
|
93
|
+
echo "| Test | ${{ steps.test.outcome || 'skipped' }} |" >> "$GITHUB_STEP_SUMMARY"
|
|
94
|
+
echo "| Lint | ${{ steps.lint.outcome || 'skipped' }} |" >> "$GITHUB_STEP_SUMMARY"
|
|
95
|
+
echo "| Typecheck | ${{ steps.typecheck.outcome || 'skipped' }} |" >> "$GITHUB_STEP_SUMMARY"
|
|
96
|
+
|
|
97
|
+
- name: Fail if tests or lint failed
|
|
98
|
+
if: ${{ steps.test.outcome == 'failure' || steps.lint.outcome == 'failure' }}
|
|
99
|
+
run: |
|
|
100
|
+
echo "::error::Tests or lint failed. See summary above."
|
|
101
|
+
exit 1
|
|
102
|
+
|
|
103
|
+
# ── Auto-fix attempt (runs only when checks fail) ─────────────────
|
|
104
|
+
auto-fix:
|
|
105
|
+
needs: checks
|
|
106
|
+
if: ${{ failure() && needs.checks.outputs.ci_auto_fix == 'true' && (github.event_name == 'push' || github.event_name == 'pull_request') }}
|
|
107
|
+
runs-on: ubuntu-latest
|
|
108
|
+
steps:
|
|
109
|
+
- uses: actions/checkout@v4
|
|
110
|
+
with:
|
|
111
|
+
ref: ${{ github.head_ref || github.ref_name }}
|
|
112
|
+
fetch-depth: 0
|
|
113
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
114
|
+
|
|
115
|
+
- name: Determine retry count
|
|
116
|
+
id: retry
|
|
117
|
+
run: |
|
|
118
|
+
COUNT="${{ github.event.inputs.retry_count || '0' }}"
|
|
119
|
+
echo "count=$COUNT" >> "$GITHUB_OUTPUT"
|
|
120
|
+
echo "Current retry: $COUNT / ${{ env.MAX_CI_RETRIES }}"
|
|
121
|
+
if [ "$COUNT" -ge "${{ env.MAX_CI_RETRIES }}" ]; then
|
|
122
|
+
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
123
|
+
echo "::warning::Max CI retries (${{ env.MAX_CI_RETRIES }}) reached. Manual intervention required."
|
|
124
|
+
else
|
|
125
|
+
echo "skip=false" >> "$GITHUB_OUTPUT"
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
- name: Read runbook for fix commands
|
|
129
|
+
id: runbook
|
|
130
|
+
if: ${{ steps.retry.outputs.skip != 'true' }}
|
|
131
|
+
run: |
|
|
132
|
+
python3 - <<'PY'
|
|
133
|
+
import os, pathlib, re
|
|
134
|
+
text = pathlib.Path("docs/engineering/runbook.md").read_text(encoding="utf-8")
|
|
135
|
+
command_section = text.split("## Notes", 1)[0]
|
|
136
|
+
def get(key):
|
|
137
|
+
m = re.search(rf"^{re.escape(key)}:[ \t]*(.*)$", command_section, re.M)
|
|
138
|
+
if not m:
|
|
139
|
+
return ""
|
|
140
|
+
val = m.group(1).strip()
|
|
141
|
+
if val in ("", "...", "<...>", "TODO", key, f"{key}:"):
|
|
142
|
+
return ""
|
|
143
|
+
if val.startswith(f"{key}:"):
|
|
144
|
+
return ""
|
|
145
|
+
return val
|
|
146
|
+
keys = ["LINT_FIX_COMMAND", "FORMAT_COMMAND"]
|
|
147
|
+
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
|
148
|
+
for key in keys:
|
|
149
|
+
val = get(key)
|
|
150
|
+
if val:
|
|
151
|
+
f.write(f"{key}={val}\n")
|
|
152
|
+
print(f" {key} = '{val}'")
|
|
153
|
+
else:
|
|
154
|
+
print(f" {key} = (not set)")
|
|
155
|
+
PY
|
|
156
|
+
|
|
157
|
+
- name: Run lint auto-fix
|
|
158
|
+
if: ${{ steps.retry.outputs.skip != 'true' && steps.runbook.outputs.LINT_FIX_COMMAND != '' }}
|
|
159
|
+
continue-on-error: true
|
|
160
|
+
run: ${{ steps.runbook.outputs.LINT_FIX_COMMAND }}
|
|
161
|
+
|
|
162
|
+
- name: Run formatter
|
|
163
|
+
if: ${{ steps.retry.outputs.skip != 'true' && steps.runbook.outputs.FORMAT_COMMAND != '' }}
|
|
164
|
+
continue-on-error: true
|
|
165
|
+
run: ${{ steps.runbook.outputs.FORMAT_COMMAND }}
|
|
166
|
+
|
|
167
|
+
- name: Check for changes and commit
|
|
168
|
+
if: ${{ steps.retry.outputs.skip != 'true' }}
|
|
169
|
+
id: commit
|
|
170
|
+
run: |
|
|
171
|
+
git config user.name "its-magic[bot]"
|
|
172
|
+
git config user.email "its-magic[bot]@users.noreply.github.com"
|
|
173
|
+
if git diff --quiet && git diff --cached --quiet; then
|
|
174
|
+
echo "No auto-fix changes to commit."
|
|
175
|
+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
|
|
176
|
+
else
|
|
177
|
+
NEXT=$(( ${{ steps.retry.outputs.count }} + 1 ))
|
|
178
|
+
git add -A
|
|
179
|
+
git commit -m "ci: auto-fix attempt $NEXT/${{ env.MAX_CI_RETRIES }}"
|
|
180
|
+
git push
|
|
181
|
+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
|
|
182
|
+
echo "Fixes committed and pushed. CI will re-run automatically."
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
- name: Post failure summary
|
|
186
|
+
if: ${{ steps.retry.outputs.skip == 'true' || steps.commit.outputs.has_changes == 'false' }}
|
|
187
|
+
run: |
|
|
188
|
+
echo "::error::CI failed and auto-fix could not resolve it."
|
|
189
|
+
echo ""
|
|
190
|
+
echo "What to do next:"
|
|
191
|
+
echo " 1. Pull the latest changes"
|
|
192
|
+
echo " 2. Run: bash scripts/validate-and-push.sh"
|
|
193
|
+
echo " (or: powershell scripts/validate-and-push.ps1)"
|
|
194
|
+
echo " 3. Fix failures, the script loops until green, then pushes."
|
|
@@ -25,11 +25,14 @@ jobs:
|
|
|
25
25
|
import re
|
|
26
26
|
|
|
27
27
|
text = pathlib.Path("docs/engineering/runbook.md").read_text()
|
|
28
|
+
command_section = text.split("## Notes", 1)[0]
|
|
28
29
|
|
|
29
30
|
def get(key):
|
|
30
|
-
m = re.search(rf"^{key}
|
|
31
|
+
m = re.search(rf"^{re.escape(key)}:[ \t]*(.*)$", command_section, re.M)
|
|
31
32
|
val = (m.group(1) or "").strip() if m else ""
|
|
32
|
-
if val in ("", "...", "<...>", "TODO"):
|
|
33
|
+
if val in ("", "...", "<...>", "TODO", key, f"{key}:"):
|
|
34
|
+
return ""
|
|
35
|
+
if val.startswith(f"{key}:"):
|
|
33
36
|
return ""
|
|
34
37
|
return val
|
|
35
38
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.0
|