add a goose2 signed release flow

This commit is contained in:
Jack Amadeo 2026-04-21 11:22:04 -04:00
parent 953fe961bc
commit 25ceddb161
4 changed files with 303 additions and 5 deletions

View file

@ -38,6 +38,11 @@ on:
required: false
default: ""
type: string
windows-signing:
description: "Whether to perform Windows signing via Azure Trusted Signing"
required: false
default: false
type: boolean
cli-run-id:
description: >
Run ID of a prior build-cli.yml workflow run to download the goose
@ -125,7 +130,7 @@ jobs:
- name: Cache Rust dependencies
if: inputs.cli-run-id == ''
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: goose2-macos-arm64
@ -291,7 +296,7 @@ jobs:
- name: Cache Rust dependencies
if: inputs.cli-run-id == ''
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: goose2-macos-x86_64
@ -477,7 +482,7 @@ jobs:
- name: Cache Rust dependencies
if: inputs.cli-run-id == ''
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: goose2-linux-x86_64
@ -564,6 +569,7 @@ jobs:
runs-on: windows-latest
timeout-minutes: 60
permissions:
id-token: write
contents: read
actions: read
steps:
@ -621,7 +627,7 @@ jobs:
- name: Cache Rust dependencies
if: inputs.cli-run-id == ''
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: goose2-windows-x86_64
@ -697,3 +703,70 @@ jobs:
name: Goose2-windows-x64-msi
path: ui/goose2/src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi/*.msi
if-no-files-found: warn
sign-windows:
name: "Sign Windows installers"
needs: bundle-windows
if: inputs.windows-signing
runs-on: windows-latest
environment: signing
permissions:
id-token: write
contents: read
actions: read
steps:
- name: Download NSIS installer
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: Goose2-windows-x64-nsis
path: unsigned/nsis
- name: Download MSI installer
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: Goose2-windows-x64-msi
path: unsigned/msi
- name: Azure login
uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5 # v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Sign Windows installers with Azure Trusted Signing
uses: azure/trusted-signing-action@db7a3a6bd3912025c705162fb7475389f5b69ec6 # v1
with:
endpoint: ${{ secrets.AZURE_SIGNING_ENDPOINT }}
trusted-signing-account-name: ${{ secrets.AZURE_SIGNING_ACCOUNT_NAME }}
certificate-profile-name: ${{ secrets.AZURE_CERTIFICATE_PROFILE_NAME }}
files-folder: ${{ github.workspace }}/unsigned
files-folder-filter: exe,msi
files-folder-recurse: true
- name: Verify signed installers
shell: pwsh
run: |
$files = Get-ChildItem -Path unsigned -Recurse -Include *.exe,*.msi
foreach ($file in $files) {
Write-Output "Verifying signature: $($file.FullName)"
$sig = Get-AuthenticodeSignature $file.FullName
if ($sig.Status -ne "Valid") {
throw "Signature invalid for $($file.Name): $($sig.Status)"
}
Write-Output "✅ Signature valid: $($file.Name)"
}
- name: Upload signed NSIS installer
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: Goose2-windows-x64-nsis-signed
path: unsigned/nsis/*.exe
if-no-files-found: error
- name: Upload signed MSI installer
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: Goose2-windows-x64-msi-signed
path: unsigned/msi/*.msi
if-no-files-found: error

199
.github/workflows/release-goose2.yml vendored Normal file
View file

@ -0,0 +1,199 @@
# Release workflow for Goose 2 (Tauri desktop app).
# Triggered by pushing a tag matching v2.*.
#
# Pipeline:
# 1. Build CLI binaries for all platforms (reuses build-cli.yml)
# 2. Bundle Goose 2 desktop app with code signing:
# - macOS: Apple codesign + notarization via keychain & APPLE_* env vars
# - Windows: Azure Trusted Signing (post-build)
# - Linux: unsigned (standard for Linux packages)
# 3. Create a versioned GitHub Release with all artifacts
on:
push:
paths-ignore:
- "documentation/**"
tags:
- "v2.*"
name: "Release Goose 2"
permissions:
id-token: write # Sigstore OIDC signing + Azure OIDC (Windows signing)
contents: write # Creating releases + actions/checkout
actions: read # Downloading artifacts across workflow runs
attestations: write # SLSA build provenance attestations
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# ------------------------------------
# 1) Derive version from the tag
# ------------------------------------
prepare-version:
name: Prepare Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.set-version.outputs.version }}
steps:
- name: Extract version from tag
id: set-version
run: |
# Strip the leading "v" from the tag (e.g. v2.0.0 → 2.0.0)
VERSION="${GITHUB_REF_NAME#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Release version: $VERSION"
# ------------------------------------
# 2) Build CLI for all platforms
# ------------------------------------
build-cli:
needs: [prepare-version]
uses: ./.github/workflows/build-cli.yml
with:
version: ${{ needs.prepare-version.outputs.version }}
# ------------------------------------
# 3) Bundle Goose 2 desktop app
# (macOS signed + notarized, Windows signed, Linux unsigned)
# ------------------------------------
bundle-goose2:
needs: [prepare-version, build-cli]
uses: ./.github/workflows/bundle-goose2.yml
permissions:
id-token: write
contents: read
actions: read
with:
version: ${{ needs.prepare-version.outputs.version }}
signing: true
windows-signing: true
environment: signing
cli-run-id: ${{ github.run_id }}
secrets: inherit
# ------------------------------------
# 4) Upload install script
# ------------------------------------
install-script:
name: Upload Install Script
runs-on: ubuntu-latest
needs: [build-cli]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: download_cli.sh
path: download_cli.sh
# ------------------------------------
# 5) Create GitHub Release
# ------------------------------------
release:
name: Release
runs-on: ubuntu-latest
needs: [prepare-version, build-cli, install-script, bundle-goose2]
permissions:
contents: write
id-token: write
actions: read
attestations: write
steps:
- name: Download CLI artifacts
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
pattern: goose-*
merge-multiple: true
path: release
- name: Download install script
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: download_cli.sh
path: release
- name: Download macOS ARM64
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: Goose2-darwin-arm64
path: release
- name: Download macOS Intel
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: Goose2-darwin-x64
path: release
- name: Download Linux .deb
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: Goose2-linux-x64-deb
path: release
continue-on-error: true
- name: Download Linux AppImage
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: Goose2-linux-x64-appimage
path: release
continue-on-error: true
- name: Download Linux RPM
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: Goose2-linux-x64-rpm
path: release
continue-on-error: true
- name: Download signed Windows NSIS installer
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: Goose2-windows-x64-nsis-signed
path: release
- name: Download signed Windows MSI installer
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: Goose2-windows-x64-msi-signed
path: release
- name: List downloaded artifacts
run: |
echo "=== All release artifacts ==="
find release -type f | sort
- name: Attest build provenance
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3
with:
subject-path: |
release/goose-*.tar.bz2
release/goose-*.tar.gz
release/goose-*.zip
release/*.dmg
release/*.exe
release/*.msi
release/*.deb
release/*.rpm
release/*.AppImage
release/download_cli.sh
# Create/update the versioned pre-release (e.g. v2.0.0)
- name: Release versioned
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
prerelease: true
artifacts: |
release/goose-*.tar.bz2
release/goose-*.tar.gz
release/goose-*.zip
release/*.dmg
release/*.exe
release/*.msi
release/*.deb
release/*.rpm
release/*.AppImage
release/download_cli.sh
allowUpdates: true
omitBody: true

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
</dict>
</plist>

View file

@ -44,6 +44,10 @@
"icons/icon.icns",
"icons/icon.ico"
],
"externalBin": ["../../../target/release/goose"]
"externalBin": ["../../../target/release/goose"],
"macOS": {
"entitlements": "entitlements.plist",
"hardenedRuntime": true
}
}
}