I work on a large engineering team. The main Slack channel for our engineering department has 425 people in it. The code base is split into many repositories, dominated by a big Ruby on Rails application with many contributors. At the time of writing, the last 1,000 commits in
master on that repository where made by 169 contributors.
The continuous integration for said mono-repo is heavily parallelized but still takes ~30 minutes to complete. Occasionally, a branch is merged that causes the build to fail. Usually, the case is that the specs worked correctly for that branch (otherwise we can’t merge), but new changes in
master are not compatible. As hard as the team tries to maintain a green build (i.e. a build that passes and is deployable), a red build is somewhat frequent.
Branching-off for new work from a commit that is not green guarantees that, later down the line, your branches build will fail, even if your code is nowhere near the failures. The solution is to merge master (hopefully green this by now!), and wait for new builds.
I developed some scar tissue around this. I noticed that I started opening Circle CI, finding the last green build for the project’s workflow, copying the commit hash, and branching-off of that for my work. The results were very positive: I haven’t seen failures in one of my branches that are not related to my work since. The process is a bit tedious, though.
Automation to the rescue. Circle CI has an API, but it seems it is suitable to work around builds, while I was interested in whole workflows. However, Circle CI posts it’s builds results to GitHub, along with some of the other integrations we use. Github’s GraphQL API lets me include the
state of the last few commits on
master and find the last one that was successful.
Let’s see the commented code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
I named it
git-last-green-commit and put it in my path, which makes it available for invoking on any project that has a GitHub remote:
Since it’s output is just the commit hash, it can be chained like so:
Or what I must commonly use:
1 2 3 4 5
Now my local master points to a green build, which I can use to branch-off, rebase, etc.