Files

Quick Reference Guide - Cannabrands Release Workflow

Print this and keep it handy!


Daily Development (What You'll Do 95% of the Time)

Making Changes

# 1. Pull latest
git checkout master
git pull origin master

# 2. Make changes, commit with conventional format
git add .
git commit -m "feat(orders): add bulk import feature"
git push origin master

# ✅ DONE - CI automatically builds dev image

Conventional Commit Format

Format: type(scope): description

Types:

  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation only
  • style: - Code style (formatting)
  • refactor: - Code refactoring
  • test: - Adding tests
  • chore: - Build/dependencies

Examples:

git commit -m "feat(orders): add CSV bulk import"
git commit -m "fix(invoices): correct CA tax calculation"
git commit -m "docs: update deployment guide"
git commit -m "refactor(auth): simplify login flow"

Creating a Release (Weekly/Monthly)

Step 1: Determine Version Number

# What's the current month and year?
# Today: November 2025

# Check existing releases this month
git tag -l "2025.11.*" | sort -V | tail -1
# Output: 2025.11.2

# Next version: 2025.11.3

Format: YYYY.MM.MICRO

  • 2025 = Year
  • 11 = Month (November)
  • 3 = Third release this month

Step 2: Create Git Tag

# Create annotated tag with release notes
git tag -a 2025.11.3 -m "Release 2025.11.3 - Bulk Import Feature

Features:
- Added CSV bulk order import
- Enhanced manifest generation

Bug Fixes:
- Fixed invoice tax calculation
- Corrected order status transitions
"

# Push tag to trigger CI
git push origin 2025.11.3

Step 3: Wait for CI Build (2-4 minutes)

Watch at: code.cannabrands.app/cannabrands/hub/pipelines

CI will automatically:

  • Run tests
  • Build Docker image
  • Tag as: 2025.11.3 and stable
  • Push to registry

Step 4: Generate Changelog

# Generate/update CHANGELOG.md from commits
npm run changelog

# Review the changes
cat CHANGELOG.md

# Commit the updated changelog
git add CHANGELOG.md
git commit -m "docs: update changelog for 2025.11.3"
git push origin master

Step 5: Deploy to Production (When Ready)

# Deploy specific version
kubectl set image deployment/cannabrands \
  app=code.cannabrands.app/cannabrands/hub:2025.11.3

# Watch deployment
kubectl rollout status deployment/cannabrands

# Verify
kubectl get pods

Emergency Rollback

Production is Broken - Immediate Action

# Option 1: Rollback to previous version
kubectl set image deployment/cannabrands \
  app=code.cannabrands.app/cannabrands/hub:2025.11.2

# Option 2: Kubernetes automatic rollback
kubectl rollout undo deployment/cannabrands

# Verify rollback
kubectl rollout status deployment/cannabrands

After Rollback - Fix Properly

# 1. Fix the bug on master
git commit -m "fix: invoice calculation regression"
git push origin master

# 2. Test thoroughly in staging
# 3. Create new release
git tag -a 2025.11.4 -m "Hotfix: Invoice calculation"
git push origin 2025.11.4

# 4. Deploy when confident
kubectl set image deployment/cannabrands \
  app=code.cannabrands.app/cannabrands/hub:2025.11.4

Image Tags Explained

Development Images (Automatic)

latest-dev          → Always newest master
dev-c658193         → Specific commit (for debugging)
master              → Branch tracking

Use in K3s dev/staging:

image: code.cannabrands.app/cannabrands/hub:latest-dev
imagePullPolicy: Always

Production Images (Manual Release)

2025.11.3           → Specific release
stable              → Latest production release

Use in K3s production:

image: code.cannabrands.app/cannabrands/hub:2025.11.3
imagePullPolicy: IfNotPresent

Common Commands

Check Current Version

# What's deployed in production?
kubectl get deployment cannabrands -o jsonpath='{.spec.template.spec.containers[0].image}'

# What releases exist this month?
git tag -l "2025.11.*" | sort -V

Test Locally

# Run tests
./vendor/bin/sail artisan test

# Check code style
./vendor/bin/pint --test

# Build Docker image locally
docker build -t cannabrands:test .

View CI Status

# Visit Woodpecker
open https://code.cannabrands.app/cannabrands/hub/pipelines

# Or check latest build
# (Visit Gitea → Repository → Pipelines)

Troubleshooting

CI Build Failing

# Check Woodpecker logs
# Visit: code.cannabrands.app/cannabrands/hub/pipelines

# Run tests locally first
./vendor/bin/sail artisan test

# Fix issues, push again
git commit -m "fix: broken tests"
git push origin master

Wrong Version Tagged

# Delete tag locally
git tag -d 2025.11.3

# Delete tag remotely
git push origin :refs/tags/2025.11.3

# Create correct tag
git tag -a 2025.11.3 -m "Release 2025.11.3"
git push origin 2025.11.3

Changelog Not Generating

# Make sure you have conventional commits
git log --oneline | head -10

# Should see: feat:, fix:, docs:, etc.

# If missing, your commits need to follow convention
# Run changelog anyway
npm run changelog

Versioning Examples

Typical Month

2025.11.1  (Nov 5)  - First release
2025.11.2  (Nov 12) - Bug fixes
2025.11.3  (Nov 19) - New features
2025.11.4  (Nov 26) - Hotfix
2025.12.1  (Dec 3)  - New month, reset

High Frequency (Multiple per day)

2025.11.23.1  - Morning release
2025.11.23.2  - Afternoon hotfix
2025.11.24.1  - Next day

Skipping Numbers (OK!)

2025.11.1  ✅
2025.11.2  ✅
2025.11.5  ✅ (skipped 3 and 4 - fine!)

CI/CD Pipeline Stages

The Woodpecker CI pipeline runs the following stages for every push to develop or master:

  1. PHP Lint - Syntax validation
  2. Code Style (Pint) - Formatting check
  3. Tests - PHPUnit/Pest tests with APP_ENV=testing
  4. Seeder Validation - Validates seeders with APP_ENV=development
  5. Docker Build - Creates container image
  6. Auto-Deploy - Deploys to dev.cannabrands.app (develop branch only)

Why Seeder Validation?

The dev environment (dev.cannabrands.app) runs migrate:fresh --seed on every K8s deployment via init container. If seeders have bugs (e.g., undefined functions, missing relationships), the deployment fails and pods crash.

The Problem:

  • Tests run with APP_ENV=testing which skips DevSeeder
  • K8s runs with APP_ENV=development which runs DevSeeder
  • Seeder bugs passed CI but crashed in K8s

The Solution:

  • Add dedicated seeder validation step with APP_ENV=development
  • Runs the exact same command as K8s init container
  • Catches seeder errors before deployment

Time Cost: ~20-30 seconds added to CI pipeline

What It Catches:

  • Runtime errors (e.g., fake() outside factory context)
  • Database constraint violations
  • Missing relationships (foreign key errors)
  • Invalid enum values
  • Seeder syntax errors

Pre-Commit Checklist

Before committing:

  • Tests pass locally (./vendor/bin/sail artisan test)
  • Code formatted (./vendor/bin/pint runs automatically)
  • Commit message follows convention (feat:, fix:, etc.)

Before releasing:

  • All tests green in CI
  • Seeder validation passed in CI
  • Tested in dev/staging environment
  • Release notes written
  • CHANGELOG updated (auto-generated)

Before deploying:

  • Tag created and pushed
  • CI build successful
  • Team notified
  • Deployment window appropriate (not Friday night!)

Getting Help

Documentation

  • RELEASE_WORKFLOW_GUIDE.md - Detailed release process
  • VERSIONING_STRATEGY.md - CalVer strategy & rollback
  • GIT_BRANCHING_STRATEGY.md - Git workflow
  • CI_CD_STRATEGIES.md - Overall strategy

Team

  • Ask in #engineering Slack channel
  • Pair with senior dev for first release

CI/CD

  • Woodpecker: code.cannabrands.app/cannabrands/hub
  • Gitea: code.cannabrands.app/cannabrands/hub
  • K3s Dashboard: (ask devops for link)

Important URLs

Code Repository: https://code.cannabrands.app/cannabrands/hub

CI/CD Pipeline: https://code.cannabrands.app/cannabrands/hub/pipelines

Container Registry: https://code.cannabrands.app/-/packages/container/cannabrands%2Fhub

Documentation: .woodpecker/ directory in repository


Commit Message Cheat Sheet

# New feature
git commit -m "feat(scope): what you added"

# Bug fix
git commit -m "fix(scope): what you fixed"

# Documentation
git commit -m "docs: what you documented"

# Code cleanup
git commit -m "refactor(scope): what you refactored"

# Testing
git commit -m "test(scope): what you tested"

# Dependencies/config
git commit -m "chore: what you updated"

Scope examples: orders, invoices, auth, products, checkout

Full example:

git commit -m "feat(orders): add CSV bulk import

Allows sellers to import multiple orders from CSV file.
Includes validation and preview before import.

Closes #42"

One-Page Summary

Task Command
Daily commit git commit -m "feat(scope): description"
Create release git tag -a 2025.11.1 -m "notes"
Update changelog npm run changelog
Deploy kubectl set image deployment/cannabrands app=...:2025.11.1
Rollback kubectl set image deployment/cannabrands app=...:2025.11.0
Check version kubectl get deployment cannabrands -o jsonpath='{.spec.template.spec.containers[0].image}'
View builds Visit code.cannabrands.app/cannabrands/hub/pipelines

Key Principle: Commit often, release when ready, rollback without fear.

Version: 1.0 Last Updated: 2025-10-23 Print and keep handy!