Skip to content

feat: add quiet-drafts input, checked against live draft state - #205

Open
asyncawaitpromise wants to merge 3 commits into
mainfrom
fix/quiet-from-live-draft-state
Open

asyncawaitpromise wants to merge 3 commits into
mainfrom
fix/quiet-from-live-draft-state

Conversation

@asyncawaitpromise

@asyncawaitpromise asyncawaitpromise commented Sep 17, 2026 •

Copy link
Copy Markdown
Collaborator

Summary / Background

The documented pattern is quiet: ${{ github.event.pull_request.draft }}, so quiet mode comes from the webhook payload, fixed when the event fires. It goes stale two ways: force-pushing and marking a PR ready at once, where cancel-in-progress can keep the synchronize run and its payload still says draft: true; or rerunning the job, which replays the original payload. Either way the PR sits with no reviewers requested and no status comment until someone pushes again.

InitPR already fetches the PR, so the action can answer this itself. Changing quiet in place felt risky though: it is a bool, so "the payload said draft" and "I never want comments" are indistinguishable, and any new meaning lands on workflows that never opted in. quiet-drafts is one way around that, happy to go a different direction if you prefer.

quiet is unchanged, both default false, and quiet: true still wins.

Code Changes

  • internal/app/app.go: QuietDrafts field, draft check after InitPR
  • main.go: -quiet-drafts flag and INPUT_QUIET-DRAFTS
  • action.yml: quiet-drafts input
  • .github/workflows/codeowners.yml: uses quiet-drafts: true
  • README.md: quiet mode section and migration note
  • internal/app/app_test.go: quiet-drafts and draft state matrix

Callers were told to compute quiet mode from the webhook payload:

    quiet: ${{ github.event.pull_request.draft }}

That value is a snapshot in the event JSON. Marking a PR ready in the
same moment as a push delivers a synchronize event still saying
draft: true, and a job rerun replays the original payload verbatim, so
the input is frozen for the life of the run. A rerun workflow on
pull_request_review reruns the existing job and inherits it, so the
check cannot un-stick itself: the PR sits with no reviewers requested
and no status comment until a fresh push or a label toggle.

The action already has the authoritative answer. InitPR does a live
PullRequests.Get and stores the full PR, including Draft, and nothing
read it.

quiet itself is left alone. A bare bool cannot distinguish "the payload
told me this is a draft" from "I never want comments", so folding live
draft state into it would both fail to rescue callers who keep the
expression and silently quiet drafts for callers who omit the input.
Instead quiet-drafts is a separate axis, defaulting false, that consults
the API on every run. Every existing workflow keeps its current meaning,
all three old behaviors stay expressible, and the fix is a one-line
migration away from an input that cannot see a state change.
@asyncawaitpromise
asyncawaitpromise marked this pull request as ready for review September 17, 2026 02:48
@github-actions

Copy link
Copy Markdown

Codeowners approval required for this PR:

@greptile-apps

greptile-apps Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge; the previously reported reviewer-notification leak is fixed and no new actionable issue remains.

Summary

This PR adds an opt-in quiet-drafts mode that derives quiet behavior from the pull request’s live GitHub API state rather than the potentially stale webhook payload.

  • Wires the new input through the Action metadata, executable flags, and application configuration.
  • Enables quiet mode after live pull-request initialization when the pull request is still a draft.
  • Preserves ownership evaluation and status output while suppressing comments and all reviewer-request paths.
  • Updates the repository workflow and migration documentation to use quiet-drafts.
  • Adds draft-state and quiet-mode regression coverage.
  • Greptile automatically discovered a related ticket that helped explain the purpose of this PR: prevent reruns and ready-for-review races from leaving pull requests permanently silent.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Action inputs] --> B[Initialize pull request from GitHub API]
    B --> C{quiet is true?}
    C -->|Yes| D[Suppress comments and review requests]
    C -->|No| E{quiet-drafts enabled and live PR is draft?}
    E -->|Yes| D
    E -->|No| F[Allow comments and review requests]
    D --> G[Continue ownership evaluation and status result]
    F --> G
Loading

Reviews (3) · Last reviewed commit: "codebadge update"

Comment thread internal/app/app.go
@coderabbitai

coderabbitai Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 00dcc89a-d15b-426b-a737-c238183cb89d

📥 Commits

Reviewing files that changed from the base of the PR and between b162f66 and 02a5a35.

📒 Files selected for processing (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md

Included review availability: Your plan provides up to 12 included reviews per hour; 10 remain after this review.


📝 Walkthrough

Walkthrough

The action adds a quiet-drafts input with a default of false. The value flows through the action environment and command-line flags into app.Config. After pull-request initialization, the application enables quiet mode when the pull request is draft. Quiet mode suppresses comments and reviewer requests. The workflow and README now use and document this draft-aware behavior. Tests cover draft and ready pull requests, including existing quiet mode.

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant CodeownersPlus
  participant GitHubAPI
  participant PullRequest
  GitHubActions->>CodeownersPlus: pass quiet-drafts
  CodeownersPlus->>GitHubAPI: initialize pull request
  GitHubAPI-->>CodeownersPlus: return draft state
  CodeownersPlus->>PullRequest: enable quiet mode when draft
  CodeownersPlus->>GitHubAPI: create comments or reviewer requests when not quiet
Loading

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 02a5a

The draft-aware quiet setting is wired through to the intended notification-suppression behavior without an identified merge-blocking risk.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 3 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding a quiet-drafts input that uses the pull request's current draft state.
Description check ✅ Passed The description directly explains the stale webhook-state problem, the quiet-drafts design, the implementation changes, and the test coverage.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 3 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

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

When every required team has approved but min_reviews is still short,
the re-request path calls RequestReviewers directly rather than going
through requestReviews, so it never saw the quiet check that lives
there. A repo with min_reviews set and quiet enabled has been getting
review requests it asked not to have since that path was added in the
same-team re-request change (#77).

quiet-drafts makes that visible: the input promises no review requests
while a PR is a draft, and this path breaks the promise. Draft state is
folded into config.Quiet before any of this runs, so one condition
covers both the new input and a plain quiet: true.

Guarding the whole block rather than the call also drops a
GetCurrentlyRequested round trip that nothing can act on when quiet.
Comment thread internal/app/app.go
// Check if we need to re-request from a satisfied team when min_reviews is not met
// Handles the case when there min_reviews is higher than the number of teams required.
if minReviewsNeeded > 0 {
if minReviewsNeeded > 0 && !a.config.Quiet {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MEDIUM Behavior change · quiet now also suppresses min_reviews re-request

Workflows already using quiet: true now also stop the min_reviews re-request, a behavior change the PR body claims does not happen.

The sandbox blocked all shell commands, so I could not scan other call sites for additional RequestReviewers paths that bypass Quiet.

Reasoning and how to verify

Adding && !a.config.Quiet changes behavior for existing quiet: true callers: the min_reviews re-request from satisfied teams now fires only when quiet is false, whereas before this PR it fired regardless. The PR body states 'quiet is unchanged' and this is not listed under Code Changes. Either document this as an intentional behavior change in the PR description and README, or revert if it is unintended. This appears to align quiet with its documented meaning ('No Review Requests'), so it may be correct but needs explicit acknowledgment.

How to verify: Run with quiet: true and a min_reviews shortfall and compare whether RequestReviewers is called before and after this change. Expected: Review requests are no longer sent in quiet mode for the min_reviews case where they previously were.

Agent prompt:

PRism finding on internal/app/app.go:424 in multimediallc/codeowners-plus#205: Workflows already using quiet: true now also stop the min_reviews re-request, a behavior change the PR body claims does not happen. Read the review comment marked <!-- prism:finding:internal/app/app.go:42:d54fdc867820 --> on that PR, decide whether it is valid, and fix it if so; otherwise explain why not.

Fix with agent

@prism-pr-review-server

Copy link
Copy Markdown

PRism review: merge confidence 4/5

Minor findings worth a look before merge.

  • MEDIUM Workflows already using quiet: true now also stop the min_reviews re-request, a behavior change the PR body claims does not happen — app.go:424
3 lower-severity notes
  • MEDIUM The claim that the check 'un-sticks itself as soon as the PR is ready' only holds if a run is actually triggered when the PR leaves draft. GitHub's default pull_request activity types are... — README.md:396
  • LOW The documented example is internally inconsistent with the pinned release, but no shipped code changes at this version — README.md:97
  • LOW No production impact; the precedence claim is simply not covered by a test — app_test.go:1362

Full report

Reviews (1) · reviewed 02a5a35 · 6 changed files · Reviewed by PRism Lite

@github-actions

Copy link
Copy Markdown

Codeowners approval required for this PR:

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