Um momento
0x20Lesson 3 of 16

Trunk-based development and feature flags

Integrate continuously: keep branches short-lived, merge to main daily, and hide unfinished work behind feature flags.

26 min 7-question quiz 2 code exercises
By the end of this lesson you can
  • Explain why long-lived branches cause “merge hell” and slow delivery
  • Practice trunk-based development with small, short-lived branches
  • Use feature flags to separate deploying code from releasing features

At old Byte Bakery, each feature lived on its own branch for weeks. The “gluten-free menu” branch was 6 weeks old and 340 commits behind main when it was finally merged - which took three people two days, and broke checkout anyway.

Continuous integration originally meant a practice, not a tool: everyone integrates their work into the shared mainline at least daily, so conflicts are small and found early. Trunk-based development makes that the default:

  • Everyone commits to main (the trunk) directly or through short-lived branches that live hours, not weeks - ideally merged within a day.
  • main is always releasable. Every merge is built and tested, and a broken main is fixed (or the change reverted) immediately.
  • Bigger work is split into small, safe steps - and unfinished features are hidden behind feature flags.

Feature flags: deploy is not release

A feature flag (feature toggle) is a runtime switch around new code. The sourdough subscription feature can be merged and deployed every day while switched off for customers, then switched on for staff, then 5% of customers, then everyone - with no deploy. If it misbehaves, switching it off is the fastest rollback there is.

Flags come in kinds: release flags (temporary, for rollouts), experiment flags (A/B tests), ops flags (kill switches for expensive features), and permission flags (premium features). Percentage rollouts must be sticky: hash the user ID, so each user consistently sees the same thing.

flags.py
1import zlib
2
3def is_enabled(flag, user, percent):
4    bucket = zlib.crc32(f"{flag}:{user}".encode()) % 100
5    return bucket < percent
6
7for user in ["ana", "gus", "bo"]:
8    print(user, [is_enabled("sourdough-subscriptions", user, percent) for percent in (10, 50, 100)])
Output
ana [True, True, True]
gus [False, True, True]
bo [False, False, True]

As the percentage grows, users only ever move from off to on: ana’s bucket is 9, gus’s is 33 and bo’s is 74, and those never change. (zlib.crc32 is used because Python’s built-in hash() of a string changes every time the program starts.)

Key takeaways

  • Integrate into main at least daily; long-lived branches create painful merges.

  • Keep main always releasable, and fix or revert a broken build immediately.

  • Feature flags separate deploying code from releasing it - and make rollback instant.

  • Use sticky, hash-based percentage rollouts, and remove flags when done.

Lesson quiz

7 questions · pass with 5 correct · up to 50 XP

Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.

Practice: automate DevOps chores in Python

Write the small Python tools DevOps teams really build - pipeline runners, plan checkers, metric calculators, scanners - and run them against sample inputs. They run locally in your browser; no servers or cloud accounts needed.

Exercise 1

Branch health report

+25 XP

The first input line is today’s day number. Each following line is a branch: name created_day last_commit_day commits_behind_main. Give each branch a verdict, checking in this order:

  • stale: delete or revive if there has been no commit for more than 3 days;
  • too long-lived: merge behind a flag if it is more than 2 days old;
  • rebase soon if it is more than 20 commits behind main;
  • otherwise healthy.

Print branches oldest first (ties alphabetically) as gluten-free-menu (age 42): stale: delete or revive, then healthy: 2 of 5 branches.

  • Byte Bakery branches
main.py
Loading editor…

Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.

Exercise 2

Evaluate feature flags

+25 XP

The input has flags, ---, then checks. A flag line is name on|off percent optionally followed by allow:user1,user2. A check line is user flag.

Evaluate each check in this order and print the result with its reason:

  • unknown flag: ana dark-mode: off (unknown flag)
  • flag switched off (kill switch): off (flag disabled)
  • user on the allowlist: on (allowlist)
  • otherwise compute bucket = zlib.crc32(f"{flag}:{user}".encode()) % 100: on (bucket 12 < 25) or off (bucket 80 >= 25).
  • Sourdough rollout
main.py
Loading editor…

Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.

Questions about this lesson

Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.

Loading posts…

Gostou da aula? 😆👍
Apoie nosso trabalho com uma doação: