diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4639b9..1ac931a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,12 @@ on: detected from project/build.properties. type: string default: '' + clean_task: + description: >- + sbt task that cleans the working directory. Defaults to `cleanFull` on sbt 2 and + `clean` on sbt 1, detected from project/build.properties. + type: string + default: '' coverage: description: 'Collect test coverage and upload it to Coveralls' type: boolean @@ -34,7 +40,7 @@ on: type: boolean default: true doc_check: - description: 'Check that scaladoc builds' + description: 'Check that Scaladoc builds' type: boolean default: true sonar: @@ -95,7 +101,7 @@ jobs: disk-cache: ${{ !inputs.coverage }} - name: resolve test task - id: tasks + id: test-task env: TEST_TASK: ${{ inputs.test_task }} run: | @@ -108,15 +114,29 @@ jobs: echo "test=test" >> "$GITHUB_OUTPUT" fi + - name: resolve clean task + id: clean-task + env: + CLEAN_TASK: ${{ inputs.clean_task }} + run: | + if [[ -n "$CLEAN_TASK" ]]; then + echo "clean=$CLEAN_TASK" >> "$GITHUB_OUTPUT" + elif grep -qE '^sbt\.version\s*=\s*2\.' project/build.properties; then + # in sbt 2 the `clean` doesn't remove all generated classes + echo "clean=cleanFull" >> "$GITHUB_OUTPUT" + else + echo "clean=clean" >> "$GITHUB_OUTPUT" + fi + # The coverage build runs before any other compile: scoverage's instrumentation is not part of # sbt's compile cache key, so a plain compile done first would be reused here and the coverage # report would come out empty. - name: build ${{ matrix.scala }} run: | if [[ "${{ inputs.coverage }}" == "true" ]]; then - sbt "++${{ matrix.scala }}; clean; coverage; ${{ steps.tasks.outputs.test }}; coverageAggregate" + sbt "++${{ matrix.scala }}; ${{ steps.clean-task.outputs.clean }}; coverage; ${{ steps.test-task.outputs.test }}; coverageAggregate" else - sbt "++${{ matrix.scala }}; clean; ${{ steps.tasks.outputs.test }}" + sbt "++${{ matrix.scala }}; ${{ steps.clean-task.outputs.clean }}; ${{ steps.test-task.outputs.test }}" fi - name: locate coverage report diff --git a/README.md b/README.md index 992b9c2..abbf295 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ ## Scala CI workflow -Runs tests, coverage, binary compatibility, formatting and scaladoc on every push and pull request. -Replaces the hand-written `ci.yml` that each project used to carry. +Runs tests, coverage, binary compatibility, formatting and Scaladoc on every push and pull request. +Replaces the handwritten `ci.yml` that each project used to carry. ### Setup @@ -42,19 +42,19 @@ alternatives and drops the security rating to C: ### Inputs -| input | default | notes | -|---|---|---| -| `scala_versions` | `'["2.13.18", "3.3.8"]'` | JSON array; becomes the build matrix | -| `java_version` | `'17'` | | -| `java_distribution` | `'temurin'` | | -| `test_task` | auto | `testFull` on sbt 2, `test` on sbt 1, read from `project/build.properties` | -| `coverage` | `true` | collect coverage and upload to Coveralls | -| `version_policy_check` | `true` | requires [sbt-version-policy](https://github.com/scalacenter/sbt-version-policy/) | -| `scalafmt_check` | `true` | | -| `doc_check` | `true` | runs `Compile/doc` | -| `sonar` | `false` | run a SonarQube Cloud scan, see below | -| `sonar_project_key` | `_` | | -| `sonar_args` | `''` | extra `-D` arguments for the scanner | +| input | default | notes | +|------------------------|--------------------------|-----------------------------------------------------------------------------------| +| `scala_versions` | `'["2.13.18", "3.3.8"]'` | JSON array; becomes the build matrix | +| `java_version` | `'17'` | | +| `java_distribution` | `'temurin'` | | +| `test_task` | auto | `testFull` on sbt 2, `test` on sbt 1, read from `project/build.properties` | +| `coverage` | `true` | collect coverage and upload to Coveralls | +| `version_policy_check` | `true` | requires [sbt-version-policy](https://github.com/scalacenter/sbt-version-policy/) | +| `scalafmt_check` | `true` | | +| `doc_check` | `true` | runs `Compile/doc` | +| `sonar` | `false` | run a SonarQube Cloud scan, see below | +| `sonar_project_key` | `_` | | +| `sonar_args` | `''` | extra `-D` arguments for the scanner | Example for a project without `sbt-version-policy` and on a different Scala set: @@ -78,10 +78,10 @@ Two sbt 2 behaviours make a naive coverage setup report nothing while still pass on any run whose build files did not change. This workflow sets `disk-cache: false` whenever coverage is enabled. -The workflow also fails if the produced cobertura report has no valid lines, so a silently empty +The workflow also fails if the produced Cobertura report has no valid lines, so a silently empty report is an error rather than a green build. -Binary compatibility, formatting and scaladoc run as **explicit sbt tasks**, not via a project-local +Binary compatibility, formatting and Scaladoc run as **explicit sbt tasks**, not via a project-local `check` alias. An alias can be stubbed out (`addCommandAlias("check", "show version")`), which makes the gate silently guarantee nothing.