Skip to content
jira-status-updater logo

Method 1: Extract from PR title (if available)

jira-status-updater

Automate JIRA ticket status transitions after pull requests are merged, ensuring proper workflow closure

SKILL.md

Full skill instructions

What I do

I provide automated JIRA ticket status transitions to ensure proper workflow completion after PR merges:

  1. Detect JIRA Ticket: Extract JIRA ticket key from PR title, commits, or branch name
  2. Query Available Transitions: Use Atlassian API to get valid status transitions for the ticket
  3. Identify Target Status: Find "Done" or "Closed" status transition
  4. Execute Status Transition: Update JIRA ticket status using transition API
  5. Add Merge Comment: Post final comment with PR merge details
  6. Handle Edge Cases: Gracefully handle missing transitions, permissions, already-done status
  7. Log Status: Provide clear feedback on transition success/​failure

When to use me

Use this framework when:

  • A PR has been successfully merged
  • You need to update the linked JIRA ticket status
  • You want to ensure JIRA tickets are properly closed after work completion
  • You're building a workflow that includes PR merge handling
  • You need automated JIRA workflow management

This is a framework skill - it provides JIRA status transition functionality that other skills use.

Core Workflow Steps

Step 1: Detect JIRA Ticket Reference

Purpose: Extract JIRA ticket key from PR or commit information

Detection Methods (in priority order):

SourceDetection PatternExampleCommand
PR TitleRegex for JIRA keyfeat: Add login [IBIS-101]Extract from gh pr view
Commit MessagesRegex for JIRA key[IBIS-123] Fix buggit log --oneline
Branch NameParse ticket keyIBIS-101-add-featuregit branch --show-current
PLAN.mdSearch for referencesJIRA Reference: IBIS-456Read PLAN.md

Detection Logic:

# Method 1: Extract from PR title (if available)
if command -v gh &>/​dev/​null; then
  PR_TITLE=$(gh pr view --json title --jq '.title')
  JIRA_TICKET=$(echo "$PR_TITLE" | grep -oE '[A-Z]+-[0-9]+' | head -1)
fi

# Method 2: Extract from latest commit
if [ -z "$JIRA_TICKET" ]; then
  JIRA_TICKET=$(git log --oneline -1 | grep -oE '[A-Z]+-[0-9]+' | head -1)
fi

# Method 3: Extract from branch name
if [ -z "$JIRA_TICKET" ]; then
  BRANCH_NAME=$(git branch --show-current)
  JIRA_TICKET=$(echo "$BRANCH_NAME" | grep -oE '[A-Z]+-[0-9]+' | head -1)
fi

# Method 4: Extract from PLAN.md
if [ -z "$JIRA_TICKET" ] && [ -f "PLAN.md" ]; then
  JIRA_TICKET=$(grep -oE '[A-Z]+-[0-9]+' PLAN.md | head -1)
fi

# Validate ticket format
if [ -n "$JIRA_TICKET" ]; then
  echo "✅ Detected JIRA ticket: $JIRA_TICKET"
else
  echo "⚠️  No JIRA ticket reference found"
  return 1
fi

Step 2: Get Available Transitions

Purpose: Query Atlassian API to get valid status transitions for the ticket

Tools Used: atlassian_getTransitionsForJiraIssue

# Get cloud ID
CLOUD_ID="${ATLASSIAN_CLOUD_ID:-<default-cloud-id>}"

# Query available transitions
TRANSITIONS=$(atlassian_getTransitionsForJiraIssue \
  --cloudId "$CLOUD_ID" \
  --issueIdOrKey "$JIRA_TICKET")

# Parse transitions
echo "Available transitions for $JIRA_TICKET:"
echo "$TRANSITIONS" | jq -r '.transitions[] | "- \(.name) → \(.to.name)"'

Expected Output:

{
  "transitions": [
    {
      "id": "121",
      "name": "Done",
      "to": {
        "id": "101",
        "name": "Done",
        "statusCategory": {
          "id": "3",
          "key": "done",
          "colorName": "green"
        }
      }
    },
    {
      "id": "131",
      "name": "In Review",
      "to": {
        "id": "103",
        "name": "In Review",
        "statusCategory": {
          "id": "4",
          "key": "inprogress",
          "colorName": "blue"
        }
      }
    }
  ]
}

Step 3: Identify Target Status Transition

Purpose: Find the transition that leads to "Done" or "Closed" status

Target Status Priority:

  1. Done - Most common final status
  2. Closed - Alternative final status
  3. Custom status - Any status with category "done"

Detection Logic:

# Try to find "Done" transition
TARGET_TRANSITION=$(echo "$TRANSITIONS" | \
  jq -r '.transitions[] | select(.to.name == "Done") | {id: .id, name: .name}')

# If no "Done", try "Closed"
if [ -z "$TARGET_TRANSITION" ]; then
  TARGET_TRANSITION=$(echo "$TRANSITIONS" | \
    jq -r '.transitions[] | select(.to.name == "Closed") | {id: .id, name: .name}')
fi

# If no specific status found, try any "done" category status
if [ -z "$TARGET_TRANSITION" ]; then
  TARGET_TRANSITION=$(echo "$TRANSITIONS" | \
    jq -r '.transitions[] | select(.to.statusCategory.key == "done") | {id: .id, name: .name} | first')
fi

# Extract transition ID and name
TRANSITION_ID=$(echo "$TARGET_TRANSITION" | jq -r '.id')
TRANSITION_NAME=$(echo "$TARGET_TRANSITION" | jq -r '.name')

if [ -n "$TRANSITION_ID" ]; then
  echo "✅ Found target transition: $TRANSITION_NAME (ID: $TRANSITION_ID)"
else
  echo "⚠️  No 'Done' or 'Closed' transition available for $JIRA_TICKET"
  return 1
fi

Alternative Status Handling: Some JIRA workflows use different final status names:

  • Done, Closed, Complete, Finished, Resolved
  • Use statusCategory.key == "done" to find any done-category status

Step 4: Check Current Status

Purpose: Avoid unnecessary transitions if ticket is already in target status

Tools Used: atlassian_getJiraIssue

# Get current ticket status
TICKET_DETAILS=$(atlassian_getJiraIssue \
  --cloudId "$CLOUD_ID" \
  --issueIdOrKey "$JIRA_TICKET")

CURRENT_STATUS=$(echo "$TICKET_DETAILS" | jq -r '.fields.status.name')

echo "Current status: $CURRENT_STATUS"
echo "Target status: $TRANSITION_NAME"

# Check if already in target status
if [ "$CURRENT_STATUS" = "$TRANSITION_NAME" ]; then
  echo "✅ Ticket already in target status: $TRANSITION_NAME"
  echo "No transition needed"
  return 0
fi

# Check if status category is already "done"
CURRENT_CATEGORY=$(echo "$TICKET_DETAILS" | jq -r '.fields.status.statusCategory.key')
if [ "$CURRENT_CATEGORY" = "done" ]; then
  echo "✅ Ticket already in done category: $CURRENT_STATUS"
  echo "No transition needed"
  return 0
fi

Step 5: Execute Status Transition

Purpose: Update JIRA ticket status to target status

Tools Used: atlassian_transitionJiraIssue

# Execute transition
echo "Transitioning $JIRA_TICKET from $CURRENT_STATUS to $TRANSITION_NAME..."

TRANSITION_RESULT=$(atlassian_transitionJiraIssue \
  --cloudId "$CLOUD_ID" \
  --issueIdOrKey "$JIRA_TICKET" \
  --transition "{\"id\": \"$TRANSITION_ID\"}")

# Check if transition was successful
if [ $? -eq 0 ]; then
  echo "✅ Successfully transitioned $JIRA_TICKET to $TRANSITION_NAME"
  STATUS="success"
else
  echo "❌ Failed to transition $JIRA_TICKET"
  STATUS="failed"
fi

Error Handling:

# Check for common errors
if echo "$TRANSITION_RESULT" | grep -q "permission"; then
  echo "❌ Permission denied: You don't have permission to transition this ticket"
  STATUS="permission_denied"
elif echo "$TRANSITION_RESULT" | grep -q "transition does not exist"; then
  echo "❌ Invalid transition: The selected transition is not available"
  STATUS="invalid_transition"
elif echo "$TRANSITION_RESULT" | grep -q "issue does not exist"; then
  echo "❌ Invalid ticket: $JIRA_TICKET does not exist"
  STATUS="invalid_ticket"
fi

Step 6: Add Merge Comment to JIRA

Purpose: Document the PR merge with details for traceability

Tools Used: atlassian_addCommentToJiraIssue

# Get PR details
PR_NUMBER=$(gh pr view --json number --jq '.number')
PR_URL=$(gh pr view --json url --jq '.url')
PR_TITLE=$(gh pr view --json title --jq '.title')
MERGED_BY=$(gh pr view --json mergedBy --jq '.mergedBy.login')
MERGED_AT=$(gh pr view --json mergedAt --jq '.mergedAt')

# Extract commit details
COMMIT_HASH=$(git log -1 --pretty=%H)
COMMIT_MSG=$(git log -1 --pretty=%s)
COMMIT_AUTHOR=$(git log -1 --pretty=%an)
COMMIT_DATE=$(git log -1 --date=iso8601 --pretty=%aI)

# Create comment body
COMMENT_BODY=$(cat <<EOF
## Pull Request Merged

**PR**: #$PR_NUMBER - $PR_TITLE
**URL**: $PR_URL
**Merged By**: @$MERGED_BY
**Merged At**: $MERGED_AT

### Status Update
✅ Ticket transitioned from **$CURRENT_STATUS** to **$TRANSITION_NAME**

### Merge Details
- **Commit**: \`$COMMIT_HASH\`
- **Author**: $COMMIT_AUTHOR
- **Date**: $COMMIT_DATE
- **Message**: $COMMIT_MSG

### Files Changed
\`\`\`
$(git diff --stat HEAD~1 HEAD)
\`\`\`

### Work Completed
The pull request has been successfully merged and the ticket has been closed.
EOF
)

# Add comment to JIRA ticket
atlassian_addCommentToJiraIssue \
  --cloudId "$CLOUD_ID" \
  --issueIdOrKey "$JIRA_TICKET" \
  --commentBody "$COMMENT_BODY"

if [ $? -eq 0 ]; then
  echo "✅ Added merge comment to $JIRA_TICKET"
else
  echo "⚠️  Failed to add comment to $JIRA_TICKET"
fi

Step 7: Provide Summary

Purpose: Display clear summary of transition operation

echo ""
echo "=========================================="
echo "📊 JIRA Status Update Summary"
echo "=========================================="
echo ""

if [ "$STATUS" = "success" ]; then
  echo "✅ Status Update: SUCCESS"
  echo ""
  echo "🎫 Ticket: $JIRA_TICKET"
  echo "🔄 Transition: $CURRENT_STATUS → $TRANSITION_NAME"
  echo "👤 Transitioned By: $COMMIT_AUTHOR"
  echo "📅 Date: $COMMIT_DATE"
  echo ""
  echo "🔗 JIRA Ticket: https://<company>.atlassian.net/​browse/​$JIRA_TICKET"
  echo "🔗 PR: $PR_URL"
elif [ "$STATUS" = "permission_denied" ]; then
  echo "❌ Status Update: FAILED - Permission Denied"
  echo ""
  echo "⚠️  You don't have permission to transition this ticket"
  echo "🔗 JIRA Ticket: https://<company>.atlassian.net/​browse/​$JIRA_TICKET"
  echo ""
  echo "💡 Solution: Contact your JIRA administrator for permissions"
elif [ "$STATUS" = "invalid_transition" ]; then
  echo "❌ Status Update: FAILED - Invalid Transition"
  echo ""
  echo "⚠️  The selected transition is not available for this ticket"
  echo "🔗 JIRA Ticket: https://<company>.atlassian.net/​browse/​$JIRA_TICKET"
  echo ""
  echo "💡 Solution: Check available transitions and try a different status"
elif [ "$STATUS" = "invalid_ticket" ]; then
  echo "❌ Status Update: FAILED - Invalid Ticket"
  echo ""
  echo "⚠️  The JIRA ticket '$JIRA_TICKET' does not exist"
  echo ""
  echo "💡 Solution: Verify the ticket key is correct"
fi

echo "=========================================="
echo ""

Integration with Other Skills

Skills That Should Use jira-status-updater

  • pr-creation-workflow: Update JIRA status after PR merge
  • git-pr-creator: Optionally update JIRA status after PR merge
  • jira-git-workflow: Document the complete workflow including status updates
  • nextjs-pr-workflow: Update JIRA status after Next.js PR merge

Integration Pattern

# In pr-creation-workflow or git-pr-creator
# After successful PR merge:

# Step 1: Check if JIRA integration is enabled
if [ "$ENABLE_JIRA_STATUS_UPDATE" = "true" ]; then

  # Step 2: Call jira-status-updater
  jira-status-updater \
    --ticket "$JIRA_TICKET" \
    --cloudId "$CLOUD_ID" \
    --target-status "Done"

  # Step 3: Check result
  if [ $? -eq 0 ]; then
    echo "✅ JIRA ticket status updated successfully"
  else
    echo "⚠️  JIRA ticket status update failed"
  fi
fi

Best Practices

Transition Detection

  • Dynamic Query: Always query available transitions, don't hardcode status names
  • Status Category: Use statusCategory.key == "done" to find any done-category status
  • Multiple Targets: Support "Done", "Closed", and other final status names
  • Priority Order: Prefer "Done" → "Closed" → Any done-category status

Error Handling

  • Current Status Check: Always check current status before transitioning
  • Graceful Failure: Don't fail entire workflow if status update fails
  • Clear Messages: Provide specific error messages for different failure modes
  • User Guidance: Suggest next steps for common errors

Documentation

  • Comment Addition: Always add a merge comment for traceability
  • PR Details: Include PR number, URL, and merge details in comments
  • Commit Info: Add commit hash, author, and date for audit trail
  • Files Changed: Include file statistics in merge comments

Configuration

  • Enable/​Disable: Make JIRA status updates optional via configuration
  • Default Status: Allow configuration of default target status
  • Cloud ID: Support cloud ID configuration via environment variable
  • Fallback Behavior: Continue workflow even if status update fails

Common Issues

No JIRA Ticket Reference Found

Issue: Cannot extract JIRA ticket key from PR or commits

Solution:

# Ask user to specify ticket
read -p "Enter JIRA ticket key (e.g., IBIS-101): " JIRA_TICKET

# Or skip status update
read -p "Skip JIRA status update? (y/​n): " SKIP_UPDATE
if [ "$SKIP_UPDATE" = "y" ]; then
  echo "Skipping JIRA status update"
fi

Transition Not Available

Issue: Target status transition not available for ticket

Solution:

# List available transitions
echo "Available transitions:"
echo "$TRANSITIONS" | jq -r '.transitions[] | "- \(.name)"'

# Ask user to select
read -p "Select transition (or skip): " USER_TRANSITION

if [ -n "$USER_TRANSITION" ]; then
  TRANSITION_ID=$(echo "$TRANSITIONS" | jq -r ".transitions[] | select(.name == \"$USER_TRANSITION\") | .id")
else
  echo "Skipping status update"
fi

Permission Denied

Issue: User lacks permission to transition ticket status

Solution:

# Provide clear error message
echo "❌ Permission denied: You don't have permission to transition this ticket"
echo ""
echo "🔗 JIRA Ticket: https://<company>.atlassian.net/​browse/​$JIRA_TICKET"
echo ""
echo "💡 Next steps:"
echo "   1. Contact your JIRA administrator"
echo "   2. Request transition permissions for this project"
echo "   3. Manually update ticket status in JIRA"

Ticket Already Done

Issue: Ticket is already in target status

Solution:

# Skip transition but add comment
if [ "$CURRENT_STATUS" = "$TRANSITION_NAME" ]; then
  echo "✅ Ticket already in target status: $TRANSITION_NAME"
  echo "Adding merge comment only..."
  # Add merge comment without transitioning
fi

Cloud ID Not Configured

Issue: ATLASSIAN_CLOUD_ID environment variable not set

Solution:

# Try to auto-detect
if [ -z "$ATLASSIAN_CLOUD_ID" ]; then
  echo "Detecting cloud ID..."
  CLOUD_ID=$(atlassian_getAccessibleAtlassianResources | jq -r '.[0].id')
  export ATLASSIAN_CLOUD_ID="$CLOUD_ID"
  echo "✅ Detected cloud ID: $ATLASSIAN_CLOUD_ID"
fi

# Or ask user
if [ -z "$ATLASSIAN_CLOUD_ID" ]; then
  read -p "Enter Atlassian cloud ID: " CLOUD_ID
  export ATLASSIAN_CLOUD_ID="$CLOUD_ID"
fi

Troubleshooting Checklist

Before updating JIRA status:

  • JIRA ticket key is valid (e.g., IBIS-101)
  • Atlassian cloud ID is configured
  • Atlassian MCP tools are available
  • User has permission to transition tickets
  • Current status is not already target status

After updating JIRA status:

  • Status transition was successful
  • Merge comment was added to ticket
  • Ticket URL is accessible
  • Summary is displayed to user

Examples

Example 1: Successful Status Update

Scenario: PR for IBIS-101 is merged, ticket transitions from "In Progress" to "Done"

Output:

✅ Detected JIRA ticket: IBIS-101
Available transitions for IBIS-101:
- In Review → In Review
- Done → Done
- Cancel → Cancelled

Current status: In Progress
Target status: Done

Transitioning IBIS-101 from In Progress to Done...
✅ Successfully transitioned IBIS-101 to Done
✅ Added merge comment to IBIS-101

==========================================
📊 JIRA Status Update Summary
==========================================

✅ Status Update: SUCCESS

🎫 Ticket: IBIS-101
🔄 Transition: In Progress → Done
👤 Transitioned By: John Doe
📅 Date: 2024-01-26T21:30:00+08:00

🔗 JIRA Ticket: https://company.atlassian.net/​browse/​IBIS-101
🔗 PR: https://github.com/​org/​repo/​pull/​42
==========================================

Example 2: Ticket Already Done

Scenario: PR for IBIS-102 is merged, but ticket is already in "Done" status

Output:

✅ Detected JIRA ticket: IBIS-102
Current status: Done
Target status: Done

✅ Ticket already in target status: Done
No transition needed
✅ Added merge comment to IBIS-102

==========================================
📊 JIRA Status Update Summary
==========================================

✅ Status Update: SUCCESS (No Transition Needed)

🎫 Ticket: IBIS-102
🔄 Transition: Done → Done (Skipped - Already Done)
👤 By: John Doe
📅 Date: 2024-01-26T21:30:00+08:00

🔗 JIRA Ticket: https://company.atlassian.net/​browse/​IBIS-102
🔗 PR: https://github.com/​org/​repo/​pull/​43
==========================================

Example 3: Permission Denied

Scenario: User lacks permission to transition IBIS-103

Output:

✅ Detected JIRA ticket: IBIS-103
Available transitions for IBIS-103:
- In Review → In Review

Current status: In Progress
Target status: Done
⚠️  No 'Done' or 'Closed' transition available for IBIS-103

❌ Status Update: FAILED - Invalid Transition

⚠️  The selected transition is not available for this ticket
🔗 JIRA Ticket: https://company.atlassian.net/​browse/​IBIS-103

💡 Solution: Check available transitions and try a different status
==========================================

Related Skills

  • JIRA Integration:
    • jira-git-integration - Provides JIRA utilities and API tools
  • Git Frameworks:
    • pr-creation-workflow - PR creation framework (uses jira-status-updater)
    • git-pr-creator - PR creation with JIRA (uses jira-status-updater)
    • git-issue-updater - Adds progress comments to JIRA
  • JIRA Workflows:
    • jira-git-workflow - Complete JIRA ticket creation and branching workflow

References

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View