Coding Gun

Integration With Gitlab

SonarQube ถือว่าเป็นเครื่องมือที่ต้องมีใน CI/CD pipelines แทบจะทุกยี่ห้อ ซึ่ง gitlab จะเป็นหนึ่งใน CI/CD pipeline ยอดนิยม และในบทความนี้ผมจะพาทุกท่านไปดูวิธีการสร้าง pipeline บน gitlab กัน ในการ scan source code ด้วย sonar scanner นั้นจะต้องทำตามขั้นตอนต่างๆ ดังนี้

  1. ประกาศตัวแปรเพื่อสร้าง connection ไปยัง sonarqube server
  2. สร้างไฟล์ .gitlab-ci.yml และใส่ job ที่ run sonar scanner เข้าไป

ประกาศตัวแปร

เราต้องประกาศตัวแปร 2 ตัวเพื่อสร้าง connection ไปยัง sonarqube server

  1. ประกาศตัวแปร SONAR_TOKEN: เราจะนำ token ที่ได้จาก sonarqube server มาใส่ไว้ในตัวแปรนี้ ซึ่งตอนที่เรา set ค่าตัวแปร SONAR_TOKEN เราจะต้อง
    • เอา checkbox หน้าคำว่า Protected ออกเพราะ protected หมายถึงใช้ได้แค่ protected branch เท่านั้นแต่ SONAR_TOKEN ควรจะใช้ได้กับทุกๆ branch
    • check หน้าคำว่า Masked หมายถึงตัวแปรนี้ห้าม show ออกมาใน log เด็ดขาดเพราะเป็น sensitive data
  2. ประกาศตัวแปร SONAR_HOST_URL: เป็น URL ที่ชี้ไปยัง sonarqube server ซึ่งขึ้นอยู่กับ network ที่เราใช้ link ระหว่าง sonarqube กับ gitlab ว่าใช้วิธีไหน อาจเป็น localhost, docker network หรือ domain แบบปกติก็ได้ สิ่งที่ต้องทำตอน set ค่าตัวแปร SONAR_HOST_URL จะคล้่ายๆกับตอน set ค่า SONAR_TOKEN
    • เอา checkbox หน้าคำว่า Protected ออกเหมือนกับตัวแปร SONAR_TOKEN
    • ไม่ต้อง check หน้า Masked เพราะ URL ไม่ใช่ sensitive data เป็นข้อมูลที่เปิดเผยได้

ใส่ SonarScanner เข้าไปใน Pipeline

เราจะใส่ sonarqube-check เข้าไปใน build stage โดยสร้างไฟล์ .gitlab-ci.yml แล้วใส่เนื้อหาด้านล่างนี้ลงไป ถ้ามีไฟล์อยู่แล้วให้แทรกเข้าไปล่างสุดได้เลย ที่สำคัญคือต้องระวังอย่าให้หน้าคำว่า sonarqube-check มีย่อหน้า

sonarqube-check:
  stage: build
  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 -Dsonar.qualitygate.wait=true
  allow_failure: true

ต่อไปเราจะมาดูกันว่า config ในแต่ละบรรทัดนั้นมีความหมายยังไงกันบ้าง

1
2
3
4
5
6
sonarqube-check:
  stage: build
  image:
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""]
  ...

ใน block นี้จะเป็นการเรียกใช้ sonar-scanner-cli ผ่านทาง docker โดยที่ gitlab จะทำการ pull source code ไปไว้ใน image ให้โดยอัตโนมติ สิ่งที่ต้องแก้ไขมีเพียงเอา entrypoint ที่เป็น default ของ image ตัวนี้ออก เพราะ gitlab runner จะต้อง attach เข้าไปใน container ดังนั้นสิ่งที่เป็น entrypoint ของ image ที่จะนำมาใช้งานกับ gitlab runner ได้ต้อง return shell ออกมาเท่านั้น(เป็น prompt ให้เราส่ง command เข้าไปได้) แต่ใน entrypoint ของ sonar-scanner-cli เป็นคำสั่ง sonar-scanner ซึ่งไม่ได้ return shell ออกมา ดังนั้นเราเลยต้อง override entrypoint ของ image sonarsource/sonar-scanner-cli:latest

entrypoint เป็นคำสั่งที่จะถูกเรียก docker run ดังนั้นพอกำหนด entrypoint เป็น [""] แบบในบรรทัดที่ 5 คำสั่งนี้ก็จะไม่ถูกเรียกใช้งาน

1
2
3
4
5
6
sonarqube-check:
  stage: build
  ...
  script:
    - sonar-scanner -Dsonar.qualitygate.wait=true
  allow_failure: true

ในส่วนของ script เราจะกำหนด parameter sonar.qualitygate.wait=true หมายถึง เราจะรอผลลัพธ์กลับมาจาก sonarqube server ว่า source code ชุดนี้ผ่าน quality gate(เงื่อนไขที่เรากำหนดบน sonarqube server ว่าผ่านหรือไม่ผ่าน) หรือไม่

ดังนั้นในบรรทัดที่ 6 จะเป็นการบอก pipeline ว่าไม่ว่าจะผ่านหรือไม่ผ่าน quality gate ก็ตามให้ไป run job ใน stage ต่อไปได้เลย ซึ่งโดยปกติแล้ว gitlab จะขึ้น stage ใหม่ได้ต้องไม่มี job ใน stage ก่อนหน้า fail เด็ดขาด

เราสามารถเลือกได้ว่าจะให้ทำการ scan source code ในทุกๆ branch หรือจะ scan เฉพาะบาง branch เท่านั้น ลองอ่นเพิ่มเติมเรื่อง การใช้ only และ except

sonarqube-check:
    ...
    only:
    - merge_requests
    - master

จากตัวอย่างนี้ sonarqube จะทำงานเฉพาะตอน push code เข้า master branch และตอนที่สั่ง merge request เท่านั้น

หลังจากเข้าใจขั้นตอนต่างๆในบทความนี้แล้ว เราสามารถเลือกปรับแต่งและนำ sonar scanner ไปไว้ใน pipeline ของเราได้เลย หวังว่าเราจะมี source code ที่มีคุณภาพดีขึ้นกันทุกคน

อ่านต่อเพิ่มเติมได้ที่

Phanupong Permpimol
Follow me