From a7edcb2ebd5397a0e29cabe5e747b3fdbaeb2ada Mon Sep 17 00:00:00 2001 From: Asgeir Frimannsson Date: Sat, 18 Jul 2026 23:34:53 +0800 Subject: [PATCH] feat: cache the project TM across CI runs (out of git) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The translation memory is derived state, not committed source (neokapi AD-009): it accumulates leverage but should never land in git. Add a job-cache step that restores the latest branch TM at setup and — via a run-unique key — saves the grown TM back at job end through actions/cache's own post step. No commits, no locking (per-branch, last-write-wins); a cold cache rebuilds from the committed translations, so losing it is a perf hit, not data loss. Covers .kapi/tm.db and the .kapi/cache/ derived stores. Gated on a *.kapi recipe being present (the .kapi/ state dir is gitignored, so the committed recipe is the signal). New inputs: cache-tm (default true), project-dir (default "."). Implements neokapi#1367. --- README.md | 3 +++ action.yml | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/README.md b/README.md index 606226b..0aa77a1 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ steps: | `plugins` | Newline- or comma-separated plugin refs to install, as the registry names them (`bowrain`, `okapi-bridge`; a `kapi-` prefix is stripped). Pass `''` to install nothing | `bowrain` | No | | `auth-token` | Bowrain server JWT, exported as `BOWRAIN_AUTH_TOKEN` | — | No | | `server` | Bowrain server URL, exported as `BOWRAIN_SERVER_URL` | — | No | +| `cache-tm` | Restore/persist the project translation memory across runs via the job cache (out of git). Runs only when a `*.kapi` recipe is present. Set `false` to disable | `true` | No | +| `project-dir` | Directory holding the `.kapi` project for the TM cache | `.` | No | ## Outputs @@ -100,6 +102,7 @@ image. 4. **Add to PATH** — makes `kapi` available to all subsequent steps. 5. **Configure auth** (optional) — exports `BOWRAIN_AUTH_TOKEN`/`BOWRAIN_SERVER_URL` when `auth-token` is set. 6. **Install plugins** — installs each ref in `plugins` (default: `bowrain`) via `kapi plugins install`, cached keyed on the plugin set + OS + arch. Refs use the registry names; a `kapi-` binary prefix is stripped (`kapi-bowrain` → `bowrain`). +7. **Restore project TM cache** (when a `*.kapi` recipe is present) — restores the latest translation memory for the branch from the job cache and, via a run-unique key, saves the grown TM back at job end. The TM is **derived state kept out of git**: it accumulates leverage across runs without being committed, and a cold cache simply rebuilds from the committed translations. No commits, no locking (per-branch, last-write-wins). Disable with `cache-tm: false`. ## Caching diff --git a/action.yml b/action.yml index 9583b12..bb9b5c6 100644 --- a/action.yml +++ b/action.yml @@ -30,6 +30,20 @@ inputs: description: "Bowrain server URL (exported as BOWRAIN_SERVER_URL)" required: false default: "" + cache-tm: + description: >- + Restore and persist the project translation memory across CI runs via the + job cache. The TM is derived state kept out of git (AD-009): the latest + branch TM is restored at setup, and the grown TM is saved back at job end + under a run-unique key, so leverage compounds without committing anything. + A cold cache is fine — kapi rebuilds the TM from the committed translations. + Runs only when a *.kapi recipe is present. Set 'false' to disable. + required: false + default: "true" + project-dir: + description: "Directory holding the .kapi project (recipe + state) for the TM cache. Default: repository root." + required: false + default: "." outputs: version: @@ -165,3 +179,39 @@ runs: echo "Installing plugin: ${plugin}" kapi plugins install "${plugin}" done <<< "${PLUGINS}" + + # 11. Detect a kapi project — a committed *.kapi recipe. The TM cache only + # runs where there is a project TM to persist (the .kapi/ state dir is + # gitignored, so it may not exist yet; the recipe is the committed signal). + - name: Detect kapi project + id: detect-project + if: inputs.cache-tm != 'false' + shell: bash + env: + PROJECT_DIR: ${{ inputs.project-dir }} + run: | + if ls "${PROJECT_DIR}"/*.kapi >/dev/null 2>&1; then + echo "found=true" >> "$GITHUB_OUTPUT" + else + echo "found=false (no *.kapi recipe in ${PROJECT_DIR}); skipping TM cache" >&2 + echo "found=false" >> "$GITHUB_OUTPUT" + fi + + # 12. Restore/persist the project TM across runs via the job cache. The TM is + # derived state kept out of git (AD-009): restore the latest branch TM at + # setup, and — because the key is run-unique — actions/cache saves the + # grown TM at job end via its own post step. No git writes, no locking + # (additive + rebuildable, last-write-wins); a cold cache rebuilds from + # committed content. Covers the current .kapi/tm.db and the .kapi/cache/ + # derived stores. + - name: Restore project TM cache + if: inputs.cache-tm != 'false' && steps.detect-project.outputs.found == 'true' + uses: actions/cache@v5 + with: + path: | + ${{ inputs.project-dir }}/.kapi/tm.db + ${{ inputs.project-dir }}/.kapi/cache + key: kapi-tm-${{ runner.os }}-${{ github.ref_name }}-${{ github.run_id }} + restore-keys: | + kapi-tm-${{ runner.os }}-${{ github.ref_name }}- + kapi-tm-${{ runner.os }}-