From c1a40e75bfab46368da8786bf60912fadf5db246 Mon Sep 17 00:00:00 2001 From: Claas Augner Date: Fri, 3 Apr 2026 15:20:31 +0200 Subject: [PATCH 1/8] ci(workflows): suggest lint fixes via reviewdog --- .github/workflows/pr-reviewdog.yml | 116 +++++++++++++++++++++++++++++ .github/workflows/test.yml | 33 +++++++- 2 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/pr-reviewdog.yml diff --git a/.github/workflows/pr-reviewdog.yml b/.github/workflows/pr-reviewdog.yml new file mode 100644 index 00000000000000..adf1fd73fb06e6 --- /dev/null +++ b/.github/workflows/pr-reviewdog.yml @@ -0,0 +1,116 @@ +name: PR Reviewdog + +on: + workflow_run: + workflows: + - "Test" + types: + - completed + +permissions: + # Download artifact from lint workflow. + actions: read + # Post inline review comments via reviewdog. + pull-requests: write + # Report commit status. + statuses: write + +jobs: + reviewdog: + runs-on: ubuntu-latest + env: + STATUS_PATH: repos/${{ github.repository }}/statuses/${{ github.event.workflow_run.head_sha }} + STATUS_CONTEXT: ${{ github.workflow }} + STATUS_TARGET: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + steps: + - name: Mark status as pending + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api "$STATUS_PATH" \ + -f state=pending \ + -f context="$STATUS_CONTEXT" \ + -f description='Running' \ + -f target_url="$STATUS_TARGET" + + - name: Identify PR + id: identify-pr + env: + BASE_REPO: ${{ github.repository }} + GITHUB_TOKEN: ${{ github.token }} + HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + run: | + PR_NUMBER=$(gh api "repos/$HEAD_REPO/commits/$HEAD_SHA/pulls" \ + --jq ".[] | select(.base.repo.full_name == \"$BASE_REPO\") | .number") + echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT + + - name: Download artifact + if: steps.identify-pr.outputs.number + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: lint-results + path: lint-results + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + + - name: Check for artifact + id: check + if: steps.identify-pr.outputs.number && hashFiles('lint-results/') != '' + run: echo "HAS_ARTIFACT=true" >> "$GITHUB_OUTPUT" + + - name: Checkout + if: steps.identify-pr.outputs.number + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + path: browser-compat-data + ref: main + persist-credentials: false + + - name: Setup reviewdog + if: steps.check.outputs.HAS_ARTIFACT == 'true' + uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1.5.0 + with: + reviewdog_version: latest + + - name: Add PR review with suggested changes using `git diff` output + if: steps.check.outputs.HAS_ARTIFACT == 'true' && hashFiles('lint-results/lint.diff') != '' + working-directory: browser-compat-data + env: + CI_PULL_REQUEST: ${{ steps.identify-pr.outputs.number }} + CI_COMMIT: ${{ github.event.workflow_run.head_sha }} + CI_REPO_OWNER: ${{ github.repository_owner }} + CI_REPO_NAME: ${{ github.event.repository.name }} + CI_BRANCH: ${{ github.event.workflow_run.head_branch }} + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + env -u GITHUB_ACTIONS reviewdog \ + -guess \ + -name="bcd-linter" \ + -f=diff \ + -f.diff.strip=1 \ + -filter-mode=diff_context \ + -reporter=github-pr-review < ../lint-results/lint.diff + + - name: Mark status as success + if: success() + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api "$STATUS_PATH" \ + -f state=success \ + -f context="$STATUS_CONTEXT" \ + -f description='Successful' \ + -f target_url="$STATUS_TARGET" + + - name: Mark status as failure + if: failure() + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api "$STATUS_PATH" \ + -f state=failure \ + -f context="$STATUS_CONTEXT" \ + -f description='Failing' \ + -f target_url="$STATUS_TARGET" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d8302f3ae940c..62d19bc5507532 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,7 +55,38 @@ jobs: - run: npm ci - - run: npm run lint -- --fail-on-warnings + - name: Lint + id: lint + run: | + LINT_FAILED=false + npm run lint -- --fail-on-warnings || LINT_FAILED=true + echo "failed=$LINT_FAILED" >> "$GITHUB_OUTPUT" + + - name: Fix lint issues + id: lint-fix + if: steps.lint.outputs.failed == 'true' + run: | + npm run lint:fix + if [[ -n $(git diff) ]]; then + echo "files_modified=true" >> "$GITHUB_OUTPUT" + fi + + - name: Collect artifact files + if: steps.lint-fix.outputs.files_modified == 'true' + run: | + mkdir -p lint-results + git diff > lint-results/lint.diff + + - name: Upload artifact + if: steps.lint-fix.outputs.files_modified == 'true' + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: lint-results + path: lint-results + + - name: Fail if lint failed + if: steps.lint.outputs.failed == 'true' + run: exit 1 test: runs-on: ubuntu-latest From 16c7f1c39f529d5c26e1c0f954f9f3c49e2f821d Mon Sep 17 00:00:00 2001 From: Claas Augner Date: Thu, 7 May 2026 17:58:33 +0200 Subject: [PATCH 2/8] docs(testing): document automated lint suggestions on PRs Explains the `bcd-linter` review suggestions that CI posts on pull requests when lint fails, and how contributors can apply them. --- docs/testing.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/testing.md b/docs/testing.md index be16403e705fa5..025d514ece3e40 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -22,6 +22,12 @@ For more information on the schema for feature data, see [`compat-data-schema.md For more information on the schema for browser data, see [`browsers-schema.md`](../schemas/browsers-schema.md) and [`browsers.schema.json`](../schemas/browsers.schema.json). +## Automated lint suggestions on pull requests + +When the lint check fails on a pull request, CI runs `npm run lint:fix` and posts the auto-fixable changes as inline review suggestions, attributed to `bcd-linter`. You can accept individual suggestions through GitHub's review UI, or apply all of them at once by running `npm run lint:fix` locally and committing the result. + +If a suggestion looks wrong (for example, the linter is reporting a false positive), reply on the suggestion explaining why — a maintainer can help. + ## Generate statistics To see how changes will affect the statistics of exact (formerly "real") and ranged values, you can run `npm run stats [folder]`. This generates a Markdown-formatted table of the percentages of exact and ranged values for the eight primary browsers that browser-compat-data is focusing on. The script also takes an optional argument regarding a specific folder (such as `api` or `javascript`), which will print statistics result for only that folder. Additionally, you can run the script with `--all` to get statistics for all browsers tracked in BCD, not just the primary eight. From 502a7f566087d2b74adc571c2f6dd48707861bbd Mon Sep 17 00:00:00 2001 From: Claas Augner Date: Thu, 7 May 2026 17:59:19 +0200 Subject: [PATCH 3/8] ci(pr-reviewdog): post sticky PR comment explaining lint suggestions When inline suggestions are posted, also create or update a single PR comment that links to the Test workflow run and to docs explaining how to apply or push back on the suggestions. --- .github/workflows/pr-reviewdog.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/pr-reviewdog.yml b/.github/workflows/pr-reviewdog.yml index adf1fd73fb06e6..823f4b6c36b58c 100644 --- a/.github/workflows/pr-reviewdog.yml +++ b/.github/workflows/pr-reviewdog.yml @@ -93,6 +93,30 @@ jobs: -filter-mode=diff_context \ -reporter=github-pr-review < ../lint-results/lint.diff + - name: Post or update PR comment with context + if: steps.check.outputs.HAS_ARTIFACT == 'true' && hashFiles('lint-results/lint.diff') != '' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + PR_NUMBER: ${{ steps.identify-pr.outputs.number }} + TEST_RUN_URL: ${{ github.event.workflow_run.html_url }} + run: | + BODY=" + The lint check found auto-fixable issues. Suggested changes have been posted as inline review comments above (attributed to \`bcd-linter\`). + + To apply all suggestions at once, run \`npm run lint:fix\` locally and commit the result. + + For details, see [Automated lint suggestions on pull requests](https://github.com/$REPO/blob/main/docs/testing.md#automated-lint-suggestions-on-pull-requests). Originating workflow run: [Test]($TEST_RUN_URL)." + + COMMENT_ID=$(gh api --paginate "repos/$REPO/issues/$PR_NUMBER/comments" \ + --jq '.[] | select(.body | startswith("")) | .id' | head -1) + + if [ -n "$COMMENT_ID" ]; then + gh api -X PATCH "repos/$REPO/issues/comments/$COMMENT_ID" -f body="$BODY" + else + gh api "repos/$REPO/issues/$PR_NUMBER/comments" -f body="$BODY" + fi + - name: Mark status as success if: success() env: From 97bca03e2521885e9c33c0c5eebd642926dfbdc8 Mon Sep 17 00:00:00 2001 From: Claas Augner Date: Thu, 7 May 2026 18:05:28 +0200 Subject: [PATCH 4/8] ci(pr-reviewdog): deep-link "lint check" to the lint job Looks up the lint job's URL from the originating Test workflow run so the sticky PR comment links directly to the lint logs instead of the run overview. Falls back to the workflow run URL if the job lookup returns nothing. Drops the now redundant "Originating workflow run" trailer. --- .github/workflows/pr-reviewdog.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-reviewdog.yml b/.github/workflows/pr-reviewdog.yml index 823f4b6c36b58c..d724de419a0ed9 100644 --- a/.github/workflows/pr-reviewdog.yml +++ b/.github/workflows/pr-reviewdog.yml @@ -99,14 +99,19 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPO: ${{ github.repository }} PR_NUMBER: ${{ steps.identify-pr.outputs.number }} + TEST_RUN_ID: ${{ github.event.workflow_run.id }} TEST_RUN_URL: ${{ github.event.workflow_run.html_url }} run: | + LINT_JOB_URL=$(gh api --paginate "repos/$REPO/actions/runs/$TEST_RUN_ID/jobs" \ + --jq '.jobs[] | select(.name == "lint") | .html_url' | head -1) + LINT_JOB_URL=${LINT_JOB_URL:-$TEST_RUN_URL} + BODY=" - The lint check found auto-fixable issues. Suggested changes have been posted as inline review comments above (attributed to \`bcd-linter\`). + The [lint check]($LINT_JOB_URL) found auto-fixable issues. Suggested changes have been posted as inline review comments above (attributed to \`bcd-linter\`). To apply all suggestions at once, run \`npm run lint:fix\` locally and commit the result. - For details, see [Automated lint suggestions on pull requests](https://github.com/$REPO/blob/main/docs/testing.md#automated-lint-suggestions-on-pull-requests). Originating workflow run: [Test]($TEST_RUN_URL)." + For details, see [Automated lint suggestions on pull requests](https://github.com/$REPO/blob/main/docs/testing.md#automated-lint-suggestions-on-pull-requests)." COMMENT_ID=$(gh api --paginate "repos/$REPO/issues/$PR_NUMBER/comments" \ --jq '.[] | select(.body | startswith("")) | .id' | head -1) From b71fdfc2db3e366342171ec0ba522129724532cc Mon Sep 17 00:00:00 2001 From: Claas Augner Date: Thu, 7 May 2026 18:06:52 +0200 Subject: [PATCH 5/8] ci(pr-reviewdog): only update sticky comments authored by the bot Filters the marker-comment lookup by author (github-actions[bot]) so a spoofed comment from another user starting with the same HTML marker can't be overwritten by the workflow. --- .github/workflows/pr-reviewdog.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-reviewdog.yml b/.github/workflows/pr-reviewdog.yml index d724de419a0ed9..7f882e4dc4ff4a 100644 --- a/.github/workflows/pr-reviewdog.yml +++ b/.github/workflows/pr-reviewdog.yml @@ -114,7 +114,7 @@ jobs: For details, see [Automated lint suggestions on pull requests](https://github.com/$REPO/blob/main/docs/testing.md#automated-lint-suggestions-on-pull-requests)." COMMENT_ID=$(gh api --paginate "repos/$REPO/issues/$PR_NUMBER/comments" \ - --jq '.[] | select(.body | startswith("")) | .id' | head -1) + --jq '.[] | select(.user.login == "github-actions[bot]" and (.body | startswith(""))) | .id' | head -1) if [ -n "$COMMENT_ID" ]; then gh api -X PATCH "repos/$REPO/issues/comments/$COMMENT_ID" -f body="$BODY" From 3eaedd9862b27e0fcc994d9cfc3ceacaef6f9593 Mon Sep 17 00:00:00 2001 From: Claas Augner Date: Thu, 7 May 2026 18:21:34 +0200 Subject: [PATCH 6/8] ci(test): let only the Lint step fail --- .github/workflows/test.yml | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2b858a56f5ed30..814d383bdbb643 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -57,14 +57,11 @@ jobs: - name: Lint id: lint - run: | - LINT_FAILED=false - npm run lint -- --fail-on-warnings || LINT_FAILED=true - echo "failed=$LINT_FAILED" >> "$GITHUB_OUTPUT" + run: npm run lint -- --fail-on-warnings - name: Fix lint issues id: lint-fix - if: steps.lint.outputs.failed == 'true' + if: failure() && steps.lint.conclusion == 'failure' run: | npm run lint:fix if [[ -n $(git diff) ]]; then @@ -72,22 +69,18 @@ jobs: fi - name: Collect artifact files - if: steps.lint-fix.outputs.files_modified == 'true' + if: failure() && steps.lint-fix.outputs.files_modified == 'true' run: | mkdir -p lint-results git diff > lint-results/lint.diff - name: Upload artifact - if: steps.lint-fix.outputs.files_modified == 'true' + if: failure() && steps.lint-fix.outputs.files_modified == 'true' uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: lint-results path: lint-results - - name: Fail if lint failed - if: steps.lint.outputs.failed == 'true' - run: exit 1 - test: runs-on: ubuntu-latest From 14e8d3e96d1b23eb91608e52377aea5d1e5a6543 Mon Sep 17 00:00:00 2001 From: Claas Augner <495429+caugner@users.noreply.github.com> Date: Wed, 13 May 2026 17:51:55 +0200 Subject: [PATCH 7/8] ci(pr-reviewdog): pin reviewdog_version --- .github/workflows/pr-reviewdog.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-reviewdog.yml b/.github/workflows/pr-reviewdog.yml index 7f882e4dc4ff4a..d3d8f8e1b0317f 100644 --- a/.github/workflows/pr-reviewdog.yml +++ b/.github/workflows/pr-reviewdog.yml @@ -72,7 +72,7 @@ jobs: if: steps.check.outputs.HAS_ARTIFACT == 'true' uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1.5.0 with: - reviewdog_version: latest + reviewdog_version: v0.21.0 - name: Add PR review with suggested changes using `git diff` output if: steps.check.outputs.HAS_ARTIFACT == 'true' && hashFiles('lint-results/lint.diff') != '' From 06eef9b4be1bffe8026963b9fa71f3b4dd2cbc8a Mon Sep 17 00:00:00 2001 From: Claas Augner Date: Wed, 13 May 2026 17:59:45 +0200 Subject: [PATCH 8/8] ci(pr-reviewdog): tighten message --- .github/workflows/pr-reviewdog.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-reviewdog.yml b/.github/workflows/pr-reviewdog.yml index d3d8f8e1b0317f..2bd5090dffecaf 100644 --- a/.github/workflows/pr-reviewdog.yml +++ b/.github/workflows/pr-reviewdog.yml @@ -107,11 +107,9 @@ jobs: LINT_JOB_URL=${LINT_JOB_URL:-$TEST_RUN_URL} BODY=" - The [lint check]($LINT_JOB_URL) found auto-fixable issues. Suggested changes have been posted as inline review comments above (attributed to \`bcd-linter\`). + The [lint check]($LINT_JOB_URL) found auto-fixable issues. Apply suggested changes (attributed to \`bcd-linter\`), or to fix all at once, run \`npm run lint:fix\` locally. - To apply all suggestions at once, run \`npm run lint:fix\` locally and commit the result. - - For details, see [Automated lint suggestions on pull requests](https://github.com/$REPO/blob/main/docs/testing.md#automated-lint-suggestions-on-pull-requests)." + See also: [Automated lint suggestions on pull requests](https://github.com/$REPO/blob/main/docs/testing.md#automated-lint-suggestions-on-pull-requests)" COMMENT_ID=$(gh api --paginate "repos/$REPO/issues/$PR_NUMBER/comments" \ --jq '.[] | select(.user.login == "github-actions[bot]" and (.body | startswith(""))) | .id' | head -1)