How to Change Jira States Automatically


It is a usual struggle between R&D leads and developers. R&D leads need to have correct timestamps in tickets, in order to be able to calculate vital information like cycle times.

This requires people click buttons in jira whenever they start working on a ticket. This rarely happens.

Most developers do not care about JIRA because it is mostly useless burden for them.

You can not blame developers for that. Also you can not fix this problem by nagging people all the time. Yet, you need correct data. No, that data is not “work logging”. Work logging is useless

This is a problem that needs to be solved automatically.


What does a developer typically do nowadays to start working on a new ticket ?

  • Saves existing changes to stash or commits them
  • Pulls latest changes from origin
  • Checks out what ticket needs to be done
  • Creates a local branch to work on that ticket
  • Starts working

This is a pretty much standard and reasonable flow.

What if we automate this flow, while implicitly doing the boring Jira work ?

This is easily possible with the help of awesome Jira client go-jira by Netflix-Skunkworks

This is a Jira command line client written in Go. It allows you to use pretty much every part of the JIRA Rest API. Since it is a static Go binary, you don’t have to mess with tons of dependencies and their package managers like in some other languages and you don’t have to be careful for not to break any dependency. Installation is just copying a single binary.

But more importantly, this tool allows you to write your own custom commands with arbitary parameters and options together with help. When invoked with -h, tool will display your custom commands as well. Great !

Now what if we have a custom command that does following:

  • Check if ticket exists
  • Check if workspace exists and ready to create a branch (no uncommitted changes)
  • Assigns ticket to yourself
  • Takes ticket to In-Progress
  • Creates a local branch with a proper name

See it in action:

No need to bother people ! No need for micromanagement !

Following is the custom command begin I have been playing.

project: TP
user: berk

  - name: begin
    help: start working on a new ticket
      - name: workspace
        short: w
        required: true
      - name: branch
        short: b
        default: "master"
      - name: JIRA_ID
        required: true
    script: |-
      if ! {{jira}} view {{args.JIRA_ID}};then
        echo "{{args.JIRA_ID}} does not exist"
        exit 1

      if [ ! -d {{options.workspace}} ];then
        echo "{{options.workspace}} does not exist"
        exit 1

      cd {{options.workspace}}

      if ! git rev-parse --is-inside-work-tree; then
        echo "`pwd` does not look like a git repository"
        exit 1

      if ! git diff-index --quiet HEAD --; then
        echo "You have unstaged changes. Please commit them before checking out for a new ticket"
        exit 1

      echo "Assigning ticket to {{env.USER}} anyway"
      {{jira}} assign {{args.JIRA_ID}} {{env.USER}}

      BRANCH=$({{jira}} view  {{args.JIRA_ID}}|grep "summary"|awk -F\: {'print $2'}|tr -s " " _)
      echo "Local branch will be ${BRANCH}"

      git checkout -b {{args.JIRA_ID}}_${BRANCH} {{options.branch}}

      echo "Possible transitions for the ticket"
      {{jira}} transitions {{args.JIRA_ID}}

      echo "Changing to In-Progress"
      {{jira}} in-progress --noedit {{args.JIRA_ID}}

      {{jira}} view {{args.JIRA_ID}}      

In the example I entered password multiple times, but that was against a demo jira setup. The client normally caches the session locally.

One final step is resolving this ticket. It really depends on your own workflow. One approach is to resolve the ticket if it contains a certain keyword ONLY WHEN it is merged to the branch.

Why don’t we immediately close the ticket ? Because it is quite common to make small checkins in order to keep changes in small, easily reviewable chunks. In that case, we would want to resolve the ticket when the last chunk is merged.

This solution assumes you start working by telling it Jira first. There are other ways as well. You can write a post-checkout hook for Git in a way that it parses your branch name and if that contains a Jira id, calls your custom Jira command to manage states.

As a complementary step, you can install a hook on your code review system that would reject the patch if the ticket is not in in-progress state. This would not recover the time lost while creating the patch but at least it would prevent it from passing through the builds without a proper ticket state.

The advantage of this kind of approach over IDE plugins is that, this approach is completely and easily customizable for your own needs and it would work for everyone.


Having correct timestamps on state changes is crucial to calculate cycle times and make data driven projections for the roadmap. Normally this requires boring and often neglected work of clicking here and there in browser and editors.

Instead of bossing around people to continously, we should change our tool chain so that the changes we need in Jira happens automatically.

go-jira is a great command line tool that allows us to work with Jira without browser. It allows defining custom commands so that it gives us the freedom and flexibility to code whatever flow that we want to have.