- Merge typecheck + lint into a single `check` job to eliminate one full
job lifecycle and one npm ci invocation (~2-4 min savings)
- Remove `apt-get install docker.io` step — Docker CLI and buildx v0.23.0
are now pre-installed in the custom brackt-runner:latest image
- Reorder Dockerfile build-env COPY layers so node_modules and config
files are copied before source, improving registry cache hit granularity
- Expand .dockerignore to exclude .forgejo, .git, docs, plans, cypress,
logs, .env files, and tsbuildinfo files from the build context
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary
- **Dockerfile layer caching**: `development-dependencies-env` now copies only `package.json`/`package-lock.json` before `npm ci` (was `COPY . /app`), so the npm install layer is cached on every code-only commit instead of rebuilt from scratch
- **Skip QEMU**: `platforms: linux/amd64` added to `build-push-action`, cutting `setup-buildx-action` from ~5 min to ~30 sec
- **npm cache in CI jobs**: Manual `actions/cache@v3` blocks (copy-pasted 3×) replaced with `actions/setup-node@v4` + `cache: 'npm'`, which handles path/key/restore automatically and pins Node 20 explicitly
- **Harden `.npmrc`**: Switched from `COPY .npmrc` to `--mount=type=secret,id=npmrc` in both `npm ci` stages — the file is available during install but never written into a Docker layer, so it cannot leak through the registry build cache regardless of future contents
## Expected timing
| Step | Before | After (code change) |
|---|---|---|
| Setup buildx | ~5 min | ~30 sec |
| Build + push | ~5 min | ~1-2 min |
| Deploy (docker pull) | ~5 min | ~1-2 min |
| **Total** | **~15 min** | **~3-5 min** |
## Test plan
- [ ] Push a code-only commit to main — confirm `setup-buildx-action` logs ~30s (no QEMU), Docker build shows `CACHED` for npm install layers, build+push completes in ~1-2 min
- [ ] Check deploy job — `docker compose pull` should show most layers as `Already exists`
- [ ] Push a commit that changes `package.json` — confirm npm layer correctly re-runs (not cached)
- [ ] Confirm deployed app is functional
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Chris Parsons <chrisparsons1127@gmail.com>
Reviewed-on: #59
node:20-bookworm doesn't include the Docker CLI; install docker.io via
apt before the buildx and registry steps.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Node 20 is already in the node:20-bookworm runner image; setup-node
was hanging ~5min trying to reach an unconfigured npm cache service.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove host port binding (conflicts with local postgres on runner) and
use service name hostname instead of localhost for DATABASE_URL.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move workflows from .github/ to .forgejo/ so they only run on Forgejo
- Replace styfle/cancel-workflow-action with native concurrency block
- Use full GitHub URLs for all third-party actions to bypass mirror
- Switch Docker layer cache from type=gha to type=registry
- Drop label-subissues workflow (relies on GitHub-specific GraphQL API)
- Add timeout-minutes to all jobs; cancel-in-progress only for non-main branches
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>