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
25 changes: 0 additions & 25 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,31 +63,6 @@ jobs:
- run: python -m ruff format --check .
- run: python -m pytest -q

# Proves the README's own quick start still works: pytest (see tests/test_quickstart_block.py)
# already proves the extractor fails a broken block, so this job just has to run the real one.
quickstart:
name: Quick start verified
runs-on: ubuntu-latest
# Reads the checkout; writes nothing.
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: "3.12"
# Installed from this checkout, not PyPI, so the README's own `pip install context-report`
# line finds itself already satisfied and does not fetch a different released version.
- run: pip install .
- name: Extract and run the README's quickstart block
run: |
workdir=$(mktemp -d)
python3 tools/quickstart_block.py README.md > "$workdir/quickstart.sh"
cd "$workdir"
bash -euo pipefail quickstart.sh

# This repo is itself a chock adopter (see AGENTS.md, .agents/policies/): it governs
# its own contributions the same way chock and chock-catalog do. Checking it here
# proves the adoption on this repo rather than only in chock's own tests, and closes
Expand Down
92 changes: 92 additions & 0 deletions .github/workflows/demo-gif.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Render demo GIF
# Two ways in: workflow_dispatch proves docs/assets/demo.gif is reproducible from
# docs/assets/demo.tape without touching any branch (download the demo-gif artifact and
# commit it by hand). A push touching the tape on a non-default branch renders and commits
# the regenerated GIF back to that branch, so a tape change carries its GIF into its own
# pull request -- main is protected with no bypass, so this workflow can never push there.
on:
workflow_dispatch:
push:
paths: ["docs/assets/demo.tape"]
branches-ignore: [main]
permissions: {}
jobs:
render:
name: Render docs/assets/demo.tape
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: "3.12"
- run: pip install .
# No verified pin for charmbracelet/vhs-action was available to this change (see the PR
# description's Deviations); this reproduces the same tape with the plain VHS binary
# instead, using the release URL already pinned in docs/README-refresh's render recipe.
- name: Install ttyd, ffmpeg and vhs
# Checksum from charmbracelet/vhs's own v0.10.0 release checksums.txt -- verified before
# this pin was added; a corrupted or substituted download fails the sha256sum check below.
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq ttyd ffmpeg
curl -sSL -o /tmp/vhs.tgz https://github.com/charmbracelet/vhs/releases/download/v0.10.0/vhs_0.10.0_Linux_x86_64.tar.gz
echo "b552c3870aca101dcafe533cfef32dceb7b783400ad32642e728775c9f125407 /tmp/vhs.tgz" | sha256sum -c -
tar xzf /tmp/vhs.tgz -C /tmp
sudo install -m 0755 /tmp/vhs_0.10.0_Linux_x86_64/vhs /usr/local/bin/vhs
- name: Render as a non-root user (Chromium refuses to run as root)
run: |
sudo useradd -m vhsuser
sudo chmod -R a+rX "$PWD"
sudo chmod 777 docs/assets
sudo su vhsuser -c "cd $PWD && vhs docs/assets/demo.tape"
sudo chown "$(id -u)":"$(id -g)" docs/assets/demo.gif
sudo chmod 755 docs/assets
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: demo-gif
path: docs/assets/demo.gif

render-and-commit:
name: Render docs/assets/demo.tape and commit the GIF
if: github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: true
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: "3.12"
- run: pip install .
# No verified pin for charmbracelet/vhs-action was available to this change (see the PR
# description's Deviations); this reproduces the same tape with the plain VHS binary
# instead, using the release URL already pinned in docs/README-refresh's render recipe.
- name: Install ttyd, ffmpeg and vhs
# Checksum from charmbracelet/vhs's own v0.10.0 release checksums.txt -- verified before
# this pin was added; a corrupted or substituted download fails the sha256sum check below.
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq ttyd ffmpeg
curl -sSL -o /tmp/vhs.tgz https://github.com/charmbracelet/vhs/releases/download/v0.10.0/vhs_0.10.0_Linux_x86_64.tar.gz
echo "b552c3870aca101dcafe533cfef32dceb7b783400ad32642e728775c9f125407 /tmp/vhs.tgz" | sha256sum -c -
tar xzf /tmp/vhs.tgz -C /tmp
sudo install -m 0755 /tmp/vhs_0.10.0_Linux_x86_64/vhs /usr/local/bin/vhs
- name: Render as a non-root user (Chromium refuses to run as root)
run: |
sudo useradd -m vhsuser
sudo chmod -R a+rX "$PWD"
sudo chmod 777 docs/assets
sudo su vhsuser -c "cd $PWD && vhs docs/assets/demo.tape"
sudo chown "$(id -u)":"$(id -g)" docs/assets/demo.gif
sudo chmod 755 docs/assets
- uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0
with:
commit_message: "docs: regenerate demo.gif"
file_pattern: docs/assets/demo.gif
48 changes: 48 additions & 0 deletions .github/workflows/quickstart.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Quick start
on:
push:
branches: [main]
pull_request:
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Proves the README's own quick start still works, and that docs/quickstart.sh (the same
# commands, committed for anyone who wants a runnable script) has not drifted from it.
# tools/quickstart_block.py stays the single source: this job regenerates
# docs/quickstart.sh from the README and diffs it before running it.
quickstart:
name: Quick start verified
runs-on: ubuntu-latest
# Reads the checkout; writes nothing (docs/quickstart.sh is checked for drift, not committed).
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: "3.12"
# Installed from this checkout, not PyPI, so the README's own `pip install context-report`
# line finds itself already satisfied and does not fetch a different released version.
- run: pip install .
- name: Regenerate docs/quickstart.sh and check it matches the committed copy
run: |
{
printf '#!/usr/bin/env bash\n'
printf 'set -euo pipefail\n'
printf '# Generated from the README.md quickstart block by tools/quickstart_block.py. Do not edit by hand.\n'
python3 tools/quickstart_block.py README.md
} > /tmp/quickstart.sh.generated
if ! diff -u docs/quickstart.sh /tmp/quickstart.sh.generated; then
echo "::error::docs/quickstart.sh is stale -- regenerate it from README.md's quickstart block (tools/quickstart_block.py) and commit it."
exit 1
fi
- name: Run docs/quickstart.sh in a fresh directory
run: |
workdir=$(mktemp -d)
cp docs/quickstart.sh "$workdir/quickstart.sh"
cd "$workdir"
bash -euo pipefail quickstart.sh
45 changes: 0 additions & 45 deletions .github/workflows/render-demo.yml

This file was deleted.

12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ Per in-toto convention, `0.X` versions are major: fields may change until 1.0.

## Unreleased

### CI

- `.github/workflows/render-demo.yml` renamed to `demo-gif.yml`: the `workflow_dispatch`
trigger still renders and uploads the `demo-gif` artifact, and a new `push` trigger (on
`docs/assets/demo.tape`, non-default branches only) renders and commits the regenerated GIF
back to the branch, since `main` is protected with no bypass and cannot receive a workflow
push directly.
- The `quickstart` job moved out of `ci.yml` into its own `.github/workflows/quickstart.yml`
(`push`, `pull_request`). It still extracts and runs the README's fenced quickstart block via
`tools/quickstart_block.py`, and now also regenerates `docs/quickstart.sh` from that block and
fails if the committed copy has drifted, so the README stays the single source.

### Docs

- README: a rendered `produce`/`verify` demo GIF (`docs/assets/demo.tape`, reproducible via
Expand Down
25 changes: 25 additions & 0 deletions docs/quickstart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -euo pipefail
# Generated from the README.md quickstart block by tools/quickstart_block.py. Do not edit by hand.
pip install context-report
mkdir -p my-plugin/hooks
cat > my-plugin/hooks/guard.py <<'PY'
#!/usr/bin/env python3
import json, sys
event = json.load(sys.stdin)
command = event.get("tool_input", {}).get("command", "")
if "destructive-pattern" in command:
print(json.dumps({"decision": "deny", "reason": "blocked destructive command"}))
sys.exit(0)
PY
cat > my-plugin/hooks/hooks.json <<'JSON'
{
"hooks": {
"PreToolUse": [
{"hooks": [{"command": "python3", "args": ["${CLAUDE_PLUGIN_ROOT}/hooks/guard.py"]}]}
]
}
}
JSON
context-report produce --subject ./my-plugin --kind plugin --target claude_code --n 20 --out report.json
context-report verify report.json --subject ./my-plugin