Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: ForgeRock Pull Request CI
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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.yml

Repository: 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)
PY

Repository: 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:


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


env:
NX_CLOUD_ENCRYPTION_KEY: ${{ secrets.NX_CLOUD_ENCRYPTION_KEY }}
Expand All @@ -14,6 +15,18 @@ concurrency:
cancel-in-progress: true

jobs:
block-merge-label:
runs-on: ubuntu-latest
steps:
Comment on lines +18 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 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:


🏁 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}")
PY

Repository: 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

- name: Fail if "Do not merge" label present
env:
LABELS: ${{ toJSON(github.event.pull_request.labels.*.name) }}
run: |
if echo "$LABELS" | tr '[:upper:]' '[:lower:]' | grep -q '"do not merge"'; then
echo "::error::Merge blocked: PR is labeled 'do not merge'."
exit 1
fi

pr:
if: ${{github.event.pull_request.head.repo.full_name == github.repository}}
runs-on: ubuntu-latest
Expand Down
Loading