chore: add release workflow (commitlint, husky, lint-staged, release-it)
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
pnpm commitlint --edit "$1"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
pnpm lint-staged
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"npm": {
|
||||||
|
"publish": false
|
||||||
|
},
|
||||||
|
"git": {
|
||||||
|
"commitMessage": "chore: release v${version}",
|
||||||
|
"tagName": "v${version}",
|
||||||
|
"requireBranch": "main"
|
||||||
|
},
|
||||||
|
"github": {
|
||||||
|
"release": true,
|
||||||
|
"releaseName": "v${version}"
|
||||||
|
},
|
||||||
|
"plugins": {
|
||||||
|
"@release-it/conventional-changelog": {
|
||||||
|
"preset": {
|
||||||
|
"name": "conventionalcommits",
|
||||||
|
"types": [
|
||||||
|
{ "type": "feat", "section": "Features" },
|
||||||
|
{ "type": "fix", "section": "Bug Fixes" },
|
||||||
|
{ "type": "perf", "section": "Performance" },
|
||||||
|
{ "type": "refactor", "section": "Refactoring" },
|
||||||
|
{ "type": "docs", "section": "Documentation" },
|
||||||
|
{ "type": "chore", "section": "Maintenance", "hidden": true },
|
||||||
|
{ "type": "ci", "section": "CI/CD", "hidden": true },
|
||||||
|
{ "type": "test", "section": "Tests", "hidden": true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"infile": "CHANGELOG.md",
|
||||||
|
"header": "# Changelog\n\nAll notable changes to famapp are documented here.\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-3
@@ -1,10 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
One line per release. "What's in prod" = the highest tag listed under a date that's been deployed.
|
All notable changes to famapp are documented here.
|
||||||
|
|
||||||
Format: `## vX.Y.Z — YYYY-MM-DD`
|
<!-- release-it prepends new entries above this line -->
|
||||||
|
|
||||||
## Unreleased
|
## Pre-release history
|
||||||
|
|
||||||
|
Changes from before the release workflow was established (2026-06-01):
|
||||||
|
|
||||||
- Production deployment scaffolding: tag-based release workflow (GHCR), migration entrypoint in container, prod-side dev-login startup assertion, image-pinned compose, pre-deploy checklist.
|
- Production deployment scaffolding: tag-based release workflow (GHCR), migration entrypoint in container, prod-side dev-login startup assertion, image-pinned compose, pre-deploy checklist.
|
||||||
- famapp/authentik-server now expose host ports (3010/9200) so existing Caddy stack can proxy by IP, matching the existing homelab pattern.
|
- famapp/authentik-server now expose host ports (3010/9200) so existing Caddy stack can proxy by IP, matching the existing homelab pattern.
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export default {
|
||||||
|
extends: ["@commitlint/config-conventional"],
|
||||||
|
rules: {
|
||||||
|
"type-enum": [
|
||||||
|
2,
|
||||||
|
"always",
|
||||||
|
["feat", "fix", "refactor", "docs", "test", "chore", "perf", "ci", "revert"],
|
||||||
|
],
|
||||||
|
"subject-case": [2, "always", "lower-case"],
|
||||||
|
"subject-max-length": [2, "always", 100],
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# 0003 — Release workflow
|
||||||
|
|
||||||
|
Date: 2026-06-01
|
||||||
|
Status: accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The project needed a consistent, enforced standard for commit messages, changelog generation, versioning, and GitHub releases — especially important since both humans and AI agents (Claude Code, Codex) commit to the repo.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
- **commitlint** (`@commitlint/config-conventional`) enforces conventional commit format at the `commit-msg` git hook
|
||||||
|
- **husky** v9 wires the hooks; `prepare` installs them on `pnpm install`
|
||||||
|
- **lint-staged** runs prettier + eslint on staged files at the `pre-commit` hook
|
||||||
|
- **release-it** + `@release-it/conventional-changelog` manages the full release cycle:
|
||||||
|
- bumps `package.json` version (semver)
|
||||||
|
- generates/prepends to `CHANGELOG.md`
|
||||||
|
- creates a signed git tag (`v{version}`)
|
||||||
|
- creates a GitHub Release with the generated notes
|
||||||
|
- pushes the tag and commit
|
||||||
|
|
||||||
|
Release commands:
|
||||||
|
|
||||||
|
- `pnpm release` — interactive (prompts for increment type)
|
||||||
|
- `pnpm release:patch` / `:minor` / `:major` — non-interactive
|
||||||
|
- `pnpm release:dry` — preview without writing anything
|
||||||
|
- Requires `GITHUB_TOKEN` in env for GitHub Release creation
|
||||||
|
|
||||||
|
Conventional commit types: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `perf`, `ci`, `revert`
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Every commit is validated; bad format is rejected immediately
|
||||||
|
- CHANGELOG.md is auto-generated from commit history — no manual upkeep
|
||||||
|
- Releases are reproducible: one command, idempotent output
|
||||||
|
- `chore`, `ci`, `test` commits are hidden in the changelog; `feat`, `fix`, `perf`, `refactor`, `docs` are surfaced
|
||||||
+25
-1
@@ -25,12 +25,33 @@
|
|||||||
"db:seed": "tsx --env-file=.env scripts/seed.ts",
|
"db:seed": "tsx --env-file=.env scripts/seed.ts",
|
||||||
"db:studio": "drizzle-kit studio",
|
"db:studio": "drizzle-kit studio",
|
||||||
"gen:icons": "node scripts/generate-icons.mjs",
|
"gen:icons": "node scripts/generate-icons.mjs",
|
||||||
"vapid:generate": "node scripts/vapid-generate.mjs"
|
"vapid:generate": "node scripts/vapid-generate.mjs",
|
||||||
|
"prepare": "husky",
|
||||||
|
"release": "release-it",
|
||||||
|
"release:patch": "release-it patch",
|
||||||
|
"release:minor": "release-it minor",
|
||||||
|
"release:major": "release-it major",
|
||||||
|
"release:dry": "release-it --dry-run"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{ts,tsx}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write"
|
||||||
|
],
|
||||||
|
"*.{js,mjs,cjs}": [
|
||||||
|
"prettier --write"
|
||||||
|
],
|
||||||
|
"*.{json,md,css,yaml,yml}": [
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@commitlint/cli": "^21.0.2",
|
||||||
|
"@commitlint/config-conventional": "^21.0.2",
|
||||||
"@eslint/eslintrc": "^3.3.5",
|
"@eslint/eslintrc": "^3.3.5",
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@playwright/test": "^1.59.1",
|
"@playwright/test": "^1.59.1",
|
||||||
|
"@release-it/conventional-changelog": "^11.0.1",
|
||||||
"@tailwindcss/postcss": "^4.2.4",
|
"@tailwindcss/postcss": "^4.2.4",
|
||||||
"@types/node": "^22.9.0",
|
"@types/node": "^22.9.0",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
@@ -41,8 +62,11 @@
|
|||||||
"eslint": "^9.15.0",
|
"eslint": "^9.15.0",
|
||||||
"eslint-config-next": "^16.2.4",
|
"eslint-config-next": "^16.2.4",
|
||||||
"globals": "^15.12.0",
|
"globals": "^15.12.0",
|
||||||
|
"husky": "^9.1.7",
|
||||||
|
"lint-staged": "^17.0.7",
|
||||||
"pino-pretty": "^13.1.3",
|
"pino-pretty": "^13.1.3",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
|
"release-it": "^20.2.0",
|
||||||
"tailwindcss": "^4.2.4",
|
"tailwindcss": "^4.2.4",
|
||||||
"tsx": "^4.19.4",
|
"tsx": "^4.19.4",
|
||||||
"typescript": "^5.6.3",
|
"typescript": "^5.6.3",
|
||||||
|
|||||||
Generated
+1719
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user