* ci: re-enable macOS code signing and notarization
Uncomment the Apple credential env vars in the release workflow
so Tauri's build step signs and notarizes the .app bundle.
This reverses the temporary disable from ee42731.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: cargo fmt
---------
Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
257 lines
11 KiB
YAML
257 lines
11 KiB
YAML
name: Release
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
|
|
concurrency:
|
|
group: release-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
# ─────────────────────────────────────────────────────────────
|
|
# Phase 1: Compute the version string once
|
|
# ─────────────────────────────────────────────────────────────
|
|
version:
|
|
name: Compute version
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
version: ${{ steps.ver.outputs.version }}
|
|
tag: ${{ steps.ver.outputs.tag }}
|
|
steps:
|
|
- id: ver
|
|
run: |
|
|
VERSION="0.$(date -u +%Y%m%d).${GITHUB_RUN_NUMBER}"
|
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
|
|
echo "### Version: \`$VERSION\`" >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
# ─────────────────────────────────────────────────────────────
|
|
# Phase 2: Build each architecture in parallel
|
|
# tauri build handles signing automatically via env vars
|
|
# ─────────────────────────────────────────────────────────────
|
|
build:
|
|
name: Build (${{ matrix.arch }})
|
|
needs: version
|
|
runs-on: macos-15
|
|
strategy:
|
|
fail-fast: true
|
|
matrix:
|
|
include:
|
|
- arch: aarch64
|
|
target: aarch64-apple-darwin
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v4
|
|
with:
|
|
version: 10
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '22'
|
|
cache: 'pnpm'
|
|
|
|
- name: Setup Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: ${{ matrix.target }}
|
|
|
|
- name: Cache Rust dependencies
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: |
|
|
~/.cargo/registry
|
|
~/.cargo/git
|
|
src-tauri/target
|
|
key: ${{ runner.os }}-release-cargo-${{ hashFiles('src-tauri/Cargo.lock') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-release-cargo-
|
|
|
|
- name: Install frontend dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Set version
|
|
run: |
|
|
VERSION="${{ needs.version.outputs.version }}"
|
|
jq --arg v "$VERSION" '.version = $v' src-tauri/tauri.conf.json > tmp.json && mv tmp.json src-tauri/tauri.conf.json
|
|
sed -i '' "s/^version = \".*\"/version = \"$VERSION\"/" src-tauri/Cargo.toml
|
|
|
|
- name: Build Tauri app (with signing + notarization)
|
|
env:
|
|
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
|
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
|
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
run: |
|
|
pnpm tauri build --target ${{ matrix.target }}
|
|
|
|
- name: Upload .dmg
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: dmg-${{ matrix.arch }}
|
|
path: src-tauri/target/${{ matrix.target }}/release/bundle/dmg/*.dmg
|
|
retention-days: 1
|
|
|
|
- name: Upload updater artifacts (.tar.gz + .sig)
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: updater-${{ matrix.arch }}
|
|
path: |
|
|
src-tauri/target/${{ matrix.target }}/release/bundle/macos/*.app.tar.gz
|
|
src-tauri/target/${{ matrix.target }}/release/bundle/macos/*.app.tar.gz.sig
|
|
retention-days: 1
|
|
|
|
# ─────────────────────────────────────────────────────────────
|
|
# Phase 3: Publish GitHub Release
|
|
# No lipo/re-signing — use the per-arch artifacts directly
|
|
# ─────────────────────────────────────────────────────────────
|
|
release:
|
|
name: GitHub Release
|
|
needs: [version, build]
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Download all artifacts
|
|
uses: actions/download-artifact@v4
|
|
|
|
- name: Generate release notes
|
|
run: |
|
|
PREV_TAG=$(git tag --sort=-version:refname | head -n 1 || echo "")
|
|
if [ -z "$PREV_TAG" ]; then
|
|
NOTES=$(git log --oneline --no-merges -20)
|
|
else
|
|
NOTES=$(git log --oneline --no-merges "${PREV_TAG}..HEAD")
|
|
fi
|
|
{
|
|
echo "## What's Changed"
|
|
echo ""
|
|
echo "$NOTES" | while IFS= read -r line; do echo "- $line"; done
|
|
echo ""
|
|
echo "---"
|
|
echo "**Requires Apple Silicon (M1/M2/M3)**"
|
|
echo ""
|
|
echo "*Built from \`$(git rev-parse --short HEAD)\` on $(date -u +%Y-%m-%d)*"
|
|
} > release_notes.md
|
|
|
|
- name: Build latest.json
|
|
run: |
|
|
VERSION="${{ needs.version.outputs.version }}"
|
|
TAG="${{ needs.version.outputs.tag }}"
|
|
REPO="refactoringhq/laputa-app"
|
|
|
|
ARM_SIG=$(cat updater-aarch64/*.app.tar.gz.sig)
|
|
ARM_DMG=$(ls dmg-aarch64/*.dmg | xargs basename)
|
|
|
|
cat > latest.json << EOF
|
|
{
|
|
"version": "${VERSION}",
|
|
"notes": "See https://refactoringhq.github.io/laputa-app/ for full release notes.",
|
|
"pub_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
"platforms": {
|
|
"darwin-aarch64": {
|
|
"signature": "${ARM_SIG}",
|
|
"url": "https://github.com/${REPO}/releases/download/${TAG}/${ARM_DMG}"
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
echo "latest.json:"; cat latest.json
|
|
|
|
- name: Publish GitHub Release
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ needs.version.outputs.tag }}
|
|
name: Laputa ${{ needs.version.outputs.version }}
|
|
body_path: release_notes.md
|
|
draft: false
|
|
prerelease: false
|
|
files: |
|
|
dmg-aarch64/*.dmg
|
|
updater-aarch64/*.app.tar.gz
|
|
updater-aarch64/*.app.tar.gz.sig
|
|
latest.json
|
|
|
|
# ─────────────────────────────────────────────────────────────
|
|
# Phase 4: Update GitHub Pages with release history
|
|
# ─────────────────────────────────────────────────────────────
|
|
pages:
|
|
name: Update release history page
|
|
needs: [version, release]
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Build release history page
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
mkdir -p _site
|
|
gh api repos/${{ github.repository }}/releases --paginate > _site/releases.json
|
|
cat > _site/index.html << 'HTMLEOF'
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Laputa — Release History</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #F7F6F3; color: #37352F; line-height: 1.6; padding: 2rem; max-width: 720px; margin: 0 auto; }
|
|
h1 { font-size: 1.75rem; font-weight: 600; margin-bottom: 0.5rem; }
|
|
.subtitle { color: #787774; margin-bottom: 2rem; }
|
|
.release { background: #fff; border: 1px solid #E9E9E7; border-radius: 8px; padding: 1.25rem 1.5rem; margin-bottom: 1rem; }
|
|
.release h2 { font-size: 1.125rem; font-weight: 600; margin-bottom: 0.25rem; }
|
|
.release .meta { font-size: 0.8125rem; color: #787774; margin-bottom: 0.75rem; }
|
|
.release .body { font-size: 0.875rem; white-space: pre-wrap; }
|
|
.release .downloads { margin-top: 0.75rem; display: flex; gap: 0.5rem; flex-wrap: wrap; }
|
|
.release .downloads a { display: inline-block; padding: 0.375rem 0.75rem; background: #155DFF; color: #fff; border-radius: 6px; text-decoration: none; font-size: 0.8125rem; font-weight: 500; }
|
|
.release .downloads a:hover { background: #1248CC; }
|
|
.empty { color: #787774; text-align: center; padding: 3rem; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Laputa Release History</h1>
|
|
<p class="subtitle">Auto-updated on every release</p>
|
|
<div id="releases"></div>
|
|
<script>
|
|
fetch('releases.json').then(r=>r.json()).then(releases=>{
|
|
const el=document.getElementById('releases');
|
|
if(!releases.length){el.innerHTML='<p class="empty">No releases yet.</p>';return;}
|
|
releases.forEach(r=>{
|
|
const date=new Date(r.published_at).toLocaleDateString('en-US',{year:'numeric',month:'long',day:'numeric'});
|
|
const dmgs=(r.assets||[]).filter(a=>a.name.endsWith('.dmg'));
|
|
const links=dmgs.map(a=>'<a href="'+a.browser_download_url+'">'+a.name+'</a>').join('');
|
|
const body=(r.body||'').replace(/</g,'<').replace(/>/g,'>');
|
|
const div=document.createElement('div');
|
|
div.className='release';
|
|
div.innerHTML='<h2>'+(r.name||r.tag_name)+'</h2><div class="meta">'+date+' · '+r.tag_name+'</div><div class="body">'+body+'</div>'+(links?'<div class="downloads">'+links+'</div>':'');
|
|
el.appendChild(div);
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|
|
HTMLEOF
|
|
|
|
- name: Deploy to GitHub Pages
|
|
uses: peaceiris/actions-gh-pages@v4
|
|
with:
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
publish_dir: ./_site
|
|
commit_message: "Update release history for ${{ needs.version.outputs.tag }}"
|