12 KiB
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
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
Examples:
feat(admin): add password protection for admin panelfix(skills): prevent focus loss when editing category headersdocs(readme): update installation instructionsfeat(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)
- Developer pushes/merges to
main - CI workflow runs (lint, test, build, e2e, integration)
- semantic-release analyzes commits since last release
- If release-worthy commits found:
- Calculates new version
- Updates
package.jsonversion - 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
- Push to
stagingbranch - CI workflow runs (lint, test, build)
- Build Docker image
- Push to registries with
stagingtag - Deploy to staging environment
Nightly Builds
- Scheduled workflow runs at 02:00 UTC daily
- Checkout
mainbranch - Build Docker image
- Push to registries with tags:
nightlyedgeYYYY-MM-DD(e.g.,2026-02-20)
Docker Registry Publishing
Registry Configuration
Docker Hub:
- Image:
DOCKERHUB_USERNAME/cv-app - Requires:
DOCKERHUB_USERNAME,DOCKERHUB_TOKENsecrets
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
## [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 repoconventional-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
stagingbranch - 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:
{
"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:
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
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
-
Secrets Management:
- Use GitHub Secrets for sensitive values
- Never commit secrets to repository
- Use
GITHUB_TOKENfor GHCR (automatic)
-
Branch Protection:
- Require PR reviews for main
- Require status checks to pass
- Restrict force pushes
-
Docker Image Security:
- Use minimal base images (alpine)
- Run as non-root user
- Scan images for vulnerabilities (optional: Trivy)
-
Environment Protection:
- Required reviewers for production
- Environment-specific secrets
Migration Plan
-
Phase 1: Setup Tooling
- Install semantic-release and plugins
- Configure commitlint and husky
- Create .releaserc.json
-
Phase 2: Update Workflows
- Enhance ci.yml with commitlint
- Create release.yml
- Create staging.yml
- Create nightly.yml
-
Phase 3: Docker Publishing
- Configure Docker Hub credentials
- Update Dockerfile for multi-platform
- Test image publishing
-
Phase 4: Branch Protection
- Create staging branch
- Configure branch protection rules
- Create GitHub environments
-
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