Skip to content

Release 0.12.0 with updated Claude/Codex models and Windows build fix… #188

Release 0.12.0 with updated Claude/Codex models and Windows build fix…

Release 0.12.0 with updated Claude/Codex models and Windows build fix… #188

Workflow file for this run

name: Release
on:
push:
branches: [main]
jobs:
check-version:
runs-on: ubuntu-latest
outputs:
should_release: ${{ steps.check.outputs.should_release }}
version: ${{ steps.check.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Compare VERSION to latest tag
id: check
run: |
version=$(cat VERSION | tr -d '[:space:]')
latest_tag=$(git tag -l 'v*' --sort=-v:refname | head -1)
echo "version=$version" >> "$GITHUB_OUTPUT"
if [ -z "$latest_tag" ]; then
echo "No tags found — releasing v$version"
echo "should_release=true" >> "$GITHUB_OUTPUT"
elif [ "$latest_tag" = "v$version" ]; then
echo "v$version already released — skipping"
echo "should_release=false" >> "$GITHUB_OUTPUT"
else
echo "New version v$version (latest tag: $latest_tag)"
echo "should_release=true" >> "$GITHUB_OUTPUT"
fi
build-macos-arm:
needs: check-version
if: needs.check-version.outputs.should_release == 'true'
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- name: Import signing certificate
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
run: |
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
echo "$APPLE_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/certificate.p12
security import $RUNNER_TEMP/certificate.p12 -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security list-keychain -d user -s "$KEYCHAIN_PATH"
- name: Set up notarization API key
env:
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
run: |
mkdir -p $HOME/private_keys
echo "$APPLE_API_KEY" > $HOME/private_keys/AuthKey_${APPLE_API_KEY_ID}.p8
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile
- name: Build, sign, and notarize
env:
APPLE_SIGNING_IDENTITY: "Developer ID Application: Software Savants LLC (5Y6UKMM68W)"
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_API_KEY_PATH: /Users/runner/private_keys/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: pnpm tauri build --target aarch64-apple-darwin
- name: Clean DMG
run: bash scripts/clean-dmg.sh src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/*.dmg
- name: Upload DMG
uses: actions/upload-artifact@v4
with:
name: macos-arm-dmg
path: src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/*.dmg
- name: Upload updater artifacts
uses: actions/upload-artifact@v4
with:
name: macos-arm-updater
path: |
src-tauri/target/aarch64-apple-darwin/release/bundle/macos/*.tar.gz
src-tauri/target/aarch64-apple-darwin/release/bundle/macos/*.tar.gz.sig
build-macos-intel:
needs: check-version
if: needs.check-version.outputs.should_release == 'true'
runs-on: macos-15-intel
steps:
- uses: actions/checkout@v4
- name: Import signing certificate
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
run: |
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
echo "$APPLE_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/certificate.p12
security import $RUNNER_TEMP/certificate.p12 -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security list-keychain -d user -s "$KEYCHAIN_PATH"
- name: Set up notarization API key
env:
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
run: |
mkdir -p $HOME/private_keys
echo "$APPLE_API_KEY" > $HOME/private_keys/AuthKey_${APPLE_API_KEY_ID}.p8
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-apple-darwin
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile
- name: Build, sign, and notarize
env:
APPLE_SIGNING_IDENTITY: "Developer ID Application: Software Savants LLC (5Y6UKMM68W)"
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_API_KEY_PATH: /Users/runner/private_keys/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: pnpm tauri build --target x86_64-apple-darwin
- name: Clean DMG
run: bash scripts/clean-dmg.sh src-tauri/target/x86_64-apple-darwin/release/bundle/dmg/*.dmg
- name: Upload DMG
uses: actions/upload-artifact@v4
with:
name: macos-intel-dmg
path: src-tauri/target/x86_64-apple-darwin/release/bundle/dmg/*.dmg
- name: Upload updater artifacts
uses: actions/upload-artifact@v4
with:
name: macos-intel-updater
path: |
src-tauri/target/x86_64-apple-darwin/release/bundle/macos/*.tar.gz
src-tauri/target/x86_64-apple-darwin/release/bundle/macos/*.tar.gz.sig
build-windows:
needs: check-version
if: needs.check-version.outputs.should_release == 'true'
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile
- name: Build
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: pnpm tauri build
- name: Upload NSIS installer
uses: actions/upload-artifact@v4
with:
name: windows-exe
path: src-tauri/target/release/bundle/nsis/*.exe
- name: Upload updater signature
uses: actions/upload-artifact@v4
with:
name: windows-updater-sig
path: src-tauri/target/release/bundle/nsis/*.exe.sig
build-linux:
needs: check-version
if: needs.check-version.outputs.should_release == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install frontend dependencies
run: pnpm install --frozen-lockfile
- name: Build
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: pnpm tauri build
- name: Upload AppImage
uses: actions/upload-artifact@v4
with:
name: linux-appimage
path: src-tauri/target/release/bundle/appimage/*.AppImage
- name: Upload updater signature
uses: actions/upload-artifact@v4
with:
name: linux-updater-sig
path: src-tauri/target/release/bundle/appimage/*.AppImage.sig
release:
needs: [check-version, build-macos-arm, build-macos-intel, build-windows, build-linux]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Prepare release assets
run: |
mkdir -p release-assets
# DMGs — static names
cp artifacts/macos-arm-dmg/*.dmg release-assets/Verun_aarch64.dmg
cp artifacts/macos-intel-dmg/*.dmg release-assets/Verun_x64.dmg
# Windows installer — static name
cp artifacts/windows-exe/*.exe release-assets/Verun_x64-setup.exe
# Linux AppImage — static name
cp artifacts/linux-appimage/*.AppImage release-assets/Verun_amd64.AppImage
# Updater artifacts — static names
cp artifacts/macos-arm-updater/*.tar.gz release-assets/Verun_aarch64.app.tar.gz
cp artifacts/macos-arm-updater/*.tar.gz.sig release-assets/Verun_aarch64.app.tar.gz.sig
cp artifacts/macos-intel-updater/*.tar.gz release-assets/Verun_x86_64.app.tar.gz
cp artifacts/macos-intel-updater/*.tar.gz.sig release-assets/Verun_x86_64.app.tar.gz.sig
# Windows updater signature — static name
cp artifacts/windows-updater-sig/*.exe.sig release-assets/Verun_x64-setup.exe.sig
# Linux updater signature — static name
cp artifacts/linux-updater-sig/*.AppImage.sig release-assets/Verun_amd64.AppImage.sig
- name: Extract changelog for this version
id: changelog
run: |
version="${{ needs.check-version.outputs.version }}"
escaped=$(echo "$version" | sed 's/\./\\./g')
awk "/^## ${escaped}( |\$)/{found=1; next} found && /^## [0-9]/{exit} found" CHANGELOG.md > /tmp/release_notes.md
if [ ! -s /tmp/release_notes.md ]; then
echo "Release v${version}" > /tmp/release_notes.md
fi
- name: Build latest.json for updater
run: |
version="${{ needs.check-version.outputs.version }}"
base_url="https://github.com/SoftwareSavants/verun/releases/download/v${version}"
pub_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
jq -n \
--arg version "$version" \
--arg notes "$(cat /tmp/release_notes.md)" \
--arg pub_date "$pub_date" \
--arg da_sig "$(cat release-assets/Verun_aarch64.app.tar.gz.sig)" \
--arg da_url "${base_url}/Verun_aarch64.app.tar.gz" \
--arg dx_sig "$(cat release-assets/Verun_x86_64.app.tar.gz.sig)" \
--arg dx_url "${base_url}/Verun_x86_64.app.tar.gz" \
--arg ws_sig "$(cat release-assets/Verun_x64-setup.exe.sig)" \
--arg wu_url "${base_url}/Verun_x64-setup.exe" \
--arg ls_sig "$(cat release-assets/Verun_amd64.AppImage.sig)" \
--arg lu_url "${base_url}/Verun_amd64.AppImage" \
'{
version: $version,
notes: $notes,
pub_date: $pub_date,
platforms: {
"darwin-aarch64": { signature: $da_sig, url: $da_url },
"darwin-x86_64": { signature: $dx_sig, url: $dx_url },
"windows-x86_64": { signature: $ws_sig, url: $wu_url },
"linux-x86_64": { signature: $ls_sig, url: $lu_url }
}
}' > release-assets/latest.json
- name: Create tag
run: |
git tag "v${{ needs.check-version.outputs.version }}"
git push origin "v${{ needs.check-version.outputs.version }}"
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create "v${{ needs.check-version.outputs.version }}" \
release-assets/* \
--title "v${{ needs.check-version.outputs.version }}" \
--notes-file /tmp/release_notes.md