DEV Community

insidewhy
insidewhy

Posted on • Edited on

Suggested Jira setup for software engineering projects

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 from In Review to Ready for QA or Done.
  • End Time: The date and time the work item was closed. There is already the resolution field which includes the resolutiondate 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 updates Status to Done and:
    • Updates Resolution to Won't Do
    • Updates Story Points to 0
  • Mark as duplicate updates Status to Done and:
    • Updates Resolution to Duplicate
    • Updates Story Points to 0
  • Finish refinement updates Status to To do
  • Finish refinement but blocked updates Status to Blocked

Blocked

A work item that has been refined but is blocked due to other pending work items.

  • Unblock updates Status to To do
  • Redraft updates Status to Draft

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 reverts Status to Draft in case something was missed or life changed
  • Start updates Status to In Progress and:
    • Updates Assignee to the user who performed the transition
    • Copies Assignee over Developer
    • Updates Start time to the current date and time

In Progress

  • Pause updates Status to To do
  • Request review updates Status to In Review and:
    • Updates Ready For Review Time to the current date and time
  • Mark invalid updates Status to Done and:
    • Updates Resolution to Won't Do
    • Clears Ready for Review Time
    • Clears Start Time
    • Clears Development Complete Time
    • Clears End Time
    • Updates Story Points to 0

In Review

  • Merge code and skip testing can be useful for updating Status to Done 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 to Done
    • Copies Developer over Tester 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
  • Merge code updates Status to Ready for review and:
    • Clears Assignee. The Developer custom field will still be there for use later
    • Updates Development Complete Time to the current date and time

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 updates Status to In testing and:
    • Updates Assignee to the user who performed the transition.
    • Copies Assignee over Tester
  • Request change updates Status to To 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 over Assignee

In testing

The work item is actively being tested.

  • Request change updates Status to To 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 over Assignee
  • Pass testing updates Status to Done and:
    • Updates Resolution to Done
    • Copies Developer over Assignee. It's useful to quickly associated a closed work item with the person who developed it and the Tester custom field is still there for deep diving.
    • Updates End time to the current date and time.

Done

The work item is most likely done with forever but may be reopened in case something comes up at a later date.

  • Reopen updates Status to To Do and:
    • Clears Assignee
    • Clears End time
    • Clears Resolution which also has the effect of clearing the resolutiondate

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
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  • 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 of Done (as enforced by the workflow) so this order 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 their fixVersion (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
Enter fullscreen mode Exit fullscreen mode

Closed issues ordered by resolution date

project = MYPROJECT
and resolution not in (Duplicate, "Cannot Reproduce", "Won't Do")
order by resolutiondate
Enter fullscreen mode Exit fullscreen mode

Issues in progress

project = MYPROJCT
and type != Epic
and status in ("In progress",  "In review", "In testing")
order by fixVersion ASC, priority desc
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Issues to be tested

project = MYPROJECT
and type != Epic and status = "Ready for QA"
order by fixVersion ASC, priority desc
Enter fullscreen mode Exit fullscreen mode

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 issue PJ-1.
  • chore/PJ-2: A task relating to the issue PJ-2.
  • feature/PJ-3: A feature/story relating to the issue PJ-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 of insidewhy/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 }})
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
pratham_naik_project_manager profile image
Pratham naik

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?