Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
"url": "https://github.com/microsoft/win-dev-skills"
},
"description": "Agents and skills for native Windows app development with WinUI 3 and the Windows App SDK.",
"version": "0.3.0",
"version": "0.3.1",
"plugins": [
{
"name": "winui",
"description": "Agents and skills for WinUI 3 app development. Create new WinUI 3 desktop apps, convert from other frameworks to WinUI 3, or add features to existing WinUI 3 applications.",
"version": "0.3.0",
"version": "0.3.1",
"source": "./plugins/winui",
"category": "windows-development",
"tags": [
Expand Down
4 changes: 2 additions & 2 deletions .github/plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
},
"metadata": {
"description": "Agents and skills for native Windows app development with WinUI 3 and the Windows App SDK.",
"version": "0.3.0"
"version": "0.3.1"
},
"plugins": [
{
"name": "winui",
"description": "Agents and skills for WinUI 3 app development. Create new WinUI 3 desktop apps, convert from other frameworks to WinUI 3, or add features to existing WinUI 3 applications.",
"version": "0.3.0",
"version": "0.3.1",
"source": "./plugins/winui"
}
]
Expand Down
43 changes: 30 additions & 13 deletions .github/workflows/release-policy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ name: Release policy
# See CONTRIBUTING.md and RELEASING.md for the human-side flow.
#
# Job matrix:
# pr-target-policy PR → main | head_ref must be staging or hotfix/*
# version-sync PR → staging | NO version field changed
# 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
# changelog-entry PR → main | top-most CHANGELOG section matches new version, has bullets
# staging-up-to-date PR → staging | staging contains every commit on main
# staging-up-to-date PR → staging | PR head contains every commit on main
# (passes naturally for backmerge/* PRs)

on:
pull_request:
Expand Down Expand Up @@ -51,7 +52,11 @@ jobs:

version-sync:
name: No version bump in feature PR
if: github.event.pull_request.base.ref == 'staging'
# Skip on backmerge/* PRs: those legitimately carry main's version-bump
# commit forward into staging. See CONTRIBUTING.md § Back-merge path.
if: >
github.event.pull_request.base.ref == 'staging' &&
!startsWith(github.event.pull_request.head.ref, 'backmerge/')
runs-on: ubuntu-latest
steps:
- name: Checkout (full depth)
Expand Down Expand Up @@ -99,21 +104,33 @@ jobs:
with:
fetch-depth: 0

- name: Verify staging contains every commit on main
- name: Verify PR head contains every commit on main
env:
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
shell: bash
run: |
set -euo pipefail
git fetch origin main staging --quiet
# Find commits on main that are not on staging.
MISSING=$(git rev-list --count origin/main ^origin/staging)
git fetch origin main --quiet
# We check the PR head (not origin/staging) so back-merge PRs — which
# bring main into staging — pass naturally: after they merge, staging
# will contain main. Any other PR that doesn't already include main
# will fail here exactly as it would have under the old "staging vs
# main" check.
MISSING=$(git rev-list --count origin/main ^"$HEAD_SHA")
if [[ "$MISSING" -gt 0 ]]; then
echo "::error::'staging' is behind 'main' by $MISSING commit(s)."
echo "::error::This usually means a hotfix landed on main and was not back-merged into staging."
echo "::error::A maintainer must run: git checkout staging && git merge origin/main && git push"
echo "::error::Then this PR can proceed. See CONTRIBUTING.md § Hotfix path."
echo "::error::PR head ('$HEAD_REF') is missing $MISSING commit(s) from 'main'."
echo "::error::This usually means a hotfix landed on main and was not back-merged into staging,"
echo "::error::and this PR was branched from a stale staging."
echo "::error::Fix: open a back-merge PR first."
echo "::error:: git checkout -b backmerge/<topic> origin/staging"
echo "::error:: git merge origin/main"
echo "::error:: git push -u origin backmerge/<topic>"
echo "::error:: gh pr create --base staging --head backmerge/<topic>"
echo "::error::Then rebase this PR on the updated staging. See CONTRIBUTING.md § Back-merge path."
exit 1
fi
echo "::notice::'staging' contains every commit on 'main' — OK."
echo "::notice::PR head contains every commit on 'main' — OK."

version-bump:
name: Version bump (5 fields in sync)
Expand Down
10 changes: 6 additions & 4 deletions .github/workflows/release-post-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,20 +114,22 @@ jobs:
BODY=$(cat <<EOF
Hotfix PR #$PR_NUMBER ('$PR_TITLE') merged into \`main\` at $MERGE_SHA.

Per [CONTRIBUTING.md § Hotfix path](../blob/main/CONTRIBUTING.md#hotfix-path),
Per [CONTRIBUTING.md § Back-merge path](../blob/main/CONTRIBUTING.md#back-merge-path),
this commit must be back-merged into \`staging\` immediately so the fix is
not lost on the next release.

To do this:

\`\`\`
git fetch origin
git checkout staging
git checkout -b backmerge/hotfix-${HEAD_REF#hotfix/} origin/staging
git merge origin/main
git push
git push -u origin backmerge/hotfix-${HEAD_REF#hotfix/}
gh pr create --base staging --head backmerge/hotfix-${HEAD_REF#hotfix/}
\`\`\`

Or open a PR from \`main\` into \`staging\` if you prefer the review trail.
The branch **must** be named \`backmerge/*\` — the \`version-sync\` CI
check skips that prefix.

The \`staging-up-to-date-with-main\` CI check will block all new feature
PRs until this back-merge happens.
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ The `version-bump` and `changelog-entry` CI jobs enforce this.

### Deprecated

## [0.3.1] — 2026-05-19

### Added

- `winui-dev` agent: window sizing rubric, screenshot validation step, and
anti-self-delegation guardrails (#84).
- `winui-search`: batched CLI mode, background cache refresh, BM25-based
ranking, and upgraded WinUI Gallery + Community Toolkit data fetchers (#83).

### Changed

- CI: `pr-validation` workflow now also runs on PRs targeting `staging`.
- Bumped `coverlet.collector` from 10.0.0 to 10.0.1 (#87).

## [0.3.0] — 2026-05-13

Baseline entry covering everything currently shipped on `main` at the time the
Expand Down
47 changes: 42 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ contributor flow. For the maintainer-side release process see

```
your-feature ──PR──▶ staging ──promotion PR──▶ main ──auto-tag──▶ vX.Y.Z
hotfix/* ──PR──▶ main (must back-merge to staging)
hotfix/* ──PR──▶ main ──backmerge/* ──▶ staging
release/X.Y.Z ──PR──▶ main ──backmerge/X.Y.Z ▶ staging
```

- **`main`** is the released branch. Marketplace consumers install from `main`,
Expand All @@ -26,6 +27,12 @@ hotfix/* ──PR──▶ main (must back-merge to staging)
for genuine emergencies (security, broken-on-install). They must include the
version bump + changelog entry themselves and be back-merged to `staging`
immediately after.
- **`release/X.Y.Z`** branches are the staging→main promotion PRs (opened by
`scripts/open-release-pr.ps1`). They carry the version bump + CHANGELOG
promotion for the release.
- **`backmerge/*`** branches are the only ones allowed to bring main's history
into `staging` (without tripping the `version-sync` check). Open one right
after every promotion PR or hotfix merges into `main`.

## Opening a PR

Expand Down Expand Up @@ -86,18 +93,48 @@ release:
4. PR against `main`. CI will run the same `version-bump` + `changelog-entry`
checks the promotion PR runs.
5. Once merged, immediately open a back-merge PR `main → staging` to get the
fix into the integration branch. The `back-merge-reminder` workflow opens a
tracking issue if you forget.
fix into the integration branch:

```powershell
git fetch origin
git checkout -b backmerge/hotfix-short-description origin/staging
git merge origin/main
git push -u origin backmerge/hotfix-short-description
gh pr create --base staging --head backmerge/hotfix-short-description `
--title "Back-merge hotfix into staging" `
--body "Brings #<hotfix PR> back into staging."
```

The branch **must** be named `backmerge/*` — the `version-sync` CI check
skips that prefix so the version-bump diff doesn't trip the gate. The
`back-merge-reminder` workflow opens a tracking issue if you forget.

## Back-merge path

Whenever `main` advances (promotion PR merge, hotfix merge, revert) `staging`
must be caught up before any new feature PR can merge. Open a back-merge:

```powershell
git fetch origin
git checkout -b backmerge/<topic> origin/staging
git merge origin/main
git push -u origin backmerge/<topic>
gh pr create --base staging --head backmerge/<topic>
```

Naming: use `backmerge/X.Y.Z` after a release, `backmerge/hotfix-<short>` after
a hotfix. The `backmerge/` prefix is required — without it the `version-sync`
check will (correctly) refuse to let the version-bump diff land on staging.

## CI checks you'll see

| Check | When it runs | What it wants |
|---|---|---|
| `pr-target-policy` | PR targets `main` | Your branch is `staging`, `release/*`, or `hotfix/*`, AND comes from this repo (not a fork). |
| `version-sync` | PR targets `staging` | You did NOT change any version field. |
| `version-sync` | PR targets `staging` | You did NOT change any version field. (Skipped on `backmerge/*`.) |
| `version-bump` | PR targets `main` | All 5 version fields bumped, valid semver, strictly greater, identical. |
| `changelog-entry` | PR targets `main` | Top-most `## [X.Y.Z]` section matches the bumped version, has at least one bullet. |
| `staging-up-to-date-with-main` | PR targets `staging` | `staging` contains every commit on `main` (so hotfixes aren't lost). |
| `staging-up-to-date-with-main` | PR targets `staging` | PR head contains every commit on `main` (back-merge PRs satisfy this naturally). |
| `build-tools` + provenance | Any PR | C# tools build, analyzer tests pass, committed payloads match source. |
| `validate-plugin-manifest` + `validate-skill-frontmatter` | Any PR | Manifests are well-formed, every `SKILL.md` has valid frontmatter. |

Expand Down
24 changes: 23 additions & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,27 @@ Automatically:
(consumers may need to run `copilot plugin marketplace update
win-dev-skills` to see the new version listed).

## Post-release back-merge (REQUIRED)

After the promotion PR merges and `auto-tag` succeeds, **immediately open a
back-merge PR `main → staging`**. Without it, `staging` is missing the version
bump + the freshly-emptied `[Unreleased]` CHANGELOG section, and
`open-release-pr.ps1` will refuse to cut the next release until staging catches
up.

```powershell
git fetch origin
git checkout -b backmerge/X.Y.Z origin/staging
git merge origin/main
git push -u origin backmerge/X.Y.Z
gh pr create --base staging --head backmerge/X.Y.Z `
--title "Back-merge main into staging after X.Y.Z" `
--body "Brings the Release X.Y.Z commit from main back into staging."
```

The branch **must** start with `backmerge/` — the `version-sync` CI check
skips that prefix so the version-bump diff doesn't trip the gate.

> [!IMPORTANT]
> **Don't announce the new tag externally until `auto-tag` succeeds.**
> Marketplace consumers (`winui@win-dev-skills`) get the new code as soon as
Expand All @@ -126,7 +147,8 @@ If a release on `main` is broken:
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.
5. Back-merge the revert into `staging` after merging.
5. Back-merge the revert into `staging` after merging via a `backmerge/*` PR
(see CONTRIBUTING.md § Back-merge path).

The original tag stays in place (we don't delete tags); the rollback creates a
new tag. Consumers updating past the broken version skip cleanly.
Expand Down
2 changes: 1 addition & 1 deletion plugins/winui/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "winui",
"description": "Agents and skills for WinUI 3 app development. Create new WinUI 3 desktop apps, convert from other frameworks to WinUI 3, or add features to existing WinUI 3 applications.",
"version": "0.3.0",
"version": "0.3.1",
"author": {
"name": "Microsoft",
"url": "https://github.com/microsoft/win-dev-skills"
Expand Down
Loading