logancyang_obsidian-copilot/version-bump.mjs

63 lines
2.7 KiB
JavaScript
Raw Permalink Normal View History

chore(release): make prerelease tooling stop poisoning master's manifest.json (#2429) * chore(release): make prerelease tooling stop poisoning master's manifest.json Background: Obsidian's community plugin store reads manifest.json from master to decide which GitHub Release to serve installers. The prerelease agent's npm version bump was rewriting manifest.json with a prerelease version, which broke plugin installs until hotfix #2428 reverted master's manifest.json to the stable version. This PR fixes the underlying tooling so it can't recur. Changes: - version-bump.mjs now branches on whether npm_package_version is a prerelease (contains a hyphen). Stable: writes to manifest.json + versions.json. Prerelease: writes to manifest-beta.json + versions.json, leaving manifest.json untouched. Seeds manifest-beta.json from manifest.json when it doesn't exist yet. On a stable bump that finds a stale manifest-beta.json, removes it (git rm) because the new stable supersedes the in-flight beta. Stages the right files itself; package.json no longer needs the explicit git-add step. - package.json: simplifies the "version" lifecycle script to just "node version-bump.mjs" since the script now stages files itself. - release.yml: * "Verify version matches manifest" step now selects the file based on is_prerelease (manifest.json for stable, manifest-beta.json for prerelease). For stable runs nothing changes. * Adds a "Prepare release-asset manifest" step before the release upload that copies manifest-beta.json over manifest.json IN THE RUNNER only when the release is a prerelease. This makes the uploaded manifest.json asset carry the prerelease version so testers sideloading the assets get a consistent manifest. The committed master manifest.json is never touched by the workflow (the workflow doesn't push back). - .claude/agents/release.md: adds a Step 0 pre-flight assertion that master's manifest.json.version equals the latest non-prerelease GitHub Release tag. Catches drift loudly before doing any work. Notes the manifest-beta.json auto-removal in the rules. - .claude/agents/prerelease.md: documents the manifest.json / manifest-beta.json split. Adds the same Step 0 drift assertion. Updates the git add step to stage manifest-beta.json instead of manifest.json. Adds an explicit guard rule that manifest.json must not change during a prerelease bump. Verified locally by exercising version-bump.mjs in a throwaway repo: - Stable 3.2.8 -> 3.2.9: writes manifest.json + versions.json, no beta side - Prerelease 3.2.8 -> 3.2.9-beta.0: creates manifest-beta.json, manifest.json untouched - Prerelease iteration 3.2.9-beta.0 -> 3.2.9-beta.1: updates manifest-beta.json, manifest.json untouched - Stable supersedes beta 3.2.9-beta.1 -> 3.2.9: writes manifest.json, git-rm's manifest-beta.json Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): address Codex review on PR #2429 1. release.yml: when verifying a prerelease, also assert that the committed manifest.json on the merge commit still equals the latest non-prerelease GitHub Release tag. This catches an old-style version bump or hand edit that accidentally modified master's manifest.json — without this guard, the verify step only inspected manifest-beta.json so a poisoned manifest.json could merge unnoticed and break the Obsidian plugin store. 2. version-bump.mjs: don't fail stable bumps when manifest-beta.json exists on disk but is untracked (or has local modifications). Check git trackedness first; use `git rm -f` only when tracked, fall back to a plain unlink for working-tree-only files. Logs which path it took. Verified both scenarios in a throwaway repo: - Untracked manifest-beta.json + stable bump: unlinked, no git rm error - Tracked manifest-beta.json + stable bump: staged deletion via git rm -f Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): use /releases/latest API for stable-drift guard gh release list defaults to 30 results, so a cluster of 30+ prereleases since the last stable would make the prerelease drift guard return empty and fail valid prerelease publishes. Switch to GitHub's /releases/latest endpoint instead, which by design returns only the most-recent non-prerelease, non-draft release in a single call regardless of how many prereleases have accumulated. Applied the same fix to the Step 0 drift check in both the release agent and prerelease agent doc for consistency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:53:48 +00:00
import { execSync } from "child_process";
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "fs";
2023-03-31 00:15:32 +00:00
const targetVersion = process.env.npm_package_version;
chore(release): make prerelease tooling stop poisoning master's manifest.json (#2429) * chore(release): make prerelease tooling stop poisoning master's manifest.json Background: Obsidian's community plugin store reads manifest.json from master to decide which GitHub Release to serve installers. The prerelease agent's npm version bump was rewriting manifest.json with a prerelease version, which broke plugin installs until hotfix #2428 reverted master's manifest.json to the stable version. This PR fixes the underlying tooling so it can't recur. Changes: - version-bump.mjs now branches on whether npm_package_version is a prerelease (contains a hyphen). Stable: writes to manifest.json + versions.json. Prerelease: writes to manifest-beta.json + versions.json, leaving manifest.json untouched. Seeds manifest-beta.json from manifest.json when it doesn't exist yet. On a stable bump that finds a stale manifest-beta.json, removes it (git rm) because the new stable supersedes the in-flight beta. Stages the right files itself; package.json no longer needs the explicit git-add step. - package.json: simplifies the "version" lifecycle script to just "node version-bump.mjs" since the script now stages files itself. - release.yml: * "Verify version matches manifest" step now selects the file based on is_prerelease (manifest.json for stable, manifest-beta.json for prerelease). For stable runs nothing changes. * Adds a "Prepare release-asset manifest" step before the release upload that copies manifest-beta.json over manifest.json IN THE RUNNER only when the release is a prerelease. This makes the uploaded manifest.json asset carry the prerelease version so testers sideloading the assets get a consistent manifest. The committed master manifest.json is never touched by the workflow (the workflow doesn't push back). - .claude/agents/release.md: adds a Step 0 pre-flight assertion that master's manifest.json.version equals the latest non-prerelease GitHub Release tag. Catches drift loudly before doing any work. Notes the manifest-beta.json auto-removal in the rules. - .claude/agents/prerelease.md: documents the manifest.json / manifest-beta.json split. Adds the same Step 0 drift assertion. Updates the git add step to stage manifest-beta.json instead of manifest.json. Adds an explicit guard rule that manifest.json must not change during a prerelease bump. Verified locally by exercising version-bump.mjs in a throwaway repo: - Stable 3.2.8 -> 3.2.9: writes manifest.json + versions.json, no beta side - Prerelease 3.2.8 -> 3.2.9-beta.0: creates manifest-beta.json, manifest.json untouched - Prerelease iteration 3.2.9-beta.0 -> 3.2.9-beta.1: updates manifest-beta.json, manifest.json untouched - Stable supersedes beta 3.2.9-beta.1 -> 3.2.9: writes manifest.json, git-rm's manifest-beta.json Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): address Codex review on PR #2429 1. release.yml: when verifying a prerelease, also assert that the committed manifest.json on the merge commit still equals the latest non-prerelease GitHub Release tag. This catches an old-style version bump or hand edit that accidentally modified master's manifest.json — without this guard, the verify step only inspected manifest-beta.json so a poisoned manifest.json could merge unnoticed and break the Obsidian plugin store. 2. version-bump.mjs: don't fail stable bumps when manifest-beta.json exists on disk but is untracked (or has local modifications). Check git trackedness first; use `git rm -f` only when tracked, fall back to a plain unlink for working-tree-only files. Logs which path it took. Verified both scenarios in a throwaway repo: - Untracked manifest-beta.json + stable bump: unlinked, no git rm error - Tracked manifest-beta.json + stable bump: staged deletion via git rm -f Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): use /releases/latest API for stable-drift guard gh release list defaults to 30 results, so a cluster of 30+ prereleases since the last stable would make the prerelease drift guard return empty and fail valid prerelease publishes. Switch to GitHub's /releases/latest endpoint instead, which by design returns only the most-recent non-prerelease, non-draft release in a single call regardless of how many prereleases have accumulated. Applied the same fix to the Step 0 drift check in both the release agent and prerelease agent doc for consistency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:53:48 +00:00
const isPrerelease = targetVersion.includes("-");
2023-03-31 00:15:32 +00:00
chore(release): make prerelease tooling stop poisoning master's manifest.json (#2429) * chore(release): make prerelease tooling stop poisoning master's manifest.json Background: Obsidian's community plugin store reads manifest.json from master to decide which GitHub Release to serve installers. The prerelease agent's npm version bump was rewriting manifest.json with a prerelease version, which broke plugin installs until hotfix #2428 reverted master's manifest.json to the stable version. This PR fixes the underlying tooling so it can't recur. Changes: - version-bump.mjs now branches on whether npm_package_version is a prerelease (contains a hyphen). Stable: writes to manifest.json + versions.json. Prerelease: writes to manifest-beta.json + versions.json, leaving manifest.json untouched. Seeds manifest-beta.json from manifest.json when it doesn't exist yet. On a stable bump that finds a stale manifest-beta.json, removes it (git rm) because the new stable supersedes the in-flight beta. Stages the right files itself; package.json no longer needs the explicit git-add step. - package.json: simplifies the "version" lifecycle script to just "node version-bump.mjs" since the script now stages files itself. - release.yml: * "Verify version matches manifest" step now selects the file based on is_prerelease (manifest.json for stable, manifest-beta.json for prerelease). For stable runs nothing changes. * Adds a "Prepare release-asset manifest" step before the release upload that copies manifest-beta.json over manifest.json IN THE RUNNER only when the release is a prerelease. This makes the uploaded manifest.json asset carry the prerelease version so testers sideloading the assets get a consistent manifest. The committed master manifest.json is never touched by the workflow (the workflow doesn't push back). - .claude/agents/release.md: adds a Step 0 pre-flight assertion that master's manifest.json.version equals the latest non-prerelease GitHub Release tag. Catches drift loudly before doing any work. Notes the manifest-beta.json auto-removal in the rules. - .claude/agents/prerelease.md: documents the manifest.json / manifest-beta.json split. Adds the same Step 0 drift assertion. Updates the git add step to stage manifest-beta.json instead of manifest.json. Adds an explicit guard rule that manifest.json must not change during a prerelease bump. Verified locally by exercising version-bump.mjs in a throwaway repo: - Stable 3.2.8 -> 3.2.9: writes manifest.json + versions.json, no beta side - Prerelease 3.2.8 -> 3.2.9-beta.0: creates manifest-beta.json, manifest.json untouched - Prerelease iteration 3.2.9-beta.0 -> 3.2.9-beta.1: updates manifest-beta.json, manifest.json untouched - Stable supersedes beta 3.2.9-beta.1 -> 3.2.9: writes manifest.json, git-rm's manifest-beta.json Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): address Codex review on PR #2429 1. release.yml: when verifying a prerelease, also assert that the committed manifest.json on the merge commit still equals the latest non-prerelease GitHub Release tag. This catches an old-style version bump or hand edit that accidentally modified master's manifest.json — without this guard, the verify step only inspected manifest-beta.json so a poisoned manifest.json could merge unnoticed and break the Obsidian plugin store. 2. version-bump.mjs: don't fail stable bumps when manifest-beta.json exists on disk but is untracked (or has local modifications). Check git trackedness first; use `git rm -f` only when tracked, fall back to a plain unlink for working-tree-only files. Logs which path it took. Verified both scenarios in a throwaway repo: - Untracked manifest-beta.json + stable bump: unlinked, no git rm error - Tracked manifest-beta.json + stable bump: staged deletion via git rm -f Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): use /releases/latest API for stable-drift guard gh release list defaults to 30 results, so a cluster of 30+ prereleases since the last stable would make the prerelease drift guard return empty and fail valid prerelease publishes. Switch to GitHub's /releases/latest endpoint instead, which by design returns only the most-recent non-prerelease, non-draft release in a single call regardless of how many prereleases have accumulated. Applied the same fix to the Step 0 drift check in both the release agent and prerelease agent doc for consistency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:53:48 +00:00
// Obsidian's community plugin store reads manifest.json on master to decide
// which GitHub Release to serve. It MUST stay at the latest stable version.
// Prereleases live in manifest-beta.json instead. See:
// https://github.com/obsidianmd/obsidian-releases#submit-your-plugin
const manifestPath = isPrerelease ? "manifest-beta.json" : "manifest.json";
// When cutting the first prerelease of a line, manifest-beta.json may not
// exist yet. Seed it from manifest.json so it inherits the stable manifest's
// fields (description, fundingUrl, etc.) and minAppVersion.
const sourceManifestPath =
isPrerelease && !existsSync(manifestPath) ? "manifest.json" : manifestPath;
const manifest = JSON.parse(readFileSync(sourceManifestPath, "utf8"));
2023-03-31 00:15:32 +00:00
const { minAppVersion } = manifest;
manifest.version = targetVersion;
chore(release): make prerelease tooling stop poisoning master's manifest.json (#2429) * chore(release): make prerelease tooling stop poisoning master's manifest.json Background: Obsidian's community plugin store reads manifest.json from master to decide which GitHub Release to serve installers. The prerelease agent's npm version bump was rewriting manifest.json with a prerelease version, which broke plugin installs until hotfix #2428 reverted master's manifest.json to the stable version. This PR fixes the underlying tooling so it can't recur. Changes: - version-bump.mjs now branches on whether npm_package_version is a prerelease (contains a hyphen). Stable: writes to manifest.json + versions.json. Prerelease: writes to manifest-beta.json + versions.json, leaving manifest.json untouched. Seeds manifest-beta.json from manifest.json when it doesn't exist yet. On a stable bump that finds a stale manifest-beta.json, removes it (git rm) because the new stable supersedes the in-flight beta. Stages the right files itself; package.json no longer needs the explicit git-add step. - package.json: simplifies the "version" lifecycle script to just "node version-bump.mjs" since the script now stages files itself. - release.yml: * "Verify version matches manifest" step now selects the file based on is_prerelease (manifest.json for stable, manifest-beta.json for prerelease). For stable runs nothing changes. * Adds a "Prepare release-asset manifest" step before the release upload that copies manifest-beta.json over manifest.json IN THE RUNNER only when the release is a prerelease. This makes the uploaded manifest.json asset carry the prerelease version so testers sideloading the assets get a consistent manifest. The committed master manifest.json is never touched by the workflow (the workflow doesn't push back). - .claude/agents/release.md: adds a Step 0 pre-flight assertion that master's manifest.json.version equals the latest non-prerelease GitHub Release tag. Catches drift loudly before doing any work. Notes the manifest-beta.json auto-removal in the rules. - .claude/agents/prerelease.md: documents the manifest.json / manifest-beta.json split. Adds the same Step 0 drift assertion. Updates the git add step to stage manifest-beta.json instead of manifest.json. Adds an explicit guard rule that manifest.json must not change during a prerelease bump. Verified locally by exercising version-bump.mjs in a throwaway repo: - Stable 3.2.8 -> 3.2.9: writes manifest.json + versions.json, no beta side - Prerelease 3.2.8 -> 3.2.9-beta.0: creates manifest-beta.json, manifest.json untouched - Prerelease iteration 3.2.9-beta.0 -> 3.2.9-beta.1: updates manifest-beta.json, manifest.json untouched - Stable supersedes beta 3.2.9-beta.1 -> 3.2.9: writes manifest.json, git-rm's manifest-beta.json Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): address Codex review on PR #2429 1. release.yml: when verifying a prerelease, also assert that the committed manifest.json on the merge commit still equals the latest non-prerelease GitHub Release tag. This catches an old-style version bump or hand edit that accidentally modified master's manifest.json — without this guard, the verify step only inspected manifest-beta.json so a poisoned manifest.json could merge unnoticed and break the Obsidian plugin store. 2. version-bump.mjs: don't fail stable bumps when manifest-beta.json exists on disk but is untracked (or has local modifications). Check git trackedness first; use `git rm -f` only when tracked, fall back to a plain unlink for working-tree-only files. Logs which path it took. Verified both scenarios in a throwaway repo: - Untracked manifest-beta.json + stable bump: unlinked, no git rm error - Tracked manifest-beta.json + stable bump: staged deletion via git rm -f Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): use /releases/latest API for stable-drift guard gh release list defaults to 30 results, so a cluster of 30+ prereleases since the last stable would make the prerelease drift guard return empty and fail valid prerelease publishes. Switch to GitHub's /releases/latest endpoint instead, which by design returns only the most-recent non-prerelease, non-draft release in a single call regardless of how many prereleases have accumulated. Applied the same fix to the Step 0 drift check in both the release agent and prerelease agent doc for consistency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:53:48 +00:00
writeFileSync(manifestPath, JSON.stringify(manifest, null, "\t") + "\n");
2023-03-31 00:15:32 +00:00
chore(release): make prerelease tooling stop poisoning master's manifest.json (#2429) * chore(release): make prerelease tooling stop poisoning master's manifest.json Background: Obsidian's community plugin store reads manifest.json from master to decide which GitHub Release to serve installers. The prerelease agent's npm version bump was rewriting manifest.json with a prerelease version, which broke plugin installs until hotfix #2428 reverted master's manifest.json to the stable version. This PR fixes the underlying tooling so it can't recur. Changes: - version-bump.mjs now branches on whether npm_package_version is a prerelease (contains a hyphen). Stable: writes to manifest.json + versions.json. Prerelease: writes to manifest-beta.json + versions.json, leaving manifest.json untouched. Seeds manifest-beta.json from manifest.json when it doesn't exist yet. On a stable bump that finds a stale manifest-beta.json, removes it (git rm) because the new stable supersedes the in-flight beta. Stages the right files itself; package.json no longer needs the explicit git-add step. - package.json: simplifies the "version" lifecycle script to just "node version-bump.mjs" since the script now stages files itself. - release.yml: * "Verify version matches manifest" step now selects the file based on is_prerelease (manifest.json for stable, manifest-beta.json for prerelease). For stable runs nothing changes. * Adds a "Prepare release-asset manifest" step before the release upload that copies manifest-beta.json over manifest.json IN THE RUNNER only when the release is a prerelease. This makes the uploaded manifest.json asset carry the prerelease version so testers sideloading the assets get a consistent manifest. The committed master manifest.json is never touched by the workflow (the workflow doesn't push back). - .claude/agents/release.md: adds a Step 0 pre-flight assertion that master's manifest.json.version equals the latest non-prerelease GitHub Release tag. Catches drift loudly before doing any work. Notes the manifest-beta.json auto-removal in the rules. - .claude/agents/prerelease.md: documents the manifest.json / manifest-beta.json split. Adds the same Step 0 drift assertion. Updates the git add step to stage manifest-beta.json instead of manifest.json. Adds an explicit guard rule that manifest.json must not change during a prerelease bump. Verified locally by exercising version-bump.mjs in a throwaway repo: - Stable 3.2.8 -> 3.2.9: writes manifest.json + versions.json, no beta side - Prerelease 3.2.8 -> 3.2.9-beta.0: creates manifest-beta.json, manifest.json untouched - Prerelease iteration 3.2.9-beta.0 -> 3.2.9-beta.1: updates manifest-beta.json, manifest.json untouched - Stable supersedes beta 3.2.9-beta.1 -> 3.2.9: writes manifest.json, git-rm's manifest-beta.json Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): address Codex review on PR #2429 1. release.yml: when verifying a prerelease, also assert that the committed manifest.json on the merge commit still equals the latest non-prerelease GitHub Release tag. This catches an old-style version bump or hand edit that accidentally modified master's manifest.json — without this guard, the verify step only inspected manifest-beta.json so a poisoned manifest.json could merge unnoticed and break the Obsidian plugin store. 2. version-bump.mjs: don't fail stable bumps when manifest-beta.json exists on disk but is untracked (or has local modifications). Check git trackedness first; use `git rm -f` only when tracked, fall back to a plain unlink for working-tree-only files. Logs which path it took. Verified both scenarios in a throwaway repo: - Untracked manifest-beta.json + stable bump: unlinked, no git rm error - Tracked manifest-beta.json + stable bump: staged deletion via git rm -f Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): use /releases/latest API for stable-drift guard gh release list defaults to 30 results, so a cluster of 30+ prereleases since the last stable would make the prerelease drift guard return empty and fail valid prerelease publishes. Switch to GitHub's /releases/latest endpoint instead, which by design returns only the most-recent non-prerelease, non-draft release in a single call regardless of how many prereleases have accumulated. Applied the same fix to the Step 0 drift check in both the release agent and prerelease agent doc for consistency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:53:48 +00:00
// versions.json records every version's minimum Obsidian app version so
// Obsidian's installer can pick the right plugin version for the user's
// Obsidian build. Both stable and prerelease entries belong here.
const versions = JSON.parse(readFileSync("versions.json", "utf8"));
2023-03-31 00:15:32 +00:00
versions[targetVersion] = minAppVersion;
chore(release): make prerelease tooling stop poisoning master's manifest.json (#2429) * chore(release): make prerelease tooling stop poisoning master's manifest.json Background: Obsidian's community plugin store reads manifest.json from master to decide which GitHub Release to serve installers. The prerelease agent's npm version bump was rewriting manifest.json with a prerelease version, which broke plugin installs until hotfix #2428 reverted master's manifest.json to the stable version. This PR fixes the underlying tooling so it can't recur. Changes: - version-bump.mjs now branches on whether npm_package_version is a prerelease (contains a hyphen). Stable: writes to manifest.json + versions.json. Prerelease: writes to manifest-beta.json + versions.json, leaving manifest.json untouched. Seeds manifest-beta.json from manifest.json when it doesn't exist yet. On a stable bump that finds a stale manifest-beta.json, removes it (git rm) because the new stable supersedes the in-flight beta. Stages the right files itself; package.json no longer needs the explicit git-add step. - package.json: simplifies the "version" lifecycle script to just "node version-bump.mjs" since the script now stages files itself. - release.yml: * "Verify version matches manifest" step now selects the file based on is_prerelease (manifest.json for stable, manifest-beta.json for prerelease). For stable runs nothing changes. * Adds a "Prepare release-asset manifest" step before the release upload that copies manifest-beta.json over manifest.json IN THE RUNNER only when the release is a prerelease. This makes the uploaded manifest.json asset carry the prerelease version so testers sideloading the assets get a consistent manifest. The committed master manifest.json is never touched by the workflow (the workflow doesn't push back). - .claude/agents/release.md: adds a Step 0 pre-flight assertion that master's manifest.json.version equals the latest non-prerelease GitHub Release tag. Catches drift loudly before doing any work. Notes the manifest-beta.json auto-removal in the rules. - .claude/agents/prerelease.md: documents the manifest.json / manifest-beta.json split. Adds the same Step 0 drift assertion. Updates the git add step to stage manifest-beta.json instead of manifest.json. Adds an explicit guard rule that manifest.json must not change during a prerelease bump. Verified locally by exercising version-bump.mjs in a throwaway repo: - Stable 3.2.8 -> 3.2.9: writes manifest.json + versions.json, no beta side - Prerelease 3.2.8 -> 3.2.9-beta.0: creates manifest-beta.json, manifest.json untouched - Prerelease iteration 3.2.9-beta.0 -> 3.2.9-beta.1: updates manifest-beta.json, manifest.json untouched - Stable supersedes beta 3.2.9-beta.1 -> 3.2.9: writes manifest.json, git-rm's manifest-beta.json Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): address Codex review on PR #2429 1. release.yml: when verifying a prerelease, also assert that the committed manifest.json on the merge commit still equals the latest non-prerelease GitHub Release tag. This catches an old-style version bump or hand edit that accidentally modified master's manifest.json — without this guard, the verify step only inspected manifest-beta.json so a poisoned manifest.json could merge unnoticed and break the Obsidian plugin store. 2. version-bump.mjs: don't fail stable bumps when manifest-beta.json exists on disk but is untracked (or has local modifications). Check git trackedness first; use `git rm -f` only when tracked, fall back to a plain unlink for working-tree-only files. Logs which path it took. Verified both scenarios in a throwaway repo: - Untracked manifest-beta.json + stable bump: unlinked, no git rm error - Tracked manifest-beta.json + stable bump: staged deletion via git rm -f Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(release): use /releases/latest API for stable-drift guard gh release list defaults to 30 results, so a cluster of 30+ prereleases since the last stable would make the prerelease drift guard return empty and fail valid prerelease publishes. Switch to GitHub's /releases/latest endpoint instead, which by design returns only the most-recent non-prerelease, non-draft release in a single call regardless of how many prereleases have accumulated. Applied the same fix to the Step 0 drift check in both the release agent and prerelease agent doc for consistency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 22:53:48 +00:00
writeFileSync("versions.json", JSON.stringify(versions, null, "\t") + "\n");
// Stage the files we modified. npm version's auto-commit (or the agent's
// later explicit commit) picks them up.
execSync(`git add ${manifestPath} versions.json`);
// When a stable release ships, an existing manifest-beta.json is now
// historical. Remove it so BRAT and similar tools don't keep surfacing the
// older prerelease entry alongside the new stable.
//
// `git rm` fails on untracked files or files with local modifications, so
// check trackedness first and fall back to a plain unlink when the file is
// only in the working tree. This keeps stable bumps robust against a partial
// or in-progress prerelease state on the local machine.
if (!isPrerelease && existsSync("manifest-beta.json")) {
let isTracked = false;
try {
execSync("git ls-files --error-unmatch manifest-beta.json", { stdio: "ignore" });
isTracked = true;
} catch {
isTracked = false;
}
if (isTracked) {
execSync("git rm -f manifest-beta.json");
} else {
unlinkSync("manifest-beta.json");
}
console.log(
`Removed manifest-beta.json (${isTracked ? "tracked, staged deletion" : "untracked, removed from working tree"}).`
);
}
console.log(`version-bump: wrote ${targetVersion} to ${manifestPath} and versions.json.`);