sync-jira.yml 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. name: Sync core-team issues to Jira
  2. on:
  3. issues:
  4. types: [opened, reopened, edited, labeled]
  5. permissions:
  6. issues: write
  7. contents: read
  8. jobs:
  9. sync:
  10. if: contains(github.event.issue.labels.*.name, 'core-team')
  11. runs-on: ubuntu-latest
  12. steps:
  13. - name: Create or update Jira ticket
  14. id: jira
  15. env:
  16. JIRA_EMAIL: ${{ secrets.JIRA_EMAIL }}
  17. JIRA_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
  18. JIRA_BASE: ${{ secrets.JIRA_BASE }}
  19. PROJECT_KEY: VEN
  20. run: |
  21. set -e # Exit on any error
  22. # Verify environment variables
  23. if [ -z "$JIRA_EMAIL" ] || [ -z "$JIRA_TOKEN" ] || [ -z "$JIRA_BASE" ]; then
  24. echo "Error: Required Jira environment variables are not set"
  25. exit 1
  26. fi
  27. GH_URL="https://github.com/${{ github.repository }}/issues/${{ github.event.issue.number }}"
  28. echo "GitHub URL: $GH_URL"
  29. # Test jq installation
  30. if ! command -v jq &> /dev/null; then
  31. echo "Error: jq is not installed"
  32. exit 1
  33. fi
  34. # Prepare the data with error checking
  35. SUMMARY="${{ github.event.issue.title }}"
  36. DESC="Imported from GitHub: $GH_URL"
  37. # Create the search request body
  38. SEARCH_BODY=$(jq -n --arg url "$GH_URL" --arg proj "$PROJECT_KEY" '
  39. {
  40. "jql": "project = \($proj) AND description ~ \"\($url)\""
  41. }' || {
  42. echo "Error creating search request body"
  43. exit 1
  44. })
  45. echo "Search request body: $SEARCH_BODY"
  46. # Search with JQL endpoint
  47. SEARCH_RESULT=$(curl -f -s -u "$JIRA_EMAIL:$JIRA_TOKEN" \
  48. -H "Content-Type: application/json" \
  49. -H "Accept: application/json" \
  50. --data "$SEARCH_BODY" \
  51. "$JIRA_BASE/rest/api/3/search" || {
  52. echo "Error: Jira search failed with status $?"
  53. exit 1
  54. })
  55. # Parse the key with error checking
  56. # The search endpoint returns issues in an issues array
  57. KEY=$(echo "$SEARCH_RESULT" | jq -r 'if .issues[0] then .issues[0].key else empty end' || {
  58. echo "Error parsing search result"
  59. exit 1
  60. })
  61. echo "Found existing key: $KEY"
  62. if [ -z "$KEY" ]; then
  63. echo "No existing ticket found, creating new one"
  64. BODY=$(jq -n --arg summary "$SUMMARY" --arg url "$GH_URL" --arg proj "$PROJECT_KEY" '
  65. {
  66. "fields": {
  67. "project": {
  68. "key": $proj
  69. },
  70. "summary": $summary,
  71. "description": {
  72. "type": "doc",
  73. "version": 1,
  74. "content": [
  75. {
  76. "type": "paragraph",
  77. "content": [
  78. {
  79. "type": "text",
  80. "text": "Imported from GitHub: "
  81. },
  82. {
  83. "type": "inlineCard",
  84. "attrs": {
  85. "url": $url
  86. }
  87. }
  88. ]
  89. }
  90. ]
  91. },
  92. "issuetype": {
  93. "name": "Task"
  94. }
  95. }
  96. }' || {
  97. echo "Error creating request body"
  98. exit 1
  99. })
  100. echo "Creating ticket with body: $BODY"
  101. # Create with error checking
  102. CREATE_RESULT=$(curl -f -s -u "$JIRA_EMAIL:$JIRA_TOKEN" \
  103. -H "Content-Type: application/json" \
  104. -H "Accept: application/json" \
  105. --data "$BODY" "$JIRA_BASE/rest/api/3/issue" || {
  106. echo "Error: Jira create failed with status $?"
  107. exit 1
  108. })
  109. echo "Create result: $CREATE_RESULT"
  110. KEY=$(echo "$CREATE_RESULT" | jq -r .key || {
  111. echo "Error parsing create result"
  112. exit 1
  113. })
  114. echo "Created new key: $KEY"
  115. fi
  116. if [ -z "$KEY" ]; then
  117. echo "Error: Failed to get a valid Jira key"
  118. exit 1
  119. fi
  120. echo "Final key value: $KEY"
  121. echo "key=$KEY" >> $GITHUB_OUTPUT
  122. - name: Record the mapping on the GH issue
  123. uses: actions/github-script@v7
  124. env:
  125. JIRA_KEY: ${{ steps.jira.outputs.key }}
  126. with:
  127. script: |
  128. const issue_number = context.issue.number;
  129. const owner = context.repo.owner;
  130. const repo = context.repo.repo;
  131. const jira = process.env.JIRA_KEY;
  132. const body = `🔗 Linked to Core Team Jira ticket **${jira}**`;
  133. const {data:comments} = await github.rest.issues.listComments({owner,repo,issue_number});
  134. const existing = comments.find(c=>/Linked to Core Team Jira ticket/i.test(c.body));
  135. if (existing) {
  136. await github.rest.issues.updateComment({owner,repo,comment_id:existing.id,body});
  137. } else {
  138. await github.rest.issues.createComment({owner,repo,issue_number,body});
  139. }