Format code via GitHub Actions
Hi
บทความในวันนี้จะเป็นเรื่องของ github actions ครับ ถ้าเพื่อน ๆ ได้ใช้ github เป็นที่เก็บโค้ดก็น่าจะเคยได้ยินบริการตัวนี้จาก github มาบ้าง github actions เป็นบริการสำหรับการทำ CI/CD pipeline ข้อดีของมันคือเราสารถใช้ได้ฟรีได้ประมาณนึง แล้วก็เราไม่จำเป็นต้องลงอะไรให้วุ่นวาย ให้ github เป็นคนจัดการให้ทั้งหมด ซึ่งในบทความนี้จะแชร์เรื่องว่าถ้าเราอยากจะ format code ให้อัตโนมัติในทุก ๆ pull request โดยอัตโนมัติ เพื่อที่ให้โค้ดของเรามีการ indent ตาม config ของเราอยู่เสมอ
ตัวอย่างในบทความนี้จะใช้ scala3 โดยใช้ library scalafmt ในการ format code ส่วน IDE จะเป็น IntelliJ Idea CE
สิ่งที่ต้องเตรียม
- IntelliJ Idea CE
- java
- sbt
- บัญชี github
เตรียมโค้ดที่ใช้ทดสอบ
-
เปิดโปรแกรม IntelliJ Idea แล้วสร้างโปรเจกต์ตามนี้
-
สร้างไฟล์
Main.scalaไว้ในโฟล์เดอร์srcแล้วพิมพ์โค้ดตามนี้object Main extends App { val data = Data("Hello scala") println(data.content) } case class Data(content: String) -
สร้างไฟล์
plugins.sbtที่โฟล์เดอร์projectเพิ่ม plugin scalafmt ตามนี้addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") -
สร้างไฟล์
.scalafmt.confไว้ที่ root โฟล์เดอร์ ใส่ config ตามนี้version = 3.5.9 runner.dialect = scala3 maxColumn = 100 -
จากนั้นให้ลองเทสโดยการแก้ format โค้ดใน
Main.scalaตามนี้object Main extends App { val data = Data("Hello scala") println(data.content) } case class Data( content: String) -
เปิด sbt shell ขึ้นมาโดยใช้คำสั่ง
scamafmtAllหรือถ้าไม่ได้ใช้ sbt shell ใช้เป็น terminal ธรรมดา ให้ใช้คำสั่งsbt scalafmtAll -
ลองเข้าไปดูไฟล์
Main.scalaอีกรอบ จะได้ผลลัพธ์ตามนี้object Main extends App { val data = Data("Hello scala") println(data.content) } case class Data(content: String) -
จากนั้นให้แก้ไฟล์ให้ไปอยู่ในรูปแบบเดิมก่อนที่จะถูก format
-
ในการที่เราจะใช้ github actions นั้น เราต้องสร้างโฟล์เดอร์
.githubไว้ที่ root โฟล์เดอร์แล้วก็ข้างในให้สร้างโฟล์เดอร์workflows
-
จากนี้นให้สร้างไฟล์
pr_build.ymlไว้ในโฟล์เดอร์workflowsแล้วใส่โค้ดตามนี้name: pr_build on: pull_request: branches: [ main ] jobs: formatCode: runs-on: ubuntu-latest if: ${{ !contains(github.actor, 'github-actions[bot]') }} # เพื่อไม่ให้ commit ของ bot มารัน job ตัวนี้อีก steps: - uses: actions/checkout@v3 with: ref: ${{ github.head_ref }} - name: Set up JDK 20 uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '20' - name: Set Git Username run: | git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" - name: Format code run: | sbt scalafmtAll - name: Check for changes run: | if git diff-index --quiet HEAD; then echo "IS_CHANGED=false" >> $GITHUB_ENV else echo "IS_CHANGED=true" >> $GITHUB_ENV fi - name: Push code if format is needed if: ${{ env.IS_CHANGED == 'true' }} run: | git add --all git commit -m ":recycle: format code" git push origin
จนถึงขั้นตอนนี้เราก็มีโค้ดที่เตรียมพร้อมสำหรับที่จะใช้ใน github actions แล้ว
สร้างโปรเจกต์บน github
-
ไปที่เว็บ github ล็อคอินบัญชีของเรา แล้วสร้างโปรเจกต์ชื่อว่า
scalafmt-testแล้วก็ให้เพิ่มREADME.mdไฟล์ไปด้วยเลย -
จากนั้นไปที่
Settingsแล้วเลือกไปที่Actions -> General
-
อนุญาติ permission ให้
GITHUB_TOKENสามารถ write ไปยัง reporisitory ของเราได้
-
จากนั้นกลับมาที่โค้ดของเรา ให้เชื่อมโค้ดเราเข้ากับ repo ที่เราสร้างขึ้น จากนั้นให้สร้าง branch ที่ชื่อว่า
feature/github-actions -
แล้วก็ให้ push โค้ดของเราขึ้น github ไป
ถ้าเห็นว่าไฟล์ที่จะ push ขึ้นไปมีเยอะผิดปกติ ให้เพื่มไฟล์
.gitignoreไว้ที่ root แล้วใส่ชื่อไฟล์ตามด้านล่างนี้.DS_Store *.class *.log *~ # sbt specific dist/* target/ lib_managed/ src_managed/ project/boot/ project/plugins/project/ project/local-plugins.sbt .history .bsp # Scala-IDE specific .scala_dependencies .cache .classpath .project .settings classes/ # idea .idea .idea_modules /.worksheet/ # Dotty-IDE .dotty-ide-artifact .dotty-ide.json # Visual Studio Code .vscode .env src/main/resources/application.local.conf -
จากนั้นไปที่เว็บ github ของเรา ให้ไปสร้าง pull request เป็นชื่ออะไรก็ได้ แล้วก็รอดูผลลัพธ์
จะเห็นได้ว่าถ้าตัว github actions รันเสร็จแล้ว มันจะมี commit ให้เพิ่มขึ้นมา เป็นอันว่าเสร็จเรียบร้อย
จากนี้ทุก ๆ pull request ที่มีการสร้างขึ้นมาก็จะถูก format ตาม config ของเราตลอดเวลา