diff --git a/.github/workflows/npm-package.yml b/.github/workflows/npm-package.yml index 2c3b94a..98915f7 100644 --- a/.github/workflows/npm-package.yml +++ b/.github/workflows/npm-package.yml @@ -69,8 +69,10 @@ jobs: node --check ../../scripts/check-public-release-skeleton.js node --check ../../scripts/check-public-publish-guard.js node --check ../../scripts/update-codex-candidate-manifest.js + node --check ../../scripts/finalize-audited-version.js node --test ../../scripts/update-codex-candidate-manifest.test.js node --test ../../scripts/sync-public-release-from-manifest.test.js + node --test ../../scripts/finalize-audited-version.test.js node --test bin/magi-node-launcher.test.js - name: Manifest / README drift check diff --git a/README.md b/README.md index 1252bdf..f06c0d3 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ codex update ## Rollback / ロールバック ```sh -npm install -g @bash0816/codex-termux@0.144.1 +npm install -g @bash0816/codex-termux@0.144.6 ``` Package files: diff --git a/config/codex-termux-release-manifest.json b/config/codex-termux-release-manifest.json index daad6ef..b9bc6fd 100644 --- a/config/codex-termux-release-manifest.json +++ b/config/codex-termux-release-manifest.json @@ -47,7 +47,7 @@ "update_command": "codex update", "update_guidance": "Run codex update to install the latest audited package version.", "manifest_url": "https://raw.githubusercontent.com/bash0816/Codex-Termux/main/config/codex-termux-release-manifest.json", - "rollback_version": "0.144.1", + "rollback_version": "0.144.6", "rollback_policy": "Reinstall an explicit published version with npm to roll back.", "distribution_strategy": "public-npm-package", "audited_at": "2026-07-01T00:00:00+09:00", diff --git a/docs/20260503_codex-termux-release-guidance.md b/docs/20260503_codex-termux-release-guidance.md index 0247d89..af91322 100644 --- a/docs/20260503_codex-termux-release-guidance.md +++ b/docs/20260503_codex-termux-release-guidance.md @@ -37,7 +37,7 @@ Do not install the upstream `@openai/codex` package directly on Termux. ## Rollback ```sh -npm install -g @bash0816/codex-termux@0.144.1 +npm install -g @bash0816/codex-termux@0.144.6 ``` ## Source Of Truth diff --git a/packages/codex-termux/config/codex-termux-release-manifest.json b/packages/codex-termux/config/codex-termux-release-manifest.json index 388f36f..2a2163e 100644 --- a/packages/codex-termux/config/codex-termux-release-manifest.json +++ b/packages/codex-termux/config/codex-termux-release-manifest.json @@ -32,7 +32,7 @@ "0.128.0" ], "gate_summary": "0.144.3 published as @latest. Build run 29282002840.", - "rollback_version": "0.144.1", + "rollback_version": "0.144.6", "install_command": "npm install -g @bash0816/codex-termux@latest", "update_strategy": "npm_reinstall_audited_package", "manifest_url": "https://raw.githubusercontent.com/bash0816/Codex-Termux/main/config/codex-termux-release-manifest.json", diff --git a/scripts/finalize-audited-version.js b/scripts/finalize-audited-version.js new file mode 100644 index 0000000..eb89715 --- /dev/null +++ b/scripts/finalize-audited-version.js @@ -0,0 +1,53 @@ +const fs = require('fs'); + +function computeFinalizedManifest(manifest, version) { + const previousAudited = manifest.latest_audited_version; + const isVersionBump = previousAudited !== version; + + if (isVersionBump) { + if (!manifest.previous_stable_version) { + throw new Error( + `previous_stable_version is missing in manifest; cannot safely finalize ${version} ` + + `(expected it to equal the current latest_audited_version ${previousAudited})` + ); + } + if (previousAudited !== manifest.previous_stable_version) { + throw new Error( + `latest_audited_version (${previousAudited}) does not match previous_stable_version ` + + `(${manifest.previous_stable_version}); fix config/codex-termux-release-manifest.json ` + + `before finalizing ${version}` + ); + } + } + + const updated = { ...manifest }; + updated.canonical_package_status = 'published'; + updated.public_distribution_status = 'published'; + if (isVersionBump) { + updated.rollback_version = previousAudited; + } + updated.latest_audited_version = version; + const tracked = Array.isArray(manifest.tracked_versions) ? manifest.tracked_versions : []; + updated.tracked_versions = tracked.includes(version) ? tracked : [...tracked, version]; + updated.updated_at = new Date().toISOString(); + return updated; +} + +function finalizeAuditedVersion(manifestPath, version) { + const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); + const updated = computeFinalizedManifest(manifest, version); + fs.writeFileSync(manifestPath, `${JSON.stringify(updated, null, 2)}\n`); + return updated; +} + +module.exports = { computeFinalizedManifest, finalizeAuditedVersion }; + +if (require.main === module) { + const manifestPath = process.argv[2]; + const version = process.argv[3]; + if (!manifestPath || !version) { + console.error('usage: node scripts/finalize-audited-version.js '); + process.exit(1); + } + finalizeAuditedVersion(manifestPath, version); +} diff --git a/scripts/finalize-audited-version.test.js b/scripts/finalize-audited-version.test.js new file mode 100644 index 0000000..627c276 --- /dev/null +++ b/scripts/finalize-audited-version.test.js @@ -0,0 +1,69 @@ +const { test } = require('node:test'); +const { strict: assert } = require('assert'); +const { computeFinalizedManifest } = require('./finalize-audited-version.js'); + +function createManifest(overrides = {}) { + return { + canonical_package_status: 'ready_to_publish', + public_distribution_status: 'staged_for_publish', + latest_audited_version: '0.144.6', + previous_stable_version: '0.144.6', + tracked_versions: ['0.144.5', '0.144.6'], + rollback_version: '0.144.1', + updated_at: '2026-07-01T00:00:00.000Z', + ...overrides, + }; +} + +test('finalize: rollback_version becomes the previous latest_audited_version', () => { + const manifest = createManifest(); + const updated = computeFinalizedManifest(manifest, '0.145.0'); + assert.equal(updated.rollback_version, '0.144.6'); + assert.equal(updated.latest_audited_version, '0.145.0'); + assert.equal(updated.canonical_package_status, 'published'); + assert.equal(updated.public_distribution_status, 'published'); +}); + +test('finalize: idempotent rerun for the same version does not touch rollback_version', () => { + const manifest = createManifest({ + latest_audited_version: '0.145.0', + previous_stable_version: '0.144.6', + rollback_version: '0.144.6', + }); + const updated = computeFinalizedManifest(manifest, '0.145.0'); + assert.equal(updated.rollback_version, '0.144.6'); + assert.equal(updated.latest_audited_version, '0.145.0'); +}); + +test('finalize: throws when previous_stable_version is missing', () => { + const manifest = createManifest({ previous_stable_version: undefined }); + assert.throws(() => computeFinalizedManifest(manifest, '0.145.0'), /previous_stable_version is missing/); +}); + +test('finalize: throws when latest_audited_version is missing entirely', () => { + const manifest = createManifest({ latest_audited_version: undefined, previous_stable_version: undefined }); + assert.throws(() => computeFinalizedManifest(manifest, '0.145.0'), /previous_stable_version is missing/); +}); + +test('finalize: throws when latest_audited_version does not match previous_stable_version', () => { + const manifest = createManifest({ + latest_audited_version: '0.144.6', + previous_stable_version: '0.144.5', + }); + assert.throws( + () => computeFinalizedManifest(manifest, '0.145.0'), + /does not match previous_stable_version/ + ); +}); + +test('finalize: does not add a duplicate entry to tracked_versions', () => { + const manifest = createManifest({ tracked_versions: ['0.144.6', '0.145.0'] }); + const updated = computeFinalizedManifest(manifest, '0.145.0'); + assert.deepEqual(updated.tracked_versions, ['0.144.6', '0.145.0']); +}); + +test('finalize: appends the new version to tracked_versions when absent', () => { + const manifest = createManifest({ tracked_versions: ['0.144.6'] }); + const updated = computeFinalizedManifest(manifest, '0.145.0'); + assert.deepEqual(updated.tracked_versions, ['0.144.6', '0.145.0']); +}); diff --git a/scripts/finalize-update-docs.sh b/scripts/finalize-update-docs.sh index fc53a61..618fd58 100755 --- a/scripts/finalize-update-docs.sh +++ b/scripts/finalize-update-docs.sh @@ -9,19 +9,7 @@ if [ "$CANDIDATE_VER" != "$VER" ]; then exit 1 fi -node -e " - const fs = require('fs'); - const p = 'config/codex-termux-release-manifest.json'; - const m = JSON.parse(fs.readFileSync(p, 'utf8')); - m.canonical_package_status = 'published'; - m.public_distribution_status = 'published'; - m.latest_audited_version = process.env.VER; - if (!m.tracked_versions.includes(process.env.VER)) { - m.tracked_versions.push(process.env.VER); - } - m.updated_at = new Date().toISOString(); - fs.writeFileSync(p, JSON.stringify(m, null, 2) + '\n'); -" +node scripts/finalize-audited-version.js config/codex-termux-release-manifest.json "$VER" node scripts/sync-public-release-from-manifest.js node scripts/sync-public-release-from-manifest.js --check