XavierFok
← all posts

How I Version And Roll Back My Automation Configs

2026-07-29 · by Xavier Fok

The afternoon I broke my own pipeline

A few months ago I changed one line in a workflow config to fix a formatting issue, and it quietly broke three other automations that depended on the same shared node. I didn't notice until the next morning when a scheduled render came back empty. I had no record of what the config looked like before the edit, so I spent close to an hour rebuilding it from memory instead of just reverting a change.

That's the moment I started treating my automation configs the same way I treat code: with version control, small commits, and a clear way to go back to the last known-good state. This isn't a groundbreaking idea. It's just something a lot of people running agents, MCP servers, and workflow tools skip because the configs feel like settings, not software. They aren't settings. They're logic. And logic needs a history.

What actually counts as a config in my setup

When I say "automation configs," I mean the specific files that define behavior in the tools I run daily:

Each of these is a text file, or exports cleanly to one. That's the whole reason version control works here. If a tool only lets you edit configuration through a GUI with no export option, that's a real limitation, and I flag it as a risk before I build anything serious on top of it.

Why I stopped editing configs in place

Editing a live config directly is fine right up until it isn't. The failure mode isn't usually a dramatic crash. It's a subtle behavior change that doesn't show up until the automation runs on a schedule, hours later, with nobody watching. By the time I notice, the "before" version is gone unless I saved it somewhere.

Putting configs in a git repo solves this in a boring, reliable way: every change is a commit, every commit has a diff, and every diff tells me exactly what changed and when. I don't need to remember what I did. I can just read it.

The workflow I actually use

Here's the process, stripped down to what matters:

Every config lives in a repo. Workflow exports, agent prompts, MCP configs, all of it, in folders organized by tool or project. Nothing gets edited outside the repo and then copied in after the fact. The repo is the source of truth, not the live tool.

One change, one commit. If I'm adjusting a prompt and also tweaking a schedule, that's two commits, not one. This matters more than it sounds like it should. When something breaks later, a commit that only touches one thing is trivial to evaluate. A commit that touches five things forces me to re-derive what actually caused the problem.

Commit messages describe the why, not the what. The diff already shows what changed. What it doesn't show is why I changed the temperature from 0.3 to 0.5, or why I removed a tool from an MCP server's exposed list. I write that down in the message. Six weeks later, that context is the difference between a two-minute fix and a full re-investigation.

I tag stable points. Before I make a change I'm unsure about, I tag the current state. Not every commit needs a tag, but any point where things are working well and I'm about to do something riskier gets one. That tag is my fallback if the next few commits go sideways.

I test before I let a schedule pick it up. Most of my automations run on triggers, not on demand. If I push a config change and walk away, I won't know it's broken until the trigger fires. So I run it manually first, watch the output, and only then let it go back on autopilot.

How rollback actually works

Rollback isn't complicated once the versioning habit is in place. It's usually one of two things:

Revert to the last commit. If a change breaks something and I catch it fast, I just go back one step. This is the common case and it takes seconds.

Revert to a tagged stable point. If I've been making a string of changes and something further back is the actual source of the problem, I go back to the last tag I know was solid, then reapply only the changes I still want, one at a time. This is slower, but it's still faster than rebuilding from scratch, and it's a lot more reliable than trying to remember which of five recent edits was the culprit.

The part that makes this fast in practice is that the "config" and the "running instance" are two different things. Reverting the file in the repo doesn't do anything on its own. I have to redeploy or re-import the reverted config into the actual tool. That step is manual for me right now. It's the one piece of this whole process I'd like to automate further, but I haven't built that yet, and I'd rather say that plainly than pretend the pipeline is more automatic than it is.

Secrets don't go in the repo

API keys, tokens, and credentials never go into the same files as the logic. I keep those in the automation platform's own credential store or in environment variables outside the repo, and reference them by name inside the config. This isn't just good hygiene, it's what makes the repo safe to actually use as a working history. If secrets were mixed into every config file, I'd either have to scrub them before every commit or accept the risk of them sitting in commit history forever. Neither is worth it. Separating logic from credentials is the one rule in this whole setup I don't bend, even when it's less convenient in the moment.

Environment differences get their own layer

I run some automations locally and some against cloud services, and the same base workflow sometimes needs different paths, different endpoints, or different rate limits depending on where it's running. Rather than keeping separate full copies of every config, I keep the core logic in one version-controlled file and layer environment-specific values on top through variables the platform resolves at run time. That way a fix to the underlying logic doesn't need to be copy-pasted into three near-duplicate files that will inevitably drift apart.

What this doesn't solve

Version control gives me a history and a way back. It doesn't catch a bad idea before I ship it, and it doesn't replace actually testing a change. I've reverted plenty of commits that were technically working exactly as written, just wrong in what they were trying to do. Git tells me what changed. It doesn't tell me what should have changed instead. That part is still on me, every time.

It also doesn't make the tools smarter than they are. An agent with a well-versioned prompt is still an agent that can misread a tool result or take an action I didn't intend. Versioning configs reduces how long a mistake stays live and how hard it is to undo. It doesn't reduce the odds that a mistake happens in the first place.

Where to start if you have none of this

If your automation configs currently live only inside whatever tool built them, the first step is just getting them into text files somewhere you control, even before you touch git. From there, committing changes as you make them is a small habit that pays for itself the first time something breaks. You don't need a complex branching strategy or a CI pipeline. You need a history you can read and a way to step back to the last point that worked.

If you want to see how I actually structure these repos and wire them into the tools I use day to day, more of that is on the channel and the site.

Check out more breakdowns like this at [xavierfok.com](/).

Get new guides and videos first — join the Telegram channel.