Просмотр исходного кода

ci: add container build workflow

Add prebuilt build images and a publish workflow to speed CI by reusing heavy dependencies.
Dax Raad 2 месяцев назад
Родитель
Сommit
5cfb5fdd06

+ 38 - 0
.github/workflows/containers.yml

@@ -0,0 +1,38 @@
+name: containers
+
+on:
+  push:
+    branches:
+      - dev
+    paths:
+      - packages/containers/**
+      - .github/workflows/containers.yml
+  workflow_dispatch:
+
+permissions:
+  contents: read
+  packages: write
+
+jobs:
+  build:
+    runs-on: blacksmith-4vcpu-ubuntu-2404
+    env:
+      REGISTRY: ghcr.io/${{ github.repository_owner }}
+      TAG: "24.04"
+    steps:
+      - uses: actions/checkout@v4
+
+      - uses: ./.github/actions/setup-bun
+
+      - name: Login to GHCR
+        uses: docker/login-action@v3
+        with:
+          registry: ghcr.io
+          username: ${{ github.repository_owner }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Build and push containers
+        run: bun ./packages/containers/script/build.ts --push
+        env:
+          REGISTRY: ${{ env.REGISTRY }}
+          TAG: ${{ env.TAG }}

+ 36 - 0
packages/containers/README.md

@@ -0,0 +1,36 @@
+# CI containers
+
+Prebuilt images intended to speed up GitHub Actions jobs by baking in
+large, slow-to-install dependencies. These are designed for Linux jobs
+that can use `job.container` in workflows.
+
+Images
+
+- `base`: Ubuntu 24.04 with common build tools and utilities
+- `bun-node`: `base` plus Bun and Node.js 24
+- `rust`: `bun-node` plus Rust (stable, minimal profile)
+- `tauri-linux`: `rust` plus Tauri Linux build dependencies
+- `publish`: `bun-node` plus Docker CLI and AUR tooling
+
+Build
+
+```
+REGISTRY=ghcr.io/anomalyco TAG=24.04 bun ./packages/containers/script/build.ts
+```
+
+Workflow usage
+
+```
+jobs:
+  build-cli:
+    runs-on: ubuntu-latest
+    container:
+      image: ghcr.io/anomalyco/build/bun-node:24.04
+```
+
+Notes
+
+- These images only help Linux jobs. macOS and Windows jobs cannot run
+  inside Linux containers.
+- If a job uses Docker Buildx, the container needs access to the host
+  Docker daemon (or `docker-in-docker` with privileged mode).

+ 18 - 0
packages/containers/base/Dockerfile

@@ -0,0 +1,18 @@
+FROM ubuntu:24.04
+
+ARG DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update \
+  && apt-get install -y --no-install-recommends \
+    build-essential \
+    ca-certificates \
+    curl \
+    git \
+    jq \
+    openssh-client \
+    pkg-config \
+    python3 \
+    unzip \
+    xz-utils \
+    zip \
+  && rm -rf /var/lib/apt/lists/*

+ 22 - 0
packages/containers/bun-node/Dockerfile

@@ -0,0 +1,22 @@
+ARG REGISTRY=ghcr.io/anomalyco
+FROM ${REGISTRY}/build/base:24.04
+
+ARG NODE_VERSION=24.4.0
+ARG BUN_VERSION=1.2.4
+
+ENV BUN_INSTALL=/opt/bun
+ENV PATH=/opt/bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+
+RUN set -euo pipefail; \
+  arch=$(uname -m); \
+  node_arch=x64; \
+  if [ "$arch" = "aarch64" ]; then node_arch=arm64; fi; \
+  curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" \
+  | tar -xJf - -C /usr/local --strip-components=1; \
+  corepack enable
+
+RUN set -euo pipefail; \
+  curl -fsSL https://bun.sh/install | bash -s -- "bun-v${BUN_VERSION}"; \
+  bun --version; \
+  node --version; \
+  npm --version

+ 10 - 0
packages/containers/publish/Dockerfile

@@ -0,0 +1,10 @@
+ARG REGISTRY=ghcr.io/anomalyco
+FROM ${REGISTRY}/build/bun-node:24.04
+
+ARG DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update \
+  && apt-get install -y --no-install-recommends \
+    docker.io \
+    pacman-package-manager \
+  && rm -rf /var/lib/apt/lists/*

+ 13 - 0
packages/containers/rust/Dockerfile

@@ -0,0 +1,13 @@
+ARG REGISTRY=ghcr.io/anomalyco
+FROM ${REGISTRY}/build/bun-node:24.04
+
+ARG RUST_TOOLCHAIN=stable
+
+ENV CARGO_HOME=/opt/cargo
+ENV RUSTUP_HOME=/opt/rustup
+ENV PATH=/opt/cargo/bin:/opt/bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+
+RUN set -euo pipefail; \
+  curl -fsSL https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain "${RUST_TOOLCHAIN}"; \
+  rustc --version; \
+  cargo --version

+ 25 - 0
packages/containers/script/build.ts

@@ -0,0 +1,25 @@
+#!/usr/bin/env bun
+
+import { $ } from "bun"
+
+const dir = new URL("..", import.meta.url).pathname
+process.chdir(dir)
+
+const reg = process.env.REGISTRY ?? "ghcr.io/anomalyco"
+const tag = process.env.TAG ?? "24.04"
+const push = process.argv.includes("--push") || process.env.PUSH === "1"
+
+const images = ["base", "bun-node", "rust", "tauri-linux", "publish"]
+
+for (const name of images) {
+  const image = `${reg}/build/${name}:${tag}`
+  const file = `packages/containers/${name}/Dockerfile`
+  const arg = name === "base" ? "" : `--build-arg REGISTRY=${reg}`
+  const cmd = `docker build -f ${file} -t ${image} ${arg} .`
+  console.log(cmd)
+  await $`${cmd}`
+
+  if (push) {
+    await $`docker push ${image}`
+  }
+}

+ 12 - 0
packages/containers/tauri-linux/Dockerfile

@@ -0,0 +1,12 @@
+ARG REGISTRY=ghcr.io/anomalyco
+FROM ${REGISTRY}/build/rust:24.04
+
+ARG DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update \
+  && apt-get install -y --no-install-recommends \
+    libappindicator3-dev \
+    libwebkit2gtk-4.1-dev \
+    librsvg2-dev \
+    patchelf \
+  && rm -rf /var/lib/apt/lists/*

+ 8 - 0
packages/containers/tsconfig.json

@@ -0,0 +1,8 @@
+{
+  "$schema": "https://json.schemastore.org/tsconfig",
+  "extends": "@tsconfig/bun/tsconfig.json",
+  "compilerOptions": {
+    "lib": ["ESNext", "DOM", "DOM.Iterable"],
+    "noUncheckedIndexedAccess": false
+  }
+}