Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/scripts/app-release/stage-binaries.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Stage the binaries produced by tauri-action into a flat directory so they
# can be uploaded as GitHub Actions build artifacts and attested.
#
# Env: ARTIFACT_PATHS (JSON array from tauri-action's artifactPaths output).
# Output: dir=<staging path> appended to $GITHUB_OUTPUT.
set -euo pipefail

: "${ARTIFACT_PATHS:?}"

staging="${GITHUB_WORKSPACE:-$PWD}/dist/release"
rm -rf "$staging"
mkdir -p "$staging"

while IFS= read -r src; do
# Strip stray CR — on windows-latest the env var can arrive CRLF-terminated.
src="${src%$'\r'}"
[ -z "$src" ] && continue
# tauri-action lists the .app bundle (a directory) alongside the .dmg on
# macOS; skip anything that isn't a regular file.
if [ ! -f "$src" ]; then
echo "Skipping non-file artifact: $src" >&2
continue
fi
cp "$src" "$staging/"
done < <(printf '%s' "$ARTIFACT_PATHS" | jq -r '.[]')

count=$(find "$staging" -maxdepth 1 -type f | wc -l | tr -d ' ')
if [ "$count" -eq 0 ]; then
echo "No binary artifacts produced by tauri-action." >&2
exit 1
fi

echo "dir=$staging" >> "$GITHUB_OUTPUT"
echo "Staged $count file(s) in $staging"
30 changes: 30 additions & 0 deletions .github/workflows/app-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ name: App Release
#
# Builds are currently unsigned. See doc/guides/releasing.md for how to obtain
# Apple and Windows code-signing credentials and wire them back in here.
#
# After the build, each platform job also uploads its bundles as GitHub
# Actions build artifacts and generates a signed SLSA provenance attestation
# (actions/attest-build-provenance). The attestation is what surfaces the
# binaries on the org's linked-artifacts view via the artifact metadata API.

on:
push:
Expand All @@ -22,6 +27,8 @@ on:

permissions:
contents: write
id-token: write
attestations: write

jobs:
build:
Expand All @@ -30,12 +37,15 @@ jobs:
matrix:
include:
- platform: macos-latest
slug: macos
args: "--target universal-apple-darwin"
rust-targets: "aarch64-apple-darwin,x86_64-apple-darwin"
- platform: ubuntu-22.04
slug: linux
args: ""
rust-targets: ""
- platform: windows-latest
slug: windows
args: ""
rust-targets: ""

Expand Down Expand Up @@ -74,6 +84,7 @@ jobs:
run: bun install --frozen-lockfile

- name: Build and release
id: tauri
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -91,3 +102,22 @@ jobs:
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}

- name: Stage binaries
id: stage
shell: bash
env:
ARTIFACT_PATHS: ${{ steps.tauri.outputs.artifactPaths }}
run: bash .github/scripts/app-release/stage-binaries.sh

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: pengine-${{ matrix.slug }}
path: ${{ steps.stage.outputs.dir }}
if-no-files-found: error

- name: Attest build provenance
uses: actions/attest-build-provenance@v2
with:
subject-path: ${{ steps.stage.outputs.dir }}/*
15 changes: 14 additions & 1 deletion doc/guides/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,20 @@
Pengine ships installers for macOS, Windows, and Linux via the
[`App Release`](../../.github/workflows/app-release.yml) GitHub Actions
workflow. Pushing a tag matching `v*` (e.g. `v1.0.1`) triggers a build on each
platform and uploads the installers as assets on a **draft** GitHub Release.
platform and publishes the installers in two places:

- as assets on a **draft** GitHub Release (for humans to download), and
- as GitHub Actions build artifacts (`pengine-macos`, `pengine-linux`,
`pengine-windows`) with a signed SLSA build-provenance attestation. The
attestations surface on the org's
[linked artifacts page](https://github.com/orgs/pengine-ai/artifacts) via
the artifact metadata API — GHCR is reserved for Docker images (tools).

Verify a downloaded binary's provenance with the GitHub CLI:

```bash
gh attestation verify ./pengine_1.0.1_amd64.AppImage --owner pengine-ai
```

```bash
git tag v1.0.1
Expand Down
Loading