From 433573693c3359d9b7dde23cbe768112043ef3ca Mon Sep 17 00:00:00 2001 From: randogoth Date: Fri, 9 Oct 2026 10:42:50 +0300 Subject: [PATCH] feat: ship an Inno Setup installer from the windows release job --- .forgejo/workflows/release.yml | 26 +++++++++++++-------- .gitignore | 1 + windows/carrier.iss | 42 ++++++++++++++++++++++++++++++++++ windows/installer.sh | 31 +++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 windows/carrier.iss create mode 100644 windows/installer.sh diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index 95437b8..feb7796 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -77,9 +77,11 @@ jobs: # desktop machine that isn't guaranteed to be on when a tag is pushed, # so it must never gate the release (and must not be gated by it # either). It builds and bundles via windows/bundle.sh - the same - # script windows/setup.sh runs for local one-command builds - then - # appends the zip to the release the linux+flatpak jobs create, with - # the same poll-for-the-release the macos job does. + # script windows/setup.sh runs for local one-command builds - wraps + # the bundle in an Inno Setup installer (windows/installer.sh; Inno + # lives in this runner host's user profile), then appends both the + # portable zip and the setup.exe to the release the linux+flatpak jobs + # create, with the same poll-for-the-release the macos job does. windows: runs-on: windows-x86_64 steps: @@ -102,6 +104,9 @@ jobs: - run: bash windows/bundle.sh working-directory: carrier shell: bash + - run: bash windows/installer.sh + working-directory: carrier + shell: bash - run: | REPO="${{ forge.repository }}" TAG="${{ forge.ref_name }}" @@ -109,8 +114,7 @@ jobs: FORGEJO="${FORGEJO%%/}" TOKEN="${{ forge.token }}" VERSION=$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -1) - FILE="carrier-windows-$VERSION.zip" - NAME="carrier-windows-$VERSION.zip" + FILES="carrier-windows-$VERSION.zip carrier-windows-$VERSION-setup.exe" release_id="" for i in $(seq 1 40); do @@ -128,11 +132,13 @@ jobs: exit 1 fi - curl --retry 5 --fail -sS -X POST \ - -H "Authorization: token $TOKEN" \ - -H "Content-Type: multipart/form-data" \ - -F "attachment=@$FILE" \ - "$FORGEJO/api/v1/repos/$REPO/releases/$release_id/assets?name=$NAME" + for FILE in $FILES; do + curl --retry 5 --fail -sS -X POST \ + -H "Authorization: token $TOKEN" \ + -H "Content-Type: multipart/form-data" \ + -F "attachment=@$FILE" \ + "$FORGEJO/api/v1/repos/$REPO/releases/$release_id/assets?name=$FILE" + done working-directory: carrier shell: bash diff --git a/.gitignore b/.gitignore index 6bc4627..51989d3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ result-* *.db-shm /dist carrier-windows-*.zip +carrier-windows-*-setup.exe diff --git a/windows/carrier.iss b/windows/carrier.iss new file mode 100644 index 0000000..e9fc5cb --- /dev/null +++ b/windows/carrier.iss @@ -0,0 +1,42 @@ +; carrier Windows installer. Packs the same portable bundle windows/ +; bundle.sh produces (dist/) into a classic setup.exe: Program Files, +; Start Menu shortcut, optional desktop icon, Apps & Features uninstall +; entry. Built by windows/installer.sh, which passes /DVersion= from +; Cargo.toml. +; +; Not yet wired into the forgejo release job - deliberately local until +; the experience is signed off. + +#ifndef Version + #error Pass the version: ISCC /DVersion=0.2.0 windows/carrier.iss +#endif + +[Setup] +AppId={{345BADA4-146B-4F57-B7D3-E9FD5D664F4B} +AppName=carrier +AppVersion={#Version} +AppPublisher=randogoth +DefaultDirName={autopf}\carrier +DefaultGroupName=carrier +; Next to the portable zip (paths relative to this script's directory). +OutputDir=.. +OutputBaseFilename=carrier-windows-{#Version}-setup +Compression=lzma2/max +SolidCompression=yes +WizardStyle=modern +ArchitecturesInstallIn64BitMode=x64compatible +UninstallDisplayName=carrier + +[Tasks] +Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:" + +[Files] +Source: "..\dist\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs ignoreversion + +[Icons] +; Shortcut icons come from carrier.exe's embedded .ico resource. +Name: "{group}\carrier"; Filename: "{app}\carrier.exe" +Name: "{autodesktop}\carrier"; Filename: "{app}\carrier.exe"; Tasks: desktopicon + +[Run] +Filename: "{app}\carrier.exe"; Description: "Launch carrier"; Flags: nowait postinstall skipifsilent diff --git a/windows/installer.sh b/windows/installer.sh new file mode 100644 index 0000000..906b8ef --- /dev/null +++ b/windows/installer.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Pack the dist/ bundle into carrier-windows--setup.exe. +# +# Run from the carrier checkout after windows/bundle.sh has produced +# dist/. Requires Inno Setup 7 (per-user install, which its own +# installer's "just me" option produces). +set -euo pipefail + +say() { printf '\n==> %s\n' "$*"; } +die() { printf '\n!! %s\n' "$*" >&2; exit 1; } + +# MSYS2's login shells prune LOCALAPPDATA from the environment, so fall +# back to cygpath (CSIDL 28 = local AppData of the current user). +if [ -n "${LOCALAPPDATA:-}" ]; then + appdata=$(cygpath -u "$LOCALAPPDATA") +else + appdata=$(cygpath -F 28) +fi +ISCC="$appdata/Programs/Inno Setup 7/ISCC.exe" +[ -f "$ISCC" ] || die "Inno Setup not found at $ISCC — install it from https://jrsoftware.org/isdl.php" + +[ -d dist ] || die "no dist/ bundle — run windows/bundle.sh first" + +version=$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -1) + +say "compiling the installer" +# MSYS2_ARG_CONV_EXCL stops MSYS2 mangling /DVersion into a path. +MSYS2_ARG_CONV_EXCL="*" "$ISCC" /DVersion="$version" windows/carrier.iss \ + || die "ISCC failed" + +say "done — carrier-windows-$version-setup.exe (in the checkout root)"