@cleocode/cleo 2026.5.77 → 2026.5.79

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/cleo",
3
- "version": "2026.5.77",
3
+ "version": "2026.5.79",
4
4
  "description": "CLEO CLI — the assembled product consuming @cleocode/core",
5
5
  "type": "module",
6
6
  "main": "./dist/cli/index.js",
@@ -29,17 +29,18 @@
29
29
  "tree-sitter-ruby": "^0.23.1",
30
30
  "tree-sitter-rust": "0.23.1",
31
31
  "tree-sitter-typescript": "^0.23.2",
32
- "@cleocode/caamp": "2026.5.77",
33
- "@cleocode/animations": "2026.5.77",
34
- "@cleocode/cant": "2026.5.77",
35
- "@cleocode/contracts": "2026.5.77",
36
- "@cleocode/lafs": "2026.5.77",
37
- "@cleocode/nexus": "2026.5.77",
38
- "@cleocode/playbooks": "2026.5.77",
39
- "@cleocode/runtime": "2026.5.77"
32
+ "@cleocode/animations": "2026.5.79",
33
+ "@cleocode/caamp": "2026.5.79",
34
+ "@cleocode/contracts": "2026.5.79",
35
+ "@cleocode/lafs": "2026.5.79",
36
+ "@cleocode/cant": "2026.5.79",
37
+ "@cleocode/nexus": "2026.5.79",
38
+ "@cleocode/paths": "2026.5.79",
39
+ "@cleocode/playbooks": "2026.5.79",
40
+ "@cleocode/runtime": "2026.5.79"
40
41
  },
41
42
  "peerDependencies": {
42
- "@cleocode/core": "2026.5.77"
43
+ "@cleocode/core": "2026.5.79"
43
44
  },
44
45
  "peerDependenciesMeta": {
45
46
  "@cleocode/core": {
@@ -0,0 +1,157 @@
1
+ # CLEO GitHub Actions workflow templates
2
+
3
+ This directory contains CLEO's templated GitHub Actions workflows for the
4
+ release pipeline defined in
5
+ `.cleo/rcasd/T9345/research/SPEC-T9345-release-pipeline-v2.md`. Templates
6
+ are project-agnostic: they ship with `{{PLACEHOLDER}}` markers that are
7
+ resolved at scaffold time by `cleo init --workflows` (T9531) against the
8
+ local `.cleo/project-context.json` and the ADR-061 tool resolver.
9
+
10
+ ## Template files
11
+
12
+ | Template | SPEC section | Purpose |
13
+ |-----------------------------------|--------------|--------------------------------------------------------|
14
+ | `release-prepare.yml.tmpl` | §5.1 | Cut release branch, bump version, open bump-PR. |
15
+ | `release-publish.yml.tmpl` | §5.2 | Publish + tag once the bump-PR is merged. |
16
+ | `release-fanout.yml.tmpl` | §5.3 | Best-effort post-publish fanout (docs, docker, etc.). |
17
+ | `release-rollback.yml.tmpl` | §5.4 | Rollback workflow (revert PR + npm deprecate + reconcile). |
18
+
19
+ ## Template contract
20
+
21
+ - Templates MUST use `{{PLACEHOLDER}}` markers compatible with simple regex
22
+ substitution (`s/{{NAME}}/value/g`). They MUST NOT use Mustache, Handlebars,
23
+ or any nested-syntax templating engine — the scaffold step relies on
24
+ deterministic, single-pass regex replacement so a stale template can be
25
+ diffed cleanly against a re-render.
26
+ - Placeholder names MUST be `UPPER_SNAKE_CASE` wrapped in double braces.
27
+ - Templates MUST be ASCII-only outside of strings.
28
+ - Templates MUST pass `actionlint` after substitution. The
29
+ `release-prepare-render.test.ts` snapshot test renders with sample values
30
+ and (if `actionlint` is on `PATH`) pipes the output through `actionlint -`
31
+ via `child_process.execSync`.
32
+
33
+ ## Placeholders
34
+
35
+ All four templates draw from the same placeholder vocabulary. Unused
36
+ placeholders for a given template are silently ignored by the scaffolder.
37
+
38
+ | Placeholder | Source | Default | Example |
39
+ |-----------------------|--------------------------------------------------------|--------------------------------------|--------------------------------------|
40
+ | `{{NODE_VERSION}}` | `.cleo/project-context.json` `node.version` | `22.x` | `"22.x"` |
41
+ | `{{INSTALL_CMD}}` | ADR-061 archetype defaults (`primaryType`-specific) | `pnpm install --frozen-lockfile` | `pnpm install --frozen-lockfile` |
42
+ | `{{LINT_CMD}}` | ADR-061 `tool:lint` resolution | `pnpm run lint` | `pnpm biome ci .` |
43
+ | `{{TYPECHECK_CMD}}` | ADR-061 `tool:typecheck` resolution | `pnpm run typecheck` | `pnpm run typecheck` |
44
+ | `{{TEST_CMD}}` | ADR-061 `tool:test` resolution | `pnpm run test` | `pnpm run test` |
45
+ | `{{BUILD_CMD}}` | ADR-061 `tool:build` resolution | `pnpm run build` | `pnpm run build` |
46
+ | `{{BRANCH_PREFIX}}` | `release.branchPrefix` in `.cleo/config.json` | `release` | `release` |
47
+ | `{{PR_LABEL}}` | `release.prLabel` in `.cleo/config.json` | `release` | `release` |
48
+ | `{{NPM_PUBLISH_CMD}}` | `release.npmPublishCmd` in `.cleo/config.json` | `pnpm publish --access public --tag latest` | `pnpm publish -r --access public --tag latest` |
49
+ | `{{PUBLISHERS}}` | `release.publishers` in `.cleo/config.json` | `npm` | `npm cargo` |
50
+ | `{{DOCS_BUILD_CMD}}` | `release.fanout.docsBuildCmd` in `.cleo/config.json` | `pnpm run docs:build` | `pnpm --filter @cleocode/docs run build` |
51
+ | `{{ENABLE_DOCS_DEPLOY}}` | `release.fanout.docsDeploy` in `.cleo/config.json` | `false` | `true` |
52
+ | `{{ENABLE_DOCKER_RETAG}}` | `release.fanout.dockerRetag` in `.cleo/config.json` | `false` | `true` |
53
+ | `{{ENABLE_SENTINEL_NOTIFY}}` | `release.fanout.sentinelNotify` in `.cleo/config.json` | `false` | `true` |
54
+ | `{{ENABLE_STUDIO_DEPLOY}}` | `release.fanout.studioDeploy` in `.cleo/config.json` | `false` | `true` |
55
+ | `{{ENABLE_NIGHTLY_TRIGGER}}` | `release.fanout.nightlyTrigger` in `.cleo/config.json` | `false` | `true` |
56
+ | `{{DOCKER_IMAGE}}` | `release.fanout.dockerImage` in `.cleo/config.json` | *(none — required if `dockerRetag=true`)* | `cleocode/cleo` |
57
+ | `{{DOCKER_HUB_USER}}` | `release.fanout.dockerHubUser` in `.cleo/config.json` | *(none — required if `dockerRetag=true`)* | `cleocode` |
58
+ | `{{SENTINEL_WEBHOOK_URL}}` | `release.fanout.sentinelWebhookUrl` in `.cleo/config.json` | *(none — required if `sentinelNotify=true`)* | `https://sentinel.example.com/hooks/release` |
59
+ | `{{STUDIO_DEPLOY_HOOK}}` | `release.fanout.studioDeployHook` in `.cleo/config.json` | *(none — required if `studioDeploy=true`)* | `https://studio.example.com/deploy` |
60
+ | `{{NPM_PACKAGES}}` | `release.rollback.npmPackages` in `.cleo/config.json` | *(none — required if `PUBLISHERS` contains `npm`)* | `@cleocode/cleo @cleocode/core` |
61
+ | `{{CARGO_CRATES}}` | `release.rollback.cargoCrates` in `.cleo/config.json` | *(none — required if `PUBLISHERS` contains `cargo`)* | `cleo-core cleo-cli` |
62
+
63
+ Source precedence (highest first):
64
+
65
+ 1. Explicit override in `.cleo/project-context.json` (ADR-061 §1).
66
+ 2. Project archetype default keyed on `primaryType` (e.g. `node` → `pnpm`,
67
+ `rust` → `cargo`, `python` → `uv`).
68
+ 3. Hard-coded fallback in the scaffolder.
69
+
70
+ ## GitHub permissions required per template
71
+
72
+ | Template | `contents` | `pull-requests` | `id-token` | `packages` | Other |
73
+ |------------------------------|-----------------|------------------|----------------------|--------------------|------------------|
74
+ | `release-prepare.yml.tmpl` | `write` | `write` | `write` (signed tags) | (MUST NOT request) | — |
75
+ | `release-publish.yml.tmpl` | `write` (tag) | `read` | `write` (OIDC) | `write` (publish job only) | — |
76
+ | `release-fanout.yml.tmpl` | `read` | — | `write` (Pages, docs job only)* | — | `pages: write`* |
77
+ | `release-rollback.yml.tmpl` | `write` (revert + tag delete) | `write` | — | `write` (npm deprecate) | — |
78
+
79
+ *Per-job — only granted to the job that needs it.
80
+
81
+ ## Required secrets
82
+
83
+ | Template | Required secrets | Optional secrets |
84
+ |------------------------------|-------------------------|---------------------------------------------------|
85
+ | `release-prepare.yml.tmpl` | `GITHUB_TOKEN` (auto) | *(none)* — MUST NOT require `NPM_TOKEN` (R-210) |
86
+ | `release-publish.yml.tmpl` | `GITHUB_TOKEN`, `NPM_TOKEN`, `ANTHROPIC_API_KEY` | `CARGO_TOKEN`, `PYPI_TOKEN`, `DOCKER_HUB_TOKEN` |
87
+ | `release-fanout.yml.tmpl` | `GITHUB_TOKEN` (auto) | `DOCKER_HUB_TOKEN` (if `dockerRetag=true`), `SENTINEL_TOKEN` (if `sentinelNotify=true`), `STUDIO_DEPLOY_TOKEN` (if `studioDeploy=true`) |
88
+ | `release-rollback.yml.tmpl` | `GITHUB_TOKEN` (auto), `NPM_TOKEN` (if `PUBLISHERS` contains `npm`) | `CARGO_TOKEN` (if `PUBLISHERS` contains `cargo`) |
89
+
90
+ ## Scaffolding workflow
91
+
92
+ ```bash
93
+ # Render the templates against the local project, writing to .github/workflows/.
94
+ cleo init --workflows
95
+
96
+ # Re-render after editing project-context.json or release config.
97
+ cleo init --workflows --force
98
+ ```
99
+
100
+ The scaffolder reads each `*.yml.tmpl` file in this directory, performs
101
+ regex substitution against the placeholder vocabulary above, validates the
102
+ result with `actionlint`, and writes the rendered YAML to
103
+ `<project>/.github/workflows/<basename>.yml`. Existing files are NOT
104
+ overwritten without `--force`.
105
+
106
+ ## Extending without forking
107
+
108
+ Per SPEC R-260, downstream projects MAY layer customizations onto the
109
+ rendered workflows via a sibling `.github/workflows/<basename>.overrides.yml`
110
+ file (planned: `.workflow-overrides.yml` at repo root for cross-template
111
+ overrides). The scaffolder merges overrides as a final pass; conflicts at
112
+ the same YAML key path resolve to the override.
113
+
114
+ Override examples (illustrative — full schema lands with T9531):
115
+
116
+ ```yaml
117
+ # .github/workflows/release-prepare.overrides.yml
118
+ jobs:
119
+ preflight:
120
+ steps:
121
+ - name: Project-specific cache warm
122
+ run: ./scripts/warm-cache.sh
123
+ timeout-minutes: 3
124
+ ```
125
+
126
+ Overrides MUST NOT remove or relax any RFC2119 invariant from
127
+ `SPEC-T9345-release-pipeline-v2.md`. The scaffolder rejects override files
128
+ that drop required `timeout-minutes`, modify `concurrency.group`, or strip
129
+ declared permissions.
130
+
131
+ ## Cross-references
132
+
133
+ - SPEC: `.cleo/rcasd/T9345/research/SPEC-T9345-release-pipeline-v2.md`
134
+ - §5.1 → `release-prepare.yml.tmpl` *(T9532, landed)*
135
+ - §5.2 → `release-publish.yml.tmpl` *(T9533, landed)*
136
+ - §5.3 → `release-fanout.yml.tmpl` *(T9534, landed)*
137
+ - §5.4 → `release-rollback.yml.tmpl` *(T9535, current)*
138
+ - ADR-061 (tool resolver): governs `tool:*` placeholder resolution.
139
+ - ADR-073 (release pipeline v2): umbrella architectural decision.
140
+ - T9531: `cleo init --workflows` scaffold command (consumes these templates).
141
+ - T9532: `release-prepare.yml.tmpl` + README skeleton + snapshot test.
142
+ - T9533: `release-publish.yml.tmpl` + README placeholders + snapshot test
143
+ (eliminates F6 tag-on-pre-merge-SHA race by construction).
144
+ - T9534: `release-fanout.yml.tmpl` + 11 fanout placeholders + snapshot test
145
+ (five independent best-effort jobs gated on env toggles, every job
146
+ carries `continue-on-error: true` so fanout failures cannot mark the
147
+ release as failed; fanout jobs MUST NOT be required status checks per
148
+ R-244).
149
+ - T9535: `release-rollback.yml.tmpl` + rollback placeholders (`NPM_PACKAGES`,
150
+ `CARGO_CRATES`) + snapshot test (current task — `workflow_dispatch`-only
151
+ rollback with 4 jobs `validate` → `revert` → `deprecate` →
152
+ `reconcile-rollback`. The `revert` job opens a revert PR against `main`
153
+ via `gh pr create --label rollback` — NEVER pushes directly to `main`
154
+ per ADR-065. The `deprecate` job is best-effort
155
+ (`continue-on-error: true`); reconcile runs whenever validate succeeded
156
+ so the provenance graph records the operator's intent even if a
157
+ downstream side-effect failed).
@@ -0,0 +1,214 @@
1
+ # CLEO release pipeline — Best-effort fanout workflow.
2
+ #
3
+ # Generated from packages/cleo/templates/workflows/release-fanout.yml.tmpl by
4
+ # `cleo init --workflows` (T9531). DO NOT EDIT the rendered file directly —
5
+ # extend via `.workflow-overrides.yml` per SPEC-T9345 R-260.
6
+ #
7
+ # Implements SPEC-T9345-release-pipeline-v2.md §5.3 (R-240 — R-244, R-260 —
8
+ # R-263). Triggers on `release: published` (the GitHub Release event, NOT
9
+ # `release: created` which fires on drafts). Each downstream job is an
10
+ # independent best-effort fanout — every job carries `continue-on-error:
11
+ # true` so a failed docs deploy, docker retag, sentinel notify, studio
12
+ # rebuild, or nightly trigger CANNOT mark the release itself as failed.
13
+ # These jobs MUST NOT be configured as required status checks (R-244).
14
+ #
15
+ # Placeholders (replaced at scaffold time — see workflows/README.md):
16
+ # <NODE_VERSION> Node.js version (e.g. "22.x")
17
+ # <INSTALL_CMD> Install command (e.g. "pnpm install --frozen-lockfile")
18
+ # <DOCS_BUILD_CMD> Docs build command (e.g. "pnpm --filter @cleocode/docs run build")
19
+ # <ENABLE_DOCS_DEPLOY> Toggle docs-deploy job ("true" | "false")
20
+ # <ENABLE_DOCKER_RETAG> Toggle docker-retag job ("true" | "false")
21
+ # <ENABLE_SENTINEL_NOTIFY> Toggle sentinel-notify job ("true" | "false")
22
+ # <ENABLE_STUDIO_DEPLOY> Toggle studio-deploy job ("true" | "false")
23
+ # <ENABLE_NIGHTLY_TRIGGER> Toggle nightly-trigger job ("true" | "false")
24
+ # <DOCKER_IMAGE> Docker image name (e.g. "cleocode/cleo")
25
+ # <DOCKER_HUB_USER> Docker Hub login user (e.g. "cleocode")
26
+ # <SENTINEL_WEBHOOK_URL> Sentinel webhook URL (HTTPS)
27
+ # <STUDIO_DEPLOY_HOOK> Studio deploy hook URL (HTTPS)
28
+ # (Angle-brackets in this doc comment are intentional — they avoid being
29
+ # substituted by the {{...}} regex pass. The placeholders below use {{...}}.)
30
+
31
+ name: Release Fanout
32
+
33
+ # R-240: trigger on `release: published` ONLY. Draft releases (which fire
34
+ # `release: created`) MUST NOT trigger the fanout — operators expect this
35
+ # to run AFTER the publish + tag workflow has shipped the artifacts.
36
+ on:
37
+ release:
38
+ types: [published]
39
+
40
+ # R-241: workflow-level grants the minimum read scope. Per-job permissions
41
+ # escalate ONLY for the jobs that need them (e.g. `pages: write` for docs
42
+ # deploy). No top-level write scope — fanout is intentionally read-only at
43
+ # the workflow level.
44
+ permissions:
45
+ contents: read
46
+
47
+ # R-243: serialize fanouts against the same release tag. cancel-in-progress
48
+ # is FALSE so an in-flight fanout completes rather than losing partial
49
+ # work (e.g. a half-pushed docker tag).
50
+ concurrency:
51
+ group: fanout-${{ github.event.release.tag_name }}
52
+ cancel-in-progress: false
53
+
54
+ # R-262: bash everywhere — no cross-platform shell drift across the fanout
55
+ # jobs (they all run on ubuntu-latest but the contract is explicit).
56
+ defaults:
57
+ run:
58
+ shell: bash
59
+
60
+ jobs:
61
+ # R-242 (1/5): deploy generated documentation site to GitHub Pages.
62
+ # continue-on-error: true so a docs-build regression cannot fail the
63
+ # release. Disabled by default — flip {{ENABLE_DOCS_DEPLOY}} to "true"
64
+ # at scaffold time. The flag is hoisted into env so the `if:` becomes a
65
+ # dynamic expression (avoids actionlint constant-expression warning).
66
+ docs-deploy:
67
+ name: Deploy docs to GitHub Pages
68
+ runs-on: ubuntu-latest
69
+ continue-on-error: true
70
+ timeout-minutes: 15
71
+ env:
72
+ ENABLE_DOCS_DEPLOY: '{{ENABLE_DOCS_DEPLOY}}'
73
+ if: ${{ env.ENABLE_DOCS_DEPLOY == 'true' }}
74
+ # R-241 (per-job): pages: write + id-token: write granted ONLY for the
75
+ # docs-deploy job — other fanout jobs MUST NOT inherit GitHub Pages
76
+ # write scope.
77
+ permissions:
78
+ contents: read
79
+ pages: write
80
+ id-token: write
81
+ steps:
82
+ # R-263: third-party Actions pinned to major+minor.
83
+ - name: Checkout
84
+ uses: actions/checkout@v4.1
85
+ with:
86
+ fetch-depth: 1
87
+ timeout-minutes: 5
88
+
89
+ - name: Set up Node.js
90
+ uses: actions/setup-node@v4.0
91
+ with:
92
+ node-version: '{{NODE_VERSION}}'
93
+ timeout-minutes: 3
94
+
95
+ - name: Install dependencies
96
+ run: {{INSTALL_CMD}}
97
+ timeout-minutes: 5
98
+
99
+ - name: Build docs
100
+ run: {{DOCS_BUILD_CMD}}
101
+ timeout-minutes: 10
102
+
103
+ - name: Configure Pages
104
+ uses: actions/configure-pages@v5.0
105
+ timeout-minutes: 2
106
+
107
+ - name: Upload Pages artifact
108
+ uses: actions/upload-pages-artifact@v3.0
109
+ with:
110
+ path: docs/dist
111
+ timeout-minutes: 5
112
+
113
+ - name: Deploy to GitHub Pages
114
+ uses: actions/deploy-pages@v4.0
115
+ timeout-minutes: 5
116
+
117
+ # R-242 (2/5): retag the published docker image to `latest`. Failure here
118
+ # does NOT roll back the release — operators can re-run manually.
119
+ docker-retag:
120
+ name: Retag docker image to latest
121
+ runs-on: ubuntu-latest
122
+ continue-on-error: true
123
+ timeout-minutes: 10
124
+ env:
125
+ ENABLE_DOCKER_RETAG: '{{ENABLE_DOCKER_RETAG}}'
126
+ DOCKER_IMAGE: '{{DOCKER_IMAGE}}'
127
+ DOCKER_HUB_USER: '{{DOCKER_HUB_USER}}'
128
+ VERSION: ${{ github.event.release.tag_name }}
129
+ if: ${{ env.ENABLE_DOCKER_RETAG == 'true' }}
130
+ steps:
131
+ - name: Log in to Docker Hub
132
+ run: |
133
+ set -euo pipefail
134
+ echo "${{ secrets.DOCKER_HUB_TOKEN }}" | \
135
+ docker login -u "$DOCKER_HUB_USER" --password-stdin
136
+ timeout-minutes: 3
137
+
138
+ - name: Pull, retag, push
139
+ run: |
140
+ set -euo pipefail
141
+ docker pull "${DOCKER_IMAGE}:${VERSION}"
142
+ docker tag "${DOCKER_IMAGE}:${VERSION}" "${DOCKER_IMAGE}:latest"
143
+ docker push "${DOCKER_IMAGE}:latest"
144
+ timeout-minutes: 5
145
+
146
+ # R-242 (3/5): POST a `release.published` event to the Sentinel webhook
147
+ # so downstream monitoring can pick the release up. Best-effort — a
148
+ # webhook outage MUST NOT mark the release as failed.
149
+ sentinel-notify:
150
+ name: Notify Sentinel of release
151
+ runs-on: ubuntu-latest
152
+ continue-on-error: true
153
+ timeout-minutes: 5
154
+ env:
155
+ ENABLE_SENTINEL_NOTIFY: '{{ENABLE_SENTINEL_NOTIFY}}'
156
+ SENTINEL_WEBHOOK_URL: '{{SENTINEL_WEBHOOK_URL}}'
157
+ SENTINEL_TOKEN: ${{ secrets.SENTINEL_TOKEN }}
158
+ VERSION: ${{ github.event.release.tag_name }}
159
+ RELEASE_URL: ${{ github.event.release.html_url }}
160
+ if: ${{ env.ENABLE_SENTINEL_NOTIFY == 'true' }}
161
+ steps:
162
+ - name: POST release.published to Sentinel
163
+ run: |
164
+ set -euo pipefail
165
+ curl -fSL -X POST "$SENTINEL_WEBHOOK_URL" \
166
+ -H 'Content-Type: application/json' \
167
+ -H "Authorization: Bearer ${SENTINEL_TOKEN}" \
168
+ -d "{\"event\":\"release.published\",\"version\":\"${VERSION}\",\"url\":\"${RELEASE_URL}\"}"
169
+ timeout-minutes: 3
170
+
171
+ # R-242 (4/5): trigger a Studio rebuild via deploy hook. Studio runs
172
+ # outside this repo, so this job is a fire-and-forget POST.
173
+ studio-deploy:
174
+ name: Trigger Studio rebuild
175
+ runs-on: ubuntu-latest
176
+ continue-on-error: true
177
+ timeout-minutes: 20
178
+ env:
179
+ ENABLE_STUDIO_DEPLOY: '{{ENABLE_STUDIO_DEPLOY}}'
180
+ STUDIO_DEPLOY_HOOK: '{{STUDIO_DEPLOY_HOOK}}'
181
+ STUDIO_DEPLOY_TOKEN: ${{ secrets.STUDIO_DEPLOY_TOKEN }}
182
+ VERSION: ${{ github.event.release.tag_name }}
183
+ if: ${{ env.ENABLE_STUDIO_DEPLOY == 'true' }}
184
+ steps:
185
+ - name: POST to Studio deploy hook
186
+ run: |
187
+ set -euo pipefail
188
+ curl -fSL -X POST "$STUDIO_DEPLOY_HOOK" \
189
+ -H "Authorization: Bearer ${STUDIO_DEPLOY_TOKEN}" \
190
+ -H 'Content-Type: application/json' \
191
+ -d "{\"version\":\"${VERSION}\"}"
192
+ timeout-minutes: 10
193
+
194
+ # R-242 (5/5): dispatch the nightly e2e workflow against the freshly
195
+ # published release version. Decoupled from the release path — a failed
196
+ # dispatch is logged but does NOT fail the release.
197
+ nightly-trigger:
198
+ name: Dispatch nightly e2e for release
199
+ runs-on: ubuntu-latest
200
+ continue-on-error: true
201
+ timeout-minutes: 3
202
+ env:
203
+ ENABLE_NIGHTLY_TRIGGER: '{{ENABLE_NIGHTLY_TRIGGER}}'
204
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
205
+ VERSION: ${{ github.event.release.tag_name }}
206
+ if: ${{ env.ENABLE_NIGHTLY_TRIGGER == 'true' }}
207
+ steps:
208
+ - name: Dispatch nightly e2e
209
+ run: |
210
+ set -euo pipefail
211
+ gh workflow run nightly-e2e.yml \
212
+ --repo "${{ github.repository }}" \
213
+ -f release_version="$VERSION"
214
+ timeout-minutes: 2