Skip to content

Modernize: toolchain, tests, containerization + GHCR/Coolify deploy - #2

Open
ddbruce wants to merge 1 commit into
mainfrom
modernization
Open

Modernize: toolchain, tests, containerization + GHCR/Coolify deploy#2
ddbruce wants to merge 1 commit into
mainfrom
modernization

Conversation

@ddbruce

@ddbruce ddbruce commented Jul 24, 2026

Copy link
Copy Markdown
Member

Summary

Behavior-preserving modernization pass on strng. No app functionality changes — same routes, same run-number logic, same auth/CSRF behavior. Verified: boots on example config, /login → 200, / → 302 → /login; 13/13 unit tests pass; amd64 image builds with 0 npm vulnerabilities.

strng was already on current Express 5 / EJS 5, so this is mostly deploy scaffolding + toolchain hygiene.

Changes

  • lib.js: extracted pure helpers (safeCompare, month/division/mush logic, run-number formatting) so they're unit-testable; server.js consumes them with identical behavior.
  • Tests: added Jest suite (13 tests) covering the extracted logic.
  • Lint: ESLint 8 (EOL) → ESLint 9 flat config, same rules; ecmaVersion 2018 → 2022.
  • Docker: pin node:24-alpine, NODE_ENV=production, HEALTHCHECK.
  • Deps: added engines, lint/test scripts; patched transitive body-parser/qs advisories via lockfile → npm audit clean.
  • CI: GitHub Actions running lint + test + amd64 image build.
  • Deploy: scripts/deploy.sh (build linux/amd64 → push GHCR → trigger Coolify POST /api/v1/deploy?uuid=), scripts/config.example.sh. Real secrets live in gitignored scripts/config.sh.

Before this can deploy

Populate scripts/config.sh from the example (GHCR org/user/PAT, Coolify base URL/token/app UUID).

Recommended follow-ups (NOT done — would change behavior/infra, need your OK)

  • Add Helmet security headers (its default CSP can break inline view assets — needs testing).
  • Replace in-memory session store with a persistent one (survives restarts; adds infra).
  • Run container as non-root (needs the data.json volume writable by that user).
  • Serialize/atomic-write data.json (the current sync whole-file write can race under concurrent generates).
  • Per-user accounts + login rate limiting (currently shared passwords).

Behavior-preserving modernization pass. No app functionality changes.

- Extract pure helpers (safeCompare, month/division/mush logic, run-number
  formatting) into lib.js; server.js consumes them unchanged.
- Add Jest unit tests for the extracted logic (13 tests).
- Migrate ESLint 8 (EOL) -> ESLint 9 flat config (eslint.config.js),
  same rule set; bump ecmaVersion 2018 -> 2022.
- Dockerfile: pin node:24-alpine, set NODE_ENV, add HEALTHCHECK, copy lib.js.
- package.json: add engines, lint/test scripts, dev deps; patch transitive
  body-parser/qs advisories via lockfile (npm audit: 0 vulnerabilities).
- Add GitHub Actions CI (lint + test + amd64 image build).
- Add scripts/deploy.sh + config.example.sh: build linux/amd64, push to GHCR,
  trigger Coolify redeploy. Real secrets live in gitignored scripts/config.sh.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant