Part 6: Branch Deployments¶
Deploy a feature branch alongside your main deployment for side-by-side testing.
What you'll learn¶
- Building and deploying from a feature branch
- Comparing branch deployments with the main deployment
- Setting branch-specific environment variables
- Promoting a branch build to main
- Cleaning up branch deployments
What you'll need¶
- A three-service app from Part 5: Background Workers
Step 1: Create a feature branch¶
Add a due_date field to the Todo model. Create the branch and make the changes:
Update backend/core/models.py:
from django.db import models
class Todo(models.Model):
title = models.CharField(max_length=255)
done = models.BooleanField(default=False)
due_date = models.DateField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created_at"]
def __str__(self):
return self.title
Update backend/core/serializers.py:
from rest_framework import serializers
from .models import Todo
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ["id", "title", "done", "due_date", "created_at"]
read_only_fields = ["id", "created_at"]
Update the frontend to show due dates. In frontend/src/App.jsx, add a date input to the form and display due dates in the list:
const [dueDate, setDueDate] = useState("");
// In the form:
<input
type="date"
value={dueDate}
onChange={(e) => setDueDate(e.target.value)}
/>
// In the POST body:
body: JSON.stringify({ title, due_date: dueDate || null })
// In the list item:
<span style={{ color: "#888", fontSize: "0.8em" }}>
{todo.due_date && ` (due: ${todo.due_date})`}
</span>
Commit and push:
Step 2: Build and deploy the branch¶
Build from the feature branch. A deploy is queued automatically after a successful build, so this one command does both:
Or build and deploy as separate steps:
mecca build trigger -e dev \
-g git@github.com:yourorg/todo-app.git \
-b feature/due-dates --no-deploy
mecca app deploy todo-app -b feature/due-dates -e dev
Separate URLs
Branch deployments get their own hostnames. The sanitised branch name is inserted between the app slug and the service name (/ becomes -), and main contributes no segment at all:
- Main:
https://todo-app-frontend-yourgroup.dev.yourdomain.com - Branch:
https://todo-app-feature-due-dates-frontend-yourgroup.dev.yourdomain.com
Step 3: Compare the deployments¶
mecca queue status takes the action ID each build or deploy printed — not an app name. To see everything currently in flight for the app, use mecca queue list:
mecca app show lists the branches the app is registered on:
Open both URLs in your browser. The main deployment has the original todo list. The branch deployment has the new due date field.
Step 4: Set branch-specific environment variables¶
mecca var set writes to every branch unless you narrow it. Pass -b to override a variable for the branch deployment only:
mecca var set todo-app PUBLIC_APP_TITLE="Todo App (Due Dates Preview)" \
-b feature/due-dates -e dev
Redeploy the branch to pick up the change:
The main deployment title remains unchanged.
Branch isolation
Every branch gets its own, initially empty database — the name is derived per branch, so main and feature/due-dates never share data. Your entrypoint's migrate step builds the schema on the branch's first deploy; no data is copied from main. Drives and buckets are per-branch too.
Step 5: Test the new feature¶
Create a todo with a due date on the branch deployment:
BRANCH_URL="https://todo-app-feature-due-dates-backend-yourgroup.dev.yourdomain.com"
curl -X POST "$BRANCH_URL/api/todos/" \
-H "Content-Type: application/json" \
-d '{"title": "Review PR", "due_date": "2026-03-15"}'
curl "$BRANCH_URL/api/todos/"
Verify the main deployment still works without the due_date field:
MAIN_URL="https://todo-app-backend-yourgroup.dev.yourdomain.com"
curl -X POST "$MAIN_URL/api/todos/" \
-H "Content-Type: application/json" \
-d '{"title": "Main branch todo"}'
Step 6: Promote and clean up¶
Once the feature is reviewed and merged to main:
Build and deploy from main:
Remove the branch deployment:
Purge option
Add --purge to also delete the branch's built images and build history. Without it, the registry data is preserved for future reference:
Workflow summary¶
| Step | Command |
|---|---|
| Build branch | mecca build trigger -g URL -b BRANCH -e dev |
| List in-flight actions | mecca queue list -a APP -e dev |
| Check one action | mecca queue status ACTION_ID -e dev |
| Set env vars (one branch) | mecca var set APP KEY=VALUE -b BRANCH -e dev |
| Undeploy branch | mecca app undeploy APP -b BRANCH --force -e dev |
| Purge branch data | mecca app undeploy APP -b BRANCH --force --purge -e dev |
What's next¶
Branch deployments communicate via public URLs. In Part 7: Internal Service Discovery, you will look at how services address each other inside AppMecca's private network.