# foundation-ci — the baked CI toolchain image (T14). # # A single, pinnable image carrying every tool the foundation's own pipelines need # so jobs don't install a toolchain on each run. Referenced by .forgejo/workflows/* # via `container: foundation-ci:`. Built on the VM (like caddy-cloudflare) and # used locally by the runner (force_pull:false) — see runner.ts / VERSIONS IMAGE_CI. # # Carries exactly what preflight/checks/tools.sh validates: pulumi, bun, node, # docker (cli), git, age, zstd, jq, vault, psql, pg_dump, ssh, mc — plus pass-free # operation (PULUMI_CONFIG_PASSPHRASE + SSH key arrive as CI secrets/env). FROM node:20-bookworm # Pulumi >= 3.149 is required: the project pins `packagemanager: bun` # (bootstrap/Pulumi.yaml) and older CLIs reject "bun" as an unknown package # manager. Matches the operator's CLI line for preview parity (TOOL_PULUMI_MIN). ARG PULUMI_VERSION=3.243.0 ARG VAULT_VERSION=1.18.5 ARG MC_RELEASE=RELEASE.2025-04-03T17-07-56Z ARG TARGETARCH=amd64 ENV DEBIAN_FRONTEND=noninteractive # Install pulumi + bun into /usr/local/bin so they're on PATH for ANY shell/user # (a login shell resets PATH, and jobs may not run as root). ENV BUN_INSTALL=/usr/local # --- base apt tools: git, ssh, age, zstd, jq, postgresql-client, docker CLI ---------- RUN set -eux; \ install -m 0755 -d /etc/apt/keyrings; \ apt-get update; \ apt-get install -y --no-install-recommends \ ca-certificates curl gnupg lsb-release unzip \ git openssh-client age zstd jq; \ # docker CE CLI (jobs build/push images via the mounted host socket) curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc; \ chmod a+r /etc/apt/keyrings/docker.asc; \ echo "deb [arch=$TARGETARCH signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" > /etc/apt/sources.list.d/docker.list; \ # postgresql-client 15 (psql + pg_dump) from pgdg curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/keyrings/pgdg.gpg; \ echo "deb [signed-by=/etc/apt/keyrings/pgdg.gpg] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" > /etc/apt/sources.list.d/pgdg.list; \ apt-get update; \ apt-get install -y --no-install-recommends docker-ce-cli postgresql-client-16; \ rm -rf /var/lib/apt/lists/* # --- pulumi (pinned) → copy binaries to /usr/local/bin ------------------------------- RUN set -eux; curl -fsSL https://get.pulumi.com | sh -s -- --version "$PULUMI_VERSION"; \ cp /root/.pulumi/bin/* /usr/local/bin/; rm -rf /root/.pulumi; \ pulumi version # --- bun (pinned via official installer; BUN_INSTALL=/usr/local) --------------------- RUN set -eux; curl -fsSL https://bun.sh/install | bash; bun --version # --- vault CLI (pinned) -------------------------------------------------------------- RUN set -eux; \ curl -fsSL "https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_${TARGETARCH}.zip" -o /tmp/vault.zip; \ unzip -d /usr/local/bin /tmp/vault.zip; rm -f /tmp/vault.zip; vault --version # --- minio client mc (pinned release) ------------------------------------------------ RUN set -eux; \ curl -fsSL "https://dl.min.io/client/mc/release/linux-${TARGETARCH}/archive/mc.${MC_RELEASE}" -o /usr/local/bin/mc; \ chmod +x /usr/local/bin/mc; mc --version # --- ecosystem CI toolchain (999_testing): linters + release tooling ----------------- # shellcheck + yamllint from apt; eslint + semantic-release as pinned global npm installs # so the reusable lint/semantic-release workflows have a toolchain even for projects that # do not vendor their own (projects MAY still `bunx`/`npx` a pinned local version, which # wins). NOT part of preflight's `up`-gating tool set — these are job tools, not deploy # tools — but pinned in VERSIONS for traceability. ARG ESLINT_VERSION=9.18.0 ARG SEMANTIC_RELEASE_VERSION=24.2.3 RUN set -eux; \ apt-get update; \ apt-get install -y --no-install-recommends shellcheck yamllint; \ rm -rf /var/lib/apt/lists/*; \ shellcheck --version; yamllint --version # semantic-release + the plugin set Olsitec's release config uses (olsitec/gitlab # ci_templates/release-automation/semantic-release.yaml): the conventionalcommits # PRESET (not bundled) drives the releaseRules; git/changelog support real releases. # Installed in the SAME global root so semantic-release resolves them by name. RUN set -eux; \ npm install -g \ "eslint@${ESLINT_VERSION}" \ "semantic-release@${SEMANTIC_RELEASE_VERSION}" \ conventional-changelog-conventionalcommits@8.0.0 \ @semantic-release/git@10.0.1 \ @semantic-release/changelog@6.0.3; \ eslint --version; semantic-release --version # Forgejo Actions overrides the entrypoint with its job script; keep a sane default. WORKDIR /workspace CMD ["bash"]