ci: block merge when PR is labeled 'do not merge'- #572 - #754
ci: block merge when PR is labeled 'do not merge'- #572#754SteinGabriel wants to merge 1 commit into
Conversation
|
📝 WalkthroughWalkthroughThe CI workflow now runs when pull-request labels change. A new job fails CI when a pull request has a case-insensitive ChangesMerge Label Enforcement
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/ci.yml:
- Around line 18-20: Add job-level permissions: {} to the block-merge-label
workflow job, alongside runs-on and before steps, leaving the existing
label-reading logic unchanged.
- Line 4: Update the workflow’s pr condition to exclude labeled and unlabeled
actions while preserving execution for the intended pull request actions;
alternatively, isolate block-merge-label in a separate workflow so label-only
events cannot rerun builds, publishing, documentation deployment, or comment
updates.
🪄 Autofix
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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 9a6ed1de-ccb6-4c06-87bd-fb54764e0004
📒 Files selected for processing (1)
.github/workflows/ci.yml
| name: ForgeRock Pull Request CI | ||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened, labeled, unlabeled] |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- workflow files ---'
git ls-files '.github/workflows/*'
printf '%s\n' '--- ci.yml outline ---'
wc -l .github/workflows/ci.yml
printf '%s\n' '--- relevant workflow content ---'
cat -n .github/workflows/ci.ymlRepository: ForgeRock/ping-javascript-sdk
Length of output: 9170
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
import re
path = Path(".github/workflows/ci.yml")
text = path.read_text()
types_match = re.search(r"(?m)^\s+types:\s*\[([^\]]+)\]", text)
pr_match = re.search(
r"(?ms)^ pr:\n(?P<body>.*?)(?=^ \S[^ \n]*:|\Z)",
text,
)
if not types_match or not pr_match:
raise SystemExit("Could not locate the pull_request types or pr job")
event_types = [item.strip() for item in types_match.group(1).split(",")]
pr_body = pr_match.group("body")
pr_if = re.search(r"(?m)^\s+if:\s*(.+)$", pr_body)
if not pr_if:
raise SystemExit("The pr job has no condition")
print("pull_request activity types:", event_types)
print("label-only activity types enabled:",
{"labeled", "unlabeled"}.issubset(event_types))
print("pr condition:", pr_if.group(1).strip())
print("pr condition checks event.action:",
"github.event.action" in pr_if.group(1))
side_effect_lines = []
for number, line in enumerate(pr_body.splitlines(), start=1):
if re.search(r"(preview-pages|sticky-pull-request-comment|create-or-update-comment|pkg-pr-new|contents:\s*write)", line):
side_effect_lines.append(line.strip())
print("pr side-effect or write-capability references:")
for line in side_effect_lines:
print(" ", line)
PYRepository: ForgeRock/ping-javascript-sdk
Length of output: 826
🌐 Web query:
GitHub Actions pull_request activity types workflow-level filtering and job-level if condition for labeled and unlabeled events
💡 Result:
To manage GitHub Actions workflows based on pull request label events, you must configure the workflow-level trigger to include the labeled and unlabeled activity types, and then use job-level if conditions to inspect the specific labels. Workflow-Level Filtering The pull_request event, by default, only triggers on opened, synchronize, and reopened activity types [1][2]. To react to changes in pull request labels, you must explicitly include the labeled and unlabeled types in the workflow definition using the types keyword [1][2]: on: pull_request: types: [opened, synchronize, labeled, unlabeled] There is no native capability to filter for specific labels at the workflow trigger level (e.g., triggering only when a label named 'ready' is added) [3]. You must include these activity types, which causes the workflow to trigger whenever any label is added or removed from a pull request [3]. Job-Level Condition Filtering Because the workflow triggers on all label changes, you must use the jobs.<job_id>.if condition to restrict execution to your desired logic [4][3]. You can inspect the github.event payload within the if expression to check for the presence or absence of specific labels [4][3]. Example: jobs: run-if-labeled: if: contains(github.event.pull_request.labels.*.name, 'my-target-label') runs-on: ubuntu-latest steps: - run: echo "The label is present." In this example, the job will run only if the pull request has the label 'my-target-label' at the time of the event [3]. When a label is removed, the unlabeled event triggers the workflow, the if condition evaluates to false, and the job is skipped [3]. Skipped jobs are reported as successful, which is important to consider if the job is part of a required status check [4][5].
Citations:
- 1: https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows
- 2: https://docs.github.com/actions/using-workflows/events-that-trigger-workflows
- 3: https://mergify.com/blog/stop-using-labels-to-control-ci-in-github-actions
- 4: https://docs.github.com/actions/using-jobs/using-conditions-to-control-job-execution
- 5: https://github.com/github/docs/blob/main/content/actions/how-tos/write-workflows/choose-when-workflows-run/control-jobs-with-conditions.md
Guard pr against label-only events.
labeled and unlabeled trigger the entire workflow. The existing pr condition only checks the repository, so same-repository label changes rerun builds, publishing, documentation deployment, and comment updates. Add an github.event.action guard to pr, or move block-merge-label to a separate workflow.
🤖 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/ci.yml at line 4, Update the workflow’s pr condition to
exclude labeled and unlabeled actions while preserving execution for the
intended pull request actions; alternatively, isolate block-merge-label in a
separate workflow so label-only events cannot rerun builds, publishing,
documentation deployment, or comment updates.
Source: MCP tools
| block-merge-label: | ||
| runs-on: ubuntu-latest | ||
| steps: |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- .github/workflows/ci.yml ---'
cat -n .github/workflows/ci.yml
printf '%s\n' '--- workflow permission and trigger references ---'
rg -n -C 3 '(^|[[:space:]])(permissions|on:|types:|block-merge-label|GITHUB_TOKEN|github\.event)' .github/workflows/ci.yml
printf '%s\n' '--- repository workflow files ---'
git ls-files '.github/workflows/*'Repository: ForgeRock/ping-javascript-sdk
Length of output: 12109
🌐 Web query:
GitHub Actions workflow syntax job-level permissions permissions: {} GITHUB_TOKEN official documentation
💡 Result:
In GitHub Actions, the permissions: {} syntax is used within a workflow file to explicitly disable all permissions for the GITHUB_TOKEN [1][2]. When you use the permissions key in your workflow—either at the top level or within a specific job—all permissions are set to none by default unless you explicitly grant them [1][2]. Consequently, defining permissions: {} effectively removes all access rights for the GITHUB_TOKEN within that scope [1][3]. Key points regarding this syntax include: - Scope: You can apply permissions: {} globally at the workflow level or restrict it to an individual job by placing it under jobs.<job_id>.permissions [1][2]. - Behavior: If you define the permissions key, any permissions not explicitly specified are set to none [1][2]. By providing an empty object ({}), you ensure that no permissions are granted [1]. - Security: This is a recommended security practice to follow the principle of least privilege, ensuring that the GITHUB_TOKEN does not have access to resources it does not need [4][5]. - Default behavior: Without an explicit permissions block, the GITHUB_TOKEN defaults to the permissions configured at the repository or organization level [6]. For detailed reference, you can consult the official GitHub Actions workflow syntax documentation [2].
Citations:
- 1: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax?use_case=
- 2: https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions
- 3: https://docs.github.com/en/enterprise-cloud@latest/actions/reference/workflows-and-actions/workflow-syntax
- 4: https://docs.github.com/en/actions/tutorials/authenticate-with-github_token
- 5: https://docs.github.com/actions/reference/authentication-in-a-workflow
- 6: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
path = Path(".github/workflows/ci.yml")
lines = path.read_text().splitlines()
def block(start, indent):
out = []
for line in lines[start + 1:]:
if line.strip() and len(line) - len(line.lstrip()) <= indent:
break
out.append(line)
return out
jobs = {}
for i, line in enumerate(lines):
if line.startswith(" ") and not line.startswith(" ") and line.rstrip().endswith(":"):
name = line.strip()[:-1]
if name in {"block-merge-label", "pr"}:
jobs[name] = block(i, 2)
for name, body in jobs.items():
keys = [line.strip().split(":", 1)[0] for line in body
if line.startswith(" ") and not line.startswith(" ")
and line.strip() and not line.lstrip().startswith("#")]
print(f"{name}: top-level job keys={keys}")
print(f"{name}: has permissions key={'permissions' in keys}")
root_env = []
in_env = False
for line in lines:
if line == "env:":
in_env = True
continue
if in_env:
if line and len(line) - len(line.lstrip()) <= 0:
break
if line.startswith(" ") and not line.startswith(" "):
root_env.append(line.strip().split(":", 1)[0])
print(f"workflow-level env keys={root_env}")
PYRepository: ForgeRock/ping-javascript-sdk
Length of output: 484
Set permissions: {} for block-merge-label.
This job only reads pull request labels and does not use GITHUB_TOKEN. Without job-level permissions, it inherits repository or organization defaults. Add permissions: {} to disable all token permissions.
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 18-28: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
🤖 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/ci.yml around lines 18 - 20, Add job-level permissions: {}
to the block-merge-label workflow job, alongside runs-on and before steps,
leaving the existing label-reading logic unchanged.
Sources: MCP tools, Linters/SAST tools
ci: make Do-not-merge label check case-insensitive ci: standardize block-merge-label error message
85f48fb to
86f9d4b
Compare
|
View your CI Pipeline Execution ↗ for commit 86f9d4b
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗ ☁️ Nx Cloud last updated this comment at |
@forgerock/davinci-client
@forgerock/device-client
@forgerock/journey-client
@forgerock/oidc-client
@forgerock/protect
@forgerock/sdk-types
@forgerock/sdk-utilities
@forgerock/iframe-manager
@forgerock/sdk-logger
@forgerock/sdk-oidc
@forgerock/sdk-request-middleware
@forgerock/storage
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project status has failed because the head coverage (23.94%) is below the target coverage (40.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #754 +/- ##
==========================================
+ Coverage 18.07% 23.94% +5.87%
==========================================
Files 155 162 +7
Lines 24398 25722 +1324
Branches 1203 1669 +466
==========================================
+ Hits 4410 6160 +1750
+ Misses 19988 19562 -426 🚀 New features to boost your workflow:
|
|
Deployed d8bb22a to https://ForgeRock.github.io/ping-javascript-sdk/pr-754/d8bb22a8cfbb1b116935101cf59a6dad6fe0ad42 branch gh-pages in ForgeRock/ping-javascript-sdk |
📦 Bundle Size Analysis📦 Bundle Size Analysis🆕 New Packages🆕 @forgerock/journey-client - 92.6 KB (new) ➖ No Changes➖ @forgerock/davinci-client - 56.7 KB 14 packages analyzed • Baseline from latest Legend🆕 New package ℹ️ How bundle sizes are calculated
🔄 Updated automatically on each push to this PR |
Summary
Cross-repo CI gate. Adds a
block-merge-labeljob that fails when a PR carries a "do not merge" label (case-insensitive), so it can be wired up as a required status check. Part of a 3-repo rollout (ping-javascript-sdk, forgerock-web-login-framework, sdk-sample-apps) — this PR coversforgerock-web-login-framework.Note: this job must also be added as a required status check in this repo's GitHub branch protection settings — see Risks / Notes below. Adding the workflow job alone does not enforce merge blocking.
Changes
.github/workflows/ci.ymlpull_requesttrigger added (opened,synchronize,reopened,labeled,unlabeled) alongside existingpushtrigger.block-merge-labeljob: reads PR labels viatoJSON(github.event.pull_request.labels.*.name), lowercases withtr, greps for"do not merge". Fails with::error::annotation if matched.build/test-lint-storybook-buildjobs) so it can be required independently without coupling to full pipeline result.Tests
pnpm exec prettier --check.How to test
1. Confirm block on labeled PR
Apply "do not merge" (or any casing variant) label to an open PR against this branch. Confirm
block-merge-labeljob fails, error annotation shows "Merge blocked: PR is labeled 'do not merge'."2. Confirm pass on unlabeled PR
Remove label (
unlabeledevent fires). Confirm job re-runs and passes.Risks / Notes
do not merge, case-insensitive. Repos using a different label string need manual sync — no config surface.pull_requestevent payload.block-merge-labelmust be added as a required status check in the repo's GitHub branch protection settings (Settings → Branches → main → require status checks) for this gate to actually block merging. Adding the job alone does not enforce anything.Summary by CodeRabbit