chore: auto format code
This commit is contained in:
@@ -8,17 +8,17 @@ CONFIGURATION="${CONFIGURATION:-Release}"
|
||||
DERIVED_DATA_PATH="${DERIVED_DATA_PATH:-$ROOT_DIR/.build/atlas-native/DerivedData}"
|
||||
|
||||
if [[ -f "$ROOT_DIR/project.yml" ]]; then
|
||||
if command -v xcodegen >/dev/null 2>&1; then
|
||||
(cd "$ROOT_DIR" && xcodegen generate)
|
||||
elif [[ ! -d "$PROJECT_PATH" || "$ROOT_DIR/project.yml" -nt "$PROJECT_PATH/project.pbxproj" ]]; then
|
||||
echo "Atlas.xcodeproj is missing or stale, but xcodegen is not installed." >&2
|
||||
exit 1
|
||||
fi
|
||||
if command -v xcodegen > /dev/null 2>&1; then
|
||||
(cd "$ROOT_DIR" && xcodegen generate)
|
||||
elif [[ ! -d "$PROJECT_PATH" || "$ROOT_DIR/project.yml" -nt "$PROJECT_PATH/project.pbxproj" ]]; then
|
||||
echo "Atlas.xcodeproj is missing or stale, but xcodegen is not installed." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
xcodebuild \
|
||||
-project "$PROJECT_PATH" \
|
||||
-scheme "$SCHEME" \
|
||||
-configuration "$CONFIGURATION" \
|
||||
-derivedDataPath "$DERIVED_DATA_PATH" \
|
||||
build
|
||||
-project "$PROJECT_PATH" \
|
||||
-scheme "$SCHEME" \
|
||||
-configuration "$CONFIGURATION" \
|
||||
-derivedDataPath "$DERIVED_DATA_PATH" \
|
||||
build
|
||||
|
||||
@@ -11,26 +11,26 @@ VALID_DAYS="${ATLAS_LOCAL_SIGNING_VALID_DAYS:-3650}"
|
||||
P12_PASSWORD="${ATLAS_LOCAL_SIGNING_P12_PASSWORD:-atlas-local-signing-p12}"
|
||||
|
||||
if atlas_local_identity_usable; then
|
||||
atlas_unlock_local_signing_keychain
|
||||
printf 'Atlas local signing identity ready\n'
|
||||
printf 'Identity: %s\n' "$IDENTITY_NAME"
|
||||
printf 'Keychain: %s\n' "$KEYCHAIN_PATH"
|
||||
exit 0
|
||||
atlas_unlock_local_signing_keychain
|
||||
printf 'Atlas local signing identity ready\n'
|
||||
printf 'Identity: %s\n' "$IDENTITY_NAME"
|
||||
printf 'Keychain: %s\n' "$KEYCHAIN_PATH"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -f "$KEYCHAIN_PATH" ]]; then
|
||||
rm -f "$KEYCHAIN_PATH"
|
||||
rm -f "$KEYCHAIN_PATH"
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$KEYCHAIN_PATH")"
|
||||
|
||||
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/atlas-local-signing.XXXXXX")"
|
||||
cleanup() {
|
||||
rm -rf "$tmpdir"
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
cat > "$tmpdir/openssl.cnf" <<EOF
|
||||
cat > "$tmpdir/openssl.cnf" << EOF
|
||||
[ req ]
|
||||
distinguished_name = dn
|
||||
x509_extensions = ext
|
||||
@@ -46,41 +46,41 @@ authorityKeyIdentifier = keyid:always
|
||||
EOF
|
||||
|
||||
/usr/bin/openssl req \
|
||||
-new \
|
||||
-x509 \
|
||||
-nodes \
|
||||
-newkey rsa:2048 \
|
||||
-days "$VALID_DAYS" \
|
||||
-keyout "$tmpdir/identity.key" \
|
||||
-out "$tmpdir/identity.crt" \
|
||||
-config "$tmpdir/openssl.cnf" >/dev/null 2>&1
|
||||
-new \
|
||||
-x509 \
|
||||
-nodes \
|
||||
-newkey rsa:2048 \
|
||||
-days "$VALID_DAYS" \
|
||||
-keyout "$tmpdir/identity.key" \
|
||||
-out "$tmpdir/identity.crt" \
|
||||
-config "$tmpdir/openssl.cnf" > /dev/null 2>&1
|
||||
|
||||
/usr/bin/openssl pkcs12 \
|
||||
-export \
|
||||
-inkey "$tmpdir/identity.key" \
|
||||
-in "$tmpdir/identity.crt" \
|
||||
-out "$tmpdir/identity.p12" \
|
||||
-passout "pass:$P12_PASSWORD" >/dev/null 2>&1
|
||||
-export \
|
||||
-inkey "$tmpdir/identity.key" \
|
||||
-in "$tmpdir/identity.crt" \
|
||||
-out "$tmpdir/identity.p12" \
|
||||
-passout "pass:$P12_PASSWORD" > /dev/null 2>&1
|
||||
|
||||
if [[ ! -f "$KEYCHAIN_PATH" ]]; then
|
||||
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" >/dev/null
|
||||
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" > /dev/null
|
||||
fi
|
||||
|
||||
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
|
||||
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
|
||||
security import "$tmpdir/identity.p12" \
|
||||
-k "$KEYCHAIN_PATH" \
|
||||
-P "$P12_PASSWORD" \
|
||||
-f pkcs12 \
|
||||
-A \
|
||||
-T /usr/bin/codesign \
|
||||
-T /usr/bin/security >/dev/null
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" >/dev/null
|
||||
-k "$KEYCHAIN_PATH" \
|
||||
-P "$P12_PASSWORD" \
|
||||
-f pkcs12 \
|
||||
-A \
|
||||
-T /usr/bin/codesign \
|
||||
-T /usr/bin/security > /dev/null
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" > /dev/null
|
||||
atlas_unlock_local_signing_keychain
|
||||
|
||||
if ! atlas_local_identity_usable; then
|
||||
echo "Failed to provision local Atlas signing identity." >&2
|
||||
exit 1
|
||||
echo "Failed to provision local Atlas signing identity." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf 'Created Atlas local signing identity\n'
|
||||
|
||||
@@ -7,6 +7,6 @@ OUTPUT_DIR="${1:-$ROOT_DIR/Docs/Media/README}"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
ATLAS_EXPORT_README_ASSETS_DIR="$OUTPUT_DIR" \
|
||||
swift run --package-path "$ROOT_DIR/Apps" AtlasApp
|
||||
swift run --package-path "$ROOT_DIR/Apps" AtlasApp
|
||||
|
||||
echo "README assets exported to: $OUTPUT_DIR"
|
||||
|
||||
@@ -6,32 +6,32 @@ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
run_ui_acceptance() {
|
||||
local atlas_log repro_log
|
||||
atlas_log="$(mktemp -t atlas-ui-acceptance.XXXXXX.log)"
|
||||
repro_log="$(mktemp -t atlas-ui-repro.XXXXXX.log)"
|
||||
trap 'rm -f "$atlas_log" "$repro_log"' RETURN
|
||||
local atlas_log repro_log
|
||||
atlas_log="$(mktemp -t atlas-ui-acceptance.XXXXXX.log)"
|
||||
repro_log="$(mktemp -t atlas-ui-repro.XXXXXX.log)"
|
||||
trap 'rm -f "$atlas_log" "$repro_log"' RETURN
|
||||
|
||||
if ./scripts/atlas/run-ui-automation.sh 2>&1 | tee "$atlas_log"; then
|
||||
return 0
|
||||
fi
|
||||
if ./scripts/atlas/run-ui-automation.sh 2>&1 | tee "$atlas_log"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Atlas UI automation failed; checking standalone repro to classify the failure..."
|
||||
echo "Atlas UI automation failed; checking standalone repro to classify the failure..."
|
||||
|
||||
if xcodebuild test \
|
||||
-project Testing/XCUITestRepro/XCUITestRepro.xcodeproj \
|
||||
-scheme XCUITestRepro \
|
||||
-destination 'platform=macOS' 2>&1 | tee "$repro_log"; then
|
||||
echo "Standalone repro passed while Atlas UI automation failed; treating this as an Atlas-specific blocker."
|
||||
if xcodebuild test \
|
||||
-project Testing/XCUITestRepro/XCUITestRepro.xcodeproj \
|
||||
-scheme XCUITestRepro \
|
||||
-destination 'platform=macOS' 2>&1 | tee "$repro_log"; then
|
||||
echo "Standalone repro passed while Atlas UI automation failed; treating this as an Atlas-specific blocker."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if grep -q 'Timed out while enabling automation mode' "$atlas_log" && grep -q 'Timed out while enabling automation mode' "$repro_log"; then
|
||||
echo "UI automation is blocked by the current macOS automation environment; continuing acceptance with a documented environment condition."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "UI automation failed for a reason that was not classified as a shared environment blocker."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if grep -q 'Timed out while enabling automation mode' "$atlas_log" && grep -q 'Timed out while enabling automation mode' "$repro_log"; then
|
||||
echo "UI automation is blocked by the current macOS automation environment; continuing acceptance with a documented environment condition."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "UI automation failed for a reason that was not classified as a shared environment blocker."
|
||||
return 1
|
||||
}
|
||||
|
||||
echo "[1/10] Shared package tests"
|
||||
|
||||
@@ -25,40 +25,40 @@ NOTARY_PROFILE="${ATLAS_NOTARY_PROFILE:-}"
|
||||
mkdir -p "$DIST_DIR"
|
||||
|
||||
sign_app_component() {
|
||||
local path="$1"
|
||||
local args=(--force --sign "$APP_SIGN_IDENTITY")
|
||||
local entitlements_file=""
|
||||
local path="$1"
|
||||
local args=(--force --sign "$APP_SIGN_IDENTITY")
|
||||
local entitlements_file=""
|
||||
|
||||
if [[ -n "$APP_SIGNING_KEYCHAIN" ]]; then
|
||||
args+=(--keychain "$APP_SIGNING_KEYCHAIN")
|
||||
fi
|
||||
if [[ -n "$APP_SIGNING_KEYCHAIN" ]]; then
|
||||
args+=(--keychain "$APP_SIGNING_KEYCHAIN")
|
||||
fi
|
||||
|
||||
if [[ "$APP_SIGNING_MODE" == "developer-id" ]]; then
|
||||
args+=(--options runtime --timestamp)
|
||||
fi
|
||||
if [[ "$APP_SIGNING_MODE" == "developer-id" ]]; then
|
||||
args+=(--options runtime --timestamp)
|
||||
fi
|
||||
|
||||
entitlements_file="$(mktemp "${TMPDIR:-/tmp}/atlas-entitlements.XXXXXX")"
|
||||
if /usr/bin/codesign -d --entitlements :- "$path" > "$entitlements_file" 2>/dev/null && /usr/bin/grep -q '<plist' "$entitlements_file"; then
|
||||
args+=(--entitlements "$entitlements_file")
|
||||
else
|
||||
rm -f "$entitlements_file"
|
||||
entitlements_file=""
|
||||
fi
|
||||
entitlements_file="$(mktemp "${TMPDIR:-/tmp}/atlas-entitlements.XXXXXX")"
|
||||
if /usr/bin/codesign -d --entitlements :- "$path" > "$entitlements_file" 2> /dev/null && /usr/bin/grep -q '<plist' "$entitlements_file"; then
|
||||
args+=(--entitlements "$entitlements_file")
|
||||
else
|
||||
rm -f "$entitlements_file"
|
||||
entitlements_file=""
|
||||
fi
|
||||
|
||||
codesign "${args[@]}" "$path"
|
||||
codesign "${args[@]}" "$path"
|
||||
|
||||
if [[ -n "$entitlements_file" ]]; then
|
||||
rm -f "$entitlements_file"
|
||||
fi
|
||||
if [[ -n "$entitlements_file" ]]; then
|
||||
rm -f "$entitlements_file"
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ -n "$APP_SIGNING_KEYCHAIN" ]]; then
|
||||
atlas_unlock_local_signing_keychain
|
||||
atlas_unlock_local_signing_keychain
|
||||
fi
|
||||
|
||||
printf 'App signing identity: %s (%s)\n' "$APP_SIGN_IDENTITY" "$APP_SIGNING_MODE"
|
||||
if [[ -n "$APP_SIGNING_KEYCHAIN" ]]; then
|
||||
printf 'App signing keychain: %s\n' "$APP_SIGNING_KEYCHAIN"
|
||||
printf 'App signing keychain: %s\n' "$APP_SIGNING_KEYCHAIN"
|
||||
fi
|
||||
printf 'Installer signing identity: %s\n' "${INSTALLER_SIGN_IDENTITY:-UNSIGNED}"
|
||||
|
||||
@@ -66,11 +66,11 @@ swift build --package-path "$ROOT_DIR/Helpers" -c release
|
||||
"$ROOT_DIR/scripts/atlas/build-native.sh"
|
||||
|
||||
if [[ ! -d "$APP_PATH" ]]; then
|
||||
echo "Built app not found at $APP_PATH" >&2
|
||||
exit 1
|
||||
echo "Built app not found at $APP_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python3 - "$PACKAGED_APP_PATH" "$DMG_STAGING_DIR" "$DMG_PATH" <<'PY'
|
||||
python3 - "$PACKAGED_APP_PATH" "$DMG_STAGING_DIR" "$DMG_PATH" << 'PY'
|
||||
from pathlib import Path
|
||||
import shutil, sys
|
||||
for raw in sys.argv[1:]:
|
||||
@@ -88,8 +88,8 @@ cp "$HELPER_BINARY" "$PACKAGED_APP_PATH/Contents/Helpers/AtlasPrivilegedHelper"
|
||||
chmod +x "$PACKAGED_APP_PATH/Contents/Helpers/AtlasPrivilegedHelper"
|
||||
|
||||
while IFS= read -r xpc; do
|
||||
sign_app_component "$xpc"
|
||||
done < <(find "$PACKAGED_APP_PATH/Contents/XPCServices" -maxdepth 1 -name '*.xpc' -type d 2>/dev/null | sort)
|
||||
sign_app_component "$xpc"
|
||||
done < <(find "$PACKAGED_APP_PATH/Contents/XPCServices" -maxdepth 1 -name '*.xpc' -type d 2> /dev/null | sort)
|
||||
sign_app_component "$PACKAGED_APP_PATH/Contents/Helpers/AtlasPrivilegedHelper"
|
||||
sign_app_component "$PACKAGED_APP_PATH"
|
||||
codesign --verify --deep --strict --verbose=2 "$PACKAGED_APP_PATH"
|
||||
@@ -99,20 +99,20 @@ codesign --verify --deep --strict --verbose=2 "$PACKAGED_APP_PATH"
|
||||
mkdir -p "$DMG_STAGING_DIR"
|
||||
cp -R "$PACKAGED_APP_PATH" "$DMG_STAGING_DIR/$APP_NAME"
|
||||
ln -s /Applications "$DMG_STAGING_DIR/Applications"
|
||||
hdiutil create -volname "Atlas for Mac" -srcfolder "$DMG_STAGING_DIR" -ov -format UDZO "$DMG_PATH" >/dev/null
|
||||
hdiutil create -volname "Atlas for Mac" -srcfolder "$DMG_STAGING_DIR" -ov -format UDZO "$DMG_PATH" > /dev/null
|
||||
|
||||
productbuild_args=(--component "$PACKAGED_APP_PATH" /Applications "$PKG_PATH")
|
||||
if [[ -n "$INSTALLER_SIGN_IDENTITY" ]]; then
|
||||
productbuild_args=(--sign "$INSTALLER_SIGN_IDENTITY" --component "$PACKAGED_APP_PATH" /Applications "$PKG_PATH")
|
||||
productbuild_args=(--sign "$INSTALLER_SIGN_IDENTITY" --component "$PACKAGED_APP_PATH" /Applications "$PKG_PATH")
|
||||
fi
|
||||
/usr/bin/productbuild "${productbuild_args[@]}"
|
||||
|
||||
(
|
||||
cd "$DIST_DIR"
|
||||
/usr/bin/shasum -a 256 \
|
||||
"$(basename "$ZIP_PATH")" \
|
||||
"$(basename "$DMG_PATH")" \
|
||||
"$(basename "$PKG_PATH")" > "$SHA_PATH"
|
||||
cd "$DIST_DIR"
|
||||
/usr/bin/shasum -a 256 \
|
||||
"$(basename "$ZIP_PATH")" \
|
||||
"$(basename "$DMG_PATH")" \
|
||||
"$(basename "$PKG_PATH")" > "$SHA_PATH"
|
||||
)
|
||||
|
||||
echo "Packaged app: $PACKAGED_APP_PATH"
|
||||
@@ -122,18 +122,18 @@ echo "Installer package: $PKG_PATH"
|
||||
echo "Checksums: $SHA_PATH"
|
||||
|
||||
if [[ -n "$NOTARY_PROFILE" && "$APP_SIGNING_MODE" == "developer-id" && -n "$INSTALLER_SIGN_IDENTITY" ]]; then
|
||||
xcrun notarytool submit "$PKG_PATH" --keychain-profile "$NOTARY_PROFILE" --wait
|
||||
xcrun stapler staple "$PKG_PATH"
|
||||
xcrun notarytool submit "$DMG_PATH" --keychain-profile "$NOTARY_PROFILE" --wait
|
||||
xcrun notarytool submit "$ZIP_PATH" --keychain-profile "$NOTARY_PROFILE" --wait
|
||||
xcrun stapler staple "$PACKAGED_APP_PATH"
|
||||
/usr/bin/ditto -c -k --sequesterRsrc --keepParent "$PACKAGED_APP_PATH" "$ZIP_PATH"
|
||||
(
|
||||
cd "$DIST_DIR"
|
||||
/usr/bin/shasum -a 256 \
|
||||
"$(basename "$ZIP_PATH")" \
|
||||
"$(basename "$DMG_PATH")" \
|
||||
"$(basename "$PKG_PATH")" > "$SHA_PATH"
|
||||
)
|
||||
echo "Notarization complete"
|
||||
xcrun notarytool submit "$PKG_PATH" --keychain-profile "$NOTARY_PROFILE" --wait
|
||||
xcrun stapler staple "$PKG_PATH"
|
||||
xcrun notarytool submit "$DMG_PATH" --keychain-profile "$NOTARY_PROFILE" --wait
|
||||
xcrun notarytool submit "$ZIP_PATH" --keychain-profile "$NOTARY_PROFILE" --wait
|
||||
xcrun stapler staple "$PACKAGED_APP_PATH"
|
||||
/usr/bin/ditto -c -k --sequesterRsrc --keepParent "$PACKAGED_APP_PATH" "$ZIP_PATH"
|
||||
(
|
||||
cd "$DIST_DIR"
|
||||
/usr/bin/shasum -a 256 \
|
||||
"$(basename "$ZIP_PATH")" \
|
||||
"$(basename "$DMG_PATH")" \
|
||||
"$(basename "$PKG_PATH")" > "$SHA_PATH"
|
||||
)
|
||||
echo "Notarization complete"
|
||||
fi
|
||||
|
||||
@@ -5,38 +5,38 @@ ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
if ! ./scripts/atlas/ui-automation-preflight.sh >/dev/null; then
|
||||
echo "Skipping native UI automation: Accessibility / automation permissions are not ready."
|
||||
exit 0
|
||||
if ! ./scripts/atlas/ui-automation-preflight.sh > /dev/null; then
|
||||
echo "Skipping native UI automation: Accessibility / automation permissions are not ready."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
run_once() {
|
||||
pkill -f 'Atlas for Mac.app/Contents/MacOS/Atlas for Mac' >/dev/null 2>&1 || true
|
||||
pkill -f 'AtlasAppUITests-Runner|XCTRunner|xcodebuild test -project Atlas.xcodeproj -scheme AtlasApp' >/dev/null 2>&1 || true
|
||||
sleep 2
|
||||
pkill -f 'Atlas for Mac.app/Contents/MacOS/Atlas for Mac' > /dev/null 2>&1 || true
|
||||
pkill -f 'AtlasAppUITests-Runner|XCTRunner|xcodebuild test -project Atlas.xcodeproj -scheme AtlasApp' > /dev/null 2>&1 || true
|
||||
sleep 2
|
||||
|
||||
xcodegen generate >/dev/null
|
||||
xcodebuild test \
|
||||
-project Atlas.xcodeproj \
|
||||
-scheme AtlasApp \
|
||||
-destination 'platform=macOS' \
|
||||
-only-testing:AtlasAppUITests
|
||||
xcodegen generate > /dev/null
|
||||
xcodebuild test \
|
||||
-project Atlas.xcodeproj \
|
||||
-scheme AtlasApp \
|
||||
-destination 'platform=macOS' \
|
||||
-only-testing:AtlasAppUITests
|
||||
}
|
||||
|
||||
LOG_FILE="$(mktemp -t atlas-ui-automation.XXXXXX.log)"
|
||||
trap 'rm -f "$LOG_FILE"' EXIT
|
||||
|
||||
for attempt in 1 2; do
|
||||
echo "UI automation attempt $attempt/2"
|
||||
if run_once 2>&1 | tee "$LOG_FILE"; then
|
||||
exit 0
|
||||
fi
|
||||
echo "UI automation attempt $attempt/2"
|
||||
if run_once 2>&1 | tee "$LOG_FILE"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if grep -q 'Timed out while enabling automation mode' "$LOG_FILE" && [[ "$attempt" -lt 2 ]]; then
|
||||
echo "UI automation timed out while enabling automation mode; retrying after cleanup..."
|
||||
sleep 3
|
||||
continue
|
||||
fi
|
||||
if grep -q 'Timed out while enabling automation mode' "$LOG_FILE" && [[ "$attempt" -lt 2 ]]; then
|
||||
echo "UI automation timed out while enabling automation mode; retrying after cleanup..."
|
||||
sleep 3
|
||||
continue
|
||||
fi
|
||||
|
||||
exit 1
|
||||
exit 1
|
||||
done
|
||||
|
||||
@@ -1,168 +1,168 @@
|
||||
#!/bin/bash
|
||||
|
||||
atlas_local_signing_keychain_path() {
|
||||
printf '%s\n' "${ATLAS_LOCAL_SIGNING_KEYCHAIN_PATH:-$HOME/Library/Keychains/AtlasLocalSigning.keychain-db}"
|
||||
printf '%s\n' "${ATLAS_LOCAL_SIGNING_KEYCHAIN_PATH:-$HOME/Library/Keychains/AtlasLocalSigning.keychain-db}"
|
||||
}
|
||||
|
||||
atlas_local_signing_keychain_password() {
|
||||
printf '%s\n' "${ATLAS_LOCAL_SIGNING_KEYCHAIN_PASSWORD:-atlas-local-signing}"
|
||||
printf '%s\n' "${ATLAS_LOCAL_SIGNING_KEYCHAIN_PASSWORD:-atlas-local-signing}"
|
||||
}
|
||||
|
||||
atlas_local_signing_identity_name() {
|
||||
printf '%s\n' "${ATLAS_LOCAL_SIGNING_IDENTITY_NAME:-Atlas Local Development}"
|
||||
printf '%s\n' "${ATLAS_LOCAL_SIGNING_IDENTITY_NAME:-Atlas Local Development}"
|
||||
}
|
||||
|
||||
atlas_detect_release_app_identity() {
|
||||
security find-identity -v -p codesigning 2>/dev/null \
|
||||
| sed -n 's/.*"\(Developer ID Application:.*\)"/\1/p' \
|
||||
| head -1
|
||||
security find-identity -v -p codesigning 2> /dev/null |
|
||||
sed -n 's/.*"\(Developer ID Application:.*\)"/\1/p' |
|
||||
head -1
|
||||
}
|
||||
|
||||
atlas_detect_development_app_identity() {
|
||||
local output
|
||||
output="$(security find-identity -v -p codesigning 2>/dev/null || true)"
|
||||
local output
|
||||
output="$(security find-identity -v -p codesigning 2> /dev/null || true)"
|
||||
|
||||
local identity
|
||||
identity="$(printf '%s\n' "$output" | sed -n 's/.*"\(Apple Development:.*\)"/\1/p' | head -1)"
|
||||
if [[ -n "$identity" ]]; then
|
||||
printf '%s\n' "$identity"
|
||||
return 0
|
||||
fi
|
||||
local identity
|
||||
identity="$(printf '%s\n' "$output" | sed -n 's/.*"\(Apple Development:.*\)"/\1/p' | head -1)"
|
||||
if [[ -n "$identity" ]]; then
|
||||
printf '%s\n' "$identity"
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf '%s\n' "$output" | sed -n 's/.*"\(Mac Developer:.*\)"/\1/p' | head -1
|
||||
printf '%s\n' "$output" | sed -n 's/.*"\(Mac Developer:.*\)"/\1/p' | head -1
|
||||
}
|
||||
|
||||
atlas_detect_installer_identity() {
|
||||
security find-identity -v -p basic 2>/dev/null \
|
||||
| sed -n 's/.*"\(Developer ID Installer:.*\)"/\1/p' \
|
||||
| head -1
|
||||
security find-identity -v -p basic 2> /dev/null |
|
||||
sed -n 's/.*"\(Developer ID Installer:.*\)"/\1/p' |
|
||||
head -1
|
||||
}
|
||||
|
||||
atlas_local_identity_exists() {
|
||||
local keychain_path identity_name
|
||||
keychain_path="$(atlas_local_signing_keychain_path)"
|
||||
identity_name="$(atlas_local_signing_identity_name)"
|
||||
local keychain_path identity_name
|
||||
keychain_path="$(atlas_local_signing_keychain_path)"
|
||||
identity_name="$(atlas_local_signing_identity_name)"
|
||||
|
||||
[[ -f "$keychain_path" ]] || return 1
|
||||
security find-certificate -a -c "$identity_name" "$keychain_path" >/dev/null 2>&1
|
||||
[[ -f "$keychain_path" ]] || return 1
|
||||
security find-certificate -a -c "$identity_name" "$keychain_path" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
atlas_unlock_local_signing_keychain() {
|
||||
local keychain_path keychain_password
|
||||
keychain_path="$(atlas_local_signing_keychain_path)"
|
||||
keychain_password="$(atlas_local_signing_keychain_password)"
|
||||
local keychain_path keychain_password
|
||||
keychain_path="$(atlas_local_signing_keychain_path)"
|
||||
keychain_password="$(atlas_local_signing_keychain_password)"
|
||||
|
||||
[[ -f "$keychain_path" ]] || return 0
|
||||
security unlock-keychain -p "$keychain_password" "$keychain_path" >/dev/null 2>&1 || true
|
||||
security set-keychain-settings -lut 21600 "$keychain_path" >/dev/null 2>&1 || true
|
||||
atlas_add_local_signing_keychain_to_search_list
|
||||
[[ -f "$keychain_path" ]] || return 0
|
||||
security unlock-keychain -p "$keychain_password" "$keychain_path" > /dev/null 2>&1 || true
|
||||
security set-keychain-settings -lut 21600 "$keychain_path" > /dev/null 2>&1 || true
|
||||
atlas_add_local_signing_keychain_to_search_list
|
||||
}
|
||||
|
||||
atlas_add_local_signing_keychain_to_search_list() {
|
||||
local keychain_path
|
||||
keychain_path="$(atlas_local_signing_keychain_path)"
|
||||
local keychain_path
|
||||
keychain_path="$(atlas_local_signing_keychain_path)"
|
||||
|
||||
[[ -f "$keychain_path" ]] || return 0
|
||||
[[ -f "$keychain_path" ]] || return 0
|
||||
|
||||
local current_keychains=()
|
||||
while IFS= read -r line; do
|
||||
line="${line#"${line%%[![:space:]]*}"}"
|
||||
line="${line%\"}"
|
||||
line="${line#\"}"
|
||||
[[ -n "$line" ]] && current_keychains+=("$line")
|
||||
done < <(security list-keychains -d user 2>/dev/null || true)
|
||||
local current_keychains=()
|
||||
while IFS= read -r line; do
|
||||
line="${line#"${line%%[![:space:]]*}"}"
|
||||
line="${line%\"}"
|
||||
line="${line#\"}"
|
||||
[[ -n "$line" ]] && current_keychains+=("$line")
|
||||
done < <(security list-keychains -d user 2> /dev/null || true)
|
||||
|
||||
if printf '%s\n' "${current_keychains[@]}" | grep -Fx "$keychain_path" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
if printf '%s\n' "${current_keychains[@]}" | grep -Fx "$keychain_path" > /dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
security list-keychains -d user -s "$keychain_path" "${current_keychains[@]}" >/dev/null 2>&1 || true
|
||||
security list-keychains -d user -s "$keychain_path" "${current_keychains[@]}" > /dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
atlas_local_identity_usable() {
|
||||
atlas_local_identity_exists || return 1
|
||||
atlas_local_identity_exists || return 1
|
||||
|
||||
local keychain_path identity_name sample_file
|
||||
keychain_path="$(atlas_local_signing_keychain_path)"
|
||||
identity_name="$(atlas_local_signing_identity_name)"
|
||||
local keychain_path identity_name sample_file
|
||||
keychain_path="$(atlas_local_signing_keychain_path)"
|
||||
identity_name="$(atlas_local_signing_identity_name)"
|
||||
|
||||
atlas_unlock_local_signing_keychain
|
||||
atlas_unlock_local_signing_keychain
|
||||
|
||||
sample_file="$(mktemp "${TMPDIR:-/tmp}/atlas-local-signing-check.XXXXXX")"
|
||||
printf 'atlas local signing check\n' > "$sample_file"
|
||||
if ! /usr/bin/codesign --force --sign "$identity_name" --keychain "$keychain_path" "$sample_file" > /dev/null 2>&1; then
|
||||
rm -f "$sample_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
sample_file="$(mktemp "${TMPDIR:-/tmp}/atlas-local-signing-check.XXXXXX")"
|
||||
printf 'atlas local signing check\n' > "$sample_file"
|
||||
if ! /usr/bin/codesign --force --sign "$identity_name" --keychain "$keychain_path" "$sample_file" >/dev/null 2>&1; then
|
||||
rm -f "$sample_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm -f "$sample_file"
|
||||
return 0
|
||||
return 0
|
||||
}
|
||||
|
||||
atlas_signing_mode_for_identity() {
|
||||
local identity="${1:-}"
|
||||
local local_identity_name
|
||||
local_identity_name="$(atlas_local_signing_identity_name)"
|
||||
local identity="${1:-}"
|
||||
local local_identity_name
|
||||
local_identity_name="$(atlas_local_signing_identity_name)"
|
||||
|
||||
if [[ -z "$identity" || "$identity" == "-" ]]; then
|
||||
printf '%s\n' "adhoc"
|
||||
elif [[ "$identity" == Developer\ ID\ Application:* ]]; then
|
||||
printf '%s\n' "developer-id"
|
||||
elif [[ "$identity" == "$local_identity_name" ]]; then
|
||||
printf '%s\n' "local-stable"
|
||||
else
|
||||
printf '%s\n' "local-stable"
|
||||
fi
|
||||
if [[ -z "$identity" || "$identity" == "-" ]]; then
|
||||
printf '%s\n' "adhoc"
|
||||
elif [[ "$identity" == Developer\ ID\ Application:* ]]; then
|
||||
printf '%s\n' "developer-id"
|
||||
elif [[ "$identity" == "$local_identity_name" ]]; then
|
||||
printf '%s\n' "local-stable"
|
||||
else
|
||||
printf '%s\n' "local-stable"
|
||||
fi
|
||||
}
|
||||
|
||||
atlas_resolve_app_signing_identity() {
|
||||
if [[ -n "${ATLAS_CODESIGN_IDENTITY:-}" ]]; then
|
||||
printf '%s\n' "$ATLAS_CODESIGN_IDENTITY"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${ATLAS_CODESIGN_IDENTITY:-}" ]]; then
|
||||
printf '%s\n' "$ATLAS_CODESIGN_IDENTITY"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local identity
|
||||
identity="$(atlas_detect_release_app_identity)"
|
||||
if [[ -n "$identity" ]]; then
|
||||
printf '%s\n' "$identity"
|
||||
return 0
|
||||
fi
|
||||
local identity
|
||||
identity="$(atlas_detect_release_app_identity)"
|
||||
if [[ -n "$identity" ]]; then
|
||||
printf '%s\n' "$identity"
|
||||
return 0
|
||||
fi
|
||||
|
||||
identity="$(atlas_detect_development_app_identity)"
|
||||
if [[ -n "$identity" ]]; then
|
||||
printf '%s\n' "$identity"
|
||||
return 0
|
||||
fi
|
||||
identity="$(atlas_detect_development_app_identity)"
|
||||
if [[ -n "$identity" ]]; then
|
||||
printf '%s\n' "$identity"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if atlas_local_identity_usable; then
|
||||
printf '%s\n' "$(atlas_local_signing_identity_name)"
|
||||
return 0
|
||||
fi
|
||||
if atlas_local_identity_usable; then
|
||||
printf '%s\n' "$(atlas_local_signing_identity_name)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf '%s\n' "-"
|
||||
printf '%s\n' "-"
|
||||
}
|
||||
|
||||
atlas_resolve_app_signing_keychain() {
|
||||
local identity="${1:-}"
|
||||
local identity="${1:-}"
|
||||
|
||||
if [[ -n "${ATLAS_CODESIGN_KEYCHAIN:-}" ]]; then
|
||||
printf '%s\n' "$ATLAS_CODESIGN_KEYCHAIN"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${ATLAS_CODESIGN_KEYCHAIN:-}" ]]; then
|
||||
printf '%s\n' "$ATLAS_CODESIGN_KEYCHAIN"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$identity" == "$(atlas_local_signing_identity_name)" ]] && atlas_local_identity_exists; then
|
||||
printf '%s\n' "$(atlas_local_signing_keychain_path)"
|
||||
return 0
|
||||
fi
|
||||
if [[ "$identity" == "$(atlas_local_signing_identity_name)" ]] && atlas_local_identity_exists; then
|
||||
printf '%s\n' "$(atlas_local_signing_keychain_path)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf '%s\n' ""
|
||||
printf '%s\n' ""
|
||||
}
|
||||
|
||||
atlas_resolve_installer_signing_identity() {
|
||||
if [[ -n "${ATLAS_INSTALLER_SIGN_IDENTITY:-}" ]]; then
|
||||
printf '%s\n' "$ATLAS_INSTALLER_SIGN_IDENTITY"
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${ATLAS_INSTALLER_SIGN_IDENTITY:-}" ]]; then
|
||||
printf '%s\n' "$ATLAS_INSTALLER_SIGN_IDENTITY"
|
||||
return 0
|
||||
fi
|
||||
|
||||
atlas_detect_installer_identity
|
||||
atlas_detect_installer_identity
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ APP_IDENTITY_OVERRIDE="${ATLAS_CODESIGN_IDENTITY:-}"
|
||||
INSTALLER_IDENTITY_OVERRIDE="${ATLAS_INSTALLER_SIGN_IDENTITY:-}"
|
||||
NOTARY_PROFILE_OVERRIDE="${ATLAS_NOTARY_PROFILE:-}"
|
||||
|
||||
codesign_output="$(security find-identity -v -p codesigning 2>/dev/null || true)"
|
||||
basic_output="$(security find-identity -v -p basic 2>/dev/null || true)"
|
||||
codesign_output="$(security find-identity -v -p codesigning 2> /dev/null || true)"
|
||||
basic_output="$(security find-identity -v -p basic 2> /dev/null || true)"
|
||||
|
||||
app_identity_detected="$(printf '%s\n' "$codesign_output" | sed -n 's/.*"\(Developer ID Application:.*\)"/\1/p' | head -1)"
|
||||
installer_identity_detected="$(printf '%s\n' "$basic_output" | sed -n 's/.*"\(Developer ID Installer:.*\)"/\1/p' | head -1)"
|
||||
@@ -18,7 +18,7 @@ app_identity="${APP_IDENTITY_OVERRIDE:-$app_identity_detected}"
|
||||
installer_identity="${INSTALLER_IDENTITY_OVERRIDE:-$installer_identity_detected}"
|
||||
local_identity=""
|
||||
if atlas_local_identity_exists; then
|
||||
local_identity="$(atlas_local_signing_identity_name)"
|
||||
local_identity="$(atlas_local_signing_identity_name)"
|
||||
fi
|
||||
|
||||
printf 'Atlas signing preflight\n'
|
||||
@@ -27,50 +27,50 @@ printf 'Developer ID Application: %s\n' "${app_identity:-MISSING}"
|
||||
printf 'Developer ID Installer: %s\n' "${installer_identity:-MISSING}"
|
||||
printf 'Notary profile: %s\n' "${NOTARY_PROFILE_OVERRIDE:-MISSING}"
|
||||
if [[ -n "$local_identity" ]]; then
|
||||
printf 'Stable local app identity: %s\n' "$local_identity"
|
||||
printf 'Stable local app identity: %s\n' "$local_identity"
|
||||
else
|
||||
printf 'Stable local app identity: MISSING\n'
|
||||
printf 'Stable local app identity: MISSING\n'
|
||||
fi
|
||||
|
||||
status=0
|
||||
if [[ -z "$app_identity" ]]; then
|
||||
echo '✗ Missing Developer ID Application identity'
|
||||
status=1
|
||||
echo '✗ Missing Developer ID Application identity'
|
||||
status=1
|
||||
fi
|
||||
if [[ -z "$installer_identity" ]]; then
|
||||
echo '✗ Missing Developer ID Installer identity'
|
||||
status=1
|
||||
echo '✗ Missing Developer ID Installer identity'
|
||||
status=1
|
||||
fi
|
||||
if [[ -z "$NOTARY_PROFILE_OVERRIDE" ]]; then
|
||||
echo '✗ Missing notarytool keychain profile name in ATLAS_NOTARY_PROFILE'
|
||||
status=1
|
||||
echo '✗ Missing notarytool keychain profile name in ATLAS_NOTARY_PROFILE'
|
||||
status=1
|
||||
fi
|
||||
|
||||
if [[ -n "$NOTARY_PROFILE_OVERRIDE" ]]; then
|
||||
if xcrun notarytool history --keychain-profile "$NOTARY_PROFILE_OVERRIDE" >/dev/null 2>&1; then
|
||||
echo '✓ notarytool profile is usable'
|
||||
else
|
||||
echo '✗ notarytool profile could not be validated'
|
||||
status=1
|
||||
fi
|
||||
if xcrun notarytool history --keychain-profile "$NOTARY_PROFILE_OVERRIDE" > /dev/null 2>&1; then
|
||||
echo '✓ notarytool profile is usable'
|
||||
else
|
||||
echo '✗ notarytool profile could not be validated'
|
||||
status=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $status -eq 0 ]]; then
|
||||
echo '✓ Release signing prerequisites are present'
|
||||
echo "export ATLAS_CODESIGN_IDENTITY='$app_identity'"
|
||||
echo "export ATLAS_INSTALLER_SIGN_IDENTITY='$installer_identity'"
|
||||
echo "export ATLAS_NOTARY_PROFILE='$NOTARY_PROFILE_OVERRIDE'"
|
||||
echo '✓ Release signing prerequisites are present'
|
||||
echo "export ATLAS_CODESIGN_IDENTITY='$app_identity'"
|
||||
echo "export ATLAS_INSTALLER_SIGN_IDENTITY='$installer_identity'"
|
||||
echo "export ATLAS_NOTARY_PROFILE='$NOTARY_PROFILE_OVERRIDE'"
|
||||
else
|
||||
echo
|
||||
echo 'To unblock signed/notarized release packaging, provide or install:'
|
||||
echo ' 1. Developer ID Application certificate'
|
||||
echo ' 2. Developer ID Installer certificate'
|
||||
echo ' 3. notarytool keychain profile name via ATLAS_NOTARY_PROFILE'
|
||||
if [[ -z "$local_identity" ]]; then
|
||||
echo
|
||||
echo 'For stable local TCC-friendly builds without Apple release credentials, run:'
|
||||
echo ' ./scripts/atlas/ensure-local-signing-identity.sh'
|
||||
fi
|
||||
echo 'To unblock signed/notarized release packaging, provide or install:'
|
||||
echo ' 1. Developer ID Application certificate'
|
||||
echo ' 2. Developer ID Installer certificate'
|
||||
echo ' 3. notarytool keychain profile name via ATLAS_NOTARY_PROFILE'
|
||||
if [[ -z "$local_identity" ]]; then
|
||||
echo
|
||||
echo 'For stable local TCC-friendly builds without Apple release credentials, run:'
|
||||
echo ' ./scripts/atlas/ensure-local-signing-identity.sh'
|
||||
fi
|
||||
fi
|
||||
|
||||
exit $status
|
||||
|
||||
@@ -7,63 +7,63 @@ DERIVED_ROOT="$HOME/Library/Developer/Xcode/DerivedData/AtlasExecutionFixturesDe
|
||||
PYCACHE_ROOT="$HOME/Library/Caches/AtlasExecutionFixturesPycache"
|
||||
|
||||
create_blob() {
|
||||
local path="$1"
|
||||
local size_mb="$2"
|
||||
mkdir -p "$(dirname "$path")"
|
||||
if command -v mkfile >/dev/null 2>&1; then
|
||||
mkfile -n "${size_mb}m" "$path"
|
||||
else
|
||||
dd if=/dev/zero of="$path" bs=1m count="$size_mb" status=none
|
||||
fi
|
||||
local path="$1"
|
||||
local size_mb="$2"
|
||||
mkdir -p "$(dirname "$path")"
|
||||
if command -v mkfile > /dev/null 2>&1; then
|
||||
mkfile -n "${size_mb}m" "$path"
|
||||
else
|
||||
dd if=/dev/zero of="$path" bs=1m count="$size_mb" status=none
|
||||
fi
|
||||
}
|
||||
|
||||
print_status() {
|
||||
local existing=false
|
||||
for path in "$CACHE_ROOT" "$LOG_ROOT" "$DERIVED_ROOT" "$PYCACHE_ROOT"; do
|
||||
if [[ -e "$path" ]]; then
|
||||
existing=true
|
||||
du -sh "$path"
|
||||
find "$path" -maxdepth 3 -type f | sort
|
||||
local existing=false
|
||||
for path in "$CACHE_ROOT" "$LOG_ROOT" "$DERIVED_ROOT" "$PYCACHE_ROOT"; do
|
||||
if [[ -e "$path" ]]; then
|
||||
existing=true
|
||||
du -sh "$path"
|
||||
find "$path" -maxdepth 3 -type f | sort
|
||||
fi
|
||||
done
|
||||
if [[ "$existing" == false ]]; then
|
||||
echo "No Smart Clean manual fixtures found."
|
||||
fi
|
||||
done
|
||||
if [[ "$existing" == false ]]; then
|
||||
echo "No Smart Clean manual fixtures found."
|
||||
fi
|
||||
}
|
||||
|
||||
create_fixtures() {
|
||||
cleanup_fixtures >/dev/null 2>&1 || true
|
||||
cleanup_fixtures > /dev/null 2>&1 || true
|
||||
|
||||
create_blob "$CACHE_ROOT/cache-a.bin" 24
|
||||
create_blob "$CACHE_ROOT/cache-b.bin" 12
|
||||
create_blob "$LOG_ROOT/app.log" 8
|
||||
create_blob "$DERIVED_ROOT/Build/Logs/build-products.bin" 16
|
||||
mkdir -p "$PYCACHE_ROOT/project/__pycache__"
|
||||
create_blob "$PYCACHE_ROOT/project/__pycache__/sample.cpython-312.pyc" 4
|
||||
create_blob "$CACHE_ROOT/cache-a.bin" 24
|
||||
create_blob "$CACHE_ROOT/cache-b.bin" 12
|
||||
create_blob "$LOG_ROOT/app.log" 8
|
||||
create_blob "$DERIVED_ROOT/Build/Logs/build-products.bin" 16
|
||||
mkdir -p "$PYCACHE_ROOT/project/__pycache__"
|
||||
create_blob "$PYCACHE_ROOT/project/__pycache__/sample.cpython-312.pyc" 4
|
||||
|
||||
echo "Created Smart Clean manual fixtures:"
|
||||
print_status
|
||||
echo ""
|
||||
echo "Note: bin/clean.sh --dry-run may aggregate these fixtures into higher-level roots such as ~/Library/Caches, ~/Library/Logs, or ~/Library/Developer/Xcode/DerivedData."
|
||||
echo "Created Smart Clean manual fixtures:"
|
||||
print_status
|
||||
echo ""
|
||||
echo "Note: bin/clean.sh --dry-run may aggregate these fixtures into higher-level roots such as ~/Library/Caches, ~/Library/Logs, or ~/Library/Developer/Xcode/DerivedData."
|
||||
}
|
||||
|
||||
cleanup_fixtures() {
|
||||
rm -rf "$CACHE_ROOT" "$LOG_ROOT" "$DERIVED_ROOT" "$PYCACHE_ROOT"
|
||||
echo "Removed Smart Clean manual fixtures."
|
||||
rm -rf "$CACHE_ROOT" "$LOG_ROOT" "$DERIVED_ROOT" "$PYCACHE_ROOT"
|
||||
echo "Removed Smart Clean manual fixtures."
|
||||
}
|
||||
|
||||
case "${1:-create}" in
|
||||
create)
|
||||
create_fixtures
|
||||
;;
|
||||
status)
|
||||
print_status
|
||||
;;
|
||||
cleanup)
|
||||
cleanup_fixtures
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [create|status|cleanup]" >&2
|
||||
exit 1
|
||||
;;
|
||||
create)
|
||||
create_fixtures
|
||||
;;
|
||||
status)
|
||||
print_status
|
||||
;;
|
||||
cleanup)
|
||||
cleanup_fixtures
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [create|status|cleanup]" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
trusted=$(swift -e 'import ApplicationServices; print(AXIsProcessTrusted())' 2>/dev/null || echo false)
|
||||
trusted=$(swift -e 'import ApplicationServices; print(AXIsProcessTrusted())' 2> /dev/null || echo false)
|
||||
|
||||
echo "Atlas UI automation preflight"
|
||||
echo "============================"
|
||||
echo "Accessibility trusted for current process: $trusted"
|
||||
|
||||
if [[ "$trusted" != "true" ]]; then
|
||||
cat <<'MSG'
|
||||
cat << 'MSG'
|
||||
✗ UI automation is currently blocked by macOS Accessibility / automation permissions.
|
||||
|
||||
To unblock local XCUITest on this machine:
|
||||
@@ -19,7 +19,7 @@ To unblock local XCUITest on this machine:
|
||||
5. Re-run the minimal repro:
|
||||
xcodebuild test -project Testing/XCUITestRepro/XCUITestRepro.xcodeproj -scheme XCUITestRepro -destination 'platform=macOS'
|
||||
MSG
|
||||
exit 1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ Current process is trusted for Accessibility APIs"
|
||||
|
||||
@@ -7,28 +7,28 @@ BIN_PATH="$APP_PATH/Contents/MacOS/Atlas for Mac"
|
||||
STATE_DIR="${STATE_DIR:-$ROOT_DIR/.build/atlas-launch-state}"
|
||||
|
||||
if [[ ! -x "$BIN_PATH" ]]; then
|
||||
echo "App binary not found: $BIN_PATH" >&2
|
||||
exit 1
|
||||
echo "App binary not found: $BIN_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
ATLAS_STATE_DIR="$STATE_DIR" "$BIN_PATH" >/tmp/atlas-launch.log 2>&1 &
|
||||
ATLAS_STATE_DIR="$STATE_DIR" "$BIN_PATH" > /tmp/atlas-launch.log 2>&1 &
|
||||
pid=$!
|
||||
|
||||
cleanup() {
|
||||
if kill -0 "$pid" >/dev/null 2>&1; then
|
||||
kill "$pid" >/dev/null 2>&1 || true
|
||||
wait "$pid" >/dev/null 2>&1 || true
|
||||
fi
|
||||
if kill -0 "$pid" > /dev/null 2>&1; then
|
||||
kill "$pid" > /dev/null 2>&1 || true
|
||||
wait "$pid" > /dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
sleep 3
|
||||
|
||||
if ! kill -0 "$pid" >/dev/null 2>&1; then
|
||||
echo "Atlas app exited immediately; see /tmp/atlas-launch.log" >&2
|
||||
cat /tmp/atlas-launch.log >&2 || true
|
||||
exit 1
|
||||
if ! kill -0 "$pid" > /dev/null 2>&1; then
|
||||
echo "Atlas app exited immediately; see /tmp/atlas-launch.log" >&2
|
||||
cat /tmp/atlas-launch.log >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "App launch smoke test succeeded"
|
||||
|
||||
@@ -9,45 +9,45 @@ PLIST_PATH="$APP_PATH/Contents/Info.plist"
|
||||
XPC_PLIST_PATH="$XPC_PATH/Contents/Info.plist"
|
||||
|
||||
if [[ ! -d "$APP_PATH" ]]; then
|
||||
echo "App bundle not found: $APP_PATH" >&2
|
||||
exit 1
|
||||
echo "App bundle not found: $APP_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x "$HELPER_PATH" ]]; then
|
||||
echo "Helper not found or not executable: $HELPER_PATH" >&2
|
||||
exit 1
|
||||
echo "Helper not found or not executable: $HELPER_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -d "$XPC_PATH" ]]; then
|
||||
echo "Embedded XPC service missing: $XPC_PATH" >&2
|
||||
exit 1
|
||||
echo "Embedded XPC service missing: $XPC_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$PLIST_PATH" ]]; then
|
||||
echo "Missing Info.plist: $PLIST_PATH" >&2
|
||||
exit 1
|
||||
echo "Missing Info.plist: $PLIST_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f "$XPC_PLIST_PATH" ]]; then
|
||||
echo "Missing XPC Info.plist: $XPC_PLIST_PATH" >&2
|
||||
exit 1
|
||||
echo "Missing XPC Info.plist: $XPC_PLIST_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! /usr/bin/codesign --verify --deep --strict "$APP_PATH" >/dev/null 2>&1; then
|
||||
echo "App bundle failed codesign verification: $APP_PATH" >&2
|
||||
exit 1
|
||||
if ! /usr/bin/codesign --verify --deep --strict "$APP_PATH" > /dev/null 2>&1; then
|
||||
echo "App bundle failed codesign verification: $APP_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bundle_id=$(/usr/bin/defaults read "$PLIST_PATH" CFBundleIdentifier 2>/dev/null || true)
|
||||
display_name=$(/usr/bin/defaults read "$PLIST_PATH" CFBundleDisplayName 2>/dev/null || true)
|
||||
xpc_bundle_id=$(/usr/bin/defaults read "$XPC_PLIST_PATH" CFBundleIdentifier 2>/dev/null || true)
|
||||
bundle_id=$(/usr/bin/defaults read "$PLIST_PATH" CFBundleIdentifier 2> /dev/null || true)
|
||||
display_name=$(/usr/bin/defaults read "$PLIST_PATH" CFBundleDisplayName 2> /dev/null || true)
|
||||
xpc_bundle_id=$(/usr/bin/defaults read "$XPC_PLIST_PATH" CFBundleIdentifier 2> /dev/null || true)
|
||||
|
||||
if [[ "$bundle_id" != "com.atlasformac.app" ]]; then
|
||||
echo "Unexpected bundle identifier: ${bundle_id:-<empty>}" >&2
|
||||
exit 1
|
||||
echo "Unexpected bundle identifier: ${bundle_id:-<empty>}" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$display_name" != "Atlas for Mac" ]]; then
|
||||
echo "Unexpected display name: ${display_name:-<empty>}" >&2
|
||||
exit 1
|
||||
echo "Unexpected display name: ${display_name:-<empty>}" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$xpc_bundle_id" != "com.atlasformac.app.worker" ]]; then
|
||||
echo "Unexpected XPC bundle identifier: ${xpc_bundle_id:-<empty>}" >&2
|
||||
exit 1
|
||||
echo "Unexpected XPC bundle identifier: ${xpc_bundle_id:-<empty>}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Bundle verification succeeded"
|
||||
|
||||
@@ -12,27 +12,27 @@ INFO_PLIST="$INSTALLED_APP_PATH/Contents/Info.plist"
|
||||
KEEP_INSTALLED_APP="${KEEP_INSTALLED_APP:-0}"
|
||||
|
||||
cleanup() {
|
||||
if mount | grep -q "on $MOUNT_POINT "; then
|
||||
hdiutil detach "$MOUNT_POINT" -quiet || true
|
||||
fi
|
||||
if [[ "$KEEP_INSTALLED_APP" != "1" && -d "$INSTALLED_APP_PATH" ]]; then
|
||||
python3 - "$INSTALLED_APP_PATH" <<'PY'
|
||||
if mount | grep -q "on $MOUNT_POINT "; then
|
||||
hdiutil detach "$MOUNT_POINT" -quiet || true
|
||||
fi
|
||||
if [[ "$KEEP_INSTALLED_APP" != "1" && -d "$INSTALLED_APP_PATH" ]]; then
|
||||
python3 - "$INSTALLED_APP_PATH" << 'PY'
|
||||
from pathlib import Path
|
||||
import shutil, sys
|
||||
app = Path(sys.argv[1])
|
||||
if app.exists():
|
||||
shutil.rmtree(app)
|
||||
PY
|
||||
fi
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
if [[ ! -f "$DMG_PATH" ]]; then
|
||||
echo "DMG not found: $DMG_PATH" >&2
|
||||
exit 1
|
||||
echo "DMG not found: $DMG_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python3 - "$MOUNT_POINT" <<'PY'
|
||||
python3 - "$MOUNT_POINT" << 'PY'
|
||||
from pathlib import Path
|
||||
import shutil, sys
|
||||
mount_path = Path(sys.argv[1])
|
||||
@@ -45,11 +45,11 @@ mkdir -p "$INSTALL_ROOT/Applications"
|
||||
hdiutil attach "$DMG_PATH" -mountpoint "$MOUNT_POINT" -nobrowse -quiet
|
||||
|
||||
if [[ ! -d "$SOURCE_APP_PATH" ]]; then
|
||||
echo "Mounted app not found at $SOURCE_APP_PATH" >&2
|
||||
exit 1
|
||||
echo "Mounted app not found at $SOURCE_APP_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python3 - "$SOURCE_APP_PATH" "$INSTALLED_APP_PATH" <<'PY'
|
||||
python3 - "$SOURCE_APP_PATH" "$INSTALLED_APP_PATH" << 'PY'
|
||||
from pathlib import Path
|
||||
import shutil, sys
|
||||
src = Path(sys.argv[1])
|
||||
@@ -59,10 +59,10 @@ if dst.exists():
|
||||
shutil.copytree(src, dst, symlinks=True)
|
||||
PY
|
||||
|
||||
APP_DISPLAY_NAME=$(/usr/bin/defaults read "$INFO_PLIST" CFBundleDisplayName 2>/dev/null || echo "")
|
||||
APP_DISPLAY_NAME=$(/usr/bin/defaults read "$INFO_PLIST" CFBundleDisplayName 2> /dev/null || echo "")
|
||||
if [[ "$APP_DISPLAY_NAME" != "Atlas for Mac" ]]; then
|
||||
echo "Unexpected installed app display name: ${APP_DISPLAY_NAME:-<empty>}" >&2
|
||||
exit 1
|
||||
echo "Unexpected installed app display name: ${APP_DISPLAY_NAME:-<empty>}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "DMG install validation succeeded"
|
||||
|
||||
@@ -9,35 +9,35 @@ INFO_PLIST="$APP_PATH/Contents/Info.plist"
|
||||
KEEP_INSTALLED_APP="${KEEP_INSTALLED_APP:-0}"
|
||||
|
||||
cleanup() {
|
||||
if [[ "$KEEP_INSTALLED_APP" != "1" && -d "$APP_PATH" ]]; then
|
||||
python3 - <<'PY'
|
||||
if [[ "$KEEP_INSTALLED_APP" != "1" && -d "$APP_PATH" ]]; then
|
||||
python3 - << 'PY'
|
||||
from pathlib import Path
|
||||
import shutil, os
|
||||
app = Path(os.environ['APP_PATH'])
|
||||
if app.exists():
|
||||
shutil.rmtree(app)
|
||||
PY
|
||||
fi
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
if [[ ! -f "$PKG_PATH" ]]; then
|
||||
echo "Installer package not found: $PKG_PATH" >&2
|
||||
exit 1
|
||||
echo "Installer package not found: $PKG_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$INSTALL_ROOT/Applications"
|
||||
installer -allowUntrusted -pkg "$PKG_PATH" -target CurrentUserHomeDirectory >/dev/null
|
||||
installer -allowUntrusted -pkg "$PKG_PATH" -target CurrentUserHomeDirectory > /dev/null
|
||||
|
||||
if [[ ! -d "$APP_PATH" ]]; then
|
||||
echo "Installed app not found at $APP_PATH" >&2
|
||||
exit 1
|
||||
echo "Installed app not found at $APP_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
APP_DISPLAY_NAME=$(/usr/bin/defaults read "$INFO_PLIST" CFBundleDisplayName 2>/dev/null || echo "")
|
||||
APP_DISPLAY_NAME=$(/usr/bin/defaults read "$INFO_PLIST" CFBundleDisplayName 2> /dev/null || echo "")
|
||||
if [[ "$APP_DISPLAY_NAME" != "Atlas for Mac" ]]; then
|
||||
echo "Unexpected installed app display name: ${APP_DISPLAY_NAME:-<empty>}" >&2
|
||||
exit 1
|
||||
echo "Unexpected installed app display name: ${APP_DISPLAY_NAME:-<empty>}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installer validation succeeded"
|
||||
|
||||
Reference in New Issue
Block a user