Bara

A resilient git commit automation tool with BullMQ workers, multi-round retry, and non-fast-forward recovery — built to keep contribution graphs green without manual intervention.

Next.jsExpressTypeScriptPostgreSQLRedisBullMQDocker Compose

The Problem

Maintaining consistent commit activity across multiple repositories is tedious. Missed days break streaks, and manually scheduling commits across branches with different states is error-prone. I needed a system that could autonomously manage git operations — including handling the edge cases that break naive automation tools.

The Solution

I built Bara as a full-stack automation platform with a Next.js frontend for configuration and an Express backend orchestrating BullMQ workers backed by Redis.

Key technical decisions:

  • BullMQ/Redis worker architecture — Each repository gets its own worker queue with configurable concurrency. Workers handle the full git lifecycle: clone, stage, commit, push.
  • Multi-round auto-retry — Failed pushes trigger up to 3 retry rounds with exponential backoff. Each round re-evaluates the repository state before attempting again.
  • Per-branch Redis locking — Distributed locks prevent concurrent operations on the same branch, eliminating race conditions when multiple jobs target the same repo.
  • Batch scheduling with time-staggering — Commits are naturally distributed throughout the day with configurable jitter, making the activity pattern look organic rather than automated.

What Went Wrong

The first major failure was non-fast-forward rejections. After a manual rebase on a target branch, the stored commit SHAs in the database became stale. The worker would try to push, get rejected, retry with the same stale state, and eventually exhaust all retries.

The fix: I designed a non-fast-forward recovery system. When a push fails with a non-fast-forward error, the worker automatically rebases the local branch onto the remote HEAD, remaps all affected commit SHAs in the PostgreSQL database, and retries the push. This required careful handling of the SHA mapping — every reference to the old commits had to be updated atomically to avoid orphaned records.

I also added cascade failure detection: if a rebase itself fails (merge conflicts), the system stops retrying and sends a Gmail SMTP notification with the conflict details instead of silently failing.

Results

  • Zero manual intervention for routine operations including post-rebase recovery
  • Handles non-fast-forward pushes automatically with SHA remapping
  • Threaded Gmail notifications for failures requiring human attention
  • Optional commit date rewriting for flexible scheduling

Interested in working together?

Let's Talk