Deployment is handled automatically by GitHub Actions. When changes to notification
YAML files are merged into main, the CI pipeline converts YAML to JSON, validates
it, and deploys to AWS via Pulumi.
Notification YAML files are kept in separate directories per environment:
stage/yaml/— notifications deployed to the stage environment.prod/yaml/— notifications deployed to the production environment.
To deploy a notification to production, its YAML file must be present in prod/yaml/.
Placing a file only in stage/yaml/ will deploy it to stage but not production. This
allows you to test notifications on stage before promoting them to production by copying
the file into prod/yaml/.
On every push to main that touches stage/yaml/, prod/yaml/, schema.json,
pulumi/, src/, or .github/workflows/:
- The validate job converts all YAML files to JSON and validates them against the schema.
- A single deploy job uses a matrix strategy to run
pulumi upfor both thestageandprodstacks in parallel. Theprodleg waits for manual approval in the GitHub Actions UI (via theproductionenvironment protection rule).
Pull requests run only the validate job, so broken YAML is caught before merge.
After a push to main, navigate to the workflow run in GitHub Actions. The
deploy (prod) job will show as "Waiting for review". Click Review deployments,
select the production environment, and approve.
The workflow uses OIDC (OpenID Connect) for both AWS and Pulumi Cloud.
If you need to run Pulumi locally (e.g. for debugging or previewing), make sure to
cd into pulumi/ and ensure you're not in any active virtual environment.
You will need a login token from Pulumi Cloud.
Previewing changes:
pulumi preview --diffDeploying changes:
pulumi up --diffOnce deployed, verify that notifications are live:
- Stage: https://notifications-stage.thunderbird.net/2.0/notifications.json
- Prod: https://notifications.thunderbird.net/2.0/notifications.json
Pulumi automatically purges the Cloudflare cache by hostname when deployed content
changes. The purge is triggered by changes to the S3 object ETags for
notifications.json or schema.json.
To purge manually, go to the Cloudflare dashboard for the thunderbird.net domain and
run a Custom Purge under Caching -> Configuration for the desired hostname.