Tauri製のmacOSユニバーサルアプリケーションをGitHub ActionsでReleaseするCDを実現する
タイトルがてんこ盛り。
pushしたらReleasesに署名済みの .dmg が焼きあがってる世界を目指します。
対象の読者
- Mac App Storeに並べるほどでもないが、とはいえ広範にアプリ配布したい人
- リリースしたアプリケーションを「プライバシーとセキュリティ」で実行を許可してもらう必要がありモヤモヤしている人
要件
-
Intel CPU Mac / Apple Silicon Macともに利用できる
→ ユニバーサルアプリとしてビルドし、.dmg でパッケージングして配布する -
ユーザーはGitHubリポジトリのRelease経由でダウンロードできる
→ GitHub Actionsでいい感じにする -
ユーザーはダウンロードした.dmg ファイルから一般的なUXでアプリをインストール・起動できる
- dmgをマウントすると左側にインストールしたいアプリ / 右側に Applicationsフォルダが配置され、D&Dすることでインストールできる
- 起動すると特別な認証を求められずそのまま起動できる
→公式Actionのサンプルに具体例が無くて苦労した
リリースするもの
公式サンプル に最低限の変更を加えたアプリケーション
完成品のサンプルリポジトリはこちら
参照すべき公式ドキュメント
Apple Developer Programで識別子を準備
この後すぐIdentiferが必要となるので作っておきます
(過去のものを流用する場合はスキップしてもOK)
0. メンバーシップ登録しましょう 💰
円安つらいよう ( 151円/ドル 2025/02/08時点)
1. Identifierの新規作成を開始
2. 種別は App IDs を選択
3. 続いてAppを選択
4. Bundle IDを指定して作成を完了
今回は決め打ちで指定しましたが、ワイルドカードで作ってしまっても問題ないはず。
Capabilities や App Servicesはひとまず未指定(後でも変更できます)
サクッとサンプルアプリをビルド可能な状態にする
リポジトリを作ってgit clone
プロジェクトのリポジトリは分かりやすく tauri_distribution_sample
とします
空のリポジトリを git clone
% pwd
/Users/8beeeaaat
% git clone git@github.com:8beeeaaat/tauri_distribution_sample.git
Cloning into 'tauri_distribution_sample'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (3/3), done.
1. セットアップ
1. Identifier 以外は適当にセットアップ。
Identifierは先ほど Apple Developer Program で作ったものを指定します。
% cd tauri_distribution_sample
% pwd
/Users/8beeeaaat/tauri_distribution_sample
% bun create tauri-app
✔ Project name · tauri-app
✔ Identifier · 作ったIdentifier
✔ Choose which language to use for your frontend · TypeScript / JavaScript - (pnpm, yarn, npm, deno, bun)
✔ Choose your package manager · bun
✔ Choose your UI template · React - (https://react.dev/)
✔ Choose your UI flavor · TypeScript
Template created! To get started run:
cd tauri-app
bun install
bun run tauri android init
bun run tauri ios init
For Desktop development, run:
bun run tauri dev
For Android development, run:
bun run tauri android dev
For iOS development, run:
bun run tauri ios dev
tauri_distribution_sample
直下にプロジェクトファイルを移動させる
2. % ls
README.md tauri-app
% mv tauri-app/* tauri-app/.* . # .gitignoreなども移動させる
% pwd
/Users/8beeeaaat/tauri_distribution_sample
% ls -a
. .git .vscode index.html package.json src tauri-app tsconfig.node.json
.. .gitignore README.md dist public src-tauri tsconfig.json vite.config.ts
3. パッケージをインストールして開発ビルドの起動を確認
% bun install
% bun tauri dev
親の顔より見たデモ画面が立ち上がったらOK
4. ビルドしてみる
% bun tauri build
...
Finished 2 bundles at:
/Users/8beeeaaat/tauri_distribution_sample/src-tauri/target/release/bundle/macos/tauri-app.app
/Users/8beeeaaat/tauri_distribution_sample/src-tauri/target/release/bundle/dmg/tauri-app_0.1.0_aarch64.dmg
ビルドに成功すると src-tauri/target/release/bundle/dmg
に.dmg パッケージが作られます。
マウントするとよく見るインストーラの面構えをしています。早速目標を達成できそう。
このままApplicationsに放り込むとそのまま使うこともできます。
5. アプリ名を変えてみる
- 仮名称にしていたけど正式名称が決まったので変えたい
- 天の声で変えざるを得なくなった
人生いろいろなことがありますので、そんな時は tauri.conf.json を編集します。
{
"$schema": "https://schema.tauri.app/config/2",
- "productName": "tauri-app",
+ "productName": "8beeeaaatのアプリ",
"version": "0.1.0",
"identifier": "com.8beeeaaat.tauri-app",
"build": {
"beforeDevCommand": "bun run dev",
"devUrl": "http://localhost:1420",
"beforeBuildCommand": "bun run build",
"frontendDist": "../dist"
},
"app": {
"windows": [
{. // ウィンドウ名も変更したければ
- "title": "tauri-app",
+ "title": "8beeeaaatのアプリ",
"width": 800,
"height": 600
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}
- インストーラ / アプリケーション名
-
app.windows.title
を変更するとウィンドウ名を変えられる
ユニバーサルアプリ化
build コマンドの target オプションで Intel Mac / Apple Silicon Mac 両対応のユニバーサルアプリとしてビルドさせることができます。
% bun tauri build --target universal-apple-darwin
It must be one of the values outputted by
$rustc --print target-list
oruniversal-apple-darwin
for an universal macOS application.
https://v2.tauri.app/reference/cli/#build
ということでやってみると...
failed to build x86_64-apple-darwin binary: Target x86_64-apple-darwin is not installed (installed targets: aarch64-apple-darwin, aarch64-apple-ios, aarch64-apple-ios-sim, aarch64-linux-android, armv7-linux-androideabi, i686-linux-android, x86_64-apple-ios, x86_64-linux-android). Please run `rustup target add x86_64-apple-darwin`.
Error failed to build x86_64-apple-darwin binary: Target x86_64-apple-darwin is not installed (installed targets: aarch64-apple-darwin, aarch64-apple-ios, aarch64-apple-ios-sim, aarch64-linux-android, armv7-linux-androideabi, i686-linux-android, x86_64-apple-ios, x86_64-linux-android). Please run `rustup target add x86_64-apple-darwin`.
error: script "tauri" exited with code 1
aarch64-apple-darwin(Apple Silicon)用のビルドターゲットだけ設定しているので、 x86_64-apple-darwin も設定せよと怒られています。
指示通りに rustup を設定して再挑戦。
% rustup target add x86_64-apple-darwin
info: downloading component 'rust-std' for 'x86_64-apple-darwin'
info: installing component 'rust-std' for 'x86_64-apple-darwin'
24.9 MiB / 24.9 MiB (100 %) 23.3 MiB/s in 1s ETA: 0s
% bun tauri build --target universal-apple-darwin
...
ユニバーサルアプリとしてのインストーラが完成しました。
src-tauri/target/universal-apple-darwin/release/bundle/dmg/8beeeaaatのアプリ_0.1.0_universal.dmg
両アーキテクチャのバイナリが含まれているのでサイズはほぼ倍ですね。致し方なし。
mainブランチにpushされたらRelease機能で署名済みのインストーラを配布できるようにする
-
GitHub Actions関連のドキュメント
https://v2.tauri.app/distribute/pipelines/github/ -
公式の GitHub Actions
https://github.com/tauri-apps/tauri-action
Releaseで配布する上で最低限の設定だけを紹介していきます
1. Workflow permissionsを書き込み可に変更する
成果物を書き込ませるので、 リポジトリの settings > Code and automation > actions > General
の Workflow permissions を Read and write permissions
に変更する
“Resource not accessible by integration” error when running the workflow. If this happens, you may need to add write permissions to this token. To do this, go to your GitHub project settings, select Actions, scroll down to Workflow permissions, and check “Read and write permissions”.
https://v2.tauri.app/distribute/pipelines/github/#github-environment-token
Saveをお忘れなく
2. Repository secrets に定数を設定する
settings > Security > Secrets and variables > Actions > Repository secrets
認証関連のドキュメント を参考に設定します。(手順を全て説明すると大変なので割愛)
最低限ビルドに必要なもの
- APPLE_ID: Apple Developer Programで使用しているE-mailアドレス
- APPLE_ID_PASSWORD: 同ログインパスワード
- APPLE_CERTIFICATE:
Developer ID Application
Certificateから作成 Creating a signing certificate参照 - APPLE_CERTIFICATE_PASSWORD:
APPLE_CERTIFICATE
の作成過程で自分で決める - KEYCHAIN_PASSWORD: キーチェーンアクセスのパスワード(通常 macOSのログインパスワードと同じはず)
アプリへの署名に必要なもの
- APPLE_PASSWORD: Apple Account管理で「アプリ用パスワード」を発行。
必ずしもパスワードタイトルをアプリID / 名称などと一致させる必要はない
- APPLE_TEAM_ID: Apple Developer ProgramのチームID
https://developer.apple.com/account のページをスクロールすると確認できる
3. 公式サンプルを調整してWorkflow を設定
name: 'publish'
on:
push:
branches:
- main
jobs:
publish-tauri:
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- platform: 'macos-latest' # ユニバーサルアプリとしてビルド
args: '--target universal-apple-darwin'
# 今回はWindows / Linux向けインストーラは作らない
# - platform: 'ubuntu-22.04' # for Tauri v1 you could replace this with ubuntu-20.04.
# args: ''
# - platform: 'windows-latest'
# args: ''
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
# ※ Bun向け: お手元のパッケージマネージャに合わせて依存関係をインストールしてください
- name: Cache Bun modules
uses: actions/cache@v3
with:
path: node_modules
key: bun-modules-${{ hashFiles('bun.lockb') }}
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: install frontend dependencies
run: |
bun install
- name: Cache Cargo registry
uses: actions/cache@v3
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
# Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Prepare for Release
run: |
echo "Preparing release..."
echo "Tagging version..."
# Additional release preparation steps here
- name: Import Apple Developer Certificate (macOS only)
if: matrix.platform == 'macos-latest'
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security set-keychain-settings -t 3600 -u build.keychain
security import certificate.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_PASSWORD" build.keychain
security find-identity -v -p codesigning build.keychain
- name: verify certificate (macOS only)
if: matrix.platform == 'macos-latest'
run: |
CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application")
CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}')
echo "CERT_ID=$CERT_ID" >> $GITHUB_ENV
echo "Certificate imported."
- name: Read version and set env
run: | #tauri.conf.jsonのversion情報をタグに使う
VERSION_TAG=v$(jq -r '.version' < src-tauri/tauri.conf.json)
echo "VERSION_TAG=$VERSION_TAG" >> $GITHUB_ENV
- name: Build and Publish
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }} #証明書から取得したものが適用される
with:
tagName: ${{ env.VERSION_TAG }}
releaseName: 'tauri-app ${{ env.VERSION_TAG }}'
releaseBody: 'See the assets to download this version and install.'
# releaseDraft: true 一旦リリースをドラフトとして作成したい場合はコメントアウトを外す
includeDebug: true
args: ${{ matrix.args }}
- name: Set Version Tag
run: |
if git rev-parse "${{ env.VERSION_TAG }}" >/dev/null 2>&1; then echo "Tag ${{ env.VERSION_TAG }} already exists. Skipping tagging."
else echo "Tagging with version: ${{ env.VERSION_TAG }}"
git tag ${{ env.VERSION_TAG }}
git push origin ${{ env.VERSION_TAG }}
fi
あるあるActionのエラー達
リポジトリ設定の settings > Code and automation > actions > General
の Workflow permissions を Read and write permissions にし忘れていないか確認する
-
Developer ID Application
証明書が存在するか確認する
% security find-identity -v -p codesigning | grep "Developer ID Application"
1) 〜〜〜 "Developer ID Application: ユーザー名 (チームID)"
- APPLE_CERTIFICATE を
Developer ID Application
証明書からエンコードして出力したか確認する
Apple Development と取り違え注意
Releaseされた .dmg を確認
Actionが終了するとReleaseで .dmg が配布されることを確認
リポジトリのReleasesにlatestタグと共に追加される
Releases
ダウンロードした .dmg からインストール / アプリケーションを起動できることを確認
-
ローカル同様、マウントするとインストーラを起動できる
-
Applicationsからそのまま起動できる
初回はWebからダウンロードしたので確認を求められます。致し方なし
めでたしめでたし!!
Tauriを使ってアプリケーション開発をしたい方はご相談ください
Discussion