diff --git a/.github/workflows/scalafmt-check.yml b/.github/workflows/scalafmt-check.yml new file mode 100644 index 00000000000..2d60b86040b --- /dev/null +++ b/.github/workflows/scalafmt-check.yml @@ -0,0 +1,31 @@ +name: 'Scalafmt' + +# This GitHub Action runs the ScalaFmt linting tool on the entire codebase. +# It fails if any files are not formatted properly. +# If it is triggered by someone commenting 'scalafmt' on a PR, it will first format, commit, and push formatted code +# to the branch. + +run-name: ${{ format('ScalaFmt Check on {0}', github.ref_name) }} + +on: + workflow_dispatch: + push: + +permissions: + contents: read + +jobs: + run-scalafmt-check: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ inputs.target-branch }} + - uses: ./.github/set_up_cromwell_action + with: + cromwell_repo_token: ${{ secrets.BROADBOT_GITHUB_TOKEN }} + - name: Run ScalaFmt + run: | + sbt scalafmtCheckAll + working-directory: ${{ github.workspace }} diff --git a/.github/workflows/scalafmt-fix.yml b/.github/workflows/scalafmt-fix.yml new file mode 100644 index 00000000000..83e6fb099ed --- /dev/null +++ b/.github/workflows/scalafmt-fix.yml @@ -0,0 +1,48 @@ +name: 'Scalafmt' + +# This GitHub Action runs the ScalaFmt linting tool on the entire codebase. +# It will fix, commit, and push linted code. +# It will only run when someone comments "scalafmt" on a PR. + +run-name: ${{ format('ScalaFmt Fix on {0}', github.ref_name) }} + +on: + workflow_dispatch: + issue_comment: + types: + - created + +jobs: + run-scalafmt-fix: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ inputs.target-branch }} + - uses: ./.github/set_up_cromwell_action + with: + cromwell_repo_token: ${{ secrets.BROADBOT_GITHUB_TOKEN }} + - name: Check for ScalaFmt Comment + id: check-comment + run: | + if [[ "${{ github.event_name }}" == "issue_comment" && "${{ github.event.comment.body }}" == *"scalafmt"* ]]; then + echo "::set-output name=comment-triggered::true" + echo "::set-output name=comment-author-email::${{ github.event.comment.user.login }}@users.noreply.github.com" + echo "::set-output name=comment-author-name::${{ github.event.comment.user.login }}" + else + echo "::set-output name=comment-triggered::false" + fi + shell: bash + - name: Run ScalaFmt + run: | + if [[ ${{ steps.check-comment.outputs.comment-triggered }} == true ]]; then + echo "PR Comment Detected. Formatting, committing, and pushing formatted scala code." + sbt scalaFmtAll + git config --global user.email "${{ steps.check-comment.outputs.comment-author-email }}" + git config --global user.name "${{ steps.check-comment.outputs.comment-author-name }}" + git add . + git commit -m "Auto-format code with ScalaFmt" + git push origin ${{ github.ref }} + fi + working-directory: ${{ github.workspace }} diff --git a/project/ContinuousIntegration.scala b/project/ContinuousIntegration.scala index f0516150cf5..aa171a72338 100644 --- a/project/ContinuousIntegration.scala +++ b/project/ContinuousIntegration.scala @@ -9,7 +9,7 @@ object ContinuousIntegration { lazy val ciSettings: Seq[Setting[_]] = List( srcCiResources := sourceDirectory.value / "ci" / "resources", targetCiResources := target.value / "ci" / "resources", - envFile := srcCiResources.value / "env.temp", //generated by resources/acquire_b2c_token.sh + envFile := srcCiResources.value / "env.temp", // generated by resources/acquire_b2c_token.sh vaultToken := userHome / ".vault-token", copyCiResources := { @@ -31,29 +31,32 @@ object ContinuousIntegration { // Only include the local file argument if the file exists (local development w/ acquire_b2c_token.sh) // Don't include it otherwise (CI/CD and other development) - val localEnvFileArgs = if(envFile.value.exists()) List("-e", s"ENV_FILE=${envFile.value}") else List() + val localEnvFileArgs = if (envFile.value.exists()) List("-e", s"ENV_FILE=${envFile.value}") else List() - val cmd: List[String] = List.concat(List( - "docker", - "run", - "--rm", - "-v", - s"${vaultToken.value}:/root/.vault-token", - "-v", - s"${srcCiResources.value}:${srcCiResources.value}", - "-v", - s"${targetCiResources.value}:${targetCiResources.value}"), + val cmd: List[String] = List.concat( + List( + "docker", + "run", + "--rm", + "-v", + s"${vaultToken.value}:/root/.vault-token", + "-v", + s"${srcCiResources.value}:${srcCiResources.value}", + "-v", + s"${targetCiResources.value}:${targetCiResources.value}" + ), localEnvFileArgs, List( - "-e", - "ENVIRONMENT=not_used", - "-e", - s"INPUT_PATH=${srcCiResources.value}", - "-e", - s"OUT_PATH=${targetCiResources.value}", - "broadinstitute/dsde-toolbox:dev", - "render-templates.sh" - )) + "-e", + "ENVIRONMENT=not_used", + "-e", + s"INPUT_PATH=${srcCiResources.value}", + "-e", + s"OUT_PATH=${targetCiResources.value}", + "broadinstitute/dsde-toolbox:dev", + "render-templates.sh" + ) + ) val result = cmd ! log if (result != 0) { sys.error( @@ -79,7 +82,8 @@ object ContinuousIntegration { private val srcCiResources: SettingKey[File] = settingKey[File]("Source directory for CI resources") private val targetCiResources: SettingKey[File] = settingKey[File]("Target directory for CI resources") private val vaultToken: SettingKey[File] = settingKey[File]("File with the vault token") - private val envFile: SettingKey[File] = settingKey[File]("File with the environment variables needed to render CI resources.") + private val envFile: SettingKey[File] = + settingKey[File]("File with the environment variables needed to render CI resources.") /** * For "reasons" these projects are excluded from the root aggregation in build.sbt. diff --git a/project/plugins.sbt b/project/plugins.sbt index bdb54f675bf..7a0203e08ea 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,4 +3,5 @@ addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.1.1") addSbtPlugin("com.github.sbt" % "sbt-git" % "2.0.0") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.4") addSbtPlugin("com.github.cb372" % "sbt-explicit-dependencies" % "0.2.16") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addDependencyTreePlugin