Skip to content

Build robust per-speaker centroids from FluidAudio chunk embeddings #137

Build robust per-speaker centroids from FluidAudio chunk embeddings

Build robust per-speaker centroids from FluidAudio chunk embeddings #137

Workflow file for this run

name: CI
on:
push:
branches: ['**']
tags: ['v*']
pull_request:
# Manual release: runs the full release pipeline from main HEAD. The version must
# already be bumped in Info.plist (release.sh does this). The tag is created by
# action-gh-release using GITHUB_TOKEN, which does not re-trigger this workflow.
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g. 0.2.3) — must match Info.plist'
required: true
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
build-and-test:
runs-on: macos-15
steps:
- uses: actions/checkout@v4
- name: Cache SPM dependencies
uses: actions/cache@v4
with:
path: .build
key: ${{ runner.os }}-spm-${{ hashFiles('Package.resolved') }}
restore-keys: |
${{ runner.os }}-spm-
- name: Build
run: swift build
- name: Test
run: swift run HeardTests
release:
runs-on: macos-15
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
needs: build-and-test
permissions:
contents: write
steps:
- uses: actions/checkout@v4
# Validate the release version before the expensive build/notarize steps.
# On tag push the version comes from the tag; on manual dispatch from the input.
- name: Resolve release version
id: version
run: |
if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
VERSION="${{ inputs.version }}"
if git ls-remote --tags origin "refs/tags/v${VERSION}" | grep -q .; then
echo "ERROR: tag v${VERSION} already exists — bump Info.plist and pass a new version"
exit 1
fi
else
VERSION="${GITHUB_REF_NAME#v}"
fi
PLIST_VERSION=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" Info.plist)
if [[ "$VERSION" != "$PLIST_VERSION" ]]; then
echo "ERROR: release version ${VERSION} does not match Info.plist CFBundleShortVersionString (${PLIST_VERSION})"
exit 1
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Cache SPM dependencies
uses: actions/cache@v4
with:
path: .build
key: ${{ runner.os }}-spm-${{ hashFiles('Package.resolved') }}
restore-keys: |
${{ runner.os }}-spm-
# Import the Developer ID Application certificate into a temporary keychain.
# security set-key-partition-list is required so codesign can access the key
# non-interactively (without it, codesign hangs waiting for a UI password prompt).
- name: Import Developer ID certificate
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
run: |
KEYCHAIN_PWD="$(openssl rand -hex 16)"
echo "KEYCHAIN_PWD=$KEYCHAIN_PWD" >> "$GITHUB_ENV"
security create-keychain -p "$KEYCHAIN_PWD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PWD" build.keychain
echo "$APPLE_CERTIFICATE" | base64 --decode > cert.p12
security import cert.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PWD" build.keychain
rm -f cert.p12
- name: Build and notarize DMG
env:
APPLE_DEVELOPER_ID: ${{ secrets.APPLE_DEVELOPER_ID }}
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }}
run: |
mkdir -p ~/.apple
echo "$APPLE_API_KEY" | base64 --decode > ~/.apple/AuthKey.p8
./scripts/dmg.sh \
--sign "$APPLE_DEVELOPER_ID" \
--api-key-path ~/.apple/AuthKey.p8 \
--api-key-id "$APPLE_API_KEY_ID" \
--api-issuer-id "$APPLE_API_ISSUER_ID" \
--output dist
rm -f ~/.apple/AuthKey.p8
- name: Collect release metadata
id: meta
run: |
VERSION="${{ steps.version.outputs.version }}"
DMG="dist/Heard-${VERSION}.dmg"
SHA256=$(shasum -a 256 "$DMG" | awk '{print $1}')
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT"
echo "dmg=${DMG}" >> "$GITHUB_OUTPUT"
# tag_name makes this work for workflow_dispatch too: the action creates the
# tag at the built commit if it doesn't exist yet (no-op on tag-push runs).
- name: Upload DMG to GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.meta.outputs.version }}
files: ${{ steps.meta.outputs.dmg }}
generate_release_notes: true
token: ${{ secrets.GITHUB_TOKEN }}
- name: Update Homebrew cask
run: |
VERSION="${{ steps.meta.outputs.version }}"
SHA256="${{ steps.meta.outputs.sha256 }}"
sed -i '' \
-e "s/version \"[^\"]*\"/version \"${VERSION}\"/" \
-e "s/sha256 \"[^\"]*\"/sha256 \"${SHA256}\"/" \
Casks/heard.rb
# Push the cask update back to main. The release commit is already at main HEAD
# (release.sh pushed it before the tag), so this is always a fast-forward.
# [skip ci] prevents this commit from re-triggering the workflow.
- name: Commit and push cask update
env:
GH_PAT: ${{ secrets.GH_PAT }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Casks/heard.rb
git commit -m "Update Homebrew cask to v${{ steps.meta.outputs.version }} [skip ci]"
git remote set-url origin "https://execsumo:${GH_PAT}@github.com/execsumo/Heard.git"
git push origin HEAD:refs/heads/main
# Clone the Homebrew tap repo, copy the updated cask, and push so that
# `brew upgrade --cask heard` picks up the new version automatically.
- name: Push cask to Homebrew tap
env:
GH_PAT: ${{ secrets.GH_PAT }}
run: |
VERSION="${{ steps.meta.outputs.version }}"
git clone "https://execsumo:${GH_PAT}@github.com/execsumo/homebrew-heard.git" homebrew-tap
mkdir -p homebrew-tap/Casks
cp Casks/heard.rb homebrew-tap/Casks/heard.rb
cd homebrew-tap
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Casks/heard.rb
git commit -m "Update heard to v${VERSION}"
git push origin HEAD:refs/heads/main