Files
kilo-cv/docs/release-engineering.md

23 KiB

Release Engineering Documentation

Overview

This project uses a fully automated release engineering pipeline powered by semantic-release, commitlint, and GitHub Actions. The pipeline handles versioning, changelog generation, Docker image publishing, and multi-environment deployments.

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                              Developer Workflow                              │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   1. Write code with conventional commits                                    │
│   2. Push to feature branch                                                  │
│   3. Create PR → CI validates commits + code                                │
│   4. Merge to master → Release pipeline triggers                            │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                           GitHub Actions Pipeline                            │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌─────────────┐    ┌─────────────────┐    ┌──────────────────────────┐    │
│  │   CI Job    │───►│  Release Job    │───►│    Docker Build Job      │    │
│  │             │    │                 │    │                          │    │
│  │ • Lint      │    │ • Analyze       │    │ • Multi-platform build   │    │
│  │ • Test      │    │   commits       │    │   (amd64, arm64)         │    │
│  │ • Build     │    │ • Bump version  │    │ • Push to Docker Hub     │    │
│  │ • Commitlint│    │ • Update        │    │ • Push to GHCR           │    │
│  │             │    │   CHANGELOG     │    │                          │    │
│  │             │    │ • Create tag    │    │                          │    │
│  │             │    │ • GitHub release│    │                          │    │
│  └─────────────┘    └─────────────────┘    └──────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                              Registries                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌─────────────────────────────┐    ┌─────────────────────────────────┐    │
│  │        Docker Hub           │    │   GitHub Container Registry     │    │
│  │                             │    │                                 │    │
│  │  username/cv-app:latest     │    │  ghcr.io/owner/cv-app:latest    │    │
│  │  username/cv-app:v1.0.0     │    │  ghcr.io/owner/cv-app:v1.0.0    │    │
│  │  username/cv-app:staging    │    │  ghcr.io/owner/cv-app:staging   │    │
│  │  username/cv-app:nightly    │    │  ghcr.io/owner/cv-app:nightly   │    │
│  └─────────────────────────────┘    └─────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Components

1. Conventional Commits

All commits must follow the Conventional Commits specification:

<type>(<scope>): <description>

[optional body]

[optional footer]

Commit Types

Type Description Version Bump Example
feat New feature Minor (1.0.0 → 1.1.0) feat(admin): add password protection
fix Bug fix Patch (1.0.0 → 1.0.1) fix(skills): prevent focus loss
perf Performance improvement Patch perf(ui): lazy load images
feat! Breaking change Major (1.0.0 → 2.0.0) feat(api)!: remove deprecated endpoints
docs Documentation only None docs(readme): update installation
style Code style (formatting) None style(ui): fix indentation
refactor Code refactoring None refactor(auth): simplify token validation
test Adding/updating tests None test(api): add auth middleware tests
build Build system changes None build(docker): update node version
ci CI/CD changes None ci(github): add staging workflow
chore Maintenance tasks None chore(deps): update dependencies
revert Revert previous commit Patch revert: remove broken feature

Allowed Scopes

Scope Description
admin Admin panel components
api Backend API
ui Frontend UI components
docker Docker configuration
ci CI/CD workflows
deps Dependencies
release Release configuration
auth Authentication
skills Skills section
experience Experience section
education Education section
projects Projects section
personal Personal info section

2. semantic-release

semantic-release automates the entire release process:

  1. Commit Analysis: Analyzes commits since last release
  2. Version Calculation: Determines next version based on commit types
  3. Changelog Generation: Updates CHANGELOG.md with changes
  4. Git Operations: Creates tags and commits version bump
  5. GitHub Release: Creates release with notes and assets

Configuration

Located in .releaserc.json:

{
  "branches": ["master", { "name": "staging", "prerelease": true }],
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/changelog",
    "@semantic-release/npm",
    "@semantic-release/git",
    "@semantic-release/github"
  ]
}

3. commitlint

Enforces conventional commits via:

  • Git hook: Validates every commit message locally
  • CI job: Validates commits in pull requests

Configuration in commitlint.config.js:

  • Validates commit types
  • Validates scopes
  • Enforces lowercase subjects
  • Limits subject length to 72 characters

4. Husky Git Hooks

Hook Purpose Command
pre-commit Run linting before commit npm run lint
commit-msg Validate commit message commitlint --edit

5. GitHub Actions Workflows

CI Workflow (.github/workflows/ci.yml)

Runs on: Push to master, Pull requests to master

┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│  Frontend   │  │   Backend   │  │ Commitlint  │
│     Job     │  │     Job     │  │     Job     │
├─────────────┤  ├─────────────┤  ├─────────────┤
│ • Lint      │  │ • Install   │  │ • Validate  │
│ • Test      │  │ • Test      │  │   commits   │
│ • Build     │  │             │  │             │
└─────────────┘  └─────────────┘  └─────────────┘
       │                │                │
       └────────────────┼────────────────┘
                        ▼
              ┌─────────────────┐
              │   Integration   │
              │       Job       │
              └─────────────────┘
                        │
                        ▼
              ┌─────────────────┐
              │      E2E        │
              │      Job        │
              └─────────────────┘

Release Workflow (.github/workflows/release.yml)

Runs on: Push to master (excluding [skip ci] commits)

┌───────────────────────────────────────────────────────────┐
│                      Release Job                          │
├───────────────────────────────────────────────────────────┤
│ 1. Checkout (fetch-depth: 0 for full history)            │
│ 2. Setup Node.js 20                                       │
│ 3. Install dependencies (root + backend)                  │
│ 4. Lint                                                   │
│ 5. Run tests (root + backend)                             │
│ 6. Build                                                  │
│ 7. semantic-release                                       │
│    - Analyze commits                                      │
│    - Bump version                                         │
│    - Update CHANGELOG.md                                  │
│    - Create git tag                                       │
│    - Create GitHub release                                │
└───────────────────────────────────────────────────────────┘
                          │
                          ▼
┌───────────────────────────────────────────────────────────┐
│                    Docker Build Job                        │
├───────────────────────────────────────────────────────────┤
│ 1. Checkout                                               │
│ 2. Get version from git tag                               │
│ 3. Setup QEMU (for multi-platform)                       │
│ 4. Setup Docker Buildx                                    │
│ 5. Login to Docker Hub                                    │
│ 6. Login to GHCR                                          │
│ 7. Build and push (amd64 + arm64)                        │
└───────────────────────────────────────────────────────────┘

Staging Workflow (.github/workflows/staging.yml)

Runs on: Push to staging branch

┌───────────────────────────────────────────────────────────┐
│                  Staging Deploy Job                       │
├───────────────────────────────────────────────────────────┤
│ 1. Checkout                                               │
│ 2. Install + Lint + Test + Build                         │
│ 3. Build Docker image (multi-platform)                   │
│ 4. Push with tag: staging                                 │
└───────────────────────────────────────────────────────────┘

Nightly Workflow (.github/workflows/nightly.yml)

Runs on: Schedule (daily at 02:00 UTC)

┌───────────────────────────────────────────────────────────┐
│                    Nightly Build Job                      │
├───────────────────────────────────────────────────────────┤
│ 1. Checkout master                                        │
│ 2. Get current date                                       │
│ 3. Install + Build                                        │
│ 4. Build Docker image (multi-platform)                   │
│ 5. Push with tags: nightly, edge, YYYY-MM-DD             │
└───────────────────────────────────────────────────────────┘

Docker Image Tags

Tag Registry Description Update Frequency
latest Both Latest stable release Every release
v1.0.0 Both Specific version Immutable
1.0 Both Major.minor Points to latest patch
1 Both Major version Points to latest minor
staging Both Staging environment Every staging push
nightly Both Latest nightly build Daily
edge Both Alias for nightly Daily
2026-02-20 Both Date-specific nightly Immutable

Pulling Images

# Docker Hub
docker pull username/cv-app:latest
docker pull username/cv-app:v1.0.0
docker pull username/cv-app:staging
docker pull username/cv-app:nightly

# GitHub Container Registry
docker pull ghcr.io/owner/cv-app:latest
docker pull ghcr.io/owner/cv-app:v1.0.0

Environments

Environment Branch Trigger Docker Tag
Production master semantic-release (feat/fix commits) latest, vX.Y.Z
Staging staging Push to branch staging
Nightly master Daily at 02:00 UTC nightly, edge, YYYY-MM-DD

Release Flow Example

Developer commits: feat(admin): add export functionality
                       │
                       ▼
              ┌─────────────────┐
              │  Git Hook Runs  │
              │  (pre-commit)   │
              │  • npm run lint │
              └─────────────────┘
                       │
                       ▼
              ┌─────────────────┐
              │  Git Hook Runs  │
              │  (commit-msg)   │
              │  • commitlint   │
              └─────────────────┘
                       │
                       ▼
              ┌─────────────────┐
              │   Push to PR    │
              │                 │
              │ CI validates:   │
              │ • commitlint    │
              │ • lint          │
              │ • test          │
              │ • build         │
              └─────────────────┘
                       │
                       ▼
              ┌─────────────────┐
              │   Merge to      │
              │    master       │
              └─────────────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ Release Workflow│
              │    Triggers     │
              └─────────────────┘
                       │
                       ▼
              ┌─────────────────────────────────────┐
              │     semantic-release analyzes       │
              │                                     │
              │  Previous version: 1.0.0            │
              │  Commits since last release:        │
              │    • feat(admin): add export        │
              │                                     │
              │  Decision: MINOR release            │
              │  New version: 1.1.0                 │
              └─────────────────────────────────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ Version bumped  │
              │ in package.json │
              │    1.0.0 → 1.1.0│
              └─────────────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ CHANGELOG.md    │
              │   updated       │
              └─────────────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ Git tag created │
              │     v1.1.0      │
              └─────────────────┘
                       │
                       ▼
              ┌─────────────────┐
              │ GitHub Release  │
              │    created      │
              │  with notes     │
              └─────────────────┘
                       │
                       ▼
              ┌─────────────────────────────────┐
              │     Docker images built and     │
              │          pushed to:             │
              │                                 │
              │  • username/cv-app:latest       │
              │  • username/cv-app:v1.1.0       │
              │  • ghcr.io/owner/cv-app:latest  │
              │  • ghcr.io/owner/cv-app:v1.1.0  │
              └─────────────────────────────────┘

Required Secrets

Configure these in GitHub repository settings → Secrets and variables → Actions:

Secret Description Required For
DOCKERHUB_USERNAME Docker Hub username Docker Hub push
DOCKERHUB_TOKEN Docker Hub access token Docker Hub push
GITHUB_TOKEN GitHub token (automatic) GHCR push, releases

Creating Docker Hub Token

  1. Go to Docker Hub → Account Settings → Security
  2. Click "New Access Token"
  3. Name: cv-app-github-actions
  4. Permissions: Read, Write, Delete
  5. Copy token and add to GitHub secrets

Local Development

Testing Commit Messages

# Test a valid commit message
echo "feat(ui): add new button component" | npx commitlint

# Test an invalid commit message
echo "added a button" | npx commitlint

Skipping CI

Add [skip ci] to commit message to skip CI:

git commit -m "docs: update readme [skip ci]"

Manual Release Trigger

  1. Go to Actions → Release workflow
  2. Click "Run workflow"
  3. Select branch (master)
  4. Click "Run workflow"

Troubleshooting

Commit Rejected by commitlint

Error: subject must be lower-case

Fix: Use lowercase for the subject:

# Wrong
git commit -m "feat(ui): Add new button"

# Correct
git commit -m "feat(ui): add new button"

Release Not Triggering

Causes:

  1. No release-worthy commits (only docs/style/refactor/test/build/ci/chore)
  2. Commit message contains [skip ci]
  3. Workflow already running

Solution: Ensure you have feat, fix, or perf commits since last release.

Docker Push Fails

Error: denied: requested access to the resource is denied

Fix:

  1. Verify DOCKERHUB_USERNAME and DOCKERHUB_TOKEN secrets
  2. Ensure Docker Hub token has Write permission
  3. Check Docker Hub repository exists (or enable auto-create)

Version Not Bumping

Cause: semantic-release requires conventional commits with proper types.

Fix: Ensure commits follow:

  • feat: for features (minor bump)
  • fix: for bug fixes (patch bump)
  • feat!: or BREAKING CHANGE: for breaking changes (major bump)

File Reference

File Purpose
.releaserc.json semantic-release configuration
commitlint.config.js Commitlint rules
.husky/pre-commit Pre-commit hook (lint)
.husky/commit-msg Commit message hook (commitlint)
.github/workflows/ci.yml CI pipeline
.github/workflows/release.yml Release pipeline
.github/workflows/staging.yml Staging deployment
.github/workflows/nightly.yml Nightly builds
docker-bake.hcl Multi-platform Docker build config
CHANGELOG.md Auto-generated changelog