Signature du code
Ceci est un guide sur la façon dont vous pouvez signer vos binaires générés avec Wails sur MacOS et Windows. Le guide ciblera les environnements CI, plus particulièrement les actions GitHub.
Windows
Tout d'abord, vous avez besoin d'un certificat de signature de code. Si vous n'en avez pas déjà une, la page d'information de Microsoft répertorie certains fournisseurs ici. Veuillez noter qu'un certificat EV n'est pas requis à moins que vous n'ayez besoin d'écrire un logiciel au niveau du noyau tel que les pilotes de périphériques. Pour signer votre application Wails, un certificat standard de signature de code fera très bien.
Il peut être judicieux de vérifier auprès de votre fournisseur de certificat comment signer vos binaires sur votre machine locale avant de cibler les systèmes de compilation automatisés afin que vous soyez au courant des exigences particulières qu'il peut demander. Par exemple, ici se trouve le guide de signature de code de SSL.com pour Windows. Si vous savez comment signer localement, il sera plus facile de de résoudre tous les problèmes potentiels dans un environnement CI. Par exemple, les certificats de signature de code SSL.com requièrent le flag /tr pour SignTool.exe alors que les autres fournisseurs n'ont besoin que du flag /t pour fournir le serveur d'horodatage. Les GitHub actions populaires pour la signature de binaires Windows comme celui-ci, ne prennent pas en charge le flag /tr sur SignTool.exe. Par conséquent, ce guide se concentrera sur la signature manuelle de notre application avec les commandes PowerShell, mais vous pouvez utiliser des actions comme code-sign-action si vous préférez.
Tout d'abord, assurons-nous que nous sommes en mesure de construire notre application Wails dans notre GitHub CI. Voici un petit modèle de workflow :
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
# Vous pouvez avoir besoin de construire votre frontend manuellement ici, sauf si vous avez configuré les commandes frontend build et install dans 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/*
Ensuite, nous devons donner accès au workflow GitHub à notre certificat de signature. Ceci est fait en encodant votre certificat .pfx ou .p12 en une chaîne de caractères base64. Pour faire cela dans PowerShell, vous pouvez utiliser la commande suivante en supposant que votre certificat est appelé 'my-cert.p12':
certutil -encode .\my-cert.p12 my-cert-base64.txt
Vous devriez maintenant avoir votre fichier .txt avec le certificat encodé en base64. Il devrait commencer par -----BEGIN CERTIFICATE----- et se terminer par -----END CERTIFICATE-----. Maintenant, vous devez faire deux secrets pour les GitHub actions sur GitHub. Naviguez vers Paramètres -> Secrets -> Actions et créez les deux secrets suivants :
- WIN_SIGNING_CERT avec le contenu de votre texte de certificat encodé en base64.
- WIN_SIGNING_CERT_PASSWORD avec votre mot de passe de certificat.
Maintenant, nous sommes prêts à implémenter la signature dans notre workflow en utilisant l'une des deux méthodes :
Méthode 1 : signer en ligne de commande
Cette méthode utilise des commandes PowerShell pour signer notre application et vous laisse le contrôle sur l'ensemble du processus de signature.
Après l'étape "Build Wails app" , nous pouvons ajouter l'étape suivante à notre flux de travail:
- 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>
Ce script crée un nouveau répertoire pour votre fichier de certificat, crée le fichier de certificat à partir de notre secret en base64, le convertit en un fichier .pfx, et signe le binaire. Les variables suivantes doivent être remplacées dans la dernière ligne:
- signing algorithm: généralement sha256.
- timestamping server: URL du serveur d'horodatage à utiliser avec votre certificat.
- path to binary: chemin vers le binaire que vous voulez signer.
Étant donné que notre configuration de Wails a outputfilename avec la valeur "app.exe" et que nous avons un certificat de SSL.com, ce serait notre workflow:
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
# Vous avez potentiellement besoin de build votre frontend ici, sauf si vous avez configuré les commandes de build et d'installation dans 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/*
Méthode 2 : signature automatique avec GitHub Action
Il est possible d'utiliser une action de signature de code Windows comme ceci, mais notez que cela nécessite un hachage SHA1 pour le certificat et un nom de certificat. Voici un exemple dans le marketplace de GitHub Action pour le configurer.
MacOS
Tout d'abord, vous avez besoin de votre certificat de signature de code d'Apple. Si vous n'en avez pas, une simple recherche Google vous aidera pour savoir comment en acquérir un. Une fois que vous avez votre certificat, vous devez l'exporter et l'encoder en base64. Ce tutoriel vous montre comment faire ça facilement. Une fois que vous avez exporté votre fichier de certificat .p12, vous pouvez l'encoder en base64 comme vu dans le tutoriel avec la commande suivante:
base64 Certificates.p12 | pbcopy
Maintenant vous êtes prêt à créer des secrets de projet GitHub, tout comme avec Windows:
- APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 avec le contenu de votre certificat base64 nouvellement copié.
- APPLE_DEVELOPER_CERTIFICATE_PASSWORD avec votre mot de passe de certificat.
- APPLE_PASSWORD avec le contenu d'un mot de passe App-Specific à votre compte Apple-ID que vous pouvez générer ici.
Veillons à ce que nous puissions construire notre application Wails dans notre flux de travail GitHub Action. Voici un petit modèle :
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
# Vous avez potentiellement besoin de build votre frontend ici, sauf si vous avez configuré les commandes de build et d'installation dans 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/*
Pour la signature de code sur macOS, gon est un outil très pratique pour la signature de code et la communication avec les serveurs Apple, également écrit en Go, et sera utilisé dans ce guide.
Après l'étape "Build Wails app" , nous pouvons ajouter l'étape suivante à notre flux de travail:
- name: Gon de téléchargement MacOS pour la signature de code et la notariation des applications
if: matrix.platform == 'macos-latest'
run: |
brew install Bearer/tap/gon
Maintenant, nous devons configurer quelques fichiers de configuration gon dans notre répertoire build/darwin:
- gon-sign.json:
{
"source": ["./build/bin/app.app"],
"bundle_id": "app.myapp",
"apple_id": {
"password": "your-app-specific-password",
"provider": "ABCDE12345"
},
"sign": {
"application_identity": "Developer ID Application: Human User"
}
}
Voici une brève description des champs ci-dessus :
source: L'emplacement de votre binaire wails à signerapple_id:username: votre adresse e-mail Apple IDDeveloper: Votre mot de passe spécifique à l'applicationDeveloper: votre ID d'équipe pour votre compte App Store Connect
sign:application_identity: votre identité de développeur Apple
L'outil déprécié d'Apple (https://developer.apple.com/documentation/technotes/tn3147-migrating-to-the-latest-notarization-tool)[altool] avec la syntaxe supportant @env: n'est plus disponible depuis que Apple a migré vers le nouvel outil de notaire.
Votre identité de développeur et votre ID d'équipe peuvent tous les deux être trouvés sur macOS en exécutant la commande suivante :
$ security find-identity -v -p codesigning
1) 00000000000000000000000000000000000000000 "Developer ID Application: Human User (ABCDE12345)"
- 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>
Dans ce fichier, vous configurez les droits dont vous avez besoin pour l'application, par exemple les autorisations d'accès à l'appareil photo si votre application utilise la caméra. En savoir plus sur les droits ici.
Assurez-vous d'avoir mis à jour votre fichier Info.plist avec le même ID de bundle que vous avez entré dans gon-sign.json. Voici un exemple de fichier 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>
Maintenant nous sommes prêts à ajouter l'étape de signature dans notre workflow après la construction de l'application 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
Veuillez noter que la signature de binaires avec Apple peut prendre entre quelques minutes à quelques heures.
Fichier de workflow combiné :
Voici notre fichier de workflow GitHub avec Windows + macOS combiné :
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
# Vous avez potentiellement besoin de build votre frontend ici, sauf si vous avez configuré les commandes de build et d'installation dans wails.json.
- name: Récupération de Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build de l'application Wails
run: |
wails build
- name: Téléchagement de gon pour la signature du code et la notarisation sur MacOS
if: matrix.platform == 'macos-latest'
run: |
brew install Bearer/tap/gon
- name: Import des certificats de signature du code pour macOS
if: matrix.platform == 'macos-latest'
uses: Apple-Actions/import-codesign-certs@v1
with:
# Le certificat PKCS12 encodé en base64
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }}
# Le mot de passe utilisé pour importer le fichier PKCS12
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/*
Notes de fin
Ce guide inspiré du projet RiftShare et de son flux de travail, qui est fortement recommandé de consulter ici.