Skip to content

maintenance/maint release utils#652

Open
greenc-FNAL wants to merge 2 commits into
mainfrom
maintenance/maint-release-utils
Open

maintenance/maint release utils#652
greenc-FNAL wants to merge 2 commits into
mainfrom
maintenance/maint-release-utils

Conversation

@greenc-FNAL

@greenc-FNAL greenc-FNAL commented Jun 17, 2026

Copy link
Copy Markdown
Contributor
  • Maintenance improvements
  • Release utility scripts

CI/Workflows

  • dependabot-auto-merge.yaml: Updated to use secrets.GITHUB_TOKEN instead of secrets.WORKFLOW_PAT for the GH_TOKEN environment variable, eliminating the need for a separate workflow PAT. Also added repository-projects: write permission.

  • guardrail-audit-alert.yaml (new): Monitors pushes to main branch and sends Slack notifications when non-Dependabot commits are pushed directly (bypassing guardrails). Uses SLACK_WEBHOOK_URL secret, jq for safe JSON payload construction, and curl to POST alerts.

Release Utilities

  • 01-detect-tier1.sh (new): Classifies repositories in actions/* directories as Tier 1 by examining internal dependencies and detecting unreleased changes. Checks for Framework-R-D/ references in action.yaml and inspects git log for changes since the latest tag.

  • 02-execute-release.sh (new): Automates the complete release workflow including:

    • Syncing with upstream and computing next version tag
    • Validating CHANGELOG.md has an entry for the new version
    • Creating annotated Git tag and pushing to upstream
    • Generating GitHub release notes via gh release create --generate-notes
    • Computing immutable SHA for the tag via gh api
    • Updating README.md with new pinned SHA and version
    • Committing and pushing README changes to main
  • trigger-dependabot.sh (new): Forces Dependabot re-scan by injecting a UTC timestamp comment into .github/dependabot.yml, creating a temporary automation branch, opening and closing a short-lived PR to trigger the scan, then cleaning up.

  • view-dependabot-logs.sh (new): Convenience utility that opens the Dependabot Management UI deep link (/network/updates) using gh repo view to fetch the repo URL, with xdg-open (Linux) or open (macOS) fallbacks.

- `dependabot-auto-merge` no longer needs `WORKFLOW_PAT`
- `guardrail-audit-alert` to report to Slack on safeguard bypass by
  admins (e.g. push to `main`, merge without approval).
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds four Bash release automation scripts (01-detect-tier1.sh, 02-execute-release.sh, trigger-dependabot.sh, view-dependabot-logs.sh) for detecting unreleased action changes, executing a full versioned release with README SHA pinning, force-triggering Dependabot re-scans, and opening Dependabot logs. Also updates the Dependabot auto-merge workflow permissions and token, and adds a new Slack guardrail alert workflow for main branch pushes.

Changes

CI/CD Workflow Changes

Layer / File(s) Summary
Dependabot auto-merge permission and token update
.github/workflows/dependabot-auto-merge.yaml
Adds repository-projects: write to workflow permissions and replaces secrets.WORKFLOW_PAT with secrets.GITHUB_TOKEN for GH_TOKEN in the auto-merge step.
Guardrail push alert Slack workflow
.github/workflows/guardrail-audit-alert.yaml
New workflow triggered on pushes to main that skips Dependabot, disables all token permissions, and conditionally POSTs a jq-constructed Slack payload via curl when the committer is not GitHub.

Release Automation Scripts

Layer / File(s) Summary
Tier 1 change detection
scripts/release/01-detect-tier1.sh
Loops over actions/* subdirectories, fetches tags, filters out Framework-R-D/ dependents, and reports each repo as needing an initial release, having unreleased action.yaml changes since the latest tag, or being clean.
End-to-end release execution
scripts/release/02-execute-release.sh
Syncs main from upstream, derives the next v<N> tag from git describe, validates a matching CHANGELOG.md heading, creates and pushes an annotated tag, publishes a GitHub release with autogenerated notes, resolves the tag's immutable SHA via gh api, and pins it in README.md before committing to upstream main.
Dependabot trigger and log-viewer utilities
scripts/release/trigger-dependabot.sh, scripts/release/view-dependabot-logs.sh
trigger-dependabot.sh injects a UTC timestamp into .github/dependabot.yml on a short-lived branch, opens and immediately closes a PR to force a re-scan, then syncs the default branch. view-dependabot-logs.sh resolves the repo URL via gh and opens the Dependabot network/updates page in the OS default browser.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • knoepfel
  • marcpaterno
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title "maintenance/maint release utils" is vague and uses non-descriptive terminology that doesn't convey meaningful information about the specific changes. Revise the title to be more specific and descriptive, e.g., 'Add release utility scripts and update Dependabot workflows' or 'Introduce release automation and maintenance improvements'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch maintenance/maint-release-utils

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

@greenc-FNAL

Copy link
Copy Markdown
Contributor Author

31 fixed, 0 new since branch point (0f6474d)
31 fixed, 0 new since previous report on PR (bd7a613)

✅ 31 CodeQL alerts resolved since the previous PR commit

  • Warning # 196 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:109:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 197 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:137:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 198 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:157:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 199 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:201:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 200 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:166:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 201 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:188:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 202 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:207:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 203 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:226:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 204 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:251:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 205 actions/untrusted-checkout-toctou/critical at .github/workflows/header-guards-fix.yaml:107:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 206 actions/untrusted-checkout-toctou/critical at .github/workflows/markdown-fix.yaml:107:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 207 actions/untrusted-checkout-toctou/critical at .github/workflows/yaml-fix.yaml:108:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 208 actions/untrusted-checkout-toctou/critical at .github/workflows/yaml-fix.yaml:111:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 209 actions/untrusted-checkout-toctou/high at .github/workflows/clang-format-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 210 actions/untrusted-checkout-toctou/high at .github/workflows/cmake-format-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 211 actions/untrusted-checkout-toctou/high at .github/workflows/jsonnet-format-fix.yaml:95:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 212 actions/untrusted-checkout-toctou/high at .github/workflows/python-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 213 actions/untrusted-checkout/high at .github/workflows/clang-format-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 214 actions/untrusted-checkout/high at .github/workflows/cmake-format-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 215 actions/untrusted-checkout/high at .github/workflows/jsonnet-format-fix.yaml:95:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • ✅ …and 11 more alerts (see Code Scanning for the full list).

✅ 31 CodeQL alerts resolved since the branch point

  • Warning # 196 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:109:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 197 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:137:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 198 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:157:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 199 actions/untrusted-checkout-toctou/critical at .github/workflows/clang-tidy-fix.yaml:201:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 200 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:166:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 201 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:188:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 202 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:207:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 203 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:226:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 204 actions/untrusted-checkout-toctou/critical at .github/workflows/coverage.yaml:251:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 205 actions/untrusted-checkout-toctou/critical at .github/workflows/header-guards-fix.yaml:107:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 206 actions/untrusted-checkout-toctou/critical at .github/workflows/markdown-fix.yaml:107:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 207 actions/untrusted-checkout-toctou/critical at .github/workflows/yaml-fix.yaml:108:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 208 actions/untrusted-checkout-toctou/critical at .github/workflows/yaml-fix.yaml:111:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 209 actions/untrusted-checkout-toctou/high at .github/workflows/clang-format-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 210 actions/untrusted-checkout-toctou/high at .github/workflows/cmake-format-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 211 actions/untrusted-checkout-toctou/high at .github/workflows/jsonnet-format-fix.yaml:95:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 212 actions/untrusted-checkout-toctou/high at .github/workflows/python-fix.yaml:94:9 — Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
    Insufficient protection against execution of untrusted code on a privileged workflow (issue_comment).
  • Warning # 213 actions/untrusted-checkout/high at .github/workflows/clang-format-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 214 actions/untrusted-checkout/high at .github/workflows/cmake-format-fix.yaml:94:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • Warning # 215 actions/untrusted-checkout/high at .github/workflows/jsonnet-format-fix.yaml:95:9 — Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
    Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: issue_comment).
  • ✅ …and 11 more alerts (see Code Scanning for the full list).

Review the full CodeQL report for details.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🤖 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/dependabot-auto-merge.yaml:
- Around line 15-19: The comment on the `repository-projects: write` permission
line is technically inaccurate. The comment claims this permission is required
to modify repository settings via API, but `repository-projects` actually
governs GitHub Projects (kanban boards) functionality, not repository
administration. The PATCH endpoint for auto_merge requires write permissions
which come from GITHUB_TOKEN's elevated privileges in workflows. Replace the
misleading comment with one that either accurately explains why
`repository-projects: write` is necessary for the dependabot auto-merge workflow
(documenting any non-obvious reasons), or clarify that GITHUB_TOKEN provides the
necessary access despite the unexpected permission scope name.

In @.github/workflows/guardrail-audit-alert.yaml:
- Around line 20-32: Add a guard check to validate that the SLACK_URL secret is
configured before attempting to use it in the curl command. Within the existing
if block that checks if the committer is not 'GitHub', add an additional
condition to verify that SLACK_URL is not empty. If SLACK_URL is missing or
empty, either exit with an error message to surface the configuration issue or
add a separate guard that returns early, preventing the curl command from
executing with an empty webhook URL and ensuring configuration problems are
caught immediately rather than failing silently.
- Around line 25-29: The jq command constructing the PAYLOAD variable on line 29
exceeds yamllint's 120-character limit at 127 characters. Fix this by either
adding a yamllint disable comment at the end of line 29 with `# yamllint
disable-line rule:line-length`, or alternatively, restructure the PAYLOAD
assignment to break the jq filter string across multiple lines for better
readability while staying within the character limit.

In `@scripts/release/01-detect-tier1.sh`:
- Around line 34-35: The comment for the git log command on line 33 states the
code checks for changes to "action.yaml or source files" but the pathspec in the
CHANGES variable assignment on line 34-35 only includes `-- action.yaml`. Either
update the comment to accurately reflect that only action.yaml changes are being
detected (if this is intentional), or expand the git log pathspec to include the
source files referenced in the comment by adding additional paths after
action.yaml in the `--` argument.

In `@scripts/release/02-execute-release.sh`:
- Line 62: The sed -i command in the release script is not portable between
macOS and Linux because BSD sed (macOS) requires an empty backup extension
argument while GNU sed (Linux) does not. Replace the sed -i invocation with
either sed -i '' to provide an empty backup extension that works on both
systems, or alternatively use perl -i -pe instead which provides consistent
behavior across both macOS and Linux platforms.
- Line 54: The jq query in the REPO_FULL_NAME assignment contains a typo in the
field name. Change `.nameWithOwnership` to `.nameWithOwner` in the gh repo view
command to correctly retrieve the repository name from the GitHub API. The typo
causes the query to return null, which will be incorrectly substituted into the
README.
- Around line 20-27: Replace the sed subprocess with bash parameter expansion to
strip the 'v' prefix from LATEST_TAG by using ${LATEST_TAG#v} instead of piping
through sed. Additionally, add validation to ensure LATEST_TAG follows the
expected vN pattern before performing arithmetic operations on VERSION_NUM,
since tags like v1.2.0 will cause the NEXT_NUM arithmetic expansion to fail
silently or produce unexpected results. Consider extracting only the major
version number or validating the tag format explicitly before the arithmetic
operation on line 23.

In `@scripts/release/trigger-dependabot.sh`:
- Around line 38-41: The local trigger branch stored in $TRIGGER_BRANCH is
created with git checkout but never deleted after the script completes. After
the script syncs back to the default branch (following the PR operations), add
an explicit git command to delete the local trigger branch by name to prevent
accumulation of stale local branches like
automation/trigger-dependabot-1718649600 on repeated script runs.
- Around line 67-73: The PR number extraction using grep -oE '[0-9]+$' on the
PR_URL output lacks validation and could silently produce an empty string or
incorrect value if the gh pr create command output format changes. Add a
defensive check immediately after the PR_NUMBER assignment that validates the
extracted value is not empty and contains only digits, and exit with a clear
error message if the validation fails. This prevents downstream commands like gh
pr close from failing with cryptic errors due to an invalid or empty PR number.

In `@scripts/release/view-dependabot-logs.sh`:
- Around line 23-37: The xdg-open command on line 26 suppresses stderr output
which masks failures when the browser fails to open (e.g., no $DISPLAY in
headless environments or no default browser configured). The script then prints
the success message regardless of whether the command actually succeeded. Remove
the `2>/dev/null` redirection from the xdg-open call to allow errors to surface,
and check the exit status of both xdg-open and open commands. Only print the
success message (the "⚡ Success: Browser session initialized." echo) after
confirming that one of the browser-opening commands actually succeeded by
checking their exit codes.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7a1c5b74-5f32-4518-8552-e9414ad94ceb

📥 Commits

Reviewing files that changed from the base of the PR and between 0f6474d and 6c3b8ce.

📒 Files selected for processing (6)
  • .github/workflows/dependabot-auto-merge.yaml
  • .github/workflows/guardrail-audit-alert.yaml
  • scripts/release/01-detect-tier1.sh
  • scripts/release/02-execute-release.sh
  • scripts/release/trigger-dependabot.sh
  • scripts/release/view-dependabot-logs.sh
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • Framework-R-D/action-workflow-setup (auto-detected)
  • Framework-R-D/action-complete-pr-comment (auto-detected)
  • Framework-R-D/action-handle-fix-commit (auto-detected)
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze actions with CodeQL
🧰 Additional context used
🪛 GitHub Check: yaml-check
.github/workflows/guardrail-audit-alert.yaml

[warning] 29-29:
29:121 [line-length] line too long (127 > 120 characters)


[warning] 2-2:
2:1 [truthy] truthy value should be one of [false, true]

🪛 Shellcheck (0.11.0)
scripts/release/01-detect-tier1.sh

[style] 39-39: See if you can use ${variable//search/replace} instead.

(SC2001)

scripts/release/02-execute-release.sh

[style] 22-22: See if you can use ${variable//search/replace} instead.

(SC2001)

🪛 zizmor (1.25.2)
.github/workflows/dependabot-auto-merge.yaml

[error] 16-16: overly broad permissions (excessive-permissions): actions: write is overly broad at the workflow level

(excessive-permissions)


[error] 17-17: overly broad permissions (excessive-permissions): contents: write is overly broad at the workflow level

(excessive-permissions)


[error] 18-18: overly broad permissions (excessive-permissions): pull-requests: write is overly broad at the workflow level

(excessive-permissions)


[warning] 19-19: overly broad permissions (excessive-permissions): repository-projects: write is overly broad at the workflow level

(excessive-permissions)


[warning] 16-16: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment

(undocumented-permissions)

.github/workflows/guardrail-audit-alert.yaml

[warning] 1-33: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[info] 7-7: workflow or action definition without a name (anonymous-definition): this job

(anonymous-definition)


[warning] 2-4: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting

(concurrency-limits)

🔀 Multi-repo context Framework-R-D/action-workflow-setup, Framework-R-D/action-complete-pr-comment, Framework-R-D/action-handle-fix-commit

Perfect! I now have comprehensive cross-repository context. Let me document my findings:

Linked repositories findings

Framework-R-D/action-workflow-setup

Dependabot Auto-Merge Workflow Consistency:

  • .github/workflows/dependabot-auto-merge.yaml:19 — Identical repository-projects: write permission added [::Framework-R-D/action-workflow-setup::]
  • .github/workflows/dependabot-auto-merge.yaml:61,68 — Both GH_TOKEN steps use secrets.GITHUB_TOKEN (replaced WORKFLOW_PAT) [::Framework-R-D/action-workflow-setup::]

Guardrail Alert Workflow Implementation:

  • .github/workflows/guardrail-audit-alert.yaml:1-32 — Identical workflow deployed; triggers on main branch pushes with permissions: {} and filters out dependabot [::Framework-R-D/action-workflow-setup::]
  • Requires SLACK_WEBHOOK_URL secret to be configured in the repository [::Framework-R-D/action-workflow-setup::]

Dependency Chain:

  • action.yaml:68,79,128 — This action depends on three Framework-R-D sub-actions (action-prepare-check-outputs, action-prepare-fix-outputs, action-run-change-detection), each SHA-pinned [::Framework-R-D/action-workflow-setup::]
  • RELEASES.md:163-172 — Release procedure documents dependent action updates required after any new version [::Framework-R-D/action-workflow-setup::]

Framework-R-D/action-complete-pr-comment

Identical Workflow Changes:

  • .github/workflows/dependabot-auto-merge.yaml:19,61,68 — Matches action-workflow-setup changes exactly [::Framework-R-D/action-complete-pr-comment::]
  • .github/workflows/guardrail-audit-alert.yaml:1-32 — Identical guardrail workflow [::Framework-R-D/action-complete-pr-comment::]

Permission Requirements:

  • Uses actions/github-script@v9.0.0 which requires issues: write permission per action.yaml description [::Framework-R-D/action-complete-pr-comment::]

Framework-R-D/action-handle-fix-commit

Identical Workflow Changes:

  • .github/workflows/dependabot-auto-merge.yaml:19,61,68 — Matches the other repositories [::Framework-R-D/action-handle-fix-commit::]
  • .github/workflows/guardrail-audit-alert.yaml:1-32 — Identical guardrail workflow [::Framework-R-D/action-handle-fix-commit::]

Critical Token Configuration:

  • action.yaml:30-31 — Requires explicit token input parameter (a PAT) for commit operations; this is distinct from the workflow GITHUB_TOKEN [::Framework-R-D/action-handle-fix-commit::]
  • .github/workflows/dependabot-auto-merge.yaml workflow change does NOT affect this action's token input requirement [::Framework-R-D/action-handle-fix-commit::]

Cross-Repository Consistency Check

Uniform Changes Across All Three Action Repositories:
All three consumer actions have been updated with identical changes:

  1. repository-projects: write permission added to enable auto-merge API calls
  2. GITHUB_TOKEN replaces WORKFLOW_PAT in the dependabot merge automation
  3. New guardrail-audit-alert workflow deployed to all three with Slack integration requirement

No Breaking Changes Detected:

  • The PR changes are consistent and uniform across repositories
  • The switch from WORKFLOW_PAT to GITHUB_TOKEN is a maintenance improvement with sufficient permissions (repository-projects: write enables the allow_auto_merge=true PATCH call needed at line 91)
  • The guardrail workflow adds new functionality without affecting existing workflows
  • Release scripts reference the correct action structure and dependency patterns
🔇 Additional comments (14)
.github/workflows/dependabot-auto-merge.yaml (2)

63-68: LGTM!


70-121: LGTM!

.github/workflows/guardrail-audit-alert.yaml (1)

1-10: LGTM!

scripts/release/trigger-dependabot.sh (4)

1-11: LGTM!


18-36: Solid fallback chain for remote resolution.

The three-level fallback (current branch tracking → main's tracking → first listed remote) handles most fork/upstream scenarios nicely. The || true guards prevent set -e from killing the script on missing configs, which is the right call here.


43-60: LGTM!


62-66: LGTM!

Also applies to: 74-85

scripts/release/view-dependabot-logs.sh (2)

1-11: LGTM!


13-21: LGTM!

scripts/release/01-detect-tier1.sh (2)

1-27: LGTM!


37-44: LGTM!

scripts/release/02-execute-release.sh (3)

1-18: LGTM!


29-43: LGTM!


64-69: LGTM!

Comment on lines 15 to +19
permissions:
actions: write
contents: write
pull-requests: write
repository-projects: write # Required if the token needs to modify repository settings via API

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if there are any existing workflows or docs that clarify the permission requirements
rg -n -C3 'allow_auto_merge|repository-projects' --type yaml

Repository: Framework-R-D/phlex

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Check if the workflow file exists and read its actual content
if [ -f ".github/workflows/dependabot-auto-merge.yaml" ]; then
  echo "=== File exists, reading content ==="
  cat -n ".github/workflows/dependabot-auto-merge.yaml"
else
  echo "=== File not found, listing .github/workflows ==="
  ls -la .github/workflows/ 2>/dev/null || echo "No .github/workflows directory"
fi

Repository: Framework-R-D/phlex

Length of output: 6769


🌐 Web query:

GitHub API PATCH repos allow_auto_merge permission required

💡 Result:

To update the allow_auto_merge setting for a repository using the GitHub REST API PATCH /repos/{owner}/{repo} endpoint, the authenticated user must have repository write permissions [1][2][3]. Specifically, the following requirements apply: 1. Permission Level: You must have admin or maintainer access to the repository to successfully perform this update [3]. 2. Authentication: If you are using a fine-grained personal access token or a GitHub App, ensure the token has the necessary repository-level permissions. For fine-grained tokens, the write access to the repository is generally required to modify repository settings [1][2]. 3. API Usage: The PATCH request must include the allow_auto_merge parameter in the body, set to true or false [4][3]. Example request: curl -X PATCH -H "Accept: application/vnd.github+json" -H "Authorization: Bearer " https://api.github.com/repos/OWNER/REPO -d '{"allow_auto_merge":true}' [5][3] Note: This setting enables the ability to use auto-merge within the repository [6]. If you are trying to enable auto-merge on an individual pull request rather than enabling the feature for the entire repository, you must use the GraphQL API mutation enablePullRequestAutoMerge instead [5].

Citations:


🌐 Web query:

GitHub permission scope repository-projects what permissions does it grant

💡 Result:

The repository-projects permission scope grants access to interact with GitHub Projects associated with a repository [1]. Specifically, it provides read and write access to repository-level projects [1]. In contexts such as GitHub Codespaces configuration, this permission allows authorized entities to perform operations like viewing, creating, or editing projects linked to that specific repository [1]. While the exact level of access (read vs. write) depends on the specific implementation or configuration, it is generally treated as a distinct permission required to manage project boards and their items within the repository's scope [1]. It is important to note that this scope is distinct from broader project management scopes (such as the general project scope used for organization-wide or user-owned projects) [2][3]. Because repository projects are often treated as distinct resources, repository-projects ensures that automation or applications can manage these specific boards without requiring broader, higher-privilege access to all organization-level or personal projects [2][1].

Citations:


Fix the misleading comment about the permission requirement on line 19.

The comment states repository-projects: write is "Required if the token needs to modify repository settings via API," but repository-projects permission specifically governs GitHub Projects (kanban boards), not repository administration. According to GitHub's API documentation, the PATCH endpoint for allow_auto_merge requires admin/maintainer access or repository write permissions—not the Projects scope.

This permission likely works in practice because secrets.GITHUB_TOKEN in workflows has elevated permissions, but the comment's explanation is technically inaccurate and will confuse future maintainers. Either correct the comment to explain that GITHUB_TOKEN grants the necessary access despite the unusual permission name, or explicitly document why repository-projects: write is present if there's a non-obvious reason.

🧰 Tools
🪛 zizmor (1.25.2)

[error] 16-16: overly broad permissions (excessive-permissions): actions: write is overly broad at the workflow level

(excessive-permissions)


[error] 17-17: overly broad permissions (excessive-permissions): contents: write is overly broad at the workflow level

(excessive-permissions)


[error] 18-18: overly broad permissions (excessive-permissions): pull-requests: write is overly broad at the workflow level

(excessive-permissions)


[warning] 19-19: overly broad permissions (excessive-permissions): repository-projects: write is overly broad at the workflow level

(excessive-permissions)


[warning] 16-16: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment

(undocumented-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/dependabot-auto-merge.yaml around lines 15 - 19, The
comment on the `repository-projects: write` permission line is technically
inaccurate. The comment claims this permission is required to modify repository
settings via API, but `repository-projects` actually governs GitHub Projects
(kanban boards) functionality, not repository administration. The PATCH endpoint
for auto_merge requires write permissions which come from GITHUB_TOKEN's
elevated privileges in workflows. Replace the misleading comment with one that
either accurately explains why `repository-projects: write` is necessary for the
dependabot auto-merge workflow (documenting any non-obvious reasons), or clarify
that GITHUB_TOKEN provides the necessary access despite the unexpected
permission scope name.

Comment on lines +20 to +32
run: |
# If the committer isn't 'GitHub', an admin pushed directly via local CLI.
if [ "$COMMITTER" != "GitHub" ]; then

# Use jq to format a completely safe, escaped JSON object for Slack
PAYLOAD=$(jq -n \
--arg msg "$COMMIT_MSG" \
--arg repo "$REPO_NAME" \
--arg actor "$ACTOR" \
'{"text": "⚠️ *Direct Push to Main Detected!*\n*Repo:* `\($repo)`\n*Actor:* `@\($actor)`\n*Commit:* `\($msg)`"}')

curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_URL"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Consider adding a guard for missing SLACK_WEBHOOK_URL.

If the secret isn't configured in a new repo, this will fail silently (or curl will try to POST to an empty string). Adding a quick check would surface configuration issues faster:

 run: |
+  if [ -z "$SLACK_URL" ]; then
+    echo "::warning::SLACK_WEBHOOK_URL secret is not configured - skipping alert"
+    exit 0
+  fi
   # If the committer isn't 'GitHub', an admin pushed directly via local CLI.

Also, kudos on using jq for the payload construction—that's the right call to avoid injection issues from funky commit messages.

📝 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
run: |
# If the committer isn't 'GitHub', an admin pushed directly via local CLI.
if [ "$COMMITTER" != "GitHub" ]; then
# Use jq to format a completely safe, escaped JSON object for Slack
PAYLOAD=$(jq -n \
--arg msg "$COMMIT_MSG" \
--arg repo "$REPO_NAME" \
--arg actor "$ACTOR" \
'{"text": "⚠️ *Direct Push to Main Detected!*\n*Repo:* `\($repo)`\n*Actor:* `@\($actor)`\n*Commit:* `\($msg)`"}')
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_URL"
fi
run: |
if [ -z "$SLACK_URL" ]; then
echo "::warning::SLACK_WEBHOOK_URL secret is not configured - skipping alert"
exit 0
fi
# If the committer isn't 'GitHub', an admin pushed directly via local CLI.
if [ "$COMMITTER" != "GitHub" ]; then
# Use jq to format a completely safe, escaped JSON object for Slack
PAYLOAD=$(jq -n \
--arg msg "$COMMIT_MSG" \
--arg repo "$REPO_NAME" \
--arg actor "$ACTOR" \
'{"text": "⚠️ *Direct Push to Main Detected!*\n*Repo:* `\($repo)`\n*Actor:* `@\($actor)`\n*Commit:* `\($msg)`"}')
curl -X POST -H 'Content-type: application/json' --data "$PAYLOAD" "$SLACK_URL"
fi
🧰 Tools
🪛 GitHub Check: yaml-check

[warning] 29-29:
29:121 [line-length] line too long (127 > 120 characters)

🤖 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/guardrail-audit-alert.yaml around lines 20 - 32, Add a
guard check to validate that the SLACK_URL secret is configured before
attempting to use it in the curl command. Within the existing if block that
checks if the committer is not 'GitHub', add an additional condition to verify
that SLACK_URL is not empty. If SLACK_URL is missing or empty, either exit with
an error message to surface the configuration issue or add a separate guard that
returns early, preventing the curl command from executing with an empty webhook
URL and ensuring configuration problems are caught immediately rather than
failing silently.

Comment on lines +25 to +29
PAYLOAD=$(jq -n \
--arg msg "$COMMIT_MSG" \
--arg repo "$REPO_NAME" \
--arg actor "$ACTOR" \
'{"text": "⚠️ *Direct Push to Main Detected!*\n*Repo:* `\($repo)`\n*Actor:* `@\($actor)`\n*Commit:* `\($msg)`"}')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Line 29 exceeds yamllint's 120-char limit (127 chars).

Split the jq heredoc for readability:

-            PAYLOAD=$(jq -n \
-              --arg msg "$COMMIT_MSG" \
-              --arg repo "$REPO_NAME" \
-              --arg actor "$ACTOR" \
-              '{"text": "⚠️ *Direct Push to Main Detected!*\n*Repo:* `\($repo)`\n*Actor:* `@\($actor)`\n*Commit:* `\($msg)`"}')
+            PAYLOAD=$(jq -n \
+              --arg msg "$COMMIT_MSG" \
+              --arg repo "$REPO_NAME" \
+              --arg actor "$ACTOR" \
+              '{"text": "⚠️ *Direct Push to Main Detected!*\n*Repo:* `\($repo)`\n*Actor:* `@\($actor)`\n*Commit:* `\($msg | .[0:100])`"}')

Actually, the cleaner fix is just to break the string literal—but since jq filter strings don't easily split, you could also just disable the lint for this line with a # yamllint disable-line rule:line-length comment if you prefer keeping it as-is.

🧰 Tools
🪛 GitHub Check: yaml-check

[warning] 29-29:
29:121 [line-length] line too long (127 > 120 characters)

🤖 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/guardrail-audit-alert.yaml around lines 25 - 29, The jq
command constructing the PAYLOAD variable on line 29 exceeds yamllint's
120-character limit at 127 characters. Fix this by either adding a yamllint
disable comment at the end of line 29 with `# yamllint disable-line
rule:line-length`, or alternatively, restructure the PAYLOAD assignment to break
the jq filter string across multiple lines for better readability while staying
within the character limit.

Source: Linters/SAST tools

Comment on lines +34 to +35
# 3. Check for any commits touching action.yaml or source files since the latest tag
CHANGES=$(git log "${LATEST_TAG}..HEAD" --oneline -- action.yaml 2>/dev/null || echo "")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Comment claims more than the code delivers.

The comment says "action.yaml or source files" but the git log only checks -- action.yaml. If that's intentional (since action.yaml is the public contract), update the comment. If you meant to catch other files (scripts, etc.), expand the pathspec.

-    # 3. Check for any commits touching action.yaml or source files since the latest tag
-    CHANGES=$(git log "${LATEST_TAG}..HEAD" --oneline -- action.yaml 2>/dev/null || echo "")
+    # 3. Check for any commits touching action.yaml since the latest tag
+    CHANGES=$(git log "${LATEST_TAG}..HEAD" --oneline -- action.yaml 2>/dev/null || echo "")
📝 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
# 3. Check for any commits touching action.yaml or source files since the latest tag
CHANGES=$(git log "${LATEST_TAG}..HEAD" --oneline -- action.yaml 2>/dev/null || echo "")
# 3. Check for any commits touching action.yaml since the latest tag
CHANGES=$(git log "${LATEST_TAG}..HEAD" --oneline -- action.yaml 2>/dev/null || echo "")
🤖 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 `@scripts/release/01-detect-tier1.sh` around lines 34 - 35, The comment for the
git log command on line 33 states the code checks for changes to "action.yaml or
source files" but the pathspec in the CHANGES variable assignment on line 34-35
only includes `-- action.yaml`. Either update the comment to accurately reflect
that only action.yaml changes are being detected (if this is intentional), or
expand the git log pathspec to include the source files referenced in the
comment by adding additional paths after action.yaml in the `--` argument.

Comment on lines +20 to +27
# Step 1: Calculate NEXT_VERSION increment rule
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0")
VERSION_NUM=$(echo "$LATEST_TAG" | sed 's/v//')
NEXT_NUM=$((VERSION_NUM + 1))
NEXT_VERSION="v${NEXT_NUM}"
TODAY=$(date +%Y-%m-%d)

echo "-> Current: $LATEST_TAG --> Targets Next: $NEXT_VERSION"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use parameter expansion and guard against non-numeric tags.

The sed can be swapped for native bash expansion—one less subprocess. Also, if LATEST_TAG ever diverges from the vN pattern (e.g., v1.2.0), the arithmetic silently explodes.

 LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0")
-VERSION_NUM=$(echo "$LATEST_TAG" | sed 's/v//')
+VERSION_NUM="${LATEST_TAG#v}"
+if ! [[ "$VERSION_NUM" =~ ^[0-9]+$ ]]; then
+  echo "❌ ERROR: Latest tag '$LATEST_TAG' is not in expected 'vN' format."
+  exit 1
+fi
 NEXT_NUM=$((VERSION_NUM + 1))
📝 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
# Step 1: Calculate NEXT_VERSION increment rule
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0")
VERSION_NUM=$(echo "$LATEST_TAG" | sed 's/v//')
NEXT_NUM=$((VERSION_NUM + 1))
NEXT_VERSION="v${NEXT_NUM}"
TODAY=$(date +%Y-%m-%d)
echo "-> Current: $LATEST_TAG --> Targets Next: $NEXT_VERSION"
# Step 1: Calculate NEXT_VERSION increment rule
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0")
VERSION_NUM="${LATEST_TAG#v}"
if ! [[ "$VERSION_NUM" =~ ^[0-9]+$ ]]; then
echo "❌ ERROR: Latest tag '$LATEST_TAG' is not in expected 'vN' format."
exit 1
fi
NEXT_NUM=$((VERSION_NUM + 1))
NEXT_VERSION="v${NEXT_NUM}"
TODAY=$(date +%Y-%m-%d)
echo "-> Current: $LATEST_TAG --> Targets Next: $NEXT_VERSION"
🧰 Tools
🪛 Shellcheck (0.11.0)

[style] 22-22: See if you can use ${variable//search/replace} instead.

(SC2001)

🤖 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 `@scripts/release/02-execute-release.sh` around lines 20 - 27, Replace the sed
subprocess with bash parameter expansion to strip the 'v' prefix from LATEST_TAG
by using ${LATEST_TAG#v} instead of piping through sed. Additionally, add
validation to ensure LATEST_TAG follows the expected vN pattern before
performing arithmetic operations on VERSION_NUM, since tags like v1.2.0 will
cause the NEXT_NUM arithmetic expansion to fail silently or produce unexpected
results. Consider extracting only the major version number or validating the tag
format explicitly before the arithmetic operation on line 23.

Source: Linters/SAST tools

NEW_SHA=$(gh api "repos/{owner}/{repo}/git/tags/${NEW_SHA}" --jq .object.sha)
fi

REPO_FULL_NAME=$(gh repo view --json nameWithOwner --jq '.nameWithOwnership')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Typo: .nameWithOwnership.nameWithOwner

This jq query will return null because the GitHub API field is nameWithOwner (no trailing "ship"). The script will then substitute a literal null@<sha> into your README, which is... not ideal. 💀

-REPO_FULL_NAME=$(gh repo view --json nameWithOwner --jq '.nameWithOwnership')
+REPO_FULL_NAME=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
📝 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
REPO_FULL_NAME=$(gh repo view --json nameWithOwner --jq '.nameWithOwnership')
REPO_FULL_NAME=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
🤖 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 `@scripts/release/02-execute-release.sh` at line 54, The jq query in the
REPO_FULL_NAME assignment contains a typo in the field name. Change
`.nameWithOwnership` to `.nameWithOwner` in the gh repo view command to
correctly retrieve the repository name from the GitHub API. The typo causes the
query to return null, which will be incorrectly substituted into the README.

OLD_PATTERN="${REPO_FULL_NAME}@[0-9a-f]\{40\} # v[0-9]*"
NEW_STRING="${REPO_FULL_NAME}@${NEW_SHA} # ${NEXT_VERSION}"

sed -i "s|${OLD_PATTERN}|${NEW_STRING}|" README.md

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

sed -i isn't portable to macOS.

BSD sed (macOS default) requires a backup extension argument even if empty: sed -i ''. GNU sed (Linux) accepts bare -i. If anyone runs this from their Mac, it'll error out cryptically.

Portable workaround:

-sed -i "s|${OLD_PATTERN}|${NEW_STRING}|" README.md
+sed -i.bak "s|${OLD_PATTERN}|${NEW_STRING}|" README.md && rm -f README.md.bak

Or if you're feeling fancy, use perl which is consistent across platforms:

perl -i -pe "s|${OLD_PATTERN}|${NEW_STRING}|" README.md
🤖 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 `@scripts/release/02-execute-release.sh` at line 62, The sed -i command in the
release script is not portable between macOS and Linux because BSD sed (macOS)
requires an empty backup extension argument while GNU sed (Linux) does not.
Replace the sed -i invocation with either sed -i '' to provide an empty backup
extension that works on both systems, or alternatively use perl -i -pe instead
which provides consistent behavior across both macOS and Linux platforms.

Comment on lines +38 to +41
# 3. Check out a temporary branch specifically for the trigger
echo "--> Creating local trigger branch..."
TRIGGER_BRANCH="automation/trigger-dependabot-$(date +%s)"
git checkout -b "$TRIGGER_BRANCH" -q

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Local trigger branch is never cleaned up.

gh pr close --delete-branch only removes the remote branch. After the script completes, the local $TRIGGER_BRANCH remains orphaned in the user's repo. Repeated runs will accumulate stale local branches like automation/trigger-dependabot-1718649600.

Add explicit local branch cleanup after syncing to the default branch:

🧹 Proposed fix to delete the local trigger branch
 # 9. Sync your default branch cleanly to ensure local tracking matches remote tip
 echo "--> Synchronizing local default branch workspace..."
 git checkout "$DEFAULT_BRANCH" -q
 git pull --ff-only "$REMOTE_NAME" "$DEFAULT_BRANCH" -q
+git branch -D "$TRIGGER_BRANCH" -q 2>/dev/null || true

 echo "⚡ SUCCESS: Dependabot has initialized an immediate version check cycle cleanly!"

Also applies to: 78-78, 82-83

🤖 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 `@scripts/release/trigger-dependabot.sh` around lines 38 - 41, The local
trigger branch stored in $TRIGGER_BRANCH is created with git checkout but never
deleted after the script completes. After the script syncs back to the default
branch (following the PR operations), add an explicit git command to delete the
local trigger branch by name to prevent accumulation of stale local branches
like automation/trigger-dependabot-1718649600 on repeated script runs.

Comment on lines +67 to +73
PR_URL=$(gh pr create \
--title "chore: dynamic version check sweep" \
--body "Automated system trigger. Safe to delete." \
--head "$TRIGGER_BRANCH")

PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$')
echo " PR Opened: #$PR_NUMBER"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

PR number extraction could fail silently with an unhelpful error.

If gh pr create ever changes its output format or returns an error message instead of a URL, grep -oE '[0-9]+$' will produce an empty string (or wrong number), and gh pr close "" will fail cryptically. Consider validating the extracted value:

🛡️ Proposed defensive check
 PR_URL=$(gh pr create \
   --title "chore: dynamic version check sweep" \
   --body "Automated system trigger. Safe to delete." \
   --head "$TRIGGER_BRANCH")

 PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$')
+if [ -z "$PR_NUMBER" ]; then
+  echo "❌ Error: Failed to extract PR number from: $PR_URL"
+  exit 1
+fi
 echo "    PR Opened: #$PR_NUMBER"
📝 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
PR_URL=$(gh pr create \
--title "chore: dynamic version check sweep" \
--body "Automated system trigger. Safe to delete." \
--head "$TRIGGER_BRANCH")
PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$')
echo " PR Opened: #$PR_NUMBER"
PR_URL=$(gh pr create \
--title "chore: dynamic version check sweep" \
--body "Automated system trigger. Safe to delete." \
--head "$TRIGGER_BRANCH")
PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$')
if [ -z "$PR_NUMBER" ]; then
echo "❌ Error: Failed to extract PR number from: $PR_URL"
exit 1
fi
echo " PR Opened: #$PR_NUMBER"
🤖 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 `@scripts/release/trigger-dependabot.sh` around lines 67 - 73, The PR number
extraction using grep -oE '[0-9]+$' on the PR_URL output lacks validation and
could silently produce an empty string or incorrect value if the gh pr create
command output format changes. Add a defensive check immediately after the
PR_NUMBER assignment that validates the extracted value is not empty and
contains only digits, and exit with a clear error message if the validation
fails. This prevents downstream commands like gh pr close from failing with
cryptic errors due to an invalid or empty PR number.

Comment on lines +23 to +37
# 3. Detect operating system environment and trigger the native window engine
if command -v xdg-open >/dev/null 2>&1; then
# Linux environment handler
xdg-open "$TARGET_LOG_PAGE" 2>/dev/null
elif command -v open >/dev/null 2>&1; then
# macOS environment handler
open "$TARGET_LOG_PAGE"
else
echo "❌ Error: Could not detect a desktop environment opener utility (xdg-open or open)."
echo " Please open this link manually instead:"
echo " $TARGET_LOG_PAGE"
exit 1
fi

echo "⚡ Success: Browser session initialized."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Suppressing stderr on xdg-open may mask failures.

Line 26 redirects stderr to /dev/null, but if xdg-open fails (e.g., no $DISPLAY set in a headless session, or no default browser configured), the script still prints "⚡ Success" even though the browser didn't actually open. The existing scripts/coverage.sh (line 680) does the same thing, so this is at least consistent with the codebase—but it's a pattern that can mislead users.

Consider checking the exit code or removing the stderr suppression so failures are visible:

🔧 Optional: let xdg-open errors surface
 if command -v xdg-open >/dev/null 2>&1; then
   # Linux environment handler
-  xdg-open "$TARGET_LOG_PAGE" 2>/dev/null
+  xdg-open "$TARGET_LOG_PAGE"
 elif command -v open >/dev/null 2>&1; then

Alternatively, if you want to keep stderr quiet but still detect failures:

-  xdg-open "$TARGET_LOG_PAGE" 2>/dev/null
+  if ! xdg-open "$TARGET_LOG_PAGE" 2>/dev/null; then
+    echo "⚠️  Warning: xdg-open returned an error. Browser may not have launched."
+  fi
📝 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
# 3. Detect operating system environment and trigger the native window engine
if command -v xdg-open >/dev/null 2>&1; then
# Linux environment handler
xdg-open "$TARGET_LOG_PAGE" 2>/dev/null
elif command -v open >/dev/null 2>&1; then
# macOS environment handler
open "$TARGET_LOG_PAGE"
else
echo "❌ Error: Could not detect a desktop environment opener utility (xdg-open or open)."
echo " Please open this link manually instead:"
echo " $TARGET_LOG_PAGE"
exit 1
fi
echo "⚡ Success: Browser session initialized."
# 3. Detect operating system environment and trigger the native window engine
if command -v xdg-open >/dev/null 2>&1; then
# Linux environment handler
xdg-open "$TARGET_LOG_PAGE"
elif command -v open >/dev/null 2>&1; then
# macOS environment handler
open "$TARGET_LOG_PAGE"
else
echo "❌ Error: Could not detect a desktop environment opener utility (xdg-open or open)."
echo " Please open this link manually instead:"
echo " $TARGET_LOG_PAGE"
exit 1
fi
echo "⚡ Success: Browser session initialized."
🤖 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 `@scripts/release/view-dependabot-logs.sh` around lines 23 - 37, The xdg-open
command on line 26 suppresses stderr output which masks failures when the
browser fails to open (e.g., no $DISPLAY in headless environments or no default
browser configured). The script then prints the success message regardless of
whether the command actually succeeded. Remove the `2>/dev/null` redirection
from the xdg-open call to allow errors to surface, and check the exit status of
both xdg-open and open commands. Only print the success message (the "⚡ Success:
Browser session initialized." echo) after confirming that one of the
browser-opening commands actually succeeded by checking their exit codes.

@knoepfel knoepfel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@greenc-FNAL, I suspect the additions to scripts/release can go away?

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.

2 participants