From 0b953ee8d070142fb10b8fd4a52079fc270db06e Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Sun, 30 Aug 2026 23:17:01 +0800 Subject: [PATCH 1/3] fix(release): sync client manifest versions --- .github/workflows/release-policy.yml | 24 ++++++++++++++++-------- RELEASING.md | 8 +++++--- scripts/open-release-pr.ps1 | 10 ++++++---- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/.github/workflows/release-policy.yml b/.github/workflows/release-policy.yml index 1bbad934..72c312bb 100644 --- a/.github/workflows/release-policy.yml +++ b/.github/workflows/release-policy.yml @@ -6,7 +6,7 @@ name: Release policy # Job matrix: # pr-target-policy PR → main | head_ref must be staging, release/*, or hotfix/* # version-sync PR → staging | NO version field changed (skipped for backmerge/*) -# version-bump PR → main | all 5 version fields bumped, in sync, valid semver, strictly greater +# version-bump PR → main | all 7 version fields bumped, in sync, valid semver, strictly greater # changelog-entry PR → main | top-most CHANGELOG section matches new version, has bullets # staging-up-to-date PR → staging | PR head contains every commit on main # (passes naturally for backmerge/* PRs) @@ -86,6 +86,8 @@ jobs: HEAD_VERSIONS=( "$(jq -r '.version' plugins/winui/agent-plugin/plugin.json)" + "$(jq -r '.version' plugins/winui/.claude-plugin/plugin.json)" + "$(jq -r '.version' plugins/winui/.codex-plugin/plugin.json)" "$(jq -r '.metadata.version' .github/plugin/marketplace.json)" "$(jq -r '.plugins[0].version' .github/plugin/marketplace.json)" "$(jq -r '.version' .claude-plugin/marketplace.json)" @@ -93,6 +95,8 @@ jobs: ) BASE_VERSIONS=( "$(read_base_plugin_version)" + "$(git show "$BASE_SHA":plugins/winui/.claude-plugin/plugin.json | jq -r '.version')" + "$(git show "$BASE_SHA":plugins/winui/.codex-plugin/plugin.json | jq -r '.version')" "$(git show "$BASE_SHA":.github/plugin/marketplace.json | jq -r '.metadata.version')" "$(git show "$BASE_SHA":.github/plugin/marketplace.json | jq -r '.plugins[0].version')" "$(git show "$BASE_SHA":.claude-plugin/marketplace.json | jq -r '.version')" @@ -100,6 +104,8 @@ jobs: ) LABELS=( "portable plugin" + "Claude client plugin" + "Codex client plugin" "GitHub marketplace metadata" "GitHub marketplace plugin" "Claude marketplace" @@ -158,7 +164,7 @@ jobs: echo "::notice::PR head contains every commit on 'main' — OK." version-bump: - name: Version bump (5 fields in sync) + name: Version bump (7 fields in sync) if: github.event.pull_request.base.ref == 'main' runs-on: ubuntu-latest steps: @@ -178,6 +184,8 @@ jobs: # Extract every version field from PR head and from main. # PR-head versions: PR_PLUGIN=$(jq -r '.version' plugins/winui/agent-plugin/plugin.json) + PR_CLAUDE_CLIENT=$(jq -r '.version' plugins/winui/.claude-plugin/plugin.json) + PR_CODEX_CLIENT=$(jq -r '.version' plugins/winui/.codex-plugin/plugin.json) PR_GH_META=$(jq -r '.metadata.version' .github/plugin/marketplace.json) PR_GH_PLUGIN=$(jq -r '.plugins[0].version' .github/plugin/marketplace.json) PR_CLAUDE_TOP=$(jq -r '.version' .claude-plugin/marketplace.json) @@ -206,15 +214,15 @@ jobs: fi done - echo "PR head: plugin=$PR_PLUGIN gh.meta=$PR_GH_META gh.plugin=$PR_GH_PLUGIN claude.top=$PR_CLAUDE_TOP claude.plugin=$PR_CLAUDE_PLUGIN" + echo "PR head: plugin=$PR_PLUGIN claude.client=$PR_CLAUDE_CLIENT codex.client=$PR_CODEX_CLIENT gh.meta=$PR_GH_META gh.plugin=$PR_GH_PLUGIN claude.top=$PR_CLAUDE_TOP claude.plugin=$PR_CLAUDE_PLUGIN" echo "main: plugin=$MAIN_PLUGIN gh.meta=$MAIN_GH_META gh.plugin=$MAIN_GH_PLUGIN claude.top=$MAIN_CLAUDE_TOP claude.plugin=$MAIN_CLAUDE_PLUGIN" - # Rule 1: all 5 PR-head versions identical. - ALL=("$PR_PLUGIN" "$PR_GH_META" "$PR_GH_PLUGIN" "$PR_CLAUDE_TOP" "$PR_CLAUDE_PLUGIN") + # Rule 1: all 7 PR-head versions identical. + ALL=("$PR_PLUGIN" "$PR_CLAUDE_CLIENT" "$PR_CODEX_CLIENT" "$PR_GH_META" "$PR_GH_PLUGIN" "$PR_CLAUDE_TOP" "$PR_CLAUDE_PLUGIN") for v in "${ALL[@]}"; do if [[ "$v" != "$PR_PLUGIN" ]]; then - echo "::error::Version fields are out of sync. All 5 fields must match. Got: ${ALL[*]}" - echo "::error::Files to fix: plugins/winui/agent-plugin/plugin.json, .github/plugin/marketplace.json, .claude-plugin/marketplace.json" + echo "::error::Version fields are out of sync. All 7 fields must match. Got: ${ALL[*]}" + echo "::error::Files to fix: plugins/winui/{agent-plugin,.claude-plugin,.codex-plugin}/plugin.json, .github/plugin/marketplace.json, .claude-plugin/marketplace.json" exit 1 fi done @@ -242,7 +250,7 @@ jobs: fi echo "VERSION=$PR_PLUGIN" >> "$GITHUB_ENV" - echo "::notice::Version bump $MAIN_PLUGIN → $PR_PLUGIN, all 5 fields in sync." + echo "::notice::Version bump $MAIN_PLUGIN → $PR_PLUGIN, all 7 fields in sync." changelog-entry: name: CHANGELOG entry matches new version diff --git a/RELEASING.md b/RELEASING.md index aa8a525f..5ecbf4c5 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -53,8 +53,10 @@ The script: either client-specific agent copy, removes a skill directory, or changes the plugin manifest schema). 4. Lets you accept or override the suggested version. -5. Writes the bumped version into all five version fields: +5. Writes the bumped version into all seven version fields: - `plugins/winui/agent-plugin/plugin.json` → `version` + - `plugins/winui/.claude-plugin/plugin.json` → `version` + - `plugins/winui/.codex-plugin/plugin.json` → `version` - `.github/plugin/marketplace.json` → `metadata.version` and `plugins[0].version` - `.claude-plugin/marketplace.json` → `version` and `plugins[0].version` 6. Drafts a `## [X.Y.Z] — YYYY-MM-DD` CHANGELOG section by promoting bullets @@ -68,7 +70,7 @@ The script: If the helper doesn't work for some reason: 1. `git checkout -b release/X.Y.Z origin/staging` -2. Edit all five version fields (use `git grep -n '"version"'` to find them). +2. Edit all seven version fields (use `git grep -n '"version"'` to find them). 3. Edit `CHANGELOG.md`: rename `## [Unreleased]` to `## [X.Y.Z] — YYYY-MM-DD` and add a fresh empty `## [Unreleased]` section above it. 4. Commit, push, `gh pr create --base main --head release/X.Y.Z`. @@ -143,7 +145,7 @@ skips that prefix so the version-bump diff doesn't trip the gate. If a release on `main` is broken: 1. `git revert -m 1 ` on a new branch from `main`. -2. Bump the patch version (`0.X.Y → 0.X.Y+1`) in all five fields. +2. Bump the patch version (`0.X.Y → 0.X.Y+1`) in all seven fields. 3. Add a CHANGELOG entry under the new version explaining what was reverted and why. 4. PR against `main` directly — this is treated like a hotfix. diff --git a/scripts/open-release-pr.ps1 b/scripts/open-release-pr.ps1 index 8db024ce..dea516c3 100644 --- a/scripts/open-release-pr.ps1 +++ b/scripts/open-release-pr.ps1 @@ -11,7 +11,7 @@ 2. Lists the commits going into the release. 3. Suggests a semver bump (patch by default; minor on heuristic triggers). 4. Lets you accept or override the version. - 5. Writes the version into all 5 manifest fields. + 5. Writes the version into all 7 manifest fields. 6. Promotes [Unreleased] CHANGELOG bullets into a new dated section. 7. Pushes a release/X.Y.Z branch and opens the PR via gh. @@ -71,7 +71,7 @@ if ([int]$behind -gt 0) { # ---- 2. Enumerate commits going into the release ------------------------- $commits = git log --pretty=format:'%H%x09%s' "origin/main..origin/staging" -$commitLines = $commits -split "`n" | Where-Object { $_ } +$commitLines = @($commits -split "`n" | Where-Object { $_ }) Info "`nCommits in this release ($($commitLines.Count)):" $commitLines | ForEach-Object { $parts = $_ -split "`t", 2 @@ -169,7 +169,7 @@ $branch = "release/$Version" Info "`nCreating local branch $branch from origin/staging..." git checkout -B $branch origin/staging | Out-Null -# ---- 5. Bump 5 version fields -------------------------------------------- +# ---- 5. Bump 7 version fields -------------------------------------------- function Set-JsonField([string]$file, [string[]]$path, [string]$value) { $json = Get-Content $file -Raw | ConvertFrom-Json @@ -183,8 +183,10 @@ function Set-JsonField([string]$file, [string[]]$path, [string]$value) { ($json | ConvertTo-Json -Depth 32) | Set-Content $file -Encoding UTF8 } -Info "Writing version into 5 fields..." +Info "Writing version into 7 fields..." Set-JsonField 'plugins/winui/agent-plugin/plugin.json' @('version') $Version +Set-JsonField 'plugins/winui/.claude-plugin/plugin.json' @('version') $Version +Set-JsonField 'plugins/winui/.codex-plugin/plugin.json' @('version') $Version Set-JsonField '.github/plugin/marketplace.json' @('metadata','version') $Version Set-JsonField '.github/plugin/marketplace.json' @('plugins','[0]','version') $Version Set-JsonField '.claude-plugin/marketplace.json' @('version') $Version From 4be712f605dfed64a7fbebfd83e47a61887c41ae Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Thu, 3 Sep 2026 11:02:16 +0800 Subject: [PATCH 2/3] fix(release): include client manifests in release checks --- .github/workflows/release-policy.yml | 10 ++++++---- scripts/open-release-pr.ps1 | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-policy.yml b/.github/workflows/release-policy.yml index 72c312bb..8bcc3328 100644 --- a/.github/workflows/release-policy.yml +++ b/.github/workflows/release-policy.yml @@ -191,7 +191,7 @@ jobs: PR_CLAUDE_TOP=$(jq -r '.version' .claude-plugin/marketplace.json) PR_CLAUDE_PLUGIN=$(jq -r '.plugins[0].version' .claude-plugin/marketplace.json) - # main-side versions: read all 5 and require they're already in sync + # main-side versions: read all 7 and require they're already in sync # (defends against a previously-bad release leaving main inconsistent). if git cat-file -e "$BASE_SHA:plugins/winui/agent-plugin/plugin.json" 2>/dev/null; then MAIN_PLUGIN=$(git show "$BASE_SHA":plugins/winui/agent-plugin/plugin.json | jq -r '.version') @@ -200,22 +200,24 @@ jobs: # the portable manifest at its former path on main. MAIN_PLUGIN=$(git show "$BASE_SHA":plugins/winui/plugin.json | jq -r '.version') fi + MAIN_CLAUDE_CLIENT=$(git show "$BASE_SHA":plugins/winui/.claude-plugin/plugin.json | jq -r '.version') + MAIN_CODEX_CLIENT=$(git show "$BASE_SHA":plugins/winui/.codex-plugin/plugin.json | jq -r '.version') MAIN_GH_META=$(git show "$BASE_SHA":.github/plugin/marketplace.json | jq -r '.metadata.version') MAIN_GH_PLUGIN=$(git show "$BASE_SHA":.github/plugin/marketplace.json | jq -r '.plugins[0].version') MAIN_CLAUDE_TOP=$(git show "$BASE_SHA":.claude-plugin/marketplace.json | jq -r '.version') MAIN_CLAUDE_PLUGIN=$(git show "$BASE_SHA":.claude-plugin/marketplace.json | jq -r '.plugins[0].version') - MAIN_ALL=("$MAIN_PLUGIN" "$MAIN_GH_META" "$MAIN_GH_PLUGIN" "$MAIN_CLAUDE_TOP" "$MAIN_CLAUDE_PLUGIN") + MAIN_ALL=("$MAIN_PLUGIN" "$MAIN_CLAUDE_CLIENT" "$MAIN_CODEX_CLIENT" "$MAIN_GH_META" "$MAIN_GH_PLUGIN" "$MAIN_CLAUDE_TOP" "$MAIN_CLAUDE_PLUGIN") for v in "${MAIN_ALL[@]}"; do if [[ "$v" != "$MAIN_PLUGIN" ]]; then echo "::error::main-side version fields are out of sync: ${MAIN_ALL[*]}" - echo "::error::A previous release left main in an inconsistent state. Fix all 5 fields in this PR before continuing." + echo "::error::A previous release left main in an inconsistent state. Fix all 7 fields in this PR before continuing." break fi done echo "PR head: plugin=$PR_PLUGIN claude.client=$PR_CLAUDE_CLIENT codex.client=$PR_CODEX_CLIENT gh.meta=$PR_GH_META gh.plugin=$PR_GH_PLUGIN claude.top=$PR_CLAUDE_TOP claude.plugin=$PR_CLAUDE_PLUGIN" - echo "main: plugin=$MAIN_PLUGIN gh.meta=$MAIN_GH_META gh.plugin=$MAIN_GH_PLUGIN claude.top=$MAIN_CLAUDE_TOP claude.plugin=$MAIN_CLAUDE_PLUGIN" + echo "main: plugin=$MAIN_PLUGIN claude.client=$MAIN_CLAUDE_CLIENT codex.client=$MAIN_CODEX_CLIENT gh.meta=$MAIN_GH_META gh.plugin=$MAIN_GH_PLUGIN claude.top=$MAIN_CLAUDE_TOP claude.plugin=$MAIN_CLAUDE_PLUGIN" # Rule 1: all 7 PR-head versions identical. ALL=("$PR_PLUGIN" "$PR_CLAUDE_CLIENT" "$PR_CODEX_CLIENT" "$PR_GH_META" "$PR_GH_PLUGIN" "$PR_CLAUDE_TOP" "$PR_CLAUDE_PLUGIN") diff --git a/scripts/open-release-pr.ps1 b/scripts/open-release-pr.ps1 index dea516c3..d395898a 100644 --- a/scripts/open-release-pr.ps1 +++ b/scripts/open-release-pr.ps1 @@ -248,6 +248,8 @@ Set-Content CHANGELOG.md -Value $newCl -Encoding UTF8 # ---- 7. Commit, push, open PR -------------------------------------------- git add plugins/winui/agent-plugin/plugin.json ` + plugins/winui/.claude-plugin/plugin.json ` + plugins/winui/.codex-plugin/plugin.json ` .github/plugin/marketplace.json ` .claude-plugin/marketplace.json ` CHANGELOG.md From 786c1e19ff8b6ee0fda911884ffc7c516415fde9 Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Fri, 4 Sep 2026 11:02:21 +0800 Subject: [PATCH 3/3] fix: fail on inconsistent main versions --- .github/workflows/release-policy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-policy.yml b/.github/workflows/release-policy.yml index 8bcc3328..46aaa8dd 100644 --- a/.github/workflows/release-policy.yml +++ b/.github/workflows/release-policy.yml @@ -212,7 +212,7 @@ jobs: if [[ "$v" != "$MAIN_PLUGIN" ]]; then echo "::error::main-side version fields are out of sync: ${MAIN_ALL[*]}" echo "::error::A previous release left main in an inconsistent state. Fix all 7 fields in this PR before continuing." - break + exit 1 fi done