Badonde is a command line tool that combines Git, GitHub, and JIRA, offering as a solution for GitHub projects to define an automatic PR creation workflow.




brew install davdroman/tap/badonde


git clone
cd Badonde
make install



First, in a terminal window, you want to navigate to your repo root and run:

$ badonde init

This will create all the required files for Badonde to work and prompt for GitHub and JIRA credentials.

Observe the .badonde folder is created to host Badonde's local user configuration (e.g. credentials). Such folder is also added to .gitignore because per-user configuration must not be commited.


Additionally, a Badondefile.swift file is created with a basic template.

Badondefile defines the rules by which Badonde derives data and outputs PR information, all through declarative Swift syntax.

In order to edit Badondefile with full autocompletion support, run:

$ badonde edit

This will open an Xcode project where you can make any modifications to this file. When you're done, go back to the terminal and press the return key to save the file.

Consider a scenario where you want to generate a PR from a local branch named fix/IOS-1234-fix-all-the-things where IOS-1234 is a JIRA ticket id. Here's an example of a Badondefile that would generate a PR automatically adding things like a standarised PR title and a Bug label for bugfix branches:

import BadondeKit

// Reads the current Git context and derives a JIRA ticket number from the
// current branch's name.
let badonde = Badonde(ticketType: .jira(derivationStrategy: .regex))

// If a ticket was successfully derived and fetched, its info is available
// through the `badonde.jira` property.
if let ticket = badonde.jira?.ticket {
    // Sets the PR title to something like:
    // [IOS-1234] Fix all the things
    title("[\(ticket.key)] \(ticket.fields.summary)")

// If the current branch has the prefix 'fix/' it means we're dealing with a
// bugfix PR, so we attach the Bug label.
if"fix/") {
    // Sets the "Bug" label defined in your GitHub repo.
    label(named: "Bug")

Here's a more advanced (but just as easily expressed) case of an automation where we match the JIRA ticket's epic to a label in your GitHub repo:

if let epicName = ticket.fields.epicSummary {
    label(roughlyNamed: epicName)
} else {
    label(named: "BAU")

By default, Badonde generates draft PRs. To disable this, simply add this to your Badondefile:


Here's a list of supported PR properties:

  • base branch
  • title
  • body
  • reviewers
  • assignees
  • labels
  • milestone
  • draft

Generating a PR

Finally, when you're ready to generate a PR, run:

$ badonde pr

Or perform a dry run first to see what the output would be:

$ badonde pr --dry-run


As said above, Badonde stores its local user configuration in .badonde/config.json.

Badonde offers an interface similar to git config to modify this options. For instance:

$ badonde config git.remote origin

Global options are also available (and stored in ~/.config/badonde/config.json):

$ badonde config --global git.autopush true

To list all available options, run:

$ badonde config --help


It's possible to report useful team-wide performance analytics to your own privately owned Firebase DB after each Badonde execution.

In order to do this, each team member should configure the required credentials as such:

$ badonde config firebase.projectId <YOUR_FIREBASE_DB_PROJECT_ID>
$ badonde config firebase.secretToken <YOUR_FIREBASE_DB_SECRET_TOKEN>

You can add custom information to the report through your Badondefile:

    "labelCount": badonde.pullRequest.labels.count,
    "hasMilestone": badonde.pullRequest.milestone != nil