Add installer build script, CI workflow, silent params and optional signing
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
name: Build Windows installer
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- 'windows/**'
|
||||
- '.github/workflows/build-installer.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
SIGNTOOL_CMD: ${{ secrets.SIGNTOOL_CMD }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Inno
|
||||
shell: pwsh
|
||||
run: |
|
||||
choco install innosetup --no-progress -y
|
||||
|
||||
- name: Build installer
|
||||
shell: pwsh
|
||||
run: |
|
||||
./windows/installer/build-installer.ps1
|
||||
|
||||
- name: Upload Setup.exe artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: awatch-rus-setup
|
||||
path: windows/installer/output/*.exe
|
||||
if-no-files-found: error
|
||||
@@ -23,6 +23,8 @@ Compression=lzma2
|
||||
SolidCompression=yes
|
||||
WizardStyle=modern
|
||||
SetupLogging=yes
|
||||
; Optional production code signing. Configure SIGNTOOL_CMD in CI/local env
|
||||
SignTool=byparam $q$zSIGNTOOL_CMD $f$q
|
||||
DisableWelcomePage=no
|
||||
AllowNoIcons=yes
|
||||
UninstallDisplayIcon={app}\tools\validate-deployment.ps1
|
||||
@@ -72,6 +74,11 @@ var
|
||||
AfkCheck: TNewCheckBox;
|
||||
WindowCheck: TNewCheckBox;
|
||||
|
||||
procedure ApplyCmdParamIfPresent(const ParamName: string; Edit: TEdit);
|
||||
forward;
|
||||
procedure ApplyCmdBoolIfPresent(const ParamName: string; Check: TNewCheckBox);
|
||||
forward;
|
||||
|
||||
procedure InitializeWizard;
|
||||
begin
|
||||
ConfigPage := CreateCustomPage(wpSelectTasks,
|
||||
@@ -131,6 +138,35 @@ begin
|
||||
WindowCheck.Top := ScaleY(224);
|
||||
WindowCheck.Caption := 'Enable Window watcher';
|
||||
WindowCheck.Checked := True;
|
||||
ApplyCmdParamIfPresent('SERVERHOST', ServerHostEdit);
|
||||
ApplyCmdParamIfPresent('SERVERPORT', ServerPortEdit);
|
||||
ApplyCmdParamIfPresent('DOMAIN', DomainEdit);
|
||||
ApplyCmdParamIfPresent('USERS', UsersEdit);
|
||||
ApplyCmdParamIfPresent('INSTALLROOT', InstallRootEdit);
|
||||
ApplyCmdParamIfPresent('STATEROOT', StateRootEdit);
|
||||
ApplyCmdBoolIfPresent('AFKENABLED', AfkCheck);
|
||||
ApplyCmdBoolIfPresent('WINDOWENABLED', WindowCheck);
|
||||
end;
|
||||
|
||||
|
||||
procedure ApplyCmdParamIfPresent(const ParamName: string; Edit: TEdit);
|
||||
var
|
||||
V: string;
|
||||
begin
|
||||
V := ExpandConstant('{param:' + ParamName + '|}');
|
||||
if Trim(V) <> '' then
|
||||
Edit.Text := V;
|
||||
end;
|
||||
|
||||
procedure ApplyCmdBoolIfPresent(const ParamName: string; Check: TNewCheckBox);
|
||||
var
|
||||
V: string;
|
||||
begin
|
||||
V := Lowercase(Trim(ExpandConstant('{param:' + ParamName + '|}')));
|
||||
if (V = '1') or (V = 'true') or (V = 'yes') then
|
||||
Check.Checked := True
|
||||
else if (V = '0') or (V = 'false') or (V = 'no') then
|
||||
Check.Checked := False;
|
||||
end;
|
||||
|
||||
function NextButtonClick(CurPageID: Integer): Boolean;
|
||||
|
||||
@@ -5,20 +5,47 @@ This directory contains a ready-to-build scaffold for a classic Setup.exe instal
|
||||
## Files
|
||||
- `AWatch-rus-Setup.iss` — Inno Setup script.
|
||||
- `Invoke-AWatchRusInstall.ps1` — wrapper that invokes `deploy-ensemble.ps1` with installer parameters.
|
||||
- `build-installer.ps1` — one-click local build script for Inno Setup.
|
||||
|
||||
## Build
|
||||
1. Install Inno Setup 6 on Windows build host.
|
||||
2. Open `AWatch-rus-Setup.iss` in Inno Setup Compiler.
|
||||
3. Build to produce `output/AWatch-rus-Setup.exe`.
|
||||
## Local build (one-click)
|
||||
```powershell
|
||||
cd .\windows\installer
|
||||
.\build-installer.ps1
|
||||
```
|
||||
|
||||
Optional custom path to compiler:
|
||||
```powershell
|
||||
.\build-installer.ps1 -IsccPath 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe'
|
||||
```
|
||||
|
||||
## Silent deployment parameters (SCCM/Intune/GPO)
|
||||
Installer supports command-line parameters:
|
||||
- `/SERVERHOST=aw.example.local`
|
||||
- `/SERVERPORT=5600`
|
||||
- `/DOMAIN=CONTOSO`
|
||||
- `/USERS=user1,user2`
|
||||
- `/INSTALLROOT="C:\Program Files\ActivityWatch"`
|
||||
- `/STATEROOT="C:\ProgramData\ActivityWatch"`
|
||||
- `/AFKENABLED=true|false`
|
||||
- `/WINDOWENABLED=true|false`
|
||||
|
||||
Example:
|
||||
```powershell
|
||||
AWatch-rus-Setup.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART `
|
||||
/SERVERHOST=aw.example.local /SERVERPORT=5600 /DOMAIN=CONTOSO `
|
||||
/USERS=user1,user2 /AFKENABLED=true /WINDOWENABLED=true
|
||||
```
|
||||
|
||||
## CI build and optional code signing
|
||||
A GitHub Actions workflow builds the installer on `windows-latest` and uploads `Setup.exe` as an artifact.
|
||||
|
||||
Optional production signing is enabled via `SignTool=byparam ...` in `.iss` and expects `SIGNTOOL_CMD`.
|
||||
Set repository secret `SIGNTOOL_CMD` with your full sign command template.
|
||||
|
||||
## Behavior
|
||||
- Requires Administrator privileges.
|
||||
- Copies toolkit scripts into `{app}\tools`.
|
||||
- Collects server/domain/users parameters via wizard page.
|
||||
- Collects server/domain/users parameters via wizard page (or command-line silent params).
|
||||
- Runs `Invoke-AWatchRusInstall.ps1` -> `deploy-ensemble.ps1`.
|
||||
- Runs validation at the end.
|
||||
- Uninstall step removes `ActivityWatch` scheduled tasks.
|
||||
|
||||
## Notes
|
||||
- Default publisher URL is a placeholder (`https://example.local/awatch-rus`), replace it.
|
||||
- For silent enterprise rollout, extend `[Run]` and parse `/SERVERHOST=...` style custom switches if needed.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$IsccPath = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe",
|
||||
[string]$IssPath = "$PSScriptRoot\AWatch-rus-Setup.iss",
|
||||
[switch]$SkipClean
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not (Test-Path -LiteralPath $IssPath)) {
|
||||
throw "ISS file not found: $IssPath"
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $IsccPath)) {
|
||||
throw "ISCC.exe not found: $IsccPath"
|
||||
}
|
||||
|
||||
$outputDir = Join-Path $PSScriptRoot 'output'
|
||||
if ((-not $SkipClean) -and (Test-Path -LiteralPath $outputDir)) {
|
||||
Remove-Item -LiteralPath $outputDir -Recurse -Force
|
||||
}
|
||||
|
||||
Write-Host "Building installer from: $IssPath"
|
||||
& $IsccPath $IssPath
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Inno Setup build failed with code: $LASTEXITCODE"
|
||||
}
|
||||
|
||||
$artifact = Get-ChildItem -Path $outputDir -Filter '*.exe' -File | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
if (-not $artifact) {
|
||||
throw "Build finished but no .exe artifact found in: $outputDir"
|
||||
}
|
||||
|
||||
Write-Host "Installer artifact: $($artifact.FullName)"
|
||||
Reference in New Issue
Block a user