AgentSkillsCN

Jira Pat

在自建/企业版Jira实例中,使用个人访问令牌(PAT)管理Jira问题。当您使用SSO/SAML认证的Jira,且Basic Auth无法正常工作时,可使用此技能。

SKILL.md
--- frontmatter
description: Manage Jira issues on self-hosted/enterprise instances using Personal Access Tokens (PAT). Use this skill when working with Jira that uses SSO/SAML authentication where Basic Auth fails.

Jira PAT Skill

This skill provides patterns for interacting with Jira REST API using Personal Access Tokens (PAT).

Prerequisites

  1. Personal Access Token (PAT): Create one in Jira:

    • Go to your Jira profile → Personal Access Tokens
    • Create a new token with appropriate permissions
    • Store it securely (e.g., in environment variable JIRA_PAT)
  2. Jira Base URL: Your Jira instance URL (e.g., https://issues.redhat.com)

Environment Setup

bash
# Set these in your shell or .bashrc/.zshrc
export JIRA_PAT="your-personal-access-token"
export JIRA_URL="https://issues.redhat.com"

Common Operations

Get Issue Details

Fetch full details of a Jira issue by its key:

bash
curl -s -H "Authorization: Bearer $JIRA_PAT" \
  "$JIRA_URL/rest/api/2/issue/TC-3494" | jq

Get specific fields only:

bash
curl -s -H "Authorization: Bearer $JIRA_PAT" \
  "$JIRA_URL/rest/api/2/issue/TC-3494?fields=summary,status,description" | jq

Search for Issues (JQL)

Search using JQL (Jira Query Language):

bash
# Find all child issues of an epic
curl -s -H "Authorization: Bearer $JIRA_PAT" \
  "$JIRA_URL/rest/api/2/search?jql=parent=TC-3494" | jq

# Search with URL encoding for complex queries
curl -s -H "Authorization: Bearer $JIRA_PAT" \
  "$JIRA_URL/rest/api/2/search?jql=project%3DTCS%20AND%20status%3DOpen" | jq

Common JQL examples:

  • parent=EPIC-123 - Child issues of an epic
  • project=TCS AND status=Open - Open issues in project
  • assignee=currentUser() - Issues assigned to you
  • labels=security - Issues with specific label
  • updated >= -7d - Recently updated

Get Available Transitions

Before changing issue status, get available transitions:

bash
curl -s -H "Authorization: Bearer $JIRA_PAT" \
  "$JIRA_URL/rest/api/2/issue/TC-3496/transitions" | jq '.transitions[] | {id, name}'

Example output:

json
{"id": "11", "name": "To Do"}
{"id": "21", "name": "In Progress"}
{"id": "31", "name": "In Review"}
{"id": "41", "name": "Done"}
{"id": "61", "name": "Closed"}

Transition (Change Status) an Issue

Close an issue with a comment:

bash
curl -s -X POST \
  -H "Authorization: Bearer $JIRA_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "transition": {"id": "61"},
    "update": {
      "comment": [
        {"add": {"body": "Closed via API. Implementation complete in PR #123."}}
      ]
    }
  }' \
  "$JIRA_URL/rest/api/2/issue/TC-3496/transitions"

Move to "In Progress" without comment:

bash
curl -s -X POST \
  -H "Authorization: Bearer $JIRA_PAT" \
  -H "Content-Type: application/json" \
  -d '{"transition": {"id": "21"}}' \
  "$JIRA_URL/rest/api/2/issue/TC-3496/transitions"

Add a Comment

bash
curl -s -X POST \
  -H "Authorization: Bearer $JIRA_PAT" \
  -H "Content-Type: application/json" \
  -d '{"body": "This is a comment added via API."}' \
  "$JIRA_URL/rest/api/2/issue/TC-3496/comment"

Update Issue Fields

bash
curl -s -X PUT \
  -H "Authorization: Bearer $JIRA_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": {
      "summary": "Updated summary",
      "labels": ["api", "security"]
    }
  }' \
  "$JIRA_URL/rest/api/2/issue/TC-3496"

Create an Issue

bash
curl -s -X POST \
  -H "Authorization: Bearer $JIRA_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": {
      "project": {"key": "TCS"},
      "summary": "New issue created via API",
      "description": "Issue description here",
      "issuetype": {"name": "Task"},
      "parent": {"key": "TC-3494"}
    }
  }' \
  "$JIRA_URL/rest/api/2/issue"

Useful jq Filters

bash
# Get just summary and status
curl -s -H "Authorization: Bearer $JIRA_PAT" \
  "$JIRA_URL/rest/api/2/issue/TC-3494" | \
  jq '{key: .key, summary: .fields.summary, status: .fields.status.name}'

# List all child issues with status
curl -s -H "Authorization: Bearer $JIRA_PAT" \
  "$JIRA_URL/rest/api/2/search?jql=parent=TC-3494" | \
  jq '.issues[] | {key: .key, summary: .fields.summary, status: .fields.status.name}'

# Get issue links
curl -s -H "Authorization: Bearer $JIRA_PAT" \
  "$JIRA_URL/rest/api/2/issue/TC-3494" | \
  jq '.fields.issuelinks[] | {type: .type.name, key: (.inwardIssue // .outwardIssue).key}'

Shell Functions

Add these to your .bashrc or .zshrc for convenience:

bash
# Get issue details
jira-get() {
  curl -s -H "Authorization: Bearer $JIRA_PAT" \
    "$JIRA_URL/rest/api/2/issue/$1" | jq
}

# Get issue summary
jira-summary() {
  curl -s -H "Authorization: Bearer $JIRA_PAT" \
    "$JIRA_URL/rest/api/2/issue/$1" | \
    jq -r '"\(.key): \(.fields.summary) [\(.fields.status.name)]"'
}

# Search issues
jira-search() {
  curl -s -H "Authorization: Bearer $JIRA_PAT" \
    "$JIRA_URL/rest/api/2/search?jql=$1" | \
    jq '.issues[] | "\(.key): \(.fields.summary) [\(.fields.status.name)]"' -r
}

# List epic children
jira-children() {
  curl -s -H "Authorization: Bearer $JIRA_PAT" \
    "$JIRA_URL/rest/api/2/search?jql=parent=$1" | \
    jq '.issues[] | "\(.key): \(.fields.summary) [\(.fields.status.name)]"' -r
}

# Get available transitions
jira-transitions() {
  curl -s -H "Authorization: Bearer $JIRA_PAT" \
    "$JIRA_URL/rest/api/2/issue/$1/transitions" | \
    jq '.transitions[] | "\(.id): \(.name)"' -r
}

# Close an issue
jira-close() {
  local issue=$1
  local comment=${2:-"Closed via API"}
  curl -s -X POST \
    -H "Authorization: Bearer $JIRA_PAT" \
    -H "Content-Type: application/json" \
    -d "{\"transition\": {\"id\": \"61\"}, \"update\": {\"comment\": [{\"add\": {\"body\": \"$comment\"}}]}}" \
    "$JIRA_URL/rest/api/2/issue/$issue/transitions"
  echo "Closed $issue"
}

Usage:

bash
jira-get TC-3494
jira-summary TC-3601
jira-search "project=TCS AND status=Open"
jira-children TC-3494
jira-transitions TC-3496
jira-close TC-3496 "Completed in PR #123"

Troubleshooting

401 Unauthorized

  • Verify your PAT is valid and not expired
  • Check the Authorization header format: Bearer <token> (not Bearer: <token>)

404 Not Found

  • Verify the issue key exists
  • Check you have permission to view the issue

400 Bad Request on Transition

  • Get available transitions first - transition IDs vary by workflow
  • Some transitions require specific fields or conditions

Notes

  • The jira-cli tool (jira) doesn't work well with self-hosted Jira instances using SSO
  • Direct curl with PAT is more reliable for self-hosted Jira
  • Always URL-encode JQL queries when using special characters
  • Transition IDs are workflow-specific - always query them first