Skip to content

Commit 4de7b50

Browse files
Geeven SinghCopilot
andcommitted
Phase 3: release.yml ships Setup.exe + Velopack auto-update channel
The release workflow now builds both the existing single-file Portable lane AND a Velopack-friendly Setup lane, runs vpk pack to produce DiffViewer-Setup.exe + per-release nupkg packages, and uploads every artifact to the GitHub release in one softprops call. Existing DiffViewer.exe users see one new asset on the release page (Setup.exe) and unchanged behavior for the portable download (renamed to DiffViewer-portable.exe for clarity). Workflow pipeline (after tag push): 1. dotnet publish in Portable mode -> 150 MB single-file DiffViewer-portable.exe 2. dotnet tool restore (brings in pinned vpk 1.1.1 from .config/dotnet-tools.json) 3. vpk download github -> pulls prior release nupkgs into releases-dir/ for delta computation. Tolerates 'nothing to download' (first release with Velopack has no prior package) 4. dotnet publish in Setup mode -> non-single-file folder layout in publish-setup/ 5. vpk pack --shortcuts StartMenuRoot -> produces full + (optionally) delta nupkgs + DiffViewer-win-Setup.exe + RELEASES into releases-dir/. The --shortcuts StartMenuRoot flag avoids the Phase 1 spike finding that Velopack 1.1.1's uninstaller does not clean up the Desktop shortcut 6. Copy / rename artifacts into artifacts/ and upload via softprops/action-gh-release Per-release assets a user sees on GitHub after this change: - DiffViewer-portable.exe (single-file, manual updates -- existing behavior, just renamed) - DiffViewer-Setup.exe (Velopack installer, subscribes to in-app auto-updates) - DiffViewer-X.Y.Z-full.nupkg (Velopack consumes -- users don't download directly) - DiffViewer-X.Y.Z-delta.nupkg (Velopack consumes, second release onward) - RELEASES + releases.win.json + assets.win.json (Velopack metadata) Why softprops instead of vpk upload github: we need to upload DiffViewer-portable.exe alongside the Velopack artifacts, so a single softprops upload is simpler than two separate upload steps. The in-app updater reads release assets via the GitHub REST API and is agnostic to which CI tool attached them. README install section now recommends Setup.exe as primary download with the portable option as the no-install alternative. SmartScreen note still applies to both -- code signing comes with Phase 4 once SignPath approves the OSS application submitted in Phase 0. Tests: 1403 passing, unchanged (this PR doesn't touch production code). dotnet build -c Release succeeds with 0 warnings, 0 errors. AI-Local-Session: 4519f6b6-393a-4476-8efa-410e5396c3a9 AI-Cloud-Session: 72f9e474-60ab-42c2-b2a0-28fee827cbbb Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f0a1c3e commit 4de7b50

3 files changed

Lines changed: 131 additions & 9 deletions

File tree

.github/workflows/release.yml

Lines changed: 102 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,117 @@ jobs:
2828
with:
2929
dotnet-version: 8.0.x
3030

31-
- name: Stamp version + publish
31+
- name: Stamp version + publish (Portable + Setup)
3232
shell: pwsh
3333
run: |
3434
$version = $env:GITHUB_REF_NAME.TrimStart('v')
3535
Write-Host "Publishing version: $version"
36+
$fileVersion = $version -replace '-.*$', ''
37+
38+
# Portable: today's single-file 150 MB exe. Built first because
39+
# the existing Definition-of-Done check (publish\DiffViewer.exe
40+
# must exist) targets this layout.
3641
dotnet publish DiffViewer\DiffViewer.csproj `
3742
-c Release `
43+
-p:DiffViewerBuildMode=Portable `
3844
-o publish `
3945
-p:Version=$version `
40-
-p:FileVersion=$($version -replace '-.*$', '') `
46+
-p:FileVersion=$fileVersion `
4147
-p:InformationalVersion=$version
4248
if (-not (Test-Path 'publish\DiffViewer.exe')) {
43-
Write-Error 'publish\DiffViewer.exe not found after publish'
49+
Write-Error 'publish\DiffViewer.exe not found after Portable publish'
50+
exit 1
51+
}
52+
# Rename to a friendlier asset name; the upload step references
53+
# DiffViewer-portable.exe so users see "what is this" cues from
54+
# the filename alone.
55+
New-Item -ItemType Directory -Path 'artifacts' -Force | Out-Null
56+
Copy-Item -Path 'publish\DiffViewer.exe' -Destination 'artifacts\DiffViewer-portable.exe' -Force
57+
58+
# Setup: non-single-file folder layout consumed by vpk pack
59+
# below. Built into a separate output dir so the two publishes
60+
# don't fight over the same files.
61+
dotnet publish DiffViewer\DiffViewer.csproj `
62+
-c Release `
63+
-p:DiffViewerBuildMode=Setup `
64+
-o publish-setup `
65+
-p:Version=$version `
66+
-p:FileVersion=$fileVersion `
67+
-p:InformationalVersion=$version
68+
if (-not (Test-Path 'publish-setup\DiffViewer.exe')) {
69+
Write-Error 'publish-setup\DiffViewer.exe not found after Setup publish'
4470
exit 1
4571
}
4672
73+
- name: Restore dotnet tools (vpk)
74+
run: dotnet tool restore
75+
76+
- name: Download prior release packages (for delta)
77+
# First release with Velopack support has no prior nupkgs to
78+
# download; vpk download exits non-zero in that case (and any
79+
# other transient failure). Tolerate that — vpk pack will then
80+
# produce a full-only release, which is exactly the right
81+
# outcome for the first Setup release.
82+
continue-on-error: true
83+
env:
84+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
85+
shell: pwsh
86+
run: |
87+
New-Item -ItemType Directory -Path 'releases-dir' -Force | Out-Null
88+
dotnet vpk download github `
89+
--repoUrl https://github.com/${{ github.repository }} `
90+
--token $env:GITHUB_TOKEN `
91+
--outputDir releases-dir
92+
93+
- name: Pack Velopack release (vpk pack)
94+
shell: pwsh
95+
run: |
96+
$version = $env:GITHUB_REF_NAME.TrimStart('v')
97+
# --shortcuts StartMenuRoot (not the default Desktop+StartMenu)
98+
# avoids the Phase 1 spike finding that Velopack 1.1.1's
99+
# uninstall does not clean up the Desktop shortcut.
100+
dotnet vpk pack `
101+
--packId DiffViewer `
102+
--packVersion $version `
103+
--packDir publish-setup `
104+
--mainExe DiffViewer.exe `
105+
--outputDir releases-dir `
106+
--shortcuts StartMenuRoot `
107+
--packTitle DiffViewer `
108+
--packAuthors "Geeven Singh"
109+
# Sanity-check the expected artifacts are present. The delta
110+
# nupkg only exists from the second release onward (no prior
111+
# full to diff against on the first one), so its absence is
112+
# not an error.
113+
if (-not (Test-Path "releases-dir\DiffViewer-win-Setup.exe")) {
114+
Write-Error 'DiffViewer-win-Setup.exe missing after vpk pack'
115+
exit 1
116+
}
117+
if (-not (Test-Path "releases-dir\DiffViewer-$version-full.nupkg")) {
118+
Write-Error "DiffViewer-$version-full.nupkg missing after vpk pack"
119+
exit 1
120+
}
121+
# Copy / rename for the upload step. We want
122+
# DiffViewer-Setup.exe (no win-* infix) as the user-facing
123+
# download name.
124+
Copy-Item -Path "releases-dir\DiffViewer-win-Setup.exe" -Destination 'artifacts\DiffViewer-Setup.exe' -Force
125+
Copy-Item -Path "releases-dir\DiffViewer-$version-full.nupkg" -Destination "artifacts\DiffViewer-$version-full.nupkg" -Force
126+
# The delta nupkg is optional (absent on first release).
127+
$delta = Get-ChildItem -Path "releases-dir\DiffViewer-$version-delta.nupkg" -ErrorAction SilentlyContinue
128+
if ($delta) {
129+
Copy-Item -Path $delta.FullName -Destination "artifacts\DiffViewer-$version-delta.nupkg" -Force
130+
}
131+
# RELEASES + Velopack metadata files are required for the
132+
# auto-updater to discover available packages on the
133+
# GitHub release page.
134+
Copy-Item -Path 'releases-dir\RELEASES' -Destination 'artifacts\RELEASES' -Force
135+
if (Test-Path 'releases-dir\releases.win.json') {
136+
Copy-Item -Path 'releases-dir\releases.win.json' -Destination 'artifacts\releases.win.json' -Force
137+
}
138+
if (Test-Path 'releases-dir\assets.win.json') {
139+
Copy-Item -Path 'releases-dir\assets.win.json' -Destination 'artifacts\assets.win.json' -Force
140+
}
141+
47142
- name: Extract CHANGELOG section
48143
shell: pwsh
49144
run: |
@@ -83,6 +178,9 @@ jobs:
83178
- name: Publish GitHub Release
84179
uses: softprops/action-gh-release@v3
85180
with:
86-
files: publish/DiffViewer.exe
181+
# Upload every asset from artifacts/ — Setup.exe + portable.exe
182+
# are the user-facing downloads; the *.nupkg files + RELEASES +
183+
# *.json files are what the in-app updater consumes silently.
184+
files: artifacts/*
87185
body: ${{ env.RELEASE_BODY }}
88186
fail_on_unmatched_files: true

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ body. Keep section headings exact and write notes in Markdown.
1414

1515
### Added
1616

17+
- **`DiffViewer-Setup.exe` installer alongside the existing portable
18+
download.** The new installer puts DiffViewer under
19+
`%LocalAppData%\DiffViewer\` with a Start Menu shortcut and
20+
subscribes to the in-app auto-update channel. No admin / UAC
21+
prompt. Per-release artifacts on GitHub now include the Setup
22+
installer plus Velopack delta packages, so subsequent updates are
23+
typically small downloads (single-digit MB) instead of full ~70 MB
24+
redownloads. Existing portable users are unaffected — the portable
25+
exe still ships, still self-extracts on first run, and still
26+
requires manual re-download for updates.
1727
- **Auto-update banner gets a "Skip this version" button.** Persists
1828
the skipped version into `settings.json` so future checks for the
1929
same version stay quiet across launches. Detection of a newer

README.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,25 @@ may take a few extra seconds. Subsequent launches are fast.
196196

197197
## Install
198198

199-
1. Go to the [Releases page] and download `DiffViewer.exe` from the latest
200-
release.
201-
2. Double-click to launch. Windows SmartScreen may show a warning for the
202-
unsigned binary; click **More info****Run anyway**. The release exe
203-
is not currently code-signed.
199+
Two download options on the [Releases page]:
200+
201+
1. **`DiffViewer-Setup.exe` (recommended).** Installs to
202+
`%LocalAppData%\DiffViewer\`, adds a Start Menu shortcut, and
203+
subscribes to **in-app auto-updates** (notification banner when a
204+
new release ships; user opts in or out via Settings → Updates).
205+
No admin / UAC prompt — Velopack installs per-user.
206+
2. **`DiffViewer-portable.exe`.** Single-file ~150 MB exe; double-click
207+
to run, no install. Updates are **manual** — re-download from the
208+
Releases page when a new version ships. Good for thumb-drive use,
209+
restricted environments, or "just try it for five minutes."
210+
211+
Both options are functionally identical app-side; the only difference
212+
is the install / update lifecycle.
213+
214+
Windows SmartScreen may show a warning the first time you launch
215+
either binary — click **More info****Run anyway**. Neither
216+
artifact is currently code-signed (see
217+
[CODE_SIGNING_POLICY.md](CODE_SIGNING_POLICY.md)).
204218

205219
## Build from source
206220

0 commit comments

Comments
 (0)