I push a feature branch a dozen times a week. Every single time, the dance is the same: git push, switch to the browser, click the “Create MR” button, set assignee, set reviewer, add labels, wait for CI, click merge, switch back to terminal, git checkout main, git pull, git branch -d feature/.... It’s not hard. It’s just tedious — and the kind of friction that adds up over a week.

I had a shell script glued together with glab, gh, jq, yq, and gum doing this for years. It worked, but it broke whenever any of those tools updated and was a pain to ship to a fresh laptop. So I rewrote the whole thing in Go and called it auto-mr. One binary, no external CLIs, works on both GitLab and GitHub.

What it does

You’re on a feature branch with a clean working tree. You run auto-mr. The tool:

  1. Detects whether the remote is GitLab or GitHub
  2. Pushes the current branch
  3. Lets you pick labels interactively
  4. Opens the MR/PR with the right assignee and reviewer
  5. Waits for the CI pipeline to finish
  6. Auto-approves (GitLab only) and merges
  7. Switches back to main and deletes the local branch

That’s it. One command, no browser tab.

Why a Go rewrite

The original shell version had a hard dependency on five external tools — glab, gh, jq, yq, gum, plus git itself. Every fresh machine meant brew install five times. Every CI image meant five extra layers.

The Go rewrite replaces all of that with libraries:

WasNow
glabGitLab Go client
ghGitHub Go client
jqencoding/json
yqyaml.v3
gumsurvey
gitgo-git

One static binary. No PATH dance.

Installation

The project ships releases for the usual platforms, plus Homebrew and go install:

# Homebrew
brew tap sgaunet/homebrew-tools
brew install sgaunet/tools/auto-mr

# Go
go install github.com/sgaunet/auto-mr@latest

Configuration

A small YAML file at ~/.config/auto-mr/config.yml tells it who to assign and who to ask for review:

gitlab:
  assignee: your-gitlab-username
  reviewer: reviewer-gitlab-username
github:
  assignee: your-github-username
  reviewer: reviewer-github-username

And a token in your environment:

export GITLAB_TOKEN="..."
export GITHUB_TOKEN="..."

For GitLab, the token needs api, read_repository, write_repository. For GitHub, repo (and workflow if you have GitHub Actions).

Daily use

The whole point is brevity. From a feature branch:

auto-mr

If you want squashed commits on merge:

auto-mr --squash

That’s the entire surface area I use day to day. There’s also --log-level debug if something misbehaves.

What I didn’t expect

Two things surprised me after switching:

  • Pipeline waiting changed how I context-switch. Because the tool blocks until CI is green, I stopped opening four tabs and refreshing. I either wait (small change) or background it and go work on the next branch.
  • Interactive label selection actually gets used. With the browser flow I’d skip labels half the time. With a TUI prompt that takes one keystroke, I label everything. The repo’s filters and reports got way more useful.

Where to find it

If you bounce between GitLab and GitHub projects and you’re tired of the same six clicks every time you ship a branch, give it a try. It’s the first tool I install on any new machine.