- release.yml: build the Tizen .wgt before the source tarball and bundle it in
(ScreenTinker.wgt at the tarball root). The signed Android APK is added by the
local finalize step (the keystore stays off CI).
- scripts/finalize-release.sh: after the release workflow publishes a tag, build
the signed APK locally, pull the CI-built unsigned .wgt from the release,
assemble a complete tarball (source + apk + wgt at the root, where /download/apk
resolves the apk after extraction), and upload the apk + complete tarball.
- .gitignore: ignore *.wgt and *.tar.gz so finalize temp files cannot be committed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- .github/workflows/release.yml: on a v* tag - verify the tag matches VERSION
(fail-fast guard), run tests, build a source tarball + the unsigned Tizen .wgt
and publish a GitHub Release with generated notes, and build+push a multi-arch
(amd64 + arm64) image to ghcr.io/screentinker/screentinker:<version> + :latest.
The Release (artifacts) and the docker push are independent jobs, so an
arm64/QEMU docker failure does not block the GitHub Release and is re-runnable.
Nothing deploys to prod. APK-build-in-CI left as a TODO (keystore secret).
- Dockerfile + .dockerignore: multi-stage node:20-slim image with server +
frontend + VERSION + scripts; DATA_DIR=/data volume for db/uploads/jwt-secret.
Verified to build, boot, serve the dashboard + web player, and persist state.
- docker-compose.example.yml: /data volume, SELF_HOSTED, a node-fetch healthcheck
against /api/status, and an admin-lockout recovery note (reset-admin.js).
- server.js: resolve the OTA APK from DATA_DIR first (a container can mount one
at /data/ScreenTinker.apk), fall back to the legacy in-repo path, 404 gracefully.
- ci.yml: bump checkout/setup-node to v6 (clears the Node-20 action deprecation).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- test job: node 20, npm ci + npm test in server/ (66 tests).
- smoke job: boot the server against a fresh SQLite db with SELF_HOSTED, then
assert /api/status is ok and reports exactly the VERSION file (proves the
single-source-of-truth wiring end to end).
- triggers: push and PR to main, plus manual workflow_dispatch. Concurrency
cancels superseded in-flight runs per ref.
- upgrade-path job left as a TODO (needs a release tag earlier than HEAD).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>