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
2 changes: 1 addition & 1 deletion .github/workflows/seed-derived-data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ jobs:
if [ "$MANIFEST_CACHE_HIT" = true ]; then
scripts/ci/swiftpm-manifest-cache.sh install "$RUNNER_TEMP/swiftpm-manifests"
else
rm -rf "$HOME/Library/Caches/org.swift.swiftpm/manifests"
scripts/ci/swiftpm-manifest-cache.sh clear
fi
env:
MANIFEST_CACHE_HIT: ${{ steps.swiftpm-manifest-restore.outputs.cache-hit }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/seed-swiftpm-manifests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
if: steps.swiftpm-manifest-restore.outputs.cache-hit != 'true'
run: |
set -euo pipefail
rm -rf "$HOME/Library/Caches/org.swift.swiftpm/manifests"
scripts/ci/swiftpm-manifest-cache.sh clear
root="${CMUX_CI_CANONICAL_ROOT:-/private/tmp/cmux-ci}"
scripts/ci/compile-app-host-test-product.sh canonical-resolve \
"$root/derived-data-compile-admission" "$PWD/.ci-source-packages"
Expand Down
28 changes: 21 additions & 7 deletions scripts/ci/swiftpm-manifest-cache.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# swiftpm-manifest-cache.sh run <command> [args...]
# swiftpm-manifest-cache.sh stage <dir>
# swiftpm-manifest-cache.sh install <dir>
# swiftpm-manifest-cache.sh clear
#
# Keeps SwiftPM's compiled-manifest cache across CI jobs. Resolving the app
# project evaluates 91 Package.swift files, and with no cache that is most of
Expand All @@ -25,10 +26,14 @@
set -euo pipefail

SCRIPT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
MANIFEST_CACHE_DIR="$HOME/Library/Caches/org.swift.swiftpm/manifests"
# The account's home from the user database, not $HOME: `run` drops HOME, so
# that is where SwiftPM looks, even on a runner that points HOME elsewhere.
# CMUX_CI_SWIFTPM_MANIFEST_CACHE_DIR overrides it for tests.
USER_HOME="$(eval echo "~$(id -un)")"
MANIFEST_CACHE_DIR="${CMUX_CI_SWIFTPM_MANIFEST_CACHE_DIR:-$USER_HOME/Library/Caches/org.swift.swiftpm/manifests}"

usage() {
echo "usage: $0 key | run <command> [args...] | stage <dir> | install <dir>" >&2
echo "usage: $0 key | run <command> [args...] | stage <dir> | install <dir> | clear" >&2
exit 64
}

Expand Down Expand Up @@ -56,21 +61,24 @@ key() {
# Runs a command under an environment that is the same in every job on a given
# runner image and Xcode. PATH is fixed because steps before a resolve append
# to it differently per workflow (Rust, Bun, Zig); the command itself is still
# found on the caller's PATH. TMPDIR is dropped so Foundation picks the
# per-user default. CMUX_CI_SWIFTPM_KEEP_ENV names extra variables to keep,
# for tests whose xcodebuild stub is configured through the environment.
# found on the caller's PATH. HOME, USER and LOGNAME are dropped too: they
# name the runner account (runner on Blacksmith, cmux on the glaeda minis), so
# keeping them split one seed into one per account, and SwiftPM finds the same
# ~/Library/Caches through the user database without them. TMPDIR is dropped
# so Foundation picks the per-user default. CMUX_CI_SWIFTPM_KEEP_ENV names
# extra variables to keep, for tests whose xcodebuild stub is configured
# through the environment.
run() {
local command_path
command_path="$(command -v "$1")" || { echo "$1: command not found" >&2; return 127; }
shift
local -a vars=(
"HOME=$HOME"
"PATH=/usr/bin:/bin:/usr/sbin:/sbin"
"LANG=en_US.UTF-8"
)
local name
# shellcheck disable=SC2086 # a space-separated list of names
for name in USER LOGNAME DEVELOPER_DIR http_proxy https_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY ${CMUX_CI_SWIFTPM_KEEP_ENV:-}; do
for name in DEVELOPER_DIR http_proxy https_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY ${CMUX_CI_SWIFTPM_KEEP_ENV:-}; do
[[ "$name" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || continue
if [ -n "${!name:-}" ]; then
vars+=("$name=${!name}")
Expand Down Expand Up @@ -116,7 +124,13 @@ install() {
echo "Installed $entries SwiftPM manifest cache entries"
}

# Empties SwiftPM's manifest cache, so a seed holds only what its resolves use.
clear() {
rm -rf "$MANIFEST_CACHE_DIR"
}

case "${1:-}" in
clear) [ "$#" -eq 1 ] || usage; clear ;;
key) [ "$#" -eq 1 ] || usage; key ;;
run) [ "$#" -ge 2 ] || usage; shift; run "$@" ;;
stage) [ "$#" -eq 2 ] || usage; stage "$2" ;;
Expand Down
11 changes: 6 additions & 5 deletions tests/test_ci_swiftpm_manifest_cache.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ STUB
chmod +x "$TMP_DIR/bin/xcodebuild" "$TMP_DIR/bin/print-env"

run_env() {
env HOME="$TMP_DIR/home" PATH="$TMP_DIR/bin:$PATH" DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer \
env HOME="$TMP_DIR/home-$2" USER="$2" LOGNAME="$2" PATH="$TMP_DIR/bin:$PATH" DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer \
GITHUB_RUN_ID="$1" GITHUB_OUTPUT="/tmp/step-$1" CMUX_CI_SWIFTPM_KEEP_ENV="NOT=A-NAME" "$SCRIPT" run print-env
}
first="$(run_env 1)"
second="$(run_env 2)"
if [ "$first" != "$second" ] || grep -q '^GITHUB_' <<<"$first"; then
echo "FAIL: run must drop per-run variables so the manifest cache key is stable"
first="$(run_env 1 runner)"
second="$(run_env 2 cmux)"
if [ "$first" != "$second" ] || grep -qE '^(GITHUB_|HOME=|USER=|LOGNAME=)' <<<"$first"; then
echo "FAIL: run must drop per-run and per-account variables so the manifest cache key is stable"
exit 1
fi
if ! grep -Fxq 'PATH=/usr/bin:/bin:/usr/sbin:/sbin' <<<"$first" \
Expand Down Expand Up @@ -65,6 +65,7 @@ echo "PASS: the key follows the manifests and the prefix follows the toolchain"

if command -v sqlite3 >/dev/null; then
cache="$TMP_DIR/home/Library/Caches/org.swift.swiftpm/manifests"
export CMUX_CI_SWIFTPM_MANIFEST_CACHE_DIR="$cache"
mkdir -p "$cache"
sqlite3 "$cache/manifest.db" 'PRAGMA journal_mode=WAL; CREATE TABLE MANIFEST_CACHE (key TEXT PRIMARY KEY, value BLOB); INSERT INTO MANIFEST_CACHE VALUES ("a", "x");' >/dev/null
HOME="$TMP_DIR/home" "$SCRIPT" stage "$TMP_DIR/staged" >/dev/null
Expand Down
Loading