Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/mcp-release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,39 @@ jobs:
manifest-file: .release-please-manifest.json
token: ${{ secrets.GITHUB_TOKEN }}

# release-please's extra-files JSON-path updater doesn't reliably reach package-lock.json's
# per-workspace version fields (keys containing "/", nested under a manifest-mode component
# block) -- confirmed empirically (both the mcp-v0.7.0 dry run's precursor and the first two
# engine-v0.2.0 dry runs left it stale, breaking npm ci with "Missing: <pkg>@<version> from
# lock file"). Patches it directly on whichever release branch(es) release-please just
# created/updated, using the same branch naming convention its own commits already rely on.
- name: Sync package-lock.json on any release branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git remote set-url origin "https://github.com/${GITHUB_REPOSITORY}.git"
gh auth setup-git
for component in mcp engine; do
branch="release-please--branches--main--components--${component}"
if ! git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then
echo "No release branch for $component, skipping."
continue
fi
git fetch origin "$branch"
git checkout -B "sync-check-${component}" "origin/$branch"
node scripts/sync-release-lockfile-versions.mjs packages/gittensory-mcp packages/gittensory-engine
if git diff --quiet package-lock.json; then
echo "package-lock.json already in sync on $branch."
else
git add package-lock.json
git commit -m "chore(release): sync package-lock.json"
git push origin "HEAD:$branch"
fi
done

# release-please creates the component tag + GitHub Release with GITHUB_TOKEN, which (by
# GitHub's recursion-prevention rule) does NOT fire push/tag-based workflows. workflow_dispatch
# IS exempt from that rule, so dispatch the OIDC publish workflow explicitly, telling it
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions packages/gittensory-engine/src/version.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/**
* Published semver of `@jsonbored/gittensory-engine`. Keep in lockstep with `package.json` `version`
* (enforced by `test/unit/engine-version.test.ts`).
*/
export const ENGINE_VERSION = "0.1.0";
import ownPackageJson from "../package.json" with { type: "json" };

/** Published semver of `@jsonbored/gittensory-engine`, derived from this package's own package.json. */
export const ENGINE_VERSION: string = ownPackageJson.version;
2 changes: 1 addition & 1 deletion packages/gittensory-mcp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"build": "node --check bin/gittensory-mcp.js && node --check lib/local-branch.js && node --check scripts/gittensor-score-preview.mjs"
},
"dependencies": {
"@jsonbored/gittensory-engine": "^0.1.0",
"@jsonbored/gittensory-engine": ">=0.1.0 <1.0.0",
"@modelcontextprotocol/sdk": "1.29.0",
"zod": "^4.4.3"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/gittensory-miner/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"build": "node --check bin/gittensory-miner.js && node --check lib/cli.js && node --check lib/deny-check.js && node --check lib/run-state-cli.js && node --check lib/update-check.js && node --check lib/opportunity-fanout.js && node --check lib/ci-poller.js && node --check lib/run-state.js && node --check lib/deny-hooks.js && node --check lib/event-ledger.js && node --check lib/event-ledger-cli.js && node --check lib/claim-ledger.js && node --check lib/claim-ledger-expiry.js && node --check lib/portfolio-queue.js && node --check lib/portfolio-queue-cli.js && node --check lib/portfolio-discovery.js && node --check lib/opportunity-ranker.js && node --check lib/plan-store.js && node --check lib/plan-store-cli.js && node --check lib/rejection-templates.js && node --check lib/governor-ledger.js && node --check lib/governor-ledger-cli.js && node --check lib/manage-status.js && node --check lib/manage-poll.js && node --check lib/status.js && node --check lib/laptop-init.js && node --check lib/replay-objective-anchor.js && node --check lib/replay-task-generation.js && node --check lib/calibration-types.js && node --check lib/calibration.js"
},
"dependencies": {
"@jsonbored/gittensory-engine": "0.1.0"
"@jsonbored/gittensory-engine": ">=0.1.0 <1.0.0"
},
"engines": {
"node": ">=22.13.0"
Expand Down
18 changes: 2 additions & 16 deletions release-please-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,12 @@
"packages/gittensory-mcp": {
"release-type": "node",
"component": "mcp",
"package-name": "@jsonbored/gittensory-mcp",
"extra-files": [
{
"type": "json",
"path": "package-lock.json",
"jsonpath": "$.packages['packages/gittensory-mcp'].version"
}
]
"package-name": "@jsonbored/gittensory-mcp"
},
"packages/gittensory-engine": {
"release-type": "node",
"component": "engine",
"package-name": "@jsonbored/gittensory-engine",
"extra-files": [
{
"type": "json",
"path": "package-lock.json",
"jsonpath": "$.packages['packages/gittensory-engine'].version"
}
]
"package-name": "@jsonbored/gittensory-engine"
}
},
"include-component-in-tag": true,
Expand Down
43 changes: 43 additions & 0 deletions scripts/sync-release-lockfile-versions.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env node
// release-please's `extra-files` JSON-path updater doesn't reliably reach package-lock.json's
// per-workspace version fields, whose keys contain slashes (e.g. "packages/gittensory-engine")
// nested under a manifest-mode component's own release-please-config.json block -- confirmed
// empirically (mcp-v0.7.0/engine-v0.2.0 dry runs both left package-lock.json un-synced, breaking
// `npm ci` with "Missing: @jsonbored/gittensory-engine@0.1.0 from lock file"). This does the same
// single-line replacement a human would make by hand: find the workspace's own manifest-mirror
// entry, replace just its "version" value. No JSON.parse/stringify round-trip on the whole
// multi-thousand-line lockfile, which would risk reordering/reformatting far beyond the one line
// that actually changed.
import { readFileSync, writeFileSync } from "node:fs";

const targets = process.argv.slice(2);
if (targets.length === 0) {
console.error("Usage: node sync-release-lockfile-versions.mjs <workspace-path> [<workspace-path> ...]");
process.exit(1);
}

const lockPath = "package-lock.json";
let content = readFileSync(lockPath, "utf8");
let changed = false;

for (const workspacePath of targets) {
const version = JSON.parse(readFileSync(`${workspacePath}/package.json`, "utf8")).version;
const escapedKey = workspacePath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
// Anchors on the workspace's own block header + its "name" line (both stable, unique) so this
// can't accidentally match a different package's "version" line elsewhere in the file.
const pattern = new RegExp(`("${escapedKey}":\\s*\\{\\s*\\n\\s*"name":[^\\n]*\\n\\s*"version":\\s*")[^"]*(")`);
if (!pattern.test(content)) {
console.error(`${workspacePath}: pattern not found in ${lockPath} -- nothing changed.`);
continue;
}
const updated = content.replace(pattern, `$1${version}$2`);
if (updated === content) {
console.log(`${workspacePath}: already at ${version}.`);
} else {
content = updated;
changed = true;
console.log(`${workspacePath}: synced to ${version}.`);
}
}

if (changed) writeFileSync(lockPath, content);
2 changes: 1 addition & 1 deletion test/unit/gittensory-engine-scaffold.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import enginePkg from "../../packages/gittensory-engine/package.json";
describe("gittensory-engine package scaffold", () => {
it("declares the published package identity", () => {
expect(enginePkg.name).toBe("@jsonbored/gittensory-engine");
expect(enginePkg.version).toBe("0.1.0");
expect(enginePkg.version).toMatch(/^\d+\.\d+\.\d+$/);
expect(enginePkg.type).toBe("module");
expect(enginePkg.license).toBe("AGPL-3.0-only");
expect(enginePkg.publishConfig?.access).toBe("public");
Expand Down
Loading