One-time provisioning for the tag-driven store-release pipeline (see
docs/release-pipeline.md for how it works). Do these once on the DFXswiss/btc-wallet
repo; afterwards every vX.Y.Z tag ships to TestFlight + Play internal automatically.
No secret values belong in this file or the repo — this only says where to get each key. Add every secret under: GitHub repo → Settings → Secrets and variables → Actions → New repository secret (or
gh secret set NAME --repo DFXswiss/btc-wallet).
Y4QBY6387T.swiss.dfx.bitcoin app.DFXswiss/btc-wallet (to add secrets) and rights to create DFXswiss/btc-wallet-certificates.bundle install (in ios/) for the one-time match seed.| Secret | What it is | Where to get it |
|---|---|---|
TAG_DEPLOY_KEY |
SSH private key with write access, so auto-tag's tag push triggers release.yml (a GITHUB_TOKEN push wouldn't). |
ssh-keygen -t ed25519 -C "btc-wallet auto-tag" -f tag_deploy_key -N "". Add tag_deploy_key.pub under repo Settings → Deploy keys → Add deploy key with Allow write access ticked. Put the private file's contents in this secret. |
Used by upload_to_testflight, deliver, and match.
| Secret | What it is | Where to get it |
|---|---|---|
APP_STORE_CONNECT_KEY |
The .p8 API key file contents. |
App Store Connect → Users and Access → Integrations → App Store Connect API → Generate API Key (role App Manager or Admin). Download the .p8 (only offered once.) Paste the whole file as the secret. |
APP_STORE_CONNECT_KEY_ID |
The key's ID. | Shown next to the key you just made (also in the .p8 filename AuthKey_<KEYID>.p8). |
APP_STORE_CONNECT_ISSUER_ID |
The team's issuer ID. | Top of the same Integrations / Keys page ("Issuer ID"). |
match)| Secret | What it is | Where to get it |
|---|---|---|
MATCH_SSH_KEY |
SSH private key that can read the certs repo. | ssh-keygen -t ed25519 -C "btc-wallet match" -f match_key -N "". Add match_key.pub as a deploy key on DFXswiss/btc-wallet-certificates (write access). Private contents → this secret. |
MATCH_PASSWORD |
The passphrase match uses to encrypt/decrypt the certs. |
You invent it when seeding (below). Store it in the password manager and as this secret. |
| Secret | What it is | Where to get it |
|---|---|---|
PLAY_STORE_JSON_BASE64 |
Play service-account JSON, base64-encoded. | Google Play Console → Setup → API access → link/create a Google Cloud project → create a service account → in Play Console Users & permissions invite that service-account email and grant release rights. In Google Cloud, create a JSON key for it and download. Encode: base64 -i service-account.json → paste output as the secret. |
v* release flow)KEYSTORE_FILE_HEX, KEYSTORE_PASSWORD, KEYSTORE_KEY_PASSWORD, KEYSTORE_ALIAS,
TRANSPARENCY_KEYSTORE_HEX, TRANSPARENCY_PASSWORD, TRANSPARENCY_ALIAS.
These already exist (used by build-release-apk.yml). The new pipeline reuses them — nothing to do.
(For reference, the *_HEX ones are xxd -plain keystore.jks.)
Used by both platforms' Release-configuration builds to upload debug symbols / source
maps (docs/crash-reports.md covers the app-side setup). A missing/empty value fails
the build intentionally — see the guards in scripts/build-release-apk.sh and
ios/fastlane/Fastfile.
| Secret / value | What it is | Where to get it |
|---|---|---|
SENTRY_AUTH_TOKEN (secret) |
Auth token for sentry-cli uploads. |
sentry.dfxserve.com → Settings → Auth Tokens (org-level if available), scopes project:releases, project:read, org:read. |
SENTRY_URL, SENTRY_ORG, SENTRY_PROJECT (plain values, not secrets) |
Where to upload to — sentry-cli defaults to sentry.io without these. |
Already fixed for this self-hosted instance/project: https://sentry.dfxserve.com/, sentry, btc-taro. Set as variables, or plain env: values as the existing workflows already do. |
| Name | When needed | Where |
|---|---|---|
ASC_TEAM_ID |
Only if the Apple ID belongs to several App Store Connect teams. | App Store Connect → team picker / Membership. Add as a variable (not secret), read by ios/fastlane/Appfile. |
The iOS build requests NFC Tag Reading, Push Notifications, and App Groups. The
App Store provisioning profile match generates must include all three, so before seeding
match (step 1), in the Apple Developer portal → Certificates, Identifiers & Profiles → Identifiers:
swiss.dfx.bitcoin App ID and enable NFC Tag Reading, Push Notifications, App Groups.group.swiss.dfx.bitcoin and assign it to the App ID.If any of these is missing, the first build fails with "provisioning profile doesn't include the … capability" — the same error class we hit signing on a device. Enabling them up front avoids it.
match certificates repo (iOS signing)DFXswiss/btc-wallet-certificates.match deploy key public half to it (write) — see MATCH_SSH_KEY above.ios/, with the ASC API key env + MATCH_PASSWORD set, run:bundle install
bundle exec fastlane match appstore
This generates the distribution certificate + App Store profile in the Apple account, encrypts them with MATCH_PASSWORD, and commits them to the certs repo. (Matchfile already points at the repo + swiss.dfx.bitcoin.) CI runs match read-only afterwards.deliver cannot create the very first version via API — until it exists, the listing push is skipped (best-effort) but the TestFlight upload still works. After the first version exists, every tag syncs the listing automatically.swiss.dfx.bitcoin app exists.PLAY_STORE_JSON_BASE64).The preflight (scripts/check-store-metadata.sh) blocks a release while any FIXME- remains. Fill these for both de-DE and en-US:
ios/fastlane/metadata/<locale>/{description,promotional_text,marketing_url,privacy_url,support_url}.txtandroid/fastlane/metadata/android/<locale>/full_description.txtios/fastlane/screenshots/<locale>/ and android/fastlane/metadata/android/<locale>/images/phoneScreenshots/.
Limits enforced: iOS name/subtitle 30, keywords 100, promo 170, description 4000; Android title 50, short 80, full 4000; URLs ≤ 255.v0.0.1) or merge to develop (auto-tag creates the next tag).release workflow runs: guard → preflight → iOS (TestFlight) + Android (Play internal) → GitHub release.