name: publish-release description: "Orchestrate XerahS release flow in strict order: run maintenance prep first, update-changelog second (optional only if docs/CHANGELOG.md is intentionally absent), verify build, bump/commit/push/tag while syncing Chocolatey version metadata, monitor GitHub Actions every 2 minutes, ensure standard release notes content, then set pre-release by default (use explicit opt-out for stable). On failures, inspect logs, fix root cause, and retry with the next patch release."
XerahS Release Bump Tag
Overview
Use this skill to run release steps in strict order:
- Step 1: Execute maintenance prep first (
git pull --recurse-submodulesandgit submodule update --init --recursive), then reattachShareX.ImageEditortodevelopand fast-forward it fromorigin/develop - Step 2: Run
.ai/skills/update-changelog/SKILL.mdsecond (optional only ifdocs/CHANGELOG.mdis intentionally absent) - Step 3: Verify build, then execute bump/commit/push/tag automation
- Step 4: Monitor the tag-triggered release workflow every 2 minutes
- Step 5: If failure occurs, inspect logs, fix issues, and retry with the next patch version
- Step 6: Ensure standard release notes block is present on the GitHub release
- Step 7: Set the successful release as pre-release by default (opt out only when intentionally publishing stable)
- Optional Step 8: Generate a Flathub source-build manifest candidate from the successful pre-release tag; do not open or automate a Flathub PR
- The GitHub Actions release upload steps must also set
prerelease: trueandmake_latest: false; do not rely only on the post-workflowgh release edit --prereleaseguard.
Repository target behavior:
- The automation is repository-agnostic. Git pushes use the local
originremote. - GitHub CLI operations (
gh run,gh release) resolve the target from the GitHuboriginremote by default, for exampleShareX/XerahSorKovaForge/XerahS. - Use
--repo owner/nameto override the inferred target when needed.
Step 3 performs:
- Pre-check: Run
dotnet build src/desktop/XerahS.sln; do not proceed if build fails. - Prompts for
x/y/zbump type (major/minor/patch) unless specified. - Updates every tracked
Directory.Build.propsfile that defines<Version>. - Syncs
build/windows/chocolatey/xerahs.nuspec<version>with the release version. - Stages all current repo changes.
- Commits with version-prefixed message.
- Pushes current branch and creates/pushes annotated tag
vX.Y.Z.
Step 4-5 performs:
- Find tag run for
Release Build (All Platforms). - Poll run status every 120 seconds until completion.
- On failure, inspect failing job logs and identify first blocking error.
- Fix root cause in code/workflow/scripts.
- Re-run local pre-check build.
- Retry release using next patch bump, then monitor again.
- Repeat until workflow succeeds.
Step 6 performs:
- Ensures release notes always include:
Change log:https://xerahs.com/changelog.html### macOS Troubleshooting ("App is damaged")section with Gatekeeperxattr -crguidance.
- After the release is published, the tag workflow also builds, smoke-tests, and attaches
xerahs.X.Y.Z.nupkgto the GitHub release. build/windows/chocolatey/Sync-ChocolateyPackage.ps1 -Version X.Y.Zremains the manual recovery path for re-syncing checksums or repacking.- Expected Windows release assets per architecture:
XerahS-X.Y.Z-win-x64.exe,XerahS-X.Y.Z-win-x64.msi,XerahS-X.Y.Z-win-arm64.exe,XerahS-X.Y.Z-win-arm64.msi.
Optional Step 8 performs:
- Runs
.ai/skills/publish-release/scripts/prepare-flathub-source-build.sh --tag vX.Y.Z --repo owner/name --lint. - Generates
dist/flathub/com.xerahs.XerahS.ymlfrom the GitHub release tag plus pinnedShareX.ImageEditorandShareX.VideoEditorsubmodule commits. - Adds the Freedesktop SDK
dotnet10andnode24extensions needed to run the Linux publish script inside the Flatpak build sandbox. - Verifies the generated manifest does not use local
dist/xerahs-flatpak-stagingsources. - Flags missing offline dependency source artifacts for NuGet/.NET and npm. A release is not Flathub-ready until these generated dependency sources are present and a network-disabled Flatpak source build passes.
- Keeps this as a pre-release validation path. Do not mark a release stable for Flathub until the source-build manifest, dependency sources, manifest lint, repo lint, and manual smoke tests pass.
Primary Command
From repository root:
./.ai/skills/publish-release/scripts/run-release-sequence.sh
Automated monitor + default pre-release (recommended):
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --set-prerelease --bump z --yes
Explicit repository target example:
./.ai/skills/publish-release/scripts/run-release-sequence.sh --repo KovaForge/XerahS --assume-changelog-done --monitor --set-prerelease --bump z --yes
Stable release opt-out example:
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --no-prerelease --bump z --yes
Manual monitor (fallback, PowerShell example):
gh run list --limit 10 --json databaseId,workflowName,headBranch,status,conclusion,url
Start-Sleep -Seconds 120
gh run view <run-id> --json status,conclusion,jobs,url
Non-Interactive Examples
Patch bump, no prompts:
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --bump z --yes
Patch bump with built-in 2-minute monitoring:
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --monitor-interval 120 --bump z --yes
Patch bump, pre-release, and generate Flathub source-build candidate:
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --set-prerelease --prepare-flathub-source --bump z --yes
Minor bump with custom commit token/summary:
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --bump y --type CI --summary "Prepare release artifacts" --yes
Preview only:
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --bump z --dry-run --yes
When bash is unavailable (e.g. Windows PowerShell)
On environments where bash is not in PATH, execute the sequence manually:
Step 1 - Maintenance
git pull --recurse-submodulesgit submodule update --init --recursive- Mandatory after submodule update:
git -C ShareX.ImageEditor fetch origin --prune - Mandatory after submodule update:
git -C ShareX.ImageEditor checkout develop - Mandatory after submodule update:
git -C ShareX.ImageEditor pull --ff-only origin develop - Verify
git -C ShareX.ImageEditor status --short --branchshowsdevelop...origin/develop, not detached HEAD. - Abort if
ShareX.ImageEditorhas local changes, cannot fast-forward, or remains detached. If this updates the recorded submodule commit, commit and push the submodule before committing the parent XerahS gitlink.
Step 2 - Changelog
- Run
.ai/skills/update-changelog/SKILL.md. - Skip only if
docs/CHANGELOG.mdis intentionally absent or the user confirms skip.
- Run
Step 3 - Bump, commit, push, tag
- Run
dotnet build src/desktop/XerahS.sln; abort if it fails. - Read current version from root
Directory.Build.props. - Compute next version: patch
Z+1, minorY+1.0, majorX+1.0.0. - Ensure tag
v<new-version>does not exist locally or onorigin. - PowerShell-safe local check (avoid false positives from
if (git rev-parse <tag>)):git show-ref --verify --quiet "refs/tags/v<new-version>"if ($LASTEXITCODE -eq 0) { throw "Local tag exists" }
- PowerShell-safe remote check:
git ls-remote --exit-code --tags origin "refs/tags/v<new-version>" *> $nullif ($LASTEXITCODE -eq 0) { throw "Remote tag exists" }
- For
--no-bump: ifv<current-version>already exists, do not try to recreate it. Use--no-tagfor commit-only flow, or bump patch for a new tag. - Update all tracked
Directory.Build.propsfiles containing<Version>. - Update
build/windows/chocolatey/xerahs.nuspec<version>to match. git add -A->git commit -m "[v<new-version>] [CI] Release v<new-version>"->git push origin <current-branch>->git tag -a v<new-version> -m "v<new-version>"->git push origin v<new-version>.
- Run
Step 4 - Monitor every 2 minutes
- Find run:
gh run list --limit 10 --json databaseId,workflowName,headBranch,status,conclusion,url - Poll:
Start-Sleep -Seconds 120; thengh run view <run-id> --json status,conclusion,jobs,url
- Find run:
Step 5 - On failure, fix and retry
- Fetch failed job logs:
gh run view <run-id> --job <job-id> --log - Fix root cause in repository.
- Re-run
dotnet build src/desktop/XerahS.sln. - Repeat Step 3 with next patch version.
- Fetch failed job logs:
Step 6 - Ensure standard release notes content
- Read current body:
gh release view v<new-version> --json body - Append the standard changelog + macOS troubleshooting block if missing.
- Write body:
gh release edit v<new-version> --notes-file <file> - Verify all 8 Windows assets are attached (
-win-x64.exe,-win-x64.msi,-win-arm64.exe,-win-arm64.msi) plus macOS and Linux assets.
- Read current body:
Step 7 - Set pre-release (default behavior)
gh release edit v<new-version> --prerelease- Verify:
gh release view v<new-version> --json isPrerelease,url,assets - Stable opt-out: skip this step only when intentionally publishing stable.
- Workflow guard:
.github/workflows/release-build-all-platforms.ymlmust create/upload releases withprerelease: trueandmake_latest: falseso the release is never briefly published as latest before this post-run verification step.
Optional Flathub source-build preparation for manual submission
- Keep the GitHub release as a pre-release while this validation is ongoing.
- Run
.ai/skills/publish-release/scripts/prepare-flathub-source-build.sh --tag v<new-version> --repo owner/name --lint. - Confirm the generated manifest uses
type: gitsources pinned by tag/commit for the main repository and submodules. - Generate and add offline dependency sources for NuGet/.NET packages and
ShareX.VideoEditor/frontendnpm packages before attempting a network-disabled Flathub build. - Build and lint the generated manifest locally before a human maintainer manually opens the Flathub PR.
Optional post-release Chocolatey maintenance
- The tag workflow should already have produced and smoke-tested
xerahs.<new-version>.nupkg. - Manual repack/re-sync:
powershell -File build/windows/chocolatey/Sync-ChocolateyPackage.ps1 -Version <new-version> -Pack - Manual smoke test:
powershell -File build/windows/chocolatey/Test-ChocolateyPackage.ps1 -Version <new-version> -SourceDirectory dist\chocolatey - Optionally push after review:
powershell -File build/windows/chocolatey/Sync-ChocolateyPackage.ps1 -Version <new-version> -Pack -Push -ApiKey <key>
- The tag workflow should already have produced and smoke-tested
Default bump when unspecified: patch (z). Default commit type token: CI.
Behavior
- Require completion of
run-maintenancefirst.- Script behavior: executes maintenance commands automatically unless explicitly bypassed with
--skip-maintenance(or legacy alias--assume-maintenance-done).
- Script behavior: executes maintenance commands automatically unless explicitly bypassed with
- Require completion of
update-changelogsecond (skip only ifdocs/CHANGELOG.mdis intentionally absent or user confirms). - Before bump, run
dotnet build src/desktop/XerahS.sln; abort on failure. - Run
scripts/bump-version-commit-tag.sh(or PowerShell/manual equivalent when bash unavailable). - After tag push, monitor the release workflow every 120 seconds until complete.
- If failed, inspect logs, fix root cause, and retry with next patch version.
- Continue retry loop until release workflow is successful.
- Ensure standard release notes content is present on the successful release.
- Mark successful release as pre-release by default; only skip when explicitly publishing stable.
- When preparing for Flathub, generate the source-build manifest candidate and treat missing offline dependency sources as release-blocking for Flathub submission.
Guardrails
- Do not skip sequence unless user explicitly requests bypass.
- Do not skip maintenance unless user explicitly requests bypass (
--skip-maintenance). - Do not commit/push during maintenance/changelog steps.
- After maintenance submodule update, always reattach
ShareX.ImageEditortodevelop, fast-forward it fromorigin/develop, and verify it is not detached before build, bump, tag, or release work continues. - Always verify build before bump/tag.
- Always monitor workflow after tag push; do not stop at tag creation.
- Always inspect logs on failure and fix root cause before retry.
- Always ensure the standard release notes block exists on the successful release.
- Always keep Flathub validation releases as pre-release until source-build, dependency-source, lint, repo-lint, and smoke-test gates pass.
- Always keep the GitHub Actions release creation step aligned with that policy by setting
prerelease: trueandmake_latest: falseinsoftprops/action-gh-release. - Always use a new patch version for retries requiring new commits/tags.
- Abort on detached HEAD.
- Abort if version format is not
X.Y.Z. - Abort if matching tag already exists locally or remotely.
- In PowerShell manual flow, use
git show-ref --verify --quiet "refs/tags/<tag>"andgit ls-remote --exit-code --tagswith$LASTEXITCODEchecks for tag existence. - Support
--no-pushand--no-tagwhen partial flow is needed.
Agent usage (Cursor / Codex)
When executing this skill:
- Run sequence: maintenance -> changelog -> build verify -> bump/commit/push/tag.
- Use bash scripts if bash exists; otherwise use PowerShell/manual flow.
- Default bump is patch (
z) when unspecified. - Monitor tag workflow every 120 seconds until completion.
- On failure, inspect logs, fix issue, and retry with next patch version.
- Ensure release notes include changelog link + macOS troubleshooting block.
- If requested, set the final successful release to pre-release.
- If preparing for Flathub, run the source-build helper and report which of the source/dependency gates passed or failed.
- Report final version, commit hash, branch push status, tag push status, run URL, and pre-release status.
Default pre-release policy: unless explicitly instructed otherwise, keep --set-prerelease enabled. Use --no-prerelease only for intentional stable publishes.
Notes (lessons learnt)
- Windows/PowerShell: bash may be unavailable; manual fallback must be first-class.
- Windows/PowerShell: avoid
if (git rev-parse <tag>)for local tag existence checks; usegit show-ref --verify --quiet refs/tags/<tag>and inspect$LASTEXITCODE. - Build before bump: avoid tagging broken trees.
- Changelog optional: do not block if
docs/CHANGELOG.mdis intentionally absent unless user requires it. - Version sync: update every tracked
Directory.Build.propswith<Version>and syncbuild/windows/chocolatey/xerahs.nuspec. - Windows packaging produces 4 assets per release:
XerahS-X.Y.Z-win-x64.exe,XerahS-X.Y.Z-win-x64.msi,XerahS-X.Y.Z-win-arm64.exe,XerahS-X.Y.Z-win-arm64.msi. The EXE is built by Inno Setup; the MSI is built by WiX Toolset v4 (build/windows/XerahS-setup.wxs). Both are produced bybuild/windows/package-windows.ps1in the same loop iteration. - ShareX.ImageEditor submodule must stay on
develop: aftergit submodule update --init --recursive, immediately rungit -C ShareX.ImageEditor fetch origin --prune,git -C ShareX.ImageEditor checkout develop, andgit -C ShareX.ImageEditor pull --ff-only origin develop.git submodule updatechecks out the parent-recorded commit and can leave a detached HEAD; do not proceed with release work untilgit -C ShareX.ImageEditor status --short --branchconfirmsdevelop...origin/develop. - WiX prerequisite (CI & local): use a pinned pre-v7 WiX CLI, currently
dotnet tool install --global wix --version 6.0.2+wix extension add --global WixToolset.UI.wixext/6.0.2. Therelease-build-all-platforms.ymlworkflow installs WiX automatically in thebuild-windowsjob. For local MSI builds: install WiX first; if not present the script emits a warning and skips MSI. - MSI install layout: per-user, no UAC elevation required. Binaries →
%LocalAppData%\Programs\XerahS\; Plugins →%USERPROFILE%\Documents\XerahS\Plugins\; Start Menu shortcut created automatically. - Winget manifest: both
InstallerType: nullsoft(EXE) andInstallerType: wix(MSI) entries must be included for each architecture when submitting to winget-pkgs. Seebuild/windows/winget/manifests/0.16.0/ShareX.XerahS.yamlas the template. - Chocolatey asset naming:
build/windows/chocolatey/tools/chocolateyInstall.ps1resolvesXerahS-<version>-win-x64.exeorXerahS-<version>-win-arm64.exefromChocolateyPackageVersion, so release bumps should not hardcode installer filenames there. - Chocolatey checksums for community publication are post-release data because GitHub release assets do not exist until after the tag workflow completes. The tag workflow now performs that sync automatically for release packaging, and
build/windows/chocolatey/Sync-ChocolateyPackage.ps1remains the manual fallback. - Flatpak CI setup must fail loudly when the runtime cannot be installed; use
flatpak remote-add --no-gpg-verifyfor unsigned Flathub setup, not--no-sign-verify. - Flatpak manifest source paths are resolved relative to the manifest directory, so staging paths outside
flatpak/need a../prefix. - Flathub submission manifests must not depend on local
dist/xerahs-flatpak-staging; generate a tag-pinned source-build candidate with.ai/skills/publish-release/scripts/prepare-flathub-source-build.sh. - Flathub source-build candidates must include pinned submodule commits; GitHub source archives do not automatically include submodule contents.
- Flathub source-build candidates are not ready until NuGet/.NET and npm dependency sources are generated and a network-disabled Flatpak build passes.
- Flatpak build commands install into
/app, not/usr; expose launchers through/app/bin. - Flatpak build commands run from the module build directory, not the repository root; add icons, desktop files, metainfo, or other repository assets as explicit manifest sources before installing them.
- Flatpak
finish-argsmust use options supported byflatpak build-finish; clipboard read/write flags are not validfinish-args. - Flatpak session bus access is expressed as
--socket=session-busor narrower--talk-name=policies, not--bus=session. - Flatpak CI bundling should export
flatpak-builderoutput to an explicit local repo with--repo=...; validate files directly or use supported Flatpak commands, notflatpak build-info. - Chocolatey release metadata lookup must use the active GitHub repository (
GITHUB_REPOSITORY,origin, or explicit-Repository owner/name), not a hardcoded upstream owner. - Chocolatey install scripts must also generate download URLs from the active release repository; updating only nuspec metadata is not enough.
- Release reliability loop: tag push is not the end; monitor, fix, and retry until green.