How to automate the build of bottles on your tap =============================================== This tutorial is a follow-up to the discussion we had on https://github.com/davidchall/homebrew-hep/pull/114. It relies on the `test-bot` provided by davidchall; you can get it with `brew tap davidchall/test-bot`. ## Use Travis CI to test and bottle your formulae The idea is to use _staged build_ in Travis CI, where the two stages will be 1) the **testing stage** where the bottles are built and tested for the different architectures with brew test-bot At the end of this stage, each job must upload its bottle.tar.gz and bottle.json to somewhere (e.g., free AWS S3 bucket). 2) the **deploy stage** (only on master) where we fetch the bottle.json and bottle.tar.gz, upload the bottle.tar.gz to Bintray and merge the multiple `bottle.json` into a commit that contains the bottle DSL with the command brew test-bot --ci-upload ![Screenshot of the staged build status on Travis CI](https://user-images.githubusercontent.com/2195781/32568431-83a25464-c4be-11e7-8c9f-31202d07fd79.png) You can see a detailed example of such a configuration in the [`.travis.yml`][#file-travis-yml] of this gist, where bottles are built for linux, sierra and el\_capitan. You can also see an example of tap, [touist/homebrew-touist](https://github.com/touist/homebrew-touist), that uses it and its [`.travis.yml`](https://github.com/touist/homebrew-touist/blob/master/.travis.yml). ### Drawbacks w.r.t. bottles when maintaining a tap relying on core formulae On the homebrew-core repo, whenever a formula on which some other formulae are relying on is updated, we also must rebuild the bottles of these dependent formulae (this is why we have the revision number `_1` after the actual version number). This seems to be automatically taken care of on the homebrew-core tap. On your own tap, this revision bump whenever a dependency bottle gets rebuilt can lead to broken bottles. This problem has not been solved yet, but: 1) may be we could rely on a cron job that tests the bottles every week to check if the bottle still works; 2) or we could subscribe to the changes on the formulae we depend on and run a script on a Travis CI build Both solutions require a lot a thoughts, that is why I did not do anything about it. I only rely on `gmp` at runtime so maybe it is fine... Note that this problem has been also descussed [here](https://github.com/Homebrew/brew/issues/2572#issuecomment-298725510) and [here](https://github.com/Homebrew/brew/issues/3346). ### What you need 1) the name of the Github repo for your tap must be `/homebrew-` 2) you need a Github OAuth2 token that you can get in your Github settings   (secret variable `GITHUB_TOKEN` in `.travis.yml`); 2) the name of the Bintray repo must be `/bottles-`   (secret variable `HOMEBREW_BINTRAY_KEY` in `.travis.yml`); 3) you also need an AWS S3 bucket, it is free and takes 1 minute to create; then you need to create a token+password and set them as secret variables in   the travis-ci settings (secret variables `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` in `.travis.yml`). ### Tricks I want to remember when I was setting up Travis CI + test-bot 1) when using `brew test-bot`, **never use** `--ci-pr`, `--ci-master`, `--ci-testing` on your mac as it is going to remove everything installed. You can still use `brew test-bot` and `brew test-bot --ci-upload`; what I would do is to make sure everything runs correctly locally (except for `brew doctor` which generally always fails on my mac) using: brew test-bot Formula/touist.rb 2) On Travis CI, mac builds are costly (in time). For trying to make the   `.travis.yml` work, I really recommend to use `os: linux` instead of a mac image. 3) Also, when you find yourself stuck when trying to make the CI work, I recommend to re-run your job in [debug mode](https://docs.travis-ci.com/user/running-build-in-debug-mode/) in order to see what is going wrong. Again, as mac images are slow, I recommend to use the linux alternative. 4) if you see that `brew test-bot` is not building/testing any bottle, check   that you have made the symlink (in travis-ci) at `$(brew --repo touist/touist)`   that should target `$TRAVIS_BUILD_DIR`. It is important because `brew test-bot`   is testing the tap inside `$(brew --repo)` but the actual repo cloned by travis is in `$TRAVIS_BUILD_DIR`. 5) the `--keep-old` option when uploading seems to be a good idea (= keeps bottles you previously built but that you don't produce anymore) but it keeps failing on stupid errors all the time; I don't use it anymore. 6) when you try to make a formula work (on master) and you want to rebuid the bottle of the formula, just edit somewhere in the formula and push. This is going to increment "rebuild 1" in the bottle DSL and reupload the bottles. 7) same thing on a PR or a branch: to make the formula rebuild, the push has to only contain edits on a Formula/formula.rb file 8) adding "revision 1" to a formula does not seem to be appropriate for forcing a bottle to be rebuil 9) the tests/building of the bottle only happens when you push a series of commit on ONE single formula; if you include some edits to .travis.yml for example, the push won't trigger build of the bottle. This caused me a lot of time lost on try and errors. 9) when creating a new formula, you may get these kind of errors during the build (on PR, branch and master):   - New formulae should not require patches to build. Patches should be submitted and accepted upstream first. - GitHub fork (not canonical repository) - GitHub repository too new (<30 days old)   First, make sure the bottles build without errors and that the only step failing is `brew audit --online`. Then, accept the PR and make a small change to the formula to force the rebuild of the bottle. The errors will disappear (as they are only there when the formula is new).