From 1741fe1ca1c38195520a394df90a983993666d39 Mon Sep 17 00:00:00 2001 From: Tuan-Dat Tran Date: Fri, 20 Feb 2026 09:51:01 +0100 Subject: [PATCH] docs: add release engineering design document --- .../2026-02-20-release-engineering-design.md | 382 ++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 docs/plans/2026-02-20-release-engineering-design.md diff --git a/docs/plans/2026-02-20-release-engineering-design.md b/docs/plans/2026-02-20-release-engineering-design.md new file mode 100644 index 0000000..34b3a75 --- /dev/null +++ b/docs/plans/2026-02-20-release-engineering-design.md @@ -0,0 +1,382 @@ +# Release Engineering Design + +**Date:** 2026-02-20 +**Status:** Approved +**Author:** Claude (AI Assistant) + +## Overview + +Implement a comprehensive release engineering pipeline for the CV application using semantic-release with Docker multi-registry publishing, automated changelog generation, and multi-environment deployment (production, staging, nightly). + +## Requirements + +- **Versioning:** Semantic Versioning with Conventional Commits +- **Changelog:** Automated from conventional commit messages +- **Release Trigger:** Continuous Delivery (automatic from main branch) +- **Deployment Targets:** Docker Hub + GitHub Container Registry (GHCR) +- **Environments:** Production, Staging, Nightly/Edge + +## Architecture + +``` + ┌─────────────────────────────────────────────────────────┐ + │ GitHub Repository │ + │ │ +┌──────────┐ │ main ─────────────────────────────────────────────────► │ Production Release +│ Developer│───────►│ │ │ ├─ Git tag v1.0.0 +└──────────┘ │ └─────► semantic-release │ ├─ GitHub Release + │ ├─ version bump │ ├─ Docker Hub: latest, v1.0.0 + │ ├─ CHANGELOG.md │ └─ GHCR: latest, v1.0.0 + │ ├─ git tag │ + │ └─ GitHub release │ + │ │ + │ staging ───────► Deploy to staging environment │ Staging Deployment + │ (Docker tag: staging) │ + │ │ + │ nightly ────────► Build nightly from main │ Nightly/Edge Builds + │ (cron job) (Docker tag: nightly, edge) │ + │ │ + └─────────────────────────────────────────────────────────┘ +``` + +## Versioning Strategy + +### Semantic Versioning (SemVer) + +Version format: `MAJOR.MINOR.PATCH` (e.g., `1.2.3`) + +| Commit Type | Version Bump | Example | +|-------------|--------------|---------| +| `feat:` | Minor | 1.0.0 → 1.1.0 | +| `fix:` | Patch | 1.0.0 → 1.0.1 | +| `feat!:` or `BREAKING CHANGE:` | Major | 1.0.0 → 2.0.0 | +| `chore:`, `docs:`, `test:`, `style:`, `refactor:`, `perf:` | None | No release | + +### Conventional Commits Format + +``` +(): + +[optional body] + +[optional footer(s)] +``` + +Examples: +- `feat(admin): add password protection for admin panel` +- `fix(skills): prevent focus loss when editing category headers` +- `docs(readme): update installation instructions` +- `feat(api)!: remove deprecated endpoints` + +### Commit Types + +| Type | Description | Release? | +|------|-------------|----------| +| `feat` | New feature | Yes (minor) | +| `fix` | Bug fix | Yes (patch) | +| `docs` | Documentation changes | No | +| `style` | Code style changes (formatting) | No | +| `refactor` | Code refactoring | No | +| `perf` | Performance improvements | No | +| `test` | Adding/updating tests | No | +| `build` | Build system changes | No | +| `ci` | CI/CD changes | No | +| `chore` | Maintenance tasks | No | +| `revert` | Revert previous commit | Yes (if reverted commit was releasing) | + +## Release Pipeline + +### Production Release (main branch) + +1. Developer pushes/merges to `main` +2. CI workflow runs (lint, test, build, e2e, integration) +3. semantic-release analyzes commits since last release +4. If release-worthy commits found: + - Calculates new version + - Updates `package.json` version + - Generates/updates `CHANGELOG.md` + - Creates git tag (e.g., `v1.0.0`) + - Creates GitHub release with release notes + - Builds Docker image + - Pushes to Docker Hub and GHCR with version tags + +### Staging Deployment + +1. Push to `staging` branch +2. CI workflow runs (lint, test, build) +3. Build Docker image +4. Push to registries with `staging` tag +5. Deploy to staging environment + +### Nightly Builds + +1. Scheduled workflow runs at 02:00 UTC daily +2. Checkout `main` branch +3. Build Docker image +4. Push to registries with tags: + - `nightly` + - `edge` + - `YYYY-MM-DD` (e.g., `2026-02-20`) + +## Docker Registry Publishing + +### Registry Configuration + +**Docker Hub:** +- Image: `DOCKERHUB_USERNAME/cv-app` +- Requires: `DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN` secrets + +**GitHub Container Registry (GHCR):** +- Image: `ghcr.io/GITHUB_OWNER/cv-app` +- Requires: `GITHUB_TOKEN` (automatic) + +### Tag Strategy + +| Event | Docker Hub Tags | GHCR Tags | +|-------|-----------------|-----------| +| Production release v1.2.3 | `latest`, `v1.2.3`, `1.2`, `1` | `latest`, `v1.2.3`, `1.2`, `1` | +| Staging push | `staging` | `staging` | +| Nightly build | `nightly`, `edge`, `2026-02-20` | `nightly`, `edge`, `2026-02-20` | + +### Multi-architecture Support + +Build for multiple platforms: +- `linux/amd64` (x86_64) +- `linux/arm64` (Apple Silicon, AWS Graviton) + +## Changelog Generation + +### Format + +```markdown +## [1.1.0] - 2026-02-20 + +### Features +* **admin:** add password protection for admin panel (#123) ([abc1234](https://github.com/owner/repo/commit/abc1234)) +* **api:** add authentication endpoints (#120) ([def5678](https://github.com/owner/repo/commit/def5678)) + +### Bug Fixes +* **skills:** prevent focus loss when editing category headers (#124) ([ghi9012](https://github.com/owner/repo/commit/ghi9012)) + +### Documentation +* update installation instructions (#125) ([jkl3456](https://github.com/owner/repo/commit/jkl3456)) + +### BREAKING CHANGES +* **api:** remove deprecated `/api/v1/*` endpoints + +--- + +## [1.0.0] - 2026-02-15 +... +``` + +### Tools + +- `@semantic-release/changelog` - Generates CHANGELOG.md +- `@semantic-release/git` - Commits updated files back to repo +- `conventional-changelog-conventionalcommits` - Preset for conventional commits + +## GitHub Environments + +### Production + +- **Protection:** Required reviewers (1+) +- **Deploy Trigger:** semantic-release on main branch merge +- **Secrets:** `DOCKERHUB_TOKEN`, `DOCKERHUB_USERNAME` +- **URL:** Production deployment URL + +### Staging + +- **Protection:** Optional reviewers +- **Deploy Trigger:** Push to `staging` branch +- **URL:** Staging deployment URL + +### Nightly + +- **Protection:** None +- **Deploy Trigger:** Scheduled (cron: `0 2 * * *`) +- **URL:** Nightly build URL + +## Branch Protection Rules + +### main branch + +| Rule | Setting | +|------|---------| +| Require PR reviews | 1+ | +| Dismiss stale reviews | Yes | +| Require linear history | Yes | +| Restrict force pushes | Yes | +| Allow deletions | No | +| Required status checks | `frontend`, `backend`, `integration`, `e2e` | + +### staging branch + +| Rule | Setting | +|------|---------| +| Require PR reviews | No | +| Require linear history | No | +| Restrict force pushes | No | +| Required status checks | `frontend`, `backend` | + +## File Structure + +``` +.github/ +├── workflows/ +│ ├── ci.yml # Enhanced with commitlint +│ ├── release.yml # semantic-release workflow +│ ├── staging.yml # Staging deployment +│ └── nightly.yml # Nightly builds +├── commitlint.config.js # Conventional commits config +└── .releaserc.json # semantic-release config + +scripts/ +├── docker-tags.sh # Docker tag computation +└── release-notes.sh # Custom release notes + +docker/ +├── Dockerfile # Multi-stage build +└── docker-compose.prod.yml # Production compose file + +CHANGELOG.md # Generated by semantic-release +package.json # Version updated by semantic-release +``` + +## Implementation Components + +### 1. semantic-release Configuration + +`.releaserc.json`: +```json +{ + "branches": ["main"], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/git", + "@semantic-release/github" + ] +} +``` + +### 2. commitlint Configuration + +`commitlint.config.js`: +```javascript +module.exports = { + extends: ['@commitlint/config-conventional'], + rules: { + 'type-enum': [2, 'always', [ + 'feat', 'fix', 'docs', 'style', 'refactor', + 'perf', 'test', 'build', 'ci', 'chore', 'revert' + ]], + 'scope-enum': [2, 'always', [ + 'admin', 'api', 'ui', 'docker', 'ci', 'deps' + ]] + } +}; +``` + +### 3. Husky Git Hooks + +```bash +npx husky init +echo "npx commitlint --edit \$1" > .husky/commit-msg +``` + +### 4. GitHub Workflows + +**release.yml:** +- Triggers on push to main +- Runs semantic-release +- Builds and pushes Docker images + +**staging.yml:** +- Triggers on push to staging branch +- Builds and pushes Docker images with staging tag + +**nightly.yml:** +- Triggers on schedule (daily at 02:00 UTC) +- Builds from main with nightly/edge tags + +### 5. Docker Configuration + +Multi-stage Dockerfile with: +- Build stage for frontend +- Build stage for backend +- Production stage with nginx + +Multi-platform build using `docker buildx` + +## Security Considerations + +1. **Secrets Management:** + - Use GitHub Secrets for sensitive values + - Never commit secrets to repository + - Use `GITHUB_TOKEN` for GHCR (automatic) + +2. **Branch Protection:** + - Require PR reviews for main + - Require status checks to pass + - Restrict force pushes + +3. **Docker Image Security:** + - Use minimal base images (alpine) + - Run as non-root user + - Scan images for vulnerabilities (optional: Trivy) + +4. **Environment Protection:** + - Required reviewers for production + - Environment-specific secrets + +## Migration Plan + +1. **Phase 1: Setup Tooling** + - Install semantic-release and plugins + - Configure commitlint and husky + - Create .releaserc.json + +2. **Phase 2: Update Workflows** + - Enhance ci.yml with commitlint + - Create release.yml + - Create staging.yml + - Create nightly.yml + +3. **Phase 3: Docker Publishing** + - Configure Docker Hub credentials + - Update Dockerfile for multi-platform + - Test image publishing + +4. **Phase 4: Branch Protection** + - Create staging branch + - Configure branch protection rules + - Create GitHub environments + +5. **Phase 5: First Release** + - Make a conventional commit + - Verify semantic-release runs + - Check GitHub release created + - Verify Docker images published + +## Success Criteria + +- [ ] Conventional commits enforced via commitlint +- [ ] Version automatically bumped based on commit types +- [ ] CHANGELOG.md automatically generated and updated +- [ ] Git tags created for each release +- [ ] GitHub releases created with release notes +- [ ] Docker images published to Docker Hub and GHCR +- [ ] Multi-platform Docker images (amd64, arm64) +- [ ] Staging deployments on staging branch push +- [ ] Nightly builds running daily +- [ ] Branch protection rules enforced + +## References + +- [semantic-release Documentation](https://semantic-release.gitbook.io/) +- [Conventional Commits Specification](https://www.conventionalcommits.org/) +- [GitHub Actions Documentation](https://docs.github.com/en/actions) +- [Docker Multi-platform Builds](https://docs.docker.com/build/building/multi-platform/)