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
4 changes: 4 additions & 0 deletions .changeset/patch-fix-macos-arm64-smoke-test.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .github/smoke-test-22204001807.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test file for PR push - smoke test run 22204001807
2 changes: 2 additions & 0 deletions .github/workflows/smoke-macos-arm64.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions actions/setup/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@

set -e

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The create_dir helper cleanly abstracts the macOS sudo requirement. Consider adding a comment clarifying why ownership must be transferred back to the current user (so subsequent non-sudo writes succeed).

# 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}"

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
138 changes: 106 additions & 32 deletions actions/setup/sh/install_awf_binary.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"

Expand All @@ -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() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice cross-platform sha256_hash helper. The shasum fallback correctly handles macOS where sha256sum is not available by default. ✅

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
Expand Down
48 changes: 48 additions & 0 deletions actions/setup/sh/install_docker_macos.sh
Original file line number Diff line number Diff line change
@@ -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"