# Per-repo harbor task Dockerfile for potion-wp-site (potion-polyglot PHP member). # # HAND-AUTHORED, not generated: PHP is not a runtime kind gen-harbor-dockerfiles.ts knows, # and adding one for a single member would be a larger change than it earns. The generator # gets a new kind when a second first-party PHP member turns up; the other estates' # members are Rust/JVM/.NET/Node. Precedent: strongsuit-client and strongsuit-server are also # hand-authored and sit outside MEMBERS. # # The repo is a full WordPress 5.9.2 checkout, but the first-party code is one directory: # wp-content/themes/potion, an Automattic _s derivative with real templates, an SCSS # pipeline and JS. WordPress core and the stock plugins around it are vendored. # # What makes this member gradable without a test suite is that the theme ships genuine # deterministic offline checks, and they are the reason to bake the toolchain rather than # just the source: # composer lint:php -> php-parallel-lint across the theme # composer lint:wpcs -> phpcs against the WordPress-theme ruleset the repo commits # itself in phpcs.xml.dist # npm run lint:js -> wp-scripts lint-js over js/*.js # npm run lint:scss -> wp-scripts lint-style over sass/**/*.scss # # No database. Grading needs none: every check above is static. *Running* the site would # need MySQL plus an import of one of the two committed SQL dumps — a documented run-app # limitation, the same shape as potion-api needing Mongo, and why this member is # runtime:'none' in TOOLKIT_GROUPS rather than bootable in Explore. FROM php:8.1-cli-bookworm ARG TOOLKIT_BUILD_ID=dev # Node 16 for the theme's node-sass/wp-scripts toolchain. node-sass builds native bindings # against a specific ABI and has no prebuilt binary for current Node, so a modern major # would fail to install rather than merely warn. ENV NODE_VERSION=16.20.2 RUN apt-get update && apt-get install -y --no-install-recommends \ git curl unzip ca-certificates xz-utils libzip-dev \ && rm -rf /var/lib/apt/lists/* \ && curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-arm64.tar.xz" \ -o /tmp/node.tar.xz \ && tar -xJf /tmp/node.tar.xz -C /usr/local --strip-components=1 \ && rm /tmp/node.tar.xz \ && node --version && npm --version # Python >=3.10 for the reduced-toolset agent's str_replace_editor (dataclass kw_only). # This block used to ASSERT the base already had it, on the claim that php:8.1-bookworm # ships python3.11. It does not — the assertion failed with exit 127 (python3: not found), # so the image could not build and this member could not be graded. Install a managed # interpreter via uv, the same way every generated per-member Dockerfile does. RUN curl -fsSL https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh \ && uv python install 3.10 \ && ln -sf "$(uv python find 3.10)" /usr/local/bin/python3 \ && python3 --version # composer, pinned by installer checksum rather than piping the web to php. RUN curl -fsSL https://getcomposer.org/installer -o /tmp/composer-setup.php \ && php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer \ && rm /tmp/composer-setup.php \ && composer --version # --- Playwright + Chromium, when the task opts in ---------------------------- # Installed only when task.toml sets `[metadata] browser = true`. A Dockerfile cannot read # task.toml, so build-workspace.sh writes that answer to environment/browser-optin. # Self-contained under /opt — the member's own runtime is untouched. ENV PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright COPY browser-optin /tmp/browser-optin RUN set -eu; \ if [ "$(cat /tmp/browser-optin)" != "1" ]; then echo "browser: task did not opt in; skipping Playwright"; exit 0; fi; \ set -x; \ apt-get update -qq; \ apt-get install -y -qq --no-install-recommends \ xz-utils \ libxcomposite1 \ libxdamage1 \ libxfixes3 \ libxrandr2 \ libasound2 \ libatk1.0-0 \ libatk-bridge2.0-0 \ libatspi2.0-0 \ libcups2 \ libdbus-1-3 \ libgbm1 \ libnspr4 \ libnss3 \ libxkbcommon0 \ libpango-1.0-0 \ libcairo2 \ libxshmfence1 \ libx11-xcb1 \ libxcb-dri3-0 \ libdrm2; \ rm -rf /var/lib/apt/lists/*; \ arch="$(dpkg --print-architecture)"; \ case "$arch" in amd64) nodearch=x64;; arm64) nodearch=arm64;; *) echo "unsupported arch: $arch" >&2; exit 1;; esac; \ curl -fsSL "https://nodejs.org/dist/v20.19.5/node-v20.19.5-linux-${nodearch}.tar.xz" -o /tmp/pw-node.tar.xz; \ mkdir -p /opt/pw-node; \ tar -xJf /tmp/pw-node.tar.xz -C /opt/pw-node --strip-components=1; \ rm /tmp/pw-node.tar.xz; \ export npm_config_prefix=/opt/pw-node PATH="/opt/pw-node/bin:$PATH"; \ /opt/pw-node/bin/npm install -g playwright@1.56.0; \ test -d /opt/pw-node/lib/node_modules/playwright; \ /opt/pw-node/bin/node /opt/pw-node/lib/node_modules/playwright/cli.js install chromium; \ printf '#!/bin/sh\nNODE_PATH=/opt/pw-node/lib/node_modules exec /opt/pw-node/bin/node "$@"\n' > /usr/local/bin/pw; \ chmod +x /usr/local/bin/pw; \ printf 'const{chromium}=require("playwright");(async()=>{const b=await chromium.launch();const p=await b.newPage();await p.setContent("