Skip to content

feat(tools): replace Download-Release with Publish-Release orchestrator, streamline Build-Installer#2070

Merged
Belphemur merged 3 commits intodevfrom
copilot/add-github-cli-to-setup-script
Apr 16, 2026
Merged

feat(tools): replace Download-Release with Publish-Release orchestrator, streamline Build-Installer#2070
Belphemur merged 3 commits intodevfrom
copilot/add-github-cli-to-setup-script

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

Replaces the REST API–based Download-Release.ps1 with a gh CLI–driven Publish-Release.ps1 that handles the full release lifecycle, and streamlines Build-Installer.ps1 to focus exclusively on installer compilation and code signing.

New: Publish-Release.ps1

  • Finds the latest draft release (created by semantic-release) via gh release list --json
  • Downloads and extracts the build artifact zip via gh release download, asserting exactly one matching zip (throws with file list on multiple)
  • Supports -BuildFromSource to build from source instead of downloading from a draft release
  • HTML documentation generation and asset bundling only run when building from source — the CI pipeline (reusable-build.yml) already includes these in the release zip
  • Derives -InstallerReleaseState automatically from -Channel (betaBeta, releaseRelease) unless explicitly overridden
  • Delegates to Build-Installer.ps1 -FinalDir for installer compilation and code signing
  • Uploads signed installer(s) with --clobber (replaces existing assets)
  • Extracts the latest CHANGELOG.md section as the release body, prompts user for optional prepended notes
  • Requires explicit y confirmation before publishing (--draft=false)
  • Captures gh CLI stdout only for JSON parsing — stderr passes through to console for diagnostics

Streamlined: Build-Installer.ps1

  • Accepts -FinalDir parameter (defaults to .\Final) — focused exclusively on signing binaries, compiling the installer, and signing the installer
  • Invokes Inno Setup (ISCC.exe) directly via Windows registry lookup — no longer depends on legacy Make-Installer.bat
  • Uses Sign-Binary.ps1 for all code signing (binaries and installer)
  • Validates directory contents recursively
  • Does not build from source, generate HTML docs, bundle assets, or interact with GitHub releases

Install-BuildTools.ps1

  • Added GitHub.cli as the first winget dependency

PS 7.0 enforcement

  • Added #Requires -Version 7.0 to Build-Installer.ps1 and Sign-Binary.ps1 — all tools/*.ps1 scripts now enforce this

Tests

  • AST-based test for GitHub CLI install ordering (not brittle string-index matching)
  • Parse validation and parameter checks for all three scripts
  • 37 tests passing

Usage

# One-time setup
.\tools\Install-BuildTools.ps1

# Full release workflow (interactive)
.\tools\Publish-Release.ps1                  # stable
.\tools\Publish-Release.ps1 -Channel beta    # beta (auto-derives InstallerReleaseState=Beta)

# Build from source locally (no release interaction)
.\tools\Publish-Release.ps1 -BuildFromSource

# Installer build only (from pre-populated Final\)
.\tools\Build-Installer.ps1
.\tools\Build-Installer.ps1 -SkipSigning

Summary by CodeRabbit

  • New Features

    • Added unified release orchestration script with GitHub CLI integration for managing SoundSwitch releases.
  • Changes

    • Simplified installer build tooling to focus on compilation only.
    • Refactored release workflow; downloading and publishing now handled through GitHub CLI.
    • GitHub CLI is now required for release operations.
  • Documentation

    • Updated build tools documentation to reflect new release process.

Copilot AI and others added 2 commits April 16, 2026 07:00
…nforce PS 7.0+

- Delete Download-Release.ps1, replaced by Publish-Release.ps1
- Publish-Release.ps1: full release orchestrator using gh CLI
  (download draft, build installer, upload, changelog body, publish)
- Build-Installer.ps1: replace -DownloadRelease with -SkipBuild,
  focused on building and code signing only
- Add #Requires -Version 7.0 to Build-Installer.ps1 and Sign-Binary.ps1
- Update tests and README.md

Agent-Logs-Url: https://github.com/Belphemur/SoundSwitch/sessions/d5956fcd-da14-4ae6-951b-41c726b479cc

Co-authored-by: Belphemur <197810+Belphemur@users.noreply.github.com>
@Belphemur Belphemur marked this pull request as ready for review April 16, 2026 07:07
Copilot AI review requested due to automatic review settings April 16, 2026 07:07
@Belphemur
Copy link
Copy Markdown
Owner

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Download-based release script was removed and replaced by a new end-to-end release orchestrator tools/Publish-Release.ps1. Build-Installer.ps1 was simplified to operate on a pre-populated Final directory (new -FinalDir), Inno Setup compilation is invoked directly, and GitHub CLI is added as an installed build tool. PowerShell 7+ is now required for some tooling scripts.

Changes

Cohort / File(s) Summary
New Release Orchestrator
tools/Publish-Release.ps1
Added a new PowerShell 7+ script that finds the appropriate draft release via gh, downloads exactly one SoundSwitch-v*.zip asset into Final, optionally builds from source, delegates installer build/signing to Build-Installer.ps1, uploads signed *Installer.exe assets to the draft (gh release upload --clobber), updates release notes from CHANGELOG, and optionally publishes the release after confirmation.
Removed Download Script
tools/Download-Release.ps1
Deleted the standalone script that previously downloaded/extracted a release zip from GitHub Releases; its responsibilities moved into Publish-Release.ps1.
Installer Build Changes
tools/Build-Installer.ps1
Removed parameters/flow for downloading/releases and source publish; added -FinalDir parameter (defaults to repo Final), enforces PowerShell 7 via #Requires -Version 7.0, locates/uses Inno Setup (ISCC.exe) directly, compiles installer via ISCC.exe /DReleaseState=..., places outputs under FinalDir\Installer, and retains conditional signing via tools\Sign-Binary.ps1.
Build Tools Installer
tools/Install-BuildTools.ps1
Added installation of GitHub CLI (GitHub.cli) before Inno Setup in winget steps and updated final installed-tools output to include GitHub CLI.
Tooling Tests
tools/Install-BuildTools.Tests.ps1
Added Pester tests that statically validate scripts: ensure winget ordering (GitHub.cli before InnoSetup), parse AST/no parse errors for Publish-Release.ps1 and Build-Installer.ps1, and check presence/absence of expected tokens (#Requires -Version 7.0, $FinalDir, ISCC, absence of Make-Installer.bat, and use of Sign-Binary.ps1).
Docs
tools/README.md
Rewrote docs to describe the new Publish-Release.ps1 workflow, GitHub CLI requirement, and Build-Installer.ps1 expectation to consume a pre-populated Final directory. Removed Download-Release.ps1 references.
Signer Version Constraint
tools/Sign-Binary.ps1
Added #Requires -Version 7.0 to enforce PowerShell 7+.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Publish as Publish-Release.ps1
    participant GH as GitHub CLI (gh)
    participant FS as File System
    participant Installer as Build-Installer.ps1
    participant Signer as Sign-Binary.ps1
    participant CHANGELOG as CHANGELOG.md

    User->>Publish: run with -Channel / options
    Publish->>GH: list/releases -> select draft matching channel
    GH-->>Publish: draft metadata + asset list
    Publish->>GH: download SoundSwitch-v*.zip to temp
    GH-->>Publish: zip downloaded
    Publish->>FS: extract zip -> `Final` (or BuildFromSource -> dotnet publish -> `Final`)
    FS-->>Publish: Final populated
    Publish->>Installer: Invoke with -FinalDir and InstallerReleaseState
    Installer->>FS: validate FinalDir exists & non-empty
    Installer->>Installer: locate ISCC.exe (registry / PATH)
    Installer->>FS: run ISCC -> produce *Installer.exe in FinalDir
    Installer->>Signer: call Sign-Binary.ps1 (if signing enabled)
    Signer-->>Installer: signed installer(s)
    Installer-->>Publish: return success
    Publish->>CHANGELOG: extract latest changelog section
    CHANGELOG-->>Publish: release notes content
    Publish->>GH: gh release upload --clobber Final\Installer\*Installer.exe
    GH-->>Publish: assets updated
    Publish->>User: prompt to publish
    User-->>Publish: confirm
    Publish->>GH: gh release edit --draft=false
    GH-->>Publish: release published
    Publish-->>User: done
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through zips and draft-release light,

GitHub CLI danced through the night,
FinalFolder ready, installers compiled,
ISCC hummed, the signing smiled,
Hooray — the rabbit shipped it right!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: replacing Download-Release with Publish-Release orchestrator and streamlining Build-Installer. It is concise, specific, and directly reflects the primary objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch copilot/add-github-cli-to-setup-script

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tools/Install-BuildTools.Tests.ps1 (1)

480-518: Please add one mocked behavior test for the new release contract.

These additions only prove that the scripts parse and contain certain strings. They will not catch workflow regressions in tools/Publish-Release.ps1, such as -Channel beta still generating a Release installer state or a custom -OutputDir drifting away from tools/Build-Installer.ps1's fixed Final\ path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/Install-BuildTools.Tests.ps1` around lines 480 - 518, Add a Pester test
that mocks the downstream behavior to verify the new release contract: in the
tests for Publish-Release.ps1 create a spec that Mocks the call to
Build-Installer.ps1 (or the function/command that Publish-Release.ps1 invokes),
invoke Publish-Release.ps1 with representative args (e.g. -Channel 'beta' and a
custom -OutputDir), and assert the mocked call received the expected parameters
(ensure -Channel does not translate to installer state "Release" and that
-OutputDir maps to the expected final path like 'Final\'), using Pester Mock and
Should assertions to fail if Publish-Release.ps1 sends incorrect parameters to
Build-Installer.ps1.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tools/Publish-Release.ps1`:
- Around line 69-70: The script defines [string]$OutputDir but never passes it
into the downstream build/upload steps, causing mismatches between where the
installer is built and where the pipeline uploads; update the Publish-Release
flow to propagate $OutputDir into the Build-Installer invocation and all uses
(e.g., the call to tools/Build-Installer.ps1 and the upload path referencing
$OutputDir\Installer), and adjust the -SkipBuild precondition logic to validate
against the same $OutputDir (or default to '..\Final' if none supplied) so build
and upload always operate on the same directory.
- Around line 64-75: The script currently hardcodes
InstallerReleaseState='Release' regardless of -Channel; change the defaulting so
when Channel is 'beta' InstallerReleaseState is set to 'Beta' (or otherwise
derived from $Channel) unless the caller explicitly passes
-InstallerReleaseState; update the parameter handling and any places that
forward InstallerReleaseState (references: the parameter names $Channel and
$InstallerReleaseState and calls to tools/Build-Installer.ps1) to
compute/override the value at startup and ensure the same logic is applied at
the other occurrences noted (the other places forwarding InstallerReleaseState).

---

Nitpick comments:
In `@tools/Install-BuildTools.Tests.ps1`:
- Around line 480-518: Add a Pester test that mocks the downstream behavior to
verify the new release contract: in the tests for Publish-Release.ps1 create a
spec that Mocks the call to Build-Installer.ps1 (or the function/command that
Publish-Release.ps1 invokes), invoke Publish-Release.ps1 with representative
args (e.g. -Channel 'beta' and a custom -OutputDir), and assert the mocked call
received the expected parameters (ensure -Channel does not translate to
installer state "Release" and that -OutputDir maps to the expected final path
like 'Final\'), using Pester Mock and Should assertions to fail if
Publish-Release.ps1 sends incorrect parameters to Build-Installer.ps1.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4812db39-93ae-413e-82fd-db478b2ca166

📥 Commits

Reviewing files that changed from the base of the PR and between 30e8469 and 09a9e5b.

📒 Files selected for processing (7)
  • tools/Build-Installer.ps1
  • tools/Download-Release.ps1
  • tools/Install-BuildTools.Tests.ps1
  • tools/Install-BuildTools.ps1
  • tools/Publish-Release.ps1
  • tools/README.md
  • tools/Sign-Binary.ps1
💤 Files with no reviewable changes (1)
  • tools/Download-Release.ps1

Comment thread tools/Publish-Release.ps1 Outdated
Comment thread tools/Publish-Release.ps1 Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR replaces the REST API–based release download script with a GitHub CLI–driven release publishing orchestrator, and refactors the installer build script to separate release orchestration from build/sign responsibilities.

Changes:

  • Added tools/Publish-Release.ps1 to orchestrate draft release download → build/sign → upload assets → set notes → publish via gh.
  • Refactored tools/Build-Installer.ps1 to use -SkipBuild (assume Final\ is already populated) instead of downloading releases.
  • Updated build tooling installation and tests to include GitHub CLI and validate new scripts.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tools/Publish-Release.ps1 New end-to-end release orchestrator using GitHub CLI (gh).
tools/Build-Installer.ps1 Removes release download; introduces -SkipBuild flow for pre-populated Final\.
tools/Install-BuildTools.ps1 Installs GitHub CLI via winget and updates installed-tools output.
tools/Install-BuildTools.Tests.ps1 Adds tests for GitHub CLI ordering and basic parse/parameter validation for scripts.
tools/README.md Updates tooling documentation to reference Publish-Release.ps1 and new behavior.
tools/Sign-Binary.ps1 Enforces PowerShell 7+ via #Requires.
tools/Download-Release.ps1 Removes deprecated REST API download script.

Comment thread tools/Publish-Release.ps1
Comment thread tools/Publish-Release.ps1 Outdated
Comment thread tools/Publish-Release.ps1 Outdated
Comment thread tools/Build-Installer.ps1 Outdated
Comment thread tools/Install-BuildTools.Tests.ps1 Outdated
@Belphemur
Copy link
Copy Markdown
Owner

@copilot apply changes based on the comments in this thread and code rabbit comments. Only relevant and comment on the thread and close them.

… release state from channel

- Build-Installer.ps1: focused on signing + Inno Setup compilation only,
  accepts -FinalDir param, invokes ISCC.exe directly via registry lookup
  (no Make-Installer.bat dependency), uses Sign-Binary.ps1 for all signing
- Publish-Release.ps1: handles download-from-draft OR build-from-source,
  HTML docs + asset bundling only when building from source (CI already
  includes them in the release zip), derives InstallerReleaseState from
  Channel (beta→Beta) unless explicitly overridden
- Fix review: separate stderr from gh CLI JSON capture
- Fix review: assert exactly one zip match
- Fix review: use -Recurse in file count validation
- Fix review: AST-based test for GitHub CLI ordering
- Updated tests (37 pass) and README.md

Agent-Logs-Url: https://github.com/Belphemur/SoundSwitch/sessions/5d94634d-af80-473e-a457-7832e43c9def

Co-authored-by: Belphemur <197810+Belphemur@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 16, 2026

@copilot apply changes based on the comments in this thread and code rabbit comments. Only relevant and comment on th...

All review comments addressed in commit 83ef154:

Copilot reviewer fixes:

  • -OutputDir mismatch → removed from Publish-Release.ps1; Build-Installer.ps1 now takes -FinalDir and both use the canonical Final\ path
  • 2>&1 stderr contamination → gh CLI stdout captured separately, stderr passes through to console
  • Multiple zip assertion → throws with helpful message listing matches when >1 found
  • -Recurse in file count → validation now counts files recursively
  • Brittle test → rewrote using AST parsing to find Install-WingetPackage call order

CodeRabbit fixes:

  • InstallerReleaseState now auto-derived from -Channel (betaBeta, releaseRelease) via $PSBoundParameters check
  • -OutputDir wiring resolved by removing it entirely — canonical Final\ always used

Additional streamlining:

  • Build-Installer.ps1 invokes ISCC.exe directly via registry lookup (no Make-Installer.bat)
  • HTML docs + asset bundling only when -BuildFromSource (CI already includes them in release zip)
  • Sign-Binary.ps1 used for all code signing

All 37 tests pass.

Copilot AI changed the title feat(tools): replace Download-Release with Publish-Release orchestrator using GitHub CLI feat(tools): replace Download-Release with Publish-Release orchestrator, streamline Build-Installer Apr 16, 2026
Copilot AI requested a review from Belphemur April 16, 2026 07:31
@Belphemur
Copy link
Copy Markdown
Owner

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Belphemur Belphemur merged commit 785ddb3 into dev Apr 16, 2026
8 checks passed
@Belphemur Belphemur deleted the copilot/add-github-cli-to-setup-script branch April 16, 2026 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants