@elalfner/relevo 0.7.0 → 0.9.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/.claude-plugin/plugin.json +1 -1
- package/README.es.md +1 -0
- package/README.md +1 -0
- package/package.json +1 -1
- package/scripts/doctor.mjs +5 -4
- package/scripts/init.mjs +25 -4
- package/scripts/lib/can-edit-issue.mjs +4 -1
- package/scripts/lib/cli.mjs +6 -4
- package/scripts/lib/config.mjs +19 -1
- package/scripts/lib/doctor.mjs +264 -25
- package/scripts/lib/github.mjs +15 -5
- package/scripts/lib/init.mjs +89 -6
- package/scripts/lib/labels.mjs +4 -0
- package/scripts/lib/messages.mjs +109 -0
- package/scripts/lib/next-step.mjs +12 -0
- package/scripts/lib/plan.mjs +29 -6
- package/scripts/lib/preflight.mjs +1 -1
- package/scripts/lib/review-events.mjs +6 -3
- package/scripts/lib/ship-github.mjs +87 -0
- package/scripts/lib/ship-unattended.mjs +271 -0
- package/scripts/lib/ship.mjs +15 -3
- package/scripts/lib/toolchain-check.mjs +6 -0
- package/scripts/lib/web-preflight.mjs +50 -4
- package/scripts/lib/workflow-upgrade.mjs +198 -0
- package/scripts/review-event.mjs +10 -1
- package/scripts/ship-check.mjs +6 -4
- package/scripts/ship-unattended.mjs +45 -0
- package/scripts/toolchain-check.mjs +3 -3
- package/scripts/web-hook.mjs +28 -0
- package/scripts/web-preflight.mjs +6 -5
- package/scripts/web-review.mjs +1 -1
- package/skills/doctor/SKILL.md +6 -5
- package/skills/go/SKILL.md +4 -2
- package/skills/init/SKILL.md +10 -4
- package/skills/review/SKILL.md +4 -3
- package/skills/ship/SKILL.md +3 -1
- package/stacks/vue.md +2 -2
- package/templates/agents/antigravity-step.yml +8 -5
- package/templates/relevo.yml +4 -0
- package/templates/workflows/relevo-digest.yml +11 -1
- package/templates/workflows/relevo-go.yml +33 -14
- package/templates/workflows/relevo-queue.yml +11 -1
- package/templates/workflows/relevo-review.yml +11 -1
- package/templates/workflows/relevo-ship.yml +136 -0
- package/templates/workflows/relevo-sla.yml +11 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# relevo-template: 0.9.0
|
|
2
|
+
# Relevo: ships an issue when a person applies the `relevo:ship` label to it.
|
|
3
|
+
# Copy to .github/workflows/relevo-ship.yml. If you renamed the ship label in relevo.yml, change it below too.
|
|
4
|
+
#
|
|
5
|
+
# It runs the steps of /relevo:ship with the same rules, and no model: it needs no model credential. The person who
|
|
6
|
+
# applied the label is the one judged (they must be the one who ships under review.merger), and the label is their
|
|
7
|
+
# written confirmation. It archives the specification on the branch, squash-merges the pull request, closes the issue
|
|
8
|
+
# and removes its labels. When anything stops it, it comments why on the issue and removes the label. Nothing from the
|
|
9
|
+
# pull request's branch is run: the scripts come from the published package and relevo.yml from the base branch.
|
|
10
|
+
#
|
|
11
|
+
# Checks: a push with the workflow token starts no workflows, so the archive commit gets no checks of its own. The
|
|
12
|
+
# checks of the approved head count for it, because it changes only openspec/. If the base branch REQUIRES status
|
|
13
|
+
# checks, GitHub refuses that merge: create a GitHub App for this repository (contents, pull requests and issues:
|
|
14
|
+
# read and write), store its id as the secret RELEVO_SHIP_APP_ID and its private key as RELEVO_SHIP_APP_KEY. The run
|
|
15
|
+
# then pushes, merges and closes with the App's token, so your CI runs on the archive commit, and waits for it. The App
|
|
16
|
+
# is also worth it when you rely on workflows that run on pushes to the base branch. Never add it to a bypass list.
|
|
17
|
+
#
|
|
18
|
+
# The repository variable RELEVO_CLOUD_SHIP set to `off` pauses it: the label then does nothing.
|
|
19
|
+
# This workflow runs from the default branch; it works only once it is there.
|
|
20
|
+
|
|
21
|
+
# Runner: `runs-on` comes from `runner.labels` in relevo.yml (`/relevo:init` writes it into this file, `/relevo:doctor` checks it).
|
|
22
|
+
# The runner needs git, gh and jq; Node and the tools of the job are installed per job. A self-hosted runner is assumed to
|
|
23
|
+
# persist between jobs, so the job puts its tools under $RUNNER_TEMP and removes what it adds to the workspace.
|
|
24
|
+
|
|
25
|
+
name: relevo-ship
|
|
26
|
+
|
|
27
|
+
# The version of @elalfner/relevo whose scripts this workflow runs. The plugin's templates carry the version they
|
|
28
|
+
# were released with, and `/relevo:init` reports this file as different when it is older; change it by hand to update.
|
|
29
|
+
env:
|
|
30
|
+
RELEVO_VERSION: '0.9.0'
|
|
31
|
+
# The version of OpenSpec that the job installs for itself.
|
|
32
|
+
OPENSPEC_VERSION: '1.14.3'
|
|
33
|
+
|
|
34
|
+
on:
|
|
35
|
+
issues:
|
|
36
|
+
types: [labeled]
|
|
37
|
+
|
|
38
|
+
# One ship per issue: a second label event waits for the first run and then finds the label gone or the issue closed.
|
|
39
|
+
concurrency:
|
|
40
|
+
group: relevo-ship-${{ github.event.issue.number }}
|
|
41
|
+
cancel-in-progress: false
|
|
42
|
+
|
|
43
|
+
permissions:
|
|
44
|
+
contents: write
|
|
45
|
+
issues: write
|
|
46
|
+
pull-requests: write
|
|
47
|
+
# To start the queue (relevo-queue.yml) after the close, which the workflow token's close does not start by itself.
|
|
48
|
+
actions: write
|
|
49
|
+
|
|
50
|
+
jobs:
|
|
51
|
+
ship:
|
|
52
|
+
# Any sender: a label applied by a bot is removed by the script without shipping anything.
|
|
53
|
+
if: vars.RELEVO_CLOUD_SHIP != 'off' && github.event.label.name == 'relevo:ship' && !github.event.issue.pull_request
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
# The run may wait up to 30 minutes for the checks of the archive commit.
|
|
56
|
+
timeout-minutes: 45
|
|
57
|
+
env:
|
|
58
|
+
HAS_APP: ${{ secrets.RELEVO_SHIP_APP_ID != '' && secrets.RELEVO_SHIP_APP_KEY != '' }}
|
|
59
|
+
steps:
|
|
60
|
+
# Only with the App: a token for this repository, used to push, merge and close.
|
|
61
|
+
- name: App token
|
|
62
|
+
id: app
|
|
63
|
+
if: env.HAS_APP == 'true'
|
|
64
|
+
uses: actions/create-github-app-token@v1
|
|
65
|
+
with:
|
|
66
|
+
app-id: ${{ secrets.RELEVO_SHIP_APP_ID }}
|
|
67
|
+
private-key: ${{ secrets.RELEVO_SHIP_APP_KEY }}
|
|
68
|
+
|
|
69
|
+
# The default branch, which holds this workflow and names the base branch. The script switches to the feature
|
|
70
|
+
# branch in this checkout only to run git and OpenSpec on it; it never installs or runs anything from it.
|
|
71
|
+
- uses: actions/checkout@v4
|
|
72
|
+
with:
|
|
73
|
+
path: work
|
|
74
|
+
fetch-depth: 0
|
|
75
|
+
token: ${{ steps.app.outputs.token || github.token }}
|
|
76
|
+
|
|
77
|
+
- uses: actions/setup-node@v4
|
|
78
|
+
with:
|
|
79
|
+
node-version: 22
|
|
80
|
+
|
|
81
|
+
- name: Install the Relevo scripts
|
|
82
|
+
# The published package at the version pinned above, unpacked outside the checkout so that the archive sees
|
|
83
|
+
# a clean working tree. A package without a script this job runs stops the run here, before anything changes.
|
|
84
|
+
run: |
|
|
85
|
+
mkdir -p "$RUNNER_TEMP/relevo"
|
|
86
|
+
npm pack "@elalfner/relevo@$RELEVO_VERSION" --silent --pack-destination "$RUNNER_TEMP" > /dev/null
|
|
87
|
+
tar -xzf "$RUNNER_TEMP"/elalfner-relevo-*.tgz --strip-components=1 -C "$RUNNER_TEMP/relevo"
|
|
88
|
+
for f in scripts/ship-unattended.mjs scripts/scan-diff.mjs scripts/check-archive.mjs scripts/stage.mjs scripts/fix-tasks.mjs scripts/conflict-scope.mjs scripts/render-message.mjs; do
|
|
89
|
+
[ -f "$RUNNER_TEMP/relevo/$f" ] || { echo "::error::The Relevo package $RELEVO_VERSION lacks $f"; exit 1; }
|
|
90
|
+
done
|
|
91
|
+
|
|
92
|
+
- name: Install OpenSpec
|
|
93
|
+
# Under the temporary folder of the job, at the pinned version: nothing global is left on a runner that persists.
|
|
94
|
+
run: |
|
|
95
|
+
npm install --prefix "$RUNNER_TEMP/openspec" "@fission-ai/openspec@$OPENSPEC_VERSION" --no-fund --no-audit
|
|
96
|
+
echo "$RUNNER_TEMP/openspec/node_modules/.bin" >> "$GITHUB_PATH"
|
|
97
|
+
env:
|
|
98
|
+
OPENSPEC_TELEMETRY: '0'
|
|
99
|
+
|
|
100
|
+
- name: Ship
|
|
101
|
+
working-directory: work
|
|
102
|
+
env:
|
|
103
|
+
GH_TOKEN: ${{ github.token }}
|
|
104
|
+
GH_PUSH_TOKEN: ${{ steps.app.outputs.token || github.token }}
|
|
105
|
+
OPENSPEC_TELEMETRY: '0'
|
|
106
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
107
|
+
ISSUE: ${{ github.event.issue.number }}
|
|
108
|
+
ACTOR: ${{ github.event.sender.login }}
|
|
109
|
+
ACTOR_TYPE: ${{ github.event.sender.type }}
|
|
110
|
+
run: |
|
|
111
|
+
git config user.name 'github-actions[bot]'
|
|
112
|
+
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
|
113
|
+
node "$RUNNER_TEMP/relevo/scripts/ship-unattended.mjs" --repo "$GITHUB_REPOSITORY" --issue "$ISSUE" --actor "$ACTOR" --actor-type "$ACTOR_TYPE" --work .
|
|
114
|
+
|
|
115
|
+
# A run that fails before it could comment (the package cannot be installed, a git or GitHub error) leaves the
|
|
116
|
+
# label on the issue with nobody told. If the label is still there, remove it and say so.
|
|
117
|
+
# If you renamed the ship label in relevo.yml, change the name below too.
|
|
118
|
+
- name: Report a run that ended without an outcome
|
|
119
|
+
if: always()
|
|
120
|
+
env:
|
|
121
|
+
GH_TOKEN: ${{ github.token }}
|
|
122
|
+
ISSUE: ${{ github.event.issue.number }}
|
|
123
|
+
ACTOR: ${{ github.event.sender.login }}
|
|
124
|
+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
125
|
+
run: |
|
|
126
|
+
labels=$(gh issue view "$ISSUE" --json labels --jq '.labels[].name')
|
|
127
|
+
if ! printf '%s\n' "$labels" | grep -qx 'relevo:ship'; then
|
|
128
|
+
exit 0
|
|
129
|
+
fi
|
|
130
|
+
gh issue edit "$ISSUE" --remove-label relevo:ship
|
|
131
|
+
body=""
|
|
132
|
+
if [ -f "$RUNNER_TEMP/relevo/scripts/render-message.mjs" ]; then
|
|
133
|
+
body=$(jq -n --arg issue "$ISSUE" --arg run "$RUN_URL" --arg actor "$ACTOR" '{issue: $issue, run: $run, actor: $actor}' | node "$RUNNER_TEMP/relevo/scripts/render-message.mjs" ship_failed --config work/relevo.yml) || body=""
|
|
134
|
+
fi
|
|
135
|
+
[ -n "$body" ] || body="@$ACTOR #$ISSUE was not shipped: the run ended without an outcome. Read the log to see why: $RUN_URL"
|
|
136
|
+
gh issue comment "$ISSUE" --body "$body"
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
# relevo-template: 0.9.0
|
|
1
2
|
# Relevo: reminds the reviewer when a pull request waits longer than limits.review_sla_hours, and escalates
|
|
2
3
|
# to the spec writer (adding the needs-reviewer label) after the same time again.
|
|
3
4
|
# Copy to .github/workflows/relevo-sla.yml. Needs a relevo.yml at the repository root.
|
|
4
5
|
# The scripts come from the published package @elalfner/relevo, at the version pinned in RELEVO_VERSION.
|
|
5
6
|
|
|
7
|
+
# Runner: `runs-on` comes from `runner.labels` in relevo.yml (`/relevo:init` writes it into this file, `/relevo:doctor` checks it).
|
|
8
|
+
# The runner needs git, gh and jq; Node and the tools of the job are installed per job. A self-hosted runner is assumed to
|
|
9
|
+
# persist between jobs, so the job puts its tools under $RUNNER_TEMP and removes what it adds to the workspace.
|
|
10
|
+
|
|
6
11
|
name: relevo-sla
|
|
7
12
|
|
|
8
13
|
# The version of @elalfner/relevo whose scripts this workflow runs. The plugin's templates carry the version they
|
|
9
14
|
# were released with, and `/relevo:init` reports this file as different when it is older; change it by hand to update.
|
|
10
15
|
env:
|
|
11
|
-
RELEVO_VERSION: '0.
|
|
16
|
+
RELEVO_VERSION: '0.9.0'
|
|
12
17
|
|
|
13
18
|
on:
|
|
14
19
|
schedule:
|
|
@@ -51,3 +56,8 @@ jobs:
|
|
|
51
56
|
GH_TOKEN: ${{ github.token }}
|
|
52
57
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
53
58
|
run: node .relevo-plugin/scripts/review-sla.mjs --repo "$GITHUB_REPOSITORY"
|
|
59
|
+
|
|
60
|
+
# A runner may keep its workspace between jobs (a self-hosted one does): remove what this job added to it.
|
|
61
|
+
- name: Remove what this job added
|
|
62
|
+
if: always()
|
|
63
|
+
run: rm -rf .relevo-plugin
|