Files
mikusays-c/.github/workflows/package-win.yml
T

289 lines
9.9 KiB
YAML

name: Windows Installer Packaging (Inno Setup)
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag_name:
description: 'Release Tag (e.g., v1.0.0). Leave empty to use "latest".'
required: false
default: ''
jobs:
package-windows:
runs-on: windows-latest
permissions:
contents: write
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Inno Setup
run: choco install innosetup
- name: Get Version from Cargo.toml
id: get_version
shell: pwsh
run: |
$VersionLine = Get-Content Cargo.toml | Select-String '^version\s*=\s*"(.*)"'
if ($VersionLine.Matches.Success) {
$Version = $VersionLine.Matches.Groups[1].Value
Write-Host "Found version in Cargo.toml: $Version"
"version=$Version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
} else {
Write-Error "Could not find version in Cargo.toml"
exit 1
}
- name: Determine Release Tag
id: get_tag
shell: pwsh
env:
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
$TAG = "${{ inputs.tag_name }}"
if (-not $TAG) { $TAG = "${{ github.event.release.tag_name }}" }
if (-not $TAG) {
Write-Host "No tag provided, fetching latest release..."
$TAG = $(gh release view --json tagName --jq .tagName)
}
if (-not $TAG) {
Write-Error "Could not determine release tag."
exit 1
}
Write-Host "Using Tag: $TAG"
"tag=$TAG" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
- name: Download Release Assets
env:
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
$TAG = "${{ steps.get_tag.outputs.tag }}"
$Version = "${{ steps.get_version.outputs.version }}"
# Download the raw binaries
gh release download $TAG -p "mikusays-windows-x86_64-$Version.exe"
gh release download $TAG -p "mikusays-windows-aarch64-$Version.exe"
# Rename to standard names for the Inno Script
mv "mikusays-windows-x86_64-$Version.exe" "mikusays-windows-x86_64.exe"
mv "mikusays-windows-aarch64-$Version.exe" "mikusays-windows-aarch64.exe"
- name: Generate Inno Setup Script
shell: pwsh
run: |
$Version = "${{ steps.get_version.outputs.version }}"
$InstallerName = "mikusays-windows-inst-any-$Version"
Write-Host "Generating Inno Setup script for version: $Version"
$issContent = @'
[Setup]
AppName=Mikusays
AppVersion=__VERSION__
AppCopyright=2025 xxanqw
AppPublisher=xxanqw
AppPublisherURL=https://xxanqw.pp.ua/
AppSupportURL=https://github.com/xxanqw/mikusays/issues
AppUpdatesURL=https://github.com/xxanqw/mikusays/releases/latest
AppId={{A0ED7972-D08B-48CB-8331-729D1001FF16}
DefaultDirName={localappdata}\Programs\mikusays
DefaultGroupName=Mikusays
DisableProgramGroupPage=yes
PrivilegesRequired=lowest
; -- Output Configuration --
OutputBaseFilename=__OUTFILE__
OutputDir=.
Compression=lzma2/ultra64
SolidCompression=yes
; -- Architecture Configuration --
ArchitecturesInstallIn64BitMode=x64compatible arm64
ArchitecturesAllowed=x64compatible arm64
ChangesEnvironment=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Files]
Source: "mikusays-windows-x86_64.exe"; DestDir: "{app}"; DestName: "mikusays.exe"; Check: IsX64; Flags: ignoreversion
Source: "mikusays-windows-aarch64.exe"; DestDir: "{app}"; DestName: "mikusays.exe"; Check: IsARM64; Flags: ignoreversion
[Icons]
Name: "{group}\Mikusays"; Filename: "{app}\mikusays.exe"
Name: "{group}\Uninstall Mikusays"; Filename: "{uninstallexe}"
[Code]
function IsX64: Boolean;
begin
Result := Is64BitInstallMode and (ProcessorArchitecture = paX64);
end;
function IsARM64: Boolean;
begin
Result := Is64BitInstallMode and (ProcessorArchitecture = paARM64);
end;
const
VC_REDIST_X64_URL = 'https://aka.ms/vs/17/release/vc_redist.x64.exe';
VC_REDIST_ARM64_URL = 'https://aka.ms/vs/17/release/vc_redist.arm64.exe';
var
DownloadPage: TDownloadWizardPage;
procedure InitializeWizard;
begin
DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil);
end;
function NextButtonClick(CurPageID: Integer): Boolean;
var
RedistUrl, RedistFile: String;
ResultCode: Integer;
begin
Result := True;
if CurPageID = wpReady then
begin
DownloadPage.Clear;
if IsARM64 then
RedistUrl := VC_REDIST_ARM64_URL
else
RedistUrl := VC_REDIST_X64_URL;
RedistFile := 'vc_redist.exe';
DownloadPage.Add(RedistUrl, RedistFile, '');
DownloadPage.Show;
try
try
DownloadPage.Download;
Exec(ExpandConstant('{tmp}\' + RedistFile), '/install /quiet /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
except
if MsgBox('Download of Visual C++ Redistributable failed: ' + GetExceptionMessage + #13#10#13#10 + 'Do you want to continue installation anyway?', mbError, MB_YESNO) = IDNO then
Result := False;
end;
finally
DownloadPage.Hide;
end;
end;
end;
function NeedsAddPath(Param: string): boolean;
var
OrigPath: string;
begin
if not RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', OrigPath) then
begin
Result := True;
exit;
end;
Result := Pos(';' + Param + ';', ';' + OrigPath + ';') = 0;
end;
procedure RemovePath(Param: string);
var
OrigPath: string;
P: Integer;
begin
if not RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', OrigPath) then
exit;
P := Pos(';' + Param + ';', OrigPath);
if P > 0 then
begin
Delete(OrigPath, P + 1, Length(Param) + 1);
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', OrigPath);
exit;
end;
if Pos(Param + ';', OrigPath) = 1 then
begin
Delete(OrigPath, 1, Length(Param) + 1);
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', OrigPath);
exit;
end;
P := Pos(';' + Param, OrigPath);
if (P > 0) and (P = Length(OrigPath) - Length(Param)) then
begin
Delete(OrigPath, P, Length(Param) + 1);
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', OrigPath);
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
OrigPath: string;
begin
if CurStep = ssPostInstall then
begin
if NeedsAddPath(ExpandConstant('{app}')) then
begin
if RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', OrigPath) then
begin
if OrigPath = '' then
OrigPath := ExpandConstant('{app}')
else
OrigPath := OrigPath + ';' + ExpandConstant('{app}');
end
else
OrigPath := ExpandConstant('{app}');
RegWriteExpandStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', OrigPath);
end;
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usUninstall then
begin
RemovePath(ExpandConstant('{app}'));
end;
end;
'@
$issContent = $issContent.Replace("__VERSION__", $Version)
$issContent = $issContent.Replace("__OUTFILE__", $InstallerName)
Set-Content -Path "installer.iss" -Value $issContent
- name: List workspace contents for debug
shell: pwsh
run: |
Write-Host "-- Workspace Contents --"
Get-ChildItem -File | ForEach-Object { Write-Host $_.Name }
- name: Compile Installer
shell: cmd
run: '"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" installer.iss'
- name: Upload Installer to Release
env:
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
$TAG = "${{ steps.get_tag.outputs.tag }}"
$Version = "${{ steps.get_version.outputs.version }}"
# With OutputDir=. the file is in root
$UploadFile = "mikusays-windows-inst-any-$Version.exe"
if (-not (Test-Path $UploadFile)) {
Write-Error "Could not find compiled installer at $UploadFile"
Get-ChildItem
exit 1
}
gh release upload $TAG $UploadFile --clobber