diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000000..38e570099f --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,101 @@ +name: Unit test coverage + +on: + workflow_call: + inputs: + sdk: + required: true + type: string + head_commit_sha: + required: true + type: string + previous_commit_sha: + required: true + type: string + use_cached_coverage: + required: true + type: boolean + +jobs: + get-cached-coverage: + runs-on: ubuntu-latest + outputs: + cache-hit: ${{ steps.download-cache.outputs.cache-hit == 'true' }} + steps: + - name: Get Cached Coverage Data + id: download-cache + uses: actions/cache/restore@v4 + with: + path: | + reports/coverage + key: coverage@${{ inputs.previous_commit_sha }} + + - name: Upload Cached Coverage Data + id: store-cache + if: ${{ steps.download-cache.outputs.cache-hit == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: coverage + path: reports/coverage + + test-coverage: + runs-on: ubuntu-latest + needs: [ get-cached-coverage ] + steps: + - uses: actions/checkout@v4 + if: ${{ !needs.get-cached-coverage.outputs.cache-hit || !inputs.use_cached_coverage }} + + - uses: dart-lang/setup-dart@v1 + if: ${{ !needs.get-cached-coverage.outputs.cache-hit || !inputs.use_cached_coverage }} + with: + sdk: ${{ inputs.sdk }} + + - name: Run Tests (DDC + coverage) + if: ${{ !needs.get-cached-coverage.outputs.cache-hit || !inputs.use_cached_coverage }} + run: dart run dart_dev test --test-args="--coverage=reports/coverage" -P dartdevc + + - name: Upload New Coverage Data + if: ${{ !needs.get-cached-coverage.outputs.cache-hit || !inputs.use_cached_coverage }} + uses: actions/upload-artifact@v4 + with: + name: coverage + path: reports/coverage + + generate-coverage: + runs-on: ubuntu-latest + needs: [ test-coverage ] + steps: + - uses: actions/checkout@v4 + - uses: dart-lang/setup-dart@v1 + with: + sdk: ${{ inputs.sdk }} + - name: Download Package Config + uses: actions/download-artifact@v4 + with: + name: package_config@${{ inputs.sdk }} + path: .dart_tool + + - name: Download Coverage Data + uses: actions/download-artifact@v4 + with: + name: coverage + path: reports/coverage + + - name: Activate Coverage Package + run: dart pub global activate coverage + + - name: Format Coverage + run: dart pub global run coverage:format_coverage --packages=.dart_tool/package_config.json --report-on=lib --lcov -o reports/coverage/lcov.info -i reports/coverage + + - name: Cache Coverage Data + uses: actions/cache/save@v4 + with: + path: | + reports/coverage + key: coverage@${{ inputs.head_commit_sha }} + + - name: Report Coverage + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: reports/coverage/lcov.info \ No newline at end of file diff --git a/.github/workflows/dart_ci.yml b/.github/workflows/dart_ci.yml index 3cc690a80e..5de26d9336 100644 --- a/.github/workflows/dart_ci.yml +++ b/.github/workflows/dart_ci.yml @@ -9,14 +9,6 @@ on: branches: - '**' -permissions: - contents: read - checks: write - deployments: write - id-token: write - pull-requests: write - statuses: read - jobs: source-check: uses: ./.github/workflows/source-check.yml @@ -34,6 +26,8 @@ jobs: gen_coverage: ${{ matrix.sdk == '2.19.6' }} run_dart_checks: ${{ needs.source-check.outputs.run_dart_checks == 'true' }} is_tag_build: ${{ needs.source-check.outputs.is_tag_build == 'true' }} + head_commit_sha: ${{ needs.source-check.outputs.head_commit_sha }} + previous_commit_sha: ${{ needs.source-check.outputs.previous_commit_sha }} analyzer-plugin: needs: [ source-check ] diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml index 1f6ec29fb6..379c3438b6 100644 --- a/.github/workflows/install.yml +++ b/.github/workflows/install.yml @@ -6,8 +6,9 @@ on: sdk: required: true type: string - gen_coverage: - required: true + store_package_config: + required: false + default: false type: boolean store_lockfile: required: true @@ -41,7 +42,7 @@ jobs: path: pubspec.lock - name: Upload Package Config - if: ${{ inputs.gen_coverage }} + if: ${{ inputs.store_package_config }} uses: actions/upload-artifact@v4 with: name: package_config@${{ inputs.sdk }} diff --git a/.github/workflows/lib_ci.yml b/.github/workflows/lib_ci.yml index 58123c6d7c..b26300f902 100644 --- a/.github/workflows/lib_ci.yml +++ b/.github/workflows/lib_ci.yml @@ -15,21 +15,19 @@ on: is_tag_build: required: true type: boolean - -permissions: - contents: read - checks: write - deployments: write - id-token: write - pull-requests: write - statuses: read + head_commit_sha: + required: true + type: string + previous_commit_sha: + required: true + type: string jobs: install: uses: ./.github/workflows/install.yml with: sdk: ${{ inputs.sdk }} - gen_coverage: ${{ inputs.gen_coverage }} + store_package_config: ${{ inputs.gen_coverage }} store_lockfile: true validate: @@ -37,38 +35,7 @@ jobs: needs: [ install ] with: sdk: ${{ inputs.sdk }} - - build-ddc: - needs: [ install ] - if: ${{ !inputs.is_tag_build && inputs.run_dart_checks }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dart-lang/setup-dart@v1 - with: - sdk: ${{ inputs.sdk }} - - - id: build - timeout-minutes: 6 - name: Build generated files / precompile DDC assets - run: | - dart run build_runner build --delete-conflicting-outputs - - - name: Verify that generated files are up-to-date - run: | - if [ ${{ inputs.sdk }} = '2.18.7' ]; then - git diff --exit-code - else - # Don't check these generated files for other SDKs, since they may generate differently - # due to different resolved dependencies. - git diff --exit-code -- ":(exclude)test/mockito.mocks.dart" ":(exclude)test/over_react/component_declaration/redux_component_test/test_reducer.g.dart" - fi - if: steps.build.outcome == 'success' - - # Analyze again after generated files are created to verify that those generated classes don't cause analysis errors - - name: Analyze project source (post-build) - run: dart analyze - if: steps.build.outcome == 'success' + run_ddc_build: ${{ !inputs.is_tag_build && inputs.run_dart_checks }} test-dart2js: needs: [ install ] @@ -99,66 +66,28 @@ jobs: run: dart test -P vm test-ddc: - runs-on: ubuntu-latest needs: [ install ] - # Run on a tag build no matter what so that coverage is generated for that commit - if: ${{ (inputs.is_tag_build && inputs.gen_coverage) || inputs.run_dart_checks }} + if: ${{ !inputs.gen_coverage && !inputs.is_tag_build && inputs.run_dart_checks }} + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ inputs.sdk }} - - - name: Run tests (DDC) - if: ${{ !inputs.gen_coverage }} + - name: Run run: dart run dart_dev test -P dartdevc - - name: Run tests (DDC + coverage) - if: ${{ inputs.gen_coverage }} - run: dart run dart_dev test --test-args="--coverage=reports/coverage" -P dartdevc - - - name: Upload Coverage Data - if: ${{ inputs.gen_coverage }} - uses: actions/upload-artifact@v4 - with: - name: coverage - path: reports/coverage - - generate-coverage: - runs-on: ubuntu-latest - needs: [ install, test-ddc ] + test-coverage: + needs: [ install ] if: ${{ inputs.gen_coverage }} - steps: - - uses: actions/checkout@v4 - - uses: dart-lang/setup-dart@v1 - with: - sdk: ${{ inputs.sdk }} - - name: Download Package Config - uses: actions/download-artifact@v4 - with: - name: package_config@${{ inputs.sdk }} - path: .dart_tool - - name: Download Coverage Data - uses: actions/download-artifact@v4 - with: - name: coverage - path: reports/coverage - - name: Activate Coverage Package - run: dart pub global activate coverage - - name: Format Coverage - run: dart pub global run coverage:format_coverage --packages=.dart_tool/package_config.json --report-on=lib --lcov -o reports/coverage/lcov.info -i reports/coverage - - name: Upload Formatted Coverage as Artifact - uses: actions/upload-artifact@v4 - with: - name: lcov.info - path: reports/coverage/lcov.info - - name: Upload Coverage to codecov.io - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: reports/coverage/lcov.info + uses: ./.github/workflows/coverage.yml + with: + sdk: ${{ inputs.sdk }} + head_commit_sha: ${{ inputs.head_commit_sha }} + previous_commit_sha: ${{ inputs.previous_commit_sha }} + use_cached_coverage: ${{ inputs.is_tag_build && inputs.gen_coverage }} - validate_analyzer: + validate-analyzer-5: needs: [ install ] if: ${{ !inputs.is_tag_build && inputs.run_dart_checks }} runs-on: ubuntu-latest diff --git a/.github/workflows/plugin_ci.yml b/.github/workflows/plugin_ci.yml index 4ac66548f7..15e2a554e2 100644 --- a/.github/workflows/plugin_ci.yml +++ b/.github/workflows/plugin_ci.yml @@ -7,14 +7,6 @@ on: required: true type: string -permissions: - contents: read - checks: write - deployments: write - id-token: write - pull-requests: write - statuses: read - jobs: test: runs-on: ubuntu-latest diff --git a/.github/workflows/source-check.yml b/.github/workflows/source-check.yml index a7f6bfdc07..157375fc79 100644 --- a/.github/workflows/source-check.yml +++ b/.github/workflows/source-check.yml @@ -3,6 +3,12 @@ name: Source check on: workflow_call: outputs: + head_commit_sha: + description: "git rev-parse HEAD" + value: ${{ jobs.get-prev-sha.outputs.head_commit_sha }} + previous_commit_sha: + description: "git rev-parse HEAD~ (so we can retrieve a cached copy of code coverage on tag commits)" + value: ${{ jobs.get-prev-sha.outputs.previous_commit_sha }} is_tag_build: description: "Whether the build is the result of a tagged release commit" value: ${{ jobs.git-diff.outputs.is_tag_build }} @@ -11,6 +17,23 @@ on: value: ${{ jobs.git-diff.outputs.run_dart_checks }} jobs: + get-prev-sha: + runs-on: ubuntu-latest + outputs: + head_commit_sha: ${{ steps.rev-parse.outputs.head_commit_sha }} + previous_commit_sha: ${{ steps.rev-parse.outputs.previous_commit_sha }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + ref: ${{ github.event.pull_request.head.sha }} + - name: Get Previous Commit Sha + id: rev-parse + shell: bash + run: | + echo "head_commit_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + echo "previous_commit_sha=$(git rev-parse HEAD~)" >> "$GITHUB_OUTPUT" + git-diff: runs-on: ubuntu-latest outputs: diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index ab72e0da1f..b0bae3b0ce 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,4 +1,4 @@ -name: Dependency / formatting validation +name: Dependency / formatting / source gen validation on: workflow_call: @@ -6,6 +6,9 @@ on: sdk: required: true type: string + run_ddc_build: + required: true + type: boolean jobs: validate-dependencies: @@ -49,4 +52,35 @@ jobs: # Analyze lib to ensure public APIs don't depend on build-to-cache files, # which could cause analysis issues for consumers who haven't run a build yet. dart analyze lib - dart analyze example/boilerplate_versions \ No newline at end of file + dart analyze example/boilerplate_versions + + validate-generated-sources: + if: ${{ inputs.run_ddc_build }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dart-lang/setup-dart@v1 + with: + sdk: ${{ inputs.sdk }} + + - id: build + timeout-minutes: 6 + name: Build generated files / precompile DDC assets + run: | + dart run build_runner build --delete-conflicting-outputs + + - name: Verify that generated files are up-to-date + run: | + if [ ${{ inputs.sdk }} = '2.18.7' ]; then + git diff --exit-code + else + # Don't check these generated files for other SDKs, since they may generate differently + # due to different resolved dependencies. + git diff --exit-code -- ":(exclude)test/mockito.mocks.dart" ":(exclude)test/over_react/component_declaration/redux_component_test/test_reducer.g.dart" + fi + if: steps.build.outcome == 'success' + + # Analyze again after generated files are created to verify that those generated classes don't cause analysis errors + - name: Analyze project source (post-build) + run: dart analyze + if: steps.build.outcome == 'success' \ No newline at end of file