bots-garden/sidekickspublic Fork
⑂ v1.2.0
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/sidekicks.git
git clone ssh://git@rickub.com/bots-garden/sidekicks.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
🛟 Updated. 8c38c6e · on v1.2.0 · k33g · yesterday
signer-et-notariser-sous-macos.md · 211 lines · 12.9 KBmarkdown
Blame HistoryOpen raw

Signer et notariser Sidekicks pour macOS

Ce guide montre comment signer Sidekicks avec un certificat Developer ID et le faire notariser par Apple, pour qu'il s'ouvre sur n'importe quel Mac sans passer par Ouvrir quand même. Il suppose une adhésion payante à l'Apple Developer Program dont vous êtes le titulaire du compte (Account Holder : seul ce rôle peut créer un certificat Developer ID), un Mac Apple Silicon avec les outils de développement du projet (Développer l'application), et une release déjà construite comme le décrit RELEASING.fr.md.

  • La partie A se fait une seule fois (compter 30 minutes).
  • La partie B se fait à chaque release, après make release-build, tant que la signature n'est pas automatisée (issue #58). Comptez 10 à 20 minutes, surtout de l'attente chez Apple.

Gardez une fenêtre du Terminal ouverte à la racine du dépôt.

Ce que font signature et notarisation

Étape Outil Ce qu'elle apporte
Signer codesign avec votre certificat Developer ID macOS sait qui a fait l'app et qu'elle n'a pas été modifiée
Runtime renforcé codesign --options runtime exigé par Apple pour notariser
Notariser xcrun notarytool Apple analyse l'app et délivre un « ticket »
Agrafer xcrun stapler le ticket est collé à l'app et au .dmg : Gatekeeper l'accepte même hors ligne

L'app et le .dmg sont signés, notarisés et agrafés. Le .zip contient l'app agrafée.

Partie A — une seule fois

A1. Relever votre Team ID

  1. Ouvrez developer.apple.com/account, section Membership details.
  2. Notez le Team ID (10 caractères, par exemple AB12CD34EF).

A2. Créer le certificat Developer ID Application

Avec Xcode (le plus simple) :

  1. Ouvrez Xcode → Settings… → Accounts. S'il n'y est pas, cliquez sur +, choisissez Apple ID et connectez-vous avec l'adresse e-mail et le mot de passe de votre compte Apple Developer (l'Apple ID, pas le Team ID).
  2. Votre équipe apparaît sous le compte, avec son Team ID : sélectionnez-la, cliquez sur Manage Certificates….
  3. Cliquez sur + en bas à gauche, puis Developer ID Application.

Sans Xcode :

  1. Ouvrez Trousseaux d'accès → Assistant de certification → Demander un certificat à une autorité de certification…, indiquez votre adresse, cochez Enregistré sur le disque. Vous obtenez un fichier .certSigningRequest.
  2. Sur developer.apple.com/account/resources/certificates, choisissez Developer ID Application, profil G2 Sub-CA, envoyez le fichier de demande, puis téléchargez le certificat.
  3. Double-cliquez sur le fichier .cer : il rejoint le trousseau session.

A3. Vérifier que le certificat est utilisable

security find-identity -v -p codesigning

Une ligne "Developer ID Application: Prénom Nom (AB12CD34EF)" doit apparaître. C'est votre identité de signature : copiez-la exactement, guillemets exclus.

Si elle manque, ou s'affiche avec CSSMERR_TP_NOT_TRUSTED, installez le certificat intermédiaire Developer ID - G2 depuis apple.com/certificateauthority, puis relancez la commande.

A4. Sauvegarder le certificat et sa clé

La clé privée n'existe que sur ce Mac : sans sauvegarde, une panne oblige à révoquer le certificat et à en refaire un.

  1. Dans Trousseaux d'accès, trousseau session, catégorie Mes certificats, dépliez Developer ID Application: … (la clé apparaît dessous).
  2. Sélectionnez le certificat, Fichier → Exporter les éléments…, format .p12, choisissez un mot de passe.
  3. Rangez le .p12 et son mot de passe dans votre gestionnaire de mots de passe. Ne le mettez jamais dans le dépôt.

A5. Créer un mot de passe d'application pour la notarisation

  1. Ouvrez account.apple.com, Connexion et sécurité → Mots de passe pour les apps.
  2. Créez-en un nommé sidekicks-notary et copiez-le (il ne sera plus affiché).

A6. Enregistrer le profil de notarisation dans le trousseau

xcrun notarytool store-credentials sidekicks-notary \
  --apple-id "vous@example.com" \
  --team-id "AB12CD34EF"

Collez le mot de passe d'application quand il est demandé. Vérifiez :

xcrun notarytool history --keychain-profile sidekicks-notary

Une liste (vide la première fois) s'affiche, sans erreur d'authentification.

A7. Définir les deux variables

Ajoutez à votre ~/.zshrc, puis ouvrez un nouveau Terminal :

export SIDEKICKS_SIGN_IDENTITY="Developer ID Application: Prénom Nom (AB12CD34EF)"
export SIDEKICKS_NOTARY_PROFILE="sidekicks-notary"

La partie B les utilise ; l'automatisation (issue #58) les utilisera aussi.

A8. Garder l'identifiant de l'app

CFBundleIdentifier vaut com.k33g.sidekicks dans build/darwin/Info.plist (et Info.dev.plist). Ne le changez plus : macOS y rattache les autorisations accordées à l'app.

Partie B — à chaque release

Mettez d'abord en pause la synchronisation si le dépôt est dans un dossier synchronisé (kDrive, iCloud Drive, Dropbox…) : elle modifie les fichiers pendant que codesign et stapler les réécrivent, ce qui casse les signatures et donne des .dmg « endommagés ». Tout se fait ensuite dans un dossier de travail, bin/sign (ignoré par git).

B1. Construire la release

Comme d'habitude (RELEASING.fr.md, étapes Avant et 1) :

make release-build                 # ou SKIP=windows make release-build pour une release macOS seule

dist/ contient les paquets non signés, et bin/sidekicks.app l'app signée en ad hoc.

B2. Copier l'app dans le dossier de travail

W="$PWD/bin/sign"
rm -rf "$W" && mkdir -p "$W"
ditto bin/sidekicks.app "$W/sidekicks.app"

Gardez ce Terminal ouvert, à la racine du dépôt : les étapes suivantes utilisent $W. Si la synchronisation ne peut pas être mise en pause, prenez plutôt W="$(mktemp -d /tmp/sidekicks-sign.XXXXXX)".

B3. Signer l'app

xattr -cr "$W/sidekicks.app"
codesign --force --options runtime --timestamp \
  --sign "$SIDEKICKS_SIGN_IDENTITY" "$W/sidekicks.app"
codesign --verify --strict --verbose=2 "$W/sidekicks.app"
codesign -dv --verbose=4 "$W/sidekicks.app" 2>&1 | grep -E "Authority=Developer ID Application|flags=.*runtime|Timestamp="

La dernière commande doit afficher l'autorité Developer ID Application, le drapeau runtime et une ligne Timestamp.

B4. Notariser l'app et agrafer le ticket

ditto -c -k --keepParent "$W/sidekicks.app" "$W/notarize.zip"
xcrun notarytool submit "$W/notarize.zip" --keychain-profile "$SIDEKICKS_NOTARY_PROFILE" --wait
xcrun stapler staple "$W/sidekicks.app"
spctl -a -vvv -t exec "$W/sidekicks.app"

notarytool attend la réponse d'Apple (quelques minutes) et doit finir par status: Accepted. spctl doit dire accepted et source=Notarized Developer ID.

B5. Faire le .dmg à partir de l'app agrafée

wails3 tool package --format dmg --name sidekicks --out "$W" \
  --background build/darwin/dmg-background.png \
  --volume-icon build/darwin/icons.icns \
  --file-icon build/darwin/dmg-file-icon.icns \
  --window-width 540 --window-height 380
hdiutil verify "$W/sidekicks.dmg"

La commande se lance depuis la racine du dépôt (pour les images) mais lit l'app et écrit le .dmg dans $W, avec la même mise en page que make release-build. hdiutil verify doit finir par checksum … is VALID.

B6. Signer, notariser et agrafer le .dmg

codesign --force --timestamp --sign "$SIDEKICKS_SIGN_IDENTITY" "$W/sidekicks.dmg"
xcrun notarytool submit "$W/sidekicks.dmg" --keychain-profile "$SIDEKICKS_NOTARY_PROFILE" --wait
xcrun stapler staple "$W/sidekicks.dmg"
hdiutil verify "$W/sidekicks.dmg"
spctl -a -vvv -t open --context context:primary-signature "$W/sidekicks.dmg"
hdiutil attach -nobrowse -readonly "$W/sidekicks.dmg" && hdiutil detach "/Volumes/sidekicks"

spctl doit dire accepted et source=Notarized Developer ID ; le .dmg doit se monter puis se démonter sans erreur. Si le volume ne s'appelle pas sidekicks, détachez celui que hdiutil attach a affiché.

B7. Remplacer les paquets macOS de dist/ et recalculer les sommes

DMG=$(scripts/package.sh names macos arm64 | sed -n 1p)   # le .dmg et le .zip, avec la version de build/config.yml
ZIP=$(scripts/package.sh names macos arm64 | sed -n 2p)
echo "$W · $DMG · $ZIP"                                    # aucune des trois valeurs ne doit être vide
rm -f dist/sidekicks.dmg                                   # un reste éventuel d'une copie ratée
cp "$W/sidekicks.dmg" "dist/$DMG"
rm -f "dist/$ZIP" && ditto -c -k --keepParent "$W/sidekicks.app" "dist/$ZIP"
cmp "$W/sidekicks.dmg" "dist/$DMG" && echo "copie identique"
spctl -a -vvv -t open --context context:primary-signature "dist/$DMG"   # accepted · Notarized Developer ID
(cd dist && rm -f SHA256SUMS && shasum -a 256 -- * > "$W/SHA256SUMS") && cp "$W/SHA256SUMS" dist/SHA256SUMS
cat dist/SHA256SUMS

Ne passez pas à la suite si cmp signale une différence ou si spctl refuse : dist/ contiendrait encore le .dmg non signé de B1, et la release aussi.

B8. Essayer sur un autre Mac

  1. Copiez le .dmg sur un autre Mac (ou un autre compte utilisateur), par le web ou AirDrop : il doit porter l'attribut de quarantaine d'un vrai téléchargement.
  2. Ouvrez-le, glissez sidekicks dans Applications, lancez-le : il s'ouvre directement, sans Ouvrir quand même.
  3. Faites le tour de ce que le runtime renforcé pourrait gêner : un agent local, un agent en conteneur ou en sbx, l'onglet Terminal, l'ouverture d'un fichier, le glisser-déposer, Settings → Open….

B9. Taguer et publier

Suivez la suite de RELEASING.fr.md (étapes 2 à 4) : les fichiers à attacher sont ceux de dist/. Une fois la release publiée, téléchargez son .dmg et vérifiez que shasum -a 256 donne la même somme que SHA256SUMS (un envoi tronqué donne aussi « image endommagée »). Supprimez ensuite $W et relancez la synchronisation.

Variantes

  • Release macOS à part, sur une version déjà publiée (par exemple v1.0.0-macos, issue #57) : ne changez pas info.version (l'app reste la 1.0.0 ; Windows refuse une version qui n'est pas faite de nombres, Apple aussi pour CFBundleShortVersionString, et les paquets s'appelleraient …-1.0.0-macos-macos-…). Construisez seulement macOS avec SKIP=windows make release-build, faites la partie B, puis créez le tag à la main : git tag -a v1.0.0-macos -m "Sidekicks 1.0.0, macOS signé et notarisé" && git push origin v1.0.0-macos. Le workflow Release démarre et s'arrête à sa vérification (le tag n'est pas v + la version de build/config.yml) : c'est attendu. Créez la release sur Rickub depuis ce tag et attachez le .dmg, le .zip et SHA256SUMS. Vous pouvez aussi simplement remplacer les fichiers macOS de la release v1.0.0.
  • La notarisation est refusée (status: Invalid) : xcrun notarytool log <id> --keychain-profile "$SIDEKICKS_NOTARY_PROFILE" donne la raison. Les plus courantes : signature sans --options runtime ou sans --timestamp, ou un fichier non signé dans l'app.
  • « L'image disque est endommagée » à l'ouverture du .dmg : il a été modifié après sa signature (dossier synchronisé) ou tronqué (envoi, téléchargement). hdiutil verify sur le fichier et shasum -a 256 comparé à SHA256SUMS disent lequel. Refaites B2 à B7 avec la synchronisation en pause (ou avec $W dans /tmp).
  • codesign refuse (« resource fork, Finder information, or similar detritus ») : l'app vient d'un dossier synchronisé, qui ajoute des métadonnées. xattr -cr "$W/sidekicks.app" puis recommencez B3.
  • L'app signée ne démarre pas ou une fonction ne marche plus : le runtime renforcé bloque quelque chose. Lisez Console.app au lancement ; si un droit précis manque, ajoutez un fichier d'entitlements (--entitlements build/darwin/entitlements.plist dans B2) avec seulement ce droit, et notez-le dans l'issue #57.
  • Vérifier une app installée : spctl -a -vvv /Applications/sidekicks.app et xcrun stapler validate /Applications/sidekicks.app.
  • Un autre Mac pour construire : importez le .p12 (double-clic), puis refaites A6 et A7.
  • Le .dmg à refaire, l'app déjà notarisée : si $W/sidekicks.app est encore là et que xcrun stapler validate "$W/sidekicks.app" réussit, reprenez directement à B5.

Voir aussi

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# Signer et notariser Sidekicks pour macOS

Ce guide montre comment signer Sidekicks avec un certificat **Developer ID** et le faire **notariser** par Apple, pour qu'il s'ouvre sur n'importe quel Mac sans passer par **Ouvrir quand même**. Il suppose une adhésion payante à l'Apple Developer Program dont vous êtes le **titulaire du compte** (Account Holder : seul ce rôle peut créer un certificat Developer ID), un Mac Apple Silicon avec les outils de développement du projet ([Développer l'application](developper-l-application.md)), et une release déjà construite comme le décrit [RELEASING.fr.md](../../../RELEASING.fr.md).

- La **partie A** se fait **une seule fois** (compter 30 minutes).
- La **partie B** se fait **à chaque release**, après `make release-build`, tant que la signature n'est pas automatisée (issue #58). Comptez 10 à 20 minutes, surtout de l'attente chez Apple.

Gardez une fenêtre du Terminal ouverte à la racine du dépôt.

## Ce que font signature et notarisation

| Étape | Outil | Ce qu'elle apporte |
| --- | --- | --- |
| Signer | `codesign` avec votre certificat Developer ID | macOS sait qui a fait l'app et qu'elle n'a pas été modifiée |
| Runtime renforcé | `codesign --options runtime` | exigé par Apple pour notariser |
| Notariser | `xcrun notarytool` | Apple analyse l'app et délivre un « ticket » |
| Agrafer | `xcrun stapler` | le ticket est collé à l'app et au `.dmg` : Gatekeeper l'accepte même hors ligne |

L'app **et** le `.dmg` sont signés, notarisés et agrafés. Le `.zip` contient l'app agrafée.

## Partie A — une seule fois

### A1. Relever votre Team ID

1. Ouvrez [developer.apple.com/account](https://developer.apple.com/account), section **Membership details**.
2. Notez le **Team ID** (10 caractères, par exemple `AB12CD34EF`).

### A2. Créer le certificat Developer ID Application

Avec Xcode (le plus simple) :

1. Ouvrez **Xcode → Settings… → Accounts**. S'il n'y est pas, cliquez sur **+**, choisissez **Apple ID** et connectez-vous avec l'adresse e-mail et le mot de passe de votre compte Apple Developer (l'Apple ID, pas le Team ID).
2. Votre équipe apparaît sous le compte, avec son Team ID : sélectionnez-la, cliquez sur **Manage Certificates…**.
3. Cliquez sur **+** en bas à gauche, puis **Developer ID Application**.

Sans Xcode :

1. Ouvrez **Trousseaux d'accès → Assistant de certification → Demander un certificat à une autorité de certification…**, indiquez votre adresse, cochez **Enregistré sur le disque**. Vous obtenez un fichier `.certSigningRequest`.
2. Sur [developer.apple.com/account/resources/certificates](https://developer.apple.com/account/resources/certificates/add), choisissez **Developer ID Application**, profil **G2 Sub-CA**, envoyez le fichier de demande, puis téléchargez le certificat.
3. Double-cliquez sur le fichier `.cer` : il rejoint le trousseau **session**.

### A3. Vérifier que le certificat est utilisable

```bash
security find-identity -v -p codesigning
```

Une ligne `"Developer ID Application: Prénom Nom (AB12CD34EF)"` doit apparaître. C'est votre **identité de signature** : copiez-la exactement, guillemets exclus.

Si elle manque, ou s'affiche avec `CSSMERR_TP_NOT_TRUSTED`, installez le certificat intermédiaire **Developer ID - G2** depuis [apple.com/certificateauthority](https://www.apple.com/certificateauthority/), puis relancez la commande.

### A4. Sauvegarder le certificat et sa clé

La clé privée n'existe que sur ce Mac : sans sauvegarde, une panne oblige à révoquer le certificat et à en refaire un.

1. Dans **Trousseaux d'accès**, trousseau **session**, catégorie **Mes certificats**, dépliez **Developer ID Application: …** (la clé apparaît dessous).
2. Sélectionnez le certificat, **Fichier → Exporter les éléments…**, format **.p12**, choisissez un mot de passe.
3. Rangez le `.p12` et son mot de passe dans votre gestionnaire de mots de passe. Ne le mettez jamais dans le dépôt.

### A5. Créer un mot de passe d'application pour la notarisation

1. Ouvrez [account.apple.com](https://account.apple.com), **Connexion et sécurité → Mots de passe pour les apps**.
2. Créez-en un nommé `sidekicks-notary` et copiez-le (il ne sera plus affiché).

### A6. Enregistrer le profil de notarisation dans le trousseau

```bash
xcrun notarytool store-credentials sidekicks-notary \
  --apple-id "vous@example.com" \
  --team-id "AB12CD34EF"
```

Collez le mot de passe d'application quand il est demandé. Vérifiez :

```bash
xcrun notarytool history --keychain-profile sidekicks-notary
```

Une liste (vide la première fois) s'affiche, sans erreur d'authentification.

### A7. Définir les deux variables

Ajoutez à votre `~/.zshrc`, puis ouvrez un nouveau Terminal :

```bash
export SIDEKICKS_SIGN_IDENTITY="Developer ID Application: Prénom Nom (AB12CD34EF)"
export SIDEKICKS_NOTARY_PROFILE="sidekicks-notary"
```

La partie B les utilise ; l'automatisation (issue #58) les utilisera aussi.

### A8. Garder l'identifiant de l'app

`CFBundleIdentifier` vaut `com.k33g.sidekicks` dans `build/darwin/Info.plist` (et `Info.dev.plist`). Ne le changez plus : macOS y rattache les autorisations accordées à l'app.

## Partie B — à chaque release

**Mettez d'abord en pause la synchronisation** si le dépôt est dans un dossier synchronisé (kDrive, iCloud Drive, Dropbox…) : elle modifie les fichiers pendant que `codesign` et `stapler` les réécrivent, ce qui casse les signatures et donne des `.dmg` « endommagés ». Tout se fait ensuite dans un dossier de travail, `bin/sign` (ignoré par git).

### B1. Construire la release

Comme d'habitude ([RELEASING.fr.md](../../../RELEASING.fr.md), étapes Avant et 1) :

```bash
make release-build                 # ou SKIP=windows make release-build pour une release macOS seule
```

`dist/` contient les paquets non signés, et `bin/sidekicks.app` l'app signée en ad hoc.

### B2. Copier l'app dans le dossier de travail

```bash
W="$PWD/bin/sign"
rm -rf "$W" && mkdir -p "$W"
ditto bin/sidekicks.app "$W/sidekicks.app"
```

Gardez ce Terminal ouvert, à la racine du dépôt : les étapes suivantes utilisent `$W`. Si la synchronisation ne peut pas être mise en pause, prenez plutôt `W="$(mktemp -d /tmp/sidekicks-sign.XXXXXX)"`.

### B3. Signer l'app

```bash
xattr -cr "$W/sidekicks.app"
codesign --force --options runtime --timestamp \
  --sign "$SIDEKICKS_SIGN_IDENTITY" "$W/sidekicks.app"
codesign --verify --strict --verbose=2 "$W/sidekicks.app"
codesign -dv --verbose=4 "$W/sidekicks.app" 2>&1 | grep -E "Authority=Developer ID Application|flags=.*runtime|Timestamp="
```

La dernière commande doit afficher l'autorité **Developer ID Application**, le drapeau **runtime** et une ligne **Timestamp**.

### B4. Notariser l'app et agrafer le ticket

```bash
ditto -c -k --keepParent "$W/sidekicks.app" "$W/notarize.zip"
xcrun notarytool submit "$W/notarize.zip" --keychain-profile "$SIDEKICKS_NOTARY_PROFILE" --wait
xcrun stapler staple "$W/sidekicks.app"
spctl -a -vvv -t exec "$W/sidekicks.app"
```

`notarytool` attend la réponse d'Apple (quelques minutes) et doit finir par `status: Accepted`. `spctl` doit dire `accepted` et `source=Notarized Developer ID`.

### B5. Faire le `.dmg` à partir de l'app agrafée

```bash
wails3 tool package --format dmg --name sidekicks --out "$W" \
  --background build/darwin/dmg-background.png \
  --volume-icon build/darwin/icons.icns \
  --file-icon build/darwin/dmg-file-icon.icns \
  --window-width 540 --window-height 380
hdiutil verify "$W/sidekicks.dmg"
```

La commande se lance depuis la racine du dépôt (pour les images) mais lit l'app et écrit le `.dmg` dans `$W`, avec la même mise en page que `make release-build`. `hdiutil verify` doit finir par `checksum … is VALID`.

### B6. Signer, notariser et agrafer le `.dmg`

```bash
codesign --force --timestamp --sign "$SIDEKICKS_SIGN_IDENTITY" "$W/sidekicks.dmg"
xcrun notarytool submit "$W/sidekicks.dmg" --keychain-profile "$SIDEKICKS_NOTARY_PROFILE" --wait
xcrun stapler staple "$W/sidekicks.dmg"
hdiutil verify "$W/sidekicks.dmg"
spctl -a -vvv -t open --context context:primary-signature "$W/sidekicks.dmg"
hdiutil attach -nobrowse -readonly "$W/sidekicks.dmg" && hdiutil detach "/Volumes/sidekicks"
```

`spctl` doit dire `accepted` et `source=Notarized Developer ID` ; le `.dmg` doit se monter puis se démonter sans erreur. Si le volume ne s'appelle pas `sidekicks`, détachez celui que `hdiutil attach` a affiché.

### B7. Remplacer les paquets macOS de `dist/` et recalculer les sommes

```bash
DMG=$(scripts/package.sh names macos arm64 | sed -n 1p)   # le .dmg et le .zip, avec la version de build/config.yml
ZIP=$(scripts/package.sh names macos arm64 | sed -n 2p)
echo "$W · $DMG · $ZIP"                                    # aucune des trois valeurs ne doit être vide
rm -f dist/sidekicks.dmg                                   # un reste éventuel d'une copie ratée
cp "$W/sidekicks.dmg" "dist/$DMG"
rm -f "dist/$ZIP" && ditto -c -k --keepParent "$W/sidekicks.app" "dist/$ZIP"
cmp "$W/sidekicks.dmg" "dist/$DMG" && echo "copie identique"
spctl -a -vvv -t open --context context:primary-signature "dist/$DMG"   # accepted · Notarized Developer ID
(cd dist && rm -f SHA256SUMS && shasum -a 256 -- * > "$W/SHA256SUMS") && cp "$W/SHA256SUMS" dist/SHA256SUMS
cat dist/SHA256SUMS
```

Ne passez pas à la suite si `cmp` signale une différence ou si `spctl` refuse : `dist/` contiendrait encore le `.dmg` non signé de B1, et la release aussi.

### B8. Essayer sur un autre Mac

1. Copiez le `.dmg` sur un autre Mac (ou un autre compte utilisateur), par le web ou AirDrop : il doit porter l'attribut de quarantaine d'un vrai téléchargement.
2. Ouvrez-le, glissez **sidekicks** dans **Applications**, lancez-le : il s'ouvre directement, sans **Ouvrir quand même**.
3. Faites le tour de ce que le runtime renforcé pourrait gêner : un agent local, un agent en conteneur ou en sbx, l'onglet Terminal, l'ouverture d'un fichier, le glisser-déposer, Settings → Open….

### B9. Taguer et publier

Suivez la suite de [RELEASING.fr.md](../../../RELEASING.fr.md) (étapes 2 à 4) : les fichiers à attacher sont ceux de `dist/`. Une fois la release publiée, téléchargez son `.dmg` et vérifiez que `shasum -a 256` donne la même somme que `SHA256SUMS` (un envoi tronqué donne aussi « image endommagée »). Supprimez ensuite `$W` et relancez la synchronisation.

## Variantes

- **Release macOS à part, sur une version déjà publiée** (par exemple `v1.0.0-macos`, issue #57) : **ne changez pas** `info.version` (l'app reste la `1.0.0` ; Windows refuse une version qui n'est pas faite de nombres, Apple aussi pour `CFBundleShortVersionString`, et les paquets s'appelleraient `…-1.0.0-macos-macos-…`). Construisez seulement macOS avec `SKIP=windows make release-build`, faites la partie B, puis créez le tag à la main : `git tag -a v1.0.0-macos -m "Sidekicks 1.0.0, macOS signé et notarisé" && git push origin v1.0.0-macos`. Le workflow **Release** démarre et s'arrête à sa vérification (le tag n'est pas `v` + la version de `build/config.yml`) : c'est attendu. Créez la release sur Rickub depuis ce tag et attachez le `.dmg`, le `.zip` et `SHA256SUMS`. Vous pouvez aussi simplement remplacer les fichiers macOS de la release `v1.0.0`.
- **La notarisation est refusée** (`status: Invalid`) : `xcrun notarytool log <id> --keychain-profile "$SIDEKICKS_NOTARY_PROFILE"` donne la raison. Les plus courantes : signature sans `--options runtime` ou sans `--timestamp`, ou un fichier non signé dans l'app.
- **« L'image disque est endommagée » à l'ouverture du `.dmg`** : il a été modifié après sa signature (dossier synchronisé) ou tronqué (envoi, téléchargement). `hdiutil verify` sur le fichier et `shasum -a 256` comparé à `SHA256SUMS` disent lequel. Refaites B2 à B7 avec la synchronisation en pause (ou avec `$W` dans `/tmp`).
- **`codesign` refuse (« resource fork, Finder information, or similar detritus »)** : l'app vient d'un dossier synchronisé, qui ajoute des métadonnées. `xattr -cr "$W/sidekicks.app"` puis recommencez B3.
- **L'app signée ne démarre pas ou une fonction ne marche plus** : le runtime renforcé bloque quelque chose. Lisez **Console.app** au lancement ; si un droit précis manque, ajoutez un fichier d'entitlements (`--entitlements build/darwin/entitlements.plist` dans B2) avec seulement ce droit, et notez-le dans l'issue #57.
- **Vérifier une app installée** : `spctl -a -vvv /Applications/sidekicks.app` et `xcrun stapler validate /Applications/sidekicks.app`.
- **Un autre Mac pour construire** : importez le `.p12` (double-clic), puis refaites A6 et A7.
- **Le `.dmg` à refaire, l'app déjà notarisée** : si `$W/sidekicks.app` est encore là et que `xcrun stapler validate "$W/sidekicks.app"` réussit, reprenez directement à B5.

## Voir aussi

- [Publier une release](publier-une-release.md) · [RELEASING.fr.md](../../../RELEASING.fr.md)
- [Installer Sidekicks](installer-sidekicks.md)
- Apple : [Notarizing macOS software before distribution](https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution)