I've been refining the way I deal with software development workflows for more than 20 years now. I've worked in different positions of seniority, with team/organisation sizes ranging from minuscule to huge, and at various stages of the software development life cycle. This article represents the current state of evolution of the Jira configuration I use.
Team-managed vs company-managed projects
I advise choosing company-managed, team-managed projects offer much less customisability, in particular the scrum/kanban board layout is extremely limited and cannot be customised to the degree shown in the configuration suggested by this article.
Custom fields
The following fields are not part of Jira by default but can be useful for tracking important information. These fields don't create any additional maintenance burden as they are updated automatically by the workflow suggestion shown later in the article.
-
Developer: The Jira user associated with the person who developed the work item. -
Tester: The Jira user associated with the person who tested the work item. -
Start Time: The date and time the work item started being actively worked on (post refinement). -
Development Complete Time: The date and time the work item was transitioned fromIn ReviewtoReady for QAorDone. -
End Time: The date and time the work item was closed. There is already theresolutionfield which includes theresolutiondatecomponent, but for some reason Jira does not show the resolution date anywhere in the UI and it can be very useful to see.
Workflow
Statuses
Draft
The initial state of any work item to show it hasn't been refined. After a refinement session:
-
DiscardupdatesStatustoDoneand:- Updates
ResolutiontoWon't Do - Updates
Story Pointsto0
- Updates
-
Mark as duplicateupdatesStatustoDoneand:- Updates
ResolutiontoDuplicate - Updates
Story Pointsto0
- Updates
-
Finish refinementupdatesStatustoTo do -
Finish refinement but blockedupdatesStatustoBlocked
Blocked
A work item that has been refined but is blocked due to other pending work items.
-
UnblockupdatesStatustoTo do -
RedraftupdatesStatustoDraft
To do
The work item is ready to work on unless there is are work items related to it with an is blocked by association that are not yet Done. Generally issues with a status of To do won't have an Assignee but a person can set this if they want to claim the work item to show that they would like to be the one to develop it in the future.
-
RedraftrevertsStatustoDraftin case something was missed or life changed -
StartupdatesStatustoIn Progressand:- Updates
Assigneeto the user who performed the transition - Copies
AssigneeoverDeveloper - Updates
Start timeto the current date and time
- Updates
In Progress
-
PauseupdatesStatustoTo do -
Request reviewupdatesStatustoIn Reviewand:- Updates
Ready For Review Timeto the current date and time
- Updates
-
Mark invalidupdatesStatustoDoneand:- Updates
ResolutiontoWon't Do - Clears
Ready for Review Time - Clears
Start Time - Clears
Development Complete Time - Clears
End Time - Updates
Story Pointsto0
- Updates
In Review
-
Merge code and skip testingcan be useful for updatingStatustoDonewhen it doesn't require any testing. This is usually not a good idea but an escape hatch when life doesn't make sense. This transition also:- Updates
ResolutiontoDone - Copies
DeveloperoverTesterto indicate that the developer tested their own work item (which is generally bad practice but can be useful in limited circumstances) - Updates
End Timeto the current date and time - Updates
Development Complete Timeto the current date and time
- Updates
-
Merge codeupdatesStatustoReady for reviewand:- Clears
Assignee. TheDevelopercustom field will still be there for use later - Updates
Development Complete Timeto the current date and time
- Clears
Ready for QA
The work item is ready for QA and won't have an Assignee, but a person may set the Assignee to claim the work item to show that they would like to be the one to test the work item in the future.
-
Start testingupdatesStatustoIn testingand:- Updates
Assigneeto the user who performed the transition. - Copies
AssigneeoverTester
- Updates
-
Request changeupdatesStatustoTo doin case something was noticed before testing started, when this happens a comment should be left in the work item indicating what should change. This also:- Copies
DeveloperoverAssignee
- Copies
In testing
The work item is actively being tested.
-
Request changeupdatesStatustoTo do, if this is done the tester should leave a comment in the work item to say what bugs were found or what changes should be made. It also:- Copies
DeveloperoverAssignee
- Copies
-
Pass testingupdatesStatustoDoneand:- Updates
ResolutiontoDone - Copies
DeveloperoverAssignee. It's useful to quickly associated a closed work item with the person who developed it and theTestercustom field is still there for deep diving. - Updates
End timeto the current date and time.
- Updates
Done
The work item is most likely done with forever but may be reopened in case something comes up at a later date.
-
ReopenupdatesStatustoTo Doand:- Clears
Assignee - Clears
End time - Clears
Resolutionwhich also has the effect of clearing theresolutiondate
- Clears
Automations
Jira automations can be used to prevent naughty things:
Do not assign QA issues to developer
A developer shouldn't test their own code, any attempts to assign a work item in Ready for QA or In testing statuses to the user in the Developer custom field will revert the assignation.
Prevent Developer transitioning issue to "In Test"
A person shouldn't transition an issue to In testing when they were the one who developed it, any attempts to do this will be reverted. Here the Edit issue fields advanced option has the following content:
{
"fields": {
"Tester": null
}
}
The board
The following filter creates a nice order for the kanban/scrum board:
project = YOURPROJECT
and (
status != Done
or resolution not in (Duplicate, "Cannot Reproduce", "Won't Do")
)
order by End Time desc, fixVersion asc, priority desc
- Don't show issues which were discarded.
- Order the work items in the
Donecolumn by the resolution date in descending order (i.e. most recently resolved work items at the top).End Timewon't be set for work items without a status ofDone(as enforced by the workflow) so thisorder byclause won't have any effect for work items in other columns. - For columns other than
Donework items will be shown in order of theirfixVersion(i.e. work items for the upcoming release will be shown at the top of the board), and within each release, work items will be ordered by priority.
Releases
Assigning work items to releases is a great way to keep track of progress of a particular release and for ordering the scrum/kanban board. Note that the releases list should be in descending date order (i.e. the most recent release should be at the top of the list and the oldest release should be at the bottom of the list). Releases can be dragged and dropped to reorder the list.
Filters
The following filters can be useful:
Open issues sorted by release then priority
project = MYPROJECT
and type != Epic and status != Done
order by fixVersion ASC, priority desc
Closed issues ordered by resolution date
project = MYPROJECT
and resolution not in (Duplicate, "Cannot Reproduce", "Won't Do")
order by resolutiondate
Issues in progress
project = MYPROJCT
and type != Epic
and status in ("In progress", "In review", "In testing")
order by fixVersion ASC, priority desc
Issues for next release
project = MYPROJECT
and fixVersion = earliestUnreleasedVersion()
and (
status != Done
or resolution not in (Duplicate, "Cannot Reproduce", "Won't Do")
)
order by resolutiondate desc, fixVersion asc, priority desc
Issues to be tested
project = MYPROJECT
and type != Epic and status = "Ready for QA"
order by fixVersion ASC, priority desc
Github
If the project "short code" in Jira is PJ then issue identifiers will look like PJ-1, PJ-42 etc. When creating a it's useful to name the branch after the Jira work items with an optional prefix to show the type of work e.g.
-
fix/PJ-1: A fix relating to the issuePJ-1. -
chore/PJ-2: A task relating to the issuePJ-2. -
feature/PJ-3: A feature/story relating to the issuePJ-3. -
PJ-4: If you don't care to mark the task type in the branch name.
Assuming this convention has been used (or that the PR title begins with PJ-42:) a github action can be used to:
- Set the
pull requesttitle to the Jira work item title. - Add a text block to the
pull requestdescription with a link to the Jira work item (this block can be updated when the Jira content changes as updating text blocks is a supported feature ofinsidewhy/actions-body-fields).
To do this the following file can be created within the github repository at a file location such as .github/workflows/jira-linker.yml:
name: jira-linker
on:
pull_request:
types:
- opened
- reopened
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
action-jira-linker:
runs-on: ubuntu-latest
permissions:
pull-requests: write
issues: write
steps:
- name: determine associated issue id
id: get-ticket-id
run: |
ticket_match='grep -Eqx [A-Z]+-[0-9]+'
# first try to get the ticket id from the title
title="${{github.event.pull_request.title}}"
ticket_id=${title%%:*}
if ! echo $ticket_id | $ticket_match; then
# otherwise try to get the ticket id from the branch
branch=${{ github.head_ref || github.ref_name }}
ticket_id=${branch#*/}
ticket_id=${ticket_id%%_*}
if ! echo $ticket_id | $ticket_match; then
exit 0
fi
fi
echo "ticket-id=$ticket_id" >> $GITHUB_OUTPUT
- uses: insidewhy/action-get-jira-issue@v1
id: jira
if: steps.get-ticket-id.outputs.ticket-id
with:
user: ${{ secrets.JIRA_USER }}
token: ${{ secrets.JIRA_TOKEN }}
base-url: ${{ secrets.JIRA_BASE_URL }}
ticket-id: ${{ steps.get-ticket-id.outputs.ticket-id }}
- uses: insidewhy/action-body-fields@v1
if: steps.get-ticket-id.outputs.ticket-id
with:
prepend: true
title: '${{ steps.get-ticket-id.outputs.ticket-id }}: ${{ steps.jira.outputs.summary }}'
header: '## Status'
fields: |
Jira: [${{ steps.get-ticket-id.outputs.ticket-id }}: ${{ steps.jira.outputs.summary }}](${{ steps.jira.outputs.link }})
For this to work a Jira token must be created, then information about this token must be set via github secrets:
-
JIRA_USER: The user that created the Jira token. -
JIRA_TOKEN: The token itself. -
JIRA_BASE_URL: The URL of the Jira instance e.g.https://my-kitten-project.atlassian.net



Top comments (1)