Skip to content

Part 6: Branch Deployments

Deploy a feature branch alongside your main deployment for testing and review, then promote or clean up.

What you'll learn

  • Building and deploying from a feature branch
  • Accessing branch-specific URLs side-by-side with the main deployment
  • Setting branch-scoped environment variables
  • Cleaning up branch deployments

What you'll need

  • The full-stack app from Part 5 deployed and working on the main branch

Create a feature branch

You will add a labels field to todos. Create the branch and make the changes locally:

git checkout -b feature/labels

Add a migration for labels

cd backend
npx knex migrate:make add_labels_to_todos

Edit the new migration file:

exports.up = function (knex) {
  return knex.schema.alterTable("todos", (table) => {
    table.specificType("labels", "text[]").defaultTo("{}");
  });
};

exports.down = function (knex) {
  return knex.schema.alterTable("todos", (table) => {
    table.dropColumn("labels");
  });
};

Update the API routes

In backend/index.js, update the POST and PUT handlers to accept labels:

app.post("/api/todos", async (req, res) => {
  const [todo] = await knex("todos")
    .insert({ title: req.body.title, labels: req.body.labels || [] })
    .returning("*");
  await todoQueue.add("new-todo", { todoId: todo.id, title: todo.title });
  res.status(201).json(todo);
});

app.put("/api/todos/:id", async (req, res) => {
  const updates = { title: req.body.title, done: req.body.done };
  if (req.body.labels !== undefined) updates.labels = req.body.labels;
  const [todo] = await knex("todos")
    .where({ id: req.params.id })
    .update(updates)
    .returning("*");
  if (!todo) return res.sendStatus(404);
  res.json(todo);
});

Push the branch

git add -A && git commit -m "feat: add labels to todos"
git push -u origin feature/labels

Build and deploy the branch

Use -b to target the feature branch. A deploy is queued automatically after a successful build, so this one command does both:

mecca build trigger -g git@github.com:yourorg/todo-app.git -b feature/labels

Pass --no-deploy if you want to build only, then deploy separately:

mecca app deploy todo-app -b feature/labels

Branch 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. So the backend is at https://todo-app-feature-labels-backend-yourgroup.dev.example.com while main continues to run at https://todo-app-backend-yourgroup.dev.example.com.

Check branch deployment status

mecca queue status takes the action ID the build or deploy printed. To see everything in flight for the app, use mecca queue list:

mecca queue list -a todo-app
mecca queue status <action-id>
mecca app show todo-app          # lists the branches the app is registered on
mecca build list --app todo-app  # build history, with branch and tag

Set branch-scoped environment variables

mecca var set writes to every branch unless you narrow it with -b:

mecca var set todo-app PUBLIC_APP_TITLE="Todo App (Labels Preview)" -b feature/labels
mecca app deploy todo-app -b feature/labels --no-build

Branch isolation

Branch-scoped variables do not affect the main deployment. Each branch has its own environment variables — and its own, initially empty database, since the database name is derived per branch. Your migration runs against the branch's own schema and cannot break main. Drives and buckets are per-branch too.

Test the feature

# Create a todo with labels on the branch deployment
curl -X POST https://todo-app-feature-labels-backend-yourgroup.dev.example.com/api/todos \
  -H "Content-Type: application/json" \
  -d '{"title": "Review PR", "labels": ["urgent", "review"]}'

# Verify main deployment is unaffected
curl https://todo-app-backend-yourgroup.dev.example.com/api/todos

Promote to main

Once you are satisfied, merge the branch in Git and redeploy main:

git checkout main
git merge feature/labels
git push origin main

mecca build trigger -g git@github.com:yourorg/todo-app.git

Clean up the branch deployment

Undeploy the branch and optionally purge all its build artifacts:

# Undeploy (keeps images and build history)
mecca app undeploy todo-app -b feature/labels --force

# Full purge (removes images, builds, and registry data)
mecca app undeploy todo-app -b feature/labels --force --purge

Purge is permanent

The --purge flag deletes that branch's images from AppMecca's image registry along with its build records. You cannot roll back to a branch build after purging.

Typical branch workflow

The full cycle for a feature branch looks like this:

# 1. Build and deploy the branch
mecca build trigger -g git@github.com:yourorg/todo-app.git -b feature/labels

# 2. Iterate -- push new commits, rebuild (each rebuild redeploys)
mecca build trigger -g git@github.com:yourorg/todo-app.git -b feature/labels

# 3. Test and review at the branch URL

# 4. Merge to main in Git, rebuild main
mecca build trigger -g git@github.com:yourorg/todo-app.git

# 5. Clean up the branch deployment
mecca app undeploy todo-app -b feature/labels --force --purge

What's next

In Part 7: Internal Service Discovery, you will add an auth service and see how AppMecca services address each other.