FOSS開発で細かいやらかしを積み上げてきたのでまとめる。
テストの失敗原因レポートをartifactとしてアップロードしそこねる
actions/upload-artifactを使ってテストレポートをartifactとしてアップロードする際、以下の書き方だと失敗する。
# bad - run: | ./gradlew test --no-daemon --stacktrace - uses: actions/upload-artifact@v2 with: name: reports path: build/reports
これはテストが失敗した時点で後続のstepsが実行されなくなるため。明示的に失敗時でもアップロードされるように指示する必要がある。
# bad - run: | ./gradlew test --no-daemon --stacktrace - uses: actions/upload-artifact@v2 if: always() # this config is necessary to upload reports in case of build failure with: name: reports path: build/reports
forkからのPRではGITHUB_TOKENを除くsecretsを参照できない
secretsの存在を前提にしているコードがあると、forkからPRをもらったときにビルドが通らなくなる。
# bad - name: Decrypt file env: GPG_SECRET_PASSPHRASE: ${{ secrets.GPG_SECRET_PASSPHRASE }} run: | gpg --quiet --batch --yes --decrypt --passphrase="$GPG_SECRET_PASSPHRASE" --output decrypted encrypted # -> gpg: missing argument for option "--passphrase="
後述する方法でsecretsが空かどうか確認する必要がある。
if では $VAR で環境変数を参照できない
if
で書くのはbashじゃくてexpressionなので、run
に書くのと同じノリでやると失敗する。
# bad - name: Run SonarQube Scanner env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }} if: ${{ $SONAR_LOGIN != "" }} run: | ./gradlew sonarqube -Dsonar.login=$SONAR_LOGIN --no-daemon
正しくはenv
コンテキストを参照する(なお${{ .. }}
で囲むのは必須ではない)か、
# good - name: Run SonarQube Scanner env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }} if: env.SONAR_LOGIN != "" run: | ./gradlew sonarqube -Dsonar.login=$SONAR_LOGIN --no-daemon
bashで統一して読みやすくしたいなら run
の中で判定する。
# good - name: Run SonarQube Scanner env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }} run: | if [ "$SONAR_LOGIN" != "" ]; then ./gradlew sonarqube -Dsonar.login=$SONAR_LOGIN --no-daemon fi
gradleで環境変数があるときだけ特定タスクを実行する場合は、こういう書き方もできるらしい。シンプル。
- name: Run SonarQube Scanner env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }} run: | ./gradlew spotlessCheck build smoketest ${SONAR_LOGIN:+sonarqube} --no-daemon -Dsonar.login=$SONAR_LOGIN