# syntax=docker/dockerfile:1 # # CI test image — Python 3 + Node.js + OCaml 5.2 + dune. # # Build chain: # 1. Compile OCaml from checked-in sx_ref.ml — produces sx_server.exe # 2. Bootstrap JS (sx-browser.js) — OcamlSync transpiler → JS # 3. Re-bootstrap OCaml (sx_ref.ml) — OcamlSync transpiler → OCaml # 4. Recompile OCaml with fresh sx_ref.ml — final native binary # # Test suites (run at CMD): # - JS standard + full tests — Node # - OCaml spec tests — native binary # - OCaml bridge integration tests — Python + OCaml subprocess # # Usage: # docker build -f .gitea/Dockerfile.test -t sx-test . # docker run --rm sx-test FROM ocaml/opam:debian-12-ocaml-5.2 USER root RUN apt-get update && apt-get install -y --no-install-recommends \ python3 ca-certificates curl xz-utils \ && rm -rf /var/lib/apt/lists/* # Node.js — direct binary (avoids the massive Debian nodejs dep tree) RUN NODE_VERSION=22.22.1 \ && ARCH=$(dpkg --print-architecture | sed 's/amd64/x64/;s/arm64/arm64/;s/armhf/armv7l/') \ && curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${ARCH}.tar.xz" \ | tar -xJ --strip-components=1 -C /usr/local USER opam # Install dune into the opam switch RUN opam install dune -y # Bake the opam switch PATH into the image so dune/ocamlfind work in RUN ENV PATH="/home/opam/.opam/5.2/bin:${PATH}" WORKDIR /home/opam/project # Copy OCaml sources first (changes less often → better caching) COPY --chown=opam:opam hosts/ocaml/dune-project ./hosts/ocaml/ COPY --chown=opam:opam hosts/ocaml/lib/ ./hosts/ocaml/lib/ COPY --chown=opam:opam hosts/ocaml/bin/ ./hosts/ocaml/bin/ # Copy spec, lib, web, shared (needed by bootstrappers + tests) COPY --chown=opam:opam spec/ ./spec/ COPY --chown=opam:opam lib/ ./lib/ COPY --chown=opam:opam web/ ./web/ COPY --chown=opam:opam shared/sx/ ./shared/sx/ COPY --chown=opam:opam shared/__init__.py ./shared/__init__.py # Copy JS host (bootstrapper + test runner) COPY --chown=opam:opam hosts/javascript/ ./hosts/javascript/ # Copy OCaml host (bootstrapper + transpiler) COPY --chown=opam:opam hosts/ocaml/bootstrap.py ./hosts/ocaml/bootstrap.py COPY --chown=opam:opam hosts/ocaml/transpiler.sx ./hosts/ocaml/transpiler.sx # Create output directory for JS builds RUN mkdir -p shared/static/scripts # Step 1: Compile OCaml from checked-in sx_ref.ml # → produces sx_server.exe (needed by both JS and OCaml bootstrappers) RUN cd hosts/ocaml && dune build # Step 2: Bootstrap JS (uses sx_server.exe via OcamlSync) RUN python3 hosts/javascript/cli.py \ --output shared/static/scripts/sx-browser.js \ && python3 hosts/javascript/cli.py \ --extensions continuations --spec-modules types \ --output shared/static/scripts/sx-full-test.js # Step 3: Re-bootstrap OCaml (transpile current spec → fresh sx_ref.ml) RUN python3 hosts/ocaml/bootstrap.py \ --output hosts/ocaml/lib/sx_ref.ml # Step 4: Recompile OCaml with freshly bootstrapped sx_ref.ml RUN cd hosts/ocaml && dune build # Default: run all tests COPY --chown=opam:opam .gitea/run-ci-tests.sh ./run-ci-tests.sh RUN chmod +x run-ci-tests.sh CMD ["./run-ci-tests.sh"]