The first tag run failed at docker login with "password is empty" -
$PACKAGE_TOKEN wasn't actually present as a bare env var in the job
shell the way I'd assumed. Checked the triggershell repo's own working
release workflow (same instance, same registry) for the real pattern:
it's a Gitea Actions secret (likely instance-wide, which is why it
didn't show up in this repo's own `tea actions secrets list`),
referenced via ${{ secrets.PACKAGE_TOKEN }} and mapped into the step's
env block, not inherited directly from the runner process.
Caught by the first real CI run: a bare `pnpm exec tsc --noEmit` fails
on a clean checkout because Next's own ambient types (LayoutProps and
friends, from .next/types) don't exist until a build has run at least
once. Locally this never surfaced since .next was always already
present from earlier dev/build runs. `next build` performs an
equivalent (and more complete) type check as part of its own process,
so the separate step was both redundant and the thing that broke.
Two jobs:
- checks: runs on every push/PR - lint, tsc --noEmit, and a full
`pnpm build` as the static-check gate.
- publish: only on a tag push, gated on checks passing first. Builds
the Dockerfile and pushes to this instance's container registry
(dev.pivoine.art/<owner>/<repo>) tagged both `latest` and the exact
git tag, using PACKAGE_TOKEN from the runner's own environment to
log in (not a repo secret, per how it's configured on this runner).