CI/CD & Versioning for dicechess-analytics-ui
Background
Currently dicechess-analytics-ui has minimal infrastructure:
- ✅
mise.tomlwith basic tasks (setup,dev,build,check) - ✅ Docker build + push to GHCR (
deploy.yml) - ✅ CodeRabbit PR reviews (
.coderabbit.yaml) - ❌ No CI pipeline (lint, type-check, test)
- ❌ No linter/formatter installed (ESLint, Prettier missing despite CodeRabbit referencing them)
- ❌ No testing framework
- ❌ No automated versioning or changelog
- ❌ No PR labeler or stale bot
- ❌ No pre-commit hooks
- ❌ No
mise run format(required by AGENTS.md)
Reference Repositories Comparison
| Feature | dicechess-lab | dicechess-engine-scala | analytics-ui now |
|---|---|---|---|
| CI pipeline | ✅ Backend + Frontend CI | ✅ sbt build+test | ❌ None |
| Versioning | ✅ Manual Ops: Release + git tags | ✅ Release Please (simple) | ❌ Static 0.1.0 |
| Deploy chain | ✅ Release → Staging → E2E → Prod | ✅ — | ✅ Docker only |
| PR labeler | ✅ | ✅ | ❌ |
| Stale bot | ✅ | ✅ | ❌ |
| Pre-commit hooks | ✅ 7 hooks | — | ❌ |
| Linting | ✅ Ruff + Svelte-check | ✅ scalafmt | ❌ Svelte-check only |
| Formatting | ✅ Ruff + Prettier | ✅ scalafmt | ❌ None |
| Unit testing | ✅ pytest + Vitest | ✅ MUnit | ❌ None |
| E2E testing | ✅ Playwright | — | ❌ |
| Type checking | ✅ ty + mypy + svelte-check | ✅ scalac | ✅ svelte-check + tsc |
| Dependabot | ✅ 7 ecosystems | — | ❌ |
| Code review bot | — | — | ✅ CodeRabbit |
| Docs site | ✅ MkDocs → GH Pages | ✅ Docusaurus → GH Pages | ❌ |
User Review Required
> Versioning strategy choice:
dicechess-labuses a manualOps: Releaseworkflow (trigger → bump tag → GitHub Release), whiledicechess-engine-scalauses Release Please (auto-generates PRs from Conventional Commits). Which approach do you prefer foranalytics-ui?
> Deployment model: Currently the Docker image is pushed to GHCR on every push to
main. Should we add a staging/production deployment chain similar todicechess-lab(with self-hosted runners on RPi), or keep the simple Docker-push model?
> SvelteKit migration consideration: The current project uses plain Svelte 5 + Vite (not SvelteKit). This is fine for a SPA but means we don't have SvelteKit's built-in adapter-static for GitHub Pages. Should we keep the current architecture?
Open Questions
- Do you want Playwright E2E tests in Phase 2, or is unit testing with Vitest sufficient for now?
- Should we add Dependabot (like
dicechess-labwith weekly schedules per ecosystem)? - Documentation site — is this needed for
analytics-ui, or is README sufficient? - Telegram notifications — should we add deployment notifications (like
dicechess-lab)?
Proposed Changes
Phase 1 — Code Quality Foundation
[NEW] .github/workflows/ci.yml
CI pipeline triggered on push/PR to main:
- Lint — ESLint check
- Format — Prettier check
- Type-check —
svelte-check+tsc - Build —
vite build(ensures the project compiles)
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v2
- run: npm ci
- run: npm run lint
- run: npm run format:check
- run: npm run check
- run: npm run build[MODIFY] package.json
Add missing dev dependencies and scripts:
- Install:
eslint,@eslint/js,typescript-eslint,eslint-plugin-svelte,prettier,prettier-plugin-svelte - Add scripts:
lint,format,format:check
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
- "check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json"
+ "check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json",
+ "lint": "eslint .",
+ "format": "prettier --write .",
+ "format:check": "prettier --check ."
}[NEW] eslint.config.js
Flat config with eslint-plugin-svelte + typescript-eslint, matching dicechess-lab frontend patterns.
[NEW] .prettierrc
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}[NEW] .prettierignore
package-lock.json
dist/
node_modules/
public/
[MODIFY] mise.toml
Add format and lint tasks to satisfy AGENTS.md requirement:
[tasks.format]
description = "🎨 Format code with Prettier"
run = "npm run format"
[tasks.lint]
description = "🔍 Run ESLint checks"
run = "npm run lint"
[tasks.check]
description = "✅ Run all quality checks (lint + format + types)"
run = ["npm run lint", "npm run format:check", "npm run check"]Phase 2 — Versioning & Release Automation
Option A: Release Please (like dicechess-engine-scala)
[NEW] .github/workflows/release.yml
name: Release Please
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
config-file: release-please-config.json
manifest-file: .release-please-manifest.json[NEW] release-please-config.json
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"packages": {
".": {
"release-type": "node",
"changelog-path": "CHANGELOG.md"
}
}
}[NEW] .release-please-manifest.json
{
".": "0.1.0"
}Option B: Manual Ops: Release (like dicechess-lab)
Similar to dicechess-lab’s release.yaml with manual workflow_dispatch and patch/minor/major input.
Phase 3 — GitHub Automation
[NEW] .github/workflows/labeler.yml
Auto-label PRs based on changed paths:
| Label | Paths |
|---|---|
frontend | src/** |
ci | .github/workflows/** |
dependencies | package.json, package-lock.json |
documentation | *.md, docs/** |
docker | Dockerfile, nginx.conf, .dockerignore |
[NEW] .github/labeler.yml
Label definitions for the labeler action.
[NEW] .github/workflows/stale.yml
Stale bot matching dicechess-engine-scala pattern:
- Issues: stale after 60 days, close after 14
- PRs: stale after 30 days, close after 10
- Exempt labels:
pinned,security,enhancement
Phase 4 — Testing Infrastructure
Install Vitest
npm install -D vitest @testing-library/svelte @testing-library/jest-dom jsdom[MODIFY] vite.config.ts
Add Vitest configuration:
/// <reference types="vitest/config" />
import { defineConfig } from "vite"
export default defineConfig({
// ... existing config
test: {
environment: "jsdom",
include: ["src/**/*.test.ts"],
coverage: {
provider: "v8",
reporter: ["text", "json-summary"],
},
},
})[MODIFY] package.json
+"test": "vitest run",
+"test:watch": "vitest",
+"test:coverage": "vitest run --coverage"[MODIFY] mise.toml
[tasks.test]
description = "🧪 Run unit tests"
run = "npm run test"Phase 5 — Optional Enhancements
Dependabot
[NEW] .github/dependabot.yml — weekly updates for npm and github-actions ecosystems.
Pre-commit Hooks
Based on dicechess-lab pattern:
- trailing-whitespace, end-of-file-fixer
- gitleaks (secret scanning)
- ESLint + Prettier
- svelte-check
- actionlint
Docker Deploy Enhancement
Modify existing deploy.yml to add version tagging from git tags (not just latest + SHA).
Verification Plan
Automated Tests
# After Phase 1
mise run check # Should run lint + format:check + svelte-check + tsc
mise run format # Should format all files with Prettier
# After Phase 4
mise run test # Should run Vitest suiteCI Validation
- Push a test branch → verify CI workflow runs lint + format + type-check + build
- Merge a conventional commit → verify Release Please creates a release PR
Manual Verification
- Confirm
mise run formatandmise run checkwork locally - Verify GitHub Actions workflows appear and run correctly
- Check that PR labeler correctly assigns labels