From aba62a58c285fa3a3b47e06756ff630fbba7b08f Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Mon, 5 Oct 2026 13:55:05 +0800 Subject: [PATCH] feat(packaging): build a windows installer with inno setup --- .github/workflows/build.yml | 1 + packaging/package.sh | 22 +++++------ packaging/windows/ykanban.iss | 69 +++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 packaging/windows/ykanban.iss diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 738a0c8..424b4de 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,7 @@ # Manual-only release build (PLAN ยง7.2): no push or pull_request trigger. # Each RID job runs build -> test -> publish/pack -> upload; a failing step # skips the rest of that job, so a RID whose tests fail produces no artifact. +# win-x64 packs an Inno Setup installer; the other RIDs keep zip/tar.gz archives. # No GitHub Release is created. name: Build diff --git a/packaging/package.sh b/packaging/package.sh index 5044319..17f7d28 100755 --- a/packaging/package.sh +++ b/packaging/package.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Packs one published RID into a release archive. +# Packs one published RID into a release artifact. # # packaging/package.sh # -# win-x64 -> YKanBan--win-x64.zip (folder YKanBan--win-x64/) +# win-x64 -> YKanBan--win-x64-setup.exe (Inno Setup installer) # linux-x64 -> YKanBan--linux-x64.tar.gz (folder YKanBan--linux-x64/) # osx-* -> YKanBan--.tar.gz (YKanBan.app bundle, ad-hoc signed when possible) # @@ -27,16 +27,14 @@ trap 'rm -rf "$staging"' EXIT case "$rid" in win-*) - cp -R "$publish_dir" "$staging/$name" - rm -f "$output_dir/$name.zip" - # 7-Zip ships on the Windows runners and writes '/' entry separators; - # Windows PowerShell 5.1's Compress-Archive writes '\', which breaks - # extraction outside Windows. - if ! command -v 7z > /dev/null 2>&1; then - echo "7z not found" >&2 - exit 1 - fi - (cd "$staging" && 7z a -tzip -bso0 -bsp0 "$output_dir/$name.zip" "$name") + # The Windows runners ship Inno Setup with ISCC on PATH. Git Bash rewrites + # arguments that start with "/" into POSIX paths, so disable the conversion + # and hand ISCC native Windows paths via cygpath. + MSYS_NO_PATHCONV=1 iscc \ + "/DMyAppVersion=${version}" \ + "/DPublishDir=$(cygpath -w "${publish_dir}")" \ + "/DOutputDir=$(cygpath -w "${output_dir}")" \ + "$(cygpath -w "${script_dir}/windows/ykanban.iss")" ;; linux-*) cp -R "$publish_dir" "$staging/$name" diff --git a/packaging/windows/ykanban.iss b/packaging/windows/ykanban.iss new file mode 100644 index 0000000..3c63fe1 --- /dev/null +++ b/packaging/windows/ykanban.iss @@ -0,0 +1,69 @@ +; Inno Setup script for the Windows installer. +; +; ISCC.exe /DMyAppVersion= /DPublishDir= /DOutputDir= packaging/windows/ykanban.iss +; +; The setup UI is English only: the single [Languages] entry uses the stock +; Default.isl, so no language dialog is shown. The install scope is chosen at +; startup (all users vs current user); HKA routes the context-menu registry +; entries to HKLM or HKCU accordingly, and {autopf} picks the matching +; program folder. + +#ifndef MyAppVersion +#define MyAppVersion "0.0.0" +#endif +#ifndef PublishDir +#define PublishDir "publish/win-x64" +#endif +#ifndef OutputDir +#define OutputDir "dist" +#endif + +#define MyAppName "YKanBan" +#define MyAppExeName "YKanBan.exe" + +[Setup] +AppId={{80A9F6AC-F6EB-48A8-A28C-EE7B0D6A6E81} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +DefaultDirName={autopf}\{#MyAppName} +DisableProgramGroupPage=yes +PrivilegesRequired=admin +PrivilegesRequiredOverridesAllowed=dialog +OutputDir={#OutputDir} +OutputBaseFilename=YKanBan-{#MyAppVersion}-win-x64-setup +SetupIconFile=..\..\YKanBan\Assets\ykanban.ico +LicenseFile=..\..\LICENSE +UninstallDisplayIcon={app}\{#MyAppExeName} +Compression=lzma2/max +SolidCompression=yes +WizardStyle=modern +ArchitecturesInstallIn64BitMode=x64compatible + +[Languages] +Name: "en"; MessagesFile: "compiler:Default.isl" + +[CustomMessages] +ContextMenuTask=Add "Open in YKanBan" to the folder context menu +OpenInYKanBan=Open in YKanBan + +[Tasks] +Name: "foldercontextmenu"; Description: "{cm:ContextMenuTask}" + +[Files] +Source: "{#PublishDir}\*"; DestDir: "{app}"; Flags: recursesubdirs ignoreversion + +[Registry] +; Folder context menu: right-clicking a folder opens it in YKanBan (%1). +Root: HKA; Subkey: "Software\Classes\Directory\shell\YKanBan"; ValueType: string; ValueName: ""; ValueData: "{cm:OpenInYKanBan}"; Flags: uninsdeletekey; Tasks: foldercontextmenu +Root: HKA; Subkey: "Software\Classes\Directory\shell\YKanBan"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletekey; Tasks: foldercontextmenu +Root: HKA; Subkey: "Software\Classes\Directory\shell\YKanBan\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey; Tasks: foldercontextmenu +; Folder background: right-clicking the empty area of a folder (%V). +Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\YKanBan"; ValueType: string; ValueName: ""; ValueData: "{cm:OpenInYKanBan}"; Flags: uninsdeletekey; Tasks: foldercontextmenu +Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\YKanBan"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletekey; Tasks: foldercontextmenu +Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\YKanBan\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%V"""; Flags: uninsdeletekey; Tasks: foldercontextmenu + +[Icons] +Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#MyAppName}}"; Flags: nowait postinstall skipifsilent