Skip to content

Commit bf23db6

Browse files
blafourcadeclaude
andauthored
ci: hold the release until its video is attached (#1093)
* ci: hold the release until its video is attached The release was published once its bundle and distributions were attached, video or not, and its publication is what n8n announces on Discord and Skool. A release whose video failed was announced without it. The video is now required: a failed video keeps the release a draft. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019tw8HkVy69fuukqR971Roz * ci: remove the way to skip the release video check The video is required for the release to publish, so a promotion that skips its coverage check only moves the failure to release day. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019tw8HkVy69fuukqR971Roz --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
1 parent dd8c352 commit bf23db6

6 files changed

Lines changed: 16 additions & 25 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ jobs:
347347
348348
# The umbrella release is created as a draft, so no `release` event reaches a subscriber
349349
# before its bundle, distributions and video are attached. Publishing it sends the event
350-
# with everything in place. A failed video does not hold the release back; a failed bundle
351-
# or distribution does, and the release stays a draft for a person to see.
350+
# with everything in place. A failed video, bundle or distribution holds the release back, and it
351+
# stays a draft for a person to see: no announcement goes out without its video.
352352
# `--latest` is set here: GitHub refuses it on a draft. GitHub marks whichever release is
353353
# created last as "Latest", and release-please creates the umbrella and every plugin release
354354
# in one unordered run, so a plugin release can outrank the marketplace version. Bare
@@ -362,6 +362,7 @@ jobs:
362362
needs.release-please.outputs.release_created == 'true' &&
363363
needs.build-and-attach.result == 'success' &&
364364
needs.build-per-tool.result == 'success' &&
365+
needs.build-release-video.result == 'success' &&
365366
(needs.build-plugin.result == 'success' || needs.build-plugin.result == 'skipped')
366367
runs-on: ubuntu-latest
367368
permissions:

‎.github/workflows/promote.yml‎

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ name: Promote next to main
1111

1212
on:
1313
workflow_dispatch:
14-
inputs:
15-
skip_video:
16-
description: Promote without checking the release video covers what ships. Urgent only.
17-
type: boolean
18-
default: false
1914

2015
concurrency:
2116
group: promote
@@ -44,7 +39,6 @@ jobs:
4439
GH_TOKEN: ${{ steps.app-token.outputs.token }}
4540
REPO: ${{ github.repository }}
4641
RUN_ID: ${{ github.run_id }}
47-
SKIP_VIDEO: ${{ inputs.skip_video }}
4842
run: |
4943
set -euo pipefail
5044
@@ -61,10 +55,8 @@ jobs:
6155
6256
# What ships needs a scene in the release video, or a written reason to be left out.
6357
# Checked here, before anything is pushed, so a refusal leaves no branch or PR behind.
64-
if [ "${SKIP_VIDEO}" != "true" ]; then
65-
git checkout --detach origin/next
66-
node .claude/skills/release-video/assets/check-release-video.js
67-
fi
58+
git checkout --detach origin/next
59+
node .claude/skills/release-video/assets/check-release-video.js
6860
6961
# A snapshot of next, never next itself: a PR headed by the live branch widens as
7062
# work merges in during review. The snapshot is next's exact tip, so the merge base

‎RELEASE.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ flowchart LR
3838
2. Open the [promotion `next` to `main`](https://github.com/ai-driven-dev/framework/actions/workflows/promote.yml) once the week's work is ready.
3939
3. release-please opens a Release PR on `main`: it is auto-merged.
4040
4. Tags and version bumps are created. The umbrella release is a draft: the bundle, the distributions and the rendered video are attached to it, then it is published. Announcements fire on that publication, with everything in place.
41-
5. The video is rendered by CI from the plan the promotion checked. A failed video does not hold the release; a failed bundle or distribution does, and the release stays a draft. Publish it by hand with `gh release edit <tag> --draft=false --latest` once fixed.
41+
5. The video is rendered by CI from the plan the promotion checked. A failed video, bundle or distribution holds the release, and it stays a draft. Publish it by hand with `gh release edit <tag> --draft=false --latest` once fixed.
4242
6. `main` is back-merged into `next` automatically.
4343

4444
## 🚑 Hotfix

‎aidd_docs/memory/deployment.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Where the project runs and how it ships: CI/CD, environments, and release.
1212
| `cli-ci.yml` | the `cli` and `kanban` gates, jobs in the CLI bank. No `paths:` filter: a `changes` job decides in bash what has work. Mutations skip only for a verified `promote/next-to-main-*` snapshot; anything unproven keeps normal scopes |
1313
| `validate.yml` | manifests against their schemas, plus the whole pre-commit over the whole tree |
1414
| `codeql.yml` | code scanning |
15-
| `promote.yml` | checks the release video covers what ships (`skip_video` bypasses), opens the `next` to `main` PR, auto-merges |
15+
| `promote.yml` | checks the release video covers what ships, opens the `next` to `main` PR, auto-merges |
1616
| `back-merge.yml` | folds `main` into `next` after each release |
1717
| `dependabot-auto-merge.yml` | merges dependency PRs that pass |
1818
| `close-finished-milestones.yml` | closes a milestone once its issues are |
@@ -55,7 +55,7 @@ flowchart TD
5555
- The Release PR merges with `--merge --admin`: the only method `.github/rulesets/main.json` allows, so `main` never holds merged but unversioned code.
5656
- Tags: umbrella, `cli-v<semver>`, `<plugin>-v<semver>`. `scripts/credit-release-authors.cjs` appends each author as `(@login)`, a workaround until [googleapis/release-please#2892](https://github.com/googleapis/release-please/pull/2892) ships.
5757
- The umbrella stays a draft until every asset is attached; its publication is the event n8n listens to.
58-
- A failed video build does not block publication, and a failed YouTube upload does not stop Discord and Skool: they post without the video link.
58+
- A failed video build keeps the release a draft, so nothing is announced without its video. A failed YouTube upload does not stop Discord and Skool: they post without the video link.
5959

6060
Config: `release-please-config.json`, eleven packages. Manifest: `.release-please-manifest.json`.
6161

‎scripts/__tests__/ci-renders-the-release-video.test.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ test("a draft cannot be the latest release, so latest is set when it is publishe
4646
assert.match(publishScript, /gh release edit "\$\{TAG\}" --draft=false --latest/);
4747
});
4848

49-
test("the release is published once its bundle and distributions are attached, video or not", () => {
49+
test("the release is published once its bundle, distributions and video are attached", () => {
5050
assert.deepEqual(publish.needs.sort(), [
5151
"build-and-attach",
5252
"build-per-tool",
@@ -57,7 +57,7 @@ test("the release is published once its bundle and distributions are attached, v
5757
assert.match(publish.if, /always\(\)/);
5858
assert.match(publish.if, /needs\.build-and-attach\.result == 'success'/);
5959
assert.match(publish.if, /needs\.build-per-tool\.result == 'success'/);
60-
assert.doesNotMatch(publish.if, /build-release-video/);
60+
assert.match(publish.if, /needs\.build-release-video\.result == 'success'/);
6161
});
6262

6363
test("publishing uses the App token so the release event reaches the other workflows", () => {

‎scripts/__tests__/promote-checks-the-release-video.test.js‎

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,9 @@ const open = promote.jobs.promote.steps.find(
1111
(step) => step.name === "Open the promote PR, enable merge auto-merge",
1212
);
1313

14-
test("promote offers a way to skip the release video check", () => {
15-
const input = promote.on.workflow_dispatch.inputs.skip_video;
16-
17-
assert.equal(input.type, "boolean");
18-
assert.equal(input.default, false);
19-
assert.equal(open.env.SKIP_VIDEO, "${{ inputs.skip_video }}");
14+
test("promote has no way to skip the release video check", () => {
15+
assert.equal(promote.on.workflow_dispatch?.inputs, undefined);
16+
assert.equal(open.env.SKIP_VIDEO, undefined);
2017
});
2118

2219
test("promote checks the release video on next's tip, before it pushes anything", () => {
@@ -28,6 +25,7 @@ test("promote checks the release video on next's tip, before it pushes anything"
2825
assert.match(open.run, /git checkout --detach origin\/next/);
2926
});
3027

31-
test("the skip is the only way past the check", () => {
32-
assert.match(open.run, /if \[ "\$\{SKIP_VIDEO\}" != "true" \]; then\n\s+git checkout --detach origin\/next\n\s+node \.claude\/skills\/release-video\/assets\/check-release-video\.js\nfi/);
28+
test("the check runs on every promotion", () => {
29+
assert.doesNotMatch(open.run, /SKIP_VIDEO/);
30+
assert.match(open.run, /git checkout --detach origin\/next\nnode \.claude\/skills\/release-video\/assets\/check-release-video\.js/);
3331
});

0 commit comments

Comments
 (0)