Skip to content

fix(dispatch): log why comment-triggered dispatches are skipped - #5214

Closed
Roming22 wants to merge 1 commit into
fullsend-ai:mainfrom
Roming22:dispatch-output
Closed

fix(dispatch): log why comment-triggered dispatches are skipped#5214
Roming22 wants to merge 1 commit into
fullsend-ai:mainfrom
Roming22:dispatch-output

Conversation

@Roming22

Copy link
Copy Markdown
Collaborator

Emit notice annotations when bot or unauthorized comments are ignored,
and centralize those checks in shared helpers.

Signed-off-by: Romain Arnaud rarnaud@redhat.com
Co-authored-by: Cursor cursoragent@cursor.com

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED

Summary

When a comment does not trigger a stage, the reason is logged to the output.

Related Issue

N/A

Changes

  • Shell script for Determine stage in fullsend-ai_fullsend/internal/scaffold/fullsend-repo/.github/workflows has been updated to output why a comment may not trigger a given stage.

Testing

  • make lint passes (stage changes first, then run): not working in my env
  • Tests added/updated for new or modified logic

Checklist

  • PR title follows Conventional Commits (correct type, ! for breaking changes)
  • Commits are signed off (DCO) — human and human-directed agent sessions only
  • I wrote this contribution myself and can explain all changes in it

Emit notice annotations when bot or unauthorized comments are ignored,
and centralize those checks in shared helpers.

Signed-off-by: Romain Arnaud <rarnaud@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED
@Roming22
Roming22 requested a review from a team as a code owner July 16, 2026 17:38
@github-actions github-actions Bot closed this Jul 16, 2026
@github-actions

Copy link
Copy Markdown

Thank you for your interest in contributing to fullsend, @Roming22.

This project uses a vouch system for first-time contributors. Before submitting a pull request, you need to be vouched by a maintainer.

To get vouched:

  1. Open a Vouch Request discussion.
  2. Describe what you want to change and why.
  3. Write in your own words — do not have an AI generate the request.
  4. A maintainer will comment /vouch if approved.
  5. Once vouched, open a new PR (preferred) or reopen this one.

See CONTRIBUTING.md for details.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Dispatch: log reasons for skipping comment-triggered stage dispatches

🐞 Bug fix 🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Add shared helpers to filter bot/unauthorized comments in the dispatch workflow.
• Emit ::notice annotations explaining why comment-triggered stage selection was skipped.
• Update scaffold tests to assert helper usage and notice message text.
Diagram

graph TD
  E{{"Issue comment event"}} --> W["dispatch.yml (Determine stage)"] --> H["Shared helpers"] --> D{"Eligible comment?"} --> S["Stage selected"] --> J["Dispatch downstream job"]
  D -->|"No"| N["::notice annotation"]
  subgraph Legend
    direction LR
    _ext{{"External trigger"}} ~~~ _wf["Workflow step"] ~~~ _dec{"Decision"} ~~~ _out["Output/annotation"]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Move eligibility checks into job/step-level `if:` conditions
  • ➕ Makes skip behavior visible in the workflow graph without running shell logic
  • ➕ Reduces branching inside the script
  • ➖ Harder to express nuanced conditions per command (authorized vs non-bot-only cases)
  • ➖ Less convenient to emit a single, centralized reason message
2. Extract eligibility logic into a small reusable action (JS/composite)
  • ➕ Better structure and testability for complex dispatch rules
  • ➕ Can use richer GitHub annotations APIs (e.g., core.notice) consistently
  • ➖ More maintenance overhead than a few bash helpers
  • ➖ Introduces another artifact/versioning surface area

Recommendation: The PR’s approach (centralized bash helpers emitting ::notice) is the best fit for the current scope: it improves observability without changing the workflow’s structure or introducing new components. If the dispatch rules continue to grow, consider migrating the logic into a reusable action to keep the workflow file readable and more easily testable.

Files changed (2) +28 / -9

Bug fix (1) +22 / -7
dispatch.ymlCentralize comment eligibility checks and emit skip notices +22/-7

Centralize comment eligibility checks and emit skip notices

• Introduces 'comment_from_user' and 'comment_from_authorized_user' helpers to consolidate bot and authorization checks. When a comment is rejected, the workflow now prints GitHub Actions '::notice' messages explaining whether the comment was from a bot or an unauthorized user, and reuses the helpers across stage command cases.

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml

Tests (1) +6 / -2
scaffold_test.goAssert shared helper usage and notice strings in dispatch workflow scaffold +6/-2

Assert shared helper usage and notice strings in dispatch workflow scaffold

• Updates the dispatch workflow content test to expect the new helper function names and notice message text. Replaces the previous direct '!= "Bot"' assertion with checks that reflect the refactored logic.

internal/scaffold/scaffold_test.go

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 61 rules

Grey Divider


Action required

1. Bad bash return value 🐞 Bug ≡ Correctness
Description
comment_from_authorized_user() uses return comment_from_user, but return requires a numeric
status, so the function errors and returns non-zero even for authorized human comments. As a result,
every if comment_from_authorized_user; then ... branch is skipped and comment-triggered stages
won’t dispatch.
Code

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[R117-123]

+          comment_from_authorized_user() {
+            if ! is_authorized; then
+              echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}"
+              return 1
+            fi
+            return comment_from_user
+          }
Relevance

⭐⭐⭐ High

Team repeatedly accepts bash/dispatch correctness fixes to prevent runtime breakage (e.g., PR390
dispatch script fixes; PR1688 routing/auth fixes).

PR-#390
PR-#1688

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The helper contains a non-numeric return argument, and all slash-command routing uses this helper
as the if condition that decides whether to set STAGE; therefore, the invalid return makes those
branches unreachable for authorized humans.

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[110-123]
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[131-177]
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[254-258]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`comment_from_authorized_user()` attempts to delegate to `comment_from_user()` via `return comment_from_user`, which is invalid in bash because `return` accepts only an integer exit code. This causes authorized human comments to fail the `if comment_from_authorized_user; then` checks and prevents `STAGE` from being set.

## Issue Context
This is inside the `Determine stage` script (`set -euo pipefail`). The helper is used as the gate for multiple slash commands.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[110-123]

## Suggested change
Replace the invalid return with actually calling the function and returning its exit status, e.g.:
```bash
comment_from_authorized_user() {
 if ! is_authorized; then
   echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}" 
   return 1
 fi
 comment_from_user
 return $?
}
```
(or make `comment_from_user` the last command without an explicit `return` argument).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Dispatch routing checks out-of-sync 📘 Rule violation ⚙ Maintainability
Description
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml centralizes bot/authorization
checks into comment_from_user/comment_from_authorized_user with notice annotations, but
.github/workflows/reusable-dispatch.yml still uses the older inline COMMENT_USER_TYPE != "Bot" +
is_authorized checks. This violates the requirement to keep dispatch routing logic in sync across
the two workflows and can cause different behavior/diagnostics between scaffolded repos and the
reusable workflow.
Code

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[R110-123]

+          comment_from_user() {
+            if [[ "${COMMENT_USER_TYPE}" == "Bot" ]]; then
+              echo "::notice::Skipping dispatch for bot comment"
+              return 1
+            fi
+            return 0
+          }
+          comment_from_authorized_user() {
+            if ! is_authorized; then
+              echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}"
+              return 1
+            fi
+            return comment_from_user
+          }
Relevance

⭐⭐ Medium

Mixed history: workflow-sync tweaks often accepted (PR1688, PR1039) but “keep scaffold+reusable in
sync” request rejected (PR3820).

PR-#1688
PR-#1039
PR-#3820

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR changes introduce shared helpers and notice annotations in the scaffold dispatch workflow, but
the reusable dispatch workflow still contains the older inline conditionals. This is a direct
mismatch in stage-routing logic across the two workflows, which the rule forbids unless
intentionally documented.

Rule 1062045: Keep jq payload, stage routing, and secret threading logic in dispatch workflows in sync
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[110-190]
.github/workflows/reusable-dispatch.yml[180-243]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The bot/authorization gating and skip-notice behavior was updated in `internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml` (via `comment_from_user` and `comment_from_authorized_user` helpers), but the reusable workflow `.github/workflows/reusable-dispatch.yml` still uses the previous inline checks. This breaks the compliance requirement that routing/dispatch logic stays aligned across both workflows.

## Issue Context
PR intent is to "Emit notice annotations when bot or unauthorized comments are ignored, and centralize those checks in shared helpers." Only the scaffold dispatch workflow was updated.

## Fix Focus Areas
- .github/workflows/reusable-dispatch.yml[180-243]
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[110-190]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Bot notice precedence wrong 🐞 Bug ◔ Observability
Description
comment_from_authorized_user() checks is_authorized before the bot filter, so an unauthorized
bot comment emits the “unauthorized comment” notice and never emits the intended bot-skip notice.
This also performs an unnecessary permission check (gh api) for bot comments that could be
rejected immediately.
Code

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[R110-123]

+          comment_from_user() {
+            if [[ "${COMMENT_USER_TYPE}" == "Bot" ]]; then
+              echo "::notice::Skipping dispatch for bot comment"
+              return 1
+            fi
+            return 0
+          }
+          comment_from_authorized_user() {
+            if ! is_authorized; then
+              echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}"
+              return 1
+            fi
+            return comment_from_user
+          }
Relevance

⭐⭐ Medium

No close precedent found for notice-precedence/avoiding extra auth calls; similar dispatch review
feedback is inconsistent.

PR-#1688

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
comment_from_authorized_user() returns early on failed authorization before delegating to
comment_from_user(), while is_authorized() performs a permission check via gh api; thus
unauthorized bot comments log the unauthorized notice and still run the permission call.

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[60-86]
internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[110-123]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
For comment-triggered dispatches, the new helper logs skip reasons. However, `comment_from_authorized_user()` checks authorization first and only then calls the bot filter, which means bot comments that aren’t authorized get logged as “unauthorized” instead of “bot comment”, and still incur a permission API call.

## Issue Context
`is_authorized()` calls `has_write_permission()`, which uses `gh api` to query collaborator permissions.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[60-86]
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[110-123]

## Suggested change
Reorder the checks so bot filtering happens first:
```bash
comment_from_authorized_user() {
 if ! comment_from_user; then
   return 1
 fi
 if ! is_authorized; then
   echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}"
   return 1
 fi
 return 0
}
```
This ensures bot comments always produce the bot notice and avoids calling the permission API for bots.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +110 to +123
comment_from_user() {
if [[ "${COMMENT_USER_TYPE}" == "Bot" ]]; then
echo "::notice::Skipping dispatch for bot comment"
return 1
fi
return 0
}
comment_from_authorized_user() {
if ! is_authorized; then
echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}"
return 1
fi
return comment_from_user
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Dispatch routing checks out-of-sync 📘 Rule violation ⚙ Maintainability

internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml centralizes bot/authorization
checks into comment_from_user/comment_from_authorized_user with notice annotations, but
.github/workflows/reusable-dispatch.yml still uses the older inline COMMENT_USER_TYPE != "Bot" +
is_authorized checks. This violates the requirement to keep dispatch routing logic in sync across
the two workflows and can cause different behavior/diagnostics between scaffolded repos and the
reusable workflow.
Agent Prompt
## Issue description
The bot/authorization gating and skip-notice behavior was updated in `internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml` (via `comment_from_user` and `comment_from_authorized_user` helpers), but the reusable workflow `.github/workflows/reusable-dispatch.yml` still uses the previous inline checks. This breaks the compliance requirement that routing/dispatch logic stays aligned across both workflows.

## Issue Context
PR intent is to "Emit notice annotations when bot or unauthorized comments are ignored, and centralize those checks in shared helpers." Only the scaffold dispatch workflow was updated.

## Fix Focus Areas
- .github/workflows/reusable-dispatch.yml[180-243]
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[110-190]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +117 to +123
comment_from_authorized_user() {
if ! is_authorized; then
echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}"
return 1
fi
return comment_from_user
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Bad bash return value 🐞 Bug ≡ Correctness

comment_from_authorized_user() uses return comment_from_user, but return requires a numeric
status, so the function errors and returns non-zero even for authorized human comments. As a result,
every if comment_from_authorized_user; then ... branch is skipped and comment-triggered stages
won’t dispatch.
Agent Prompt
## Issue description
`comment_from_authorized_user()` attempts to delegate to `comment_from_user()` via `return comment_from_user`, which is invalid in bash because `return` accepts only an integer exit code. This causes authorized human comments to fail the `if comment_from_authorized_user; then` checks and prevents `STAGE` from being set.

## Issue Context
This is inside the `Determine stage` script (`set -euo pipefail`). The helper is used as the gate for multiple slash commands.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[110-123]

## Suggested change
Replace the invalid return with actually calling the function and returning its exit status, e.g.:
```bash
comment_from_authorized_user() {
  if ! is_authorized; then
    echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}" 
    return 1
  fi
  comment_from_user
  return $?
}
```
(or make `comment_from_user` the last command without an explicit `return` argument).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +110 to +123
comment_from_user() {
if [[ "${COMMENT_USER_TYPE}" == "Bot" ]]; then
echo "::notice::Skipping dispatch for bot comment"
return 1
fi
return 0
}
comment_from_authorized_user() {
if ! is_authorized; then
echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}"
return 1
fi
return comment_from_user
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

3. Bot notice precedence wrong 🐞 Bug ◔ Observability

comment_from_authorized_user() checks is_authorized before the bot filter, so an unauthorized
bot comment emits the “unauthorized comment” notice and never emits the intended bot-skip notice.
This also performs an unnecessary permission check (gh api) for bot comments that could be
rejected immediately.
Agent Prompt
## Issue description
For comment-triggered dispatches, the new helper logs skip reasons. However, `comment_from_authorized_user()` checks authorization first and only then calls the bot filter, which means bot comments that aren’t authorized get logged as “unauthorized” instead of “bot comment”, and still incur a permission API call.

## Issue Context
`is_authorized()` calls `has_write_permission()`, which uses `gh api` to query collaborator permissions.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[60-86]
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[110-123]

## Suggested change
Reorder the checks so bot filtering happens first:
```bash
comment_from_authorized_user() {
  if ! comment_from_user; then
    return 1
  fi
  if ! is_authorized; then
    echo "::notice::Skipping dispatch for unauthorized comment from ${COMMENT_USER_LOGIN}"
    return 1
  fi
  return 0
}
```
This ensures bot comments always produce the bot notice and avoids calling the permission API for bots.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

1 participant