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
10 changes: 8 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,16 @@ jobs:
shell: bash
env:
GH_TOKEN: ${{ secrets.NEOKAPI_GITHUB_TOKEN }}
# Use the action's own resolver rather than a second copy of the logic.
# This step used to call `releases/latest` directly and hit exactly the
# bug the action had: neokapi/neokapi publishes plugin and app releases
# alongside CLI ones, so that flag lands on whichever was published last
# (a plugin, today), and the pinned test then asked for version
# "check-v0.1.0".
run: |
TAG=$(gh api repos/neokapi/neokapi/releases/latest --jq .tag_name)
VERSION="${TAG#v}"
VERSION=$(./scripts/resolve-version.sh latest)
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "Pinning to CLI version ${VERSION}"

- name: Setup kapi (pinned)
id: setup
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The built-in `GITHUB_TOKEN` is used by default for release downloads, so no toke
steps:
- uses: neokapi/setup-kapi@v1
with:
version: "1.0.0"
version: "1.1.0"
```

### Run a localization pipeline
Expand All @@ -43,16 +43,16 @@ steps:
auth-token: ${{ secrets.BOWRAIN_AUTH_TOKEN }}
server: https://your.bowrain.server

- run: kapi sync
- run: kapi up
```

To run the full sync-and-commit flow, pair this with [`kapi-action`](https://github.com/neokapi/kapi-action).
`kapi up` is the convergence verb: with the bowrain plugin installed and a `server:` block in the recipe, it pushes, converges on the server, and pulls the produced targets back. To run it and commit the results, pair this with [`kapi-action`](https://github.com/neokapi/kapi-action).

## Inputs

| Input | Description | Default | Required |
|-------|-------------|---------|----------|
| `version` | Kapi CLI version (e.g. `1.0.0` or `latest`) | `latest` | No |
| `version` | Kapi CLI version (e.g. `1.1.0`), or `latest` for the newest stable CLI release | `latest` | No |
| `token` | GitHub token for release downloads and API rate limits | `${{ github.token }}` | No |
| `plugins` | Newline- or comma-separated plugin refs to install (e.g. `kapi-bowrain`) | — | No |
| `auth-token` | Bowrain server JWT, exported as `BOWRAIN_AUTH_TOKEN` | — | No |
Expand All @@ -67,7 +67,7 @@ To run the full sync-and-commit flow, pair this with [`kapi-action`](https://git

## How it works

1. **Resolve version** — `latest` queries the GitHub API for the most recent release; pinned versions pass through.
1. **Resolve version** — `latest` resolves the newest *stable CLI* release (a `vX.Y.Z` tag). It deliberately does not use GitHub's "latest release" flag: the same repository publishes plugin and app releases (`check-v0.1.0`, `asr-v0.1.1`, `bowrain-v…`), and that flag lands on whichever was published last. Pinned versions pass through.
2. **Cache check** — restores a cached binary keyed on `kapi-{version}-{os}-{arch}`.
3. **Download + verify** (on cache miss) — downloads the archive and `checksums.txt` from the GitHub release, verifies the SHA-256 checksum, and extracts the binary.
4. **Add to PATH** — makes `kapi` available to all subsequent steps.
Expand All @@ -83,7 +83,7 @@ The binary is cached keyed on version + OS + arch; plugins are cached keyed on t
| Runner OS | Architectures |
|-----------|---------------|
| Linux | amd64, arm64 |
| macOS | amd64, arm64 |
| macOS | arm64 (Apple silicon; no Intel build is published) |
| Windows | amd64, arm64 |

## License
Expand Down
11 changes: 8 additions & 3 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ branding:

inputs:
version:
description: "Kapi CLI version (e.g. '0.5.0' or 'latest')"
description: "Kapi CLI version (e.g. '1.1.0' or 'latest' for the newest stable CLI release)"
required: false
default: "1.0.0"
default: "latest"
token:
description: "GitHub token used for release downloads and API rate limits. The built-in GITHUB_TOKEN is sufficient now that neokapi/neokapi is public."
required: false
Expand Down Expand Up @@ -134,7 +134,12 @@ runs:
id: plugin-cache
uses: actions/cache@v5
with:
path: ~/.config/kapi/plugins
# kapi installs plugins under $XDG_DATA_HOME/kapi/plugins — i.e.
# ~/.local/share/kapi/plugins when XDG_DATA_HOME is unset, as it is on a
# runner. The old ~/.config/kapi/plugins is the CONFIG dir: nothing was
# ever written there, so the cache saved an empty path and every run
# re-downloaded every plugin.
path: ~/.local/share/kapi/plugins
key: kapi-plugins-${{ steps.plugin-hash.outputs.hash }}-${{ runner.os }}-${{ runner.arch }}
restore-keys: |
kapi-plugins-
Expand Down
7 changes: 7 additions & 0 deletions scripts/platform.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ case "${RUNNER_ARCH}" in
*) echo "::error::Unsupported architecture: ${RUNNER_ARCH}" >&2; exit 1 ;;
esac

# The CLI ships darwin_arm64 only — there is no Intel-mac archive to download, so
# say that plainly here instead of failing later with a 404 on a release asset.
if [ "${GOOS}" = "darwin" ] && [ "${GOARCH}" = "amd64" ]; then
echo "::error::kapi does not publish an Intel-macOS (darwin_amd64) build. Use an arm64 macOS runner (macos-14 or newer, or macos-latest)." >&2
exit 1
fi

case "${GOOS}" in
windows) ARCHIVE_EXT="zip" ;;
*) ARCHIVE_EXT="tar.gz" ;;
Expand Down
30 changes: 26 additions & 4 deletions scripts/resolve-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Resolve kapi CLI version.
#
# Usage: resolve-version.sh <version>
# If <version> is "latest", queries the GitHub API for the latest release tag.
# If <version> is "latest", resolves the newest STABLE kapi CLI release.
# Otherwise, strips a leading "v" and echoes the version.
#
# Requires: GH_TOKEN for the `gh` CLI (API rate limits). The built-in
Expand All @@ -13,11 +13,33 @@ set -euo pipefail
VERSION="${1:?Usage: resolve-version.sh <version>}"

if [ "${VERSION}" = "latest" ]; then
TAG=$(gh api repos/neokapi/neokapi/releases/latest --jq .tag_name 2>/dev/null) || {
echo "::error::Failed to query the latest neokapi/neokapi release." >&2
# NOT `releases/latest`. One repository publishes the CLI, the desktop apps,
# the bowrain server, and every plugin, so its releases are a mix of tags:
# v1.1.0 ← the CLI (what we want)
# check-v0.1.0 ← the kapi-check plugin
# asr-v0.1.1 ← the kapi-asr plugin
# bowrain-v1.2.0-rc8
# v1.2.0-rc9 ← a CLI prerelease
# GitHub's "latest" flag lands on whichever of those was published last — as of
# writing, a plugin (check-v0.1.0). Asking for it yielded VERSION=check-v0.1.0,
# a download of `kapi_check-v0.1.0_linux_amd64.tar.gz` from tag `vcheck-v0.1.0`,
# and a 404. So resolve the CLI ourselves: tags of the exact shape vX.Y.Z,
# excluding drafts, prereleases, and every plugin/app tag prefix.
VERSION=$(
gh api "repos/neokapi/neokapi/releases?per_page=100" --paginate \
--jq '.[] | select(.draft == false and .prerelease == false) | .tag_name' 2>/dev/null |
grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' |
sed 's/^v//' |
sort -V |
tail -n 1
) || {
echo "::error::Failed to query neokapi/neokapi releases." >&2
exit 1
}
VERSION="${TAG#v}"
if [ -z "${VERSION}" ]; then
echo "::error::No stable kapi CLI release (vX.Y.Z) found in neokapi/neokapi." >&2
exit 1
fi
else
VERSION="${VERSION#v}"
fi
Expand Down
Loading