diff --git a/.gitea/ISSUE_TEMPLATE/adr-proposal.md b/.gitea/ISSUE_TEMPLATE/adr-proposal.md new file mode 100644 index 0000000..587b4d6 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/adr-proposal.md @@ -0,0 +1,24 @@ +--- +name: ADR proposal +about: Propose a decision that needs recording before coding (CLAUDE.md §14) +title: "ADR: " +labels: + - type:adr-proposal +--- + +**Decision to be made:** + +**Context / forces:** + +**Options considered:** +1. +2. + +**Proposed option + why:** + +**Consequences:** + +**Coupling rules touched (CLAUDE.md §8):** + +> On acceptance, the ADR file (`docs/architecture/adr-NNNN-title.md`, Nygard +> template) lands in the PR that implements the decision. diff --git a/.gitea/ISSUE_TEMPLATE/bug.md b/.gitea/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000..6724e72 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,21 @@ +--- +name: Bug +about: Something behaves incorrectly +title: "" +labels: + - type:bug +--- + +**What happened:** + +**What you expected:** + +**Steps to reproduce:** +1. +2. + +**Environment:** + +**Logs / evidence:** + +**Suspected area:** diff --git a/.gitea/ISSUE_TEMPLATE/slice.md b/.gitea/ISSUE_TEMPLATE/slice.md new file mode 100644 index 0000000..43d0f15 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/slice.md @@ -0,0 +1,31 @@ +--- +name: Slice (user story) +about: A backlog slice — independently demoable, encodes the Definition of Done +title: "S-NN · " +labels: + - type:slice +--- + +**Outcome:** + +**Acceptance:** + +- + +**Touches:** + +**Out of scope:** + +## Definition of Done + +- [ ] This linked Gitea issue exists and is on the right milestone. +- [ ] Failing test written and committed first (`test(scope): … (refs #NN)`). +- [ ] Implementation makes the test pass (`feat(scope): … (refs #NN)`). +- [ ] Refactor commit follows if structure improved. +- [ ] Conventional Commit messages referencing this issue. +- [ ] All Gitea Actions CI jobs green (or `make ci` green while no runner exists). +- [ ] `docker compose up` from a fresh clone reaches green health checks within 3 minutes. +- [ ] Docs touched if behaviour, contracts, or operations changed. +- [ ] ADR added in `docs/architecture/` if a non-obvious decision was made. +- [ ] Demo note appended to `docs/demo-script.md` if the slice is user-visible. +- [ ] This issue closed by the merging PR (`closes #NN`). diff --git a/.gitea/PULL_REQUEST_TEMPLATE.md b/.gitea/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..2d19747 --- /dev/null +++ b/.gitea/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,23 @@ + + +## What & why + + + +Closes # + +## Definition of Done + +- [ ] Linked Gitea issue (above). +- [ ] Failing test committed before the implementation. +- [ ] Implementation makes the test pass; refactor commit if structure improved. +- [ ] Conventional Commits referencing the issue (`refs #NN`). +- [ ] CI green — all Gitea Actions jobs (or `make ci` green while no runner exists). +- [ ] `docker compose up` from a fresh clone reaches green health checks within 3 minutes. +- [ ] Docs updated if behaviour, contracts, or operations changed. +- [ ] ADR added in `docs/architecture/` if a non-obvious decision was made. +- [ ] Demo note in `docs/demo-script.md` if user-visible. + +## Notes for reviewers + + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9330697 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ +# Changelog + +All notable changes to this project. Generated from Conventional Commits by git-cliff. + +## Unreleased + +### CI +- Gitea Actions pipeline + runner runbook (refs #30) (#37) + +### Chores +- Add idempotent Gitea backlog seeder +- Remove bootstrap scripts from main (#35) + +### Documentation +- Split S-00 into sub-slices (refs #1) (#33) + +### Features +- Placeholder BFF + /health endpoint (closes #28) (#34) +- Containerize BFF + compose-up smoke (closes #29) (#36) + diff --git a/Makefile b/Makefile index f28b612..4848f54 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ export DOCKER_HOST := unix://$(PODMAN_SOCK) endif endif -.PHONY: ci lint build unit smoke down help +.PHONY: ci lint build unit smoke down changelog help ## ci: run the full pipeline — lint, build, unit, smoke (mirrors Gitea Actions) ci: lint build unit smoke @@ -45,6 +45,10 @@ smoke: down: docker compose -f $(COMPOSE) down --volumes +## changelog: regenerate CHANGELOG.md from Conventional Commits (git-cliff) +changelog: + git-cliff --output CHANGELOG.md + ## help: list available targets help: @grep -E '^## ' $(MAKEFILE_LIST) | sed 's/^## //' diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..9d95d2a --- /dev/null +++ b/cliff.toml @@ -0,0 +1,45 @@ +# git-cliff configuration — generates CHANGELOG.md from Conventional Commits. +# Run via `make changelog`. See https://git-cliff.org. + +[changelog] +header = """ +# Changelog + +All notable changes to this project. Generated from Conventional Commits by git-cliff.\n +""" +body = """ +{% if version %}\ +## {{ version }} — {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ +## Unreleased +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} +### {{ group | upper_first }} +{% for commit in commits %}\ +- {{ commit.message | upper_first }}{% if commit.breaking %} **[BREAKING]**{% endif %} +{% endfor %}\ +{% endfor %}\n +""" +trim = true + +[git] +conventional_commits = true +filter_unconventional = true +split_commits = false +protect_breaking_commits = true +tag_pattern = "v[0-9]*" +# CalVer tags: YYYY.MM.PATCH +filter_commits = false +commit_parsers = [ + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^perf", group = "Performance" }, + { message = "^refactor", group = "Refactor" }, + { message = "^docs", group = "Documentation" }, + { message = "^test", group = "Tests" }, + { message = "^ci", group = "CI" }, + { message = "^build", group = "Build" }, + { message = "^arch", group = "Architecture" }, + { message = "^chore", group = "Chores" }, + { message = ".*", group = "Other" }, +] diff --git a/docs/gitea-workflow.md b/docs/gitea-workflow.md new file mode 100644 index 0000000..04011f9 --- /dev/null +++ b/docs/gitea-workflow.md @@ -0,0 +1,52 @@ +# Working with Gitea: issues, milestones, PRs + +Gitea is the **system of record** (CLAUDE.md §7). `BACKLOG.md` is a human-readable +mirror of the active milestone — when they disagree, Gitea wins. + +## Issues + +- Open issues from the templates in `.gitea/ISSUE_TEMPLATE/`: + - **Slice** — a backlog user story (`S-NN · …`), encodes the Definition of Done. + - **Bug** — a defect. + - **ADR proposal** — a decision to record before coding (CLAUDE.md §14). +- Every issue gets `type:*` plus the relevant `area:*` label(s), and is assigned to + its iteration **milestone** (`Iteration N — …`). +- Splitting a slice that grew too big: see CLAUDE.md §13 and the "How to split a + slice" section of `BACKLOG.md`. + +## Branches & commits + +- Trunk-based: short-lived branches off `main`, squash-merged. Never push to `main`. +- Branch name: `/-`, e.g. `feat/28-bff-health`. +- Conventional Commits, each referencing its issue: `feat(bff): … (refs #28)`. +- TDD order: the `test(...)` red commit precedes the `feat(...)` green commit. + +## Pull requests + +- Open with `tea pr create` (the Gitea CLI) or the web UI; the body uses + `.gitea/PULL_REQUEST_TEMPLATE.md` and its DoD checklist. +- The merging PR closes its issue via `closes #NN` in the squash-commit body. + Work that isn't finished (e.g. CI green pending a runner) uses `refs #NN` and the + issue stays open. +- A PR needs a linked issue. Don't open one without it. + +## CI gate + +Until a self-hosted `respellion-linux` runner is registered, `make ci` is the gate +(it runs the same checks the workflow does). See [runbooks/ci.md](runbooks/ci.md). + +## CLI cheatsheet (`tea`) + +```bash +tea issues list --state open # backlog +tea issue create --title "S-NN · …" --labels type:slice,area:bff --milestone "Iteration 1 — Walking Skeleton" +tea pr create --base main --head --title "…" --description "… closes #NN" +tea pr list # open PRs +tea pr merge --style squash # merge (after review) +``` + +## Changelog & releases + +`CHANGELOG.md` is generated from commits by `git-cliff` (`make changelog`), refreshed +on tag. Versioning is **CalVer** `YYYY.MM.PATCH`; releases are published via Gitea +Releases.