bump: update plugin version to 1.0.3 (#180)
This commit is contained in:
parent
bc8fa661a5
commit
11a720b7db
@ -5,13 +5,13 @@
|
|||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"description": "Codex plugins to use in Claude Code for delegation and code review.",
|
"description": "Codex plugins to use in Claude Code for delegation and code review.",
|
||||||
"version": "1.0.2"
|
"version": "1.0.3"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "codex",
|
"name": "codex",
|
||||||
"description": "Use Codex from Claude Code to review code or delegate tasks.",
|
"description": "Use Codex from Claude Code to review code or delegate tasks.",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "OpenAI"
|
"name": "OpenAI"
|
||||||
},
|
},
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@openai/codex-plugin-cc",
|
"name": "@openai/codex-plugin-cc",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@openai/codex-plugin-cc",
|
"name": "@openai/codex-plugin-cc",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^25.5.0",
|
"@types/node": "^25.5.0",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@openai/codex-plugin-cc",
|
"name": "@openai/codex-plugin-cc",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "Use Codex from Claude Code to review code or delegate tasks.",
|
"description": "Use Codex from Claude Code to review code or delegate tasks.",
|
||||||
@ -9,6 +9,8 @@
|
|||||||
"node": ">=18.18.0"
|
"node": ">=18.18.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"bump-version": "node scripts/bump-version.mjs",
|
||||||
|
"check-version": "node scripts/bump-version.mjs --check",
|
||||||
"prebuild": "mkdir -p plugins/codex/.generated/app-server-types && codex app-server generate-ts --out plugins/codex/.generated/app-server-types",
|
"prebuild": "mkdir -p plugins/codex/.generated/app-server-types && codex app-server generate-ts --out plugins/codex/.generated/app-server-types",
|
||||||
"build": "tsc -p tsconfig.app-server.json",
|
"build": "tsc -p tsconfig.app-server.json",
|
||||||
"test": "node --test tests/*.test.mjs"
|
"test": "node --test tests/*.test.mjs"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "codex",
|
"name": "codex",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"description": "Use Codex from Claude Code to review code or delegate tasks.",
|
"description": "Use Codex from Claude Code to review code or delegate tasks.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "OpenAI"
|
"name": "OpenAI"
|
||||||
|
|||||||
227
scripts/bump-version.mjs
Normal file
227
scripts/bump-version.mjs
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
import fs from "node:fs";
|
||||||
|
import path from "node:path";
|
||||||
|
import process from "node:process";
|
||||||
|
|
||||||
|
const VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
||||||
|
|
||||||
|
const TARGETS = [
|
||||||
|
{
|
||||||
|
file: "package.json",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
label: "version",
|
||||||
|
get: (json) => json.version,
|
||||||
|
set: (json, version) => {
|
||||||
|
json.version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: "package-lock.json",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
label: "version",
|
||||||
|
get: (json) => json.version,
|
||||||
|
set: (json, version) => {
|
||||||
|
json.version = version;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "packages[\"\"].version",
|
||||||
|
get: (json) => json.packages?.[""]?.version,
|
||||||
|
set: (json, version) => {
|
||||||
|
requireObject(json.packages?.[""], "package-lock.json packages[\"\"]");
|
||||||
|
json.packages[""].version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: "plugins/codex/.claude-plugin/plugin.json",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
label: "version",
|
||||||
|
get: (json) => json.version,
|
||||||
|
set: (json, version) => {
|
||||||
|
json.version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: ".claude-plugin/marketplace.json",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
label: "metadata.version",
|
||||||
|
get: (json) => json.metadata?.version,
|
||||||
|
set: (json, version) => {
|
||||||
|
requireObject(json.metadata, ".claude-plugin/marketplace.json metadata");
|
||||||
|
json.metadata.version = version;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "plugins[codex].version",
|
||||||
|
get: (json) => findMarketplacePlugin(json).version,
|
||||||
|
set: (json, version) => {
|
||||||
|
findMarketplacePlugin(json).version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function usage() {
|
||||||
|
return [
|
||||||
|
"Usage:",
|
||||||
|
" node scripts/bump-version.mjs <version>",
|
||||||
|
" node scripts/bump-version.mjs --check [version]",
|
||||||
|
"",
|
||||||
|
"Options:",
|
||||||
|
" --check Verify manifest versions. Uses package.json when version is omitted.",
|
||||||
|
" --root <dir> Run against a different repository root.",
|
||||||
|
" --help Print this help."
|
||||||
|
].join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseArgs(argv) {
|
||||||
|
const options = {
|
||||||
|
check: false,
|
||||||
|
root: process.cwd(),
|
||||||
|
version: null
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let i = 0; i < argv.length; i += 1) {
|
||||||
|
const arg = argv[i];
|
||||||
|
|
||||||
|
if (arg === "--check") {
|
||||||
|
options.check = true;
|
||||||
|
} else if (arg === "--root") {
|
||||||
|
const root = argv[i + 1];
|
||||||
|
if (!root) {
|
||||||
|
throw new Error("--root requires a directory.");
|
||||||
|
}
|
||||||
|
options.root = root;
|
||||||
|
i += 1;
|
||||||
|
} else if (arg === "--help" || arg === "-h") {
|
||||||
|
options.help = true;
|
||||||
|
} else if (arg.startsWith("-")) {
|
||||||
|
throw new Error(`Unknown option: ${arg}`);
|
||||||
|
} else if (options.version) {
|
||||||
|
throw new Error(`Unexpected extra argument: ${arg}`);
|
||||||
|
} else {
|
||||||
|
options.version = arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
options.root = path.resolve(options.root);
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateVersion(version) {
|
||||||
|
if (!VERSION_PATTERN.test(version)) {
|
||||||
|
throw new Error(`Expected a semver-like version such as 1.0.3, got: ${version}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function requireObject(value, label) {
|
||||||
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
||||||
|
throw new Error(`Expected ${label} to be an object.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findMarketplacePlugin(json) {
|
||||||
|
const plugin = json.plugins?.find((entry) => entry?.name === "codex");
|
||||||
|
requireObject(plugin, ".claude-plugin/marketplace.json plugins[codex]");
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
function readJson(root, file) {
|
||||||
|
const filePath = path.join(root, file);
|
||||||
|
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeJson(root, file, json) {
|
||||||
|
const filePath = path.join(root, file);
|
||||||
|
fs.writeFileSync(filePath, `${JSON.stringify(json, null, 2)}\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readPackageVersion(root) {
|
||||||
|
const packageJson = readJson(root, "package.json");
|
||||||
|
if (typeof packageJson.version !== "string") {
|
||||||
|
throw new Error("package.json version must be a string.");
|
||||||
|
}
|
||||||
|
validateVersion(packageJson.version);
|
||||||
|
return packageJson.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkVersions(root, expectedVersion) {
|
||||||
|
const mismatches = [];
|
||||||
|
|
||||||
|
for (const target of TARGETS) {
|
||||||
|
const json = readJson(root, target.file);
|
||||||
|
for (const value of target.values) {
|
||||||
|
const actual = value.get(json);
|
||||||
|
if (actual !== expectedVersion) {
|
||||||
|
mismatches.push(`${target.file} ${value.label}: expected ${expectedVersion}, found ${actual ?? "<missing>"}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mismatches;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bumpVersion(root, version) {
|
||||||
|
const changedFiles = [];
|
||||||
|
|
||||||
|
for (const target of TARGETS) {
|
||||||
|
const json = readJson(root, target.file);
|
||||||
|
const before = JSON.stringify(json);
|
||||||
|
|
||||||
|
for (const value of target.values) {
|
||||||
|
value.set(json, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JSON.stringify(json) !== before) {
|
||||||
|
writeJson(root, target.file, json);
|
||||||
|
changedFiles.push(target.file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changedFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const options = parseArgs(process.argv.slice(2));
|
||||||
|
if (options.help) {
|
||||||
|
console.log(usage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = options.version ?? (options.check ? readPackageVersion(options.root) : null);
|
||||||
|
if (!version) {
|
||||||
|
throw new Error(`Missing version.\n\n${usage()}`);
|
||||||
|
}
|
||||||
|
validateVersion(version);
|
||||||
|
|
||||||
|
if (options.check) {
|
||||||
|
const mismatches = checkVersions(options.root, version);
|
||||||
|
if (mismatches.length > 0) {
|
||||||
|
throw new Error(`Version metadata is out of sync:\n${mismatches.join("\n")}`);
|
||||||
|
}
|
||||||
|
console.log(`All version metadata matches ${version}.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const changedFiles = bumpVersion(options.root, version);
|
||||||
|
const touched = changedFiles.length > 0 ? changedFiles.join(", ") : "no files changed";
|
||||||
|
console.log(`Set version metadata to ${version}: ${touched}.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
main();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error instanceof Error ? error.message : String(error));
|
||||||
|
process.exitCode = 1;
|
||||||
|
}
|
||||||
88
tests/bump-version.test.mjs
Normal file
88
tests/bump-version.test.mjs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import fs from "node:fs";
|
||||||
|
import path from "node:path";
|
||||||
|
import test from "node:test";
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
|
import { makeTempDir, run } from "./helpers.mjs";
|
||||||
|
|
||||||
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||||
|
const SCRIPT = path.join(ROOT, "scripts", "bump-version.mjs");
|
||||||
|
|
||||||
|
function writeJson(filePath, json) {
|
||||||
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||||
|
fs.writeFileSync(filePath, `${JSON.stringify(json, null, 2)}\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readJson(filePath) {
|
||||||
|
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeVersionFixture() {
|
||||||
|
const root = makeTempDir();
|
||||||
|
|
||||||
|
writeJson(path.join(root, "package.json"), {
|
||||||
|
name: "@openai/codex-plugin-cc",
|
||||||
|
version: "1.0.2"
|
||||||
|
});
|
||||||
|
writeJson(path.join(root, "package-lock.json"), {
|
||||||
|
name: "@openai/codex-plugin-cc",
|
||||||
|
version: "1.0.2",
|
||||||
|
lockfileVersion: 3,
|
||||||
|
packages: {
|
||||||
|
"": {
|
||||||
|
name: "@openai/codex-plugin-cc",
|
||||||
|
version: "1.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
writeJson(path.join(root, "plugins", "codex", ".claude-plugin", "plugin.json"), {
|
||||||
|
name: "codex",
|
||||||
|
version: "1.0.2"
|
||||||
|
});
|
||||||
|
writeJson(path.join(root, ".claude-plugin", "marketplace.json"), {
|
||||||
|
metadata: {
|
||||||
|
version: "1.0.2"
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: "codex",
|
||||||
|
version: "1.0.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
test("bump-version updates every release manifest", () => {
|
||||||
|
const root = makeVersionFixture();
|
||||||
|
|
||||||
|
const result = run("node", [SCRIPT, "--root", root, "1.2.3"], {
|
||||||
|
cwd: ROOT
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(result.status, 0, result.stderr);
|
||||||
|
assert.equal(readJson(path.join(root, "package.json")).version, "1.2.3");
|
||||||
|
assert.equal(readJson(path.join(root, "package-lock.json")).version, "1.2.3");
|
||||||
|
assert.equal(readJson(path.join(root, "package-lock.json")).packages[""].version, "1.2.3");
|
||||||
|
assert.equal(readJson(path.join(root, "plugins", "codex", ".claude-plugin", "plugin.json")).version, "1.2.3");
|
||||||
|
assert.equal(readJson(path.join(root, ".claude-plugin", "marketplace.json")).metadata.version, "1.2.3");
|
||||||
|
assert.equal(readJson(path.join(root, ".claude-plugin", "marketplace.json")).plugins[0].version, "1.2.3");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("bump-version check mode reports stale metadata", () => {
|
||||||
|
const root = makeVersionFixture();
|
||||||
|
writeJson(path.join(root, "package.json"), {
|
||||||
|
name: "@openai/codex-plugin-cc",
|
||||||
|
version: "1.0.3"
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = run("node", [SCRIPT, "--root", root, "--check"], {
|
||||||
|
cwd: ROOT
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.notEqual(result.status, 0);
|
||||||
|
assert.match(result.stderr, /plugins\/codex\/\.claude-plugin\/plugin\.json version/);
|
||||||
|
assert.match(result.stderr, /\.claude-plugin\/marketplace\.json metadata\.version/);
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user