Skip to content

quotes are evil

quotes are evil #13

Workflow file for this run

name: Build Release Binaries
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
jobs:
build:
name: Release binaries
strategy:
matrix:
include:
# Linux compiles itself
- os: ubuntu-24.04
bundle: linux
targets: cross-aarch64-unknown-linux-gnu cross-aarch64-unknown-linux-musl cross-x86_64-unknown-linux-gnu cross-x86_64-unknown-linux-musl
# We can compile the windows target from linux
- os: ubuntu-24.04
bundle: windows
targets: cross-aarch64-pc-windows-gnullvm cross-x86_64-pc-windows-gnullvm
# Apple SDK does not allow us to cross compile from non-apple-branded
# machines, so we run that bundle on a macOS runner
# Note: We use macos-13 here since it is the latest version that runs
# on an x86_64-apple-darwin machine
- os: macos-13
bundle: darwin
targets: cross-aarch64-apple-darwin default
runs-on: ${{ matrix.os }}
permissions:
contents: write
packages: write
attestations: write
id-token: write
steps:
- uses: actions/checkout@v4
- uses: nixbuild/nix-quick-install-action@v30
with:
nix_conf: ${{ env.nix_conf }}
- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v6
with:
primary-key: release-${{ matrix.bundle }}-${{ hashFiles('Cargo.lock', '**/Cargo.toml', 'flake.nix', 'flake.lock', 'rust-toolchain.toml') }}
restore-prefixes-first-match: |
release-${{ matrix.bundle }}-
build-${{ runner.os }}-
purge: true
purge-prefixes: release-${{ matrix.bundle }}-
purge-created: 0
purge-primary-key: never
gc-max-store-size: 5G
- name: Build binaries
run: |
mkdir release
for BUILD_TARGET in ${{ matrix.targets }}; do
# Hack for x86_64-apple-darwin since it doesn't yet work with cross compilation
if [ "$BUILD_TARGET" == "default" ]; then
TARGET="x86_64-apple-darwin"
else
TARGET=${BUILD_TARGET#"cross-"}
fi
echo "Scaffolding release for $TARGET..."
mkdir -p "release/$TARGET/dist"
cp README.md LICENSE "release/$TARGET/dist"
echo "Building release for $TARGET..."
nix build .#$TARGET
cp result/bin/* "release/$TARGET/dist/"
done
- name: Sign Apple Binary
if: ${{ runner.os == 'macOS' }}
env:
MACOS_CERT_BUNDLE_PASSWORD: ${{ secrets.MACOS_CERT_BUNDLE_PASSWORD }}
MACOS_CERT_BUNDLE_BASE64: ${{ secrets.MACOS_CERT_BUNDLE_BASE64 }}
MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_USERNAME: ${{ secrets.APPLE_USERNAME }}
KEYCHAIN_NAME: "apollo-mcp-server-keychain"
ENTITLEMENTS_PATH: "macos-entitlements.plist"
VERSION: ${{ github.ref }}
run: |
echo "Pre-check: Valid Codesigning Identify"
security find-identity -v -p codesigning
echo "Pre-check: Codesigning Identify"
security find-identity -p codesigning
echo "Pre-check: Any Identify"
security find-identity
echo "|||||||||||||||||||||||||||||||||||||||||||||"
# Create a temporary keychain
EPHEMERAL_KEYCHAIN=`mktemp`
echo "Creating keychain..."
security create-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" $KEYCHAIN_NAME
echo "Removing relock timeout on keychain..."
security set-keychain-settings $KEYCHAIN_NAME
echo "Decoding certificate bundle..."
echo "${MACOS_CERT_BUNDLE_BASE64}" | base64 --decode > $EPHEMERAL_KEYCHAIN/certificate.p12
echo "Importing codesigning certificate to build keychain..."
security import $EPHEMERAL_KEYCHAIN/certificate.p12 -k $KEYCHAIN_NAME -P "${MACOS_CERT_BUNDLE_PASSWORD}" -T /usr/bin/codesign
echo "Adding the codesign tool to the security partition-list..."
security set-key-partition-list -S "apple-tool:,apple:,codesign:" -s -k "${MACOS_KEYCHAIN_PASSWORD}" $KEYCHAIN_NAME
echo "Setting default keychain..."
security default-keychain -d user -s $KEYCHAIN_NAME
echo "Unlocking keychain..."
security unlock-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" $KEYCHAIN_NAME
echo "Verifying keychain is set up correctly..."
security find-identity -v -p codesigning
echo "|||||||||||||||||||||||||||||||||||||||||||||"
echo "Post-check: Valid Codesigning Identify"
security find-identity -v -p codesigning
echo "Post-check: Codesigning Identify"
security find-identity -p codesigning
echo "Post-check: Any Identify"
security find-identity
echo "|||||||||||||||||||||||||||||||||||||||||||||"
# Sign each binary
for RELEASE in release/*/; do
RELEASE=${RELEASE%/}
RELEASE=${RELEASE#"release/"}
BINARY_PATH="release/$RELEASE/dist/apollo-mcp-server"
echo "Starting code signing for $RELEASE..."
echo "> Signing code (step 1)..."
codesign --sign "$APPLE_TEAM_ID" --options runtime --entitlements $ENTITLEMENTS_PATH --force --timestamp "$BINARY_PATH" -v
echo "> Signing code (step 2)..."
codesign -vvv --deep --strict "$BINARY_PATH"
echo "> Zipping dist..."
TMP_DIST=`mktemp`
mkdir $TMP_DIST/dist
cp "$BINARY_PATH" "$TMP_DIST/dist/"
zip -r "$TMP_DIST/apollo-mcp-server-$VERSION.zip" "$TMP_DIST/dist"
echo "> Beginning notarization process (might take up to 20m)..."
xcrun notarytool submit "$TMP_DIST/apollo-mcp-server-$VERSION.zip" \
--apple-id "$APPLE_USERNAME" \
--password "$APPLE_NOTARIZATION_PASSWORD" \
--team-id "$APPLE_TEAM_ID" \
--wait \
--timeout 20m
echo "> Cleaning up release..."
rm -rf $TMP_DIST
done
echo "Cleaning up ephemeral keychain..."
rm -rf $EPHEMERAL_KEYCHAIN/
- name: Create release bundles
env:
VERSION: ${{ github.ref }}
run: |
mkdir artifacts
for RELEASE in release/*/; do
# Remove trailing slash and leading parent
RELEASE=${RELEASE%/}
RELEASE=${RELEASE#"release/"}
echo "Creating an artifact for $RELEASE"
tar -C release/$RELEASE -cf - dist/ | gzip -9 > artifacts/apollo-mcp-server-$VERSION-$RELEASE.tar.gz
done
- name: Upload release artifacts
uses: softprops/action-gh-release@v2
with:
files: result/*
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
with:
subject-path: "result/*"