Skip to content

Commit 58eeecb

Browse files
committed
Add win-arm64, linux-arm64 and osx-x64 releases
1 parent 4d66cfd commit 58eeecb

4 files changed

Lines changed: 115 additions & 43 deletions

File tree

.github/workflows/ci.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,12 @@ jobs:
2424

2525
- name: Test
2626
run: dotnet test BasisPM.slnx -c Release --no-build --verbosity normal
27+
28+
# Catch a dependency that stops shipping natives for the non-x64 release targets
29+
# before release day (release.yml cross-packs these same RIDs).
30+
- name: Publish smoke (non-x64 release targets)
31+
run: |
32+
for rid in win-arm64 linux-arm64 osx-x64; do
33+
dotnet publish src/BasisPM.App/BasisPM.App.csproj \
34+
-c Release -r "$rid" --self-contained true -o "/tmp/pub-$rid"
35+
done

.github/workflows/release.yml

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
name: Release
22

3-
# Push a semver tag to build installers for every platform and publish them
4-
# (plus the Velopack update manifest) to a single GitHub Release:
3+
# Push a semver tag to build installers for every platform and architecture and publish them
4+
# (plus the Velopack update manifests) to a single GitHub Release:
55
#
66
# git tag v0.1.0 && git push origin v0.1.0
77
#
8+
# Each OS job publishes and packs all of its architectures — vpk cross-packs with --runtime,
9+
# so no ARM runners are needed. Update channels: the original three (win / linux / osx) keep
10+
# their historical architectures (win-x64 / linux-x64 / osx-arm64) because existing installs
11+
# follow the channel baked into their package; every other architecture uses its RID as the
12+
# channel name (win-arm64, linux-arm64, osx-x64). Never re-point a channel at a different
13+
# architecture — installs on it would update onto binaries they can't run.
14+
#
815
# Code signing is optional and auto-detected: releases are unsigned until the signing
916
# secrets are configured, then the next tag signs automatically. See RELEASING.md.
1017
on:
@@ -23,15 +30,18 @@ jobs:
2330
matrix:
2431
include:
2532
- os: windows-latest
26-
rid: win-x64
27-
mainExe: BasisPM.App.exe
33+
targets: win-x64 win-arm64
34+
legacyRid: win-x64 # ships on the original 'win' channel
2835
- os: ubuntu-latest
29-
rid: linux-x64
30-
mainExe: BasisPM.App
36+
targets: linux-x64 linux-arm64
37+
legacyRid: linux-x64 # ships on the original 'linux' channel
3138
- os: macos-latest
32-
rid: osx-arm64
33-
mainExe: BasisPM.App
39+
targets: osx-arm64 osx-x64
40+
legacyRid: osx-arm64 # ships on the original 'osx' channel
3441
runs-on: ${{ matrix.os }}
42+
env:
43+
TARGETS: ${{ matrix.targets }}
44+
LEGACY_RID: ${{ matrix.legacyRid }}
3545
steps:
3646
- uses: actions/checkout@v4
3747

@@ -67,18 +77,24 @@ jobs:
6777
dotnet tool install -g vpk --version 1.2.0
6878
echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
6979
70-
- name: Publish (self-contained)
80+
- name: Publish (self-contained, per architecture)
7181
shell: bash
72-
run: >
73-
dotnet publish src/BasisPM.App/BasisPM.App.csproj
74-
-c Release -r ${{ matrix.rid }} --self-contained true
75-
-o publish -p:Version=$VERSION
82+
run: |
83+
for RID in $TARGETS; do
84+
dotnet publish src/BasisPM.App/BasisPM.App.csproj \
85+
-c Release -r "$RID" --self-contained true \
86+
-o "publish/$RID" -p:Version=$VERSION
87+
done
7688
77-
- name: Download previous release (enables delta updates)
89+
- name: Download previous releases (enables delta updates)
7890
shell: bash
7991
run: |
80-
vpk download github --repoUrl "https://github.com/${{ github.repository }}" \
81-
--token "${{ secrets.GITHUB_TOKEN }}" || true
92+
for RID in $TARGETS; do
93+
if [ "$RID" = "$LEGACY_RID" ]; then CHANNEL="${RID%%-*}"; else CHANNEL="$RID"; fi
94+
vpk download github --repoUrl "https://github.com/${{ github.repository }}" \
95+
--channel "$CHANNEL" -o "releases/$RID" \
96+
--token "${{ secrets.GITHUB_TOKEN }}" || true
97+
done
8298
8399
# --- macOS code signing (Apple Developer ID + notarization) — only when secrets are set ---
84100
- name: Import Apple certificates (macOS)
@@ -125,16 +141,24 @@ jobs:
125141
run: |
126142
SIGN=()
127143
if [ "$SIGN_WINDOWS" = "true" ]; then SIGN=(--signParams "$WINDOWS_SIGN_PARAMS"); fi
128-
vpk pack -u BasisPackageManager -v "$VERSION" -p publish -e BasisPM.App.exe \
129-
--packTitle "Basis Package Manager" --shortcuts StartMenuRoot \
130-
--icon src/BasisPM.App/Assets/BasisLogo.ico "${SIGN[@]}"
144+
for RID in $TARGETS; do
145+
if [ "$RID" = "$LEGACY_RID" ]; then CHANNEL="${RID%%-*}"; else CHANNEL="$RID"; fi
146+
vpk pack -u BasisPackageManager -v "$VERSION" -p "publish/$RID" -e BasisPM.App.exe \
147+
--runtime "$RID" --channel "$CHANNEL" -o "releases/$RID" \
148+
--packTitle "Basis Package Manager" --shortcuts StartMenuRoot \
149+
--icon src/BasisPM.App/Assets/BasisLogo.ico "${SIGN[@]}"
150+
done
131151
132152
- name: Pack (Linux)
133153
if: ${{ matrix.os == 'ubuntu-latest' }}
134154
shell: bash
135155
run: |
136-
vpk pack -u BasisPackageManager -v "$VERSION" -p publish -e BasisPM.App \
137-
--packTitle "Basis Package Manager"
156+
for RID in $TARGETS; do
157+
if [ "$RID" = "$LEGACY_RID" ]; then CHANNEL="${RID%%-*}"; else CHANNEL="$RID"; fi
158+
vpk pack -u BasisPackageManager -v "$VERSION" -p "publish/$RID" -e BasisPM.App \
159+
--runtime "$RID" --channel "$CHANNEL" -o "releases/$RID" \
160+
--packTitle "Basis Package Manager"
161+
done
138162
139163
- name: Pack (macOS)
140164
if: ${{ matrix.os == 'macos-latest' }}
@@ -150,19 +174,27 @@ jobs:
150174
--notaryProfile velopack-notary \
151175
--signEntitlements build/entitlements.plist)
152176
fi
153-
vpk pack -u BasisPackageManager -v "$VERSION" -p publish -e BasisPM.App \
154-
--packTitle "Basis Package Manager" "${SIGN[@]}"
177+
for RID in $TARGETS; do
178+
if [ "$RID" = "$LEGACY_RID" ]; then CHANNEL="${RID%%-*}"; else CHANNEL="$RID"; fi
179+
vpk pack -u BasisPackageManager -v "$VERSION" -p "publish/$RID" -e BasisPM.App \
180+
--runtime "$RID" --channel "$CHANNEL" -o "releases/$RID" \
181+
--packTitle "Basis Package Manager" "${SIGN[@]}"
182+
done
155183
156184
- name: Upload to GitHub Release
157185
shell: bash
158-
run: >
159-
vpk upload github
160-
--repoUrl "https://github.com/${{ github.repository }}"
161-
--publish
162-
--releaseName "Basis Package Manager $VERSION"
163-
--tag "${{ github.ref_name }}"
164-
--merge
165-
--token "${{ secrets.GITHUB_TOKEN }}"
186+
run: |
187+
for RID in $TARGETS; do
188+
if [ "$RID" = "$LEGACY_RID" ]; then CHANNEL="${RID%%-*}"; else CHANNEL="$RID"; fi
189+
vpk upload github \
190+
--repoUrl "https://github.com/${{ github.repository }}" \
191+
--publish \
192+
--releaseName "Basis Package Manager $VERSION" \
193+
--tag "${{ github.ref_name }}" \
194+
--merge \
195+
--channel "$CHANNEL" -o "releases/$RID" \
196+
--token "${{ secrets.GITHUB_TOKEN }}"
197+
done
166198
167199
# A tag with a prerelease suffix (e.g. v0.2.0-beta.1) is the prerelease channel: mark the
168200
# GitHub release as a pre-release so stable users don't receive it (opt-in via app Settings).

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ Grab the latest installer for your platform from the
1919

2020
| Platform | File | First run |
2121
|----------|------|-----------|
22-
| Windows | `*-win-Setup.exe` | Unsigned for now, so SmartScreen may warn — choose **More info → Run anyway**. |
23-
| Linux | `*.AppImage` | `chmod +x` it, then run. (Needs FUSE, which most distros ship.) |
24-
| macOS | `*.pkg` (Apple Silicon) | Unsigned — **right-click → Open**, then **Open** the first time. |
22+
| Windows | `*-win-Setup.exe` (x64) or `*-win-arm64-Setup.exe` (Windows on ARM) | Unsigned for now, so SmartScreen may warn — choose **More info → Run anyway**. |
23+
| Linux | `BasisPackageManager.AppImage` (x64) or `*-linux-arm64.AppImage` (arm64) | `chmod +x` it, then run. (Needs FUSE, which most distros ship.) |
24+
| macOS | `*-osx-Setup.pkg` (Apple Silicon) or `*-osx-x64-Setup.pkg` (Intel) | Unsigned — **right-click → Open**, then **Open** the first time. |
25+
26+
Not sure which architecture you have? Windows: Settings → System → About → *System type*.
27+
Mac: Apple menu → About This Mac (an *Intel* processor means `osx-x64`). Pick the matching
28+
file — the installer refuses a package built for a different processor.
2529

2630
The app installs per-user (no admin required) and keeps itself up to date — see below.
2731

RELEASING.md

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Releasing Basis Package Manager
22

33
Releases are automated with [Velopack](https://velopack.io). Pushing a semver tag builds
4-
installers for Windows, Linux and macOS, packs them (plus the update manifest) with `vpk`,
5-
and publishes them to a single GitHub Release. The in-app updater reads that release, so a
6-
new version promotes itself to existing users.
4+
installers for Windows, Linux and macOS — each in x64 **and** ARM flavours — packs them
5+
(plus the update manifests) with `vpk`, and publishes them to a single GitHub Release. The
6+
in-app updater reads that release, so a new version promotes itself to existing users.
77

88
## Cut a release
99

@@ -16,16 +16,43 @@ That's it. [`.github/workflows/release.yml`](.github/workflows/release.yml) runs
1616
`windows-latest` / `ubuntu-latest` / `macos-latest` matrix and, when it finishes, the
1717
[Releases page](https://github.com/BasisVR/BasisPackageManager/releases) has:
1818

19-
| Platform | Asset |
20-
|----------|-------|
21-
| Windows | `BasisPackageManager-win-Setup.exe` (+ portable zip) |
22-
| Linux | `BasisPackageManager-linux-*.AppImage` |
23-
| macOS | `BasisPackageManager-osx-*.pkg` |
24-
| (all) | `*-full.nupkg` + `releases.*.json` / `RELEASES` — the update manifest |
19+
| Platform | Architecture | Asset | Update channel |
20+
|----------|--------------|-------|----------------|
21+
| Windows | x64 | `BasisPackageManager-win-Setup.exe` (+ portable zip) | `win` |
22+
| Windows | arm64 | `BasisPackageManager-win-arm64-Setup.exe` (+ portable zip) | `win-arm64` |
23+
| Linux | x64 | `BasisPackageManager.AppImage` | `linux` |
24+
| Linux | arm64 | `BasisPackageManager-linux-arm64.AppImage` | `linux-arm64` |
25+
| macOS | Apple Silicon | `BasisPackageManager-osx-Setup.pkg` (+ portable zip) | `osx` |
26+
| macOS | Intel | `BasisPackageManager-osx-x64-Setup.pkg` (+ portable zip) | `osx-x64` |
27+
| (all) | | `*-full.nupkg` + `releases.*.json` / `RELEASES` — the update manifests | |
2528

2629
**Verify:** install the previous version, publish a higher tag, and confirm the in-app
2730
banner offers the update and one click installs + restarts onto it.
2831

32+
## Architectures
33+
34+
Every architecture that both .NET 9 and Velopack support is built: the three OS jobs
35+
cross-compile and cross-pack their second architecture with `vpk pack --runtime <rid>`,
36+
so no ARM runners are involved. The setup binary checks the machine architecture at
37+
install time, so a user who grabs the wrong file gets a clear refusal, not a broken install.
38+
39+
Update channels are how an install finds the right binaries: the channel name is baked
40+
into each package, and the app updates from that same channel forever. The three original
41+
channels predate multi-arch support and keep their historical meaning — `win` and `linux`
42+
are x64 and `osx` is Apple Silicon — while every newer architecture uses its RID as the
43+
channel name. **Never re-point an existing channel at a different architecture**: every
44+
install on that channel would self-update onto binaries its CPU can't run.
45+
46+
Deliberately not shipped:
47+
48+
- **win-x86** — 32-bit-only Windows machines can't run Unity, so the app is pointless there
49+
(and Windows 10 32-bit is out of support).
50+
- **linux-arm (32-bit, armhf)** — Velopack 1.2.0 ships no 32-bit ARM update/AppImage stubs.
51+
- **riscv64 / loongarch64** — no official .NET runtime, so no self-contained publish.
52+
53+
To add an architecture later, add its RID to `targets` in the release matrix (it gets a
54+
RID-named channel automatically) and to the CI publish-smoke list.
55+
2956
## Versioning
3057

3158
The baseline version lives in [`Directory.Build.props`](Directory.Build.props), but the

0 commit comments

Comments
 (0)