Skip to content

chore(release): unblock 5.3.0 — version lockstep sync + npm-publish chaining - #804

Merged
Pedrovaleriolopez merged 1 commit into
mainfrom
ci/release-lockstep-npm-chain
Jul 11, 2026
Merged

chore(release): unblock 5.3.0 — version lockstep sync + npm-publish chaining#804
Pedrovaleriolopez merged 1 commit into
mainfrom
ci/release-lockstep-npm-chain

Conversation

@Pedrovaleriolopez

@Pedrovaleriolopez Pedrovaleriolopez commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Why

The 5.3.0 release attempt failed at the prepublishOnly publish safety gate: validate-publish.js (Check 5 / validate-aiox-core-namespace.js) requires .aiox-core/package.json to be in version lockstep with the root package.json, but semantic-release (.releaserc.json, no @semantic-release/git) only bumps the root manifest in the release working tree. Nothing bumps the internal manifest → every release is blocked. The failed run also pushed an orphan v5.3.0 tag (already deleted).

What

  1. scripts/sync-version-lockstep.js — syncs .aiox-core/package.json + compat/aiox-core/package.json (version and the exact @aiox-squads/core dependency pin) to the target version. Idempotent; usable standalone in release-bump PRs.
  2. .releaserc.json@semantic-release/exec prepare step runs the sync with ${nextRelease.version}, so the safety gate passes inside the release run.
  3. semantic-release.yml — after a non-dry-run release, explicitly dispatches npm-publish.yml (stable, all) via gh workflow run. The tag/release created with GITHUB_TOKEN never chains npm-publish.yml (Actions anti-recursion); workflow_dispatch via API is the documented exception — the same pattern release.yml uses in trigger-npm-publish. Adds actions: write. npm-publish.yml is idempotent (skips versions already in the registry).
  4. Version bump 5.2.9 → 5.3.0 committed across the three manifests (repo convention — cf. chore(release): bump to 5.2.8 #776, chore(release): 5.2.7 — consolidate PRs #744-#750 from 5.2.6 #751), so the chained npm-publish.yml publishes the legacy aiox-core wrapper at 5.3.0 from the committed tree.

Validation (local)

Release plan after merge

  1. semantic-release.yml dispatch with dry_run=true → confirm "next release 5.3.0"
  2. Real dispatch → publishes @aiox-squads/core@5.3.0, tags v5.3.0, GitHub release, chains npm-publish.yml → legacy aiox-core@5.3.0 wrapper + workspace packages
  3. Verify: npm view @aiox-squads/core version and npm view aiox-core version = 5.3.0

Context: aiox-cockpit docs/handoffs/2026-07-11-env-normalization-consolidation.md (Fase 4). Follow-up from the #802 review remains open (shell-level guard in pm.sh spawn_terminal()).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Release Management
    • Updated the package suite to version 5.3.0.
    • Improved release automation to synchronize versions across related packages.
    • Releases can now automatically trigger stable package publishing after completion.
  • Maintenance
    • Refreshed release metadata and package integrity information.
    • Added validation for version updates to help prevent inconsistent package versions.

…haining

Every semantic-release run was blocked at the prepublishOnly safety gate:
validate-publish.js (Check 5) requires .aiox-core/package.json to match the
root version, but semantic-release only bumps the root manifest. Fixes:

- scripts/sync-version-lockstep.js: syncs .aiox-core/package.json and
  compat/aiox-core/package.json (version + @aiox-squads/core dependency pin)
  to the target version. Idempotent, standalone-usable.
- .releaserc.json: @semantic-release/exec prepare step runs the sync with
  ${nextRelease.version} — the gate now passes inside the release run.
- semantic-release.yml: after a non-dry-run release, explicitly dispatch
  npm-publish.yml (stable, all) via gh workflow run — the GITHUB_TOKEN tag/
  release events do not chain workflows (anti-recursion); workflow_dispatch
  is the documented exception (same pattern as release.yml
  trigger-npm-publish). Requires the new actions:write permission.
- Version bump 5.2.9 -> 5.3.0 committed across the three manifests (repo
  convention: chore(release) bump PRs), so the chained npm-publish.yml can
  publish the legacy aiox-core wrapper at 5.3.0 from the committed tree.

Context: docs/handoffs (aiox-cockpit) 2026-07-11-env-normalization-
consolidation.md, Fase 4. The orphan v5.3.0 tag from the failed attempt was
deleted; baseline tag for semantic-release remains v5.2.8 (next: 5.3.0,
minor, driven by the feat commits in #800/#801).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
aiox-core Ready Ready Preview, Comment Jul 11, 2026 4:43pm

Request Review

@github-actions github-actions Bot added area: docs Documentation (docs/) area: devops CI/CD, GitHub Actions (.github/) labels Jul 11, 2026
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Version metadata is aligned to 5.3.0, semantic-release now synchronizes related manifests during preparation, and successful non-dry-run releases dispatch the stable npm publishing workflow for all packages.

Changes

Release version synchronization and publishing

Layer / File(s) Summary
Version lockstep synchronization
.releaserc.json, package.json, scripts/sync-version-lockstep.js, .aiox-core/package.json, compat/aiox-core/package.json
Semantic-release invokes a new script that validates and synchronizes package versions and the compatibility dependency.
Post-release publish dispatch
.github/workflows/semantic-release.yml
The workflow gains actions: write permission and conditionally dispatches npm-publish.yml for stable publishing of all packages.
Release metadata refresh
.aiox-core/install-manifest.yaml
The generated manifest is updated to version 5.3.0 with a refreshed timestamp and package checksum.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: area: workflows, area: cli, area: core

Suggested reviewers: oalanicolas

Sequence Diagram(s)

sequenceDiagram
  participant SemanticRelease
  participant SyncVersionLockstep
  participant PackageManifests
  participant NpmPublishWorkflow
  SemanticRelease->>SyncVersionLockstep: prepare with nextRelease.version
  SyncVersionLockstep->>PackageManifests: synchronize package versions
  SemanticRelease->>NpmPublishWorkflow: dispatch stable publish for all packages
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the release/version-lockstep changes and the new npm-publish chaining workflow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-lockstep-npm-chain

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

📊 Coverage Report

Coverage report not available

📈 Full coverage report available in Codecov


Generated by PR Automation (Story 6.1)

@Pedrovaleriolopez
Pedrovaleriolopez merged commit 3b0738a into main Jul 11, 2026
42 of 43 checks passed
@Pedrovaleriolopez
Pedrovaleriolopez deleted the ci/release-lockstep-npm-chain branch July 11, 2026 16:49
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 5.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
scripts/sync-version-lockstep.js (1)

32-38: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Wrap main() in try/catch for the documented IO-error exit path.

The header promises 1 = invalid input / IO error (Line 21), but only the semver-validation branch emits a clean FAIL: message before exiting — a missing/corrupt .aiox-core/package.json or compat/aiox-core/package.json will instead throw an uncaught exception. The exit code (1) is still correct by Node's default behavior, but the error output is an unstructured stack trace rather than the intended FAIL: message.

🐛 Proposed fix
-function main() {
+function main() {
+  try {
     const rootPkg = readJson(path.join(ROOT, 'package.json'));
     ...
     console.log(`PASS: version lockstep at ${version}`);
+  } catch (err) {
+    console.error(`FAIL: ${err.message}`);
+    process.exit(1);
+  }
 }

Note: static analysis flagged fs.readFileSync/writeFileSync (Lines 32, 36) for path traversal — these are false positives since filePath is always built from the hardcoded ROOT constant, never from external input.

Also applies to: 40-82

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/sync-version-lockstep.js` around lines 32 - 38, Wrap the top-level
main() execution in a try/catch so IO or JSON parsing failures from readJson and
writeJson produce the documented FAIL: message and exit with status 1 instead of
an uncaught stack trace. Preserve the existing semver-validation failure
behavior and successful main() flow.

Sources: Path instructions, Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/semantic-release.yml:
- Around line 176-190: Before the npm-publish dispatch in the semantic-release
workflow, persist the version changes produced by
scripts/sync-version-lockstep.js by committing and pushing the updated
.aiox-core/package.json and compat/aiox-core/package.json to main. Ensure the
push completes before gh workflow run npm-publish.yml executes, while preserving
the existing dry-run guard and dispatch behavior.

---

Nitpick comments:
In `@scripts/sync-version-lockstep.js`:
- Around line 32-38: Wrap the top-level main() execution in a try/catch so IO or
JSON parsing failures from readJson and writeJson produce the documented FAIL:
message and exit with status 1 instead of an uncaught stack trace. Preserve the
existing semver-validation failure behavior and successful main() flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: eb217907-59fd-45ab-bfd6-314898200894

📥 Commits

Reviewing files that changed from the base of the PR and between 0ad5a9f and 8552da3.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • .aiox-core/install-manifest.yaml
  • .aiox-core/package.json
  • .github/workflows/semantic-release.yml
  • .releaserc.json
  • compat/aiox-core/package.json
  • package.json
  • scripts/sync-version-lockstep.js

Comment on lines +176 to +190
- name: Chain npm-publish (legacy wrapper + workspace packages)
if: inputs.dry_run != true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# The tag/release created by semantic-release uses GITHUB_TOKEN, which does
# NOT trigger npm-publish.yml's push/release triggers (GitHub Actions
# anti-recursion). workflow_dispatch via API is the documented exception —
# same pattern release.yml relies on in its trigger-npm-publish job.
# npm-publish.yml is idempotent (should_publish skips versions already in
# the registry), so dispatching after a no-release run is a safe no-op.
gh workflow run npm-publish.yml --ref main -f publish_mode=stable -f packages=all
echo "✅ npm-publish.yml dispatched (stable, all packages)"
echo "### 🔗 Chained npm-publish.yml (stable, all)" >> $GITHUB_STEP_SUMMARY

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect npm-publish.yml for how it resolves package versions to publish,
# and check for any commit/push step in this workflow that might persist
# the lockstep-synced manifests.
fd -H npm-publish.yml .github
cat .github/workflows/npm-publish.yml 2>/dev/null | rg -n -B2 -A5 'version|package\.json|ref'
rg -n 'git (add|commit|push)|`@semantic-release/git`' .github/workflows/semantic-release.yml .releaserc.json

Repository: SynkraAI/aiox-core

Length of output: 13729


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== semantic-release workflow around the chained dispatch =="
sed -n '1,260p' .github/workflows/semantic-release.yml | cat -n | sed -n '1,240p'

echo
echo "== releaserc =="
sed -n '1,220p' .releaserc.json | cat -n | sed -n '1,220p'

echo
echo "== lockstep sync script =="
sed -n '1,240p' scripts/sync-version-lockstep.js | cat -n | sed -n '1,240p'

Repository: SynkraAI/aiox-core

Length of output: 14867


Persist the lockstep manifests before dispatching npm-publish.yml
.github/workflows/semantic-release.yml:176-187 dispatches npm-publish.yml --ref main, but scripts/sync-version-lockstep.js only updates .aiox-core/package.json and compat/aiox-core/package.json in the semantic-release job’s working tree. The chained workflow checks out committed main and reads those package manifests directly, so future releases will publish against stale legacy versions unless the synced files are committed/pushed first or the publish workflow re-runs the sync itself.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/semantic-release.yml around lines 176 - 190, Before the
npm-publish dispatch in the semantic-release workflow, persist the version
changes produced by scripts/sync-version-lockstep.js by committing and pushing
the updated .aiox-core/package.json and compat/aiox-core/package.json to main.
Ensure the push completes before gh workflow run npm-publish.yml executes, while
preserving the existing dry-run guard and dispatch behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: devops CI/CD, GitHub Actions (.github/) area: docs Documentation (docs/) released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant