mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 14:18:04 +08:00
image
This commit is contained in:
97
.github/workflows/runner/containerfile
vendored
Normal file
97
.github/workflows/runner/containerfile
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# System dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
jq \
|
||||
libssl-dev \
|
||||
lsb-release \
|
||||
mold \
|
||||
pkg-config \
|
||||
sudo \
|
||||
unzip \
|
||||
wget \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install sccache to /usr/bin (CI expects it there for RUSTC_WRAPPER)
|
||||
ARG SCCACHE_VERSION=0.9.1
|
||||
RUN ARCH=$(uname -m) && \
|
||||
curl -fsSL "https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VERSION}/sccache-v${SCCACHE_VERSION}-${ARCH}-unknown-linux-musl.tar.gz" \
|
||||
| tar xz --strip-components=1 -C /usr/bin/ "sccache-v${SCCACHE_VERSION}-${ARCH}-unknown-linux-musl/sccache" && \
|
||||
chmod +x /usr/bin/sccache
|
||||
|
||||
# Install Node.js LTS
|
||||
ARG NODE_MAJOR=22
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - && \
|
||||
apt-get install -y --no-install-recommends nodejs && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create runner user
|
||||
RUN useradd -m -s /bin/bash runner && \
|
||||
echo "runner ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/runner
|
||||
|
||||
# Create cache directories with correct ownership
|
||||
RUN mkdir -p /var/lib/github-actions/.cache && \
|
||||
chown -R runner:runner /var/lib/github-actions
|
||||
|
||||
USER runner
|
||||
WORKDIR /home/runner
|
||||
|
||||
# Install Rust stable + wasm target
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile default && \
|
||||
. "$HOME/.cargo/env" && \
|
||||
rustup target add wasm32-unknown-unknown && \
|
||||
rustup component add clippy rustfmt
|
||||
|
||||
ENV PATH="/home/runner/.cargo/bin:${PATH}"
|
||||
|
||||
# Install cargo tools required by the project
|
||||
# wasm-bindgen-cli is pinned to match the version in Cargo.toml (=0.2.100)
|
||||
RUN cargo install --locked wasm-bindgen-cli@0.2.100 && \
|
||||
cargo install --locked wasm-pack && \
|
||||
cargo install --locked cargo-about
|
||||
|
||||
# Environment variables matching CI configuration
|
||||
ENV RUSTC_WRAPPER=/usr/bin/sccache
|
||||
ENV CARGO_INCREMENTAL=0
|
||||
ENV SCCACHE_DIR=/var/lib/github-actions/.cache
|
||||
|
||||
# Install GitHub Actions runner
|
||||
ARG RUNNER_VERSION=2.322.0
|
||||
RUN ARCH=$(uname -m | sed 's/x86_64/x64/' | sed 's/aarch64/arm64/') && \
|
||||
curl -fsSL "https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${ARCH}-${RUNNER_VERSION}.tar.gz" \
|
||||
| tar xz -C /home/runner
|
||||
|
||||
# Entrypoint script: configure and start the runner
|
||||
COPY --chown=runner:runner <<'ENTRYPOINT' /home/runner/entrypoint.sh
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
RUNNER_NAME="${RUNNER_NAME:-$(hostname)}"
|
||||
RUNNER_LABELS="${RUNNER_LABELS:-target/wasm,target/native}"
|
||||
RUNNER_WORKDIR="${RUNNER_WORKDIR:-/home/runner/_work}"
|
||||
|
||||
# Configure the runner if not already configured
|
||||
if [ ! -f /home/runner/.runner ]; then
|
||||
/home/runner/config.sh \
|
||||
--unattended \
|
||||
--url "${GITHUB_URL}" \
|
||||
--token "${RUNNER_TOKEN}" \
|
||||
--name "${RUNNER_NAME}" \
|
||||
--labels "${RUNNER_LABELS}" \
|
||||
--work "${RUNNER_WORKDIR}" \
|
||||
--replace
|
||||
fi
|
||||
|
||||
# Run with automatic cleanup on container stop
|
||||
exec /home/runner/run.sh
|
||||
ENTRYPOINT
|
||||
RUN chmod +x /home/runner/entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/home/runner/entrypoint.sh"]
|
||||
124
.github/workflows/runner/setup-runners.sh
vendored
Executable file
124
.github/workflows/runner/setup-runners.sh
vendored
Executable file
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE_NAME="graphite-github-actions-runner"
|
||||
GITHUB_URL="https://github.com/GraphiteEditor/Graphite"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 [options]
|
||||
|
||||
Spawn self-hosted GitHub Actions runners for Graphite.
|
||||
|
||||
Required:
|
||||
-t TOKEN GitHub runner registration token
|
||||
-p PREFIX Runner name prefix
|
||||
|
||||
Optional:
|
||||
-n COUNT Number of target/native runners to create (default: 1)
|
||||
-w COUNT Number of target/wasm runners to create (default: 1)
|
||||
-u URL GitHub repository URL (default: $GITHUB_URL)
|
||||
-i IMAGE Container image name (default: $IMAGE_NAME)
|
||||
-b Build the image before starting runners
|
||||
-d Tear down existing runners matching the prefix first
|
||||
-h Show this help message
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
NATIVE_COUNT=1
|
||||
WASM_COUNT=1
|
||||
TOKEN=""
|
||||
PREFIX=""
|
||||
BUILD=false
|
||||
TEARDOWN=false
|
||||
|
||||
while getopts "t:p:n:w:u:i:bdh" opt; do
|
||||
case $opt in
|
||||
t) TOKEN="$OPTARG" ;;
|
||||
p) PREFIX="$OPTARG" ;;
|
||||
n) NATIVE_COUNT="$OPTARG" ;;
|
||||
w) WASM_COUNT="$OPTARG" ;;
|
||||
u) GITHUB_URL="$OPTARG" ;;
|
||||
i) IMAGE_NAME="$OPTARG" ;;
|
||||
b) BUILD=true ;;
|
||||
d) TEARDOWN=true ;;
|
||||
h) usage ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$PREFIX" ]; then
|
||||
echo "Error: -p PREFIX is required"
|
||||
usage
|
||||
fi
|
||||
|
||||
teardown() {
|
||||
local pattern="$IMAGE_NAME-${PREFIX}-"
|
||||
echo "Tearing down containers matching: ${pattern}*"
|
||||
for cid in $(podman ps -a --filter "name=${pattern}" --format '{{.ID}}' 2>/dev/null); do
|
||||
name=$(podman inspect --format '{{.Name}}' "$cid")
|
||||
echo " Stopping and removing $name"
|
||||
podman rm -f "$cid"
|
||||
done
|
||||
}
|
||||
|
||||
if [ "$TEARDOWN" = true ]; then
|
||||
teardown
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "Teardown complete."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "Error: -t TOKEN is required to create runners"
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ "$BUILD" = true ]; then
|
||||
echo "Building image: $IMAGE_NAME"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
podman build -t "$IMAGE_NAME" -f "$SCRIPT_DIR/containerfile" "$SCRIPT_DIR/.."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
start_runner() {
|
||||
local target="$1" # native or wasm
|
||||
local index="$2"
|
||||
|
||||
local name="${IMAGE_NAME}-${PREFIX}-${target}-${index}"
|
||||
local runner_name="${PREFIX}-${target}-${index}"
|
||||
local label="target/${target}"
|
||||
|
||||
# Each runner gets its own sccache volume for isolation
|
||||
local cache_vol="${name}-cache"
|
||||
|
||||
echo "Starting runner: $name (label: $label)"
|
||||
podman run -d \
|
||||
--name "$name" \
|
||||
--restart unless-stopped \
|
||||
-v "${cache_vol}:/var/lib/github-actions/.cache" \
|
||||
-e RUNNER_NAME="$runner_name" \
|
||||
-e RUNNER_LABELS="$label" \
|
||||
-e GITHUB_URL="$GITHUB_URL" \
|
||||
-e RUNNER_TOKEN="$TOKEN" \
|
||||
"$IMAGE_NAME"
|
||||
|
||||
echo " -> $name started (volume: $cache_vol)"
|
||||
}
|
||||
|
||||
echo "Creating $NATIVE_COUNT native runner(s) and $WASM_COUNT wasm runner(s)"
|
||||
echo ""
|
||||
|
||||
for i in $(seq 0 $((NATIVE_COUNT - 1))); do
|
||||
start_runner "native" "$i"
|
||||
done
|
||||
|
||||
for i in $(seq 0 $((WASM_COUNT - 1))); do
|
||||
start_runner "wasm" "$i"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "All runners started. Verify with: podman ps --filter name=$IMAGE_NAME"
|
||||
Reference in New Issue
Block a user