From f1249d39156781ae59c41cc4921e179fc3b013cb Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Sun, 12 Apr 2026 22:10:06 -0700 Subject: [PATCH] fix: tighten release script version sync --- docs/tr/README.md | 2 +- scripts/release.sh | 30 +++++++++++++++++++++++------- tests/plugin-manifest.test.js | 10 +++++----- tests/scripts/release.test.js | 2 +- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/docs/tr/README.md b/docs/tr/README.md index 7ad2f8c2..812e172e 100644 --- a/docs/tr/README.md +++ b/docs/tr/README.md @@ -82,7 +82,7 @@ Bu repository yalnızca ham kodu içerir. Rehberler her şeyi açıklıyor. ### v1.10.0 — Surface Sync, Operatör İş Akışları ve ECC 2.0 Alpha (Nis 2026) - **Public surface canlı repo ile senkronlandı** — metadata, katalog sayıları, plugin manifest'leri ve kurulum odaklı dokümanlar artık gerçek OSS yüzeyiyle eşleşiyor. -- **Operatör ve dışa dönük iş akışları büyüdü** — `brand-voice`, `social-graph-ranker`, `customer-billing-ops`, `google-workspace-ops` ve ilgili operator skill'leri aynı sistem içinde tamamlandı. +- **Operatör ve dışa dönük iş akışları büyüdü** — `brand-voice`, `social-graph-ranker`, `customer-billing-ops`, `google-workspace-ops` ve ilgili operatör skill'leri aynı sistem içinde tamamlandı. - **Medya ve lansman araçları** — `manim-video`, `remotion-video-creation` ve sosyal yayın yüzeyleri teknik anlatım ve duyuru akışlarını aynı repo içine taşıdı. - **Framework ve ürün yüzeyi genişledi** — `nestjs-patterns`, daha zengin Codex/OpenCode kurulum yüzeyleri ve çapraz harness paketleme iyileştirmeleri repo'yu Claude Code dışına da taşıdı. - **ECC 2.0 alpha repoda** — `ecc2/` altındaki Rust kontrol katmanı artık yerelde derleniyor ve `dashboard`, `start`, `sessions`, `status`, `stop`, `resume` ve `daemon` komutlarını sunuyor. diff --git a/scripts/release.sh b/scripts/release.sh index 9518d514..d2694623 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -91,9 +91,15 @@ update_package_lock_version() { process.exit(1); } lock.version = version; - if (lock.packages && lock.packages[""] && typeof lock.packages[""] === "object") { - lock.packages[""].version = version; + if (!lock.packages || typeof lock.packages !== "object" || Array.isArray(lock.packages)) { + console.error(`Error: ${file} is missing lock.packages`); + process.exit(1); } + if (!lock.packages[""] || typeof lock.packages[""] !== "object" || Array.isArray(lock.packages[""])) { + console.error(`Error: ${file} is missing lock.packages[\"\"]`); + process.exit(1); + } + lock.packages[""].version = version; fs.writeFileSync(file, `${JSON.stringify(lock, null, 2)}\n`); ' "$1" "$VERSION" } @@ -101,22 +107,32 @@ update_package_lock_version() { update_readme_version_row() { local file="$1" local label="$2" + local first_col="$3" + local second_col="$4" + local third_col="$5" node -e ' const fs = require("fs"); const file = process.argv[1]; const version = process.argv[2]; const label = process.argv[3]; + const firstCol = process.argv[4]; + const secondCol = process.argv[5]; + const thirdCol = process.argv[6]; + const escape = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const current = fs.readFileSync(file, "utf8"); const updated = current.replace( - new RegExp(`^\\| \\*\\*${label}\\*\\* \\| Plugin \\| Plugin \\| Reference config \\| [0-9][0-9.]* \\|$`, "m"), - `| **${label}** | Plugin | Plugin | Reference config | ${version} |` + new RegExp( + `^\\| \\*\\*${escape(label)}\\*\\* \\| ${escape(firstCol)} \\| ${escape(secondCol)} \\| ${escape(thirdCol)} \\| [0-9]+\\.[0-9]+\\.[0-9]+ \\|$`, + "m" + ), + `| **${label}** | ${firstCol} | ${secondCol} | ${thirdCol} | ${version} |` ); if (updated === current) { console.error(`Error: could not update README version row in ${file}`); process.exit(1); } fs.writeFileSync(file, updated); - ' "$file" "$VERSION" "$label" + ' "$file" "$VERSION" "$label" "$first_col" "$second_col" "$third_col" } update_selective_install_repo_version() { @@ -215,8 +231,8 @@ update_codex_marketplace_version update_version "$CODEX_PLUGIN_JSON" "s|\"version\": *\"[^\"]*\"|\"version\": \"$VERSION\"|" update_version "$OPENCODE_PACKAGE_JSON" "s|\"version\": *\"[^\"]*\"|\"version\": \"$VERSION\"|" update_package_lock_version "$OPENCODE_PACKAGE_LOCK_JSON" -update_readme_version_row "$README_FILE" "Version" -update_readme_version_row "$ZH_CN_README_FILE" "版本" +update_readme_version_row "$README_FILE" "Version" "Plugin" "Plugin" "Reference config" +update_readme_version_row "$ZH_CN_README_FILE" "版本" "插件" "插件" "参考配置" update_selective_install_repo_version "$SELECTIVE_INSTALL_ARCHITECTURE_DOC" # Verify the bumped release surface is still internally consistent before diff --git a/tests/plugin-manifest.test.js b/tests/plugin-manifest.test.js index 1bd7bb48..b779f382 100644 --- a/tests/plugin-manifest.test.js +++ b/tests/plugin-manifest.test.js @@ -95,28 +95,28 @@ test('package-lock.json root version matches package.json', () => { test('AGENTS.md version line matches package.json', () => { const agentsSource = fs.readFileSync(rootAgentsPath, 'utf8'); - const match = agentsSource.match(/^\*\*Version:\*\* ([0-9][0-9.]*)$/m); + const match = agentsSource.match(/^\*\*Version:\*\* ([0-9]+\.[0-9]+\.[0-9]+)$/m); assert.ok(match, 'Expected AGENTS.md to declare a top-level version line'); assert.strictEqual(match[1], expectedVersion); }); test('docs/tr/AGENTS.md version line matches package.json', () => { const agentsSource = fs.readFileSync(trAgentsPath, 'utf8'); - const match = agentsSource.match(/^\*\*Sürüm:\*\* ([0-9][0-9.]*)$/m); + const match = agentsSource.match(/^\*\*Sürüm:\*\* ([0-9]+\.[0-9]+\.[0-9]+)$/m); assert.ok(match, 'Expected docs/tr/AGENTS.md to declare a top-level version line'); assert.strictEqual(match[1], expectedVersion); }); test('docs/zh-CN/AGENTS.md version line matches package.json', () => { const agentsSource = fs.readFileSync(zhCnAgentsPath, 'utf8'); - const match = agentsSource.match(/^\*\*版本:\*\* ([0-9][0-9.]*)$/m); + const match = agentsSource.match(/^\*\*版本:\*\* ([0-9]+\.[0-9]+\.[0-9]+)$/m); assert.ok(match, 'Expected docs/zh-CN/AGENTS.md to declare a top-level version line'); assert.strictEqual(match[1], expectedVersion); }); test('agent.yaml version matches package.json', () => { const agentYamlSource = fs.readFileSync(agentYamlPath, 'utf8'); - const match = agentYamlSource.match(/^version:\s*([0-9][0-9.]*)$/m); + const match = agentYamlSource.match(/^version:\s*([0-9]+\.[0-9]+\.[0-9]+)$/m); assert.ok(match, 'Expected agent.yaml to declare a top-level version field'); assert.strictEqual(match[1], expectedVersion); }); @@ -129,7 +129,7 @@ test('VERSION file matches package.json', () => { test('docs/SELECTIVE-INSTALL-ARCHITECTURE.md repoVersion example matches package.json', () => { const source = fs.readFileSync(selectiveInstallArchitecturePath, 'utf8'); - const match = source.match(/"repoVersion":\s*"([0-9][0-9.]*)"/); + const match = source.match(/"repoVersion":\s*"([0-9]+\.[0-9]+\.[0-9]+)"/); assert.ok(match, 'Expected docs/SELECTIVE-INSTALL-ARCHITECTURE.md to declare a repoVersion example'); assert.strictEqual(match[1], expectedVersion); }); diff --git a/tests/scripts/release.test.js b/tests/scripts/release.test.js index 3a0511c6..299f5352 100644 --- a/tests/scripts/release.test.js +++ b/tests/scripts/release.test.js @@ -35,7 +35,7 @@ function runTests() { })) passed++; else failed++; if (test('release script reruns release metadata sync validation before commit/tag', () => { - const syncCheckIndex = source.indexOf('node tests/plugin-manifest.test.js'); + const syncCheckIndex = source.lastIndexOf('node tests/plugin-manifest.test.js'); const commitIndex = source.indexOf('git commit -m "chore: bump plugin version to $VERSION"'); assert.ok(syncCheckIndex >= 0, 'release.sh should run plugin-manifest.test.js');