Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions .github/workflows/action-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,99 @@ jobs:
if-no-files-found: error
retention-days: 7

# Dogfood the *review*, not only the mechanism: the legs above prove the
# action runs; this job produces the artifact a reviewer of THIS pull
# request is meant to read instead of the raw diff, and pins it to the PR as
# one sticky comment. `/qa` reads it (QA.md § Diff-context review), and a
# selection that looks wrong on our own PRs is a product finding before any
# consumer sees it.
pr-review-context:
name: Review context for this PR
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout Code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0

- name: Build review context
id: diffctx
uses: ./
with:
format: md
scoring: ego
budget: '8000'

- name: Upload review context
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: diffctx-review-context
path: ${{ steps.diffctx.outputs.context-file }}
if-no-files-found: error
retention-days: 14

- name: Summarise and pin to the PR
shell: bash
env:
GH_TOKEN: ${{ github.token }}
CONTEXT_FILE: ${{ steps.diffctx.outputs.context-file }}
TOKEN_COUNT: ${{ steps.diffctx.outputs.token-count }}
DIFF_RANGE: ${{ steps.diffctx.outputs.diff-range }}
EMPTY: ${{ steps.diffctx.outputs.empty }}
PR_NUMBER: ${{ github.event.pull_request.number }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -euo pipefail
marker='<!-- diffctx-review-context -->'
# The changed-files block: from its header to the first blank line
# after the list starts (the header is followed by one blank line).
changed=$(awk '/^\*\*Changed files:\*\*/{f=1;next}
f&&/^$/{if(seen)exit; next}
f{seen=1; print}' "$CONTEXT_FILE")
files=$(printf '%s\n' "$changed" | grep -c . || true)
frags=$(grep -cE '^## `' "$CONTEXT_FILE" || true)
# The first thing dogfooding found: this repo's own .diffctx/ignore
# withholds *.yml, so a PR whose main change is a workflow shows up
# with that file absent and nothing saying so. Surface the policy
# line the artifact carries, so the reviewer knows to open the raw
# diff for exactly those.
withheld=$(grep -oE '^\*[0-9]+ changed file\(s\) withheld by exclusion policy[^*]*\*' "$CONTEXT_FILE" || true)
{
echo "$marker"
echo "### diffctx review context"
echo
echo "Range \`${DIFF_RANGE}\` — **${TOKEN_COUNT} tokens** (o200k_base)," \
"${frags} fragments across ${files} changed files. Empty: ${EMPTY}."
echo
echo "Review this instead of the raw diff: [download the context](${RUN_URL}#artifacts)" \
"(artifact \`diffctx-review-context\`, 14 days)."
if [ -n "$withheld" ]; then
echo
echo "${withheld} — read those in the raw diff."
fi
echo
echo "<details><summary>Changed files as diffctx lists them (omitted = no fragment fit)</summary>"
echo
printf '%s\n' "$changed" | head -80
echo
echo "</details>"
} > /tmp/comment.md
cp /tmp/comment.md "$GITHUB_STEP_SUMMARY"

# One sticky comment per PR: find ours by marker and edit it, else create.
api="repos/${GITHUB_REPOSITORY}/issues"
existing=$(gh api "${api}/${PR_NUMBER}/comments" --paginate \
--jq "[.[] | select(.body | startswith(\"${marker}\"))] | first | .id // empty")
if [ -n "$existing" ]; then
gh api -X PATCH "${api}/comments/${existing}" -F body=@/tmp/comment.md >/dev/null
else
gh api -X POST "${api}/${PR_NUMBER}/comments" -F body=@/tmp/comment.md >/dev/null
fi

# `fail-on-empty` gates whether a consumer's build breaks when a diff yields
# no semantic context. It sits behind an `if [ "$empty" = "true" ] && ...`
# branch in action.yml that no smoke leg ever entered, so the flag could stop
Expand Down
14 changes: 14 additions & 0 deletions QA.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,20 @@ dismissing as bot noise.

## Diff-context review

- **Every pull request in this repo carries its own diffctx review context**
(`action-smoke.yml` → `pr-review-context`: the published composite action
run on the PR's `base..head` at `--budget 8000`, uploaded as the
`diffctx-review-context` artifact and pinned to the PR as one sticky comment
marked `<!-- diffctx-review-context -->`). A `/qa` pass that reviews a PR
reads THAT artifact first and the raw diff only for what it withheld —
that is the dogfood. Two things to judge each time, because they are
product findings: whether the selection is what a reviewer of this change
would want (a missing caller, a pulled-in irrelevant sibling, an omitted
changed file at 8k), and whether the comment's numbers agree with a local
run of the same range. The action installs the **released** wheel
(`diffctx-version` default), so a PR that changes selection is reviewed by
the version before it — compare against a source install when the diff
touches the engine.
- Use the uv-tool binary `~/.local/bin/diffctx` (pipx-equivalent),
never `.venv/bin/diffctx`. Check its version FIRST (`uv tool list`,
not `--version` alone): a stale tool silently re-introduces fixed
Expand Down
11 changes: 11 additions & 0 deletions docs/product/github-action.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ wheels are `abi3` manylinux builds with the Rust extension compiled in, so no
toolchain and no build step are needed on the runner, and nothing touches the
repository's own Python environment.

## We use it on our own pull requests

Every PR to this repository runs the action on its own `base..head`
(`action-smoke.yml` → *Review context for this PR*) and pins the result to
the PR as one sticky comment: range, token count, fragment and file counts,
the changed-file list with omissions marked, and a link to the full context
as a workflow artifact. Reviewers read that instead of the raw diff; a
selection that reads wrong there is treated as a product defect. Copy the job
if you want the same on yours — it needs `pull-requests: write` for the
comment and nothing else.

## Notes

- Requires no token and no secret. Grant only `contents: read` unless a
Expand Down
Loading