Working with Monorepos

Monorepos add some additional complexity with setting up Screenshotbot.

In particular:

  • There could hundreds of individual build targets. We can solve this with batching.
  • If you use some kind of test-target selection, not all tests will run on each commit. We can solve this with unchanged runs.
  • Since there are multiple test targets, and the number of builds in each run can differ, Screenshotbot needs to be told when all the possible builds are complete. For this we use finalize commit.

For a monorepo you will have to implement each of the above three steps. Batching might be useful in context outside of monorepos to avoid PR noise.

Batching

Typically in a monorepo or large modular repository you might have multiple build targets each generating their own screenshots. We recommend keeping an independent channel per branch.

However, by default Screenshotbot will send one notification per channel on your GitHub Pull Requests. This might be noisy, so instead you might want to group all the changes under one single PR build status.

You can use batching for this. You can also create multiple batches.

For instance, if you have iOS and Android in the same monorepo, you can pass --batch ios for your iOS screenshots, and --batch android for your Android screenshots. This will batch all the iOS channels together, and all the Android channels together. More typically, all your screenshots will be under the same batch name, in which case pick an arbitrary short string and stick with it.

Unchanged runs

Most monorepos will not run all the tests on every commit. Instead, you might be using some mechanism to of target selection to run tests (e.g. Using Buck, Bazel or Gradle Predictive Test Selection). In this case, you will have to inform Screenshotbot when you ignore a specific test target.

You can do this by providing using the --mark-unchanged-from for each channel that wasn't run:

    ~/screenshotbot/recorder --channel //my/build:target \
         --batch batch-name \
         --mark-unchanged-from 28916047d2fc8e6e5c4670b56c6134791f5dff17

Note that we need the full commit hash. This must also be run inside of the Git repository during the CI build.

Depending on your CI logic the commit hash you provide might not be the parent hash, it could be any arbitrary commit in your repository.

It is legal to have a chain of such markings. For instance you can mark commit foo to be unchanged from bar, and bar to be unchanged form car. Any time we need to lookup screenshots for foo, we'll automatically use the screenshots from car instead.

Finalize commit

Once all your builds for a specific commit are done, we recommend you invoke the following command from a CI step from within the Git repository:

      ~/screenshotbot/recorder --finalize-commit

You must run this even if the previous build steps failed.

This step will tell Screenshotbot not to expect any more screenshots on any more channels for this commit. This step is optional, but we highly recommend it. If you skip this step developers might see a message such as "Waiting for abcd commit" on their PR in situations where we could've determined that no such runs would appear.

It is safe to re-run the job, Screenshotbot will detect that more runs are coming in and wait for another --finalize-commit.

Sample project

See tdrhq/monorepo-example for a simple project that mimics a monorepo. In particular, the run-all-tests.sh file mimics test selection, and uses each of the above features.

Ready to get started?

Sign up or contact us.