sync-jira.yml 5.5 KB

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