[Gitlab] .gitlab-ci.yml 스크립트 작성 중급 (feat. stages, SonarQube, Jira)

2024. 10. 21. 23:24IT/Git

반응형

오늘은 저번에 이어 .gitlab-ci.yml 스크립트 작성을 진행해보자.
이번에는 stages, needs 를 활용한 깃랩 CI 스크립트이며,
소나큐브 코드 품질 분석과 그 결과물에 이슈가 있을 경우 지라 티켓 발행까지 하는 스크립트이다.

대부분의 내용을 스크립트의 주석을 달아두었으니, 충분히 이해하고 실행할 수 있을 것으로 보인다.


 

stages:
  - sonarqube_analysis # 1. 소나큐브 실행
  - create_jira_ticket # 2. 소나큐브 이슈 검출 시 지라 티켓 생성

sonarqube-check:
  stage: sonarqube_analysis
  tags:
    - sonarqube-test
  image: 
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""] 
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"  # 캐시 위치
    GIT_DEPTH: "0"  # 모든 브랜치를 가져옴
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script: 
    - sonar-scanner
  allow_failure: true
  rules: # 깃랩 master 브랜치에 MR 진행 시 소나큐브 동작하는 조건 
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'

create-jira-ticket:
  stage: create_jira_ticket
  tags:
    - sonarqube-test
  script:
    - |
      # SonarQube API로부터 BLOCKER와 CRITICAL 이슈를 가져옵니다.
      ISSUES=$(curl -s "http://your_sonarqube_url:9000/api/issues/search?pageSize=500&componentKeys=TonyLee_sonarqubetest_AZFKM9vjWFDDsiLE2qFp&severities=BLOCKER,CRITICAL&types=BUG,VULNERABILITY" | tr -d '\r')

      # 이슈가 있는지 확인
      ISSUE_COUNT=$(echo "$ISSUES" | jq -r '.total | tonumber?')

      # ISSUE_COUNT가 유효한 숫자인지 확인하고, 빈 경우 0으로 처리
      if [[ "$ISSUE_COUNT" =~ ^[0-9]+$ ]]; then
          echo "Parsed issue count: $ISSUE_COUNT"
      else
          echo "Invalid issue count or not an integer"
          ISSUE_COUNT=0
      fi

      if [ "$ISSUE_COUNT" -gt 0 ]; then
        echo "$ISSUE_COUNT 개의 Blocker 및 Critical 이슈가 발견되었습니다. 개별 지라 티켓을 생성합니다."

      # JSON 데이터를 jq로 직접 처리하여 변수에 할당
      echo "$ISSUES" | jq -c '.issues[]' | while IFS= read -r issue; do
          # 각 필드를 안전하게 추출하여 바로 변수에 할당
          MESSAGE=$(echo "$issue" | jq -r '.message // "No message available"')
          SEVERITY=$(echo "$issue" | jq -r '.severity // "Unknown severity"')
          COMPONENT=$(echo "$issue" | jq -r '.component // "Unknown component"')
          LINE=$(echo "$issue" | jq -r '.line // "N/A"')
          
          # COMPONENT 에서 ':' 기준으로 오른쪽 값만 추출
          COMPONENT=$(echo "$COMPONENT" | cut -d ':' -f 2-)

          # 각 필드 출력 (디버깅용)
          echo "Message: $MESSAGE"
          echo "Severity: $SEVERITY"
          echo "Component: $COMPONENT"
          echo "Line: $LINE"
          echo "----------------------------------------"

          # 각 이슈에 대해 Jira 티켓 생성
          curl -X POST \
          -H "Authorization: Bearer YOURTOKEN" \
          -H "Content-Type: application/json" \
          -d "$(jq -n --arg severity "$SEVERITY" --arg message "$MESSAGE" --arg component "$COMPONENT" --arg line "$LINE" '{
              fields: {
                project: { key: "yourproject" },
                summary: ("[\($severity)] \($message) (컴포넌트: \($component), 라인: \($line))"),
                description: ("Detected \($severity) issue:\nMessage: \($message)\nSeverity: \($severity)\nComponent: \($component)\nLine: \($line)"),
                issuetype: { id: 10002 }
              }
          }')" \
          https://your_jira_url/rest/api/2/issue

      done
      
      else
        echo "Blocker 또는 Critical 이슈가 없습니다. 지라 티켓을 생성하지 않습니다."
      fi

  only:
    - master

 

반응형