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 featurefix:- Bug fixdocs:- Documentation onlystyle:- Code style (formatting)refactor:- Code refactoringtest:- Adding testschore:- 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= Year11= 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.3andstable - 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:
- PHP Lint - Syntax validation
- Code Style (Pint) - Formatting check
- Tests - PHPUnit/Pest tests with
APP_ENV=testing - Seeder Validation - Validates seeders with
APP_ENV=development - Docker Build - Creates container image
- 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=testingwhich skips DevSeeder - K8s runs with
APP_ENV=developmentwhich 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/pintruns 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 processVERSIONING_STRATEGY.md- CalVer strategy & rollbackGIT_BRANCHING_STRATEGY.md- Git workflowCI_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!