From 31419e596fc4e5505af344acd56a3d72e491ff1b Mon Sep 17 00:00:00 2001 From: Asgeir Frimannsson Date: Sat, 26 Sep 2026 10:28:39 +0200 Subject: [PATCH] Add a context-sync input that pulls and pushes the project's context A project whose kapi.yaml declares a context backend (kapi 1.3 and later) keeps its context there; the input pulls it before the command and, when true, pushes what the run recorded after it. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01NcQUx2CZv5hQhQHiNRQyGX --- README.md | 37 ++++++++++++++++++++++++++++++++++++- action.yml | 31 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a4b54a..290c3bc 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,36 @@ The Action reads the cause from the report kapi printed, in whichever format `ar This runs `kapi run -p kapi.yaml translate`. +### Share the project's context + +A project whose `kapi.yaml` declares a context backend keeps its terms, voice +profiles, approved wording and decisions there rather than in files the +repository carries: + +```yaml +context: + backend: git # the context lives on refs/kapi/context in this repository +``` + +`context-sync` moves it around the run: `pull` takes in what the team pushed +before the command runs, and `true` also pushes what the run recorded after it. + +```yaml +permissions: + contents: write # push the context ref +steps: + - uses: actions/checkout@v5 + - uses: neokapi/setup-kapi@v1 + - uses: neokapi/kapi-action@v1 + with: + command: up + context-sync: true +``` + +A pull request from a fork can pull and cannot push, so use `context-sync: pull` +there. A pull or push that cannot reach the backend exits with status 5 and +changes nothing. + ### Settle suggestions after a merge A suggestion recorded in the project's context becomes an established rule once a person's signal backs it, and a change reaching the default branch is one: a person reviewed and merged it. Run `kapi context settle --merged` on a push to the default branch to record that evidence and establish what it backs. The same range records the same evidence, so a rerun changes nothing. @@ -251,6 +281,10 @@ jobs: The pull request is read from the merge commit's subject (`(#412)` or `Merge pull request #412`); pass `--pr` in `args` when it is not there. +A project with a context backend can leave out the cache and the data +directory: set `context-sync: true` on the settle step, and it pulls the +context, settles, and pushes the rules it established. + ### Caching `neokapi/setup-kapi@v1` carries kapi's parse cache (`.kapi/work/cache/docs`) between runs. Its `cache-tm` input is on by default for a project with a `kapi.yaml`, so this Action needs no cache step of its own. Set setup-kapi's `project-dir` when the recipe is not at the repository root. @@ -269,6 +303,7 @@ Leave the rest of `.kapi/work/` out of any cache. Its store holds the targets an | `pr-comment` | `false` | Sticky report comment on pull-request events, including for a failed gate or a check that did not run | | `token` | `${{ github.token }}` | Token for the sticky PR comment | | `paths` | | Space-separated paths to scan for changes (whole working tree if empty) | +| `context-sync` | `false` | `pull` runs `kapi context pull` before the command; `true` also runs `kapi context push` after it, except in plan mode (kapi 1.3 and later) | ## Outputs @@ -287,7 +322,7 @@ Leave the rest of `.kapi/work/` out of any cache. Its store holds the targets an ## Permissions -The action itself needs no write permissions. Your delivery step needs `contents: write` (plus `pull-requests: write` for PR delivery); `pr-comment` needs `pull-requests: write`. +The action itself needs no write permissions, except that `context-sync: true` with a `git` backend pushes the context ref and needs `contents: write`. Your delivery step needs `contents: write` (plus `pull-requests: write` for PR delivery); `pr-comment` needs `pull-requests: write`. ## License diff --git a/action.yml b/action.yml index 15e5d59..7a602bf 100644 --- a/action.yml +++ b/action.yml @@ -48,6 +48,15 @@ inputs: description: "Space-separated paths to scan for changes (empty = whole working tree)" required: false default: "" + context-sync: + description: >- + Move the project's context through the backend its kapi.yaml declares + under `context:` (kapi 1.3 and later). `pull` runs `kapi context pull` + before the command; `true` also runs `kapi context push` after it, unless + the run is a plan. Pushing a git backend needs `permissions: contents: + write`; a pull request from a fork can pull and cannot push. + required: false + default: "false" outputs: status: @@ -97,6 +106,17 @@ outputs: runs: using: "composite" steps: + - name: Pull the project's context + if: ${{ inputs.context-sync == 'pull' || inputs.context-sync == 'true' }} + shell: bash + env: + PROJECT: ${{ inputs.project }} + run: | + set -euo pipefail + cmd=(kapi context pull) + [ -n "$PROJECT" ] && cmd+=(-p "$PROJECT") + "${cmd[@]}" + - name: Run kapi id: run-kapi shell: bash @@ -338,6 +358,17 @@ runs: # already did, and a later step that succeeds does not undo it. A run that # failed any other way reports nothing, so a delivery step is never handed # the partial work of a broken `kapi up`. + - name: Push the context the run recorded + if: ${{ inputs.context-sync == 'true' && inputs.plan != 'true' }} + shell: bash + env: + PROJECT: ${{ inputs.project }} + run: | + set -euo pipefail + cmd=(kapi context push) + [ -n "$PROJECT" ] && cmd+=(-p "$PROJECT") + "${cmd[@]}" + - name: Check for changes id: check-changes if: ${{ !cancelled() && inputs.plan != 'true' && (success() || steps.run-kapi.outputs.result == 'failed' || steps.run-kapi.outputs.result == 'did_not_run') }}