# Job container image for forgejo-runner. Adds yarn (classic) on top of
# catthehacker's runner-22.04 so Node-based workflows using
# `actions/setup-node@v4` with `cache: 'yarn'` work out of the box.
#
# Built locally by setup.sh and tagged forgejo-stack/job:latest. Override the
# tag via RUNNER_JOB_IMAGE in .env if you want a different base.
FROM ghcr.io/catthehacker/ubuntu:runner-22.04

USER root

# corepack ships with node; activate yarn 1.x (classic) into the toolcache so
# every uid in the container has it on PATH. The toolcache lives under
# /opt/acttoolcache and is root-owned, so this has to run before USER switches.
RUN corepack enable \
 && corepack prepare yarn@1.22.22 --activate \
 && yarn --version

# Preinstall Playwright system deps (chromium + webkit) so the per-job
# `npx playwright install-deps` step short-circuits — it still runs in the
# workflow but finds every package present and exits in <1s instead of
# fetching the apt index and apt-installing. Browser binaries themselves
# stay out of the image (version-pinned to the consumer project; cached via
# actions/cache).
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive npx --yes playwright@latest install-deps chromium webkit \
 && rm -rf /var/lib/apt/lists/*

# Pre-stage Node 22 in AGENT_TOOLSDIRECTORY so actions/setup-node@v4 finds it
# locally and skips the ~30s nodejs.org download every job. Layout matches
# @actions/tool-cache:
#   /opt/hostedtoolcache/node/<version>/x64/   ← extracted tarball
#   /opt/hostedtoolcache/node/<version>/x64.complete   ← sentinel
# Bump NODE_VERSION when upstream LTS moves.
ARG NODE_VERSION=22.22.3
RUN mkdir -p /opt/hostedtoolcache/node/${NODE_VERSION}/x64 \
 && curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" \
  | tar -xJ --strip-components=1 -C /opt/hostedtoolcache/node/${NODE_VERSION}/x64 \
 && touch /opt/hostedtoolcache/node/${NODE_VERSION}/x64.complete \
 && chmod -R a+rX /opt/hostedtoolcache

# Centralised yarn cache. setup-node@v4's `cache: 'yarn'` reads `yarn cache
# dir`, which honors YARN_CACHE_FOLDER — so this is where both the optional
# pre-warm below AND runtime yarn invocations read/write. Persisting it via
# the shared toolcache volume isn't strictly needed once the image is baked,
# but workflows that add deps still benefit from the in-image starting point.
ENV YARN_CACHE_FOLDER=/opt/forgejo-stack/yarn-cache

# Optional yarn classic offline-cache pre-warm. Drop yarn.lock + package.json
# (and any .yarnrc your workflow relies on) into runner-image/cache-seed/
# before building; the entire yarn cache for that lockfile gets baked into
# the image and made world-readable. With no seed files present this step is
# a no-op. Two COPYs because Docker requires the destination directory to
# exist before the per-file COPY can be conditional on globbing.
RUN mkdir -p /opt/forgejo-stack/cache-seed
COPY cache-seed/ /opt/forgejo-stack/cache-seed/
RUN if [ -f /opt/forgejo-stack/cache-seed/yarn.lock ] \
    && [ -f /opt/forgejo-stack/cache-seed/package.json ]; then \
      cd /opt/forgejo-stack/cache-seed \
      && export PATH="/opt/hostedtoolcache/node/${NODE_VERSION}/x64/bin:$PATH" \
      && corepack prepare yarn@1.22.22 --activate >/dev/null \
      && yarn install --frozen-lockfile --non-interactive --ignore-scripts --no-bin-links \
      && rm -rf node_modules \
      && chmod -R a+rX "$YARN_CACHE_FOLDER" ; \
    fi \
 && rm -rf /opt/forgejo-stack/cache-seed
