Wave 7: Phase 2 features - sync --all, external refs, cross-alias discovery, CI/CD, reliability tests (bd-1ky, bd-1bp, bd-1rk, bd-1lj, bd-gvr, bd-1x5)

- Sync --all with async concurrency, per-host throttling, failure budgets, resumable execution
- External ref bundling at fetch time with origin tracking
- Cross-alias discovery (--all-aliases) for list and search commands
- CI/CD pipeline (.gitlab-ci.yml), cargo-deny config, Dockerfile, install script
- Reliability test suite: crash consistency (8 tests), lock contention (3 tests), property-based (4 tests)
- Criterion performance benchmarks (5 benchmarks)
- Bug fix: doctor --fix now repairs missing index.json when raw.json exists
- Bug fix: shared $ref references no longer incorrectly flagged as circular (refs.rs)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
teernisse
2026-02-12 15:29:31 -05:00
parent 398311ca4c
commit 4ac8659ebd
20 changed files with 3430 additions and 68 deletions

186
install.sh Executable file
View File

@@ -0,0 +1,186 @@
#!/usr/bin/env bash
set -euo pipefail
# swagger-cli installer
# Downloads the correct binary for your platform, verifies its checksum,
# and installs it to /usr/local/bin or ~/.local/bin.
REPO_URL="${SWAGGER_CLI_REPO_URL:-https://gitlab.com/api/v4/projects/YOUR_PROJECT_ID/packages/generic/swagger-cli}"
VERSION="${SWAGGER_CLI_VERSION:-latest}"
# --- Helpers ---------------------------------------------------------------
die() {
printf 'Error: %s\n' "$1" >&2
exit 1
}
info() {
printf ' %s\n' "$1"
}
# --- Secure temp directory with cleanup trap --------------------------------
TMPDIR_INSTALL="$(mktemp -d)"
trap 'rm -rf "${TMPDIR_INSTALL}"' EXIT INT TERM
# --- OS / arch detection ----------------------------------------------------
detect_os() {
local os
os="$(uname -s)"
case "${os}" in
Darwin) echo "apple-darwin" ;;
Linux) echo "unknown-linux-gnu" ;;
*) die "Unsupported operating system: ${os}. Only macOS and Linux are supported." ;;
esac
}
detect_arch() {
local arch
arch="$(uname -m)"
case "${arch}" in
x86_64|amd64) echo "x86_64" ;;
arm64|aarch64) echo "aarch64" ;;
*) die "Unsupported architecture: ${arch}. Only x86_64 and aarch64 are supported." ;;
esac
}
# --- Checksum verification -------------------------------------------------
verify_checksum() {
local file="$1"
local checksums_file="$2"
local basename
basename="$(basename "${file}")"
local expected
expected="$(grep "${basename}" "${checksums_file}" | awk '{print $1}')"
if [ -z "${expected}" ]; then
die "No checksum found for ${basename} in SHA256SUMS"
fi
local actual
if command -v sha256sum >/dev/null 2>&1; then
actual="$(sha256sum "${file}" | awk '{print $1}')"
elif command -v shasum >/dev/null 2>&1; then
actual="$(shasum -a 256 "${file}" | awk '{print $1}')"
else
die "Neither sha256sum nor shasum found. Cannot verify checksum."
fi
if [ "${actual}" != "${expected}" ]; then
die "Checksum mismatch for ${basename}: expected ${expected}, got ${actual}"
fi
info "Checksum verified: ${basename}"
}
# --- Optional minisign verification -----------------------------------------
verify_signature() {
local checksums_file="$1"
local sig_file="${checksums_file}.minisig"
if [ ! -f "${sig_file}" ]; then
info "No signature file found; skipping signature verification."
return 0
fi
if ! command -v minisign >/dev/null 2>&1; then
info "minisign not found; skipping signature verification."
info "Install minisign to enable: https://jedisct1.github.io/minisign/"
return 0
fi
if [ -z "${SWAGGER_CLI_MINISIGN_PUBKEY:-}" ]; then
info "SWAGGER_CLI_MINISIGN_PUBKEY not set; skipping signature verification."
return 0
fi
minisign -V -P "${SWAGGER_CLI_MINISIGN_PUBKEY}" -m "${checksums_file}" \
|| die "Signature verification failed for SHA256SUMS"
info "Signature verified: SHA256SUMS"
}
# --- Install location -------------------------------------------------------
select_install_dir() {
if [ -w /usr/local/bin ]; then
echo "/usr/local/bin"
else
local user_bin="${HOME}/.local/bin"
mkdir -p "${user_bin}"
echo "${user_bin}"
fi
}
check_path() {
local dir="$1"
case ":${PATH}:" in
*":${dir}:"*) ;;
*)
printf '\nWarning: %s is not in your PATH.\n' "${dir}"
printf 'Add it with: export PATH="%s:${PATH}"\n' "${dir}"
;;
esac
}
# --- Download ---------------------------------------------------------------
download() {
local url="$1"
local output="$2"
if command -v curl >/dev/null 2>&1; then
curl --fail --silent --location --output "${output}" "${url}"
elif command -v wget >/dev/null 2>&1; then
wget --quiet --output-document="${output}" "${url}"
else
die "Neither curl nor wget found. Cannot download."
fi
}
# --- Main -------------------------------------------------------------------
main() {
local os arch target binary_name download_base
printf 'Installing swagger-cli %s\n' "${VERSION}"
os="$(detect_os)"
arch="$(detect_arch)"
target="${arch}-${os}"
binary_name="swagger-cli-${target}"
download_base="${REPO_URL}/${VERSION}"
info "Detected platform: ${target}"
# Download binary and checksums
info "Downloading ${binary_name}..."
download "${download_base}/${binary_name}" "${TMPDIR_INSTALL}/${binary_name}"
download "${download_base}/SHA256SUMS" "${TMPDIR_INSTALL}/SHA256SUMS"
# Attempt to download signature file (optional)
download "${download_base}/SHA256SUMS.minisig" "${TMPDIR_INSTALL}/SHA256SUMS.minisig" 2>/dev/null || true
# Verify
verify_checksum "${TMPDIR_INSTALL}/${binary_name}" "${TMPDIR_INSTALL}/SHA256SUMS"
verify_signature "${TMPDIR_INSTALL}/SHA256SUMS"
# Install
local install_dir
install_dir="$(select_install_dir)"
install -m 755 "${TMPDIR_INSTALL}/${binary_name}" "${install_dir}/swagger-cli"
info "Installed to ${install_dir}/swagger-cli"
check_path "${install_dir}"
printf '\nswagger-cli %s installed successfully.\n' "${VERSION}"
printf 'Run "swagger-cli --help" to get started.\n'
}
main "$@"