diff --git a/.github/workflows/health.yaml b/.github/workflows/health.yaml index 63d91eeb..d2cf26e1 100644 --- a/.github/workflows/health.yaml +++ b/.github/workflows/health.yaml @@ -12,17 +12,9 @@ name: Health # jobs: # health: # uses: dart-lang/ecosystem/.github/workflows/health.yaml@main -# with: -# coverage_web: true #If the coverage should run browser tests - -# Callers may optionally specify the version of the SDK to use when running the -# health check. This can be useful if your package has a very recent minimum SDK -# constraint. This is done via the `sdk` input parameter. Note that this -# parameter is not required; it defaults to `stable` - using the most recent -# stable release of the Dart SDK. -# -# The checks can also be restricted to any subset of version, changelog, and license, -# if needed. + + +# Or with options: # # jobs: # health: @@ -30,10 +22,21 @@ name: Health # with: # sdk: beta # checks: "version,changelog,license,coverage,breaking,do-not-submit" +# fail_on: "version,changelog,do-not-submit" +# warn_on: "license,coverage,breaking" +# coverage_web: false +# upload_coverage: false +# use-flutter: true + on: workflow_call: inputs: + # Callers may optionally specify the version of the SDK to use when running the + # health check. This can be useful if your package has a very recent minimum SDK + # constraint. This is done via the `sdk` input parameter. Note that this + # parameter is not required; it defaults to `stable` - using the most recent + # stable release of the Dart SDK. sdk: description: >- The channel, or a specific version from a channel, to install @@ -42,11 +45,23 @@ on: default: "stable" required: false type: string + # Restrict the checks to any subset of version, changelog, and license if + # needed. checks: description: What to check for in the PR health check - any subset of "version,changelog,license,coverage,breaking,do-not-submit" default: "version,changelog,license,coverage,breaking,do-not-submit" type: string required: false + fail_on: + description: Which checks should lead to failure - any subset of "version,changelog,license,coverage,breaking,do-not-submit" + default: "version,changelog,do-not-submit" + type: string + required: false + warn_on: + description: Which checks should not fail, but only warn - any subset of "version,changelog,license,coverage,breaking,do-not-submit" + default: "license,coverage,breaking" + type: string + required: false local_debug: description: Whether to use a local copy of package:firehose - only for debug default: false @@ -70,7 +85,77 @@ on: type: boolean jobs: - health: + version: + if: contains(${{ inputs.checks }}, 'version') + uses: ./.github/workflows/health_base.yaml + with: + sdk: ${{ inputs.sdk }} + check: version + fail_on: ${{ inputs.fail_on }} + warn_on: ${{ inputs.warn_on }} + local_debug: ${{ inputs.local_debug }} + use-flutter: ${{ inputs.use-flutter }} + + changelog: + if: contains(${{ inputs.checks }}, 'changelog') + uses: ./.github/workflows/health_base.yaml + with: + sdk: ${{ inputs.sdk }} + check: changelog + fail_on: ${{ inputs.fail_on }} + warn_on: ${{ inputs.warn_on }} + local_debug: ${{ inputs.local_debug }} + use-flutter: ${{ inputs.use-flutter }} + + license: + if: contains(${{ inputs.checks }}, 'license') + uses: ./.github/workflows/health_base.yaml + with: + sdk: ${{ inputs.sdk }} + check: license + fail_on: ${{ inputs.fail_on }} + warn_on: ${{ inputs.warn_on }} + local_debug: ${{ inputs.local_debug }} + use-flutter: ${{ inputs.use-flutter }} + + coverage: + if: contains(${{ inputs.checks }}, 'coverage') + uses: ./.github/workflows/health_base.yaml + with: + sdk: ${{ inputs.sdk }} + check: coverage + fail_on: ${{ inputs.fail_on }} + warn_on: ${{ inputs.warn_on }} + upload_coverage: ${{ inputs.upload_coverage }} + coverage_web: ${{ inputs.coverage_web }} + local_debug: ${{ inputs.local_debug }} + use-flutter: ${{ inputs.use-flutter }} + + breaking: + if: contains(${{ inputs.checks }}, 'breaking') + uses: ./.github/workflows/health_base.yaml + with: + sdk: ${{ inputs.sdk }} + check: breaking + fail_on: ${{ inputs.fail_on }} + warn_on: ${{ inputs.warn_on }} + local_debug: ${{ inputs.local_debug }} + use-flutter: ${{ inputs.use-flutter }} + + do-not-submit: + if: contains(${{ inputs.checks }}, 'do-not-submit') + uses: ./.github/workflows/health_base.yaml + with: + sdk: ${{ inputs.sdk }} + check: do-not-submit + fail_on: ${{ inputs.fail_on }} + warn_on: ${{ inputs.warn_on }} + local_debug: ${{ inputs.local_debug }} + use-flutter: ${{ inputs.use-flutter }} + + comment: + needs: [version, changelog, license, coverage, breaking, do-not-submit] + if: always() # These permissions are required for us to create comments on PRs. permissions: pull-requests: write @@ -78,68 +163,34 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - with: - path: current_repo/ - - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - with: - ref: ${{ github.event.pull_request.base.ref }} - path: base_repo/ - - - uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225 - if: ${{ inputs.use-flutter }} - with: - channel: ${{ inputs.sdk }} - - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d - if: ${{ !inputs.use-flutter }} + - name: Download All Artifacts + uses: actions/download-artifact@f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110 with: - sdk: ${{ inputs.sdk }} + path: single-comments - - name: Install coverage - run: dart pub global activate coverage + - run: ls -R single-comments - - name: Install firehose - run: dart pub global activate firehose - if: ${{ !inputs.local_debug }} - - - name: Install local firehose - run: dart pub global activate --source path current_repo/pkgs/firehose/ - if: ${{ inputs.local_debug }} - - - name: Install api_tool - run: dart pub global activate dart_apitool - - - name: Check PR health - id: healthstep - if: ${{ github.event_name == 'pull_request' }} - continue-on-error: true # continue, so that the result is written as a comment. Fail in the last step - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ISSUE_NUMBER: ${{ github.event.number }} - PR_LABELS: "${{ join(github.event.pull_request.labels.*.name) }}" - run: cd current_repo/ && dart pub global run firehose:health --checks ${{ inputs.checks }} ${{ fromJSON('{"true":"--coverage_web","false":""}')[inputs.coverage_web] }} - - - name: Upload coverage to Coveralls - if: ${{ inputs.upload_coverage }} - uses: coverallsapp/github-action@3dfc5567390f6fa9267c0ee9c251e4c8c3f18949 + - name: Find Comment + uses: peter-evans/find-comment@4541d1b6b0e618acc24284e118743fc5ad0bc5de + id: fc with: - format: lcov - base-path: current_repo/ - compare-sha: ${{ github.event.pull_request.base.ref }} - allow-empty: true - - - name: Save PR number + issue-number: ${{ github.event.number }} + comment-author: github-actions[bot] + body-includes: '## PR Health' + + - name: Merge all single comments run: | - mkdir -p current_repo/output/ && echo ${{ github.event.number }} > current_repo/output/issueNumber + mkdir output + echo $'## PR Health \n\n' >> output/comment.md + cat single-comments/*/*.md >> output/comment.md + echo ${{ github.event.number }} > output/issueNumber + - name: Write comment id to file + if: ${{ steps.fc.outputs.comment-id != 0 }} + run: echo ${{ steps.fc.outputs.comment-id }} >> output/commentId + - name: Upload folder with number and markdown uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 with: name: output - path: current_repo/output/ - - - name: Fail the workflow if "Check PR health" failed - if: steps.healthstep.outcome != 'success' - run: exit 1 + path: output/ diff --git a/.github/workflows/health_base.yaml b/.github/workflows/health_base.yaml new file mode 100644 index 00000000..8870ec0c --- /dev/null +++ b/.github/workflows/health_base.yaml @@ -0,0 +1,128 @@ +# A CI configuration to check PR health. + +name: Health:Base + +# The workflow doing the checks for `health.yaml`. Not meant to be used externally. + +on: + workflow_call: + inputs: + sdk: + description: >- + The channel, or a specific version from a channel, to install + ('2.19.0','stable', 'beta', 'dev'). Using one of the three channels + will give you the latest version published to that channel. + default: "stable" + required: false + type: string + check: + description: What to check for in the PR health check - any of "version,changelog,license,coverage,breaking,do-not-submit" + type: string + required: true + fail_on: + description: Which checks should lead to failure - any subset of "version,changelog,license,coverage,breaking,do-not-submit" + default: "version,changelog,do-not-submit" + type: string + required: false + warn_on: + description: Which checks should not fail, but only warn - any subset of "version,changelog,license,coverage,breaking,do-not-submit" + default: "license,coverage,breaking" + type: string + required: false + local_debug: + description: Whether to use a local copy of package:firehose - only for debug + default: false + type: boolean + required: false + upload_coverage: + description: Whether to upload the coverage to coveralls + default: true + type: boolean + required: false + coverage_web: + description: Whether to run `dart test -p chrome` for coverage + default: false + type: boolean + required: false + use-flutter: + description: >- + Whether to setup Flutter in this workflow. + default: false + required: false + type: boolean + +jobs: + health: + name: run + # These permissions are required for us to create comments on PRs. + permissions: + pull-requests: write + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + with: + path: current_repo/ + + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + with: + ref: ${{ github.event.pull_request.base.ref }} + path: base_repo/ + if: ${{ inputs.check == 'coverage' }} || ${{ inputs.check == 'breaking' }} + + - name: Write comment if not present + run: | + mkdir -p current_repo/output/ + test -f current_repo/output/comment.md || echo $'The ${{ inputs.check }} workflow has encountered an exception and did not complete.' >> current_repo/output/comment.md + + - uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225 + if: ${{ inputs.use-flutter }} + with: + channel: ${{ inputs.sdk }} + + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + if: ${{ !inputs.use-flutter }} + with: + sdk: ${{ inputs.sdk }} + + - name: Install coverage + run: dart pub global activate coverage + if: ${{ inputs.check == 'coverage' }} + + - name: Install firehose + run: dart pub global activate firehose + if: ${{ !inputs.local_debug }} + + - name: Install local firehose + run: dart pub global activate --source path current_repo/pkgs/firehose/ + if: ${{ inputs.local_debug }} + + - name: Install api_tool + run: dart pub global activate dart_apitool + if: ${{ inputs.check == 'breaking' }} + + - name: Check PR health + id: healthstep + if: ${{ github.event_name == 'pull_request' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ISSUE_NUMBER: ${{ github.event.number }} + PR_LABELS: "${{ join(github.event.pull_request.labels.*.name) }}" + run: cd current_repo/ && dart pub global run firehose:health --check ${{ inputs.check }} ${{ fromJSON('{"true":"--coverage_web","false":""}')[inputs.coverage_web] }} --fail_on ${{ inputs.fail_on }} --warn_on ${{ inputs.warn_on }} + + - name: Upload coverage to Coveralls + if: ${{ inputs.upload_coverage }} + uses: coverallsapp/github-action@3dfc5567390f6fa9267c0ee9c251e4c8c3f18949 + with: + format: lcov + base-path: current_repo/ + compare-sha: ${{ github.event.pull_request.base.ref }} + allow-empty: true + + - name: Upload markdown + if: success() || failure() + uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 + with: + name: comment-${{ inputs.check }} + path: current_repo/output/comment.md diff --git a/.github/workflows/health_internal.yaml b/.github/workflows/health_internal.yaml index aae8ba10..cf46b50f 100644 --- a/.github/workflows/health_internal.yaml +++ b/.github/workflows/health_internal.yaml @@ -13,3 +13,5 @@ jobs: coverage_web: false upload_coverage: false checks: version,changelog,license,coverage,breaking,do-not-submit + fail_on: version,changelog,do-not-submit + warn_on: license,coverage,breaking diff --git a/.github/workflows/post_summaries.yaml b/.github/workflows/post_summaries.yaml index b0dfd64f..10e82c91 100644 --- a/.github/workflows/post_summaries.yaml +++ b/.github/workflows/post_summaries.yaml @@ -7,7 +7,7 @@ on: workflow_run: workflows: - Publish - - Health + - Health:Comment types: - completed diff --git a/pkgs/firehose/CHANGELOG.md b/pkgs/firehose/CHANGELOG.md index 94b3dd43..23613cda 100644 --- a/pkgs/firehose/CHANGELOG.md +++ b/pkgs/firehose/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.0 + +- Split health checks in individual workflows. + ## 0.4.2 - Get needed version from `dart_apitool` in PR health checks. diff --git a/pkgs/firehose/bin/health.dart b/pkgs/firehose/bin/health.dart index 1f6ab49a..19a98d40 100644 --- a/pkgs/firehose/bin/health.dart +++ b/pkgs/firehose/bin/health.dart @@ -9,25 +9,34 @@ import 'package:firehose/src/health/health.dart'; void main(List arguments) async { var argParser = ArgParser() - ..addMultiOption( - 'checks', - allowed: [ - 'version', - 'license', - 'changelog', - 'coverage', - 'breaking', - 'do-not-submit', - ], + ..addOption( + 'check', + allowed: checkTypes, help: 'Check PR health.', ) + ..addMultiOption( + 'warn_on', + allowed: checkTypes, + help: 'Which checks to display warnings on', + ) + ..addMultiOption( + 'fail_on', + allowed: checkTypes, + help: 'Which checks should lead to workflow failure', + ) ..addFlag( 'coverage_web', help: 'Whether to run web tests for coverage', ); var parsedArgs = argParser.parse(arguments); - var checks = parsedArgs['checks'] as List; + var check = parsedArgs['check'] as String; + var warnOn = parsedArgs['warn_on'] as List; + var failOn = parsedArgs['fail_on'] as List; var coverageWeb = parsedArgs['coverage_web'] as bool; - - await Health(Directory.current).healthCheck(checks, coverageWeb); + if (warnOn.toSet().intersection(failOn.toSet()).isNotEmpty) { + throw ArgumentError('The checks for which warnings are displayed and the ' + 'checks which lead to failure must be disjoint.'); + } + await Health(Directory.current, check, warnOn, failOn, coverageWeb) + .healthCheck(); } diff --git a/pkgs/firehose/lib/src/github.dart b/pkgs/firehose/lib/src/github.dart index f2d763ba..866bf32a 100644 --- a/pkgs/firehose/lib/src/github.dart +++ b/pkgs/firehose/lib/src/github.dart @@ -91,7 +91,7 @@ class GithubApi { /// Find a comment on the PR matching the given criteria ([user], /// [searchTerm]). Return the issue ID if a matching comment is found or null /// if there's no match. - Future findCommentId({ + Future findCommentId({ required String user, String? searchTerm, }) async { @@ -107,7 +107,7 @@ class GithubApi { }, orElse: () => null, ); - return matchingComment?.id; + return matchingComment; } Future> listFilesForPR() async => await github.pullRequests @@ -170,4 +170,14 @@ enum FileStatus { static FileStatus fromString(String s) => FileStatus.values.firstWhere((element) => element.name == s); + + bool get isRelevant => switch (this) { + FileStatus.added => true, + FileStatus.removed => true, + FileStatus.modified => true, + FileStatus.renamed => true, + FileStatus.copied => true, + FileStatus.changed => true, + FileStatus.unchanged => false, + }; } diff --git a/pkgs/firehose/lib/src/health/health.dart b/pkgs/firehose/lib/src/health/health.dart index 440b31fd..5dab5e4d 100644 --- a/pkgs/firehose/lib/src/health/health.dart +++ b/pkgs/firehose/lib/src/health/health.dart @@ -22,8 +22,6 @@ import 'license.dart'; const String _botSuffix = '[bot]'; -const String _githubActionsUser = 'github-actions[bot]'; - const String _publishBotTag2 = '### Package publish validation'; const String _licenseBotTag = '### License Headers'; @@ -36,16 +34,33 @@ const String _coverageBotTag = '### Coverage'; const String _breakingBotTag = '### Breaking changes'; -const String _prHealthTag = '## PR Health'; +const checkTypes = [ + 'version', + 'license', + 'changelog', + 'coverage', + 'breaking', + 'do-not-submit', +]; class Health { final Directory directory; - Health(this.directory); - - Future healthCheck(List args, bool coverageweb) async { - var github = GithubApi(); - + Health( + this.directory, + this.check, + this.warnOn, + this.failOn, + this.coverageweb, + ); + final github = GithubApi(); + + final String check; + final List warnOn; + final List failOn; + final bool coverageweb; + + Future healthCheck() async { // Do basic validation of our expected env var. if (!expectEnv(github.repoSlug?.fullName, 'GITHUB_REPOSITORY')) return; if (!expectEnv(github.issueNumber?.toString(), 'ISSUE_NUMBER')) return; @@ -56,35 +71,48 @@ class Health { return; } - print('Start health check for the checks $args'); - var checks = [ - if (args.contains('version') && - !github.prLabels.contains('skip-validate-check')) - validateCheck, - if (args.contains('license') && - !github.prLabels.contains('skip-license-check')) - licenseCheck, - if (args.contains('changelog') && - !github.prLabels.contains('skip-changelog-check')) - changelogCheck, - if (args.contains('coverage') && - !github.prLabels.contains('skip-coverage-check')) - (GithubApi github) => coverageCheck(github, coverageweb), - if (args.contains('breaking') && - !github.prLabels.contains('skip-breaking-check')) - breakingCheck, - if (args.contains('do-not-submit') && - !github.prLabels.contains('skip-do-not-submit-check')) - doNotSubmitCheck, - ]; - final results = []; - for (var check in checks) { - results.add(await check(github)); + print('Start health check for the check $check'); + print('Checking for $check'); + if (!github.prLabels.contains('skip-$check-check')) { + final firstResult = await checkFor(check)(); + final HealthCheckResult finalResult; + if (warnOn.contains(check) && firstResult.severity == Severity.error) { + finalResult = firstResult.withSeverity(Severity.warning); + } else if (failOn.contains(check) && + firstResult.severity == Severity.warning) { + finalResult = firstResult.withSeverity(Severity.error); + } else { + finalResult = firstResult; + } + await writeInComment(github, finalResult); + print('\n\n${finalResult.severity.name.toUpperCase()}: $check done.\n\n'); + } else { + print('Skipping $check, as the skip tag is present.'); } - await writeInComment(github, results); } - Future validateCheck(GithubApi github) async { + String tagFor(String checkType) => switch (checkType) { + 'version' => _publishBotTag2, + 'license' => _licenseBotTag, + 'changelog' => _changelogBotTag, + 'coverage' => _coverageBotTag, + 'breaking' => _breakingBotTag, + 'do-not-submit' => _doNotSubmitBotTag, + String() => throw ArgumentError('Invalid check type $checkType'), + }; + + Future Function() checkFor(String checkType) => + switch (checkType) { + 'version' => validateCheck, + 'license' => licenseCheck, + 'changelog' => changelogCheck, + 'coverage' => coverageCheck, + 'breaking' => breakingCheck, + 'do-not-submit' => doNotSubmitCheck, + String() => throw ArgumentError('Invalid check type $checkType'), + }; + + Future validateCheck() async { //TODO: Add Flutter support for PR health checks var results = await Firehose(directory, false).verify(github); @@ -97,19 +125,17 @@ Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automati '''; return HealthCheckResult( - 'validate', - _publishBotTag2, + 'version', results.severity, markdownTable, ); } - Future breakingCheck(GithubApi github) async { - final repo = Repository(); - final packages = repo.locatePackages(); - var changeForPackage = {}; - var baseDirectory = Directory('../base_repo'); - for (var package in packages) { + Future breakingCheck() async { + final filesInPR = await github.listFilesForPR(); + final changeForPackage = {}; + final baseDirectory = Directory('../base_repo'); + for (var package in packagesContaining(filesInPR)) { var currentPath = path.relative(package.directory.path, from: Directory.current.path); var basePackage = path.relative( @@ -153,7 +179,6 @@ Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automati } return HealthCheckResult( 'breaking', - _breakingBotTag, changeForPackage.values.any((element) => !element.versionIsFine) ? Severity.warning : Severity.info, @@ -179,7 +204,7 @@ ${changeForPackage.entries.map((e) => '|${e.key.name}|${e.value.toMarkdownRow()} return breakingLevel; } - Future licenseCheck(GithubApi github) async { + Future licenseCheck() async { var files = await github.listFilesForPR(); var allFilePaths = await getFilesWithoutLicenses(Directory.current); @@ -217,13 +242,12 @@ ${unchangedFilesPaths.isNotEmpty ? unchangedMarkdown : ''} return HealthCheckResult( 'license', - _licenseBotTag, changedFilesPaths.isNotEmpty ? Severity.error : Severity.success, markdownResult, ); } - Future changelogCheck(GithubApi github) async { + Future changelogCheck() async { var filePaths = await packagesWithoutChangelog(github); final markdownResult = ''' @@ -236,13 +260,12 @@ Changes to files need to be [accounted for](https://github.com/dart-lang/ecosyst return HealthCheckResult( 'changelog', - _changelogBotTag, filePaths.isNotEmpty ? Severity.error : Severity.success, markdownResult, ); } - Future doNotSubmitCheck(GithubApi github) async { + Future doNotSubmitCheck() async { final body = await github.pullrequestBody(); final files = await github.listFilesForPR(); print('Checking for DO_NOT${'_'}SUBMIT strings: $files'); @@ -268,17 +291,13 @@ ${filesWithDNS.map((e) => e.filename).map((e) => '|$e|').join('\n')} final hasDNS = filesWithDNS.isNotEmpty || bodyContainsDNS; return HealthCheckResult( 'do-not-submit', - _doNotSubmitBotTag, hasDNS ? Severity.error : Severity.success, hasDNS ? markdownResult : null, ); } - Future coverageCheck( - GithubApi github, - bool coverageWeb, - ) async { - var coverage = await Coverage(coverageWeb).compareCoverages(github); + Future coverageCheck() async { + var coverage = await Coverage(coverageweb).compareCoverages(github); var markdownResult = ''' | File | Coverage | @@ -290,7 +309,6 @@ This check for [test coverage](https://github.com/dart-lang/ecosystem/wiki/Test- return HealthCheckResult( 'coverage', - _coverageBotTag, Severity.values[coverage.coveragePerFile.values .map((change) => change.severity.index) .fold(0, max)], @@ -299,11 +317,9 @@ This check for [test coverage](https://github.com/dart-lang/ecosystem/wiki/Test- } Future writeInComment( - GithubApi github, - List results, - ) async { - var commentText = - results.where((result) => result.markdown != null).map((result) { + GithubApi github, HealthCheckResult result) async { + final String markdownSummary; + if (result.markdown != null) { var markdown = result.markdown; var isWorseThanInfo = result.severity.index >= Severity.warning.index; var s = ''' @@ -318,43 +334,33 @@ ${isWorseThanInfo ? 'This check can be disabled by tagging the PR with `skip-${r '''; - return '${result.title} ${result.severity.emoji}\n\n$s'; - }).join('\n'); - - var summary = '$_prHealthTag\n\n$commentText'; - github.appendStepSummary(summary); - - var existingCommentId = await allowFailure( - github.findCommentId(user: _githubActionsUser, searchTerm: _prHealthTag), - logError: print, - ); - - if (existingCommentId != null) { - var idFile = File('./output/commentId'); - print(''' -Saving existing comment id $existingCommentId to file ${idFile.path}'''); - await idFile.create(recursive: true); - await idFile.writeAsString(existingCommentId.toString()); + markdownSummary = '${tagFor(result.name)} ${result.severity.emoji}\n\n$s'; + } else { + markdownSummary = ''; } + github.appendStepSummary(markdownSummary); + var commentFile = File('./output/comment.md'); print('Saving comment markdown to file ${commentFile.path}'); await commentFile.create(recursive: true); - await commentFile.writeAsString(summary); + await commentFile.writeAsString(markdownSummary); - if (results.any((result) => result.severity == Severity.error) && - exitCode == 0) { + if (result.severity == Severity.error && exitCode == 0) { exitCode = 1; } } -} -Version getNewVersion(BreakingLevel level, Version oldVersion) { - return switch (level) { - BreakingLevel.none => oldVersion, - BreakingLevel.nonBreaking => oldVersion.nextMinor, - BreakingLevel.breaking => oldVersion.nextBreaking, - }; + List packagesContaining(List filesInPR) { + var files = filesInPR.where((element) => element.status.isRelevant); + final repo = Repository(); + return repo.locatePackages().where((package) { + var relativePackageDirectory = + path.relative(package.directory.path, from: Directory.current.path); + return files.any( + (file) => path.isWithin(relativePackageDirectory, file.relativePath)); + }).toList(); + } } enum BreakingLevel { @@ -369,11 +375,16 @@ enum BreakingLevel { class HealthCheckResult { final String name; - final String title; final Severity severity; final String? markdown; - HealthCheckResult(this.name, this.title, this.severity, this.markdown); + HealthCheckResult(this.name, this.severity, this.markdown); + + HealthCheckResult withSeverity(Severity severity) => HealthCheckResult( + name, + severity, + markdown, + ); } class BreakingChange { diff --git a/pkgs/firehose/pubspec.yaml b/pkgs/firehose/pubspec.yaml index 404af5e8..57e90f3f 100644 --- a/pkgs/firehose/pubspec.yaml +++ b/pkgs/firehose/pubspec.yaml @@ -1,6 +1,6 @@ name: firehose description: A tool to automate publishing of Pub packages from GitHub actions. -version: 0.4.2 +version: 0.5.0 repository: https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose environment: diff --git a/pkgs/firehose/test/github_test.dart b/pkgs/firehose/test/github_test.dart index ef47b54e..ae3a195a 100644 --- a/pkgs/firehose/test/github_test.dart +++ b/pkgs/firehose/test/github_test.dart @@ -26,14 +26,14 @@ Future main() async { }); test('Find comment', () async { var commentId = await github.findCommentId(user: 'auto-submit[bot]'); - expect(commentId, 1660891263); + expect(commentId?.id, 1660891263); }); test('Find comment with searchterm', () async { var commentId = await github.findCommentId( user: 'auto-submit[bot]', searchTerm: 'before re-applying this label.', ); - expect(commentId, 1660891263); + expect(commentId?.id, 1660891263); }); test('Find comment with searchterm', () async { var commentId = await github.findCommentId(