Skip to content

Run lint as a plain CI job so fork PRs report status - #1494

Merged
brianr merged 2 commits into
masterfrom
ci/lint-job-for-fork-prs
Sep 28, 2026
Merged

brianr merged 2 commits into
masterfrom
ci/lint-job-for-fork-prs

Conversation

@brianr

@brianr brianr commented Sep 27, 2026

Copy link
Copy Markdown
Member

Description of the change

PRs opened from forks can't be merged without an admin override, because the required ESLint and Prettier checks never show up (e.g. #1477).

Cause: wearerequired/lint-action doesn't pass or fail the job itself. It reports results by creating separate ESLint/Prettier check runs through the Checks API, which needs checks: write. GitHub always gives pull_request runs from forks a read-only token, whatever the workflow's permissions: block says, so creating the check runs fails:

ESLint found no issues (success)
Prettier found no issues (success)
Creating GitHub check with success conclusion and 0 annotations for ESLint…
##[error]Received status code 403. Resource not accessible by integration

Because the action runs with continue_on_error: true, the step still passes. So on fork PRs the required checks stay pending forever, and a fork PR with real lint errors would still finish green.

Fix: replace the action with a single lint job that runs the existing npm run lint -- --max-warnings 0 and npm run format:check scripts, so the job itself fails on lint errors. This also:

  • runs lint once instead of once per matrix leg
  • drops the checks: write permission, which only the action used

Trade-off: we lose the action's inline annotations on the diff. They never worked for fork PRs anyway.

⚠️ Branch protection must change with this PR

master currently requires the ESLint and Prettier checks, and this PR no longer produces them, so this PR will itself show as blocked until the rule changes. A repo admin needs to update Settings → Branches → master → Required status checks:

  • remove ESLint and Prettier
  • add lint

Do this right before merging. Once it's done, open PRs that haven't merged this change yet won't report lint until they're updated from master (which the strict up-to-date rule already requires).

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Maintenance
  • New release

Related issues

Checklists

Development

  • Lint rules pass locally (npm run lint -- --max-warnings 0 and npm run format:check both pass on this branch)
  • The code changed/added as part of this pull request has been covered with tests
  • All tests related to the changed code pass in development

Code review

  • This pull request has a descriptive title and information useful to a reviewer. There may be a screenshot or screencast attached
  • "Ready for review" label attached to the PR and reviewers assigned
  • Issue from task tracker has a link to this pull request
  • Changes have been reviewed by at least one other engineer

🤖 Generated with Claude Code

wearerequired/lint-action reports results by creating ESLint/Prettier
check runs, which needs checks: write. GitHub gives pull_request runs
from forks a read-only token, so check-run creation 403s, the step still
passes (continue_on_error), and the required ESLint/Prettier checks stay
pending forever, blocking merge (e.g. #1477).

Replace it with a single `lint` job that runs the existing `lint` and
`format:check` scripts, so the job itself fails on lint errors, and drop
the now-unused checks: write permission.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-27T20:53:05.743922Z 41687a2 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@rollbar-circleci-machine

Copy link
Copy Markdown

AI Agent Review (openai, openai-astra)

Nothing to flag. The new lint job runs the same checks the removed wearerequired/lint-action step did.

  • ESLint: npm run lint -- --max-warnings 0 runs eslint --max-warnings 0 (package.json:144). With no file arguments, the installed ESLint 9.39.5 lints . (node_modules/eslint/lib/eslint/eslint.js:965-977), as lint-action did. File selection and ignores still come from eslint.config.js:103-150.
  • Prettier: format:check (package.json:147) covers js,cjs,mjs,md,json,yml,yaml, the same extensions as before, and still respects .prettierignore. CONTRIBUTING.md:52 already says CI uses format:check.
  • Install: package.json has no prepare/postinstall script, so npm install in the lint job only installs packages.
  • Permissions: no other job needs checks: write.
  • Behaviour change (intended): lint failures now fail the job itself instead of only showing up as separate check runs, and lint runs once instead of on every Node version.

Before merging: if branch protection on master requires the check runs lint-action used to create (probably named ESLint / Prettier), those checks will never report again and every PR will stay pending. Update the required checks to the new lint job. This is a repo setting and can't be confirmed from the checkout.

This review did not run CI, so it can't say whether the job passes. If there are existing import/order warnings (set to warn in eslint.config.js:44-45), --max-warnings 0 will fail the job.

@rollbar-circleci-machine

Copy link
Copy Markdown

AI Agent Review LGTM (openai, openai-astra)

LGTM. No blocking findings were found.

LGTM. This PR removes wearerequired/lint-action and the workflow-wide checks: write permission. Linting now runs in its own lint job, which passes or fails on its own result, so PRs from forks get a real status.

What I checked in the checkout:

  • ESLint covers the same files as before. npm run lint -- --max-warnings 0 becomes eslint --max-warnings 0 (package.json:144). With no path given, ESLint 9.39.5 lints the current directory (node_modules/eslint/lib/eslint/eslint.js:965-977). The flat config's ignores apply (eslint.config.js:149). The import/order rule is set to warn (eslint.config.js:44-61), so --max-warnings 0 still fails the build on it, as it did before.
  • Prettier covers the same files as before. format:check (package.json:147) uses the same js,cjs,mjs,md,json,yml,yaml extensions as the old prettier_extensions input and still reads .prettierignore.
  • No other step needs checks: write. Removing it is safe; nothing else in the workflow uses a token.
  • Linting doesn't need a build. The ESLint config has no type-aware rules and no import/no-unresolved, and package.json has no prepare or postinstall hook. The job can run on its own, in parallel with build.
  • Lint no longer runs four times. The old action ran on every Node leg of the build matrix. It now runs once.

Notes that are not line findings:

  1. Required checks in branch protection (couldn't verify from the repo). The old action created check runs named after each linter (e.g. ESLint / Prettier). The new status context is the job id, lint; the step names don't create checks. If branch protection requires the old names, every PR will sit pending after merge, not just fork PRs. Update the required checks to lint when this merges.
  2. Optional: Prettier stops if ESLint fails. The Prettier step uses the default if: success(), so it's skipped when ESLint fails. The old action reported both. Impact is small: ESLint already runs Prettier on JS through eslint-plugin-prettier (eslint.config.js:6,24), so only md/json/yml results would be delayed. Adding if: ${{ !cancelled() }} to the Prettier step would show both results in one run.
  3. Consistency, not a defect. Like build, the new job uses npm install without npm caching. Switching both jobs to npm ci with cache: npm would make installs faster and more reproducible.

I can't run anything in this environment, so I couldn't confirm the workflow passes in CI.

@brianr brianr self-assigned this Sep 28, 2026
@brianr
brianr enabled auto-merge September 28, 2026 21:08
@brianr
brianr disabled auto-merge September 28, 2026 21:08
@brianr
brianr enabled auto-merge September 28, 2026 21:09
@brianr
brianr merged commit 036cb73 into master Sep 28, 2026
5 checks passed
@brianr
brianr deleted the ci/lint-job-for-fork-prs branch September 28, 2026 21:12
devtools-agent Bot pushed a commit that referenced this pull request Sep 28, 2026
Resolve the .github/workflows/ci.yml conflict with #1494, which moved
linting out of the build job into its own lint job. Drop the old
wearerequired/lint-action step and keep this branch's Type check step
in the build job, between npm install and Build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants