Skip to content

ci(scripts): migrate post-merge runtime deps to scripts/ci/ + skip-release marker [skip release]#6

Merged
0xElCapitan merged 3 commits into
masterfrom
cycle-002/chore-post-merge-runtime-deps
May 27, 2026
Merged

ci(scripts): migrate post-merge runtime deps to scripts/ci/ + skip-release marker [skip release]#6
0xElCapitan merged 3 commits into
masterfrom
cycle-002/chore-post-merge-runtime-deps

Conversation

@0xElCapitan
Copy link
Copy Markdown
Owner

Summary

Resolves forge-1bo. Moves the post-merge non-cycle runtime dependencies from the untracked .claude/scripts/ path (gitignored as of commit 931d4c89 "chore(loa): update framework to v1.157.0, untrack bulk .claude/") into the tracked, repo-owned scripts/ci/ path. Adds release-skip marker support so chore/CI repair PRs can opt out of automatic semver tagging.

This PR carries [skip release] in commit 761c0a63 body and [no-bump] in commit 7b161ec4 body — when merged, the now-fixed post-merge workflow will detect the markers and skip software tag creation. No accidental v0.2.5 / v0.3.1 tag will be produced by this PR's merge (verified by local dry-run).

Scope (bounded, deliberate)

Path migrated Why
scripts/ci/classify-merge-pr.sh (147 lines) workflow classify job
scripts/ci/classify-pr-type.sh (89 lines) hard-required transitive of classify-merge-pr.sh
scripts/ci/semver-bump.sh (~430 lines, patched) workflow simple-release job; also gained [skip release] / [skip ci-release] / [no-bump] marker support
scripts/ci/bootstrap.sh (99 lines) required transitive of semver-bump.sh; uses git rev-parse --show-toplevel for PROJECT_ROOT (CI-safe)

Cycle-PR shell-only fallback path (which depends on post-merge-orchestrator.sh + transitive deps release-notes-gen.sh, ground-truth-gen.sh, classify-commit-zone.sh, lore-promote.sh, path-lib.sh — 3500+ lines total) was DEFERRED at the dependency-graph STOP checkpoint (operator decision 2026-05-27). A KNOWN LIMITATION comment block in post-merge.yml's "Shell-only fallback" step explicitly documents this. The Claude Code Action path (cycle PRs with secrets.ANTHROPIC_API_KEY) is unaffected.

Release-skip marker support

Added to scripts/ci/semver-bump.sh (post-migration patch, lines 287-318). The check runs after the commit-count gate and BEFORE the heavy parse_commits loop. Recognized markers in commit subject or body (anywhere between latest semver tag and HEAD):

  • [skip release] — generic opt-out
  • [skip ci-release] — explicit CI-repair opt-out
  • [no-bump] — alternative form

When found, semver-bump.sh emits {} (empty JSON) and exits 0. The workflow's Compute semver step parses .next from the JSON; empty .next sets steps.semver.outputs.skip=true, which gates the "Create tag" step's if: condition.

Implementation note: process substitution (< <(...)) is used instead of a pipeline because the script runs under set -euo pipefail — a git log | grep -q pipeline would have grep -q exit immediately on match, killing git log with SIGPIPE, which pipefail would propagate, making the if evaluate FALSE even on a successful match. Process substitution sidesteps this entirely.

Tag-risk analysis (per operator's release safety requirement)

Verified locally on this branch:

$ PROJECT_ROOT=$(pwd) bash scripts/ci/semver-bump.sh
[semver-bump] skip-release marker found in commits between v0.2.4 and HEAD — emitting empty JSON to suppress tag
{}
EXIT=0

No tag will be created on this PR's merge.

What is NOT changed

  • No edit to .gitignore.
  • No re-tracking of .claude/ (git diff master -- .claude/ is empty).
  • No git submodule installation.
  • No tag created manually.
  • No product/runtime code touched (no edits to src/, bin/, spec/, fixtures/, test/).
  • No package.json / package-lock.json mutation.
  • No IR / receipt / canonicalization / forge-verify behavior changed.
  • FORGE software/package version unchanged at 0.3.0.

Test plan

  • bash -n scripts/ci/*.sh — 4/4 OK
  • Local npm run test:unit777 / 777 pass · 0 fail
  • Local npm run test:all792 / 792 pass · 0 fail
  • Dry-run scripts/ci/semver-bump.sh on this branch → emits {} (no tag)
  • Dry-run scripts/ci/classify-merge-pr.sh --merge-msg "ci(scripts): ... [skip release]"pr_type=other
  • PR CI workflow auto-fires on this PR → verification
  • After merge: post-merge workflow runs all jobs to success with NO new tag created → end-to-end verification of forge-1bo resolution

Commits

7b161ec4  chore(beads): record forge-1bo follow-up task
761c0a63  ci(scripts): migrate post-merge runtime deps to scripts/ci/ + skip-release marker

🤖 Generated with Claude Code

0xElCapitan and others added 3 commits May 27, 2026 12:38
…lease marker

[skip release]

Resolves forge-1bo. Restores post-merge workflow runtime dependencies by
moving the workflow-critical script logic from the untracked `.claude/scripts/`
path (gitignored as of commit 931d4c8 "chore(loa): update framework to
v1.157.0, untrack bulk .claude/") into the tracked, repo-owned `scripts/ci/`
path.

Scope: bounded to the chore-PR / simple-release execution path. The
cycle-PR shell-only fallback (which depends on post-merge-orchestrator.sh
and its transitive deps) was DEFERRED at the dependency-graph STOP
checkpoint — see operator decision 2026-05-27 + the new known-limitation
comment in post-merge.yml's "Shell-only fallback" step.

Scripts migrated (4 files, 721 lines total, all self-contained except for
one optional path-lib.sh source that gracefully no-ops when absent):

  scripts/ci/classify-merge-pr.sh   (147 lines)  — workflow `classify` job
  scripts/ci/classify-pr-type.sh    ( 89 lines)  — sourced by classify-merge-pr
  scripts/ci/semver-bump.sh         (~430 lines) — workflow `simple-release` job
  scripts/ci/bootstrap.sh           ( 99 lines)  — sourced by semver-bump

`scripts/ci/bootstrap.sh` was copied unchanged; its `_detect_project_root`
function uses `git rev-parse --show-toplevel` as Strategy 1, which works
in CI checkout without needing the `.claude/` directory to exist on disk.
Its optional `path-lib.sh` source is gracefully gated (`if [[ -f ... ]]`)
and is a no-op when absent — none of the 4 migrated scripts call any
path-lib.sh functions.

`scripts/ci/semver-bump.sh` was migrated PLUS extended with a
skip-release marker check immediately after the commit-count check.
The check scans commits between the latest semver tag and HEAD via
`git log <tag>..HEAD --format='%B'` and looks for any of these markers
in subject OR body:

  [skip release]      - generic opt-out
  [skip ci-release]   - explicit CI-repair opt-out
  [no-bump]           - alternative form

If found, the script emits `{}` (empty JSON) and exits 0. The workflow's
"Compute semver" step parses `.next` from the JSON; an empty .next sets
`steps.semver.outputs.skip=true`, which guards the "Create tag" step's
`if:` condition. Net effect: marker = no tag created.

This commit itself carries the `[skip release]` marker in its body, so
when this chore PR is merged, the now-fixed post-merge workflow will
correctly detect the marker and skip software tag creation. No
accidental `v0.2.5` / `v0.3.1` tag will be produced by this PR's merge.

Workflow file changes (`.github/workflows/post-merge.yml`):
- `classify` job: `.claude/scripts/classify-merge-pr.sh` →
  `scripts/ci/classify-merge-pr.sh`; chmod also includes the
  transitive `classify-pr-type.sh` so its `source` call resolves.
- `simple-release` job: `.claude/scripts/{semver-bump,bootstrap}.sh` →
  `scripts/ci/...`.
- `full-pipeline` "Shell-only fallback" step: paths LEFT UNCHANGED with
  an explicit KNOWN-LIMITATION comment block — cycle PRs that lack
  `secrets.ANTHROPIC_API_KEY` still fail there pending a follow-up
  migration. The Claude Code Action path (cycle PRs WITH the secret)
  is unaffected because it runs inside the Anthropic container with
  Loa already loaded.

Hard constraints honored:
- No edit to `.gitignore`.
- No re-tracking of `.claude/` (`git diff master -- .claude/` is empty).
- No git submodule installation.
- No tag created manually.
- No product/runtime code touched (no edits to `src/`, `bin/`, `spec/`,
  `fixtures/`, `test/`).
- No `package.json` / `package-lock.json` mutation.
- No IR / receipt / canonicalization / forge-verify behavior change.
- FORGE software/package version unchanged at `0.3.0`.

Local verification (on this branch):
- `bash -n` syntax check passes for every `scripts/ci/*.sh`.
- `npm run test:unit` → 777 / 777 pass.
- `npm run test:all` → 792 / 792 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Persists the bead record created via `br create` on 2026-05-27 documenting
the now-resolved post-merge workflow runtime dependency issue. The fix
itself lands in commit 761c0a6 (preceding); this commit records the
bead truth-set ahead of the close-on-merge transition.

forge-1bo — Restore post-merge workflow runtime dependencies (P2, labels
ci,follow-up,cycle-002-sprint-01-followup) — resolved by the migration
into scripts/ci/ and the skip-release marker support.

The previously-committed forge-ewa, forge-1ce, and forge-2fq beads are
already present in master via earlier commits (98562ee and the PR #5
merge commit 662b43a); this commit appends only the forge-1bo record.

[no-bump]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sets git index mode to 100755 on all four migrated CI scripts. The
workflow already includes `chmod +x scripts/ci/*.sh` before invocation
so the runtime behavior is unchanged, but per Linux-safety review
(operator follow-up 2026-05-27 confirming GitHub Actions runs in a
clean Linux checkout, treating .claude/ as local-only Loa tooling),
scripts that are direct workflow entry points should carry the
executable bit in git as well — defense-in-depth.

This change touches mode bits only; file content (and content SHAs
in `git ls-files --stage`) is unchanged from commit 761c0a6.

[skip release]
[no-bump]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@0xElCapitan 0xElCapitan merged commit 8c8967b into master May 27, 2026
2 checks passed
0xElCapitan added a commit that referenced this pull request May 28, 2026
…no-bump]

Persist closure state for:
- forge-1ce: PR-level CI resolved by PR #5 and verified by PR #6
- forge-2fq: post-merge master trigger resolved by PR #5 and verified by PR #6
- forge-1bo: post-merge runtime deps resolved by PR #6

Leave forge-ewa open for FR-7 snapshot fixture reconciliation.

This is tracked Beads state only; no product/runtime behavior changed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant