add a goose2 signed release flow (#8728)

This commit is contained in:
Jack Amadeo 2026-04-24 13:45:07 -04:00 committed by GitHub
parent c6755d3259
commit 910e01af3f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 300 additions and 10 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
@ -175,13 +180,11 @@ jobs:
certificate-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
# ── Tauri bundle ──
- name: Check disk space before bundle
run: df -h
- name: Bundle Goose 2 (pnpm tauri build)
env:
APPLE_SIGNING_IDENTITY: ${{ inputs.signing && 'Developer ID Application' || '' }}
APPLE_ID: ${{ inputs.signing && secrets.APPLE_ID || '' }}
APPLE_ID_PASSWORD: ${{ inputs.signing && secrets.APPLE_ID_PASSWORD || '' }}
APPLE_PASSWORD: ${{ inputs.signing && secrets.APPLE_ID_PASSWORD || '' }}
APPLE_TEAM_ID: ${{ inputs.signing && secrets.APPLE_TEAM_ID || '' }}
working-directory: ui/goose2
run: |
@ -291,7 +294,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
@ -360,8 +363,9 @@ jobs:
# ── Tauri bundle (cross-compile for Intel) ──
- name: Bundle Goose 2 for Intel
env:
APPLE_SIGNING_IDENTITY: ${{ inputs.signing && 'Developer ID Application' || '' }}
APPLE_ID: ${{ inputs.signing && secrets.APPLE_ID || '' }}
APPLE_ID_PASSWORD: ${{ inputs.signing && secrets.APPLE_ID_PASSWORD || '' }}
APPLE_PASSWORD: ${{ inputs.signing && secrets.APPLE_ID_PASSWORD || '' }}
APPLE_TEAM_ID: ${{ inputs.signing && secrets.APPLE_TEAM_ID || '' }}
working-directory: ui/goose2
run: |
@ -477,7 +481,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 +568,7 @@ jobs:
runs-on: windows-latest
timeout-minutes: 60
permissions:
id-token: write
contents: read
actions: read
steps:
@ -621,7 +626,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 +702,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

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

@ -0,0 +1,192 @@
on:
push:
tags:
- "v2.*"
workflow_dispatch:
inputs:
version:
description: "Version string (e.g. 2.0.0-rc.1). Used when testing from a branch."
required: true
type: string
cli-run-id:
description: "Run ID of a build-cli workflow to pull goose binaries from (skips CLI build step)"
required: false
type: string
default: ""
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:
prepare-version:
name: Prepare Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.set-version.outputs.version }}
steps:
- name: Extract version
id: set-version
run: |
if [ -n "${{ inputs.version }}" ]; then
VERSION="${{ inputs.version }}"
else
# Strip the leading "v" from the tag (e.g. v2.0.0 → 2.0.0)
VERSION="${GITHUB_REF_NAME#v}"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Release version: $VERSION"
build-cli:
if: inputs.cli-run-id == ''
needs: [prepare-version]
uses: ./.github/workflows/build-cli.yml
with:
version: ${{ needs.prepare-version.outputs.version }}
bundle-goose2:
needs: [prepare-version, build-cli]
if: ${{ !cancelled() && needs.prepare-version.result == 'success' && (needs.build-cli.result == 'success' || needs.build-cli.result == 'skipped') }}
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: ${{ inputs.cli-run-id != '' && inputs.cli-run-id || github.run_id }}
secrets: inherit
install-script:
name: Upload Install Script
runs-on: ubuntu-latest
if: inputs.cli-run-id == ''
needs: [build-cli]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: download_cli.sh
path: download_cli.sh
release:
name: Release
runs-on: ubuntu-latest
needs: [prepare-version, build-cli, install-script, bundle-goose2]
if: ${{ !cancelled() && needs.bundle-goose2.result == 'success' }}
permissions:
contents: write
id-token: write
actions: read
attestations: write
steps:
- name: Download CLI artifacts
if: needs.build-cli.result == 'success'
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
pattern: goose-*
merge-multiple: true
path: release
- name: Download install script
if: needs.install-script.result == 'success'
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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Before After
Before After

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
}
}
}