Skip to content

feat(ci): add /fix slash command and widen review-relay filter#1561

Merged
jaceksan merged 1 commit intomasterfrom
feature/slash-command-relay
Apr 20, 2026
Merged

feat(ci): add /fix slash command and widen review-relay filter#1561
jaceksan merged 1 commit intomasterfrom
feature/slash-command-relay

Conversation

@tychtjan
Copy link
Copy Markdown
Contributor

@tychtjan tychtjan commented Apr 20, 2026

What this changes

Two fixes to the PR-review automation between gooddata-python-sdk and gdc-nas.

1. Relay missed the new auto-PR branch naming.
The sync pipeline used to name PRs feature/auto-P.... It now names them auto/openapi-sync-C<cluster>-<date>-r<run>. The relay's if: filter hadn't been updated, so reviews on every new auto-PR were silently dropped and never reached gdc-nas. The filter now matches the current naming. The feature/auto-P* prefix is retired — last produced 2026-03-18, no open PRs carry it today.

  if: >-
    (github.event.review.state == 'changes_requested'
      || (github.event.review.state == 'commented' && github.event.review.body))
    && github.event.pull_request.user.login == 'yenkins-admin'
-   && startsWith(github.event.pull_request.head.ref, 'feature/auto-P')
+   && startsWith(github.event.pull_request.head.ref, 'auto/openapi-sync-')
    && github.event.pull_request.head.repo.full_name == ...

2. No lightweight way to re-kick the pipeline.
Until now the only trigger was a formal "Request changes" review. For small follow-ups — or re-kicking after a missed relay event — that's heavier than needed. A PR comment of /fix (optionally /fix short note) now dispatches the same event as a formal review.

Important

GitHub activates issue_comment / pull_request_review workflow changes only from the default branch. Full end-to-end verification can only happen after this PR is merged.

Note

No changes are required in gdc-nas. The new workflow emits the exact same repository_dispatch: sdk-review-submitted payload that the existing relay does.

How it works

Topology

flowchart LR
    A["Reviewer submits<br/>formal review"] --> R
    B["User comments<br/>/fix [note]"] --> S

    subgraph SDK["gooddata-python-sdk (public)"]
      R["sdk-review-relay.yml<br/><i>pull_request_review</i>"]
      S["sdk-slash-commands.yaml<br/><i>issue_comment</i>"]
      G{"Gates"}
      R --> G
      S --> G
    end

    G -->|"repository_dispatch<br/>sdk-review-submitted"| N

    subgraph NAS["gdc-nas (private)"]
      N["sdk-py-review-fix.yml<br/><i>unchanged</i>"]
    end

    style R fill:#d4edda,stroke:#28a745,color:#000
    style S fill:#d4edda,stroke:#28a745,color:#000
    style N fill:#cce5ff,stroke:#004085,color:#000
    style G fill:#fff3cd,stroke:#856404,color:#000
Loading

/fix decision flow

flowchart TD
    Start(["User comments<br/><b>/fix [note]</b>"])
    Syntax{"Valid <b>/fix</b> syntax?<br/><i>(not /fixme, /fix-review, …)</i>"}
    Context{"PR open, open auto-PR,<br/>authored by yenkins-admin?"}
    Branch{"head.ref starts with<br/><b>auto/openapi-sync-</b>?"}
    Auth{"Commenter is a<br/><b>gdc-nas</b> collaborator?"}
    Dispatch["POST repository_dispatch<br/><b>sdk-review-submitted</b>"]
    Ack["🚀 reaction on comment"]
    Silent(["Silent exit<br/><i>green run, no reply</i>"])
    Done(["<b>gdc-nas</b> runs<br/>sdk-py-review-fix.yml"])

    Start --> Syntax
    Syntax -->|no| Silent
    Syntax -->|yes| Context
    Context -->|no| Silent
    Context -->|yes| Branch
    Branch -->|no| Silent
    Branch -->|yes| Auth
    Auth -->|no| Silent
    Auth -->|yes| Dispatch
    Dispatch --> Ack
    Dispatch --> Done

    style Start fill:#e7f3ff,stroke:#004085,color:#000
    style Dispatch fill:#d4edda,stroke:#28a745,color:#000,font-weight:bold
    style Ack fill:#d4edda,stroke:#28a745,color:#000
    style Done fill:#d4edda,stroke:#28a745,color:#000
    style Silent fill:#f8d7da,stroke:#721c24,color:#000
Loading

/fix security model

Gate ladder — cheap checks first, API calls last (click to expand)
# Gate Blocks
1 issue.pull_request != null ❌ comments on plain issues
2 issue.state == 'open' ❌ closed/merged PRs
3 startsWith(body, '/fix') + strict regex ^/fix([[:space:]].*)?$ /fixme, /fix-review, etc.
4 issue.user.login == 'yenkins-admin' ❌ comments on non-auto PRs
5 head.ref starts with auto/openapi-sync- ❌ legacy/non-auto branches
6 commenter is a collaborator on gooddata/gdc-nas ❌ everyone outside the private-repo ACL

Gates 1–4 are free (job if:). Gate 5 is one API call to resolve the PR's head.ref. Gate 6 is the auth check.

Caution

Denied commenters get a silent green run — no reply, no reaction. This is intentional: it avoids leaking authorization state (who is / isn't on the gdc-nas ACL) from the public Actions tab.

Cost to the repo

  • No new secrets. Reuses the existing TOKEN_GITHUB_YENKINS_ADMIN PAT.
  • No changes in gdc-nas. Payload is byte-identical to what the receiver already consumes.
  • Narrow token scope. Workflow's GITHUB_TOKEN is restricted to pull-requests: read; every write uses the PAT.
Payload compatibility — which fields the receiver reads (click to expand)

All seven fields match gdc-nas/.github/workflows/sdk-py-review-fix.yml:

field source (slash command) source (formal review)
pr_number github.event.issue.number github.event.pull_request.number
pr_branch resolved via gh api .../pulls/N github.event.pull_request.head.ref
pr_author literal "yenkins-admin" github.event.pull_request.user.login
reviewer github.event.comment.user.login github.event.review.user.login
review_id "" (empty) github.event.review.id
review_state literal "commented" github.event.review.state
review_body /fix arg (first line, trimmed) github.event.review.body

Empty review_id is guarded on the receiver side — it falls back to a GraphQL unresolved-threads query, so no 404.

@tychtjan tychtjan force-pushed the feature/slash-command-relay branch from 5937a75 to 7f85ea1 Compare April 20, 2026 09:21
Relay now matches the current sync pipeline branch naming
(auto/openapi-sync-*) instead of the retired feature/auto-P* prefix,
so reviews on new auto-PRs reach gdc-nas.

Adds sdk-slash-commands.yaml: a /fix PR comment dispatches the same
sdk-review-submitted repository_dispatch payload to gdc-nas that a
formal review does. Access is gated by gdc-nas collaborator membership
using the existing TOKEN_GITHUB_YENKINS_ADMIN PAT — no new secrets,
no changes in gdc-nas.

risk: low
@tychtjan tychtjan force-pushed the feature/slash-command-relay branch from 7f85ea1 to c915fc2 Compare April 20, 2026 09:31
@jaceksan jaceksan merged commit 4cb8139 into master Apr 20, 2026
7 checks passed
@jaceksan jaceksan deleted the feature/slash-command-relay branch April 20, 2026 11:07
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