|
| 1 | +### ### E2E |
| 2 | +### |
| 3 | +### End-to-end test of the localhost-cert install recipe, walked |
| 4 | +### through the supplied tasks the same way an operator would: bootstrap |
| 5 | +### env files via `task env:init`, configure traefik via |
| 6 | +### `task env:traefik`, generate a self-signed cert via `task dev:cert`, |
| 7 | +### bring the stack up via `task up`, run migrations + JWT + tenant + |
| 8 | +### admin user via `task console`, install templates via |
| 9 | +### `task templates:install`, and tear down via `task dev:teardown`. |
| 10 | +### Curls `/admin/` over HTTPS using the generated cert as the success |
| 11 | +### gate. |
| 12 | +### |
| 13 | +### Triggers on `pull_request` against `release/**` and pushes to |
| 14 | +### `release/**` only — too slow + too much docker churn to run on every |
| 15 | +### casual PR. Acts as the release-cut quality bar that the static |
| 16 | +### `markdown` / `yaml` / `sh` / `compose` / `tasks` workflows can't catch: |
| 17 | +### actual stack boot, Doctrine migrations, JWT keypair generation, and |
| 18 | +### Traefik routing. |
| 19 | +### |
| 20 | +### #### Known fragility points |
| 21 | +### |
| 22 | +### - **`APP_ENV=dev` upstream image bug**: the bundled `/app/.env` still |
| 23 | +### defaults to `APP_ENV=dev` until a 3.0.0-rc3+ tag ships the fix |
| 24 | +### from display-api-service#435. We sed it to `prod` after `task |
| 25 | +### env:init`. Drop the workaround once a fixed image tag is in |
| 26 | +### `OS2DISPLAY_VERSION_API`. |
| 27 | +### - **`task install` is interactive**: chained `task: <subtask>` calls |
| 28 | +### don't reliably pipe stdin to the Symfony console for tenant:add |
| 29 | +### and user:add (B23 caveat). We walk the install steps individually |
| 30 | +### via `task console -- ARGS` (which is non-interactive when the |
| 31 | +### bin/console subcommand accepts CLI args) instead of calling |
| 32 | +### `task install` directly. |
| 33 | +### - **`scripts/install-secrets.sh` runs as the first step of `task |
| 34 | +### install`**: not currently a standalone task, so we invoke the |
| 35 | +### script directly. It's tracked under `scripts/` and shellcheck- |
| 36 | +### validated; equivalent to running task install's secrets-fill |
| 37 | +### step in isolation. |
| 38 | +### - **GHCR pulls without auth**: bot quota, can flake on heavy CI days. |
| 39 | + |
| 40 | +name: E2E |
| 41 | + |
| 42 | +on: |
| 43 | + pull_request: |
| 44 | + branches: |
| 45 | + - "release/**" |
| 46 | + push: |
| 47 | + branches: |
| 48 | + - "release/**" |
| 49 | + |
| 50 | +jobs: |
| 51 | + install-localhost: |
| 52 | + runs-on: ubuntu-latest |
| 53 | + timeout-minutes: 15 |
| 54 | + steps: |
| 55 | + - uses: actions/checkout@v6 |
| 56 | + |
| 57 | + - name: Install Task |
| 58 | + uses: arduino/setup-task@v2 |
| 59 | + with: |
| 60 | + version: 3.x |
| 61 | + repo-token: ${{ secrets.GITHUB_TOKEN }} |
| 62 | + |
| 63 | + - name: task env:init (domain prompt piped) |
| 64 | + run: printf 'os2display.localhost\n' | task env:init |
| 65 | + |
| 66 | + - name: APP_ENV=prod workaround (upstream image bug — see header) |
| 67 | + run: sed -i 's|^APP_ENV=dev|APP_ENV=prod|' .env.symfony |
| 68 | + |
| 69 | + - name: task env:traefik (cert-file branch, prompts piped) |
| 70 | + # Choice 2 = cert-file. Domain = traefik.localhost. LE email blank |
| 71 | + # (cert-file branch ignores it). Cert filename defaults accepted |
| 72 | + # via blank lines. Dashboard admin / password. |
| 73 | + run: printf '2\ntraefik.localhost\n\n\nadmin\npassword\n' | task env:traefik |
| 74 | + |
| 75 | + - name: task dev:cert |
| 76 | + run: task dev:cert |
| 77 | + |
| 78 | + - name: install-secrets (would be `task install`'s first step) |
| 79 | + run: ./scripts/install-secrets.sh |
| 80 | + |
| 81 | + - name: Pre-create bind-mount dirs with container-writable perms |
| 82 | + # The os2display container writes JWT keys as UID 1042 (`deploy`) |
| 83 | + # per README's deploy-host UID/GID contract, and uploads to |
| 84 | + # ./media as the same user. CI runners aren't the operator's |
| 85 | + # 1042-group host, so chown the bind-mount sources to match. |
| 86 | + run: | |
| 87 | + mkdir -p jwt media backup |
| 88 | + sudo chown -R 1042:1042 jwt media backup |
| 89 | +
|
| 90 | + - name: task up |
| 91 | + # `task up` uses `compose up -d --wait`, so this blocks until every |
| 92 | + # service's healthcheck passes. Migrations on the next step can |
| 93 | + # connect immediately. |
| 94 | + run: task up |
| 95 | + |
| 96 | + - name: task console -- app:update (Doctrine migrations) |
| 97 | + run: task console -- --no-interaction app:update |
| 98 | + |
| 99 | + - name: task console -- lexik:jwt:generate-keypair |
| 100 | + run: task console -- lexik:jwt:generate-keypair --skip-if-exists |
| 101 | + |
| 102 | + - name: task console -- app:tenant:add |
| 103 | + run: task console -- app:tenant:add e2e 'E2E Tenant' CI |
| 104 | + |
| 105 | + - name: task console -- app:user:add |
| 106 | + run: task console -- app:user:add admin@os2display.localhost e2epassword 'E2E Admin' admin e2e |
| 107 | + |
| 108 | + - name: task templates:install |
| 109 | + run: task templates:install |
| 110 | + |
| 111 | + - name: Smoke test — admin route over HTTPS |
| 112 | + # --resolve maps os2display.localhost → 127.0.0.1; --cacert trusts |
| 113 | + # the generated dev cert (covers os2display.localhost as a SAN). |
| 114 | + # -f makes curl exit non-zero on >=400. |
| 115 | + run: | |
| 116 | + curl -fv \ |
| 117 | + --resolve os2display.localhost:443:127.0.0.1 \ |
| 118 | + --cacert traefik/ssl/dev.crt \ |
| 119 | + https://os2display.localhost/admin/ \ |
| 120 | + -o /dev/null |
| 121 | +
|
| 122 | + - name: task dev:teardown |
| 123 | + if: always() |
| 124 | + run: task -y dev:teardown |
0 commit comments