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
|
SolidCompression=yes
|
||||||
WizardStyle=modern
|
WizardStyle=modern
|
||||||
SetupLogging=yes
|
SetupLogging=yes
|
||||||
|
; Optional production code signing. Configure SIGNTOOL_CMD in CI/local env
|
||||||
|
SignTool=byparam $q$zSIGNTOOL_CMD $f$q
|
||||||
DisableWelcomePage=no
|
DisableWelcomePage=no
|
||||||
AllowNoIcons=yes
|
AllowNoIcons=yes
|
||||||
UninstallDisplayIcon={app}\tools\validate-deployment.ps1
|
UninstallDisplayIcon={app}\tools\validate-deployment.ps1
|
||||||
@@ -72,6 +74,11 @@ var
|
|||||||
AfkCheck: TNewCheckBox;
|
AfkCheck: TNewCheckBox;
|
||||||
WindowCheck: TNewCheckBox;
|
WindowCheck: TNewCheckBox;
|
||||||
|
|
||||||
|
procedure ApplyCmdParamIfPresent(const ParamName: string; Edit: TEdit);
|
||||||
|
forward;
|
||||||
|
procedure ApplyCmdBoolIfPresent(const ParamName: string; Check: TNewCheckBox);
|
||||||
|
forward;
|
||||||
|
|
||||||
procedure InitializeWizard;
|
procedure InitializeWizard;
|
||||||
begin
|
begin
|
||||||
ConfigPage := CreateCustomPage(wpSelectTasks,
|
ConfigPage := CreateCustomPage(wpSelectTasks,
|
||||||
@@ -131,6 +138,35 @@ begin
|
|||||||
WindowCheck.Top := ScaleY(224);
|
WindowCheck.Top := ScaleY(224);
|
||||||
WindowCheck.Caption := 'Enable Window watcher';
|
WindowCheck.Caption := 'Enable Window watcher';
|
||||||
WindowCheck.Checked := True;
|
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;
|
end;
|
||||||
|
|
||||||
function NextButtonClick(CurPageID: Integer): Boolean;
|
function NextButtonClick(CurPageID: Integer): Boolean;
|
||||||
|
|||||||
@@ -5,20 +5,47 @@ This directory contains a ready-to-build scaffold for a classic Setup.exe instal
|
|||||||
## Files
|
## Files
|
||||||
- `AWatch-rus-Setup.iss` — Inno Setup script.
|
- `AWatch-rus-Setup.iss` — Inno Setup script.
|
||||||
- `Invoke-AWatchRusInstall.ps1` — wrapper that invokes `deploy-ensemble.ps1` with installer parameters.
|
- `Invoke-AWatchRusInstall.ps1` — wrapper that invokes `deploy-ensemble.ps1` with installer parameters.
|
||||||
|
- `build-installer.ps1` — one-click local build script for Inno Setup.
|
||||||
|
|
||||||
## Build
|
## Local build (one-click)
|
||||||
1. Install Inno Setup 6 on Windows build host.
|
```powershell
|
||||||
2. Open `AWatch-rus-Setup.iss` in Inno Setup Compiler.
|
cd .\windows\installer
|
||||||
3. Build to produce `output/AWatch-rus-Setup.exe`.
|
.\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
|
## Behavior
|
||||||
- Requires Administrator privileges.
|
- Requires Administrator privileges.
|
||||||
- Copies toolkit scripts into `{app}\tools`.
|
- 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 `Invoke-AWatchRusInstall.ps1` -> `deploy-ensemble.ps1`.
|
||||||
- Runs validation at the end.
|
- Runs validation at the end.
|
||||||
- Uninstall step removes `ActivityWatch` scheduled tasks.
|
- 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