================== Introducing Tarmac ================== Merging branches is boring. Really, it is. After humans have looked over a merge, it should really just magically be merged. That's what Tarmac does, and it does it well. How it works ============ Tarmac uses Launchpad to manage merging branches. It does this by checking over all the branches configured to have Tarmac manage them for merge proposals that are approved and have commit messages set. It then merges those branches, one by one, and automatically commits them. What's more, Tarmac supports plugins that can prevent a branch from landing if it doesn't meet specific requirements, or perform specific tasks after the branch has landed. This opens up all sorts of branch landing options that can happen behind the scenes, while you can safely do more exciting work. Prerequisite Branches ===================== Tarmac understands the launchpad concept of prerequisite branches. The following conditions are supported when evaluating a candidate merge proposal (MP). * Prerequisite branch without an associated MP => error * Prerequisite branch with multiple non-superseded MPs => error * Prerequisite branch with exactly one non-superseded unmerged MP => skip * Prerequisite branch with exactly one non-superseded *Merged* MP => proceed Additionally, the tarmac queue is processed taking into account prerequisite branches. That is, dependent branches are processed *after* their prerequisites. Configuration ============= Tarmac gets it's configuration data from ``~/.config/tarmac/tarmac.conf`` -- The configuration is split up by projects. As an example, a fictional `phoo` project will be used. The config file starts with items that apply to the Tarmac command. Add to the following to the config file, creating it if it doesn't exist already).:: [Tarmac] # Configuration for the Tarmac command. This doesn't mean much by itself. Optionally, we can also specify where to write the log (by default, it logs to ~/tarmac.log). A basic log file setting would look like this:: [Tarmac] log_file = /var/log/tarmac.log If placing the file in ``/var/log`` be sure the user running ``tarmac`` has write permission to that file. Now let's provide some branches for Tarmac to manage. How about phoo's development focus first? Specifying this is REALLY easy. Now my config file will look like this:: [Tarmac] log_file = /var/log/tarmac.log [lp:phoo] That's it! I specify the branch by it's lp: name, and Tarmac knows that when it's instructed to land branches, it should check up on lp:phoo for approved merge proposals. However, this means that Tarmac has to make a new tree of lp:phoo every time it makes a landing run. This is rather inefficient. We can actually have Tarmac cache a tree, and just update it on every run. This path to the cache tree can be specified by changing the config file to look like this:: [Tarmac] log_file = /var/log/tarmac.log [lp:phoo] tree_dir = /var/cache/tarmac/phoo/trunk If this directory or tree doesn't exist, Tarmac will go ahead and create it. Running Tarmac ============== Once Tarmac is all configured, simply run ``tarmac merge``. Voila! If there are issues at all, you can run ``tarmac merge --debug`` to get more debug information. ============== Tarmac on Cron ============== Tarmac runs best on a cron job, because it's doing stuff you shouldn't even need to worry about. To make Tarmac run on a cron, add this to your crontab:: 0 * * * * tarmac merge This will run Tarmac every hour, and merge branches if needed, and just quickly shut down if not needed. Depending on the velocity of your project and what things Tarmac is doing when it merges (are your tests taking FOREVER?), you'll want to tune this to work best for your project. If the above cron does not work for you, try giving the full path to tarmac:: 0 * * * * /usr/local/bin/tarmac merge ========================== Authenticating with Tarmac ========================== If you ever feel the need to manually authenticate Tarmac, you can run:: tarmac authenticate Follow the prompts and you'll be ready to go. Tarmac creates an authorization token in $HOME/.config/tarmac/credentials. If this file is ever corrupted, you can just remove it and run the authentication again. ================ Built-in Plugins ================ Tarmac ships with a few built-in plugins available. They can be enabled by setting some config options on the branch's config. The following are the plugins available, and the config options required to set it properly. Commit Message Formatter ======================== The Commit Message Formatter allows a user to specify a template for how a commit message should appear. In order to use it, you must set the ``commit_message_template`` config option on the branch, like so:: [lp:tarmac] commit_message_template = by review by The formatter can take a few different items available and re-format the commit message. Among those items are the following: **approved_by** Display name of reviewers who approved the review, comma-separated. **approved_by_nicks** Short names of reviewers who approved the review, comma-separated. **author** The display name of the source branch author. **author_nick** The short name of the source branch author. **bugs_fixed** Comma-separated list of the bug numbers fixed in the source branch. **commit_message** This is the commit message that is set on the merge proposal itself. **reviewer** The display name of the merge proposal reviewer. Command ======= The Command plugin exports the merged tree result to a temporary location, and runs a command on the tree in that new location, removing it when done. If the command fails, then it raises an exception that causes the merge to be abandoned, a comment on the merge proposal to be added, and the merge proposal set to "Needs Review" (so that Tarmac doesn't try to merge it in the next run). This command can be a script that runs tests, verifies certain files aren't changed, a script that verifies a proper build, etc. In order to use the Command plugin, your branch must have a ``verify_command`` option in the config, like so:: [lp:tarmac] verify_command = python setup.py test In this example, we're using Tarmac's distutils script to run our tests. If the tests fail, then the branch won't be merged, ensuring a pristine trunk. **Important note:** When running commands like this, one must stop and think about the potential of merging in questionable code that may be executed by your command. This means that a malicious user could execute code on the tarmac machine that could read files on your system. This is generally bad. Okay, well, more than generally, it's quite specifically bad. What the instance specifically does is use ``schroot`` to run the command inside a chrooted jail. It is configured to provide the tree in a neutral place in the chroot. The chroot is configured in /etc/schroot/schroot.conf as "tarmac-jail" and is run in the schroot with ``schroot -c tarmac-jail ``. By default the branch failing the verify_command is set back to the 'Needs review' status. If you want it to be set back to another status (like 'Work in progress'), you can use the 'rejected_branch_status' parameter in the global configuration: [Tarmac] rejected_branch_status = Work in progress CIA.vc Notifier =============== The CIA.vc Notifier (see ``http://cia.vc``) can be configured to notify the CIA.vc service of successful merges. Tarmac has already been configured to work with the CIA.vc service and is set up to notify those in the #tarmac IRC channel on Freenode. This configuration looks like this:: [lp:tarmac] cia_project = tarmac cia_server = http://cia.vc Voting Policy ============= This enforces a simple voting policy for branches. For example, to only land branches that have 2 Approve votes and no Disapprove votes:: [lp:tarmac] voting_criteria = Approve >= 2, Disapprove == 0 Add as many criteria as you need, comma or semi-colon separated. All criteria have to pass. Recipe Builder ============== The Recipe Builder plug-in can be configured to trigger the building of a Source Package Recipe on Launchpad, after all proposals for a target branch have finished merging into the tree. There are two configuration options required to use the plug-in: [lp:target_branch] package_recipe = / recipe_series = [,[,...]] This will trigger the recipe owned by to build into the 's Daily Build Archive, as specified in the Launchpad configuration for the Recipe, for the specified relase series of the Ubuntu distribution. The [recipe_series] option accepts a comma- separated list of Ubuntu distribution series names or versions. Bug Resolver ============ The Bug Resolver plug-in will automatically mark bugs as 'Fix Committed' on Launchpad, when the bug is tagged in the proposed branch using the '--fixes' option to the 'bzr commit' command, upon the branch being successfully merged and committed into its target. You can specify that your branch fixes a bug by committing to it with the following command, replacing '000000' with the bug number your commit fixes: bzr commit --fixes=lp:000000 ======================== Installing other plugins ======================== Tarmac's plugin system is very clever, because it's based on Bazaar's plugin system. In order to install extra plugins, place them ``$HOME/.config/tarmac/plugins``. They will then be available for import in python at tarmac.plugins. Getting Help ============ If you ever get stuck with Tarmac, you can easily find help by running:: tarmac help