Merge pull request #3551 from stgraber/main
Some checks are pending
Tests / Code (oldstable) (push) Waiting to run
Tests / Code (stable) (push) Waiting to run
Tests / Code (tip) (push) Waiting to run
Tests / System (btrfs, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (btrfs, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (ceph, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (ceph, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, standalone_container) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, standalone_core) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, standalone_network) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, cluster) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, standalone_container) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, standalone_core) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, standalone_network) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, standalone_storage) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, standalone_container) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, standalone_core) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, standalone_network) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, cluster) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, standalone_container) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, standalone_core) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, standalone_network) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, standalone_storage) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, standalone_container) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, standalone_core) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, standalone_network) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, cluster) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, standalone_container) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, standalone_core) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, standalone_network) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, standalone_storage) (push) Waiting to run
Tests / System (linstor, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (linstor, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (lvm, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (lvm, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (random, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (random, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (zfs, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (zfs, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / Client (oldstable, macos-latest) (push) Waiting to run
Tests / Client (oldstable, ubuntu-latest) (push) Waiting to run
Tests / Client (oldstable, windows-latest) (push) Waiting to run
Tests / Client (stable, macos-latest) (push) Waiting to run
Tests / Client (stable, ubuntu-latest) (push) Waiting to run
Tests / Client (stable, windows-latest) (push) Waiting to run
Tests / Documentation (push) Waiting to run

github: Build Windows and MacOS native installers.
This commit is contained in:
Stéphane Graber 2026-06-27 16:43:11 -04:00 committed by GitHub
commit 2ee187f542
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 226 additions and 11 deletions

30
.github/packaging/macos/build.sh vendored Executable file
View File

@ -0,0 +1,30 @@
#!/bin/bash
# Build a universal Incus client PKG installer.
set -eu
VERSION="${VERSION:?VERSION must be set}"
here="$(dirname "$0")"
out="installers"
root="pkgroot"
res="pkgresources"
mkdir -p "${out}" "${root}/usr/local/bin" "${res}"
cp COPYING "${res}/LICENSE.txt"
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o incus.amd64 ./cmd/incus
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o incus.arm64 ./cmd/incus
lipo -create -output "${root}/usr/local/bin/incus" incus.amd64 incus.arm64
chmod 0755 "${root}/usr/local/bin/incus"
pkgbuild --root "${root}" \
--identifier org.linuxcontainers.incus \
--version "${VERSION}" \
--install-location / \
incus-component.pkg
productbuild --distribution "${here}/distribution.xml" \
--package-path . \
--resources "${res}" \
"${out}/incus.macos.pkg"
rm -rf incus.amd64 incus.arm64 incus-component.pkg "${root}" "${res}"

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<installer-gui-script minSpecVersion="2">
<title>Incus</title>
<license file="LICENSE.txt" />
<options customize="never" require-scripts="false" hostArchitectures="x86_64,arm64" />
<choices-outline>
<line choice="default">
<line choice="org.linuxcontainers.incus" />
</line>
</choices-outline>
<choice id="default" />
<choice id="org.linuxcontainers.incus" visible="false">
<pkg-ref id="org.linuxcontainers.incus" />
</choice>
<pkg-ref id="org.linuxcontainers.incus" version="0" onConclusion="none">incus-component.pkg</pkg-ref>
</installer-gui-script>

30
.github/packaging/windows/build.sh vendored Executable file
View File

@ -0,0 +1,30 @@
#!/bin/bash
# Build per-architecture Incus client MSI installers.
set -eu
VERSION="${VERSION:?VERSION must be set}"
here="$(dirname "$0")"
out="installers"
mkdir -p "${out}"
bash "${here}/make-license-rtf.sh" COPYING "${out}/license.rtf"
build_one() {
goarch="$1"
wixarch="$2"
name="$3"
CGO_ENABLED=0 GOOS=windows GOARCH="${goarch}" go build -o "${out}/incus.exe" ./cmd/incus
wix build -arch "${wixarch}" \
-ext WixToolset.UI.wixext \
-d Version="${VERSION}" \
-d BinPath="${out}/incus.exe" \
-d LicenseRtf="${out}/license.rtf" \
-o "${out}/incus.windows.${name}.msi" \
"${here}/incus.wxs"
}
build_one amd64 x64 x86_64
build_one arm64 arm64 aarch64
rm -f "${out}/incus.exe" "${out}/license.rtf"

33
.github/packaging/windows/incus.wxs vendored Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
<Package Name="Incus"
Manufacturer="Linux Containers"
Version="$(var.Version)"
UpgradeCode="7E2B5C1D-4A3F-4B8E-9C6D-1F0A2B3C4D5E"
Scope="perMachine">
<MajorUpgrade DowngradeErrorMessage="A newer version of Incus is already installed." />
<MediaTemplate EmbedCab="yes" />
<StandardDirectory Id="ProgramFiles6432Folder">
<Directory Id="INSTALLFOLDER" Name="Incus">
<Directory Id="BINFOLDER" Name="bin" />
</Directory>
</StandardDirectory>
<ComponentGroup Id="ProductComponents" Directory="BINFOLDER">
<Component Id="IncusExe" Guid="*">
<File Id="IncusExe" Name="incus.exe" Source="$(var.BinPath)" KeyPath="yes" />
<Environment Id="UpdatePath" Name="PATH" Value="[BINFOLDER]"
Permanent="no" Part="last" Action="set" System="yes" />
</Component>
</ComponentGroup>
<Feature Id="Main">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<ui:WixUI Id="WixUI_Minimal" />
<WixVariable Id="WixUILicenseRtf" Value="$(var.LicenseRtf)" />
</Package>
</Wix>

12
.github/packaging/windows/make-license-rtf.sh vendored Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
# Wrap a plain-text license into a minimal RTF for the WiX license dialog.
set -eu
src="$1"
dst="$2"
{
printf '{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0 Courier New;}}\\fs16\n'
sed -e 's/\\/\\\\/g' -e 's/{/\\{/g' -e 's/}/\\}/g' -e 's/$/\\par/' "$src"
printf '}\n'
} > "$dst"

View File

@ -11,9 +11,96 @@ permissions:
attestations: write
jobs:
version:
name: Format version
runs-on: ubuntu-latest
outputs:
display: ${{ steps.version.outputs.display }}
full: ${{ steps.version.outputs.full }}
steps:
- name: Format version
id: version
run: |
raw="${GITHUB_REF_NAME#v}"
IFS='.' read -r major minor patch <<< "$raw"
echo "full=${major}.${minor}.${patch}" >> $GITHUB_OUTPUT
if [ "${patch}" = "0" ]; then
echo "display=${major}.${minor}" >> $GITHUB_OUTPUT
else
echo "display=${major}.${minor}.${patch}" >> $GITHUB_OUTPUT
fi
build-msi:
name: Build Windows installer
runs-on: windows-latest
needs: version
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
# Pinned to v5, the last release before WiX v6/v7 moved to the Open
# Source Maintenance Fee license requiring EULA acceptance.
- name: Install WiX
shell: pwsh
run: |
dotnet tool install --global wix --version 5.0.2
echo "$env:USERPROFILE\.dotnet\tools" | Out-File -FilePath $env:GITHUB_PATH -Append
- name: Add WiX extensions
shell: pwsh
run: wix extension add -g WixToolset.UI.wixext/5.0.2
- name: Build installers
shell: bash
env:
VERSION: ${{ needs.version.outputs.full }}
run: bash .github/packaging/windows/build.sh
- name: Upload installers
uses: actions/upload-artifact@v4
with:
name: installers-windows
path: installers/*.msi
if-no-files-found: error
build-pkg:
name: Build macOS installer
runs-on: macos-latest
needs: version
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Build installer
env:
VERSION: ${{ needs.version.outputs.full }}
run: bash .github/packaging/macos/build.sh
- name: Upload installer
uses: actions/upload-artifact@v4
with:
name: installers-macos
path: installers/*.pkg
if-no-files-found: error
goreleaser:
name: Release
runs-on: ubuntu-latest
needs: [version, build-msi, build-pkg]
steps:
- name: Checkout
@ -29,16 +116,12 @@ jobs:
- name: Install syft
uses: anchore/sbom-action/download-syft@v0
- name: Format version
id: version
run: |
raw="${GITHUB_REF_NAME#v}"
IFS='.' read -r major minor patch <<< "$raw"
if [ "${patch}" = "0" ]; then
echo "value=${major}.${minor}" >> $GITHUB_OUTPUT
else
echo "value=${major}.${minor}.${patch}" >> $GITHUB_OUTPUT
fi
- name: Download installers
uses: actions/download-artifact@v4
with:
pattern: installers-*
path: installers
merge-multiple: true
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v7
@ -48,9 +131,16 @@ jobs:
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INCUS_VERSION: ${{ steps.version.outputs.value }}
INCUS_VERSION: ${{ needs.version.outputs.display }}
- name: Handle attestation
uses: actions/attest@v4
with:
subject-checksums: ./dist/checksums.txt
- name: Handle installer attestation
uses: actions/attest@v4
with:
subject-path: |
installers/*.msi
installers/*.pkg

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
po/*.mo
po/*.po~
incus-*.tar.xz
installers
.vagrant
*~
tags

View File

@ -162,6 +162,9 @@ release:
owner: lxc
name: incus
name_template: "Incus {{ .Env.INCUS_VERSION }}"
extra_files:
- glob: ./installers/*.msi
- glob: ./installers/*.pkg
sboms:
- id: archive