ทดลองใช้ GitHub Actions

GitHub Actions เป็นฟีเจอร์ด้าน Continuous Integration ของ Github ก็คือ เราสามารถลำดับของการกระทำบางอย่างกับโค๊ดหลังจากที่เกิดเหตุการบางอย่างขึ้นบน repository เช่น

  • มีโค๊ดใหม่ถูก push เข้าไปใน repository
  • มี tag ใหม่ถูกสร้างขึ้น
  • มีคนสร้าง pull request

ซึ่งเมื่อเกิดเหตุการดังกล่าว เราก็อาจจะอยากทำอะไรสักอย่างกับโค๊ดหรือโปรเจค เช่น

  • ทดลอง build โค๊ด เพื่อดูว่าเกิด build error หรือ warning
  • ทดลองรันโปรแกรมทดสอบ หาว่ารันได้อย่างที่ควรจะเป็นหรือไม่ มีพฤติกรรมที่ไม่เหมาะสมเกิดขึ้นหรือเปล่า
  • ทำ static analysis หาปัญหาที่อาจจะมีในโค๊ด
  • ส่งโค๊ดไปรันบนเซิร์ฟเวอร์
  • อะไรก็แล้วแต่เท่าที่จะจิตนาการณ์ได้

การกระทำที่ว่านี้ใน GitHub Actions จะเรียกว่า job ครับ

โดยที่เราสามารถกำหนดชุดของการกระทำเป็นชุด ๆ เพื่อให้ทำเมื่อเกิดเหตุการณ์นั้นเกิดขึ้นในรูปแบบที่เรียกว่า workflow โดยที่เราจะกำหนดได้ว่า workflow นั้น ๆ จะทำงานก็ต่อเมื่อเกิดเหตุการณ์อะไรขึ้นกับโปรเจค

ยกตัวอย่าง workflow #1

เมื่อมีคน push code ขึ้นไปใน main branch ให้ทำการ

  1. คอมไพล์โปรแกรมบน Linux
  2. เตรียมข้อมูลสำหรับใช้รันชุดทดสอบ
  3. รันชุดทดสอบ
  4. ติด tag latest ที่ commit ที่ใหม่ที่สุดใน branch
  5. เตรียม docker image
  6. อัพโหลดโปรแกรมที่ release ของ github
  7. สั่งให้ development server ทำการสร้าง container ใหม่โดยรันโปรแกรมเวอร์ชั่นล่าสุด

ทั้งนี้ workflow สามารถทำงานหลาย ๆ job พร้อม ๆ กัน แต่เราสามารถกำหนดว่า job ไหนจะต้องทำหลังจาก job ไหน อย่างเช่นบน workflow ข้างบน ผมอาจจะทำ job #1 กับ #2 พร้อมกันได้ แต่ job #3 จะต้องรอ #1 กับ #2 ให้เสร็จก่อน เราก็กำหนด dependency ไปว่า #3 depend on #1 และ #2 เป็นต้น

แต่ละ job ใน workflow เราสามารถใช้ job ที่มีผู้สร้างเอาไว้อยู่แล้ว หรือกำหนดลำดับการทำงานของแต่ละ job ได้ด้วย เช่นการรันชุดทดสอบผมอาจจะกำหนด job นี้ว่า

  1. สร้าง environment variable จำวนหนึ่ง
  2. ติดโปรแกรม database server ใน virtual environment
  3. รัน database server ใน VE
  4. import test data ที่ใช้ทดสอบเข้าไป
  5. รันชุดทดสอบ
  6. อัพโหลดผลการทดสอบขึ้นไปบน server

ทั้งนี้ในหนึ่งโปรเจคอาจจะมีหลาย workflow ได้ เช่นอาจจะมี workflow หนึ่งสำหรับสร้าง Windows Build อีกตัวหนึ่งสำหรับสร้าง MacOS Build อะไรแบบนี้ GitHub สามารถรันหลาย ๆ workflow พร้อม ๆ กันได้ เพื่อลดเวลาที่ใช้โดยรวมครับ ตัว workflow นี่เราจะเขียนด้วยภาษา yaml ซึ่งจะต้องอยู่ใน directory .github/workflows ภายในโปรเจคเรา ข้างล่างเป็น workflow นึงที่ผมเขียนใช้กับโปรเจคที่ผมเขียนเล่น ๆ อยู่ตอนนี้ครับ

name: main
on: 
  push:
    branches:
      - main

jobs:
  build:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v2
        with:
          submodules: true
      - run: "Get-ChildItem Env:"
      - name: Create output dir
        run: mkdir out

      - name: Configure the project.
        run: cmake -D CMAKE_TOOLCHAIN_FILE=$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake $env:GITHUB_WORKSPACE
        working-directory: out

      - name: Build the project.
        run: cmake --build out --config Release

      - name: Copy font files.
        run: xcopy fonts out\Release\fonts\*

      - uses: EndBug/latest-tag@latest

      - uses: actions/upload-artifact@v2
        with:
          name: windows
          path: out/Release

      - name: "Create latest release file"
        run: |
          Get-ChildItem -Path out\Release | Compress-Archive -DestinationPath windows-latest.zip
      - name: Release
        uses: softprops/action-gh-release@v1
        with:
          body: |
            This is the latest, the bleeding edge. Might not work properly and might harm your system. Use with care.
          files: windows-latest.zip
          name: Latest
          prerelease: true
          tag_name: latest
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

จุดเด่นอันหนึ่งของ GitHub Actions คือตัว job จะรันบน Virtual Environment ที่รัน OS ได้หลายแบบ (มี Windows, Linux และ MacOS ให้เลือกในตอนนี้) การที่่สามารถเลือก OS ได้นั้นทำให้เราสามารถที่จะสร้าง job ที่จำเป็นจะต้องใช้ OS เฉพาะทางเท่านั้นถึงจะทำได้ เช่นการ build Mac OS application หรือการทดสอบ web application บน windows server เป็นต้น ทำให้เรามีความสะดวกในการทำงานแบบหลายแพลตฟอร์ม ไม่จำเป็นจะต้องหาเครื่อง host มาทำงานดังกล่าวเอง

อ่านมาจนถึงตรงนี้แล้วหลายคนคงสงสัยว่า ฟีเจอร์เทพขนาดนี้ แล้วราคามันจะแพงหรือไม่ สำหรับโปรเจคที่เป็น Open Source เราสามารถใช้งาน GitHub Actions ได้ฟรีครับ ส่วนพวก Private Repository จะมีค่าใช้จ่าย (แพงอยู่เหมือนกัน) อันนี้ลองศึกษาหาข้อมูลเพิ่มดูครับ

ส่วนความไม่สะดวกของ GitHub Actions ตอนนี้น่าจะเป็นเรื่องที่เราไม่สามารถทดสอบตัว workflow ในเครื่องเราเองได้ ดังนั้นกว่าที่จะมี workflow ที่ใช้งานได้จริงก็อาจจะต้องรันบน server หลายครั้งอยู่ครับ อันนี้จะไม่สะดวกเท่าของ CircleCI ที่สามารถทดสอบในเครื่องตัวเองได้เลย

สำหรับคนที่สนใจลองศึกษาเพิ่มบนเว็บของ GitHub ดูครับ