KtLint + Spotless + GitHub Actions로 PR에 sugggested change

조금 30분 정도로 쓴 작은 재료로 죄송합니다만, 몹시 간단하고, 편리하기 때문에, 어드벤트 캘린더로 소개합니다.

Android Studio의 자동 포맷이라면 KtLint에서 지적되는 것을 수정할 수 없고, Formatter를 커밋 전이나 빌드시에 달리는 것도 코드량에 비례하여 느려질 것 같고, 또 변경한 곳만 포맷시키고 싶습니다만 잘 할 수 없습니다. 커밋마다 시간이 걸릴 것 같고 미묘하고 뭔가 해결책을 찾고있었습니다.
이것을 조사 시작해 30분 정도로 할 수 있어 굉장히 간단하게 기계적으로 리뷰시킬 수 있으므로, 조금 시험해 보세요.

들여 쓰기를 수정하는 suggested change 예제


사용하는 도구



Spotless
변경된 파일을 감지하고 Formatter를 호출하거나 다양한 기능이 있습니다. (JetNews 등 Google의 OSS 등에서도 사용되고 있습니다.)

KtLint
Kotlin에서 자주 사용되는 Formatter입니다. Spotless와 함께 작동할 수 있습니다.

reviewdog
PR에 리뷰 코멘트를 해주는 툴입니다. 최근 git diff에서 변경이 나오는 부분을 Suggested Change로 검토할 수 있는 기능이 추가되었습니다.

이 세 가지를 함께 사용하여 변경된 파일을 포맷하고 변경 사항을 sugggested change 할 수 있습니다.

절차



먼저 Spotless + KtLint를 소개합니다.
plugins {
    id 'com.diffplug.spotless' version '5.7.0'
}

allprojects {
    repositories {
...
    }
}

subprojects {
    repositories {
        google()
        jcenter()
    }

    apply plugin: 'com.diffplug.spotless'
    spotless {
        kotlin {
            target '**/*.kt'
            targetExclude("$buildDir/**/*.kt")
            targetExclude('bin/**/*.kt')

            ktlint("0.39.0")
        }
    }
}

그리고는 다음을 .github/workflows/review-suggest.yml 등에 저장합니다.
GITHUB_TOKEN은 마음대로 GitHub Actions가 제공하므로 다른 일은 없습니다.
여기서는 reviewdog/action-suggester를 사용하고 있습니다.
name: reviewdog-suggester
on: [pull_request]
jobs:
  kotlin:
    name: runner / suggester / spotless
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-java@v1 # JDK 11が必要なければ消してください
        with:
          java-version: '11'
      - run: ./gradlew spotlessKotlinApply
      - uses: reviewdog/action-suggester@v1
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          tool_name: spotless

아래에서 포맷을 걸고
./gradlew spotlessKotlinApply

아래에서 reviewdog를 사용하여 차이를 주석 처리하면됩니다. 즉 차분만 있으면 리뷰 시킬 수 있으므로, 여러가지 포매터에 사용할 수 있어 편리합니다.
uses: reviewdog/action-suggester@v1

이제 댓글을 달 수 있었습니다. GitHub Actions에서 reviewdog를 사용하는 것에 대해 보안 등 조금 신경이 쓰이는 곳은 있습니다만, reviewdog의 작가 분은 이전에 Google에는 있는 블로그등을 쓰고 있어, 비교적 신원을 알고 있는 분이므로 안심하고 사용할 수 있습니다.

로컬에서 커밋하기 전에 포맷하는 방법?



아무것도 생각하지 않고 ./gradlew spotlessApply 뿐이라면 전부의 소스 코드를 포맷 걸어 버립니다.

spotless에는 ratchet이라는 편리한 기능이 있으며, 다음과 같이 ratchetFrom에서 브랜치를 지정해 두고, ./gradlew spotlessApply 편리합니다.
spotless {
    ratchetFrom 'origin/master'

다만 이 기능을 GitHub Actions에서도 사용하는 형태가 되므로, yaml 파일에 checkout을 추가해 한 번 master를 체크아웃하고 나서 필요한 브랜치에 체크아웃 해 이용할 필요가 있습니다. 이것을 하지 않으면 origin/master가 존재하지 않는 형태로 빌드가 실패합니다.
      - uses: actions/checkout@v2
        with:
          ref: master # 一度masterでcheckoutする
      - uses: actions/checkout@v2 # 目的のブランチでcheckoutする

좋은 웹페이지 즐겨찾기