diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 6de471e..acf8008 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -20,7 +20,7 @@ on:
workflow_dispatch:
env:
- KAPI_VERSION: "1.2.0-rc29"
+ KAPI_VERSION: "1.2.0-rc32"
jobs:
test-plan:
@@ -39,7 +39,7 @@ jobs:
uses: ./
with:
plan: "true"
- project: "test/fixture/fixture.kapi"
+ project: "test/fixture/kapi.yaml"
- name: Verify plan outputs
env:
@@ -71,7 +71,7 @@ jobs:
with:
command: check
args: "--ship"
- project: "test/fixture/fixture.kapi"
+ project: "test/fixture/kapi.yaml"
- name: Verify gate contract
env:
@@ -382,3 +382,58 @@ jobs:
run: |
test -f test/fixture/content/en_qps.json
test "${STATUS}" = "no-changes"
+
+ # The README sends callers to setup-kapi's cache-tm for caching rather than a
+ # cache step of their own. The save job runs the action and finds kapi's parse
+ # cache where setup-kapi saves it, and nothing at the retired .kapi/cache path;
+ # the restore job must find that cache in place before the action runs again.
+ test-parse-cache-save:
+ name: "parse cache: written where setup-kapi saves it"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+
+ - uses: neokapi/setup-kapi@v1
+ with:
+ version: ${{ env.KAPI_VERSION }}
+ plugins: ""
+ project-dir: test/fixture
+
+ - name: Report status
+ uses: ./
+ with:
+ command: status
+ project: "test/fixture/kapi.yaml"
+
+ - name: Verify the cache paths
+ run: |
+ test -f test/fixture/.kapi/work/cache/docs/index.db
+ test ! -e test/fixture/.kapi/cache
+
+ test-parse-cache-restore:
+ name: "parse cache: restored before the action runs"
+ needs: test-parse-cache-save
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6
+
+ - uses: neokapi/setup-kapi@v1
+ with:
+ version: ${{ env.KAPI_VERSION }}
+ plugins: ""
+ project-dir: test/fixture
+
+ - name: Verify the restored cache
+ run: test -f test/fixture/.kapi/work/cache/docs/index.db
+
+ - name: Report status on the restored cache
+ id: status
+ uses: ./
+ with:
+ command: status
+ project: "test/fixture/kapi.yaml"
+
+ - name: Verify the action reports no changes
+ env:
+ STATUS: ${{ steps.status.outputs.status }}
+ run: test "${STATUS}" = "no-changes"
diff --git a/README.md b/README.md
index 6d2e580..55c287f 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ This action requires the `kapi` CLI to be installed. Use [`neokapi/setup-kapi@v1
### Bring translations up to date
-`kapi up` runs the kapi loop, and is the Action's default. In a server-connected project — a recipe with a `server:` block — it pushes, catches up on the Bowrain server (org keys, shared TM, team review), and pulls the produced targets back. With no server it runs the same loop locally.
+`kapi up` runs the kapi loop, and is the Action's default. It needs kapi 1.2.0 or later, which `neokapi/setup-kapi@v1` installs by default. In a server-connected project, a recipe with a `bowrain:` block, it pushes, catches up on the Bowrain server, and pulls the produced targets back; give setup-kapi the server token. With no server it runs the same loop locally and needs an AI provider key, such as `ANTHROPIC_API_KEY`.
```yaml
name: Translations
@@ -29,10 +29,16 @@ jobs:
- uses: actions/checkout@v6
- uses: neokapi/setup-kapi@v1
+ with:
+ # A recipe with a bowrain: block runs the loop on the server.
+ auth-token: ${{ secrets.BOWRAIN_AUTH_TOKEN }}
- uses: neokapi/kapi-action@v1
+ env:
+ # A project with no server translates locally with your provider key.
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- # The action reports; delivery is your step. Any commit action works —
+ # The action reports; delivery is your step. Any commit action works,
# or plain git. See "Delivering the changes" for the PR-based recipe.
- uses: stefanzweifel/git-auto-commit-action@v5
with:
@@ -76,11 +82,11 @@ flowchart LR
U --> PASS
CK -->|every gate met| CV["up to date
changes ready to deliver"]
CK -->|needs a person| PK["parked
the review queue"]
- PK --> RV["review & approve
recorded in .kapi-state.json"]
+ PK --> RV["review & approve
committed under .kapi/state"]
RV -.->|next run sees it| U
```
-**Parked work is the review queue, not an error.** What the machine couldn't decide waits for a person: review the wording, approve or fix it, and the decision is recorded — in the committed `.kapi-state.json` state store, or on the connected server. Approvals raise the `reviewed` coverage the ship gate measures, so the next run and the next gate see them. `kapi check --ship` (see [Gate pull requests](#gate-pull-requests-on-content-quality)) is what enforces the bar at release time.
+**Parked work is the review queue, not an error.** What the machine couldn't decide waits for a person: review the wording, approve or fix it, and `kapi commit` records the decision under `.kapi/state/`, or the connected server records it. Approvals raise the `reviewed` coverage the ship gate measures, so the next run and the next gate see them. `kapi check --ship` (see [Gate pull requests](#gate-pull-requests-on-content-quality)) is what enforces the bar at release time.
The kapi up report (outcome, passes, parked locales) is always written to the job summary. Under the hood the Action runs `kapi up --json`, an NDJSON stream — one convergence event per line, closed by a single `{"type":"result", ...}` record. That record is the contract; the events are the log. It becomes the `outcome`, `passes`, and `parked-locales` outputs.
@@ -155,7 +161,7 @@ jobs:
### Gate pull requests on content quality
-`command: check` with `--ship` is the release bar: the project's bound quality gates (brand, terminology, QA) plus its ship/source coverage gates. An unmet gate exits `3`, which the Action surfaces as a distinct **"gate unmet"** annotation (not a generic failure), as `gate: fail` and as `result: failed`:
+`command: check` with `--ship` is the release bar: the project's bound gates (voice, terminology, rule-based checks) plus its ship and source coverage gates. An unmet gate exits `3`, which the Action surfaces as a distinct **"gate unmet"** annotation (not a generic failure), as `gate: fail` and as `result: failed`:
```yaml
name: Ship gate
@@ -213,17 +219,9 @@ This runs `kapi run -p kapi.yaml translate`.
### Caching
-The loop runs incrementally via the project's `.kapi/cache` (block store, extractions), which is gitignored and therefore rebuilt on every fresh runner. Restore it across runs to skip re-extraction:
-
-```yaml
-- uses: actions/cache@v5
- with:
- path: .kapi/cache
- key: kapi-cache-${{ hashFiles('kapi.yaml', 'src/locales/en/**') }}
- restore-keys: kapi-cache-
-```
+`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.
-Server-connected projects don't need this — the project state lives on the server.
+Leave the rest of `.kapi/work/` out of any cache. Its store holds the targets and review state a run produced, and a restored copy changes what `kapi status`, `kapi check --ship` and `kapi up` report.
## Inputs
diff --git a/test/fixture/fixture.kapi b/test/fixture/kapi.yaml
similarity index 100%
rename from test/fixture/fixture.kapi
rename to test/fixture/kapi.yaml