XerahS Release Bump Tag
Windows Portable Releases
Windows portable ZIPs are part of every normal tagged release alongside the EXE/MSI installers. For portable-only local packaging, artifact verification, and upgrade guidance, read references/windows-portable.md. A request to build a portable ZIP locally does not require a version bump, tag, or GitHub release; use that reference instead of the publishing sequence below.
Overview
Use this skill to run release steps in strict order:
- Step 1: Execute maintenance prep first (
git pull --recurse-submodules and git submodule update --init --recursive), then reattach ShareX.ImageEditor to develop and fast-forward it from origin/develop. Uncommitted local changes in the working tree are auto-committed with message [skill] Auto-commit uncommitted changes before release maintenance before the pull. Submodule local changes still block the sequence and must be committed/stashed manually.
- Step 2: Run
.ai/skills/update-changelog/SKILL.md second (optional only if docs/CHANGELOG.md is 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 the root cause in code or workflow first (do not skip the fix and retry the same version), commit and push the fix, then retry with the next patch version. If the failure is in the
build-flatpak job, verify all plugin DLLs are present in the staging directory; the workflow now includes a plugin re-validation step but a code fix in package-linux.sh may also be needed. Repeat until workflow succeeds.
- Step 6: Ensure standard release notes block is present on the GitHub release
- Step 7: Apply repo release-channel policy (see below)
- Optional Step 8: Generate a Flathub source-build manifest candidate from the successful release tag; do not open or automate a Flathub PR
- Optional Step 9: Stamp Launchpad PPA / Fedora COPR / openSUSE OBS candidates, or publish them with
--publish-distro-repos (secrets-gated skip per backend; see docs/linux/distro-repos.md)
- GitHub Actions release upload steps must match the same repo policy (
prerelease / make_latest by github.repository); do not rely only on the post-workflow gh release edit guard.
Repository target behavior (dual-repo):
- Supported release targets:
https://github.com/KovaForge/XerahS and https://github.com/ShareX/XerahS.
- Git pushes use
--push-remote (default: origin). For ShareX publishes from a KovaForge fork checkout, use --push-remote upstream --repo ShareX/XerahS.
- GitHub CLI operations (
gh run, gh release) resolve from the origin remote URL by default.
- Origin may be a standard
github.com URL or a KovaForge per-person SSH alias such as git@github-vladislava:KovaForge/XerahS.git.
- Do not rely on bare
gh repo view for target inference on fork checkouts: it often resolves the upstream parent (ShareX/XerahS) instead of origin (KovaForge/XerahS).
- Use
--repo owner/name to override the inferred target when needed.
- After a successful workflow, the skill verifies the required asset set on the chosen repo (Windows installers and portable ZIPs/macOS/Linux/Flatpak + Chocolatey nupkg).
Release channel policy (default):
ShareX/XerahS -> always Pre-release (prerelease: true, not latest)
KovaForge/XerahS -> Release / latest (prerelease: false, make_latest: true)
- Override with
--set-prerelease or --no-prerelease when intentionally forcing the opposite channel.
Step 3 performs:
- Pre-check: Run
dotnet build src/desktop/XerahS.sln; do not proceed if build fails.
- Prompts for
x/y/z bump type (major/minor/patch) unless specified.
- Updates every tracked
Directory.Build.props file 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 Gatekeeper xattr -cr guidance.
- After the release is published, the tag workflow also builds, smoke-tests, and attaches
xerahs.X.Y.Z.nupkg to the GitHub release.
build/windows/chocolatey/Sync-ChocolateyPackage.ps1 -Version X.Y.Z remains the manual recovery path for re-syncing checksums or repacking.
- Expected Windows release assets: six files across x64 and ARM64, with
XerahS-X.Y.Z-win-<arch>.exe, XerahS-X.Y.Z-win-<arch>.msi, and XerahS-X.Y.Z-win-<arch>-portable.zip for each architecture. The ZIP must contain portable.txt next to XerahS.exe; see the portable reference for validation.
- Expected Linux AppImage assets:
XerahS-X.Y.Z-linux-x64.AppImage, XerahS-X.Y.Z-linux-arm64.AppImage (in addition to tar.gz/deb/rpm and the existing Flatpak bundle).
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.yml from the GitHub release tag plus pinned ShareX.ImageEditor and ShareX.VideoEditor submodule commits.
- Adds the Freedesktop SDK
dotnet10 and node24 extensions needed to run the Linux publish script inside the Flatpak build sandbox.
- Verifies the generated manifest does not use local
dist/xerahs-flatpak-staging sources.
- 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.
Optional Step 9 performs:
--prepare-distro-repo-source runs .ai/skills/publish-release/scripts/prepare-distro-repo-assets.sh --tag vX.Y.Z --repo owner/name and stamps dist/distro-repo/ from build/linux/repo-staging/.
--publish-distro-repos runs .ai/skills/publish-release/scripts/publish-distro-repos.sh --tag vX.Y.Z --repo owner/name: stamp, then dput / copr-cli build / osc commit when credentials exist.
- Missing Launchpad GPG, COPR config, or OBS login skips that backend and does not fail the release. A backend with credentials that fails the upload does fail.
- One-time project creation and secret names live in
docs/linux/distro-repos.md.
- Does not invent a second
.deb / .rpm format. GitHub release assets remain the one-off installers; these channels are the apt / dnf / zypper update path from ShareX/XerahS#253.
Primary Command
From repository root:
./.ai/skills/publish-release/scripts/run-release-sequence.sh
Automated monitor with repo-default channel (recommended):
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --bump z --yes
KovaForge fork example (publishes as full Release / latest):
./.ai/skills/publish-release/scripts/run-release-sequence.sh --repo KovaForge/XerahS --git-wrapper git-vladislava --push-remote vladislava --assume-changelog-done --monitor --bump z --yes
ShareX upstream example from a KovaForge checkout (publishes as Pre-release):
./.ai/skills/publish-release/scripts/run-release-sequence.sh --repo ShareX/XerahS --push-remote upstream --assume-changelog-done --monitor --bump z --yes
Force pre-release on KovaForge (override):
./.ai/skills/publish-release/scripts/run-release-sequence.sh --repo KovaForge/XerahS --assume-changelog-done --monitor --set-prerelease --bump z --yes
Force stable/latest on ShareX (override; uncommon):
./.ai/skills/publish-release/scripts/run-release-sequence.sh --repo ShareX/XerahS --push-remote upstream --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 forced, 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
Patch bump and stamp PPA/COPR/OBS candidates (does not publish):
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --prepare-distro-repo-source --bump z --yes
Patch bump and publish PPA/COPR/OBS (skips a backend without credentials):
./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --publish-distro-repos --bump z --yes
Stamp or publish an existing tag without running the rest of the sequence:
./.ai/skills/publish-release/scripts/prepare-distro-repo-assets.sh --tag vX.Y.Z --repo KovaForge/XerahS
./.ai/skills/publish-release/scripts/publish-distro-repos.sh --tag vX.Y.Z --repo KovaForge/XerahS
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-submodules
git 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 --branch shows develop...origin/develop, not detached HEAD.
- Abort if
ShareX.ImageEditor has 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.md is intentionally absent or the user confirms skip.
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, minor Y+1.0, major X+1.0.0.
- Ensure tag
v<new-version> does not exist locally or on origin.
- 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>" *> $null
if ($LASTEXITCODE -eq 0) { throw "Remote tag exists" }
- For
--no-bump: if v<current-version> already exists, do not try to recreate it. Use --no-tag for commit-only flow, or bump patch for a new tag.
- Update all tracked
Directory.Build.props files 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>.
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; then gh run view <run-id> --json status,conclusion,jobs,url
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.
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 6 Windows assets are attached (EXE, MSI, and
-portable.zip for both win-x64 and win-arm64) plus macOS and Linux assets. Validate portable ZIP contents as described in references/windows-portable.md, not just filenames.
Step 7 - Apply release channel policy
ShareX/XerahS: gh release edit v<new-version> --prerelease --latest=false
KovaForge/XerahS: gh release edit v<new-version> --prerelease=false --latest
- Verify:
gh release view v<new-version> --json isPrerelease,isLatest,url,assets
- Overrides:
--set-prerelease / --no-prerelease
- Workflow guard:
.github/workflows/release-build-all-platforms.yml must create/upload with the same repo policy (prerelease: github.repository != 'KovaForge/XerahS', make_latest: github.repository == 'KovaForge/XerahS').
Optional Flathub source-build preparation for manual submission
- Prefer keeping ShareX validation releases as pre-release while Flathub work 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: git sources pinned by tag/commit for the main repository and submodules.
- Generate and add offline dependency sources for NuGet/.NET packages and
ShareX.VideoEditor/frontend npm 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 PPA / COPR / OBS
- Stamp only:
.ai/skills/publish-release/scripts/prepare-distro-repo-assets.sh --tag v<new-version> --repo owner/name.
- Publish:
.ai/skills/publish-release/scripts/publish-distro-repos.sh --tag v<new-version> --repo owner/name (or --publish-distro-repos on the sequence script).
- Confirm Source0 /
_service URLs point at XerahS-<version>-linux-x64.tar.gz (or arm64), not a doubled linux-linux- path.
- Secret names and one-time Launchpad / COPR / OBS setup:
docs/linux/distro-repos.md.
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>
Default bump when unspecified: patch (z). Default commit type token: CI.
Behavior
- Require completion of
run-maintenance first.
- Script behavior: executes maintenance commands automatically unless explicitly bypassed with
--skip-maintenance (or legacy alias --assume-maintenance-done).
- Uncommitted local working-tree changes are auto-committed before the pull; submodule changes still block and require manual resolution.
- Require completion of
update-changelog second (skip only if docs/CHANGELOG.md is 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.
- Apply release-channel policy for the target repo: ShareX/XerahS = pre-release; KovaForge/XerahS = full latest release.
- 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). Local working-tree changes are auto-committed before the pull rather than blocking.
- Do not commit/push during maintenance/changelog steps.
- After maintenance submodule update, always reattach
ShareX.ImageEditor to develop, fast-forward it from origin/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 on ShareX/XerahS 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 repo channel policy: ShareX/XerahS uses
prerelease: true / make_latest: false; KovaForge/XerahS uses prerelease: false / make_latest: true.
- 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>" and git ls-remote --exit-code --tags with $LASTEXITCODE checks for tag existence.
- Support
--no-push and --no-tag when 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 explicitly, override channel with
--set-prerelease or --no-prerelease; otherwise apply repo defaults.
- If preparing for Flathub, run the source-build helper and report which of the source/dependency gates passed or failed.
- If preparing first-party Linux repos, run the distro-repo stamp helper. If publishing, run
publish-distro-repos.sh and report which backends uploaded vs skipped.
- Report final version, commit hash, branch push status, tag push status, run URL, repo target, and release channel (pre-release vs latest).
Default release-channel policy: ShareX/XerahS = pre-release; KovaForge/XerahS = full latest release. Use --set-prerelease / --no-prerelease only for intentional overrides.
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; use git 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.md is intentionally absent unless user requires it.
- Version sync: update every tracked
Directory.Build.props with <Version>, sync build/windows/chocolatey/xerahs.nuspec, and prepend a new <release version="X.Y.Z" date="YYYY-MM-DD"> entry to the <releases> block in flatpak/com.xerahs.XerahS.metainfo.xml. The metainfo insertion uses a generic "See CHANGELOG.md for details." placeholder description; edit it in the resulting commit before pushing if a hand-written note is preferred.
- Windows packaging produces 6 assets per release: EXE, MSI, and portable ZIP for each of x64 and ARM64.
build/windows/package-windows.ps1 uses the same self-contained publish payload for all three formats. Portable mode is enabled only in the ZIP; installer payloads must remain free of portable.txt.
- ShareX.ImageEditor submodule must stay on
develop: after git submodule update --init --recursive, immediately run git -C ShareX.ImageEditor fetch origin --prune, git -C ShareX.ImageEditor checkout develop, and git -C ShareX.ImageEditor pull --ff-only origin develop. git submodule update checks out the parent-recorded commit and can leave a detached HEAD; do not proceed with release work until git -C ShareX.ImageEditor status --short --branch confirms develop...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. The release-build-all-platforms.yml workflow installs WiX automatically in the build-windows job. 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) and InstallerType: wix (MSI) entries must be included for each architecture when submitting to winget-pkgs. See build/windows/winget/manifests/0.16.0/ShareX.XerahS.yaml as the template.
- Chocolatey asset naming:
build/windows/chocolatey/tools/chocolateyInstall.ps1 resolves XerahS-<version>-win-x64.exe or XerahS-<version>-win-arm64.exe from ChocolateyPackageVersion, 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.ps1 remains the manual fallback.
- Flatpak CI setup must fail loudly when the runtime cannot be installed; use
flatpak remote-add --no-gpg-verify for 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.
- Distro-repo candidates (PPA / COPR / OBS) wrap the existing GitHub linux tarball. They are not a second package format.
publish-distro-repos.sh uploads when secrets are present and skips a backend when they are not.
- 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-args must use options supported by flatpak build-finish; clipboard read/write flags are not valid finish-args.
- Flatpak session bus access is expressed as
--socket=session-bus or narrower --talk-name= policies, not --bus=session.
- Flatpak CI bundling should export
flatpak-builder output to an explicit local repo with --repo=...; validate files directly or use supported Flatpak commands, not flatpak 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.
- Dual-repo remote resolution must parse
git@github-<alias>:Owner/Repo.git; bare gh repo view on a KovaForge fork checkout often returns ShareX/XerahS and must not be used for release targeting.
- After XIP0078 ad-hoc signing was added, macos-15 CI can fail when codesign hard-fails on unsigned nested managed DLLs; ad-hoc signing must use
--deep and must not fail the release matrix for interim unsigned seals.
- Always verify the full required asset list on the chosen repo after workflow success; an empty GitHub release with zero assets is a failed publish even if a tag/release shell exists.
- Release channel is repo-scoped: never publish ShareX/XerahS as latest by default; never leave KovaForge/XerahS as pre-release by default after a successful publish-release run.
- Release reliability loop: tag push is not the end; monitor, fix, and retry until green.
1---2name: publish-release3description: Publish a requested XerahS release or prepare a Windows portable package. Local packaging does not authorize publishing.4---56# XerahS Release Bump Tag78## Windows Portable Releases910Windows portable ZIPs are part of every normal tagged release alongside the EXE/MSI installers. For portable-only local packaging, artifact verification, and upgrade guidance, read [references/windows-portable.md](references/windows-portable.md). A request to build a portable ZIP locally does not require a version bump, tag, or GitHub release; use that reference instead of the publishing sequence below.1112## Overview1314Use this skill to run release steps in strict order:15- Step 1: Execute maintenance prep first (`git pull --recurse-submodules` and `git submodule update --init --recursive`), then reattach `ShareX.ImageEditor` to `develop` and fast-forward it from `origin/develop`. Uncommitted local changes in the working tree are auto-committed with message `[skill] Auto-commit uncommitted changes before release maintenance` before the pull. Submodule local changes still block the sequence and must be committed/stashed manually.16- Step 2: Run `.ai/skills/update-changelog/SKILL.md` second (optional only if `docs/CHANGELOG.md` is intentionally absent)17- Step 3: Verify build, then execute bump/commit/push/tag automation18- Step 4: Monitor the tag-triggered release workflow every 2 minutes19- Step 5: If failure occurs, inspect logs, fix the root cause in code or workflow first (do not skip the fix and retry the same version), commit and push the fix, then retry with the next patch version. If the failure is in the `build-flatpak` job, verify all plugin DLLs are present in the staging directory; the workflow now includes a plugin re-validation step but a code fix in `package-linux.sh` may also be needed. Repeat until workflow succeeds.20- Step 6: Ensure standard release notes block is present on the GitHub release21- Step 7: Apply repo release-channel policy (see below)22- Optional Step 8: Generate a Flathub source-build manifest candidate from the successful release tag; do not open or automate a Flathub PR23- Optional Step 9: Stamp Launchpad PPA / Fedora COPR / openSUSE OBS candidates, or publish them with `--publish-distro-repos` (secrets-gated skip per backend; see `docs/linux/distro-repos.md`)24- GitHub Actions release upload steps must match the same repo policy (`prerelease` / `make_latest` by `github.repository`); do not rely only on the post-workflow `gh release edit` guard.2526Repository target behavior (dual-repo):27- Supported release targets: `https://github.com/KovaForge/XerahS` and `https://github.com/ShareX/XerahS`.28- Git pushes use `--push-remote` (default: `origin`). For ShareX publishes from a KovaForge fork checkout, use `--push-remote upstream --repo ShareX/XerahS`.29- GitHub CLI operations (`gh run`, `gh release`) resolve from the `origin` remote URL by default.30- Origin may be a standard `github.com` URL or a KovaForge per-person SSH alias such as `git@github-vladislava:KovaForge/XerahS.git`.31- Do **not** rely on bare `gh repo view` for target inference on fork checkouts: it often resolves the upstream parent (`ShareX/XerahS`) instead of origin (`KovaForge/XerahS`).32- Use `--repo owner/name` to override the inferred target when needed.33- After a successful workflow, the skill verifies the required asset set on the chosen repo (Windows installers and portable ZIPs/macOS/Linux/Flatpak + Chocolatey nupkg).3435Release channel policy (default):36- `ShareX/XerahS` -> always **Pre-release** (`prerelease: true`, not latest)37- `KovaForge/XerahS` -> **Release** / latest (`prerelease: false`, `make_latest: true`)38- Override with `--set-prerelease` or `--no-prerelease` when intentionally forcing the opposite channel.3940Step 3 performs:41- Pre-check: Run `dotnet build src/desktop/XerahS.sln`; do not proceed if build fails.42- Prompts for `x/y/z` bump type (major/minor/patch) unless specified.43- Updates every tracked `Directory.Build.props` file that defines `<Version>`.44- Syncs `build/windows/chocolatey/xerahs.nuspec` `<version>` with the release version.45- Stages all current repo changes.46- Commits with version-prefixed message.47- Pushes current branch and creates/pushes annotated tag `vX.Y.Z`.4849Step 4-5 performs:50- Find tag run for `Release Build (All Platforms)`.51- Poll run status every 120 seconds until completion.52- On failure, inspect failing job logs and identify first blocking error.53- Fix root cause in code/workflow/scripts.54- Re-run local pre-check build.55- Retry release using next patch bump, then monitor again.56- Repeat until workflow succeeds.5758Step 6 performs:59- Ensures release notes always include:60 - `Change log:`61 - `https://xerahs.com/changelog.html`62 - `### macOS Troubleshooting ("App is damaged")` section with Gatekeeper `xattr -cr` guidance.63- After the release is published, the tag workflow also builds, smoke-tests, and attaches `xerahs.X.Y.Z.nupkg` to the GitHub release.64- `build/windows/chocolatey/Sync-ChocolateyPackage.ps1 -Version X.Y.Z` remains the manual recovery path for re-syncing checksums or repacking.65- Expected Windows release assets: six files across x64 and ARM64, with `XerahS-X.Y.Z-win-<arch>.exe`, `XerahS-X.Y.Z-win-<arch>.msi`, and `XerahS-X.Y.Z-win-<arch>-portable.zip` for each architecture. The ZIP must contain `portable.txt` next to `XerahS.exe`; see the portable reference for validation.66- Expected Linux AppImage assets: `XerahS-X.Y.Z-linux-x64.AppImage`, `XerahS-X.Y.Z-linux-arm64.AppImage` (in addition to tar.gz/deb/rpm and the existing Flatpak bundle).6768Optional Step 8 performs:69- Runs `.ai/skills/publish-release/scripts/prepare-flathub-source-build.sh --tag vX.Y.Z --repo owner/name --lint`.70- Generates `dist/flathub/com.xerahs.XerahS.yml` from the GitHub release tag plus pinned `ShareX.ImageEditor` and `ShareX.VideoEditor` submodule commits.71- Adds the Freedesktop SDK `dotnet10` and `node24` extensions needed to run the Linux publish script inside the Flatpak build sandbox.72- Verifies the generated manifest does not use local `dist/xerahs-flatpak-staging` sources.73- 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.74- 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.7576Optional Step 9 performs:77- `--prepare-distro-repo-source` runs `.ai/skills/publish-release/scripts/prepare-distro-repo-assets.sh --tag vX.Y.Z --repo owner/name` and stamps `dist/distro-repo/` from `build/linux/repo-staging/`.78- `--publish-distro-repos` runs `.ai/skills/publish-release/scripts/publish-distro-repos.sh --tag vX.Y.Z --repo owner/name`: stamp, then `dput` / `copr-cli build` / `osc commit` when credentials exist.79- Missing Launchpad GPG, COPR config, or OBS login skips that backend and does not fail the release. A backend with credentials that fails the upload does fail.80- One-time project creation and secret names live in `docs/linux/distro-repos.md`.81- Does not invent a second `.deb` / `.rpm` format. GitHub release assets remain the one-off installers; these channels are the `apt` / `dnf` / `zypper` update path from ShareX/XerahS#253.8283## Primary Command8485From repository root:8687```bash88./.ai/skills/publish-release/scripts/run-release-sequence.sh89```9091Automated monitor with repo-default channel (recommended):9293```bash94./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --bump z --yes95```9697KovaForge fork example (publishes as full Release / latest):9899```bash100./.ai/skills/publish-release/scripts/run-release-sequence.sh --repo KovaForge/XerahS --git-wrapper git-vladislava --push-remote vladislava --assume-changelog-done --monitor --bump z --yes101```102103ShareX upstream example from a KovaForge checkout (publishes as Pre-release):104105```bash106./.ai/skills/publish-release/scripts/run-release-sequence.sh --repo ShareX/XerahS --push-remote upstream --assume-changelog-done --monitor --bump z --yes107```108109Force pre-release on KovaForge (override):110111```bash112./.ai/skills/publish-release/scripts/run-release-sequence.sh --repo KovaForge/XerahS --assume-changelog-done --monitor --set-prerelease --bump z --yes113```114115Force stable/latest on ShareX (override; uncommon):116117```bash118./.ai/skills/publish-release/scripts/run-release-sequence.sh --repo ShareX/XerahS --push-remote upstream --assume-changelog-done --monitor --no-prerelease --bump z --yes119```120121Manual monitor (fallback, PowerShell example):122123```powershell124gh run list --limit 10 --json databaseId,workflowName,headBranch,status,conclusion,url125Start-Sleep -Seconds 120126gh run view <run-id> --json status,conclusion,jobs,url127```128129## Non-Interactive Examples130131Patch bump, no prompts:132133```bash134./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --bump z --yes135```136137Patch bump with built-in 2-minute monitoring:138139```bash140./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --monitor-interval 120 --bump z --yes141```142143Patch bump, pre-release forced, and generate Flathub source-build candidate:144145```bash146./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --set-prerelease --prepare-flathub-source --bump z --yes147```148149Patch bump and stamp PPA/COPR/OBS candidates (does not publish):150151```bash152./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --prepare-distro-repo-source --bump z --yes153```154155Patch bump and publish PPA/COPR/OBS (skips a backend without credentials):156157```bash158./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --monitor --publish-distro-repos --bump z --yes159```160161Stamp or publish an existing tag without running the rest of the sequence:162163```bash164./.ai/skills/publish-release/scripts/prepare-distro-repo-assets.sh --tag vX.Y.Z --repo KovaForge/XerahS165./.ai/skills/publish-release/scripts/publish-distro-repos.sh --tag vX.Y.Z --repo KovaForge/XerahS166```167168Minor bump with custom commit token/summary:169170```bash171./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --bump y --type CI --summary "Prepare release artifacts" --yes172```173174Preview only:175176```bash177./.ai/skills/publish-release/scripts/run-release-sequence.sh --assume-changelog-done --bump z --dry-run --yes178```179180## When bash is unavailable (e.g. Windows PowerShell)181182On environments where `bash` is not in PATH, execute the sequence manually:1831841. Step 1 - Maintenance185 - `git pull --recurse-submodules`186 - `git submodule update --init --recursive`187 - Mandatory after submodule update: `git -C ShareX.ImageEditor fetch origin --prune`188 - Mandatory after submodule update: `git -C ShareX.ImageEditor checkout develop`189 - Mandatory after submodule update: `git -C ShareX.ImageEditor pull --ff-only origin develop`190 - Verify `git -C ShareX.ImageEditor status --short --branch` shows `develop...origin/develop`, not detached HEAD.191 - Abort if `ShareX.ImageEditor` has 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.1921932. Step 2 - Changelog194 - Run `.ai/skills/update-changelog/SKILL.md`.195 - Skip only if `docs/CHANGELOG.md` is intentionally absent or the user confirms skip.1961973. Step 3 - Bump, commit, push, tag198 - Run `dotnet build src/desktop/XerahS.sln`; abort if it fails.199 - Read current version from root `Directory.Build.props`.200 - Compute next version: patch `Z+1`, minor `Y+1.0`, major `X+1.0.0`.201 - Ensure tag `v<new-version>` does not exist locally or on `origin`.202 - PowerShell-safe local check (avoid false positives from `if (git rev-parse <tag>)`):203 - `git show-ref --verify --quiet "refs/tags/v<new-version>"`204 - `if ($LASTEXITCODE -eq 0) { throw "Local tag exists" }`205 - PowerShell-safe remote check:206 - `git ls-remote --exit-code --tags origin "refs/tags/v<new-version>" *> $null`207 - `if ($LASTEXITCODE -eq 0) { throw "Remote tag exists" }`208 - For `--no-bump`: if `v<current-version>` already exists, do not try to recreate it. Use `--no-tag` for commit-only flow, or bump patch for a new tag.209 - Update all tracked `Directory.Build.props` files containing `<Version>`.210 - Update `build/windows/chocolatey/xerahs.nuspec` `<version>` to match.211 - `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>`.2122134. Step 4 - Monitor every 2 minutes214 - Find run: `gh run list --limit 10 --json databaseId,workflowName,headBranch,status,conclusion,url`215 - Poll: `Start-Sleep -Seconds 120`; then `gh run view <run-id> --json status,conclusion,jobs,url`2162175. Step 5 - On failure, fix and retry218 - Fetch failed job logs: `gh run view <run-id> --job <job-id> --log`219 - Fix root cause in repository.220 - Re-run `dotnet build src/desktop/XerahS.sln`.221 - Repeat Step 3 with next patch version.2222236. Step 6 - Ensure standard release notes content224 - Read current body: `gh release view v<new-version> --json body`225 - Append the standard changelog + macOS troubleshooting block if missing.226 - Write body: `gh release edit v<new-version> --notes-file <file>`227 - Verify all **6 Windows assets** are attached (EXE, MSI, and `-portable.zip` for both `win-x64` and `win-arm64`) plus macOS and Linux assets. Validate portable ZIP contents as described in [references/windows-portable.md](references/windows-portable.md), not just filenames.2282297. Step 7 - Apply release channel policy230 - `ShareX/XerahS`: `gh release edit v<new-version> --prerelease --latest=false`231 - `KovaForge/XerahS`: `gh release edit v<new-version> --prerelease=false --latest`232 - Verify: `gh release view v<new-version> --json isPrerelease,isLatest,url,assets`233 - Overrides: `--set-prerelease` / `--no-prerelease`234 - Workflow guard: `.github/workflows/release-build-all-platforms.yml` must create/upload with the same repo policy (`prerelease: github.repository != 'KovaForge/XerahS'`, `make_latest: github.repository == 'KovaForge/XerahS'`).2352368. Optional Flathub source-build preparation for manual submission237 - Prefer keeping ShareX validation releases as pre-release while Flathub work is ongoing.238 - Run `.ai/skills/publish-release/scripts/prepare-flathub-source-build.sh --tag v<new-version> --repo owner/name --lint`.239 - Confirm the generated manifest uses `type: git` sources pinned by tag/commit for the main repository and submodules.240 - Generate and add offline dependency sources for NuGet/.NET packages and `ShareX.VideoEditor/frontend` npm packages before attempting a network-disabled Flathub build.241 - Build and lint the generated manifest locally before a human maintainer manually opens the Flathub PR.2422439. Optional PPA / COPR / OBS244 - Stamp only: `.ai/skills/publish-release/scripts/prepare-distro-repo-assets.sh --tag v<new-version> --repo owner/name`.245 - Publish: `.ai/skills/publish-release/scripts/publish-distro-repos.sh --tag v<new-version> --repo owner/name` (or `--publish-distro-repos` on the sequence script).246 - Confirm Source0 / `_service` URLs point at `XerahS-<version>-linux-x64.tar.gz` (or arm64), not a doubled `linux-linux-` path.247 - Secret names and one-time Launchpad / COPR / OBS setup: `docs/linux/distro-repos.md`.24824910. Optional post-release Chocolatey maintenance250 - The tag workflow should already have produced and smoke-tested `xerahs.<new-version>.nupkg`.251 - Manual repack/re-sync: `powershell -File build/windows/chocolatey/Sync-ChocolateyPackage.ps1 -Version <new-version> -Pack`252 - Manual smoke test: `powershell -File build/windows/chocolatey/Test-ChocolateyPackage.ps1 -Version <new-version> -SourceDirectory dist\chocolatey`253 - Optionally push after review: `powershell -File build/windows/chocolatey/Sync-ChocolateyPackage.ps1 -Version <new-version> -Pack -Push -ApiKey <key>`254255Default bump when unspecified: patch (`z`). Default commit type token: `CI`.256257## Behavior2582591. Require completion of `run-maintenance` first.260 - Script behavior: executes maintenance commands automatically unless explicitly bypassed with `--skip-maintenance` (or legacy alias `--assume-maintenance-done`).261 - Uncommitted local working-tree changes are auto-committed before the pull; submodule changes still block and require manual resolution.2622. Require completion of `update-changelog` second (skip only if `docs/CHANGELOG.md` is intentionally absent or user confirms).2633. Before bump, run `dotnet build src/desktop/XerahS.sln`; abort on failure.2644. Run `scripts/bump-version-commit-tag.sh` (or PowerShell/manual equivalent when bash unavailable).2655. After tag push, monitor the release workflow every 120 seconds until complete.2666. If failed, inspect logs, fix root cause, and retry with next patch version.2677. Continue retry loop until release workflow is successful.2688. Ensure standard release notes content is present on the successful release.2699. Apply release-channel policy for the target repo: ShareX/XerahS = pre-release; KovaForge/XerahS = full latest release.27010. When preparing for Flathub, generate the source-build manifest candidate and treat missing offline dependency sources as release-blocking for Flathub submission.271272## Guardrails273274- Do not skip sequence unless user explicitly requests bypass.275- Do not skip maintenance unless user explicitly requests bypass (`--skip-maintenance`). Local working-tree changes are auto-committed before the pull rather than blocking.276- Do not commit/push during maintenance/changelog steps.277- After maintenance submodule update, always reattach `ShareX.ImageEditor` to `develop`, fast-forward it from `origin/develop`, and verify it is not detached before build, bump, tag, or release work continues.278- Always verify build before bump/tag.279- Always monitor workflow after tag push; do not stop at tag creation.280- Always inspect logs on failure and fix root cause before retry.281- Always ensure the standard release notes block exists on the successful release.282- Always keep Flathub validation on ShareX/XerahS as pre-release until source-build, dependency-source, lint, repo-lint, and smoke-test gates pass.283- Always keep the GitHub Actions release creation step aligned with repo channel policy: ShareX/XerahS uses `prerelease: true` / `make_latest: false`; KovaForge/XerahS uses `prerelease: false` / `make_latest: true`.284- Always use a new patch version for retries requiring new commits/tags.285- Abort on detached HEAD.286- Abort if version format is not `X.Y.Z`.287- Abort if matching tag already exists locally or remotely.288- In PowerShell manual flow, use `git show-ref --verify --quiet "refs/tags/<tag>"` and `git ls-remote --exit-code --tags` with `$LASTEXITCODE` checks for tag existence.289- Support `--no-push` and `--no-tag` when partial flow is needed.290291## Agent usage (Cursor / Codex)292293When executing this skill:2941. Run sequence: maintenance -> changelog -> build verify -> bump/commit/push/tag.2952. Use bash scripts if bash exists; otherwise use PowerShell/manual flow.2963. Default bump is patch (`z`) when unspecified.2974. Monitor tag workflow every 120 seconds until completion.2985. On failure, inspect logs, fix issue, and retry with next patch version.2996. Ensure release notes include changelog link + macOS troubleshooting block.3008. If requested explicitly, override channel with `--set-prerelease` or `--no-prerelease`; otherwise apply repo defaults.3019. If preparing for Flathub, run the source-build helper and report which of the source/dependency gates passed or failed.30210. If preparing first-party Linux repos, run the distro-repo stamp helper. If publishing, run `publish-distro-repos.sh` and report which backends uploaded vs skipped.30311. Report final version, commit hash, branch push status, tag push status, run URL, repo target, and release channel (pre-release vs latest).304305Default release-channel policy: `ShareX/XerahS` = pre-release; `KovaForge/XerahS` = full latest release. Use `--set-prerelease` / `--no-prerelease` only for intentional overrides.306307## Notes (lessons learnt)308309- Windows/PowerShell: bash may be unavailable; manual fallback must be first-class.310- Windows/PowerShell: avoid `if (git rev-parse <tag>)` for local tag existence checks; use `git show-ref --verify --quiet refs/tags/<tag>` and inspect `$LASTEXITCODE`.311- Build before bump: avoid tagging broken trees.312- Changelog optional: do not block if `docs/CHANGELOG.md` is intentionally absent unless user requires it.313- Version sync: update every tracked `Directory.Build.props` with `<Version>`, sync `build/windows/chocolatey/xerahs.nuspec`, and prepend a new `<release version="X.Y.Z" date="YYYY-MM-DD">` entry to the `<releases>` block in `flatpak/com.xerahs.XerahS.metainfo.xml`. The metainfo insertion uses a generic "See CHANGELOG.md for details." placeholder description; edit it in the resulting commit before pushing if a hand-written note is preferred.314- **Windows packaging produces 6 assets per release**: EXE, MSI, and portable ZIP for each of x64 and ARM64. `build/windows/package-windows.ps1` uses the same self-contained publish payload for all three formats. Portable mode is enabled only in the ZIP; installer payloads must remain free of `portable.txt`.315- **ShareX.ImageEditor submodule must stay on `develop`**: after `git submodule update --init --recursive`, immediately run `git -C ShareX.ImageEditor fetch origin --prune`, `git -C ShareX.ImageEditor checkout develop`, and `git -C ShareX.ImageEditor pull --ff-only origin develop`. `git submodule update` checks out the parent-recorded commit and can leave a detached HEAD; do not proceed with release work until `git -C ShareX.ImageEditor status --short --branch` confirms `develop...origin/develop`.316- **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`. The `release-build-all-platforms.yml` workflow installs WiX automatically in the `build-windows` job. For local MSI builds: install WiX first; if not present the script emits a warning and skips MSI.317- **MSI install layout**: per-user, no UAC elevation required. Binaries → `%LocalAppData%\Programs\XerahS\`; Plugins → `%USERPROFILE%\Documents\XerahS\Plugins\`; Start Menu shortcut created automatically.318- **Winget manifest**: both `InstallerType: nullsoft` (EXE) and `InstallerType: wix` (MSI) entries must be included for each architecture when submitting to winget-pkgs. See `build/windows/winget/manifests/0.16.0/ShareX.XerahS.yaml` as the template.319- Chocolatey asset naming: `build/windows/chocolatey/tools/chocolateyInstall.ps1` resolves `XerahS-<version>-win-x64.exe` or `XerahS-<version>-win-arm64.exe` from `ChocolateyPackageVersion`, so release bumps should not hardcode installer filenames there.320- 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.ps1` remains the manual fallback.321- Flatpak CI setup must fail loudly when the runtime cannot be installed; use `flatpak remote-add --no-gpg-verify` for unsigned Flathub setup, not `--no-sign-verify`.322- Flatpak manifest source paths are resolved relative to the manifest directory, so staging paths outside `flatpak/` need a `../` prefix.323- 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`.324- Flathub source-build candidates must include pinned submodule commits; GitHub source archives do not automatically include submodule contents.325- Flathub source-build candidates are not ready until NuGet/.NET and npm dependency sources are generated and a network-disabled Flatpak build passes.326- Distro-repo candidates (PPA / COPR / OBS) wrap the existing GitHub linux tarball. They are not a second package format. `publish-distro-repos.sh` uploads when secrets are present and skips a backend when they are not.327- Flatpak build commands install into `/app`, not `/usr`; expose launchers through `/app/bin`.328- 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.329- Flatpak `finish-args` must use options supported by `flatpak build-finish`; clipboard read/write flags are not valid `finish-args`.330- Flatpak session bus access is expressed as `--socket=session-bus` or narrower `--talk-name=` policies, not `--bus=session`.331- Flatpak CI bundling should export `flatpak-builder` output to an explicit local repo with `--repo=...`; validate files directly or use supported Flatpak commands, not `flatpak build-info`.332- Chocolatey release metadata lookup must use the active GitHub repository (`GITHUB_REPOSITORY`, `origin`, or explicit `-Repository owner/name`), not a hardcoded upstream owner.333- Chocolatey install scripts must also generate download URLs from the active release repository; updating only nuspec metadata is not enough.334- Dual-repo remote resolution must parse `git@github-<alias>:Owner/Repo.git`; bare `gh repo view` on a KovaForge fork checkout often returns `ShareX/XerahS` and must not be used for release targeting.335- After XIP0078 ad-hoc signing was added, macos-15 CI can fail when codesign hard-fails on unsigned nested managed DLLs; ad-hoc signing must use `--deep` and must not fail the release matrix for interim unsigned seals.336- Always verify the full required asset list on the chosen repo after workflow success; an empty GitHub release with zero assets is a failed publish even if a tag/release shell exists.337- Release channel is repo-scoped: never publish ShareX/XerahS as latest by default; never leave KovaForge/XerahS as pre-release by default after a successful publish-release run.338- Release reliability loop: tag push is not the end; monitor, fix, and retry until green.