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 Review
toReady for QA
orDone
. -
End Time
: The date and time the work item was closed. There is already theresolution
field which includes theresolutiondate
component, 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:
-
Discard
updatesStatus
toDone
and:- Updates
Resolution
toWon't Do
- Updates
Story Points
to0
- Updates
-
Mark as duplicate
updatesStatus
toDone
and:- Updates
Resolution
toDuplicate
- Updates
Story Points
to0
- Updates
-
Finish refinement
updatesStatus
toTo do
-
Finish refinement but blocked
updatesStatus
toBlocked
Blocked
A work item that has been refined but is blocked due to other pending work items.
-
Unblock
updatesStatus
toTo do
-
Redraft
updatesStatus
toDraft
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.
-
Redraft
revertsStatus
toDraft
in case something was missed or life changed -
Start
updatesStatus
toIn Progress
and:- Updates
Assignee
to the user who performed the transition - Copies
Assignee
overDeveloper
- Updates
Start time
to the current date and time
- Updates
In Progress
-
Pause
updatesStatus
toTo do
-
Request review
updatesStatus
toIn Review
and:- Updates
Ready For Review Time
to the current date and time
- Updates
-
Mark invalid
updatesStatus
toDone
and:- Updates
Resolution
toWon't Do
- Clears
Ready for Review Time
- Clears
Start Time
- Clears
Development Complete Time
- Clears
End Time
- Updates
Story Points
to0
- Updates
In Review
-
Merge code and skip testing
can be useful for updatingStatus
toDone
when 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
Resolution
toDone
- Copies
Developer
overTester
to indicate that the developer tested their own work item (which is generally bad practice but can be useful in limited circumstances) - Updates
End Time
to the current date and time - Updates
Development Complete Time
to the current date and time
- Updates
-
Merge code
updatesStatus
toReady for review
and:- Clears
Assignee
. TheDeveloper
custom field will still be there for use later - Updates
Development Complete Time
to 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 testing
updatesStatus
toIn testing
and:- Updates
Assignee
to the user who performed the transition. - Copies
Assignee
overTester
- Updates
-
Request change
updatesStatus
toTo do
in 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
Developer
overAssignee
- Copies
In testing
The work item is actively being tested.
-
Request change
updatesStatus
toTo 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
Developer
overAssignee
- Copies
-
Pass testing
updatesStatus
toDone
and:- Updates
Resolution
toDone
- Copies
Developer
overAssignee
. It's useful to quickly associated a closed work item with the person who developed it and theTester
custom field is still there for deep diving. - Updates
End time
to 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.
-
Reopen
updatesStatus
toTo Do
and:- Clears
Assignee
- Clears
End time
- Clears
Resolution
which 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
Done
column by the resolution date in descending order (i.e. most recently resolved work items at the top).End Time
won't be set for work items without a status ofDone
(as enforced by the workflow) so thisorder by
clause won't have any effect for work items in other columns. - For columns other than
Done
work 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 request
title to the Jira work item title. - Add a text block to the
pull request
description 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)
Jira is a solid choice for software engineering projects, but setup can be overwhelming. Defining clear workflows, issue types, and automation rules is key. For teams seeking a streamlined alternative, Teamcamp provides an intuitive project management experience with simpler task tracking and collaboration. Have you tried Teamcamp for software projects?