Repository navigation
Expand file tree
/
Copy pathaction.yml
More file actions
239 lines (225 loc) · 9.81 KB
/
Copy pathaction.yml
File metadata and controls
239 lines (225 loc) · 9.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
name: "Setup Kapi CLI"
description: "Install the kapi CLI for CI workflows — downloads, verifies, caches, and configures the binary"
branding:
icon: "globe"
color: "blue"
inputs:
version:
description: "Kapi CLI version (e.g. '1.1.0' or 'latest' for the newest stable CLI release)"
required: false
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
default: ${{ github.token }}
plugins:
description: >-
Newline- or comma-separated plugin refs to install, as the registry
names them (e.g. 'bowrain', 'okapi-bridge'). The 'kapi-' binary prefix
is accepted and stripped ('kapi-bowrain' → 'bowrain'). Defaults to
'bowrain' so server-connected projects work out of the box; pass '' to
install nothing.
required: false
default: "bowrain"
auth-token:
description: "Bowrain server JWT auth token (exported as BOWRAIN_AUTH_TOKEN)"
required: false
default: ""
server:
description: "Bowrain server URL (exported as BOWRAIN_SERVER_URL)"
required: false
default: ""
cache-tm:
description: >-
Carry kapi's parse cache (.kapi/work/cache/docs) between CI runs with the
job cache. kapi keeps the state it derives out of git, under .kapi/work/.
The content memory, terms and unit-state record are committed under
.kapi/, and kapi builds its local store from them in a fresh checkout, so
they need no cache. Only the parse cache is restored: each entry is keyed
by the file's content, the parse configuration, the recipe and the kapi
build, and kapi parses a file again when any of them differs. The store
and the rest of .kapi/work/ are never restored, because restoring them
changes what kapi status, kapi check and kapi up report. Runs only when a
kapi.yaml recipe (or legacy *.kapi) is present. Set 'false' to disable.
required: false
default: "true"
project-dir:
description: "Directory holding the kapi.yaml project whose parse cache is carried between runs. Default: repository root."
required: false
default: "."
outputs:
version:
description: "Installed kapi CLI version (e.g. '0.5.0')"
value: ${{ steps.resolve.outputs.version }}
cache-hit:
description: "Whether the plugin cache was hit"
value: ${{ steps.plugin-cache.outputs.cache-hit }}
runs:
using: "composite"
steps:
# 1. Resolve version
- name: Resolve version
id: resolve
shell: bash
env:
GH_TOKEN: ${{ inputs.token }}
INPUT_VERSION: ${{ inputs.version }}
ACTION_PATH: ${{ github.action_path }}
run: |
VERSION=$("${ACTION_PATH}/scripts/resolve-version.sh" "${INPUT_VERSION}")
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "Resolved version: ${VERSION}"
# 2. Detect platform
- name: Detect platform
id: platform
shell: bash
env:
ACTION_PATH: ${{ github.action_path }}
run: |
source "${ACTION_PATH}/scripts/platform.sh"
echo "os=${GOOS}" >> "$GITHUB_OUTPUT"
echo "arch=${GOARCH}" >> "$GITHUB_OUTPUT"
echo "ext=${ARCHIVE_EXT}" >> "$GITHUB_OUTPUT"
echo "Platform: ${GOOS}/${GOARCH} (archive: .${ARCHIVE_EXT})"
# 3. Restore binary cache
- name: Restore binary cache
id: binary-cache
uses: actions/cache@v5
with:
path: ${{ runner.temp }}/setup-kapi
key: kapi-${{ steps.resolve.outputs.version }}-${{ runner.os }}-${{ runner.arch }}
# 4. Download + verify (on cache miss)
- name: Download and verify
if: steps.binary-cache.outputs.cache-hit != 'true'
shell: bash
env:
GH_TOKEN: ${{ inputs.token }}
ACTION_PATH: ${{ github.action_path }}
VERSION: ${{ steps.resolve.outputs.version }}
PLATFORM_OS: ${{ steps.platform.outputs.os }}
PLATFORM_ARCH: ${{ steps.platform.outputs.arch }}
PLATFORM_EXT: ${{ steps.platform.outputs.ext }}
INSTALL_DIR: ${{ runner.temp }}/setup-kapi
run: |
"${ACTION_PATH}/scripts/download-verify.sh" \
"${VERSION}" \
"${PLATFORM_OS}" \
"${PLATFORM_ARCH}" \
"${PLATFORM_EXT}" \
"${INSTALL_DIR}"
# 5. Add to PATH
- name: Add to PATH
shell: bash
env:
INSTALL_DIR: ${{ runner.temp }}/setup-kapi
run: echo "${INSTALL_DIR}" >> "$GITHUB_PATH"
# 6. Verify installation
- name: Verify installation
shell: bash
run: kapi version
# 7. Configure bowrain server auth (optional)
- name: Configure auth
if: inputs.auth-token != ''
shell: bash
env:
INPUT_AUTH_TOKEN: ${{ inputs.auth-token }}
INPUT_SERVER: ${{ inputs.server }}
run: |
echo "BOWRAIN_AUTH_TOKEN=${INPUT_AUTH_TOKEN}" >> "$GITHUB_ENV"
if [ -n "${INPUT_SERVER}" ]; then
echo "BOWRAIN_SERVER_URL=${INPUT_SERVER}" >> "$GITHUB_ENV"
fi
echo "Auth configured for kapi"
# 8. Compute plugin hash
- name: Compute plugin hash
if: inputs.plugins != ''
id: plugin-hash
shell: bash
env:
INPUT_PLUGINS: ${{ inputs.plugins }}
run: |
HASH=$(echo "${INPUT_PLUGINS}" | sha256sum | awk '{print $1}' 2>/dev/null || echo "${INPUT_PLUGINS}" | shasum -a 256 | awk '{print $1}')
echo "hash=${HASH}" >> "$GITHUB_OUTPUT"
# 9. Restore plugin cache
- name: Restore plugin cache
if: inputs.plugins != ''
id: plugin-cache
uses: actions/cache@v5
with:
# 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-
# 10. Install plugins (on cache miss)
- name: Install plugins
if: inputs.plugins != '' && steps.plugin-cache.outputs.cache-hit != 'true'
shell: bash
env:
INPUT_PLUGINS: ${{ inputs.plugins }}
run: |
# Normalize: replace commas with newlines, trim whitespace, skip empty
# lines, and strip the 'kapi-' binary prefix — the registry names the
# plugin 'bowrain' while its binary and archives are 'kapi-bowrain',
# so both spellings should install.
PLUGINS=$(echo "${INPUT_PLUGINS}" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/^kapi-//' | grep -v '^$')
while IFS= read -r plugin; do
# A prerelease constraint (name@X.Y.Z-rcN) lives on the beta
# channel; resolving it against stable can only fail.
args=()
case "${plugin}" in
*@*-*) args+=(--channel beta) ;;
esac
echo "Installing plugin: ${plugin}${args:+ (${args[*]})}"
kapi plugins install ${args[@]+"${args[@]}"} "${plugin}"
done <<< "${PLUGINS}"
# 11. Detect a kapi project: a committed kapi.yaml recipe (or legacy *.kapi).
# The parse cache is carried only for a project. The recipe is the
# signal because .kapi/work/ is gitignored and absent from a checkout.
- 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.yaml >/dev/null 2>&1 || ls "${PROJECT_DIR}"/*.kapi >/dev/null 2>&1; then
echo "found=true" >> "$GITHUB_OUTPUT"
else
echo "found=false (no kapi.yaml recipe (or legacy *.kapi) in ${PROJECT_DIR}); skipping the parse cache" >&2
echo "found=false" >> "$GITHUB_OUTPUT"
fi
# 12. Restore kapi's parse cache, and save it at job end. The key is unique
# to the job and run attempt, so actions/cache saves through its own
# post step; the restore takes the newest cache for the same kapi
# version, preferring the same ref.
#
# Only .kapi/work/cache/docs is carried. kapi keys each entry by the
# file's absolute path and content hash, the parse configuration, the
# recipe and the kapi build, and parses again on any mismatch, so a
# restored entry is either valid for the checkout or ignored. The rest
# of .kapi/work/ stays out of the cache:
# - store.db holds stored targets and the unit working set; restored,
# it changes what kapi status, kapi check --ship and kapi up report.
# - cache/extractions holds kapi extract batches that kapi merge reads.
# - cache/redaction and vault/ hold withheld original values.
# - cache/sync-cache.json and cache/refs.json hold server sync state,
# including a claim token.
# The content memory, terms and unit-state record are committed under
# .kapi/ and come with the checkout.
#
# The kapi version is part of the key because the parse cache keeps the
# entries every build wrote; a new version starts from an empty cache.
- name: Restore kapi parse cache
if: inputs.cache-tm != 'false' && steps.detect-project.outputs.found == 'true'
uses: actions/cache@v5
with:
path: ${{ inputs.project-dir }}/.kapi/work/cache/docs
key: kapi-parse-${{ runner.os }}-${{ steps.resolve.outputs.version }}-${{ github.ref_name }}-${{ github.job }}-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: |
kapi-parse-${{ runner.os }}-${{ steps.resolve.outputs.version }}-${{ github.ref_name }}-
kapi-parse-${{ runner.os }}-${{ steps.resolve.outputs.version }}-