mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-04 04:48:15 +03:00
feat: significantly better ci images (#1516)
This commit is contained in:
@@ -38,7 +38,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/zkldi/tachi-dev:main
|
||||
image: ghcr.io/zkldi/tachi-ci:main
|
||||
options: --user root
|
||||
env:
|
||||
NODE_ENV: "test"
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/zkldi/tachi-dev:main
|
||||
image: ghcr.io/zkldi/tachi-ci:main
|
||||
options: --user root
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/zkldi/tachi-dev:main
|
||||
image: ghcr.io/zkldi/tachi-ci:main
|
||||
options: --user root
|
||||
needs: test
|
||||
if: ${{ github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/zkldi/tachi-dev:main
|
||||
image: ghcr.io/zkldi/tachi-ci:main
|
||||
options: --user root
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/zkldi/tachi-dev:main
|
||||
image: ghcr.io/zkldi/tachi-ci:main
|
||||
options: --user root
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -53,16 +53,39 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
|
||||
- name: Build and push
|
||||
# `tachi-ci` = the minimal `base` stage. Used as the `container:` image
|
||||
# for every workspace CI job. Kept small so the per-job image pull is
|
||||
# cheap.
|
||||
- name: Build and push tachi-ci (base stage)
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.dev
|
||||
target: base
|
||||
push: ${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}
|
||||
tags: |
|
||||
ghcr.io/zkldi/tachi-ci:main
|
||||
ghcr.io/zkldi/tachi-ci:latest
|
||||
ghcr.io/zkldi/tachi-ci:${{ steps.revision.outputs.image_tag }}
|
||||
ghcr.io/zkldi/tachi-ci:${{ github.sha }}
|
||||
cache-from: type=gha,scope=dev-image-base
|
||||
cache-to: type=gha,mode=max,scope=dev-image-base
|
||||
|
||||
# `tachi-dev` = full devcontainer image (`dev` stage on top of `base`).
|
||||
# Pulled by devs once and rebuilt rarely; CI never touches it.
|
||||
- name: Build and push tachi-dev (dev stage)
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.dev
|
||||
target: dev
|
||||
push: ${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}
|
||||
tags: |
|
||||
ghcr.io/zkldi/tachi-dev:main
|
||||
ghcr.io/zkldi/tachi-dev:latest
|
||||
ghcr.io/zkldi/tachi-dev:${{ steps.revision.outputs.image_tag }}
|
||||
ghcr.io/zkldi/tachi-dev:${{ github.sha }}
|
||||
cache-from: type=gha,scope=dev-image
|
||||
cache-to: type=gha,mode=max,scope=dev-image
|
||||
cache-from: |
|
||||
type=gha,scope=dev-image-dev
|
||||
type=gha,scope=dev-image-base
|
||||
cache-to: type=gha,mode=max,scope=dev-image-dev
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/zkldi/tachi-dev:main
|
||||
image: ghcr.io/zkldi/tachi-ci:main
|
||||
options: --user root
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/zkldi/tachi-dev:main
|
||||
image: ghcr.io/zkldi/tachi-ci:main
|
||||
options: --user root
|
||||
if: ${{ github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
|
||||
steps:
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/zkldi/tachi-dev:main
|
||||
image: ghcr.io/zkldi/tachi-ci:main
|
||||
options: --user root
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/zkldi/tachi-dev:main
|
||||
image: ghcr.io/zkldi/tachi-ci:main
|
||||
options: --user root
|
||||
env:
|
||||
NODE_ENV: "test"
|
||||
|
||||
+79
-32
@@ -1,56 +1,103 @@
|
||||
# For use via `devcontainer.json`. The docker-compose-dev file sets some other
|
||||
# important variables.
|
||||
# syntax=docker/dockerfile:1.7
|
||||
#
|
||||
# Two stages live here:
|
||||
#
|
||||
# - `base`: minimal image used as the `container:` for every CI job. Just
|
||||
# enough to run `bun install`, `bun run …`, `just`, `psql`, `rsync`, ssh.
|
||||
# Published as `ghcr.io/zkldi/tachi-ci`.
|
||||
# - `dev`: superset of `base` with all the devcontainer QoL (fish, neovim,
|
||||
# gh, ripgrep, fd, bat, fzf, mkdocs, minio-client, locales, sudo, the
|
||||
# `tachi` user, ...). Published as `ghcr.io/zkldi/tachi-dev`.
|
||||
#
|
||||
# Always use `--no-install-recommends`. Debian's recommends-by-default pulls
|
||||
# the full LLVM/Mesa/Vulkan/GCC chain in via various transitive deps and adds
|
||||
# ~750MB of crap that nothing here actually needs.
|
||||
|
||||
FROM debian:13
|
||||
# ---------------------------------------------------------------------------
|
||||
# bun-src: just here so we can `COPY --from=` the binary into our stages.
|
||||
#
|
||||
# We deliberately track the same floating tag prod uses (see
|
||||
# `docker/Dockerfile.server`, `FROM oven/bun:alpine`). The `debian` variant
|
||||
# is used here because our base is `debian:13-slim` (glibc), not Alpine
|
||||
# (musl). If/when prod pins a specific bun version, pin this to match.
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM oven/bun:debian AS bun-src
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# base: CI image
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM debian:13-slim AS base
|
||||
|
||||
WORKDIR /tachi
|
||||
|
||||
# Add the official PostgreSQL APT repository so we can install client tools
|
||||
# that match the server version (v18). The Debian-packaged postgresql-client
|
||||
# only provides v17 on Debian 13 (trixie).
|
||||
# only provides v17 on Debian 13 (trixie). `gnupg` is only needed to dearmor
|
||||
# the keyring and is purged afterwards.
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends gnupg curl ca-certificates \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
ca-certificates curl gnupg \
|
||||
&& curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
|
||||
| gpg --dearmor -o /etc/apt/trusted.gpg.d/pgdg.gpg \
|
||||
&& echo "deb https://apt.postgresql.org/pub/repos/apt trixie-pgdg main" \
|
||||
> /etc/apt/sources.list.d/pgdg.list
|
||||
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
|
||||
&& apt-get upgrade -y \
|
||||
&& apt-get install -y \
|
||||
# essentials
|
||||
git npm locales sudo unzip jq \
|
||||
# docs pythonisms
|
||||
python-is-python3 python3-setuptools pip mkdocs mkdocs-material \
|
||||
# postgres client tools (psql, pg_dump, pg_restore, pg_isready, etc.)
|
||||
> /etc/apt/sources.list.d/pgdg.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
# essentials for running the workspace in CI
|
||||
git jq unzip just \
|
||||
# vitest spawns workers via node; bun runs vitest itself but the
|
||||
# worker subprocesses are node. With --no-install-recommends this
|
||||
# pulls libnode115 but skips npm + nodejs-doc.
|
||||
nodejs \
|
||||
# postgres client tools (psql, pg_dump, pg_restore, pg_isready, ...)
|
||||
postgresql-client-18 \
|
||||
# nice to haves
|
||||
gh fish just fzf curl wget parallel neovim fd-find bat ripgrep rsync \
|
||||
# MinIO CLI (binary is `minio-client`, not Midnight Commander's `mc`)
|
||||
minio-client \
|
||||
# uninstall lynx so people don't get a CLI browser that can't load anything when they do `gh auth login`
|
||||
&& apt-get purge -y lynx
|
||||
# rsync + ssh client for the homepage deploy job
|
||||
rsync openssh-client \
|
||||
&& apt-get purge -y gnupg \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# so apt doesn't complain about the lack of a dialog-like program
|
||||
ENV DEBIAN_FRONTEND=readline
|
||||
|
||||
# `fd` is called `fdfind` on debian. Awesome.
|
||||
RUN ln -s $(which fdfind) /usr/bin/fd
|
||||
# bun — copied from the official oven/bun image (see BUN_VERSION arg at top).
|
||||
# `bunx` is a symlink to `bun` in the upstream image; we recreate it here.
|
||||
COPY --from=bun-src /usr/local/bin/bun /usr/local/bin/bun
|
||||
RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx
|
||||
|
||||
# expose the db CLI globally
|
||||
RUN ln -sf /tachi/typescript/db-cli/src/index.ts /usr/local/bin/tachidb
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# dev: devcontainer image
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM base AS dev
|
||||
|
||||
# so apt doesn't complain about the lack of a dialog-like program
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
# shell + editor + admin
|
||||
fish neovim sudo locales \
|
||||
# search / files / network / parallel
|
||||
ripgrep fd-find bat fzf parallel wget \
|
||||
# python stack for docs work (mkdocs is run via Dockerfile.docs in CI,
|
||||
# but devs build/preview docs locally from here)
|
||||
python-is-python3 python3-pip mkdocs mkdocs-material \
|
||||
# github CLI for `gh auth login`-style flows
|
||||
gh \
|
||||
# MinIO CLI (binary is `minio-client`, not Midnight Commander's `mc`)
|
||||
minio-client \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV DEBIAN_FRONTEND=readline
|
||||
|
||||
# `fd` is called `fdfind` on debian. Awesome.
|
||||
RUN ln -s "$(which fdfind)" /usr/bin/fd
|
||||
|
||||
# setup locales
|
||||
# https://stackoverflow.com/questions/28405902/how-to-set-the-locale-inside-a-debian-ubuntu-docker-container
|
||||
RUN echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen && locale-gen
|
||||
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
|
||||
|
||||
# bun
|
||||
# TODO(zk): This will just pull a random version off
|
||||
# the internet, unpinned. There's got to be something
|
||||
# better...
|
||||
RUN curl -fsSL https://bun.sh/install | BUN_INSTALL=/usr/local bash
|
||||
|
||||
# https://github.com/python-babel/babel/issues/990
|
||||
# it wouldn't be python without needing absurd global state manipulation to fix
|
||||
# an incoherent error message
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "tachi",
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
# NOTE: bun build --compile is NOT used here because it's
|
||||
# FUCKING BROKEN
|
||||
|
||||
FROM oven/bun:alpine AS deps
|
||||
# Bun version is pinned and kept in sync with Dockerfile.dev (which uses the
|
||||
# `-debian` variant of the same tag). Bump both together.
|
||||
FROM oven/bun:1.3.14-alpine AS deps
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN bun install --frozen-lockfile
|
||||
|
||||
FROM oven/bun:alpine AS prod
|
||||
FROM oven/bun:1.3.14-alpine AS prod
|
||||
|
||||
ARG VERSION
|
||||
ARG VERSION_DETAIL
|
||||
|
||||
Reference in New Issue
Block a user