Introduce a health checking workflow (#115)
* add health workflow
* add health check
* Add license check
* Add unified comment
* Add health check
* dart pub global run mono_repo generate
* Add internal on
* Add firehose version
* Add health tag
* switch to branch name
* Switch to different tag to not delete comment
* Fix formatting
* Switch to different tag
* Remove "great..." message
* Details on error
* fix formatting in details
* fix formatting in details 2
* Add changelog check
* add line breaks to paths in changelog
* add line breaks to paths in changelog 2
* Add changelog entry
* Add debug info
* add debug msg
* Remove debug messages
* Remove debug messages 2
* Remove changelog entry
* Add new file
* Add file_licenser to health check
* Remove license from test file again
* Remove unnecessary stuff from workflow
* Add messages for stdout
* Switch internal to ref
* use local
* add branch
* Rename workflow
* Fix typo...
* Make configurable
* Add stdout
* Remove spaces
* Add arg
* Tweak docs
* Fix copy-paste typo
* Switch `open` to details
* dart pub global run mono_repo generate (#116)
* Changes as per review
* Add description in readme
* add main to fake test
* Add changelog entry + version rev
* Remove empty test
---------
Co-authored-by: Devon Carew <devoncarew@google.com>
diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml
index 7ad3370..aaf0d46 100644
--- a/.github/workflows/dart.yml
+++ b/.github/workflows/dart.yml
@@ -20,7 +20,7 @@
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:stable"
@@ -28,37 +28,37 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: stable
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- name: mono_repo self validate
run: dart pub global activate mono_repo 6.5.7
- name: mono_repo self validate
run: dart pub global run mono_repo generate --validate
job_002:
- name: "analyze_and_format; Dart 2.19.0; PKGS: pkgs/corpus, pkgs/dart_flutter_team_lints, pkgs/firehose, pkgs/repo_manage; `dart analyze --fatal-infos .`"
+ name: "analyze_and_format; Dart 2.19.0; PKGS: pkgs/corpus, pkgs/dart_flutter_team_lints, pkgs/repo_manage; `dart analyze --fatal-infos .`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/corpus-pkgs/dart_flutter_team_lints-pkgs/firehose-pkgs/repo_manage;commands:analyze"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/corpus-pkgs/dart_flutter_team_lints-pkgs/repo_manage;commands:analyze"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/corpus-pkgs/dart_flutter_team_lints-pkgs/firehose-pkgs/repo_manage
+ os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/corpus-pkgs/dart_flutter_team_lints-pkgs/repo_manage
os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: "2.19.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_corpus_pub_upgrade
name: pkgs/corpus; dart pub upgrade
run: dart pub upgrade
@@ -77,15 +77,6 @@
run: dart analyze --fatal-infos .
if: "always() && steps.pkgs_dart_flutter_team_lints_pub_upgrade.conclusion == 'success'"
working-directory: pkgs/dart_flutter_team_lints
- - id: pkgs_firehose_pub_upgrade
- name: pkgs/firehose; dart pub upgrade
- run: dart pub upgrade
- if: "always() && steps.checkout.conclusion == 'success'"
- working-directory: pkgs/firehose
- - name: "pkgs/firehose; dart analyze --fatal-infos ."
- run: dart analyze --fatal-infos .
- if: "always() && steps.pkgs_firehose_pub_upgrade.conclusion == 'success'"
- working-directory: pkgs/firehose
- id: pkgs_repo_manage_pub_upgrade
name: pkgs/repo_manage; dart pub upgrade
run: dart pub upgrade
@@ -98,11 +89,43 @@
needs:
- job_001
job_003:
+ name: "analyze_and_format; Dart 3.0.0; PKG: pkgs/firehose; `dart analyze --fatal-infos .`"
+ runs-on: ubuntu-latest
+ steps:
+ - name: Cache Pub hosted dependencies
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
+ with:
+ path: "~/.pub-cache/hosted"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/firehose;commands:analyze"
+ restore-keys: |
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/firehose
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
+ os:ubuntu-latest;pub-cache-hosted
+ os:ubuntu-latest
+ - name: Setup Dart SDK
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
+ with:
+ sdk: "3.0.0"
+ - id: checkout
+ name: Checkout repository
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
+ - id: pkgs_firehose_pub_upgrade
+ name: pkgs/firehose; dart pub upgrade
+ run: dart pub upgrade
+ if: "always() && steps.checkout.conclusion == 'success'"
+ working-directory: pkgs/firehose
+ - name: "pkgs/firehose; dart analyze --fatal-infos ."
+ run: dart analyze --fatal-infos .
+ if: "always() && steps.pkgs_firehose_pub_upgrade.conclusion == 'success'"
+ working-directory: pkgs/firehose
+ needs:
+ - job_001
+ job_004:
name: "analyze_and_format; Dart dev; PKGS: pkgs/corpus, pkgs/dart_flutter_team_lints, pkgs/firehose, pkgs/repo_manage; `dart analyze --fatal-infos .`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/corpus-pkgs/dart_flutter_team_lints-pkgs/firehose-pkgs/repo_manage;commands:analyze"
@@ -112,12 +135,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_corpus_pub_upgrade
name: pkgs/corpus; dart pub upgrade
run: dart pub upgrade
@@ -156,12 +179,12 @@
working-directory: pkgs/repo_manage
needs:
- job_001
- job_004:
+ job_005:
name: "analyze_and_format; Dart dev; PKGS: pkgs/corpus, pkgs/dart_flutter_team_lints, pkgs/firehose, pkgs/repo_manage; `dart format --output=none --set-exit-if-changed .`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/corpus-pkgs/dart_flutter_team_lints-pkgs/firehose-pkgs/repo_manage;commands:format"
@@ -171,12 +194,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_corpus_pub_upgrade
name: pkgs/corpus; dart pub upgrade
run: dart pub upgrade
@@ -215,12 +238,12 @@
working-directory: pkgs/repo_manage
needs:
- job_001
- job_005:
+ job_006:
name: "unit_test; Dart 2.19.0; PKG: pkgs/corpus; `dart test`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/corpus;commands:test_1"
@@ -230,12 +253,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: "2.19.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_corpus_pub_upgrade
name: pkgs/corpus; dart pub upgrade
run: dart pub upgrade
@@ -250,12 +273,13 @@
- job_002
- job_003
- job_004
- job_006:
+ - job_005
+ job_007:
name: "unit_test; Dart 2.19.0; PKG: pkgs/dart_flutter_team_lints; `dart test`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/dart_flutter_team_lints;commands:test_1"
@@ -265,12 +289,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: "2.19.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_dart_flutter_team_lints_pub_upgrade
name: pkgs/dart_flutter_team_lints; dart pub upgrade
run: dart pub upgrade
@@ -285,27 +309,28 @@
- job_002
- job_003
- job_004
- job_007:
- name: "unit_test; Dart 2.19.0; PKG: pkgs/firehose; `dart test`"
+ - job_005
+ job_008:
+ name: "unit_test; Dart 3.0.0; PKG: pkgs/firehose; `dart test`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
- key: "os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/firehose;commands:test_1"
+ key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/firehose;commands:test_1"
restore-keys: |
- os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0;packages:pkgs/firehose
- os:ubuntu-latest;pub-cache-hosted;sdk:2.19.0
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0;packages:pkgs/firehose
+ os:ubuntu-latest;pub-cache-hosted;sdk:3.0.0
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
- sdk: "2.19.0"
+ sdk: "3.0.0"
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_firehose_pub_upgrade
name: pkgs/firehose; dart pub upgrade
run: dart pub upgrade
@@ -320,12 +345,13 @@
- job_002
- job_003
- job_004
- job_008:
+ - job_005
+ job_009:
name: "unit_test; Dart dev; PKG: pkgs/corpus; `dart test`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/corpus;commands:test_1"
@@ -335,12 +361,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_corpus_pub_upgrade
name: pkgs/corpus; dart pub upgrade
run: dart pub upgrade
@@ -355,12 +381,13 @@
- job_002
- job_003
- job_004
- job_009:
+ - job_005
+ job_010:
name: "unit_test; Dart dev; PKG: pkgs/dart_flutter_team_lints; `dart test`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/dart_flutter_team_lints;commands:test_1"
@@ -370,12 +397,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_dart_flutter_team_lints_pub_upgrade
name: pkgs/dart_flutter_team_lints; dart pub upgrade
run: dart pub upgrade
@@ -390,12 +417,13 @@
- job_002
- job_003
- job_004
- job_010:
+ - job_005
+ job_011:
name: "unit_test; Dart dev; PKG: pkgs/firehose; `dart test`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/firehose;commands:test_1"
@@ -405,12 +433,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_firehose_pub_upgrade
name: pkgs/firehose; dart pub upgrade
run: dart pub upgrade
@@ -425,12 +453,13 @@
- job_002
- job_003
- job_004
- job_011:
+ - job_005
+ job_012:
name: "analyze_format; Dart dev; PKG: pkgs/blast_repo; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/blast_repo;commands:format-analyze"
@@ -440,12 +469,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_blast_repo_pub_upgrade
name: pkgs/blast_repo; dart pub upgrade
run: dart pub upgrade
@@ -470,12 +499,13 @@
- job_008
- job_009
- job_010
- job_012:
+ - job_011
+ job_013:
name: "test; Dart dev; PKG: pkgs/blast_repo; `dart test --test-randomize-ordering-seed=random`"
runs-on: ubuntu-latest
steps:
- name: Cache Pub hosted dependencies
- uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
+ uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0
with:
path: "~/.pub-cache/hosted"
key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/blast_repo;commands:test_0"
@@ -485,12 +515,12 @@
os:ubuntu-latest;pub-cache-hosted
os:ubuntu-latest
- name: Setup Dart SDK
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
with:
sdk: dev
- id: checkout
name: Checkout repository
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- id: pkgs_blast_repo_pub_upgrade
name: pkgs/blast_repo; dart pub upgrade
run: dart pub upgrade
@@ -512,3 +542,4 @@
- job_009
- job_010
- job_011
+ - job_012
diff --git a/.github/workflows/health.yaml b/.github/workflows/health.yaml
new file mode 100644
index 0000000..49f964d
--- /dev/null
+++ b/.github/workflows/health.yaml
@@ -0,0 +1,71 @@
+# A CI configuration to check PR health.
+
+name: Health
+
+# Callers of this workflow should use it as follows:
+#
+# name: Health
+# on:
+# pull_request:
+# branches: [ main ]
+# types: [opened, synchronize, reopened, labeled, unlabeled]
+# jobs:
+# health:
+# uses: dart-lang/ecosystem/.github/workflows/health.yaml@main
+
+# 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.
+#
+# jobs:
+# health:
+# uses: dart-lang/ecosystem/.github/workflows/health.yaml@main
+# with:
+# sdk: beta
+# checks: "version,changelog,license"
+
+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
+ checks:
+ description: What to check for in the PR health check - any subset of "version,changelog,license"
+ default: "version,changelog,license"
+ type: string
+ required: false
+
+jobs:
+ health:
+ # These permissions are required for us to create comments on PRs.
+ permissions:
+ pull-requests: write
+
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
+ - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
+ with:
+ sdk: ${{ inputs.sdk }}
+
+ - name: Install firehose
+ run: dart pub global activate --source git https://github.com/dart-lang/ecosystem.git --git-path pkgs/firehose/ --git-ref=unifiedWorkflow #TODO remove, just for testing
+
+ - name: Validate packages
+ 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: dart pub global run firehose --health ${{ inputs.checks }}
diff --git a/.github/workflows/health_internal.yaml b/.github/workflows/health_internal.yaml
new file mode 100644
index 0000000..81616c5
--- /dev/null
+++ b/.github/workflows/health_internal.yaml
@@ -0,0 +1,12 @@
+# A CI configuration to check PR health.
+
+name: Health
+on:
+ pull_request:
+ branches: [ main ]
+ types: [opened, synchronize, reopened, labeled, unlabeled]
+jobs:
+ health:
+ uses: ./.github/workflows/health.yaml
+ with:
+ checks: "changelog,license"
\ No newline at end of file
diff --git a/pkgs/firehose/CHANGELOG.md b/pkgs/firehose/CHANGELOG.md
index 44c2b1c..2fca507 100644
--- a/pkgs/firehose/CHANGELOG.md
+++ b/pkgs/firehose/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.3.18-wip
+- Add Github workflow for PR health.
+
## 0.3.17
- Correctly parse pre-release versions from the CHANGELOG.
diff --git a/pkgs/firehose/README.md b/pkgs/firehose/README.md
index e923f9f..18134bf 100644
--- a/pkgs/firehose/README.md
+++ b/pkgs/firehose/README.md
@@ -1,11 +1,12 @@
[![pub package](https://img.shields.io/pub/v/firehose.svg)](https://pub.dev/packages/firehose)
[![package publisher](https://img.shields.io/pub/publisher/firehose.svg)](https://pub.dev/packages/firehose/publisher)
-## What's this?
+## firehose
+### What's this?
This is a tool to automate publishing of pub packages from GitHub actions.
-## Conventions and setup
+### Conventions and setup
When run from a PR, this tool will validate the package pubspecs and
changelogs and indicate whether the criteria for publishing has been met.
@@ -15,18 +16,18 @@
When run in response to a git tag event (a tag with a pattern like `v1.2.3` or
`name_v1.2.3` for monorepos), this tool will publish the indicated package.
-## Pre-release versions
+### Pre-release versions
Pre-release versions (aka, `'1.2.3-dev'`) are handled specially; this tool will
validate the package but will not auto-publish it. This can be used to
accumulate several changes and later publish them as a group.
-## Disabling auto-publishing
+### Disabling auto-publishing
In order to disable package validation and auto-publishing, add the
`publish_to: none` key to your pubspec.
-## PR branch actions
+### PR branch actions
For PRs, this tool:
@@ -34,7 +35,7 @@
- validates that the changelog version equals the pubspec version
- performs a `dart pub publish --dry-run`
-## Git tag actions
+### Git tag actions
In response to a git tag event, this tool:
@@ -42,7 +43,7 @@
- determines the indicated package
- attempts to publish that package (`dart pub publish --force`)
-## Mono-repos
+### Mono-repos
This tool can work with either single package repos or with mono-repos (repos
containing several packages). It will scan for and detect packages in a mono
@@ -52,7 +53,7 @@
For single package repos, the tag pattern should be `v1.2.3`. For mono-repos,
the tag pattern must be prefixed with the package name, e.g. `foo-v1.2.3`.
-## Integrating this tool into a repo
+### Integrating this tool into a repo
- copy the yaml below into a `.github/workflows/publish.yaml` file in your repo
- update the target branch below if necessary (currently, `main`)
@@ -78,7 +79,7 @@
uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main
```
-## Publishing from a specific version of the SDK
+### Publishing from a specific version of the SDK
Callers may optionally specify the version of the SDK to use when publishing a
package. This can be useful if your package has a very recent minimum SDK
@@ -94,7 +95,49 @@
sdk: beta
```
-## Workflow docs
+### Workflow docs
The description of the common workflow for repos using this tool can be found at
https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.
+
+<br/>
+
+## health
+
+### What's this?
+
+This is a Github workflow to check PR health.
+
+### Conventions and setup
+
+When run from a PR, this tool will check a configurable subset of the following
+
+* If the package versioning is correct and consistent, see `firehose` description above.
+* If a changelog entry has been added.
+* If all `.dart` files have a license header.
+
+This tool can work with either single package repos or with mono-repos (repos
+containing several packages).
+
+### Integrating this tool into a repo
+
+- copy the yaml below into a `.github/workflows/health.yaml` file in your repo
+- update the target branch below if necessary (currently, `main`)
+
+```yaml
+name: Health
+on:
+ pull_request:
+ branches: [ main ]
+ types: [opened, synchronize, reopened, labeled, unlabeled]
+jobs:
+ health:
+ uses: dart-lang/ecosystem/.github/workflows/health.yaml@main
+# with:
+# checks: "version,changelog,license"
+```
+
+### Workflow docs
+
+The description of the common workflow for repos using this tool can be found at
+https://github.com/dart-lang/ecosystem/wiki/Pull-Request-Health.
\ No newline at end of file
diff --git a/pkgs/firehose/bin/firehose.dart b/pkgs/firehose/bin/firehose.dart
index e561bd9..5e01d27 100644
--- a/pkgs/firehose/bin/firehose.dart
+++ b/pkgs/firehose/bin/firehose.dart
@@ -20,10 +20,11 @@
var validate = argResults['validate'] == true;
var publish = argResults['publish'] == true;
+ var health = argResults['health'] != null;
- if (!validate && !publish) {
- _usage(argParser,
- error: 'Error: one of --validate or --publish must be specified.');
+ if (!validate && !publish && !health) {
+ _usage(argParser, error: '''
+Error: one of --validate, --publish, or --health must be specified.''');
exit(1);
}
@@ -41,6 +42,8 @@
await firehose.validate();
} else if (publish) {
await firehose.publish();
+ } else if (health) {
+ await firehose.healthCheck(argResults['health'] as List);
}
} on ArgParserException catch (e) {
_usage(argParser, error: e.message);
@@ -73,6 +76,11 @@
help: 'Validate packages and indicate whether --publish would publish '
'anything.',
)
+ ..addMultiOption(
+ 'health',
+ defaultsTo: ['version', 'license', 'changelog'],
+ help: 'Check PR health.',
+ )
..addFlag(
'publish',
negatable: false,
diff --git a/pkgs/firehose/lib/firehose.dart b/pkgs/firehose/lib/firehose.dart
index 73c2740..56a51d4 100644
--- a/pkgs/firehose/lib/firehose.dart
+++ b/pkgs/firehose/lib/firehose.dart
@@ -2,9 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// ignore_for_file: always_declare_return_types
+
import 'dart:io';
+import 'dart:math';
import 'package:firehose/src/repo.dart';
+import 'package:path/path.dart' as path;
import 'src/github.dart';
import 'src/pub.dart';
@@ -15,6 +19,13 @@
const String _githubActionsUser = 'github-actions[bot]';
const String _publishBotTag = '## Package publishing';
+const String _publishBotTag2 = '### Package publish validation';
+
+const String _licenseBotTag = '### License Headers';
+
+const String _changelogBotTag = '### Changelog entry';
+
+const String _prHealthTag = '## PR Health';
const String _ignoreWarningsLabel = 'publish-ignore-warnings';
@@ -23,6 +34,178 @@
Firehose(this.directory);
+ Future<void> healthCheck(List argResult) async {
+ print('Start health check for the checks $argResult');
+ var checks = [
+ if (argResult.contains('version')) validateCheck,
+ if (argResult.contains('license')) licenseCheck,
+ if (argResult.contains('changelog')) changelogCheck,
+ ];
+ await _healthCheck(checks);
+ }
+
+ Future<void> _healthCheck(
+ List<Future<HealthCheckResult> Function(Github)> checks) async {
+ var github = Github();
+
+ // Do basic validation of our expected env var.
+ if (!_expectEnv(github.githubAuthToken, 'GITHUB_TOKEN')) return;
+ if (!_expectEnv(github.repoSlug, 'GITHUB_REPOSITORY')) return;
+ if (!_expectEnv(github.issueNumber, 'ISSUE_NUMBER')) return;
+ if (!_expectEnv(github.sha, 'GITHUB_SHA')) return;
+
+ if ((github.actor ?? '').endsWith(_botSuffix)) {
+ print('Skipping package validation for ${github.actor} PRs.');
+ return;
+ }
+
+ var checked =
+ await Future.wait(checks.map((check) => check(github)).toList());
+ await writeInComment(github, checked);
+
+ github.close();
+ }
+
+ Future<HealthCheckResult> validateCheck(Github github) async {
+ var results = await _validate(github);
+
+ var markdownTable = '''
+| Package | Version | Status | Publish tag (post-merge) |
+| :--- | ---: | :--- | ---: |
+${results.describeAsMarkdown}
+
+ ''';
+
+ return HealthCheckResult(
+ _publishBotTag2,
+ results.severity,
+ markdownTable,
+ );
+ }
+
+ Future<HealthCheckResult> licenseCheck(Github github) async {
+ final license = '''
+// Copyright (c) ${DateTime.now().year}, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.''';
+
+ var filePaths = await _getFilesWithoutLicenses(github);
+
+ var markdownResult = '''
+Some `.dart` files were found to not have license headers. Please add the following header to all listed files:
+```
+$license
+```
+
+| Files |
+| :--- |
+${filePaths.map((e) => '|$e|').join('\n')}
+
+Either manually or by running the following in your repository directory
+
+```
+dart pub global activate --source git https://github.com/mosuem/file_licenser
+dart pub global run file_licenser .
+```
+
+'''; //TODO: replace by pub.dev version
+
+ return HealthCheckResult(
+ _licenseBotTag,
+ filePaths.isNotEmpty ? Severity.error : Severity.success,
+ markdownResult,
+ );
+ }
+
+ Future<HealthCheckResult> changelogCheck(Github github) async {
+ var filePaths = await _packagesWithoutChangelog(github);
+
+ final markdownResult = '''
+Changes to these files need to be accounted for in their respective changelogs:
+
+| Package | Files |
+| :--- | :--- |
+${filePaths.entries.map((e) => '| package:${e.key.name} | ${e.value.map((e) => path.relative(e, from: Directory.current.path)).join('<br />')} |').join('\n')}
+''';
+
+ return HealthCheckResult(
+ _changelogBotTag,
+ filePaths.isNotEmpty ? Severity.error : Severity.success,
+ markdownResult,
+ );
+ }
+
+ Future<Map<Package, List<String>>> _packagesWithoutChangelog(
+ Github github) async {
+ final repo = Repository();
+ final packages = repo.locatePackages();
+
+ final files = await github.listFilesForPR();
+ print('Collecting packages without changed changelogs:');
+ final packagesWithoutChangedChangelog = packages.where((package) {
+ var changelogPath = package.changelog.file.path;
+ var changelog =
+ path.relative(changelogPath, from: Directory.current.path);
+ return !files.contains(changelog);
+ }).toList();
+ print('Done, found ${packagesWithoutChangedChangelog.length} packages.');
+
+ print('Collecting files without license headers in those packages:');
+ var packagesWithChanges = <Package, List<String>>{};
+ for (final file in files) {
+ for (final package in packagesWithoutChangedChangelog) {
+ if (fileNeedsEntryInChangelog(package, file)) {
+ print(file);
+ packagesWithChanges.update(
+ package,
+ (changedFiles) => [...changedFiles, file],
+ ifAbsent: () => [file],
+ );
+ }
+ }
+ }
+ print('''
+Done, found ${packagesWithChanges.length} packages with a need for a changelog.''');
+ return packagesWithChanges;
+ }
+
+ bool fileNeedsEntryInChangelog(Package package, String file) {
+ final directoryPath = package.directory.path;
+ final directory =
+ path.relative(directoryPath, from: Directory.current.path);
+ final isInPackage = path.isWithin(directory, file);
+ final isInLib = path.isWithin(path.join(directory, 'lib'), file);
+ final isInBin = path.isWithin(path.join(directory, 'bin'), file);
+ final isPubspec = file.endsWith('pubspec.yaml');
+ final isReadme = file.endsWith('README.md');
+ return isInPackage && (isInLib || isInBin || isPubspec || isReadme);
+ }
+
+ Future<List<String>> _getFilesWithoutLicenses(Github github) async {
+ var dir = Directory.current;
+ var dartFiles = await dir
+ .list(recursive: true)
+ .where((f) => f.path.endsWith('.dart'))
+ .toList();
+ print('Collecting files without license headers:');
+ var filesWithoutLicenses = dartFiles
+ .map((file) {
+ var fileContents = File(file.path).readAsStringSync();
+ var fileContainsCopyright = fileContents.contains('// Copyright (c)');
+ if (!fileContainsCopyright) {
+ var relativePath =
+ path.relative(file.path, from: Directory.current.path);
+ print(relativePath);
+ return relativePath;
+ }
+ })
+ .whereType<String>()
+ .toList();
+ print('''
+Done, found ${filesWithoutLicenses.length} files without license headers''');
+ return filesWithoutLicenses;
+ }
+
/// Validate the packages in the repository.
///
/// This method is intended to run in the context of a PR. It will:
@@ -53,8 +236,6 @@
Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.
''';
-
- // Write the publish info status to the job summary.
github.appendStepSummary(markdownTable);
var existingCommentId = await allowFailure(
@@ -99,6 +280,59 @@
github.close();
}
+ Future<void> writeInComment(
+ Github github,
+ List<HealthCheckResult> results,
+ ) async {
+ var commentText = results.map((e) {
+ var markdown = e.markdown;
+ var s = '''
+<details${e.severity == Severity.error ? ' open' : ''}>
+<summary>
+Details
+</summary>
+
+$markdown
+</details>
+
+''';
+ return '${e.tag} ${e.severity.emoji}\n\n$s';
+ }).join('\n');
+
+ var summary = '$_prHealthTag\n\n$commentText';
+ github.appendStepSummary(summary);
+
+ var repoSlug = github.repoSlug!;
+ var issueNumber = github.issueNumber!;
+
+ var existingCommentId = await allowFailure(
+ github.findCommentId(
+ repoSlug,
+ issueNumber,
+ user: _githubActionsUser,
+ searchTerm: _prHealthTag,
+ ),
+ logError: print,
+ );
+
+ if (existingCommentId == null) {
+ await allowFailure(
+ github.createComment(repoSlug, issueNumber, summary),
+ logError: print,
+ );
+ } else {
+ await allowFailure(
+ github.updateComment(repoSlug, existingCommentId, summary),
+ logError: print,
+ );
+ }
+
+ if (results.any((result) => result.severity == Severity.error) &&
+ exitCode == 0) {
+ exitCode = 1;
+ }
+ }
+
Future<VerificationResults> _validate(Github github) async {
var repo = Repository();
var packages = repo.locatePackages();
@@ -289,6 +523,9 @@
void addResult(Result result) => results.add(result);
+ Severity get severity =>
+ Severity.values[results.map((e) => e.severity.index).reduce(max)];
+
bool get hasSuccess => results.any((r) => r.severity == Severity.success);
bool get hasError => results.any((r) => r.severity == Severity.error);
@@ -310,6 +547,14 @@
}
}
+class HealthCheckResult {
+ final String tag;
+ final Severity severity;
+ final String markdown;
+
+ HealthCheckResult(this.tag, this.severity, this.markdown);
+}
+
class Result {
final Severity severity;
final Package package;
@@ -343,4 +588,10 @@
success,
info,
error;
+
+ String get emoji => switch (this) {
+ Severity.info => ':heavy_check_mark:',
+ Severity.error => ':exclamation:',
+ success => ':heavy_check_mark:',
+ };
}
diff --git a/pkgs/firehose/lib/src/github.dart b/pkgs/firehose/lib/src/github.dart
index 822d5e2..76a57a4 100644
--- a/pkgs/firehose/lib/src/github.dart
+++ b/pkgs/firehose/lib/src/github.dart
@@ -192,6 +192,19 @@
'https://api.github.com/repos/$repoSlug/issues/comments/$commentId'));
}
+ Future<List<String>> listFilesForPR() async {
+ var result = await callRestApiGet(
+ Uri.parse(
+ 'https://api.github.com/repos/$repoSlug/pulls/$issueNumber/files'),
+ );
+ var json = jsonDecode(result) as List;
+ var filenames = json
+ .map((e) => e as Map<String, dynamic>)
+ .map((e) => e['filename'] as String)
+ .toList();
+ return filenames;
+ }
+
void close() {
_httpClient?.close();
}
diff --git a/pkgs/firehose/pubspec.yaml b/pkgs/firehose/pubspec.yaml
index 9cf472a..205f46e 100644
--- a/pkgs/firehose/pubspec.yaml
+++ b/pkgs/firehose/pubspec.yaml
@@ -1,10 +1,10 @@
name: firehose
description: A tool to automate publishing of Pub packages from GitHub actions.
-version: 0.3.17
+version: 0.3.18-wip
repository: https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose
environment:
- sdk: '>=2.19.0 <3.0.0'
+ sdk: ^3.0.0
executables:
firehose: firehose