forked from 1b-agent/fieldcraft-upstream
ci: release secrets from the main-only release environment
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
1dc4c27dc1
commit
7a9cb2cb22
5 files changed
+65
-7
No files matched your search
@@ -1,2 +1,13 @@
|
||||
# Every change to FieldCraft needs the maintainer's review before it merges.
|
||||
* @jyviko
|
||||
|
||||
# Release and supply-chain paths, named explicitly so they stay owner-reviewed if the rule above
|
||||
# is ever relaxed: workflows and secrets use, packaging and signing, the updater, dependencies,
|
||||
# licences.
|
||||
/.github/ @jyviko
|
||||
/packaging/ @jyviko
|
||||
/crates/update/ @jyviko
|
||||
/Cargo.toml @jyviko
|
||||
/Cargo.lock @jyviko
|
||||
/ATTRIBUTION.md @jyviko
|
||||
/deny.toml @jyviko
|
||||
@@ -33,6 +33,10 @@ env:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# POSTHOG_KEY lives in the `release` environment (main only, docs/releasing.md). The deploy job
|
||||
# already uses github-pages and a job has one environment, so the build job reads the key: on
|
||||
# main it runs in `release`, elsewhere in no environment and with an empty key.
|
||||
environment: ${{ github.ref == 'refs/heads/main' && 'release' || '' }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
|
||||
@@ -73,6 +73,9 @@ jobs:
|
||||
macos:
|
||||
name: macOS universal
|
||||
needs: version
|
||||
# Signing, notarization and analytics secrets live in the `release` environment, which only
|
||||
# `main` may use; a dry run on another branch asks for no environment and builds unsigned.
|
||||
environment: ${{ github.ref == 'refs/heads/main' && 'release' || '' }}
|
||||
runs-on: macos-14
|
||||
timeout-minutes: 120
|
||||
outputs:
|
||||
@@ -118,6 +121,9 @@ jobs:
|
||||
name: Linux x86_64
|
||||
needs: version
|
||||
# The oldest GitHub-hosted image, so the binaries need only glibc >= 2.35.
|
||||
# Signing, notarization and analytics secrets live in the `release` environment, which only
|
||||
# `main` may use; a dry run on another branch asks for no environment and builds unsigned.
|
||||
environment: ${{ github.ref == 'refs/heads/main' && 'release' || '' }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
@@ -201,6 +207,9 @@ jobs:
|
||||
windows:
|
||||
name: Windows x64
|
||||
needs: version
|
||||
# Signing, notarization and analytics secrets live in the `release` environment, which only
|
||||
# `main` may use; a dry run on another branch asks for no environment and builds unsigned.
|
||||
environment: ${{ github.ref == 'refs/heads/main' && 'release' || '' }}
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
@@ -230,6 +239,9 @@ jobs:
|
||||
release:
|
||||
name: Draft release (or dry-run artifacts)
|
||||
needs: [version, macos, linux, windows]
|
||||
# Signing, notarization and analytics secrets live in the `release` environment, which only
|
||||
# `main` may use; a dry run on another branch asks for no environment and builds unsigned.
|
||||
environment: ${{ github.ref == 'refs/heads/main' && 'release' || '' }}
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
+1
-1
@@ -86,5 +86,5 @@ A `command_run` as sent:
|
||||
The events and the policy are `fieldcraft_engine::usage`; the consent question and the settings
|
||||
are `crates/ui-egui/src/privacy.rs`; the desktop sender is `apps/fieldcraft/src/usage.rs`, the
|
||||
web one `apps/fieldcraft-web/src/usage.rs`. The PostHog project key is the build-time variable
|
||||
`FIELDCRAFT_POSTHOG_KEY`, which the release workflow and the Pages build of `main` set from the repository secret
|
||||
`FIELDCRAFT_POSTHOG_KEY`, which the release workflow and the Pages build of `main` set from the `release` environment secret
|
||||
`POSTHOG_KEY`; it is an ingest-only key. A new event or property is added here first.
|
||||
+37
-6
@@ -51,7 +51,8 @@ about it, and the release notes say which of the two the draft contains.
|
||||
| `APPLE_PASSWORD` | An app-specific password for that Apple ID (appleid.apple.com › Sign-In and Security) |
|
||||
| `APPLE_TEAM_ID` | The 10-character team id of the Developer ID |
|
||||
|
||||
Add them with `gh secret set <NAME> -R jyviko/fieldcraft`. With the certificate but without the
|
||||
Add them to the `release` environment ([Where the secrets live](#where-the-secrets-live)) with
|
||||
`gh secret set <NAME> --env release -R jyviko/fieldcraft`. With the certificate but without the
|
||||
three notarization secrets the app is signed and not notarized. A dmg made locally with
|
||||
`packaging/macos/package.sh` is ad-hoc signed unless `MACOS_SIGN_IDENTITY` names an identity
|
||||
in the keychain.
|
||||
@@ -66,7 +67,7 @@ untrusted comment: minisign public key: FEF410EFEF5BAB21
|
||||
RWQhq1vv7xD0/uAOt8fqERP1hP+1UCM9U9QHTDYTYytWKiuedTkT7Lgr
|
||||
```
|
||||
|
||||
The secret half is the repository secret `FIELDCRAFT_SIGNING_KEY`: the whole secret key file
|
||||
The secret half is the `release` environment secret `FIELDCRAFT_SIGNING_KEY`: the whole secret key file
|
||||
(two lines), made without a password. With it, the release job signs `SHA256SUMS.txt` with
|
||||
[rsign2](https://github.com/jedisct1/rsign2) (pinned in `release.yml`), checks the signature
|
||||
against the public key in the source, and uploads `SHA256SUMS.txt.minisig`. Without it the
|
||||
@@ -79,7 +80,7 @@ Setting it up, once:
|
||||
```sh
|
||||
cargo install --locked rsign2 --version 0.6.7
|
||||
rsign generate -W -p fieldcraft-release.pub -s fieldcraft-release.key # -W: no password
|
||||
gh secret set FIELDCRAFT_SIGNING_KEY -R jyviko/fieldcraft < fieldcraft-release.key
|
||||
gh secret set FIELDCRAFT_SIGNING_KEY --env release -R jyviko/fieldcraft < fieldcraft-release.key
|
||||
```
|
||||
|
||||
Keep an offline copy of the secret key file (a password manager, an encrypted backup) and
|
||||
@@ -101,9 +102,39 @@ certificate is added.
|
||||
## Usage analytics key
|
||||
|
||||
The release builds (macOS, Linux and Windows jobs) build in the PostHog project key from the
|
||||
repository secret `POSTHOG_KEY` as `FIELDCRAFT_POSTHOG_KEY` ([privacy.md](privacy.md)). Without the
|
||||
secret the builds ask nothing and send nothing, as local and fork builds do. The web build on
|
||||
Pages has no key.
|
||||
`release` environment secret `POSTHOG_KEY` as `FIELDCRAFT_POSTHOG_KEY` ([privacy.md](privacy.md)).
|
||||
Without the secret the builds ask nothing and send nothing, as local, fork and dry-run builds do.
|
||||
The web build on Pages gets the key only when it runs from `main`: its build job then runs in the
|
||||
`release` environment (the deploy job already uses `github-pages`, and a job has one environment).
|
||||
|
||||
## Where the secrets live
|
||||
|
||||
Every release secret (the `APPLE_*` secrets, `KEYCHAIN_PASSWORD`, `FIELDCRAFT_SIGNING_KEY`,
|
||||
`POSTHOG_KEY`) is a secret of the GitHub Environment `release`, whose deployment branches allow
|
||||
`main` only. Repository secrets are readable by any workflow a writer can run on any branch;
|
||||
environment secrets reach only jobs that name the environment and run from an allowed branch, so a
|
||||
contributor with write access cannot read the signing keys from a branch of their own. The jobs
|
||||
that read them (`release.yml`'s macos, linux, windows and release jobs, `pages.yml`'s build job)
|
||||
ask for `release` only on `main`
|
||||
(`environment: ${{ github.ref == 'refs/heads/main' && 'release' || '' }}`); elsewhere the name is
|
||||
empty, the job runs in no environment, sees no secrets and builds unsigned. `.github/CODEOWNERS`
|
||||
keeps the workflows, packaging and updater under the owner's review.
|
||||
|
||||
Moving them from repository secrets, once (the owner; each value comes from its own source file,
|
||||
never the shell history):
|
||||
|
||||
```sh
|
||||
for n in APPLE_CERTIFICATE APPLE_CERTIFICATE_PASSWORD KEYCHAIN_PASSWORD APPLE_ID APPLE_PASSWORD \
|
||||
APPLE_TEAM_ID FIELDCRAFT_SIGNING_KEY POSTHOG_KEY; do
|
||||
gh secret set "$n" --env release -R jyviko/fieldcraft < "$n.txt"
|
||||
done
|
||||
gh secret list --env release -R jyviko/fieldcraft # all eight listed
|
||||
# After a release run on main has signed with them:
|
||||
for n in APPLE_CERTIFICATE APPLE_CERTIFICATE_PASSWORD KEYCHAIN_PASSWORD APPLE_ID APPLE_PASSWORD \
|
||||
APPLE_TEAM_ID FIELDCRAFT_SIGNING_KEY POSTHOG_KEY; do
|
||||
gh secret delete "$n" -R jyviko/fieldcraft
|
||||
done
|
||||
```
|
||||
|
||||
## Choose and prepare the version
|
||||
|
||||
|
||||
Reference in new issue
Block a user