Skip to content

Commit 550f2a6

Browse files
authored
Merge pull request #4 from buildkite-plugins/codex/hosted-agent-cache
feat: add hosted agent cache support
2 parents 11e8721 + 9b43dc0 commit 550f2a6

4 files changed

Lines changed: 148 additions & 50 deletions

File tree

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,25 @@ steps:
3131
command: go test ./...
3232
```
3333
34+
## Hosted Agent Cache Volumes
35+
36+
```yml
37+
cache: ".buildkite/cache-volume"
38+
39+
steps:
40+
- label: ":wrench: Test"
41+
plugins:
42+
- buildkite-plugins/mise#v1.0.0: ~
43+
command: go test ./...
44+
```
45+
46+
When running on Buildkite hosted agents, the plugin automatically uses `/cache/bkcache/mise` as `MISE_DATA_DIR` if a cache volume is attached. Buildkite only mounts that volume when the pipeline or step defines `cache`, so you still need to request one in `pipeline.yml`.
47+
3448
## Configuration
3549

3650
- `version` (default: `latest`): mise version to install.
3751
- `dir` (default: checkout directory): directory where `mise install` and `mise env` run.
52+
- `cache-dir` (default: unset): directory to use for `MISE_DATA_DIR`. This is mainly useful on self-hosted agents with a persistent disk.
3853

3954
## Repo Requirements
4055

@@ -44,7 +59,7 @@ The target directory must contain one of:
4459
- `.mise.toml`
4560
- `.tool-versions`
4661

47-
Advanced `mise` behavior should be configured with normal step environment variables such as `MISE_DATA_DIR`, `MISE_LOG_LEVEL`, or `MISE_EXPERIMENTAL`, not plugin-specific config keys.
62+
`MISE_DATA_DIR` still takes precedence over plugin configuration. Advanced `mise` behavior should otherwise be configured with normal step environment variables such as `MISE_LOG_LEVEL` or `MISE_EXPERIMENTAL`.
4863

4964
## Development
5065

hooks/pre-command

Lines changed: 82 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,44 @@ cleanup_install_mise() {
4747
rm -rf "$2"
4848
}
4949

50+
hosted_cache_volume_root() {
51+
printf '%s' "${MISE_HOSTED_CACHE_VOLUME_ROOT:-/cache/bkcache}"
52+
}
53+
54+
resolve_mise_dir() {
55+
local cache_dir_cfg
56+
local hosted_cache_root
57+
58+
if [ -n "${MISE_DATA_DIR:-}" ]; then
59+
MISE_DIR_SOURCE="MISE_DATA_DIR environment variable"
60+
MISE_DIR="$MISE_DATA_DIR"
61+
return
62+
fi
63+
64+
cache_dir_cfg="$(plugin_cfg cache-dir)"
65+
if [ -n "$cache_dir_cfg" ]; then
66+
MISE_DIR_SOURCE="plugin cache-dir configuration"
67+
MISE_DIR="$cache_dir_cfg"
68+
return
69+
fi
70+
71+
hosted_cache_root="$(hosted_cache_volume_root)"
72+
if [ "${BUILDKITE_COMPUTE_TYPE:-self-hosted}" = "hosted" ] && [ -d "$hosted_cache_root" ] && [ -w "$hosted_cache_root" ]; then
73+
MISE_DIR_SOURCE="Buildkite hosted agent cache volume"
74+
MISE_DIR="${hosted_cache_root}/mise"
75+
return
76+
fi
77+
78+
if [ -n "${XDG_DATA_HOME:-}" ]; then
79+
MISE_DIR_SOURCE="XDG_DATA_HOME fallback"
80+
MISE_DIR="${XDG_DATA_HOME}/mise"
81+
return
82+
fi
83+
84+
MISE_DIR_SOURCE="HOME fallback"
85+
MISE_DIR="${HOME}/.local/share/mise"
86+
}
87+
5088
detect_platform() {
5189
local os
5290
local arch
@@ -173,55 +211,58 @@ ensure_mise_config_present() {
173211
exit 1
174212
}
175213

176-
required_version_raw="$(plugin_cfg_default version latest)"
177-
dir_cfg="$(plugin_cfg dir)"
214+
main() {
215+
local current_version
216+
local dir_cfg
217+
local required_version_raw
178218

179-
if [ -n "$dir_cfg" ]; then
180-
WORKING_DIRECTORY="$dir_cfg"
181-
else
182-
WORKING_DIRECTORY="${BUILDKITE_BUILD_CHECKOUT_PATH:-${PWD}}"
183-
fi
219+
required_version_raw="$(plugin_cfg_default version latest)"
220+
dir_cfg="$(plugin_cfg dir)"
184221

185-
if [ -n "${MISE_DATA_DIR:-}" ]; then
186-
MISE_DIR="$MISE_DATA_DIR"
187-
elif [ -n "${XDG_DATA_HOME:-}" ]; then
188-
MISE_DIR="${XDG_DATA_HOME}/mise"
189-
else
190-
MISE_DIR="${HOME}/.local/share/mise"
191-
fi
222+
if [ -n "$dir_cfg" ]; then
223+
WORKING_DIRECTORY="$dir_cfg"
224+
else
225+
WORKING_DIRECTORY="${BUILDKITE_BUILD_CHECKOUT_PATH:-${PWD}}"
226+
fi
192227

193-
MISE_BIN="${MISE_DIR}/bin"
194-
MISE_BINARY="${MISE_BIN}/mise"
228+
resolve_mise_dir
229+
MISE_BIN="${MISE_DIR}/bin"
230+
MISE_BINARY="${MISE_BIN}/mise"
195231

196-
if [ "$required_version_raw" = latest ]; then
197-
VERSION="$(latest_version)"
198-
else
199-
VERSION="${required_version_raw#v}"
200-
fi
201-
VERSION="${VERSION#v}"
232+
echo "Using mise data dir: ${MISE_DIR} (${MISE_DIR_SOURCE})"
202233

203-
PLATFORM="$(detect_platform)"
204-
require_cmd curl
205-
require_cmd tar
234+
if [ "$required_version_raw" = latest ]; then
235+
VERSION="$(latest_version)"
236+
else
237+
VERSION="${required_version_raw#v}"
238+
fi
239+
VERSION="${VERSION#v}"
206240

207-
current_version="$(installed_version)"
208-
if [ -z "$current_version" ] || [ "$current_version" != "$VERSION" ]; then
209-
install_mise "$VERSION" "$PLATFORM"
210-
fi
241+
PLATFORM="$(detect_platform)"
242+
require_cmd curl
243+
require_cmd tar
211244

212-
ensure_mise_config_present
245+
current_version="$(installed_version)"
246+
if [ -z "$current_version" ] || [ "$current_version" != "$VERSION" ]; then
247+
install_mise "$VERSION" "$PLATFORM"
248+
fi
213249

214-
run_mise --version
215-
run_mise install
250+
ensure_mise_config_present
216251

217-
if [ -z "${BUILDKITE_ENV_FILE:-}" ]; then
218-
echo "BUILDKITE_ENV_FILE is not set" >&2
219-
exit 1
220-
fi
252+
run_mise --version
253+
run_mise install
221254

222-
append_export MISE_DATA_DIR "$MISE_DIR"
223-
append_export MISE_TRUSTED_CONFIG_PATHS "$WORKING_DIRECTORY"
224-
append_export MISE_YES "1"
225-
run_mise env --shell bash >> "$BUILDKITE_ENV_FILE"
255+
if [ -z "${BUILDKITE_ENV_FILE:-}" ]; then
256+
echo "BUILDKITE_ENV_FILE is not set" >&2
257+
exit 1
258+
fi
259+
260+
append_export MISE_DATA_DIR "$MISE_DIR"
261+
append_export MISE_TRUSTED_CONFIG_PATHS "$WORKING_DIRECTORY"
262+
append_export MISE_YES "1"
263+
run_mise env --shell bash >> "$BUILDKITE_ENV_FILE"
264+
265+
echo "~~~ :white_check_mark: mise setup complete"
266+
}
226267

227-
echo "~~~ :white_check_mark: mise setup complete"
268+
main "$@"

plugin.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ configuration:
1414
dir:
1515
type: string
1616
description: Directory where `mise install` and `mise env` run. Defaults to the checkout directory.
17+
cache-dir:
18+
type: string
19+
description: Directory to use for `MISE_DATA_DIR`. Useful for persistent caches on self-hosted agents.

tests/pre-command.bats

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,24 @@ setup() {
99
export MISE_DATA_DIR="${TEST_TMPDIR}/mise-data"
1010
export BUILDKITE_PLUGIN_MISE_VERSION="1.0.0"
1111

12-
mkdir -p "${BUILDKITE_BUILD_CHECKOUT_PATH}" "${MISE_DATA_DIR}/bin" "${MISE_DATA_DIR}/shims"
12+
mkdir -p "${BUILDKITE_BUILD_CHECKOUT_PATH}"
13+
write_mise_mock "${MISE_DATA_DIR}"
1314

14-
cat > "${MISE_DATA_DIR}/bin/mise" <<'MOCK'
15+
export MISE_MOCK_LOG="${TEST_TMPDIR}/mise.log"
16+
: > "${MISE_MOCK_LOG}"
17+
18+
unset BUILDKITE_PLUGIN_MISE_CACHE_DIR
19+
unset BUILDKITE_PLUGIN_MISE_DIR
20+
unset BUILDKITE_COMPUTE_TYPE
21+
unset MISE_HOSTED_CACHE_VOLUME_ROOT
22+
}
23+
24+
write_mise_mock() {
25+
local data_dir="$1"
26+
27+
mkdir -p "${data_dir}/bin" "${data_dir}/shims"
28+
29+
cat > "${data_dir}/bin/mise" <<'MOCK'
1530
#!/usr/bin/env bash
1631
set -euo pipefail
1732
@@ -40,12 +55,7 @@ case "${cmd}" in
4055
;;
4156
esac
4257
MOCK
43-
chmod +x "${MISE_DATA_DIR}/bin/mise"
44-
45-
export MISE_MOCK_LOG="${TEST_TMPDIR}/mise.log"
46-
: > "${MISE_MOCK_LOG}"
47-
48-
unset BUILDKITE_PLUGIN_MISE_DIR
58+
chmod +x "${data_dir}/bin/mise"
4959
}
5060

5161
teardown() {
@@ -134,6 +144,35 @@ MOCK
134144
grep -F "env pwd=${subdir} env --shell bash" "${MISE_MOCK_LOG}"
135145
}
136146

147+
@test "uses cache-dir config when MISE_DATA_DIR is unset" {
148+
cache_dir="${TEST_TMPDIR}/self-hosted-cache"
149+
unset MISE_DATA_DIR
150+
export BUILDKITE_PLUGIN_MISE_CACHE_DIR="${cache_dir}"
151+
write_mise_mock "${cache_dir}"
152+
printf 'go 1.0.0\n' > "${BUILDKITE_BUILD_CHECKOUT_PATH}/.tool-versions"
153+
154+
run bash hooks/pre-command
155+
156+
[ "${status}" -eq 0 ]
157+
grep -F "Using mise data dir: ${cache_dir} (plugin cache-dir configuration)" <<< "${output}"
158+
grep -F "export MISE_DATA_DIR=${cache_dir}" "${BUILDKITE_ENV_FILE}"
159+
}
160+
161+
@test "uses hosted cache volume automatically when available" {
162+
hosted_cache_root="${TEST_TMPDIR}/hosted-cache"
163+
unset MISE_DATA_DIR
164+
export BUILDKITE_COMPUTE_TYPE="hosted"
165+
export MISE_HOSTED_CACHE_VOLUME_ROOT="${hosted_cache_root}"
166+
write_mise_mock "${hosted_cache_root}/mise"
167+
printf 'go 1.0.0\n' > "${BUILDKITE_BUILD_CHECKOUT_PATH}/.tool-versions"
168+
169+
run bash hooks/pre-command
170+
171+
[ "${status}" -eq 0 ]
172+
grep -F "Using mise data dir: ${hosted_cache_root}/mise (Buildkite hosted agent cache volume)" <<< "${output}"
173+
grep -F "export MISE_DATA_DIR=${hosted_cache_root}/mise" "${BUILDKITE_ENV_FILE}"
174+
}
175+
137176
@test "fails when no mise config exists" {
138177
run bash hooks/pre-command
139178

0 commit comments

Comments
 (0)