autonomous-sdlc-harness 0.4.2 → 0.5.0
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/dist/commands/init.js +101 -13
- package/dist/commands/init.js.map +1 -1
- package/dist/config/check.js +1 -1
- package/dist/config/check.js.map +1 -1
- package/dist/config/model.js +17 -1
- package/dist/config/model.js.map +1 -1
- package/dist/core/writer.js +9 -5
- package/dist/core/writer.js.map +1 -1
- package/dist/core/yamlScalar.js +14 -0
- package/dist/core/yamlScalar.js.map +1 -0
- package/dist/doctor/checks.js +169 -15
- package/dist/doctor/checks.js.map +1 -1
- package/dist/generators/githubWorkflows.js +115 -20
- package/dist/generators/githubWorkflows.js.map +1 -1
- package/dist/generators/repoRoot.js +17 -8
- package/dist/generators/repoRoot.js.map +1 -1
- package/dist/remote/githubActions.js +51 -7
- package/dist/remote/githubActions.js.map +1 -1
- package/package.json +1 -1
- package/templates/README.md +1 -1
- package/templates/github/workflows/harness-resume.yml +2 -0
- package/templates/github/workflows/harness-run.yml +27 -11
- package/templates/github/workflows/harness-trigger.yml +143 -0
- package/templates/repo/gitignore +5 -0
- package/templates/scripts/autonomous-watcher.sh +92 -247
- package/templates/scripts/create-worktree.sh +52 -10
- package/templates/scripts/lib/harness-run-lib.sh +432 -11
- package/templates/scripts/remote-run.sh +1179 -106
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# harness-trigger.yml — starts an autonomous-sdlc-harness task run when an
|
|
2
|
+
# issue is labelled, or when a `repository_dispatch` asks for one.
|
|
3
|
+
#
|
|
4
|
+
# WHO WRITES IT. `autonomous-sdlc-harness init`, only when harness.config.json's
|
|
5
|
+
# `forge` is `github` and its `execution.target` is `github-actions`. Written
|
|
6
|
+
# create-if-absent: from then on it is yours to tune, and a re-run of `init`
|
|
7
|
+
# keeps your copy. `init --upgrade-workflows` does NOT re-render it: it carries
|
|
8
|
+
# no version pin and calls the scripts on the default branch, so it shares
|
|
9
|
+
# their re-run contract — `init --force` replaces it after a `.bak`.
|
|
10
|
+
#
|
|
11
|
+
# WHAT IT DOES. One job runs `remote-run.sh trigger`, which does everything
|
|
12
|
+
# else: it authorises the start, derives the branch, places and commits the task
|
|
13
|
+
# prompt, pushes, dispatches harness-run.yml, comments on the issue and removes
|
|
14
|
+
# the label. Every decision lives in that script; this file carries only the
|
|
15
|
+
# events, the permissions and the label filter. The `run-name` below is not
|
|
16
|
+
# harness-run.yml's `harness <action> <branch>` title, so no run lookup
|
|
17
|
+
# `remote-run.sh` makes by that title can match a trigger run.
|
|
18
|
+
#
|
|
19
|
+
# THE EVENTS.
|
|
20
|
+
# issues, type `labeled` only, never `opened`: labelling an issue at creation
|
|
21
|
+
# raises `labeled` too, so listening to both would start twice
|
|
22
|
+
# (docs/github-integration-research.md, T1). The job runs only for the
|
|
23
|
+
# label the HARNESS_TRIGGER_LABEL variable names (`harness` when unset);
|
|
24
|
+
# every other label yields a skipped job, which runs no runner and bills
|
|
25
|
+
# nothing (docs/remote-execution.md, `### Verified in Gate 12 round 2`).
|
|
26
|
+
# repository_dispatch, type `harness-task`: the entry for any other adapter
|
|
27
|
+
# (a Jira rule, a script). Its body is
|
|
28
|
+
# {"event_type": "harness-task",
|
|
29
|
+
# "client_payload": {"title": …, "body": …, "source": …}}
|
|
30
|
+
# within GitHub's client_payload limits (10 top-level properties, under
|
|
31
|
+
# 64 KB). Sending one needs a token with Contents write, so its holder is
|
|
32
|
+
# the authority.
|
|
33
|
+
#
|
|
34
|
+
# WHO CAN START A RUN. `remote-run.sh`'s `trigger` paragraph owns the check —
|
|
35
|
+
# the labeller, bots and HARNESS_TRIGGER_ALLOWED_BOTS, the permission call —
|
|
36
|
+
# and the order its refusals are made in. Nothing here pre-filters on it.
|
|
37
|
+
#
|
|
38
|
+
# THE PERMISSIONS, declared because the default token may be read-only
|
|
39
|
+
# (docs/github-integration-research.md, T2):
|
|
40
|
+
# contents: write push the new branch carrying the task prompt
|
|
41
|
+
# actions: write dispatch harness-run.yml and look up the run it created
|
|
42
|
+
# issues: write comment on the issue and remove the trigger label
|
|
43
|
+
# The job reads no repository secret: it needs only its own token, so the
|
|
44
|
+
# credential secrets never reach the job that reads untrusted issue text.
|
|
45
|
+
#
|
|
46
|
+
# THE CHECKOUT. The default branch, with the job's own token and never
|
|
47
|
+
# HARNESS_GIT_TOKEN: a branch pushed with GITHUB_TOKEN starts no workflow
|
|
48
|
+
# (docs/remote-execution.md, `### Verified in Gate 12 round 3`), so the prompt
|
|
49
|
+
# commit does not run your CI. A full fetch, because pushing a new branch from
|
|
50
|
+
# a shallow clone has not been measured anywhere.
|
|
51
|
+
#
|
|
52
|
+
# NO CONCURRENCY GROUP. A group keeps at most one pending run and cancels an
|
|
53
|
+
# earlier pending one, which would drop a trigger. Two starts that race for one
|
|
54
|
+
# branch name are caught by the refused push of an existing branch, and the
|
|
55
|
+
# refusal is commented on the issue.
|
|
56
|
+
#
|
|
57
|
+
# TWO RULES EVERY EDIT KEEPS.
|
|
58
|
+
# * Event text and variables reach a shell line only through `env:` and the
|
|
59
|
+
# event file, never through a GitHub expression inside `run:` — an issue
|
|
60
|
+
# title is written by whoever opened the issue (script injection).
|
|
61
|
+
# * Every GitHub expression has a space after its opening braces. `init`
|
|
62
|
+
# renders its workflows with the CLI's double-brace token renderer, which
|
|
63
|
+
# reads a letter straight after the braces as a token; this file carries
|
|
64
|
+
# no token.
|
|
65
|
+
#
|
|
66
|
+
# DECLARED MIRRORS — a rename on either side is an edit to both:
|
|
67
|
+
# cli/src/remote/githubActions.ts WORKFLOW_TRIGGER_FILE, HARNESS_RUNNER,
|
|
68
|
+
# HARNESS_REMOTE_STOP, HARNESS_TRIGGER_LABEL,
|
|
69
|
+
# DEFAULT_TRIGGER_LABEL (`harness`),
|
|
70
|
+
# HARNESS_TRIGGER_ALLOWED_BOTS,
|
|
71
|
+
# TRIGGER_DISPATCH_EVENT_TYPE (`harness-task`)
|
|
72
|
+
# cli/src/config/model.ts DEFAULTS.scriptsDir
|
|
73
|
+
#
|
|
74
|
+
# ACTION PINS.
|
|
75
|
+
# actions/checkout@v5
|
|
76
|
+
# The lowest major whose own action.yml declares `runs.using: node24`, per a
|
|
77
|
+
# maintainer's lookups of its action.yml and release notes on
|
|
78
|
+
# 2026-09-29T08:21Z (UTC). That major's release notes require Actions Runner
|
|
79
|
+
# 2.327.1 or newer; a GitHub-hosted runner already has it, and a self-hosted
|
|
80
|
+
# one must run it (docs/remote-execution.md, section 8). A major tag, not a
|
|
81
|
+
# commit sha: it is GitHub's own `actions/` organisation, the owner of the
|
|
82
|
+
# runner and GITHUB_TOKEN this job already trusts, and a major tag takes the
|
|
83
|
+
# action's own patch and security releases where a sha would freeze your copy.
|
|
84
|
+
# Pin a sha in your copy if you want one.
|
|
85
|
+
|
|
86
|
+
name: harness-trigger
|
|
87
|
+
run-name: harness trigger ${{ github.event.issue.number || github.event.action }}
|
|
88
|
+
|
|
89
|
+
on:
|
|
90
|
+
issues:
|
|
91
|
+
types: [labeled]
|
|
92
|
+
repository_dispatch:
|
|
93
|
+
types: [harness-task]
|
|
94
|
+
|
|
95
|
+
permissions:
|
|
96
|
+
contents: write
|
|
97
|
+
actions: write
|
|
98
|
+
issues: write
|
|
99
|
+
|
|
100
|
+
defaults:
|
|
101
|
+
run:
|
|
102
|
+
shell: bash
|
|
103
|
+
|
|
104
|
+
jobs:
|
|
105
|
+
trigger:
|
|
106
|
+
if: github.event_name == 'repository_dispatch' || github.event.label.name == (vars.HARNESS_TRIGGER_LABEL || 'harness')
|
|
107
|
+
runs-on: ${{ vars.HARNESS_RUNNER || 'ubuntu-latest' }}
|
|
108
|
+
env:
|
|
109
|
+
GH_TOKEN: ${{ github.token }}
|
|
110
|
+
HARNESS_REMOTE_STOP: ${{ vars.HARNESS_REMOTE_STOP }}
|
|
111
|
+
HARNESS_REMOTE_SLUG: ${{ github.repository }}
|
|
112
|
+
HARNESS_TRIGGER_LABEL: ${{ vars.HARNESS_TRIGGER_LABEL }}
|
|
113
|
+
HARNESS_TRIGGER_ALLOWED_BOTS: ${{ vars.HARNESS_TRIGGER_ALLOWED_BOTS }}
|
|
114
|
+
steps:
|
|
115
|
+
- name: Check out the default branch
|
|
116
|
+
uses: actions/checkout@v5
|
|
117
|
+
with:
|
|
118
|
+
token: ${{ github.token }}
|
|
119
|
+
fetch-depth: 0
|
|
120
|
+
|
|
121
|
+
- name: Check for jq and gh
|
|
122
|
+
run: |
|
|
123
|
+
missing=""
|
|
124
|
+
for tool in jq gh; do
|
|
125
|
+
command -v "$tool" >/dev/null 2>&1 || missing="$missing $tool"
|
|
126
|
+
done
|
|
127
|
+
if [ -n "$missing" ]; then
|
|
128
|
+
echo "::error::this runner lacks:$missing. Install them on the self-hosted runner, or use a GitHub-hosted one."
|
|
129
|
+
exit 1
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
- name: Read the configuration
|
|
133
|
+
run: |
|
|
134
|
+
scripts_dir=$(jq -r '.scriptsDir // "scripts"' harness.config.json)
|
|
135
|
+
echo "SCRIPTS_DIR=${scripts_dir%/}" >> "$GITHUB_ENV"
|
|
136
|
+
|
|
137
|
+
- name: Set the git identity
|
|
138
|
+
run: |
|
|
139
|
+
git config user.name "github-actions[bot]"
|
|
140
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
141
|
+
|
|
142
|
+
- name: Start the run
|
|
143
|
+
run: bash "$SCRIPTS_DIR/remote-run.sh" trigger
|
package/templates/repo/gitignore
CHANGED
|
@@ -68,5 +68,10 @@
|
|
|
68
68
|
# rule a wired repository carries an untracked file from its first `config set` onward. The leading
|
|
69
69
|
# slash anchors it at the repository root, the only place the configuration is written.
|
|
70
70
|
/{{configBackupFile}}
|
|
71
|
+
# The copies `init --upgrade-workflows` and `init --force` take of the two remote-execution workflows
|
|
72
|
+
# and of the permission profile. The upgrade's report names each workflow copy in a diff command, and
|
|
73
|
+
# the profile copy carries this machine's absolute paths just as the profile does. Every other .bak a
|
|
74
|
+
# forced run writes is left visible on purpose.
|
|
75
|
+
{{harnessBackups}}
|
|
71
76
|
{{qaBrowserArtifacts}}
|
|
72
77
|
{{docsRetrievalIndex}}
|