Skip to content

chore(release): prepare v0.1.21 #23

chore(release): prepare v0.1.21

chore(release): prepare v0.1.21 #23

name: Build installers
on:
workflow_dispatch:
push:
tags:
- "v*"
permissions:
contents: write
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: "0"
jobs:
build:
name: Build ${{ matrix.label }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- label: macOS Apple Silicon
os: macos-latest
artifact: rau-studio-macos-arm64
tauri_args: --bundles app
rust_target: ""
build_target_arg: ""
bundle_dir: target/release/bundle
mac_artifact_arch: arm64
artifact_paths: |
target/release/bundle/dmg/*.dmg
- label: macOS Intel
os: macos-latest
artifact: rau-studio-macos-intel
tauri_args: --bundles app
rust_target: x86_64-apple-darwin
build_target_arg: --target x86_64-apple-darwin
bundle_dir: target/x86_64-apple-darwin/release/bundle
mac_artifact_arch: x86_64
artifact_paths: |
target/x86_64-apple-darwin/release/bundle/dmg/*.dmg
- label: Windows
os: windows-latest
artifact: rau-studio-windows
tauri_args: --bundles nsis,msi
rust_target: ""
build_target_arg: ""
bundle_dir: target/release/bundle
mac_artifact_arch: ""
artifact_paths: |
target/release/bundle/**/*.msi
target/release/bundle/**/*.exe
- label: Linux
os: ubuntu-22.04
artifact: rau-studio-linux
tauri_args: --bundles appimage,deb
rust_target: ""
build_target_arg: ""
bundle_dir: target/release/bundle
mac_artifact_arch: ""
artifact_paths: |
target/release/bundle/**/*.AppImage
target/release/bundle/**/*.deb
target/release/bundle/**/*.rpm
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Setup Rust stable
shell: bash
run: |
rustup toolchain install stable --profile minimal
rustup default stable
- name: Add Rust target
if: matrix.rust_target != ''
shell: bash
run: rustup target add ${{ matrix.rust_target }}
- name: Install Linux Tauri dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
libasound2-dev \
librsvg2-dev \
patchelf
- name: Install macOS media build dependencies
if: runner.os == 'macOS'
run: brew install nasm pkg-config
- name: Install frontend dependencies
run: npm ci
- name: Restore bundled FFmpeg cache
if: runner.os == 'macOS'
uses: actions/cache@v4
with:
path: |
.cache/ffmpeg
src-tauri/binaries
key: ffmpeg-8.1.2-lame-3.101-network-avfoundation-${{ matrix.artifact }}
- name: Validate Apple secrets
if: runner.os == 'macOS'
shell: bash
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
run: |
for name in \
APPLE_CERTIFICATE \
APPLE_CERTIFICATE_PASSWORD \
KEYCHAIN_PASSWORD \
APPLE_ID \
APPLE_PASSWORD \
APPLE_TEAM_ID \
APPLE_SIGNING_IDENTITY
do
if [[ -z "${!name}" ]]; then
echo "Missing required repository secret: $name"
exit 1
fi
done
- name: Import Apple Developer certificate
if: runner.os == 'macOS'
shell: bash
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
certificate_path="$RUNNER_TEMP/developer-id.p12"
keychain_path="$RUNNER_TEMP/rau-studio-build.keychain-db"
printf '%s' "$APPLE_CERTIFICATE" | \
openssl base64 -d -A -out "$certificate_path"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path"
security set-keychain-settings -lut 21600 "$keychain_path"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path"
security import "$certificate_path" \
-k "$keychain_path" \
-P "$APPLE_CERTIFICATE_PASSWORD" \
-T /usr/bin/codesign
security set-key-partition-list \
-S apple-tool:,apple:,codesign: \
-s \
-k "$KEYCHAIN_PASSWORD" \
"$keychain_path"
security default-keychain -s "$keychain_path"
security list-keychains -d user -s "$keychain_path"
security find-identity -v -p codesigning "$keychain_path"
rm -f "$certificate_path"
echo "APPLE_KEYCHAIN_PATH=$keychain_path" >> "$GITHUB_ENV"
- name: Build non-macOS installers
if: runner.os != 'macOS'
shell: bash
run: npm run tauri:build -- ${{ matrix.build_target_arg }} ${{ matrix.tauri_args }}
- name: Build signed and notarized macOS app
if: runner.os == 'macOS'
shell: bash
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
run: |
npm run tauri:build -- \
${{ matrix.build_target_arg }} \
--bundles app
app="${{ matrix.bundle_dir }}/macos/Rau Studio.app"
for tool in ffmpeg ffprobe; do
test -x "$app/Contents/MacOS/$tool"
codesign --verify --strict --verbose=2 "$app/Contents/MacOS/$tool"
done
codesign --verify --deep --strict --verbose=2 "$app"
xcrun stapler validate "$app"
spctl --assess --type execute -vv "$app"
- name: Create, sign, and notarize macOS DMG
if: runner.os == 'macOS'
shell: bash
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
run: |
version="$(node -p "require('./package.json').version")"
arch="${{ matrix.mac_artifact_arch }}"
app="${{ matrix.bundle_dir }}/macos/Rau Studio.app"
dmg_dir="${{ matrix.bundle_dir }}/dmg"
dmg="$dmg_dir/Rau Studio_${version}_${arch}.dmg"
staging="$(mktemp -d "$RUNNER_TEMP/rau-studio-dmg.XXXXXX")"
cleanup() {
rm -rf "$staging"
}
trap cleanup EXIT
mkdir -p "$dmg_dir"
ditto "$app" "$staging/Rau Studio.app"
ln -s /Applications "$staging/Applications"
hdiutil create \
-volname "Rau Studio" \
-srcfolder "$staging" \
-ov \
-format UDZO \
"$dmg"
codesign \
--force \
--timestamp \
--keychain "$APPLE_KEYCHAIN_PATH" \
--sign "$APPLE_SIGNING_IDENTITY" \
"$dmg"
codesign --verify --strict --verbose=2 "$dmg"
xcrun notarytool store-credentials "rau-studio-notary" \
--keychain "$APPLE_KEYCHAIN_PATH" \
--apple-id "$APPLE_ID" \
--team-id "$APPLE_TEAM_ID" \
--password "$APPLE_PASSWORD"
xcrun notarytool submit "$dmg" \
--keychain-profile "rau-studio-notary" \
--keychain "$APPLE_KEYCHAIN_PATH" \
--wait \
--timeout 30m
xcrun stapler staple "$dmg"
xcrun stapler validate "$dmg"
spctl --assess \
--type open \
--context context:primary-signature \
-vv \
"$dmg"
hdiutil verify "$dmg"
- name: Delete temporary Apple keychain
if: always() && runner.os == 'macOS'
shell: bash
run: |
if [[ -n "${APPLE_KEYCHAIN_PATH:-}" ]]; then
security delete-keychain "$APPLE_KEYCHAIN_PATH" || true
fi
- name: Upload installer artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
if-no-files-found: error
retention-days: 14
path: ${{ matrix.artifact_paths }}
release:
name: Publish GitHub Release
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download installer artifacts
uses: actions/download-artifact@v4
with:
path: release-artifacts
- name: Add corresponding FFmpeg source
shell: bash
run: |
curl --fail --location --show-error \
https://ffmpeg.org/releases/ffmpeg-8.1.2.tar.xz \
--output release-artifacts/ffmpeg-8.1.2-source.tar.xz
echo "464beb5e7bf0c311e68b45ae2f04e9cc2af88851abb4082231742a74d97b524c release-artifacts/ffmpeg-8.1.2-source.tar.xz" | \
sha256sum --check
curl --fail --location --show-error \
https://code.videolan.org/videolan/x264/-/archive/b35605ace3ddf7c1a5d67a2eb553f034aef41d55/x264-b35605ace3ddf7c1a5d67a2eb553f034aef41d55.tar.bz2 \
--output release-artifacts/x264-b35605ace3dd-source.tar.bz2
echo "6eeb82934e69fd51e043bd8c5b0d152839638d1ce7aa4eea65a3fedcf83ff224 release-artifacts/x264-b35605ace3dd-source.tar.bz2" | \
sha256sum --check
curl --fail --location --show-error \
https://downloads.sourceforge.net/project/lame/lame/3.101/lame-3.101.tar.gz \
--output release-artifacts/lame-3.101-source.tar.gz
echo "7578af6eebd578b2bd64e468fac4ae1f03670a7e028166e67f855674b9b6aeac release-artifacts/lame-3.101-source.tar.gz" | \
sha256sum --check
- name: Publish release assets
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
TAG_NAME: ${{ github.ref_name }}
shell: bash
run: |
mapfile -t files < <(find release-artifacts -type f \( \
-name '*.dmg' -o \
-name '*.msi' -o \
-name '*.exe' -o \
-name '*.AppImage' -o \
-name '*.deb' -o \
-name '*.rpm' -o \
-name 'ffmpeg-*-source.tar.xz' \
-o -name 'x264-*-source.tar.bz2' \
-o -name 'lame-*-source.tar.gz' \
\))
if [ "${#files[@]}" -eq 0 ]; then
echo "No installer files found."
exit 1
fi
gh release view "$TAG_NAME" --repo "$GH_REPO" >/dev/null 2>&1 || \
gh release create "$TAG_NAME" --repo "$GH_REPO" --title "Rau Studio $TAG_NAME" --generate-notes
gh release upload "$TAG_NAME" "${files[@]}" --repo "$GH_REPO" --clobber