Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .secrets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ exposing one.
The documented local convention is `~/.secrets/`, not this directory. CI supplies the same
values directly from the GitHub Environment instead, reading no file here at all.
`ENV_FILE=<name> deploy/make-release.sh` resolves a relative `ENV_FILE` against `$HOME/.secrets`,
refuses a traversing one, and defaults to `~/.secrets/blog.local.production.env`. An absolute
refuses a traversing one, and defaults to `~/.secrets/blog_local_production.env`. An absolute
`ENV_FILE` is honored as given rather than resolved against `~/.secrets/`, an escape hatch rather
than the documented shape.
`~/.secrets/` is shared across every repo on the host, so each of this repo's files carries the
`blog.` prefix:
`blog_` prefix:

| File | Selects |
| --- | --- |
| `~/.secrets/blog.local.production.env` | The default, read when `ENV_FILE` is unset. |
| `~/.secrets/blog.local.staging.env` | The local staging mirror. |
| `~/.secrets/blog.vps.production.env` | The VPS production environment. |
| `~/.secrets/blog.vps.staging.env` | The VPS staging environment. |
| `~/.secrets/blog_local_production.env` | The default, read when `ENV_FILE` is unset. |
Comment thread
ptr727 marked this conversation as resolved.
| `~/.secrets/blog_local_staging.env` | The local staging mirror. |
| `~/.secrets/blog_vps_production.env` | The VPS production environment. |
| `~/.secrets/blog_vps_staging.env` | The VPS staging environment. |

Every value each file holds, and what reads it, is described once in
[`ENVIRONMENT.md`](../ENVIRONMENT.md). Start a new one from [`example.env`](./example.env).
12 changes: 6 additions & 6 deletions .secrets/example.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This file states the shape and a placeholder. Add a value here and describe it there,
# or checks/env_docs_gate.py fails.
#
# One destination: ~/.secrets/blog.<server>.<environment>.env on a workstation, one file
# One destination: ~/.secrets/blog_<server>_<environment>.env on a workstation, one file
# per environment. The off-host VPS backup pull, and the environment file it reads, are
# maintained outside this repository -- see OPERATIONS.md, Working With the VPS.
#
Expand All @@ -15,14 +15,14 @@
# HUGO_BASEURL for Hugo, only where that tool requires its own name.

# =============================================================================
# ~/.secrets/blog.<server>.<environment>.env
# ~/.secrets/blog_<server>_<environment>.env
# =============================================================================
# One file per environment, named for the server it describes and the environment on it,
# with both words spelled out, and selected by ENV_FILE:
# blog.local.production.env the default, read when ENV_FILE is unset
# blog.local.staging.env ENV_FILE=blog.local.staging.env deploy/make-release.sh
# blog.vps.production.env ENV_FILE=blog.vps.production.env deploy/make-release.sh
# blog.vps.staging.env ENV_FILE=blog.vps.staging.env deploy/make-release.sh
# blog_local_production.env the default, read when ENV_FILE is unset
# blog_local_staging.env ENV_FILE=blog_local_staging.env deploy/make-release.sh
# blog_vps_production.env ENV_FILE=blog_vps_production.env deploy/make-release.sh
# blog_vps_staging.env ENV_FILE=blog_vps_staging.env deploy/make-release.sh
#
# Sourced with `set -a`, which overwrites a variable the caller exported first. A named
# file that does not exist is a hard failure rather than a fall-through. Real files live
Expand Down
10 changes: 5 additions & 5 deletions ENVIRONMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ Every configuration value this repository reads or writes, described once. [`OPE

## The mechanism

A local run reads one file. `~/.secrets/blog.<server>.<environment>.env` is sourced with `set -a`, selected by `ENV_FILE`, and defaults to `~/.secrets/blog.local.production.env`. The real files live on the host, never in this checkout, and [`.secrets/example.env`](./.secrets/example.env) is the tracked template that documents the shape.
A local run reads one file. `~/.secrets/blog_<server>_<environment>.env` is sourced with `set -a`, selected by `ENV_FILE`, and defaults to `~/.secrets/blog_local_production.env`. The real files live on the host, never in this checkout, and [`.secrets/example.env`](./.secrets/example.env) is the tracked template that documents the shape.

Two consequences of `set -a` are worth stating because both have surprised someone. Sourcing overwrites a variable the caller exported first, so exporting `DEPLOY_ROOT` by hand does not switch environments and only `ENV_FILE` does. And a named file that does not exist is a hard failure rather than a fall-through, because on a host serving two sites the ambient value is the other site's root.

CI reads no file. The deploy workflow resolves the same values from the GitHub Environment, which is why the shapes have to match even though the sources do not.

## Repository environment files

Held in `~/.secrets/blog.<server>.<environment>.env`, one file per environment, on the host rather than in this checkout. Template: [`.secrets/example.env`](./.secrets/example.env).
Held in `~/.secrets/blog_<server>_<environment>.env`, one file per environment, on the host rather than in this checkout. Template: [`.secrets/example.env`](./.secrets/example.env).

| Value | Names | Notes |
| --- | --- | --- |
Expand Down Expand Up @@ -62,9 +62,9 @@ Every variable and secret this repository stores for GitHub Actions, Dependabot,

**[`checks/github_env_gate.py`](./checks/github_env_gate.py) compares this table against GitHub.** It reads the names those stores hold, never a value, and leaves the Codespaces secret store unread. It reports a value missing from a store, held on a store the table does not name, or held as the wrong kind. Every environment GitHub has is read, so an environment the table never names must hold nothing. Run it after changing a value on GitHub or a row here. It needs a `gh` login that can administer the repository, since listing environment secrets requires that. A workflow's `GITHUB_TOKEN` cannot, so CI does not run it.

**The family values take the hub's names for a second site.** The hub's deploy task reads `SITE_EXTRA_BASE_URL` and the `SITE_EXTRA_AUTH_TOKEN_ID`/`SITE_EXTRA_AUTH_TOKEN` pair by those names from the environment. `check-live-urls.sh` and the `~/.secrets/blog.*.env` files use the same three names, so nothing translates between them. A deploy therefore checks the family host with its own token.
**The family values take the hub's names for a second site.** The hub's deploy task reads `SITE_EXTRA_BASE_URL` and the `SITE_EXTRA_AUTH_TOKEN_ID`/`SITE_EXTRA_AUTH_TOKEN` pair by those names from the environment. `check-live-urls.sh` and the `~/.secrets/blog_*.env` files use the same three names, so nothing translates between them. A deploy therefore checks the family host with its own token.

**`SITE_BASE_URL` being read twice is the trap worth knowing.** A wrong value bakes the wrong address into every canonical tag and then runs the full URL contract against that same wrong address, so the deploy verifies itself and passes. Its generic name is the hub's own `deploy-site-task.yml` interface, and it is also the one this repository's own scripts and `~/.secrets/blog.*.env` files read: `make-release.sh` bridges it to Hugo's own `HUGO_BASEURL` in one place, since only Hugo requires that name.
**`SITE_BASE_URL` being read twice is the trap worth knowing.** A wrong value bakes the wrong address into every canonical tag and then runs the full URL contract against that same wrong address, so the deploy verifies itself and passes. Its generic name is the hub's own `deploy-site-task.yml` interface, and it is also the one this repository's own scripts and `~/.secrets/blog_*.env` files read: `make-release.sh` bridges it to Hugo's own `HUGO_BASEURL` in one place, since only Hugo requires that name.

**A host rebuild regenerates the SSH host keys and the pinned value stops matching**, which fails every deploy closed and blocks the rollback path at the same moment a rebuild makes both matter. Replace `DEPLOY_SSH_KNOWN_HOSTS` on **both** environments before the first deploy after a rebuild.

Expand All @@ -74,7 +74,7 @@ Set on the command line for one run rather than stored anywhere.

| Value | Effect |
| --- | --- |
| `ENV_FILE` | which environment file to source. Defaults to `~/.secrets/blog.local.production.env` |
| `ENV_FILE` | which environment file to source. Defaults to `~/.secrets/blog_local_production.env` |
| `REQUIRE_BROTLI=1` | fail rather than shipping gzip-only. CI sets it |
| `NO_LINK_DEST=1` | full copy instead of hard-linking from the previous release |
| `KEEP_RELEASES` | how many releases `make-release.sh` leaves behind |
Expand Down
Loading
Loading