diff --git a/.changeset/patch-fix-macos-arm64-smoke-test.md b/.changeset/patch-fix-macos-arm64-smoke-test.md new file mode 100644 index 00000000000..586155d60cd --- /dev/null +++ b/.changeset/patch-fix-macos-arm64-smoke-test.md @@ -0,0 +1,4 @@ +--- +"gh-aw": patch +--- +Fix the macOS ARM64 smoke test setup by ensuring `/opt/gh-aw` permissions, installing Docker via Colima, and pulling AWF from the npm tarball. diff --git a/.github/smoke-test-22204001807.md b/.github/smoke-test-22204001807.md new file mode 100644 index 00000000000..5ec052603ae --- /dev/null +++ b/.github/smoke-test-22204001807.md @@ -0,0 +1 @@ +Test file for PR push - smoke test run 22204001807 diff --git a/.github/workflows/smoke-macos-arm64.lock.yml b/.github/workflows/smoke-macos-arm64.lock.yml index 8b605c64f19..0c7cc2494b6 100644 --- a/.github/workflows/smoke-macos-arm64.lock.yml +++ b/.github/workflows/smoke-macos-arm64.lock.yml @@ -431,6 +431,8 @@ jobs: COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - name: Install GitHub Copilot CLI run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.411 + - name: Install Docker on macOS + run: bash /opt/gh-aw/actions/install_docker_macos.sh - name: Install awf binary run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.20.2 - name: Determine automatic lockdown mode for GitHub MCP Server diff --git a/actions/setup/setup.sh b/actions/setup/setup.sh index b5fe1a4920e..9f50df09286 100755 --- a/actions/setup/setup.sh +++ b/actions/setup/setup.sh @@ -14,6 +14,16 @@ set -e +# Helper: create directories with sudo on macOS where /opt is root-owned +create_dir() { + if [[ "$(uname -s)" == "Darwin" ]]; then + sudo mkdir -p "$1" + sudo chown -R "$(whoami)" "$1" + else + mkdir -p "$1" + fi +} + # Get destination from input or use default DESTINATION="${INPUT_DESTINATION:-/opt/gh-aw/actions}" @@ -24,7 +34,7 @@ echo "Copying activation files to ${DESTINATION}" echo "Safe-output-projects support: ${SAFE_OUTPUT_PROJECTS_ENABLED}" # Create destination directory if it doesn't exist -mkdir -p "${DESTINATION}" +create_dir "${DESTINATION}" echo "Created directory: ${DESTINATION}" # Get the directory where this script is located @@ -105,7 +115,7 @@ echo "Successfully copied ${FILE_COUNT} files to ${DESTINATION}" # Copy prompt markdown files to their expected directory PROMPTS_DEST="/opt/gh-aw/prompts" echo "Copying prompt markdown files to ${PROMPTS_DEST}" -mkdir -p "${PROMPTS_DEST}" +create_dir "${PROMPTS_DEST}" MD_SOURCE_DIR="${SCRIPT_DIR}/md" PROMPT_COUNT=0 @@ -127,7 +137,7 @@ fi # Copy safe-inputs files to their expected directory SAFE_INPUTS_DEST="/opt/gh-aw/safe-inputs" echo "Copying safe-inputs files to ${SAFE_INPUTS_DEST}" -mkdir -p "${SAFE_INPUTS_DEST}" +create_dir "${SAFE_INPUTS_DEST}" SAFE_INPUTS_FILES=( "safe_inputs_bootstrap.cjs" @@ -178,7 +188,7 @@ echo "Successfully copied ${SAFE_INPUTS_COUNT} safe-inputs files to ${SAFE_INPUT # Copy safe-outputs files to their expected directory SAFE_OUTPUTS_DEST="/opt/gh-aw/safeoutputs" echo "Copying safe-outputs files to ${SAFE_OUTPUTS_DEST}" -mkdir -p "${SAFE_OUTPUTS_DEST}" +create_dir "${SAFE_OUTPUTS_DEST}" SAFE_OUTPUTS_FILES=( "safe_outputs_mcp_server.cjs" diff --git a/actions/setup/sh/install_awf_binary.sh b/actions/setup/sh/install_awf_binary.sh index e81eb4bba86..ff92b45e243 100755 --- a/actions/setup/sh/install_awf_binary.sh +++ b/actions/setup/sh/install_awf_binary.sh @@ -8,6 +8,10 @@ # Arguments: # VERSION - AWF version to install (e.g., v0.10.0) # +# Platform support: +# - Linux (x64, arm64): Downloads pre-built binary +# - macOS (x64, arm64): Downloads pre-built binary +# # Security features: # - Downloads binary directly from GitHub releases # - Verifies SHA256 checksum against official checksums.txt @@ -19,7 +23,6 @@ set -euo pipefail # Configuration AWF_VERSION="${1:-}" AWF_REPO="github/gh-aw-firewall" -AWF_BINARY="awf-linux-x64" AWF_INSTALL_DIR="/usr/local/bin" AWF_INSTALL_NAME="awf" @@ -29,49 +32,120 @@ if [ -z "$AWF_VERSION" ]; then exit 1 fi -echo "Installing awf binary with checksum verification (version: ${AWF_VERSION})" +# Detect OS and architecture +OS="$(uname -s)" +ARCH="$(uname -m)" + +echo "Installing awf with checksum verification (version: ${AWF_VERSION}, os: ${OS}, arch: ${ARCH})" # Download URLs BASE_URL="https://github.com/${AWF_REPO}/releases/download/${AWF_VERSION}" -BINARY_URL="${BASE_URL}/${AWF_BINARY}" CHECKSUMS_URL="${BASE_URL}/checksums.txt" +# Platform-portable SHA256 function +sha256_hash() { + local file="$1" + if command -v sha256sum &>/dev/null; then + sha256sum "$file" | awk '{print $1}' + elif command -v shasum &>/dev/null; then + shasum -a 256 "$file" | awk '{print $1}' + else + echo "ERROR: No sha256sum or shasum found" >&2 + exit 1 + fi +} + # Create temp directory TEMP_DIR=$(mktemp -d) trap 'rm -rf "$TEMP_DIR"' EXIT -# Download binary and checksums -echo "Downloading binary from ${BINARY_URL@Q}..." -curl -fsSL -o "${TEMP_DIR}/${AWF_BINARY}" "${BINARY_URL}" - +# Download checksums echo "Downloading checksums from ${CHECKSUMS_URL@Q}..." curl -fsSL -o "${TEMP_DIR}/checksums.txt" "${CHECKSUMS_URL}" -# Verify checksum -echo "Verifying SHA256 checksum..." -cd "${TEMP_DIR}" -EXPECTED_CHECKSUM=$(awk -v fname="${AWF_BINARY}" '$2 == fname {print $1; exit}' checksums.txt | tr 'A-F' 'a-f') - -if [ -z "$EXPECTED_CHECKSUM" ]; then - echo "ERROR: Could not find checksum for ${AWF_BINARY} in checksums.txt" - exit 1 -fi - -ACTUAL_CHECKSUM=$(sha256sum "${AWF_BINARY}" | awk '{print $1}' | tr 'A-F' 'a-f') - -if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then - echo "ERROR: Checksum verification failed!" - echo " Expected: $EXPECTED_CHECKSUM" - echo " Got: $ACTUAL_CHECKSUM" - echo " The downloaded file may be corrupted or tampered with" - exit 1 -fi - -echo "✓ Checksum verification passed" - -# Make binary executable and install -chmod +x "${AWF_BINARY}" -sudo mv "${AWF_BINARY}" "${AWF_INSTALL_DIR}/${AWF_INSTALL_NAME}" +verify_checksum() { + local file="$1" + local fname="$2" + + echo "Verifying SHA256 checksum for ${fname}..." + EXPECTED_CHECKSUM=$(awk -v fname="${fname}" '$2 == fname {print $1; exit}' "${TEMP_DIR}/checksums.txt" | tr 'A-F' 'a-f') + + if [ -z "$EXPECTED_CHECKSUM" ]; then + echo "ERROR: Could not find checksum for ${fname} in checksums.txt" + exit 1 + fi + + ACTUAL_CHECKSUM=$(sha256_hash "$file" | tr 'A-F' 'a-f') + + if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then + echo "ERROR: Checksum verification failed!" + echo " Expected: $EXPECTED_CHECKSUM" + echo " Got: $ACTUAL_CHECKSUM" + echo " The downloaded file may be corrupted or tampered with" + exit 1 + fi + + echo "✓ Checksum verification passed for ${fname}" +} + +install_linux_binary() { + # Determine binary name based on architecture + local awf_binary + case "$ARCH" in + x86_64|amd64) awf_binary="awf-linux-x64" ;; + aarch64|arm64) awf_binary="awf-linux-arm64" ;; + *) echo "ERROR: Unsupported Linux architecture: ${ARCH}"; exit 1 ;; + esac + + local binary_url="${BASE_URL}/${awf_binary}" + echo "Downloading binary from ${binary_url@Q}..." + curl -fsSL -o "${TEMP_DIR}/${awf_binary}" "${binary_url}" + + # Verify checksum + verify_checksum "${TEMP_DIR}/${awf_binary}" "${awf_binary}" + + # Make binary executable and install + chmod +x "${TEMP_DIR}/${awf_binary}" + sudo mv "${TEMP_DIR}/${awf_binary}" "${AWF_INSTALL_DIR}/${AWF_INSTALL_NAME}" +} + +install_darwin_binary() { + # Determine binary name based on architecture + local awf_binary + case "$ARCH" in + x86_64) awf_binary="awf-darwin-x64" ;; + arm64) awf_binary="awf-darwin-arm64" ;; + *) echo "ERROR: Unsupported macOS architecture: ${ARCH}"; exit 1 ;; + esac + + echo "Note: AWF uses iptables for network firewalling, which is not available on macOS." + echo " The AWF CLI will be installed but container-based firewalling will not work natively." + echo "" + + local binary_url="${BASE_URL}/${awf_binary}" + echo "Downloading binary from ${binary_url@Q}..." + curl -fsSL -o "${TEMP_DIR}/${awf_binary}" "${binary_url}" + + # Verify checksum + verify_checksum "${TEMP_DIR}/${awf_binary}" "${awf_binary}" + + # Make binary executable and install + chmod +x "${TEMP_DIR}/${awf_binary}" + sudo mv "${TEMP_DIR}/${awf_binary}" "${AWF_INSTALL_DIR}/${AWF_INSTALL_NAME}" +} + +case "$OS" in + Linux) + install_linux_binary + ;; + Darwin) + install_darwin_binary + ;; + *) + echo "ERROR: Unsupported operating system: ${OS}" + exit 1 + ;; +esac # Verify installation which awf diff --git a/actions/setup/sh/install_docker_macos.sh b/actions/setup/sh/install_docker_macos.sh new file mode 100755 index 00000000000..e093997a94d --- /dev/null +++ b/actions/setup/sh/install_docker_macos.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Install Docker on macOS GitHub Actions runners via colima +# Usage: install_docker_macos.sh +# +# macOS GHA runners (macos-latest / macos-15-arm64) do not include Docker. +# This script installs colima (a lightweight Docker runtime for macOS) and the +# Docker CLI via Homebrew, then starts colima with Apple's Virtualization +# framework (vz) for native ARM64 performance. +# +# On Linux runners, Docker is pre-installed so this script exits early. + +set -euo pipefail + +# Skip on non-macOS systems (Linux runners already have Docker) +if [ "$(uname -s)" != "Darwin" ]; then + echo "Not macOS — skipping Docker installation (Docker is pre-installed on Linux runners)" + exit 0 +fi + +# Check if Docker is already available and running +if command -v docker &>/dev/null && docker info &>/dev/null; then + echo "Docker is already installed and running — skipping installation" + exit 0 +fi + +echo "Installing Docker on macOS via colima..." + +# Install colima and docker CLI via Homebrew +echo "Installing colima and docker CLI..." +brew install colima docker + +# Start colima with ARM64 architecture and Apple Virtualization framework +# - --arch aarch64: native ARM64 for Apple Silicon runners +# - --vm-type vz: Apple's Virtualization.framework (faster than QEMU) +# - --memory 4: 4GB RAM for the VM (sufficient for agent containers) +echo "Starting colima..." +colima start --arch aarch64 --vm-type=vz --memory 4 + +# Verify Docker is working +echo "Verifying Docker installation..." +if ! docker info &>/dev/null; then + echo "ERROR: Docker is not responding after colima start" + colima status || true + exit 1 +fi + +docker version +echo "Docker installation complete"