Change status and assignee of Jira ticket
Overview
This self-service guide facilitates transitioning the status and assignee of a Jira ticket from Port using Port's self service actions. With this, you can manage ticket (issue) status without leaving Port.
Prerequisites
-
Port's GitHub app needs to be installed.
-
In your GitHub repository, go to Settings > Secrets and add the following secrets:
JIRA_API_TOKEN
- Jira API token generated by the user.JIRA_BASE_URL
- The URL of your Jira organization. For example, https://your-organization.atlassian.net.JIRA_USER_EMAIL
- The email of the Jira user that owns the Jira API token.PORT_AUTH_CLIENT_ID
- Your portclient id
How to get the credentials.PORT_AUTH_CLIENT_SECRET
- Your portclient secret
How to get the credentials.
-
Optional - Install Port's Jira integration learn more
Jira IntegrationThis step is not required for this example, but it will create all the blueprint boilerplate for you, and also ingest and update the catalog in real time with your Jira Issues.
-
In Case you decided not to install the Jira integration, you will need to create a blueprint for the Jira issue in Port.
Jira Issue Blueprint
{
"identifier": "jiraIssue",
"title": "Jira Issue",
"icon": "Jira",
"schema": {
"properties": {
"url": {
"title": "Issue URL",
"type": "string",
"format": "url",
"description": "URL to the issue in Jira"
},
"status": {
"title": "Status",
"type": "string",
"description": "The status of the issue"
},
"issueType": {
"title": "Type",
"type": "string",
"description": "The type of the issue"
},
"components": {
"title": "Components",
"type": "array",
"description": "The components related to this issue"
},
"assignee": {
"title": "Assignee",
"type": "string",
"format": "user",
"description": "The user assigned to the issue"
},
"reporter": {
"title": "Reporter",
"type": "string",
"description": "The user that reported to the issue",
"format": "user"
},
"creator": {
"title": "Creator",
"type": "string",
"description": "The user that created to the issue",
"format": "user"
},
"priority": {
"title": "Priority",
"type": "string",
"description": "The priority of the issue"
},
"created": {
"title": "Created At",
"type": "string",
"description": "The created datetime of the issue",
"format": "date-time"
},
"updated": {
"title": "Updated At",
"type": "string",
"description": "The updated datetime of the issue",
"format": "date-time"
}
}
},
"calculationProperties": {},
"relations": {}
}
GitHub Workflow
Create the file .github/workflows/change-jira-ticket-status-and-assignee.yml
in the .github/workflows
folder of your repository.
We recommend creating a dedicated repository for the workflows that are used by Port actions.
GitHub Workflow
name: Change Jira Ticket Status and Assignee
on:
workflow_dispatch:
inputs:
status:
type: string
required: false
assignee:
type: string
required: false
port_context:
required: true
type: string
jobs:
change-jira-ticket-status-and-assignee:
runs-on: ubuntu-latest
outputs:
selected_user_id: ${{ steps.user_list_from_search.outputs.selected_user_id }}
selected_user_name: ${{ steps.user_list_from_search.outputs.selected_user_name }}
steps:
- name: Login
uses: atlassian/gajira-login@v3
env:
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
- name: Inform starting of changing Jira ticket status
id: inform_ticket_start
if: ${{ inputs.status }}
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
operation: PATCH_RUN
runId: ${{ fromJson(inputs.port_context).run_id }}
logMessage: |
Changing status of Jira issue... ⛴️
- name: Inform skipping of changing Jira ticket status
id: inform_skip_ticket_status
if: steps.inform_ticket_start.outcome == 'skipped'
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
operation: PATCH_RUN
runId: ${{ fromJson(inputs.port_context).run_id }}
logMessage: |
Status field is blank, skipping status change... ⛴️
- name: Transition issue
id: transition_issue_status
if: steps.inform_ticket_start.outcome == 'success'
uses: atlassian/gajira-transition@v3
with:
issue: ${{ fromJson(inputs.port_context).entity }}
transition: ${{ inputs.status }}
- name: Inform that status has been changed
if: steps.transition_issue_status.outcome == 'success'
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
operation: PATCH_RUN
link: ${{ secrets.JIRA_BASE_URL }}/browse/${{ fromJson(inputs.port_context).entity }}
runId: ${{ fromJson(inputs.port_context).run_id }}
logMessage: |
Jira issue status changed to ${{ inputs.status }}! ✅
- name: Inform starting of changing Jira ticket assignee
id: inform_assignee_start
if: ${{ inputs.assignee }}
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
operation: PATCH_RUN
runId: ${{ fromJson(inputs.port_context).run_id }}
logMessage: |
Assigning ticket to user... ⛴️
- name: Inform skipping of changing Jira ticket assignee
id: inform_skip_assignee
if: steps.inform_assignee_start.outcome == 'skipped'
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
operation: PATCH_RUN
runId: ${{ fromJson(inputs.port_context).run_id }}
logMessage: |
Assignee field is blank, skipping assigning of ticket... ⛴️
- name: Inform searching of user in user list
if: steps.inform_skip_assignee.outcome == 'skipped'
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
operation: PATCH_RUN
runId: ${{ fromJson(inputs.port_context).run_id }}
logMessage: |
Searching for user in organization user list... ⛴️
- name: Search for assignee among user list
id: search_for_assignee
if: steps.inform_skip_assignee.outcome == 'skipped'
uses: fjogeleit/http-request-action@v1
with:
url: "${{ secrets.JIRA_BASE_URL }}/rest/api/3/user/search?query=${{ inputs.assignee }}"
method: "GET"
username: ${{ secrets.JIRA_USER_EMAIL }}
password: ${{ secrets.JIRA_API_TOKEN }}
customHeaders: '{"Content-Type": "application/json"}'
- name: Install jq
run: sudo apt-get install jq
if: steps.search_for_assignee.outcome == 'success'
- name: Retrieve user list from search
id: user_list_from_search
if: steps.search_for_assignee.outcome == 'success'
run: |
selected_user_id=$(echo '${{ steps.search_for_assignee.outputs.response }}' | jq -r 'if length > 0 then .[0].accountId else "empty" end')
selected_user_name=$(echo '${{ steps.search_for_assignee.outputs.response }}' | jq -r 'if length > 0 then .[0].displayName else "empty" end')
echo "selected_user_id=${selected_user_id}" >> $GITHUB_OUTPUT
echo "selected_user_name=${selected_user_name}" >> $GITHUB_OUTPUT
- name: Inform user existence
if: steps.user_list_from_search.outputs.selected_user_id != 'empty'
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
operation: PATCH_RUN
runId: ${{ fromJson(inputs.port_context).run_id }}
logMessage: |
User found 🥹 Assigning ticket ${{ fromJson(inputs.port_context).entity }} to ${{ steps.user_list_from_search.outputs.selected_user_name }}... ⛴️
- name: Inform user inexistence
if: steps.user_list_from_search.outputs.selected_user_id == 'empty'
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
operation: PATCH_RUN
runId: ${{ fromJson(inputs.port_context).run_id }}
logMessage: |
User not found 😭 Skipping assignment... ⛴️
- name: Assign ticket to selected user
id: assign_ticket
if: steps.user_list_from_search.outputs.selected_user_id != 'empty'
uses: fjogeleit/http-request-action@v1
with:
url: "${{ secrets.JIRA_BASE_URL }}/rest/api/3/issue/${{ fromJson(inputs.port_context).entity }}/assignee"
method: "PUT"
username: ${{ secrets.JIRA_USER_EMAIL }}
password: ${{ secrets.JIRA_API_TOKEN }}
customHeaders: '{"Content-Type": "application/json"}'
data: '{"accountId": "${{ steps.user_list_from_search.outputs.selected_user_id }}"}'
- name: Inform ticket has been assigned
if: steps.assign_ticket.outcome == 'success'
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
operation: PATCH_RUN
link: ${{ secrets.JIRA_BASE_URL }}/browse/${{ fromJson(inputs.port_context).entity }}
runId: ${{ fromJson(inputs.port_context).run_id }}
logMessage: |
Jira issue has been assigned to ${{ steps.user_list_from_search.outputs.selected_user_name }}! ✅
Port Configuration
- Head to the self-service page.
- Click on the
+ New Action
button. - Choose the
Jira Issue
blueprint and clickNext
. - Click on the
{...} Edit JSON
button. - Copy and paste the following JSON configuration into the editor.
Change status of a Jira ticket (Click to expand)
Make sure to replace <GITHUB_ORG>
and <GITHUB_REPO>
with your GitHub organization and repository names respectively.
{
"identifier": "jiraIssue_change_jira_ticket_status",
"title": "Change Jira ticket status and assignee",
"icon": "Jira",
"description": "Transition a ticket to another status.",
"trigger": {
"type": "self-service",
"operation": "DAY-2",
"userInputs": {
"properties": {
"status": {
"icon": "DefaultProperty",
"title": "Status",
"type": "string",
"enum": [
"To Do",
"In Progress",
"Code Review",
"Product Review",
"Waiting For Prod",
"Done"
],
"enumColors": {
"To Do": "lightGray",
"In Progress": "bronze",
"Code Review": "darkGray",
"Product Review": "purple",
"Waiting For Prod": "orange",
"Done": "green"
}
},
"assignee": {
"type": "string",
"title": "Assignee",
"icon": "User",
"format": "user"
}
},
"required": [
"status",
"assignee"
],
"order": [
"status"
]
},
"blueprintIdentifier": "jiraIssue"
},
"invocationMethod": {
"type": "GITHUB",
"org": "<Enter GitHub organization>",
"repo": "<Enter GitHub repository>",
"workflow": "change_jira_ticket_status_and_assignee.yml",
"workflowInputs": {
"status": "{{.inputs.\"status\"}}",
"assignee": "{{.inputs.\"assignee\"}}",
"port_context": {
"entity": "{{.entity.identifier}}",
"run_id": "{{.run.id}}"
}
},
"reportWorkflowStatus": true
},
"requiredApproval": false,
"publish": true
}
- Click
Save
.
Now you should see the Change Jira ticket status and assignee
action in the self-service page. 🎉
Let's test it!
- Head to the Self Service hub
- Click on the
Change Jira ticket status and assignee
action - Choose the jira ticket you want to change the status and assignee for (In case you didn't install the Jira integration, it means you don't have any Jira tickets in Port yet, so you will need to create one manually in Port to test this action)
- Select the new status
- Enter the name of the assignee or their email address
- Click on
Execute
- Done! wait for the ticket's status and assignee to be changed in Jira
Congrats 🎉 You've changed a ticket status and its assignee in Port 🔥
More Self Service Jira Actions Examples
- Report a bug in Jira using Port's self-service actions
- Open Jira issues with automatic labels
- Open/close JIRA issues for entities with violated scorecard rules
- Add a comment to a Jira ticket using Port's self-service actions