メインコンテンツにスキップ
バージョン: 次期バージョン 🚧

コード署名

このガイドでは、MacOSおよびWindowsでWailsによって生成されたバイナリに署名するための方法を解説します。 このガイドは、CI環境、とりわけGitHub Actionsを対象としています。

Windows

まず初めに、コード署名証明書が必要となります。 まだ証明書を持っていない場合は、こちらのMicrosoftのページに、いくつかのプロバイダーが紹介されていますので入手してください、 デバイスドライバといったカーネルレベルのソフトウェアを作成する必要がない限り、EV証明書を入手する必要はありません。 Wailsアプリに署名する場合、標準のコード証明書で問題ありません。

自動ビルドシステムを対象に作業する前に、ローカルマシン上でバイナリに署名する方法を証明書プロバイダに確認し、特別な要件がないかを確認することを推奨します。 例えば、こちらはSSL.comのWindows向けコード署名ガイドです。 ローカル環境での署名方法が分かっていれば、CI環境で発生するかもしれない問題のトラブルシューティングが容易になることでしょう。 例えば、SSL.comのコード署名証明書はSignTool.exeにおいて/trフラグを指定する必要がありますが、他の証明書プロバイダでは、タイムスタンプサーバの提供のために、/tフラグのみ必要である場合もあります。 こちらのような、Windowsバイナリの署名によく使われるGitHub Actionsのアクションは、SignTool.exeの/trフラグに対応していません。 したがって、このガイドではPowerShellコマンドを使用して手動でアプリケーションに署名する方法に焦点をあてます。ただし、必要であればcode-sign-actionアクションといったアクションを使用することも可能です。

まずは、GitHub CIでWailsアプリをビルドできるようにしておきましょう。 簡単なワークフローテンプレートは次のとおりです:

name: "example"
on:
workflow_dispatch:
# This Action only starts when you go to Actions and manually run the workflow.

jobs:
package:
strategy:
matrix:
platform: [windows-latest, macos-latest]
go-version: [1.18]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: setup node
uses: actions/setup-node@v2
with:
node-version: 14
# wails.jsonでフロントエンドのビルドおよびインストールコマンドを設定していない場合、ここで手動でフロントエンドをビルドする必要があるかもしれません。
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
run: |
wails build
- name: upload artifacts macOS
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-macos
path: build/bin/*
- name: upload artifacts windows
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-windows
path: build/bin/*

次に、GitHubワークフローに署名証明書へのアクセス権を付与する必要があります。 これは、.pfxまたは.p12形式の証明書をbase64文字列にエンコードすることで実現できます。 PowerShellの場合、証明書名が仮に'my-cert.p12'だとすると、次のコマンドが使用できます:

certutil -encode .\my-cert.p12 my-cert-base64.txt

これで、base64でエンコードされた証明書が含まれる.txtファイルが作成されます。 このファイルの中身は、-----BEGIN CERTIFICATE-----で始まり、-----END CERTIFICATE-----で終わる必要があります。 次に、GitHubで2つのActions secretsを作成します。 Settings -> Secrets -> Actionsのページに移動し、2つのシークレットを作成してください:

  • WIN_SIGNING_CERT には、base64エンコードされた証明書テキストの内容を設定します。
  • WIN_SIGNING_CERT_PASSWORD には、証明書のパスワードを設定します。

ここまでの作業で、次の2つのいずれかの方法を使用して、ワークフローによる署名処理を実装する準備が整いました。

方法1: コマンドを使用して署名

この方法では、Power Shellコマンドを使用してアプリに署名し、署名プロセス全体をコントロールします。

"Build Wails app"ステップのあとに、下記のステップをワークフローに追加してください。

- name: Sign Windows binaries
if: matrix.platform == 'windows-latest'
run: |
echo "Creating certificate file"
New-Item -ItemType directory -Path certificate
Set-Content -Path certificate\certificate.txt -Value '${{ secrets.WIN_SIGNING_CERT }}'
certutil -decode certificate\certificate.txt certificate\certificate.pfx
echo "Signing our binaries"
& 'C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe' sign /fd <signing algorithm> /t <timestamping server> /f certificate\certificate.pfx /p '${{ secrets.WIN_SIGNING_CERT_PASSWORD }}' <path to binary>

このスクリプトでは、証明書ファイル用に新しいディレクトリを作成して、base64シークレットから証明書ファイルを作成します。その証明書を.pfxファイルに変換し、最後にバイナリへ署名します。 下記の変数は、最後の行内で置換してください:

  • signing algorithm: 通常は、sha256。
  • timestamping server: 証明書で使用するタイムスタンプサーバのURL。
  • path to binary: 署名したいバイナリへのパス。

Wailsの構成においてoutputfilenameに"app.exe"という値が設定されており、SSL.comでの証明書が用意されている場合、次のようなワークフローとなります:

name: "example"
on:
workflow_dispatch:
# This Action only starts when you go to Actions and manually run the workflow.

jobs:
package:
strategy:
matrix:
platform: [windows-latest, macos-latest]
go-version: [1.18]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: setup node
uses: actions/setup-node@v2
with:
node-version: 14
# wails.jsonでフロントエンドのビルドおよびインストールコマンドを設定していない場合、ここで手動でフロントエンドをビルドする必要があるかもしれません。
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
run: |
wails build
- name: Sign Windows binaries
if: matrix.platform == 'windows-latest'
run: |
echo "Creating certificate file"
New-Item -ItemType directory -Path certificate
Set-Content -Path certificate\certificate.txt -Value '${{ secrets.WIN_SIGNING_CERT }}'
certutil -decode certificate\certificate.txt certificate\certificate.pfx
echo "Signing our binaries"
& 'C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe' sign /fd sha256 /tr http://ts.ssl.com /f certificate\certificate.pfx /p '${{ secrets.WIN_SIGNING_CERT_PASSWORD }}' .\build\bin\app.exe

- name: upload artifacts macOS
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-macos
path: build/bin/*
- name: upload artifacts windows
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-windows
path: build/bin/*

方法2: アクションを使用して自動的に署名

こちらのようなWindowsコード署名のためのアクションを使用することはできますが、証明書用のSHA1ハッシュや証明書名が必要であることに注意してください。 詳しくは、アクションのマーケットプレイスで、使用方法を確認してください。


MacOS

まずは、Appleのコード署名証明書が必要です。 もし所有していない場合は、Googleで検索すれば取得方法が分るでしょう。 証明書を入手できたら、それをエクスポートし、base64でエンコードする必要があります。 このチュートリアルをご覧いただければ、簡単にエンコードする方法が分ります。 .p12証明書ファイルをエクスポートした場合、次のコマンドを使用して、チュートリアルで示されているようにbase64にエンコードできます:

base64 Certificates.p12 | pbcopy

これにより、Windowsと同様に、GitHubプロジェクトにいくつかのシークレットを設定する準備が整いました:

  • APPLE_DEVELOPER_CERTIFICATE_P12_BASE64には、新しくコピーしたbase64証明書の内容を設定します。
  • APPLE_DEVELOPER_CERTIFICATE_PASSWORDには、証明書のパスワードを設定します。
  • APPLE_PASSWORDには、こちらで生成できるアプリ固有のパスワードを設定します。

GitHub Actionのワークフローで、Wailsアプリをビルドできるようにしましょう。 簡単な例は次のとおりです:

name: "example"
on:
workflow_dispatch:
# This Action only starts when you go to Actions and manually run the workflow.

jobs:
package:
strategy:
matrix:
platform: [windows-latest, macos-latest]
go-version: [1.18]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: setup node
uses: actions/setup-node@v2
with:
node-version: 14
# wails.jsonでフロントエンドのビルドおよびインストールコマンドを設定していない場合、ここで手動でフロントエンドをビルドする必要があるかもしれません。
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
run: |
wails build
- name: upload artifacts macOS
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-macos
path: build/bin/*
- name: upload artifacts windows
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-windows
path: build/bin/*

macOSでコード署名をするときは、gonという非常に便利なツールを使うことで、コード署名およびAppleサーバとの通信ができます。これはGoで記述されており、このガイドでも使用されています。

Build Wails appステップの後に、次のワークフローを追加します:

- name: MacOS download gon for code signing and app notarization
if: matrix.platform == 'macos-latest'
run: |
brew install mitchellh/gon/gon

ここで、build/darwinディレクトリ内に、gonの構成設定ファイルを用意する必要があります:

  1. gon-sign.json:
{
"source": ["./build/bin/app.app"],
"bundle_id": "app.myapp",
"apple_id": {
"username": "my-appleid@email.com",
"password": "@env:APPLE_PASSWORD"
},
"sign": {
"application_identity": "Developer ID Application: My Name"
}
}

sourceにはWailsのバイナリファイルの場所、bundle_idにはバンドルID、apple_idにはあらかじめ作成したApple IDのユーザ名とアプリ固有のパスワード、sign.application_identityには次のコマンドを実行することで分かるIDを指定します:

security find-identity -v -p codesigning
  1. entitlements.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
</dict>
</plist>

このファイルでは、アプリに必要な権限(たとえば、アプリがカメラを使用する場合、カメラへのアクセス権限)を設定します。 権限について詳しくはこちらをご覧ください。

Info.plistファイルのバンドルIDを、gon-sign.jsonに入力したものと同じIDに書き換えてください。 次は、Info.plistファイルの例です:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>CFBundlePackageType</key><string>APPL</string>
<key>CFBundleName</key><string>MyApp</string>
<key>CFBundleExecutable</key><string>app</string>
<key>CFBundleIdentifier</key><string>app.myapp</string>
<key>CFBundleVersion</key><string>0.1.0</string>
<key>CFBundleGetInfoString</key><string>My app is cool and nice and chill and</string>
<key>CFBundleShortVersionString</key><string>0.1.0</string>
<key>CFBundleIconFile</key><string>iconfile</string>
<key>LSMinimumSystemVersion</key><string>10.13.0</string>
<key>NSHighResolutionCapable</key><string>true</string>
<key>LSApplicationCategoryType</key><string>public.app-category.utilities</string>
<key>NSHumanReadableCopyright</key><string>© Me</string>
</dict></plist>

これで、Wailsアプリをビルドしたあとに、ワークフローに署名のステップを追加する準備ができました:

- name: Import Code-Signing Certificates for macOS
if: matrix.platform == 'macos-latest'
uses: Apple-Actions/import-codesign-certs@v1
with:
# The certificates in a PKCS12 file encoded as a base64 string
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }}
# The password used to import the PKCS12 file.
p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }}
- name: Sign our macOS binary
if: matrix.platform == 'macos-latest'
run: |
echo "Signing Package"
gon -log-level=info ./build/darwin/gon-sign.json

Appleでバイナリに署名する場合、数分から数時間程度の所要時間がかかることがありますのでご注意ください。

ワークフローファイルの組み合わせ

WindowsとmacOSを組み合わせたGitHubワークフローファイルの例は次のとおりです:

name: "example combined"
on:
workflow_dispatch:
# This Action only starts when you go to Actions and manually run the workflow.

jobs:
package:
strategy:
matrix:
platform: [windows-latest, macos-latest]
go-version: [1.18]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: setup node
uses: actions/setup-node@v2
with:
node-version: 14
# wails.jsonでフロントエンドのビルドおよびインストールコマンドを設定していない場合、ここで手動でフロントエンドをビルドする必要があるかもしれません。
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
run: |
wails build
- name: MacOS download gon for code signing and app notarization
if: matrix.platform == 'macos-latest'
run: |
brew install mitchellh/gon/gon
- name: Import Code-Signing Certificates for macOS
if: matrix.platform == 'macos-latest'
uses: Apple-Actions/import-codesign-certs@v1
with:
# The certificates in a PKCS12 file encoded as a base64 string
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }}
# The password used to import the PKCS12 file.
p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }}
- name: Sign our macOS binary
if: matrix.platform == 'macos-latest'
run: |
echo "Signing Package"
gon -log-level=info ./build/darwin/gon-sign.json
- name: Sign Windows binaries
if: matrix.platform == 'windows-latest'
run: |
echo "Creating certificate file"
New-Item -ItemType directory -Path certificate
Set-Content -Path certificate\certificate.txt -Value '${{ secrets.WIN_SIGNING_CERT }}'
certutil -decode certificate\certificate.txt certificate\certificate.pfx
echo "Signing our binaries"
& 'C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe' sign /fd sha256 /tr http://ts.ssl.com /f certificate\certificate.pfx /p '${{ secrets.WIN_SIGNING_CERT_PASSWORD }}' .\build\bin\Monitor.exe
- name: upload artifacts macOS
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-macos
path: build/bin/*
- name: upload artifacts windows
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-windows
path: build/bin/*

おわりに

このガイドは、RiftShareプロジェクトとそのワークフローに触発されて作成されたものであり、 こちらを併せて確認することを強く推奨します。