Skip to content

Commit d7b1717

Browse files
author
multi-cli
committed
fix: repair cross-platform CI gates
Normalize explicit Windows platform overrides, scope macOS credential tests to the ephemeral keychain, write redirected PowerShell test input as BOM-free UTF-8, and install a checksum-pinned kcov build on Ubuntu 24.04.
1 parent db8b163 commit d7b1717

7 files changed

Lines changed: 74 additions & 14 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ jobs:
181181
exec bash tests/run-bats.sh
182182
'
183183
else
184-
bash tests/run-bats.sh
184+
env MULTICLI_MACOS_KEYCHAIN="$MULTICLI_CI_KEYCHAIN" bash tests/run-bats.sh
185185
fi
186186
187187
- name: Run the real POSIX OS-user lifecycle
@@ -205,8 +205,15 @@ jobs:
205205
- uses: actions/checkout@v4
206206
- name: Install coverage dependencies
207207
run: |
208+
KCOV_VERSION=v40
209+
KCOV_SHA256=5914803b8b84150b8c4a92f89d49edd870bf451d3d610040152d3cb31104b000
210+
KCOV_ARCHIVE="$RUNNER_TEMP/kcov-amd64.tar.gz"
208211
sudo apt-get update -y
209-
sudo apt-get install -y kcov bats jq libsecret-tools gnome-keyring dbus-x11 acl
212+
sudo apt-get install -y bats jq libsecret-tools gnome-keyring dbus-x11 acl
213+
curl -fsSL "https://github.com/SimonKagstrom/kcov/releases/download/$KCOV_VERSION/kcov-amd64.tar.gz" -o "$KCOV_ARCHIVE"
214+
printf '%s %s\n' "$KCOV_SHA256" "$KCOV_ARCHIVE" | sha256sum --check --strict
215+
sudo tar -xzf "$KCOV_ARCHIVE" -C /
216+
kcov --version
210217
- name: Enforce Bash coverage
211218
env:
212219
COVERAGE_BASELINE: ${{ github.event.pull_request.base.sha || github.event.before || 'HEAD^' }}

‎docs/testing.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,6 @@ bash tests/coverage/run-bash-coverage.sh
6262
powershell -NoProfile -ExecutionPolicy Bypass -File tests/coverage/Run-PowerShellCoverage.ps1
6363
```
6464

65+
The Bash gate requires `kcov` and Python 3. CI installs the pinned kcov v40 release archive after verifying SHA-256 because Ubuntu 24.04 does not publish a `kcov` package. The PowerShell gate requires Pester 3.4.
66+
6567
Both gates read `COVERAGE_BASELINE` when CI supplies it and otherwise compare with `HEAD^`. They write machine-readable changed-line reports under `tests/coverage/out/` and fail when a changed production file has no coverage data.

‎lib/credential-store.sh‎

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,11 @@ mc_cred_mac_require_security() {
160160
}
161161

162162
mc_cred_mac_present() {
163-
local target="$1" rc=0 errors
163+
local target="$1" rc=0 errors keychain_args=()
164164
mc_cred_mac_require_security
165+
[ -n "${MULTICLI_MACOS_KEYCHAIN:-}" ] && keychain_args=("$MULTICLI_MACOS_KEYCHAIN")
165166
# stderr is captured for the not-found check; stdout holds no diagnostics.
166-
errors="$(security find-generic-password -s "$target" -a multicli 2>&1 >/dev/null)" || rc=$?
167+
errors="$(security find-generic-password -s "$target" -a multicli "${keychain_args[@]+"${keychain_args[@]}"}" 2>&1 >/dev/null)" || rc=$?
167168
case "$rc" in
168169
0) return 0 ;;
169170
*)
@@ -175,29 +176,35 @@ mc_cred_mac_present() {
175176
}
176177

177178
mc_cred_mac_set() {
178-
local target="$1" secret="$2"
179+
local target="$1" secret="$2" keychain_args=()
179180
mc_cred_mac_require_security
181+
[ -n "${MULTICLI_MACOS_KEYCHAIN:-}" ] && keychain_args=("$MULTICLI_MACOS_KEYCHAIN")
180182
# `security` has no stdin secret channel; -U updates an existing item.
181-
security add-generic-password -s "$target" -a multicli -w "$secret" -U >/dev/null
183+
security add-generic-password -s "$target" -a multicli -w "$secret" -U \
184+
"${keychain_args[@]+"${keychain_args[@]}"}" >/dev/null
182185
}
183186

184187
mc_cred_mac_get() {
185-
local target="$1" rc=0
188+
local target="$1" rc=0 keychain_args=()
186189
mc_cred_mac_require_security
190+
[ -n "${MULTICLI_MACOS_KEYCHAIN:-}" ] && keychain_args=("$MULTICLI_MACOS_KEYCHAIN")
187191
mc_cred_mac_present "$target" || rc=$?
188192
case "$rc" in
189-
0) security find-generic-password -s "$target" -a multicli -w ;;
193+
0) security find-generic-password -s "$target" -a multicli -w \
194+
"${keychain_args[@]+"${keychain_args[@]}"}" ;;
190195
1) return 1 ;;
191196
*) return "$rc" ;;
192197
esac
193198
}
194199

195200
mc_cred_mac_clear() {
196-
local target="$1" rc=0
201+
local target="$1" rc=0 keychain_args=()
197202
mc_cred_mac_require_security
203+
[ -n "${MULTICLI_MACOS_KEYCHAIN:-}" ] && keychain_args=("$MULTICLI_MACOS_KEYCHAIN")
198204
mc_cred_mac_present "$target" || rc=$?
199205
case "$rc" in
200-
0) security delete-generic-password -s "$target" -a multicli >/dev/null ;;
206+
0) security delete-generic-password -s "$target" -a multicli \
207+
"${keychain_args[@]+"${keychain_args[@]}"}" >/dev/null ;;
201208
1) return 0 ;;
202209
*) return "$rc" ;;
203210
esac

‎multi-cli‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ platform() {
4646
case "$raw" in
4747
darwin|macos|mac|osx) printf 'macos\n' ;;
4848
linux) printf 'linux\n' ;;
49-
mingw*|msys*|cygwin*) printf 'windows\n' ;;
49+
mingw*|msys*|cygwin*|windows*) printf 'windows\n' ;;
5050
*) abort "unsupported platform '$raw'" ;;
5151
esac
5252
}

‎tests/ProfileSafety.Tests.ps1‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ function Invoke-ProfileLauncher {
2525
MULTICLI_OVERRIDE_BINARY = (Get-Command powershell.exe).Source
2626
}.GetEnumerator()) { $startInfo.EnvironmentVariables[$entry.Key] = $entry.Value }
2727
$process = [System.Diagnostics.Process]::Start($startInfo)
28-
if ($null -ne $StdinText) { $process.StandardInput.WriteLine($StdinText) }
28+
if ($null -ne $StdinText) {
29+
$inputBytes = [Text.Encoding]::UTF8.GetBytes($StdinText + "`n")
30+
$process.StandardInput.BaseStream.Write($inputBytes, 0, $inputBytes.Length)
31+
}
2932
$process.StandardInput.Close()
3033
$stdoutTask = $process.StandardOutput.ReadToEndAsync()
3134
$stderrTask = $process.StandardError.ReadToEndAsync()

‎tests/adapter_schema.bats‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,12 @@ JSON
241241
[[ "$output" == *"share.linkable path 'auth.json' overlaps share.neverLink path 'auth.json'"* ]]
242242
}
243243

244-
@test "macOS platform normalization matches schema binary keys" {
244+
@test "platform normalization matches schema binary keys" {
245245
run bash -c "set -- help; source '$MULTICLI_BIN' >/dev/null 2>&1; MULTICLI_PLATFORM=darwin platform"
246-
247246
[ "$status" -eq 0 ]
248247
[ "$output" = "macos" ]
248+
249+
run bash -c "set -- help; source '$MULTICLI_BIN' >/dev/null 2>&1; MULTICLI_PLATFORM=windows platform"
250+
[ "$status" -eq 0 ]
251+
[ "$output" = "windows" ]
249252
}

‎tests/credential_store.bats‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,51 @@ write_security_stub_absent() {
209209
mkdir -p "$bin_dir"
210210
cat > "$bin_dir/security" <<'STUB'
211211
#!/usr/bin/env bash
212+
if [ -n "${SECURITY_ARGUMENT_CAPTURE:-}" ]; then
213+
printf '%s\n' "$@" > "$SECURITY_ARGUMENT_CAPTURE"
214+
fi
212215
echo "security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain." >&2
213216
exit 44
214217
STUB
215218
chmod +x "$bin_dir/security"
216219
printf '%s\n' "$bin_dir"
217220
}
218221

222+
@test "macos backend restricts every operation to the configured keychain" {
223+
local bin_dir capture keychain
224+
bin_dir="$(write_security_stub_absent)"
225+
capture="$MULTICLI_SCRATCH/security-arguments"
226+
keychain="$MULTICLI_SCRATCH/multicli-ci.keychain-db"
227+
228+
run env PATH="$bin_dir:$PATH" MULTICLI_PLATFORM=macos MULTICLI_MACOS_KEYCHAIN="$keychain" SECURITY_ARGUMENT_CAPTURE="$capture" bash -c '
229+
source "$CRED_STORE_LIB"
230+
"$1" "multi-cli/tests/absent/MCLI_BATS_TOKEN" "test-secret"
231+
' _ mc_cred_mac_present
232+
[ "$status" -eq 1 ]
233+
[ "$(tail -n 1 "$capture")" = "$keychain" ]
234+
235+
run env PATH="$bin_dir:$PATH" MULTICLI_PLATFORM=macos MULTICLI_MACOS_KEYCHAIN="$keychain" SECURITY_ARGUMENT_CAPTURE="$capture" bash -c '
236+
source "$CRED_STORE_LIB"
237+
"$1" "multi-cli/tests/absent/MCLI_BATS_TOKEN" "test-secret"
238+
' _ mc_cred_mac_set
239+
[ "$status" -eq 44 ]
240+
[ "$(tail -n 1 "$capture")" = "$keychain" ]
241+
242+
run env PATH="$bin_dir:$PATH" MULTICLI_PLATFORM=macos MULTICLI_MACOS_KEYCHAIN="$keychain" SECURITY_ARGUMENT_CAPTURE="$capture" bash -c '
243+
source "$CRED_STORE_LIB"
244+
"$1" "multi-cli/tests/absent/MCLI_BATS_TOKEN" "test-secret"
245+
' _ mc_cred_mac_get
246+
[ "$status" -eq 1 ]
247+
[ "$(tail -n 1 "$capture")" = "$keychain" ]
248+
249+
run env PATH="$bin_dir:$PATH" MULTICLI_PLATFORM=macos MULTICLI_MACOS_KEYCHAIN="$keychain" SECURITY_ARGUMENT_CAPTURE="$capture" bash -c '
250+
source "$CRED_STORE_LIB"
251+
"$1" "multi-cli/tests/absent/MCLI_BATS_TOKEN" "test-secret"
252+
' _ mc_cred_mac_clear
253+
[ "$status" -eq 0 ]
254+
[ "$(tail -n 1 "$capture")" = "$keychain" ]
255+
}
256+
219257
@test "macos backend treats an absent item as not-present (not an error)" {
220258
local bin_dir
221259
bin_dir="$(write_security_stub_absent)"

0 commit comments

Comments
 (0)