rtl8733b: keep the send path free of register I/O, scope the TSSI rate-table knob #454
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Merge gate for the Qodo code-review agent. | |
| # | |
| # Why: branch protection's "require conversation resolution" only blocks | |
| # unresolved threads that EXIST at merge time. Qodo posts its review a minute | |
| # or two after the PR opens, so a "merge when CI is green" flow can race past | |
| # it (PR #355 merged 64 s before the review landed). This required check stays | |
| # red until (a) Qodo has reviewed the PR at least once — the first, whole-diff | |
| # pass is the valuable one — and (b) every review thread Qodo opened is | |
| # resolved. | |
| # | |
| # Deliberately NOT pinned to the current head: requiring a review of every | |
| # follow-up commit turns each review-response push into a fresh summon, and | |
| # each re-review re-scans the diff and opens a new batch of ever-smaller | |
| # findings — an unbounded fix/re-review treadmill. The first review catches | |
| # the substance; thread resolution keeps each finding accountable (address it | |
| # or dismiss it with rationale, in the thread, before resolving); follow-up | |
| # commits are maintainer judgment, exactly as with a human reviewer who does | |
| # not re-review every fixup. | |
| # | |
| # Event-driven: re-evaluates when the PR updates, when a review is submitted, | |
| # and when someone replies in a review thread. GitHub's workflow parser | |
| # rejects the documented `pull_request_review_thread` trigger ("Unexpected | |
| # value"), so plain thread resolution does not auto-retrigger — after | |
| # resolving the last thread, either leave a reply (retriggers) or Re-run the | |
| # failed qodo-gate check from the PR's Checks tab; the check reads the live | |
| # resolution state each run. Escape hatch for a Qodo outage: the | |
| # `skip-qodo-gate` label passes the check (label changes re-trigger it). | |
| name: qodo-gate | |
| on: | |
| pull_request: | |
| types: [opened, reopened, synchronize, ready_for_review, labeled, unlabeled] | |
| pull_request_review: | |
| types: [submitted] | |
| pull_request_review_comment: | |
| types: [created, deleted] | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| jobs: | |
| qodo-gate: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Require a Qodo review with all its threads resolved | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR: ${{ github.event.pull_request.number }} | |
| REPO_OWNER: ${{ github.repository_owner }} | |
| REPO_NAME: ${{ github.event.repository.name }} | |
| run: | | |
| set -euo pipefail | |
| BOT='qodo-free-for-open-source-projects' | |
| json=$(gh api graphql \ | |
| -F owner="$REPO_OWNER" -F name="$REPO_NAME" -F pr="$PR" \ | |
| -f query=' | |
| query($owner: String!, $name: String!, $pr: Int!) { | |
| repository(owner: $owner, name: $name) { | |
| pullRequest(number: $pr) { | |
| labels(first: 100) { nodes { name } } | |
| } | |
| } | |
| }') | |
| if echo "$json" | jq -e --arg l skip-qodo-gate \ | |
| '.data.repository.pullRequest.labels.nodes[] | select(.name == $l)' \ | |
| >/dev/null; then | |
| echo "PASS: skip-qodo-gate label set (Qodo outage escape hatch)" | |
| exit 0 | |
| fi | |
| # Any review by the bot counts — the first pass reviews the whole | |
| # diff, and its later in-place updates edit the same review object, | |
| # so one review object existing == the PR has been Qodo-reviewed. | |
| # Paginated: a busy PR accumulates well over 100 review objects | |
| # (every inline reply wraps itself in one), and the bot's first | |
| # review is the OLDEST — exactly what a last-100 window loses | |
| # first. --paginate applies --jq per page, so emit ids and count | |
| # lines. REST spells the bot login with a [bot] suffix, unlike | |
| # GraphQL, so match on the prefix. | |
| reviewed=$(gh api "repos/$REPO_OWNER/$REPO_NAME/pulls/$PR/reviews" \ | |
| --paginate --jq ".[] | |
| | select(.user.login | startswith(\"$BOT\")) | |
| | .id" | wc -l) | |
| if [ "$reviewed" -eq 0 ]; then | |
| echo "FAIL: no Qodo review on this PR yet — it reviews new PRs" | |
| echo "automatically within a couple of minutes; comment /review to" | |
| echo "summon one, then re-run this check once it answers. (Outage?" | |
| echo "Apply the skip-qodo-gate label.)" | |
| exit 1 | |
| fi | |
| # Unresolved Qodo threads, paginated (a long-lived PR can exceed one | |
| # 100-thread page; a truncated read must never produce a false pass). | |
| unresolved=0 | |
| cursor="" | |
| while :; do | |
| args=( -F owner="$REPO_OWNER" -F name="$REPO_NAME" -F pr="$PR" ) | |
| [ -n "$cursor" ] && args+=( -F cursor="$cursor" ) | |
| page=$(gh api graphql "${args[@]}" \ | |
| -f query=' | |
| query($owner: String!, $name: String!, $pr: Int!, $cursor: String) { | |
| repository(owner: $owner, name: $name) { | |
| pullRequest(number: $pr) { | |
| reviewThreads(first: 100, after: $cursor) { | |
| pageInfo { hasNextPage endCursor } | |
| nodes { | |
| isResolved | |
| comments(first: 10) { nodes { author { login } } } | |
| } | |
| } | |
| } | |
| } | |
| }') | |
| # A thread is Qodo's if ANY of its first comments is by the bot — | |
| # first-comment-only attribution loses the thread when the bot's | |
| # opening comment is deleted while replies remain (and deletion | |
| # re-triggers this check, so that would be a false pass). | |
| n=$(echo "$page" | jq --arg b "$BOT" \ | |
| '[.data.repository.pullRequest.reviewThreads.nodes[] | |
| | select(.isResolved | not) | |
| | select([.comments.nodes[].author.login] | index($b))] | length') | |
| unresolved=$((unresolved + n)) | |
| more=$(echo "$page" | jq -r \ | |
| '.data.repository.pullRequest.reviewThreads.pageInfo.hasNextPage') | |
| [ "$more" = "true" ] || break | |
| cursor=$(echo "$page" | jq -r \ | |
| '.data.repository.pullRequest.reviewThreads.pageInfo.endCursor') | |
| done | |
| if [ "$unresolved" -gt 0 ]; then | |
| echo "FAIL: $unresolved unresolved Qodo review thread(s) — address" | |
| echo "or explicitly dismiss each finding in its thread, then mark" | |
| echo "it resolved. Plain resolution does not auto-retrigger this" | |
| echo "check: leave a reply in a thread (retriggers) or Re-run the" | |
| echo "check from the PR's Checks tab after resolving." | |
| exit 1 | |
| fi | |
| echo "PASS: Qodo review present, all its threads resolved" |