Skip to content

ci(repo): post Major Version Check as a commit status on the PR head#8761

Open
jacekradko wants to merge 1 commit into
mainfrom
jacek/major-version-check-pr-head-status
Open

ci(repo): post Major Version Check as a commit status on the PR head#8761
jacekradko wants to merge 1 commit into
mainfrom
jacek/major-version-check-pr-head-status

Conversation

@jacekradko
Copy link
Copy Markdown
Member

@jacekradko jacekradko commented Jun 5, 2026

The major-version guard signalled pass/fail only through the implicit github-script job check-run. On issue_comment runs (the !allow-major approval re-run) that check-run is tied to the default branch, not the PR head, so approving a major bump never updated the PR head's status. That's what kept this check off the required list: requiring it as-is would leave a major PR blocked even after approval.

Now it posts an explicit Major Version Check commit status to the PR head SHA on every run, so the required context flips red to green correctly no matter which event triggered the run. The job intentionally stays green when it posts a red status, otherwise the approval re-run's green status would sit behind a stale red job check-run that never clears (the re-run lands on main, not the PR head).

listFiles/listComments are now paginated so a changeset or approval comment past the first page isn't missed, which matters once this gates merges.

Follow-up after this lands: add Major Version Check to the required status checks on main (and optionally release/v4 / release/core-2). It can't be added before merge or it would block every open PR waiting on a context that doesn't exist yet.

Summary by CodeRabbit

  • Chores
    • Major version check workflow now posts explicit commit status directly on pull request heads for enhanced visibility into version change reviews.
    • Implemented organization member approval requirement for major version changes detected through changeset analysis.
    • Enhanced workflow to handle issue comments and comprehensive changeset processing.

The major-version guard reported pass/fail only via the implicit github-script
job check-run. On issue_comment runs (the !allow-major re-run) that check-run is
tied to the default branch, not the PR head, so approving a major bump never
updated the PR head's status. That made the check unsafe to require: a major PR
would stay blocked even after approval.

Post an explicit "Major Version Check" commit status to the PR head SHA on every
run, so the required context flips red->green correctly regardless of trigger
event. Also paginate listFiles/listComments so a changeset or approval comment
past the first page isn't missed now that this gates merges.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 5, 2026

🦋 Changeset detected

Latest commit: 84d3685

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jun 5, 2026 12:18pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The PR refactors the major version check workflow to post explicit commit statuses on the PR head SHA instead of using step output failures. It adds pagination for files and comments, detects major changesets from .changeset/ YAML frontmatter, requires org-member approval via !allow-major comments, and resolves PR context for both trigger event types.

Changes

Major Version Check Workflow Refactor

Layer / File(s) Summary
Permissions, infrastructure, and changeset metadata
.changeset/major-version-check-pr-head-status.md, .github/workflows/major-version-check.yml (lines 13–14, 20–52)
Workflow permission adds statuses: write capability. GitHub Script consolidates PR/head SHA resolution for both pull_request and issue_comment events, and introduces a helper function to post commit statuses to the resolved PR head.
Major changeset detection with pagination
.github/workflows/major-version-check.yml (lines 54–83)
PR files are paginated to find .changeset/ entries. Each non-removed changeset file is fetched at the head ref, and the YAML frontmatter is scanned for a major value; detection exits early on first match.
Approval verification with org membership check
.github/workflows/major-version-check.yml (lines 90–116)
All PR comments are paginated to locate an exact match for !allow-major (case-insensitive/trimmed). The matching commenter is verified as a public organization member using orgs.checkMembershipForUser.
Commit status posting
.github/workflows/major-version-check.yml (lines 117–126)
Success or failure commit statuses replace core.setFailed. Approved changes post success; unapproved major changes post failure status and a warning log.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested Labels

actions

Suggested Reviewers

  • wobsoriano
  • tmilewski
  • brkalow

Poem

🐇 A rabbit hops through GitHub's lanes,
Commit statuses bloom where change remains,
Org members nod with !allow-major cheer,
YAML frontmatter shines crystal clear,
The workflow dances, pagination refined! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: posting the Major Version Check as a commit status on the PR head SHA, which is the core modification in this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 5, 2026

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@8761

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@8761

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@8761

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@8761

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@8761

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@8761

@clerk/express

npm i https://pkg.pr.new/@clerk/express@8761

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@8761

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@8761

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@8761

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@8761

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@8761

@clerk/react

npm i https://pkg.pr.new/@clerk/react@8761

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@8761

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@8761

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@8761

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@8761

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@8761

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@8761

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@8761

commit: 84d3685

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/major-version-check.yml:
- Around line 101-112: The catch block around
github.rest.orgs.checkMembershipForUser currently swallows all errors; change it
to only ignore a 404 by checking error?.status === 404 and continuing in that
case, but rethrow any other errors so transient 403/5xx fail fast; update the
catch that wraps the call to github.rest.orgs.checkMembershipForUser (the block
referencing comment.user.login and approvalFound) to implement this conditional
rethrow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: ebe6bfe6-06fb-45cb-85b5-de8a05713ccb

📥 Commits

Reviewing files that changed from the base of the PR and between 83f50f6 and 84d3685.

📒 Files selected for processing (2)
  • .changeset/major-version-check-pr-head-status.md
  • .github/workflows/major-version-check.yml

Comment on lines 101 to +112
try {
const { status } = await github.rest.orgs.checkMembershipForUser({
org,
username,
org: context.repo.owner,
username: comment.user.login,
});

if (status === 204) {
approvalFound = true;
break;
}
} catch (error) {
if (error.status !== 204) {
// User is not a public member
continue;
}
// Not a public org member; keep looking.
continue;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the referenced workflow section
sed -n '1,200p' .github/workflows/major-version-check.yml | nl -ba | sed -n '80,160p'

Repository: clerk/javascript

Length of output: 103


🌐 Web query:

GitHub REST API checkMembershipForUser error status codes 404 403 5xx and octokit behavior

💡 Result:

The GitHub REST API endpoint GET /orgs/{org}/members/{username}, accessible via octokit.rest.orgs.checkMembershipForUser, uses specific HTTP status codes to communicate membership status and authorization [1][2][3]. Status Codes Explained: - 204 No Content: The authenticated user is an organization member and the specified user is also a member of the organization [1][3]. - 302 Found: The authenticated user is not a member of the organization [1][3]. The response will typically redirect to check public membership instead [4]. - 404 Not Found: The authenticated user is an organization member, but the specified user is not a member of the organization [1][3]. This code is also returned if the organization or the user does not exist [5][6]. - 403 Forbidden: Returned if the request is made by a GitHub App that is blocked by the organization, if the requester has insufficient OAuth scopes (e.g., missing user or read:org), or if rate limits are exceeded [1][5][2]. Octokit Behavior: - Method Renaming: In older versions of Octokit, this was named checkMembership. It was renamed to checkMembershipForUser in version 18.0.0 [7]. - Error Handling: Octokit typically throws an error (often a RequestError or ApiException) for non-success status codes that are not explicitly handled as expected outcomes [8][9]. For example, in some Octokit implementations, a 404 response is caught and translated into a boolean false return value, while other error codes are raised as exceptions that your application must catch [9]. Always verify your specific version's implementation, as it may wrap these status codes differently depending on the language (e.g., Octokit.js vs Octokit.net) [9]. - 5xx Errors: These represent server-side issues at GitHub and are not specific to this endpoint. Octokit will generally throw these as exceptions [5]. Recommendation: Always implement robust error handling (e.g., try-catch blocks) when calling this method, as it relies on specific status codes to distinguish between successful membership checks and various failure scenarios [5][9].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the referenced range with line numbers using awk (nl isn't available here)
awk 'NR>=80 && NR<=150 { printf "%4d\t%s\n", NR, $0 }' .github/workflows/major-version-check.yml

Repository: clerk/javascript

Length of output: 2463


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find other usages of checkMembershipForUser
rg -n "checkMembershipForUser\\(" -S .github/workflows || true

# Find common error shape handling patterns in workflows
rg -n "error\\?\\.status|error\\.status|statusCode" .github/workflows || true

Repository: clerk/javascript

Length of output: 582


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,120p' .github/workflows/e2e-staging.yml | nl -ba | sed -n '35,95p'

Repository: clerk/javascript

Length of output: 103


🏁 Script executed:

#!/bin/bash
set -euo pipefail

awk 'NR>=30 && NR<=110 { printf "%4d\t%s\n", NR, $0 }' .github/workflows/e2e-staging.yml

Repository: clerk/javascript

Length of output: 3366


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show top of workflow + setStatus helper and surrounding control flow
awk 'NR<=220 { printf "%4d\t%s\n", NR, $0 }' .github/workflows/major-version-check.yml

Repository: clerk/javascript

Length of output: 6141


Only treat 404 as “not a member” in checkMembershipForUser

In .github/workflows/major-version-check.yml (lines ~101-113), the catch currently continues on any checkMembershipForUser failure, so transient 403/5xx can wrongly prevent recognizing a valid !allow-major and flip an approved PR to failed. Keep swallowing 404, but rethrow everything else (repo already uses the error?.status === 404 pattern in .github/workflows/e2e-staging.yml).

Suggested fix
                 try {
                   const { status } = await github.rest.orgs.checkMembershipForUser({
                     org: context.repo.owner,
                     username: comment.user.login,
                   });
                   if (status === 204) {
                     approvalFound = true;
                     break;
                   }
                 } catch (error) {
-                  // Not a public org member; keep looking.
-                  continue;
+                  if (error?.status === 404) {
+                    // Not a public org member; keep looking.
+                    continue;
+                  }
+                  throw error;
                 }
               }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
const { status } = await github.rest.orgs.checkMembershipForUser({
org,
username,
org: context.repo.owner,
username: comment.user.login,
});
if (status === 204) {
approvalFound = true;
break;
}
} catch (error) {
if (error.status !== 204) {
// User is not a public member
continue;
}
// Not a public org member; keep looking.
continue;
try {
const { status } = await github.rest.orgs.checkMembershipForUser({
org: context.repo.owner,
username: comment.user.login,
});
if (status === 204) {
approvalFound = true;
break;
}
} catch (error) {
if (error?.status === 404) {
// Not a public org member; keep looking.
continue;
}
throw error;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/major-version-check.yml around lines 101 - 112, The catch
block around github.rest.orgs.checkMembershipForUser currently swallows all
errors; change it to only ignore a 404 by checking error?.status === 404 and
continuing in that case, but rethrow any other errors so transient 403/5xx fail
fast; update the catch that wraps the call to
github.rest.orgs.checkMembershipForUser (the block referencing
comment.user.login and approvalFound) to implement this conditional rethrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant