@open-tomato/rafa 0.45.0 → 0.46.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/README.md +255 -23
- package/dist/PROMPT.md +18 -1
- package/dist/adapters/logger/settings.d.ts +132 -0
- package/dist/bugs/closest.d.ts +19 -0
- package/dist/bugs/fenced.d.ts +8 -0
- package/dist/bugs/places.d.ts +20 -0
- package/dist/bugs/record.d.ts +145 -0
- package/dist/bugs/title.d.ts +83 -0
- package/dist/bundled/agents/doc-updater.md +17 -3
- package/dist/bundled/agents/loop-implementer.md +14 -2
- package/dist/bundled/operators/skills/rafa-stretch-pit-stop/SKILL.md +10 -3
- package/dist/bundled/operators/skills/rafa-stretch-sweep/SKILL.md +5 -0
- package/dist/bundled/skills/dev-planner/SKILL.md +101 -18
- package/dist/cli.js +74726 -62960
- package/dist/config/entry.d.ts +119 -0
- package/dist/config/index.d.ts +36 -0
- package/dist/config/index.js +51 -0
- package/dist/config/shape.d.ts +232 -0
- package/dist/config-registry.d.ts +127 -0
- package/dist/config-schema-board-project.d.ts +157 -0
- package/dist/config-schema-bugs.d.ts +71 -0
- package/dist/config-schema-errors.d.ts +54 -0
- package/dist/config-schema-features.d.ts +64 -0
- package/dist/config-schema-hub.d.ts +150 -0
- package/dist/config-schema-issues.d.ts +95 -0
- package/dist/config-schema-logger.d.ts +91 -0
- package/dist/config-schema-loop-continue.d.ts +122 -0
- package/dist/config-schema-loop-retries.d.ts +94 -0
- package/dist/config-schema-release.d.ts +307 -0
- package/dist/config-schema-tests.d.ts +170 -0
- package/dist/config-schema-triage.d.ts +142 -0
- package/dist/config-schema-wrap-up.d.ts +96 -0
- package/dist/core/command/command.d.ts +228 -0
- package/dist/core/command/confirm.d.ts +67 -0
- package/dist/core/command/index.d.ts +112 -0
- package/dist/core/command/lazy.d.ts +54 -0
- package/dist/core/command/registry-types.d.ts +96 -0
- package/dist/core/command/running.d.ts +96 -0
- package/dist/core/command/spends.d.ts +39 -0
- package/dist/core/command/types.d.ts +92 -0
- package/dist/core/command/version.d.ts +4 -0
- package/dist/core/config/branch-template.d.ts +20 -0
- package/dist/core/config/config-items.d.ts +86 -0
- package/dist/core/config/config-load.d.ts +47 -0
- package/dist/core/config/config-origins.d.ts +57 -0
- package/dist/core/config/config-readers.d.ts +167 -0
- package/dist/core/config/config-schema.d.ts +207 -0
- package/dist/core/config/config-sections.d.ts +493 -0
- package/dist/core/config/config.d.ts +320 -0
- package/dist/core/config/core-section.d.ts +39 -0
- package/dist/core/config/dangerous.d.ts +58 -0
- package/dist/core/config/default-routing.d.ts +16 -0
- package/dist/core/config/index.d.ts +141 -0
- package/dist/core/config/scope.d.ts +42 -0
- package/dist/core/config/section.d.ts +206 -0
- package/dist/core/config/sections.d.ts +45 -0
- package/dist/core/config/standard-schema.d.ts +27 -0
- package/dist/core/git/commit.d.ts +232 -0
- package/dist/core/git/gh-runner.d.ts +24 -0
- package/dist/core/git/git.d.ts +22 -0
- package/dist/core/git/index.d.ts +85 -0
- package/dist/core/loop/claude.d.ts +388 -0
- package/dist/core/loop/hop-record.d.ts +52 -0
- package/dist/core/loop/index.d.ts +179 -0
- package/dist/core/loop/session-env.d.ts +20 -0
- package/dist/core/loop/session-record-parse.d.ts +63 -0
- package/dist/core/loop/sessions.d.ts +408 -0
- package/dist/core/loop/suite-failure.d.ts +25 -0
- package/dist/core/output/active.d.ts +100 -0
- package/dist/core/output/stream.d.ts +20 -0
- package/dist/core/output/text.d.ts +55 -0
- package/dist/core/plan/block-reader.d.ts +46 -0
- package/dist/core/plan/blocks.d.ts +139 -0
- package/dist/core/plan/declaration.d.ts +366 -0
- package/dist/core/plan/plan-stamp.d.ts +75 -0
- package/dist/core/runtime/identity.d.ts +21 -0
- package/dist/core/runtime/index.d.ts +46 -0
- package/dist/effort/store/bring-forward.d.ts +131 -0
- package/dist/effort/store/check-rows.d.ts +31 -0
- package/dist/effort/store/commit-stats.d.ts +42 -0
- package/dist/effort/store/copy.d.ts +35 -0
- package/dist/effort/store/development-build.d.ts +105 -0
- package/dist/effort/store/effort-levels.d.ts +13 -0
- package/dist/effort/store/findings.d.ts +214 -0
- package/dist/effort/store/fix-schema.d.ts +184 -0
- package/dist/effort/store/index.js +10 -7
- package/dist/effort/store/location.d.ts +44 -0
- package/dist/effort/store/merge-commit-gaps.d.ts +68 -0
- package/dist/effort/store/merge-conflicts.d.ts +91 -0
- package/dist/effort/store/merge-rules.d.ts +82 -0
- package/dist/effort/store/merge-store.d.ts +211 -0
- package/dist/effort/store/merge-union.d.ts +92 -0
- package/dist/effort/store/migrate.d.ts +146 -0
- package/dist/effort/store/migrations.d.ts +92 -0
- package/dist/effort/store/ndjson-files.d.ts +114 -0
- package/dist/effort/store/origins.d.ts +116 -0
- package/dist/effort/store/plan-stubs.d.ts +79 -0
- package/dist/effort/store/rebuild-aside.d.ts +172 -0
- package/dist/effort/store/schema-plan.d.ts +102 -0
- package/dist/effort/store/session-row-types.d.ts +64 -0
- package/dist/effort/store/settings.d.ts +13 -0
- package/dist/effort/store/sqlite.d.ts +340 -0
- package/dist/effort/store/store-generation.d.ts +17 -0
- package/dist/effort/store/store-identity.d.ts +220 -0
- package/dist/effort/store/store-meta.d.ts +305 -0
- package/dist/effort/store/store-replaced.d.ts +72 -0
- package/dist/effort/store/types.d.ts +223 -0
- package/dist/errors/codes.d.ts +56 -0
- package/dist/errors/rafa-codes.d.ts +36 -0
- package/dist/index-2a7nb3an.js +125 -0
- package/dist/{index-r28fzsvc.js → index-39kbcw68.js} +350 -165
- package/dist/{index-nv34ptht.js → index-77ajfffn.js} +14 -9
- package/dist/index-cy98y87p.js +2597 -0
- package/dist/index-gqz4jn6j.js +13447 -0
- package/dist/index-gvek4r8m.js +710 -0
- package/dist/index-j4k2vdz3.js +1125 -0
- package/dist/index-jh1r4kcn.js +1067 -0
- package/dist/{index-mgh2s9bj.js → index-ykggr043.js} +58 -455
- package/dist/index-z1w83f81.js +4 -0
- package/dist/index.js +14715 -21516
- package/dist/learning/index.js +5 -6
- package/dist/plan/index.js +12 -11
- package/dist/plan-prompt.md +3 -1
- package/dist/ports/index.d.ts +732 -0
- package/dist/ports/learning.d.ts +101 -0
- package/dist/ports/log-level.d.ts +13 -0
- package/dist/ports/spec-review.d.ts +66 -0
- package/dist/pr/checks.d.ts +133 -0
- package/dist/pr/types.d.ts +422 -0
- package/dist/ready-4f8edezt.js +2016 -0
- package/dist/release-templates/release-bot-fragment.yml +153 -0
- package/dist/release-templates/release-publish.yml +110 -0
- package/dist/release-templates/release-settle.yml +122 -0
- package/dist/release-templates/release-tag.yml +102 -0
- package/dist/report/parse.d.ts +415 -0
- package/dist/schema/project-id.d.ts +79 -0
- package/dist/schema/tiers.d.ts +107 -0
- package/package.json +41 -3
- package/dist/index-hf2k497d.js +0 -16
- package/dist/index-nsr78ct2.js +0 -8219
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# The rafa release bot fragment workflow: the fragment of a Dependabot
|
|
2
|
+
# pull request, for levels 3 and 4 of the release ladder.
|
|
3
|
+
#
|
|
4
|
+
# Written into a project's `.github/workflows/` by `writeReleaseWorkflow`
|
|
5
|
+
# (`src/release/templates.ts`) at levels 3 and 4 while
|
|
6
|
+
# `.github/dependabot.yml` exists. A bot pull request has no wrap-up to
|
|
7
|
+
# write its fragment, so this workflow writes one with
|
|
8
|
+
# `rafa release fragment --plan=dependabot-<number>`, at `patch` when
|
|
9
|
+
# `dependabot/fetch-metadata` reads the update as `direct:production` and
|
|
10
|
+
# at `none` otherwise, commits it as `chore: release fragment
|
|
11
|
+
# dependabot-<number>` and pushes it to the pull request's branch. A
|
|
12
|
+
# branch that already adds a fragment named for the pull request
|
|
13
|
+
# (`dependabot-<number>.md`, or `-2`, `-3` and on) is left as it is.
|
|
14
|
+
#
|
|
15
|
+
# A `pull_request` run started by Dependabot gets a read-only token, so
|
|
16
|
+
# this runs on `pull_request_target`, in the base branch's context with a
|
|
17
|
+
# writable one. That is why nothing from the pull request's branch runs
|
|
18
|
+
# here: the branch is checked out under `head/` only to add one file and
|
|
19
|
+
# push, while bun is set up from, and rafa installed or run from, the
|
|
20
|
+
# base branch's checkout under `base/`. rafa reads its config (a
|
|
21
|
+
# `rafa.config.ts` included) and loads its modules from the directory it
|
|
22
|
+
# runs in, so the fragment is written in `base/` and copied to `head/`.
|
|
23
|
+
#
|
|
24
|
+
# A commit pushed with the workflow's GITHUB_TOKEN starts no other
|
|
25
|
+
# workflow run, and Dependabot stops rebasing a branch someone else has
|
|
26
|
+
# pushed to; a rebase it is asked for drops the fragment commit, and the
|
|
27
|
+
# `synchronize` run that follows writes it again.
|
|
28
|
+
#
|
|
29
|
+
# rafa needs a config with `release.enabled: true`, and the base's
|
|
30
|
+
# checkout may hold none: when none of `rafa.config.ts`, `rafa.config.mjs`
|
|
31
|
+
# and `.rafa/config.yaml` is there, the workflow writes
|
|
32
|
+
# `.rafa/config.yaml` with that key in `base/`. A committed config is left
|
|
33
|
+
# as it is, so a project that needs other release keys in CI commits
|
|
34
|
+
# them. The written config stays in the runner's checkout: the commit
|
|
35
|
+
# stages the fragment alone.
|
|
36
|
+
#
|
|
37
|
+
# rafa runs from the base's checkout when the project is rafa itself (its
|
|
38
|
+
# manifest names `@open-tomato/rafa` and git tracks `src/rafa.ts`), and
|
|
39
|
+
# from a global install otherwise, so one file serves both.
|
|
40
|
+
name: Release bot fragment
|
|
41
|
+
|
|
42
|
+
on:
|
|
43
|
+
pull_request_target:
|
|
44
|
+
types: [opened, synchronize, reopened]
|
|
45
|
+
|
|
46
|
+
permissions:
|
|
47
|
+
contents: write
|
|
48
|
+
pull-requests: read
|
|
49
|
+
|
|
50
|
+
concurrency:
|
|
51
|
+
group: release-bot-fragment-${{ github.event.pull_request.number }}
|
|
52
|
+
cancel-in-progress: false
|
|
53
|
+
|
|
54
|
+
jobs:
|
|
55
|
+
fragment:
|
|
56
|
+
if: >-
|
|
57
|
+
github.actor == 'dependabot[bot]'
|
|
58
|
+
&& github.event.pull_request.head.repo.full_name == github.repository
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
timeout-minutes: 15
|
|
61
|
+
steps:
|
|
62
|
+
- name: Fetch metadata
|
|
63
|
+
id: metadata
|
|
64
|
+
uses: dependabot/fetch-metadata@v2
|
|
65
|
+
|
|
66
|
+
- name: Checkout the base
|
|
67
|
+
uses: actions/checkout@v4
|
|
68
|
+
with:
|
|
69
|
+
ref: ${{ github.event.pull_request.base.ref }}
|
|
70
|
+
path: base
|
|
71
|
+
fetch-depth: 0
|
|
72
|
+
|
|
73
|
+
- name: Checkout the head
|
|
74
|
+
uses: actions/checkout@v4
|
|
75
|
+
with:
|
|
76
|
+
ref: ${{ github.event.pull_request.head.ref }}
|
|
77
|
+
path: head
|
|
78
|
+
fetch-depth: 0
|
|
79
|
+
persist-credentials: true
|
|
80
|
+
|
|
81
|
+
- name: Look for the fragment
|
|
82
|
+
id: held
|
|
83
|
+
shell: bash
|
|
84
|
+
working-directory: head
|
|
85
|
+
env:
|
|
86
|
+
BASE_REF: ${{ github.event.pull_request.base.ref }}
|
|
87
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
88
|
+
run: |
|
|
89
|
+
added=$(git diff --name-only --diff-filter=A "origin/$BASE_REF...HEAD")
|
|
90
|
+
if printf '%s\n' "$added" | grep -Eq "(^|/)dependabot-$PR_NUMBER(-[0-9]+)?\.md$"; then
|
|
91
|
+
echo "held=true" >> "$GITHUB_OUTPUT"
|
|
92
|
+
else
|
|
93
|
+
echo "held=false" >> "$GITHUB_OUTPUT"
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
- name: Set up bun
|
|
97
|
+
if: steps.held.outputs.held == 'false'
|
|
98
|
+
uses: oven-sh/setup-bun@v2
|
|
99
|
+
with:
|
|
100
|
+
bun-version-file: base/package.json
|
|
101
|
+
|
|
102
|
+
- name: Write the CI config
|
|
103
|
+
if: steps.held.outputs.held == 'false'
|
|
104
|
+
shell: bash
|
|
105
|
+
working-directory: base
|
|
106
|
+
run: |
|
|
107
|
+
if [ ! -f rafa.config.ts ] && [ ! -f rafa.config.mjs ] && [ ! -f .rafa/config.yaml ]; then
|
|
108
|
+
mkdir -p .rafa
|
|
109
|
+
printf '%s\n' '# Written by the Release bot fragment workflow: the checkout holds no rafa config.' 'release:' ' enabled: true' > .rafa/config.yaml
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
- name: Write the fragment
|
|
113
|
+
id: write
|
|
114
|
+
if: steps.held.outputs.held == 'false'
|
|
115
|
+
shell: bash
|
|
116
|
+
working-directory: base
|
|
117
|
+
env:
|
|
118
|
+
DEPENDENCY_TYPE: ${{ steps.metadata.outputs.dependency-type }}
|
|
119
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
120
|
+
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
121
|
+
run: |
|
|
122
|
+
if [ "$DEPENDENCY_TYPE" = 'direct:production' ]; then
|
|
123
|
+
level=patch
|
|
124
|
+
else
|
|
125
|
+
level=none
|
|
126
|
+
fi
|
|
127
|
+
name=$(node -p "require('./package.json').name")
|
|
128
|
+
if [ "$name" = '@open-tomato/rafa' ] && git ls-files --error-unmatch src/rafa.ts > /dev/null 2>&1; then
|
|
129
|
+
bun install --frozen-lockfile
|
|
130
|
+
written=$(bun src/rafa.ts release fragment "--plan=dependabot-$PR_NUMBER" "--level=$level" "--title=$PR_TITLE" | tail -n 1)
|
|
131
|
+
else
|
|
132
|
+
bun install -g @open-tomato/rafa
|
|
133
|
+
export PATH="${BUN_INSTALL:-$HOME/.bun}/bin:$PATH"
|
|
134
|
+
written=$(rafa release fragment "--plan=dependabot-$PR_NUMBER" "--level=$level" "--title=$PR_TITLE" | tail -n 1)
|
|
135
|
+
fi
|
|
136
|
+
mkdir -p "../head/$(dirname "$written")"
|
|
137
|
+
cp "$written" "../head/$written"
|
|
138
|
+
echo "path=$written" >> "$GITHUB_OUTPUT"
|
|
139
|
+
|
|
140
|
+
- name: Commit and push
|
|
141
|
+
if: steps.held.outputs.held == 'false'
|
|
142
|
+
shell: bash
|
|
143
|
+
working-directory: head
|
|
144
|
+
env:
|
|
145
|
+
FRAGMENT: ${{ steps.write.outputs.path }}
|
|
146
|
+
HEAD_REF: ${{ github.event.pull_request.head.ref }}
|
|
147
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
148
|
+
run: |
|
|
149
|
+
git config user.name 'github-actions[bot]'
|
|
150
|
+
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
|
151
|
+
git add -- "$FRAGMENT"
|
|
152
|
+
git commit -m "chore: release fragment dependabot-$PR_NUMBER"
|
|
153
|
+
git push origin "HEAD:$HEAD_REF"
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# The rafa release publish workflow: level 2 of the release ladder.
|
|
2
|
+
#
|
|
3
|
+
# Written into a project's `.github/workflows/` by `writeReleaseWorkflow`
|
|
4
|
+
# (`src/release/templates.ts`) for `release.publish: ci`. A pushed tag,
|
|
5
|
+
# or a workflow that tags in its own run and calls this one with the tag
|
|
6
|
+
# as `ref`, checks the tag out, runs the gates and then
|
|
7
|
+
# `rafa release publish`, which publishes every release unit whose tag
|
|
8
|
+
# points at the checked-out commit and skips a version the registry
|
|
9
|
+
# already holds.
|
|
10
|
+
#
|
|
11
|
+
# npm trusted publishing needs npm 11.5.1 or newer, `id-token: write` on
|
|
12
|
+
# the job, and a trusted publisher configured on npmjs.com for each
|
|
13
|
+
# package, naming this repository and this workflow file. npm attaches
|
|
14
|
+
# provenance on a trusted publish, so no token and no flag are set here.
|
|
15
|
+
#
|
|
16
|
+
# The publish job runs only when the repository variable
|
|
17
|
+
# `RAFA_RELEASE_PUBLISH` is `ci`: with it unset or holding anything else,
|
|
18
|
+
# GitHub skips the job, and a skipped job does not fail the run. Set it
|
|
19
|
+
# under Settings, Secrets and variables, Actions, Variables, or with
|
|
20
|
+
# `gh variable set RAFA_RELEASE_PUBLISH --body ci`.
|
|
21
|
+
#
|
|
22
|
+
# A tag pushed with a workflow's GITHUB_TOKEN starts no other workflow
|
|
23
|
+
# run, so a workflow that tags calls this one through `workflow_call`
|
|
24
|
+
# instead of waiting for the `push` trigger.
|
|
25
|
+
#
|
|
26
|
+
# rafa needs a config with `release.enabled: true`, and the checkout may
|
|
27
|
+
# hold none: when none of `rafa.config.ts`, `rafa.config.mjs` and
|
|
28
|
+
# `.rafa/config.yaml` is there, the workflow writes `.rafa/config.yaml`
|
|
29
|
+
# with that key. A committed config is left as it is, so a project that
|
|
30
|
+
# needs other release keys in CI commits them.
|
|
31
|
+
#
|
|
32
|
+
# rafa runs from the checkout when the project is rafa itself (its
|
|
33
|
+
# manifest names `@open-tomato/rafa` and git tracks `src/rafa.ts`), and
|
|
34
|
+
# from a global install otherwise, so one file serves both.
|
|
35
|
+
name: Release publish
|
|
36
|
+
|
|
37
|
+
on:
|
|
38
|
+
push:
|
|
39
|
+
tags: ['**']
|
|
40
|
+
workflow_call:
|
|
41
|
+
inputs:
|
|
42
|
+
ref:
|
|
43
|
+
description: The tag or commit to publish from.
|
|
44
|
+
required: true
|
|
45
|
+
type: string
|
|
46
|
+
|
|
47
|
+
permissions:
|
|
48
|
+
contents: read
|
|
49
|
+
id-token: write
|
|
50
|
+
|
|
51
|
+
jobs:
|
|
52
|
+
publish:
|
|
53
|
+
if: vars.RAFA_RELEASE_PUBLISH == 'ci'
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
timeout-minutes: 30
|
|
56
|
+
steps:
|
|
57
|
+
- name: Checkout
|
|
58
|
+
uses: actions/checkout@v4
|
|
59
|
+
with:
|
|
60
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
61
|
+
fetch-depth: 0
|
|
62
|
+
|
|
63
|
+
- name: Set up bun
|
|
64
|
+
uses: oven-sh/setup-bun@v2
|
|
65
|
+
with:
|
|
66
|
+
bun-version-file: package.json
|
|
67
|
+
|
|
68
|
+
- name: Set up node
|
|
69
|
+
uses: actions/setup-node@v4
|
|
70
|
+
with:
|
|
71
|
+
node-version: 24
|
|
72
|
+
registry-url: https://registry.npmjs.org
|
|
73
|
+
|
|
74
|
+
- name: Upgrade npm
|
|
75
|
+
run: npm install -g npm@latest && npm --version
|
|
76
|
+
|
|
77
|
+
- name: Install
|
|
78
|
+
run: bun install --frozen-lockfile
|
|
79
|
+
|
|
80
|
+
- name: Test
|
|
81
|
+
if: ${{ !cancelled() }}
|
|
82
|
+
run: bun test
|
|
83
|
+
|
|
84
|
+
- name: Lint
|
|
85
|
+
if: ${{ !cancelled() }}
|
|
86
|
+
run: bunx eslint .
|
|
87
|
+
|
|
88
|
+
- name: Types
|
|
89
|
+
if: ${{ !cancelled() }}
|
|
90
|
+
run: bun run check-types
|
|
91
|
+
|
|
92
|
+
- name: Write the CI config
|
|
93
|
+
shell: bash
|
|
94
|
+
run: |
|
|
95
|
+
if [ ! -f rafa.config.ts ] && [ ! -f rafa.config.mjs ] && [ ! -f .rafa/config.yaml ]; then
|
|
96
|
+
mkdir -p .rafa
|
|
97
|
+
printf '%s\n' '# Written by the Release publish workflow: the checkout holds no rafa config.' 'release:' ' enabled: true' > .rafa/config.yaml
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
- name: Publish
|
|
101
|
+
shell: bash
|
|
102
|
+
run: |
|
|
103
|
+
name=$(node -p "require('./package.json').name")
|
|
104
|
+
if [ "$name" = '@open-tomato/rafa' ] && git ls-files --error-unmatch src/rafa.ts > /dev/null 2>&1; then
|
|
105
|
+
bun src/rafa.ts release publish
|
|
106
|
+
else
|
|
107
|
+
bun install -g @open-tomato/rafa
|
|
108
|
+
export PATH="${BUN_INSTALL:-$HOME/.bun}/bin:$PATH"
|
|
109
|
+
rafa release publish
|
|
110
|
+
fi
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# The rafa release settle workflow: level 4 of the release ladder.
|
|
2
|
+
#
|
|
3
|
+
# Written into a project's `.github/workflows/` by `writeReleaseWorkflow`
|
|
4
|
+
# (`src/release/templates.ts`) for `release.settle: push` with
|
|
5
|
+
# `release.tag: settle` and `release.publish: ci`. Every push to the base
|
|
6
|
+
# branch checks it out with full history, sets a git identity for the
|
|
7
|
+
# release commit, and runs `rafa release settle`, which folds the waiting
|
|
8
|
+
# fragments into a release commit, pushes it to the base and tags it.
|
|
9
|
+
# A push with no fragment waiting settles nothing and exits 0.
|
|
10
|
+
#
|
|
11
|
+
# The settle job runs on a push to the repository's default branch. When
|
|
12
|
+
# `pr.base` names another branch, write that branch's name in place of
|
|
13
|
+
# `github.event.repository.default_branch` in the job's `if`.
|
|
14
|
+
#
|
|
15
|
+
# A commit or tag pushed with the workflow's GITHUB_TOKEN starts no other
|
|
16
|
+
# workflow run, so the release commit settle pushes does not run this
|
|
17
|
+
# workflow again, and the publish job calls `release-publish.yml` through
|
|
18
|
+
# `workflow_call` with the release commit as `ref` instead of waiting for
|
|
19
|
+
# its `push: tags` trigger. It runs only when settle pushed a release
|
|
20
|
+
# commit and tagged it; the job grants `id-token: write` for npm trusted
|
|
21
|
+
# publishing, and the settle job needs only `contents: write`.
|
|
22
|
+
#
|
|
23
|
+
# The publish job runs only when the repository variable
|
|
24
|
+
# `RAFA_RELEASE_PUBLISH` is `ci`: with it unset or holding anything else,
|
|
25
|
+
# GitHub skips the job, and a skipped job does not fail the run. Set it
|
|
26
|
+
# under Settings, Secrets and variables, Actions, Variables, or with
|
|
27
|
+
# `gh variable set RAFA_RELEASE_PUBLISH --body ci`.
|
|
28
|
+
# Settling and tagging run either way; publishing waits for the switch.
|
|
29
|
+
#
|
|
30
|
+
# rafa needs a config with `release.enabled: true`, and the checkout may
|
|
31
|
+
# hold none: when none of `rafa.config.ts`, `rafa.config.mjs` and
|
|
32
|
+
# `.rafa/config.yaml` is there, the workflow writes `.rafa/config.yaml`
|
|
33
|
+
# with that key. A committed config is left as it is, so a project that
|
|
34
|
+
# needs other release keys in CI commits them.
|
|
35
|
+
#
|
|
36
|
+
# rafa runs from the checkout when the project is rafa itself (its
|
|
37
|
+
# manifest names `@open-tomato/rafa` and git tracks `src/rafa.ts`), and
|
|
38
|
+
# from a global install otherwise, so one file serves both.
|
|
39
|
+
name: Release settle
|
|
40
|
+
|
|
41
|
+
on:
|
|
42
|
+
push:
|
|
43
|
+
branches: ['**']
|
|
44
|
+
|
|
45
|
+
permissions:
|
|
46
|
+
contents: write
|
|
47
|
+
|
|
48
|
+
concurrency:
|
|
49
|
+
group: release-settle
|
|
50
|
+
cancel-in-progress: false
|
|
51
|
+
|
|
52
|
+
jobs:
|
|
53
|
+
settle:
|
|
54
|
+
if: github.ref_name == github.event.repository.default_branch
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
timeout-minutes: 15
|
|
57
|
+
outputs:
|
|
58
|
+
release: ${{ steps.settle.outputs.release }}
|
|
59
|
+
steps:
|
|
60
|
+
- name: Checkout
|
|
61
|
+
uses: actions/checkout@v4
|
|
62
|
+
with:
|
|
63
|
+
ref: ${{ github.ref_name }}
|
|
64
|
+
fetch-depth: 0
|
|
65
|
+
|
|
66
|
+
- name: Set git identity
|
|
67
|
+
run: |
|
|
68
|
+
git config user.name 'github-actions[bot]'
|
|
69
|
+
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
|
70
|
+
|
|
71
|
+
- name: Set up bun
|
|
72
|
+
uses: oven-sh/setup-bun@v2
|
|
73
|
+
with:
|
|
74
|
+
bun-version-file: package.json
|
|
75
|
+
|
|
76
|
+
- name: Write the CI config
|
|
77
|
+
shell: bash
|
|
78
|
+
run: |
|
|
79
|
+
if [ ! -f rafa.config.ts ] && [ ! -f rafa.config.mjs ] && [ ! -f .rafa/config.yaml ]; then
|
|
80
|
+
mkdir -p .rafa
|
|
81
|
+
printf '%s\n' '# Written by the Release settle workflow: the checkout holds no rafa config.' 'release:' ' enabled: true' > .rafa/config.yaml
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
- name: Settle
|
|
85
|
+
id: settle
|
|
86
|
+
shell: bash
|
|
87
|
+
run: |
|
|
88
|
+
result="${RUNNER_TEMP:-/tmp}/settle.json"
|
|
89
|
+
name=$(node -p "require('./package.json').name")
|
|
90
|
+
if [ "$name" = '@open-tomato/rafa' ] && git ls-files --error-unmatch src/rafa.ts > /dev/null 2>&1; then
|
|
91
|
+
bun install --frozen-lockfile
|
|
92
|
+
bun src/rafa.ts release settle --output=json > "$result"
|
|
93
|
+
else
|
|
94
|
+
bun install -g @open-tomato/rafa
|
|
95
|
+
export PATH="${BUN_INSTALL:-$HOME/.bun}/bin:$PATH"
|
|
96
|
+
rafa release settle --output=json > "$result"
|
|
97
|
+
fi
|
|
98
|
+
cat "$result"
|
|
99
|
+
node -e '
|
|
100
|
+
const fs = require("fs");
|
|
101
|
+
const events = fs.readFileSync(process.argv[1], "utf8").split("\n").flatMap((line) => {
|
|
102
|
+
try { return [JSON.parse(line)]; } catch { return []; }
|
|
103
|
+
});
|
|
104
|
+
const data = (events.find((event) => event && event.type === "result") || {}).data || {};
|
|
105
|
+
const pushed = data.delivered && data.delivered.outcome && data.delivered.outcome.outcome === "pushed";
|
|
106
|
+
const tagged = data.tag && data.tag.outcome === "tagged" && data.tag.tags.length > 0;
|
|
107
|
+
const release = pushed && tagged
|
|
108
|
+
? data.tag.commit
|
|
109
|
+
: "";
|
|
110
|
+
fs.appendFileSync(process.env.GITHUB_OUTPUT, `release=${release}\n`);
|
|
111
|
+
' "$result"
|
|
112
|
+
|
|
113
|
+
publish:
|
|
114
|
+
needs: settle
|
|
115
|
+
if: needs.settle.outputs.release != '' && vars.RAFA_RELEASE_PUBLISH == 'ci'
|
|
116
|
+
permissions:
|
|
117
|
+
contents: read
|
|
118
|
+
id-token: write
|
|
119
|
+
uses: ./.github/workflows/release-publish.yml
|
|
120
|
+
with:
|
|
121
|
+
ref: ${{ needs.settle.outputs.release }}
|
|
122
|
+
secrets: inherit
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# The rafa release tag workflow: level 3 of the release ladder.
|
|
2
|
+
#
|
|
3
|
+
# Written into a project's `.github/workflows/` by `writeReleaseWorkflow`
|
|
4
|
+
# (`src/release/templates.ts`) for `release.settle: pr` with
|
|
5
|
+
# `release.tag: settle` and `release.publish: ci`. Settle never tags a
|
|
6
|
+
# `pr` delivery: it pushes the release commit to `rafa/release` and opens
|
|
7
|
+
# one release pull request. When that pull request merges, by any merge
|
|
8
|
+
# button, this workflow checks the base branch out at the merge commit,
|
|
9
|
+
# runs `rafa release tag --push`, and then publishes.
|
|
10
|
+
#
|
|
11
|
+
# It runs only on the release pull request's merge: a closed pull
|
|
12
|
+
# request that did not merge, or one from another head or from a fork,
|
|
13
|
+
# runs nothing, since `rafa release tag` refuses `tagged` (exit 1) once
|
|
14
|
+
# every unit is tagged.
|
|
15
|
+
#
|
|
16
|
+
# A tag pushed with the workflow's GITHUB_TOKEN starts no other workflow
|
|
17
|
+
# run, so the publish job calls `release-publish.yml` through
|
|
18
|
+
# `workflow_call` with the merge commit as `ref` instead of waiting for
|
|
19
|
+
# its `push: tags` trigger. That job grants `id-token: write` for npm
|
|
20
|
+
# trusted publishing; the tag job needs only `contents: write`.
|
|
21
|
+
#
|
|
22
|
+
# The publish job runs only when the repository variable
|
|
23
|
+
# `RAFA_RELEASE_PUBLISH` is `ci`: with it unset or holding anything else,
|
|
24
|
+
# GitHub skips the job, and a skipped job does not fail the run. Set it
|
|
25
|
+
# under Settings, Secrets and variables, Actions, Variables, or with
|
|
26
|
+
# `gh variable set RAFA_RELEASE_PUBLISH --body ci`.
|
|
27
|
+
# Tagging runs either way; publishing waits for the switch.
|
|
28
|
+
#
|
|
29
|
+
# rafa needs a config with `release.enabled: true`, and the checkout may
|
|
30
|
+
# hold none: when none of `rafa.config.ts`, `rafa.config.mjs` and
|
|
31
|
+
# `.rafa/config.yaml` is there, the workflow writes `.rafa/config.yaml`
|
|
32
|
+
# with that key. A committed config is left as it is, so a project that
|
|
33
|
+
# needs other release keys in CI commits them.
|
|
34
|
+
#
|
|
35
|
+
# rafa runs from the checkout when the project is rafa itself (its
|
|
36
|
+
# manifest names `@open-tomato/rafa` and git tracks `src/rafa.ts`), and
|
|
37
|
+
# from a global install otherwise, so one file serves both.
|
|
38
|
+
name: Release tag
|
|
39
|
+
|
|
40
|
+
on:
|
|
41
|
+
pull_request:
|
|
42
|
+
types: [closed]
|
|
43
|
+
|
|
44
|
+
permissions:
|
|
45
|
+
contents: write
|
|
46
|
+
|
|
47
|
+
jobs:
|
|
48
|
+
tag:
|
|
49
|
+
if: >-
|
|
50
|
+
github.event.pull_request.merged == true
|
|
51
|
+
&& github.event.pull_request.head.ref == 'rafa/release'
|
|
52
|
+
&& github.event.pull_request.head.repo.full_name == github.repository
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
timeout-minutes: 15
|
|
55
|
+
steps:
|
|
56
|
+
- name: Checkout
|
|
57
|
+
uses: actions/checkout@v4
|
|
58
|
+
with:
|
|
59
|
+
ref: ${{ github.event.pull_request.base.ref }}
|
|
60
|
+
fetch-depth: 0
|
|
61
|
+
|
|
62
|
+
- name: Move to the merge commit
|
|
63
|
+
env:
|
|
64
|
+
MERGE_COMMIT: ${{ github.event.pull_request.merge_commit_sha }}
|
|
65
|
+
run: git reset --hard "$MERGE_COMMIT"
|
|
66
|
+
|
|
67
|
+
- name: Set up bun
|
|
68
|
+
uses: oven-sh/setup-bun@v2
|
|
69
|
+
with:
|
|
70
|
+
bun-version-file: package.json
|
|
71
|
+
|
|
72
|
+
- name: Write the CI config
|
|
73
|
+
shell: bash
|
|
74
|
+
run: |
|
|
75
|
+
if [ ! -f rafa.config.ts ] && [ ! -f rafa.config.mjs ] && [ ! -f .rafa/config.yaml ]; then
|
|
76
|
+
mkdir -p .rafa
|
|
77
|
+
printf '%s\n' '# Written by the Release tag workflow: the checkout holds no rafa config.' 'release:' ' enabled: true' > .rafa/config.yaml
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
- name: Tag
|
|
81
|
+
shell: bash
|
|
82
|
+
run: |
|
|
83
|
+
name=$(node -p "require('./package.json').name")
|
|
84
|
+
if [ "$name" = '@open-tomato/rafa' ] && git ls-files --error-unmatch src/rafa.ts > /dev/null 2>&1; then
|
|
85
|
+
bun install --frozen-lockfile
|
|
86
|
+
bun src/rafa.ts release tag --push --output=json
|
|
87
|
+
else
|
|
88
|
+
bun install -g @open-tomato/rafa
|
|
89
|
+
export PATH="${BUN_INSTALL:-$HOME/.bun}/bin:$PATH"
|
|
90
|
+
rafa release tag --push --output=json
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
publish:
|
|
94
|
+
needs: tag
|
|
95
|
+
if: vars.RAFA_RELEASE_PUBLISH == 'ci'
|
|
96
|
+
permissions:
|
|
97
|
+
contents: read
|
|
98
|
+
id-token: write
|
|
99
|
+
uses: ./.github/workflows/release-publish.yml
|
|
100
|
+
with:
|
|
101
|
+
ref: ${{ github.event.pull_request.merge_commit_sha }}
|
|
102
|
+
secrets: inherit
|