[WIP] Rehaul CI to run examples and generate artifacts again (#562)

This commit is contained in:
Louis Gesbert 2024-01-19 18:34:24 +01:00 committed by GitHub
commit c336a7bb62
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 270 additions and 201 deletions

173
.github/workflows/harness.yml vendored Normal file
View File

@ -0,0 +1,173 @@
name: CI
on:
push:
branches: [master]
pull_request:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
name: Build Catala and generate image
runs-on: self-hosted
permissions:
packages: write
outputs:
image: ghcr.io/catalalang/catala@${{ steps.image.outputs.digest }}
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Make build context image
uses: docker/build-push-action@v5
with:
target: dev-build-context
# Caching using GH cache doesn't work, use registry caching directly
# instead
cache-from: type=registry,ref=ghcr.io/catalalang/catala:dev-cache
cache-to: type=registry,ref=ghcr.io/catalalang/catala:dev-cache,mode=max
- name: Build and push
id: image
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/catalalang/catala:${{ github.run_id }}
labels: org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
cache-from: type=registry,ref=ghcr.io/catalalang/catala:build-cache
cache-to: type=registry,ref=ghcr.io/catalalang/catala:build-cache,mode=max
tests:
name: Run integrated tests
needs: build
runs-on: self-hosted
container:
image: ${{ needs.build.outputs.image }}
options: --user ocaml
steps:
- name: Run tests
run: cd /home/ocaml/catala && opam exec -- make tests
- name: Check promoted files
if: ${{ always() }}
run: cd /home/ocaml/catala && opam exec -- make check-promoted
examples:
name: Build examples and generate artifacts
needs: build
runs-on: self-hosted
container:
image: ${{ needs.build.outputs.image }}
options: --user ocaml
env:
DUNE_PROFILE: release
steps:
- name: Fix home
# Workaround Github actions issue, see
# https://github.com/actions/runner/issues/863
run: sudo sh -c "echo HOME=/home/ocaml >> ${GITHUB_ENV}"
- name: Install LaTeX deps
# This is done late because caching would not benefit compared to
# installation through apk (1,5G upload is slow)
run: sudo apk add texlive-xetex texmf-dist-latexextra texmf-dist-pictures font-dejavu groff
- name: Build Catala extra docs
run: |
cd ~/catala
opam --cli=2.1 exec -- make syntax
opam --cli=2.1 exec -- make doc
- name: Checkout examples repo
# Github fetch action is expected to work for containers, but doesn't
# (permission issues)
run: git clone https://github.com/CatalaLang/catala-examples --depth 1 ~/catala-examples
- name: Build examples
run: cd ~/catala-examples && opam --cli=2.1 exec -- make build install
- name: Checkout french-law repo
run: git clone https://github.com/CatalaLang/french-law --depth 1 ~/french-law
- name: Build french-law
run: |
cd ~/french-law
opam --cli=2.1 exec -- make dependencies
opam --cli=2.1 exec -- make all
- name: Gather all artifacts
run: |
cd
mkdir -p artifacts
cp catala/_build/install/default/bin/catala.js artifacts/catala_'"${RELEASE_TAG}"'_node.js
mv catala/_build/default/_doc/_html artifacts/api-doc
mv catala/doc/syntax/syntax.pdf artifacts/
mv catala/_build/default/*.html artifacts/
mv ~/.opam/catala/doc/catala-examples/tuto*/*.html artifacts/
tar czf artifacts/french_law_'"${RELEASE_TAG}"'_ocaml.tar.gz french-law/ocaml
tar czf artifacts/french_law_'"${RELEASE_TAG}"'_js.tar.gz french-law/js
tar czf artifacts/french_law_'"${RELEASE_TAG}"'_python.tar.gz french-law/python
ln -s french_law_'"${RELEASE_TAG}"'_ocaml.tar.gz artifacts/french_law_ocaml.tar.gz
ln -s french_law_'"${RELEASE_TAG}"'_js.tar.gz artifacts/french_law_js.tar.gz
ln -s french_law_'"${RELEASE_TAG}"'_python.tar.gz artifacts/french_law_python.tar.gz
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: Catala examples
path: artifacts/*
binaries:
name: Build static binaries
runs-on: self-hosted
if: github.ref == 'refs/heads/master'
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Build release binaries
run: mkdir -p artifacts && ./build_release.sh -C artifacts
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: Catala binaries
path: artifacts/*
pages:
name: Publish static content to github-pages
needs: [ examples, binaries, tests ]
# Doesn't really depend on tests, but we don't want to publish if they fail
if: github.ref == 'refs/heads/master'
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Download artifacts
uses: actions/download-artifact@v4
with:
merge-multiple: true
path: artifacts/
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: tree
version: 1.0
- name: Generate HTML index
run: |
cd artifacts
tree -H . -L 1 --noreport --dirsfirst -T 'Catala latest development artifacts' --charset utf-8 -o index.html
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
path: 'artifacts/'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1

View File

@ -1,59 +0,0 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages
on:
workflow_run:
workflows: ["Harness"]
branches: [master]
types:
- completed
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
# Single deploy job since we're just deploying
deploy:
# Don't run if test harness failed
if: ${{ github.event.workflow_run.conclusion == 'success' }}
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Download build artifacts
# Not the default gh download-artifact action, which doesn't work
# between workflows
uses: dawidd6/action-download-artifact@v2
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: Catala artifacts
path: artifacts/
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: tree
version: 1.0
- name: Generate HTML index
run: |
cd artifacts
tree -H . -L 1 --noreport --dirsfirst -T 'Catala latest development artifacts' --charset utf-8 -o index.html
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
path: 'artifacts/'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1

View File

@ -1,65 +0,0 @@
name: Harness
on:
push:
branches: [master]
pull_request:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
run-make-all:
# The type of runner that the job will run on
runs-on: self-hosted
env:
IMAGE_TAG: ${{ github.head_ref || github.ref_name }}
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Prepare container with all dependencies
run: git archive HEAD | docker build - --target dev-build-context
- name: Escape chars in IMAGE_TAG (to avoid Docker issues)
run: sed 's/[^a-zA-Z0-9-]/-/g; s/^/IMAGE_TAG=/' <<<"${IMAGE_TAG}" >> $GITHUB_ENV
- name: Run builds, checks and tests
run: git archive HEAD | docker build - --force-rm -t "catalalang/catala-build:${IMAGE_TAG}"
- name: Cleanup Docker image
if: ${{ github.ref != 'refs/heads/master' }}
run: docker image rm catalalang/catala-build:${IMAGE_TAG}
- name: Build architecture-independent artifacts
if: ${{ github.ref == 'refs/heads/master' }}
run: |
RELEASE_TAG=$(git describe --tags)
docker run --rm catalalang/catala-build:${IMAGE_TAG} sh -uexc '
opam --cli=2.1 remove z3 >&2
opam --cli=2.1 exec -- dune build --profile=release french_law compiler/catala.bc.js >&2
opam --cli=2.1 exec -- dune build --profile=release @doc >&2
sudo apk add font-dejavu >&2
opam --cli=2.1 exec -- make -C doc/syntax >&2
opam --cli=2.1 exec -- make literate_tutorial_en literate_tutoriel_fr >&2
opam --cli=2.1 exec -- dune build --profile=release grammar.html catala.html clerk.html >&2
mkdir -p artifacts >&2
mv _build/default/compiler/catala.bc.js artifacts/catala_'"${RELEASE_TAG}"'_node.js >&2
mv _build/default/_doc/_html artifacts/api-doc >&2
mv doc/syntax/syntax.pdf artifacts/ >&2
mv examples/tuto*/*.html _build/default/*.html artifacts/ >&2
tar czf artifacts/french_law_'"${RELEASE_TAG}"'_ocaml.tar.gz french_law/ocaml >&2
tar czf artifacts/french_law_'"${RELEASE_TAG}"'_js.tar.gz french_law/js --exclude french_law/js/node_modules >&2
tar czf artifacts/french_law_'"${RELEASE_TAG}"'_python.tar.gz french_law/python >&2
ln -s french_law_'"${RELEASE_TAG}"'_ocaml.tar.gz artifacts/french_law_ocaml.tar.gz >&2
ln -s french_law_'"${RELEASE_TAG}"'_js.tar.gz artifacts/french_law_js.tar.gz >&2
ln -s french_law_'"${RELEASE_TAG}"'_python.tar.gz artifacts/french_law_python.tar.gz >&2
tar c artifacts/*
' | tar vx
- name: Build static binaries
if: ${{ github.ref == 'refs/heads/master' }}
run: ./build_release.sh -C artifacts
- name: Publish artifacts
if: ${{ github.ref == 'refs/heads/master' }}
uses: actions/upload-artifact@v3
with:
name: Catala artifacts
path: artifacts/*

View File

@ -21,10 +21,10 @@ distributed under the Apache2 license.
Before writing Catala code, please read the
[tutorial](https://catala-lang.org/en/examples/tutorial). You can run the
programs of the tutorial yourself by following the instruction in the
[README of the `examples` directory](examples/README.md). Then, it is suggested
that you create a new example directory again according to the instructions of
this README.
programs of the tutorial yourself by following the instruction in the [README of
the `examples` repository](https://github.com/CatalaLang/catala-examples/README.md).
Then, it is suggested that you create a new example directory again according to
the instructions of this README.
Let us now present the typical Catala workflow. First, you need to locate
the legislative text that you want to use as a reference. Then, simply
@ -77,9 +77,11 @@ declaration structure FooBar:
```
````
Again, make sure to regularly check that your example is parsing correctly. The error message from the compiler should help you debug the syntax if need be. You can also
live-test the programs you wrote by feeding them to the interpreter
(see the [README of the `examples` directory](examples/README.md)); this will
Again, make sure to regularly check that your example is parsing correctly. The
error message from the compiler should help you debug the syntax if need be. You
can also live-test the programs you wrote by feeding them to the interpreter
(see the [README of the `examples`
repository](https://github.com/CatalaLang/catala-examples/README.md)); this will
also type-check the programs, which is useful for debugging them.
## Working on the compiler

View File

@ -26,34 +26,27 @@ RUN opam --cli=2.1 switch create catala ocaml-system && \
# should be enough once opam 2.2 is released (see opam#5185)
#
# STAGE 2: get the whole repo, run checks and builds
# STAGE 2: get the whole repo and build
#
FROM dev-build-context
# Prepare extra local dependencies (doing this first allows caching)
ADD --chown=ocaml:ocaml runtimes/python/pyproject.toml runtimes/python/pyproject.toml
ADD --chown=ocaml:ocaml Makefile .
ADD --chown=ocaml:ocaml syntax_highlighting syntax_highlighting
RUN opam exec -- make dependencies-python pygments
# Get the full repo
ADD --chown=ocaml:ocaml . .
# Prepare extra local dependencies
RUN opam exec -- make dependencies-python pygments
# OCaml backtraces may be useful on failure
ENV OCAMLRUNPARAM=b
# Make sure warnings are treated as errors (variable used in Makefile, profile
# defined in ./dune)
ENV DUNE_PROFILE=check
# Check promoted files (but delay failure)
RUN opam exec -- make check-promoted > promotion.out 2>&1 || touch bad-promote
# Check the build
RUN opam exec -- make build
RUN opam exec -- make build js_build
# Check tests & all alt targets
RUN OCAMLRUNPARAM=b opam exec -- make all -B
# Forward results of promotion check
RUN if [ -e bad-promote ]; then \
echo "[ERROR] Some promoted files were not up-to-date"; \
cat promotion.out; \
exit 1; \
fi
# Install to prefix
RUN opam exec -- make install

View File

@ -88,8 +88,7 @@ build: parser-messages format build_dev
#> js_build : Builds the Web-compatible JS versions of the Catala compiler
js_build:
dune build $(COMPILER_DIR)/catala.bc.js
dune build $(COMPILER_DIR)/catala_web_interpreter.bc.js
dune build $(COMPILER_DIR)/catala.bc.js $(COMPILER_DIR)/catala_web_interpreter.bc.js
#> doc : Generates the HTML OCaml documentation
doc:
@ -180,6 +179,7 @@ vscode: vscode_fr vscode_en
# Extra documentation
##########################################
#> syntax : Buils syntax sheet (requires latexmk and dejavu fonts)
syntax:
$(MAKE) -C doc/syntax
@ -199,8 +199,11 @@ CLERK=$(CLERK_BIN) --exe $(CATALA_BIN) \
.FORCE:
unit-tests: .FORCE
dune runtest
#> tests : Run interpreter tests
tests: .FORCE prepare-install
tests: .FORCE prepare-install unit-tests
@$(MAKE) -C tests pass_all_tests
tests/%: .FORCE
@ -210,6 +213,8 @@ tests/%: .FORCE
# Website assets
##########################################
# Note: these are already built by the @doc dune alias
# (and therefore the doc target here)
WEBSITE_ASSETS = grammar.html catala.html clerk.html
$(addprefix _build/default/,$(WEBSITE_ASSETS)):
@ -231,8 +236,7 @@ all: \
build js_build doc \
tests \
runtimes \
plugins \
website-assets-base
plugins
#> clean : Clean build artifacts

View File

@ -185,7 +185,7 @@ to generate the documentation, then open the `doc/odoc.html` file in any browser
## Examples
To explore the different programs written in Catala, see
[the dedicated readme](examples/README.md).
[the dedicated readme](https://github.com/CatalaLang/catala-examples/README.md).
## API

View File

@ -26,13 +26,13 @@ CUSTOM_LINKING_CATALA_NOZ3="(-cclib -static -cclib -no-pie)"
CUSTOM_LINKING_CLERK="(-cclib -static -cclib -no-pie)"
git archive HEAD --prefix catala/ | \
docker run --rm -i registry.gitlab.inria.fr/lgesbert/catala-ci-images:ocaml.4.14-z3static.4.11.2 \
docker run --rm -i registry.gitlab.inria.fr/verifisc/docker-catala:ocaml.4.14-z3static.4.11.2 \
sh -uexc \
'{ tar x &&
cd catala &&
echo "'"${CUSTOM_LINKING_CATALA_Z3}"'" >compiler/custom_linking.sexp &&
echo "'"${CUSTOM_LINKING_CLERK}"'" >build_system/custom_linking.sexp &&
opam --cli=2.1 install ./ninja_utils.opam ./clerk.opam ./catala.opam --destdir ../release.out/ &&
opam --cli=2.1 install ./catala.opam --destdir ../release.out/ &&
mv ../release.out/bin/catala ../release.out/bin/catala-z3 &&
opam --cli=2.1 remove z3 catala &&
echo "'"${CUSTOM_LINKING_CATALA_NOZ3}"'" >compiler/custom_linking.sexp &&

View File

@ -256,7 +256,10 @@ module Poll = struct
let catala_project_root : File.t option Lazy.t =
lazy
(match Lazy.force project_root with
| Some root when Sys.file_exists File.(root / "catala.opam") -> Some root
| Some root
when Sys.file_exists File.(root / "catala.opam")
&& Sys.file_exists File.(root / "dune-project") ->
Some root
| _ -> None)
let exec_dir : File.t =
@ -337,9 +340,10 @@ module Poll = struct
dir
| None ->
Message.raise_error
"@[<hov>Could not locate the Catala runtime library.@ Make sure \
that either catala is correctly installed,@ or you are running \
from the root of a compiled source tree.@]")
"@[<hov>Could not locate the Catala runtime library at %s.@ Make \
sure that either catala is correctly installed,@ or you are \
running from the root of a compiled source tree.@]"
d)
let ocaml_link_flags : string list Lazy.t =
lazy
@ -712,7 +716,7 @@ let gen_build_statements
reset but that shouldn't cause trouble. *)
Nj.build "post-test" ~inputs:[reference; test_out]
~implicit_in:["always"]
~outputs:[reference ^ "@post"]
~outputs:[(!Var.builddir / reference) ^ "@post"]
:: acc)
[] item.legacy_tests
in
@ -740,7 +744,8 @@ let gen_build_statements
~implicit_in:
("always"
:: List.map
(fun test -> legacy_test_reference test ^ "@post")
(fun test ->
(!Var.builddir / legacy_test_reference test) ^ "@post")
item.legacy_tests);
results;
]
@ -751,7 +756,8 @@ let gen_build_statements
~implicit_out:[srcv ^ "@test"]
~inputs:
(List.map
(fun test -> legacy_test_reference test ^ "@post")
(fun test ->
(!Var.builddir / legacy_test_reference test) ^ "@post")
item.legacy_tests);
results;
]

View File

@ -75,10 +75,14 @@ build: [
]
dev-repo: "git+https://github.com/CatalaLang/catala.git"
depexts: [
["groff" "latexmk" "python3-pip" "pandoc"]
["groff"] { with-doc }
["python3-pip" "pandoc"]
# "latexmk"
{cataladevmode & os-family = "debian"}
["groff" "texlive-xetex" "texmf-dist-latexextra" "texmf-dist-pictures" "py3-pip" "py3-pygments" "pandoc-cli"]
["py3-pip" "py3-pygments" "pandoc-cli"]
# "texlive-xetex" "texmf-dist-latexextra" "texmf-dist-pictures"
{cataladevmode & os-distribution = "alpine"}
["groff" "latex-mk" "python-pygments" "pandoc"]
["python-pygments" "pandoc"]
# "latex-mk"
{cataladevmode & os-family = "arch"}
]

View File

@ -17,8 +17,6 @@
(executable
(name catala_web_interpreter)
(modes byte js)
(package catala)
(public_name catala_web_interpreter)
(modules catala_web_interpreter)
(preprocess
(pps js_of_ocaml-ppx))
@ -28,11 +26,21 @@
catala.runtime_ocaml
catala.runtime_jsoo))
(install
(section bin)
(package catala)
(files (catala_web_interpreter.bc.js as catala_web_interpreter)))
(executable
(name tests)
(modules tests)
(libraries catala.driver alcotest))
(install
(section bin)
(package catala)
(files (catala.bc.js as catala.js)))
(rule
(target custom_linking.sexp)
(mode fallback)

View File

@ -324,12 +324,12 @@ let test_iota_reduction_1 () =
let matchA = Expr.ematch ~e:injA ~name:enumT ~cases nomark in
Alcotest.(check string)
"same string"
"before=match (A x)\n\
\ with\n\
\ | A (λ (x: any) C x)\n\
\ | B (λ (x: any) D x)\n\
after=C\n\
x"
begin[@ocamlformat "disable"]
"before=match (A x) with\n\
\ | A x C x\n\
\ | B x D x\n\
after=C x"
end
(Format.asprintf "before=%a\nafter=%a" Expr.format (Expr.unbox matchA)
Expr.format
(Expr.unbox (optimize_expr Program.empty_ctx (Expr.unbox matchA))))
@ -382,18 +382,16 @@ let test_iota_reduction_2 () =
in
Alcotest.(check string)
"same string "
"before=match\n\
\ (match 1\n\
\ with\n\
\ | A (λ (x: any) A 20)\n\
\ | B (λ (x: any) B B x))\n\
\ with\n\
\ | A (λ (x: any) C x)\n\
\ | B (λ (x: any) D x)\n\
after=match 1\n\
\ with\n\
\ | A (λ (x: any) C 20)\n\
\ | B (λ (x: any) D B x)\n"
begin[@ocamlformat "disable"]
"before=match (match 1 with\n\
\ | A x A 20\n\
\ | B x B (B x)) with\n\
\ | A x C x\n\
\ | B x D x\n\
after=match 1 with\n\
\ | A x C 20\n\
\ | B x D B x"
end
(Format.asprintf "before=@[%a@]@.after=%a@." Expr.format (Expr.unbox matchA)
Expr.format
(Expr.unbox (optimize_expr Program.empty_ctx (Expr.unbox matchA))))

View File

@ -5,6 +5,7 @@ let () =
( "Iota-reduction",
[
test_case "#1" `Quick Shared_ast.Optimizations.test_iota_reduction_1;
test_case "#2" `Quick Shared_ast.Optimizations.test_iota_reduction_2;
(* test_case "#2" `Quick
Shared_ast.Optimizations.test_iota_reduction_2; FIXME *)
] );
]

22
dune
View File

@ -2,7 +2,9 @@
(data_only_dirs tests syntax_highlighting)
(copy_files compiler/surface/grammar.html)
(copy_files
(alias doc)
(files compiler/surface/grammar.html))
; Override dune default warnings with sane settings
@ -29,6 +31,7 @@
-a))))
(rule
(alias doc)
(action
(with-stdout-to
catala.html
@ -37,6 +40,7 @@
(run groff -P -l -P -r -mandoc -Thtml)))))
(rule
(alias doc)
(action
(with-stdout-to
clerk.html
@ -48,10 +52,12 @@
(name exec)
(deps compiler/catala.exe build_system/clerk.exe))
(rule
(alias runtest)
(package catala)
(deps
(source_tree tests))
(action
(run clerk --exe %{bin:catala} test tests)))
;; This garbles Clerk output, prefer to run from Makefile
;; (rule
;; (alias runtest)
;; (package catala)
;; (deps
;; (source_tree tests)
;; (alias install))
;; (action
;; (run %{bin:clerk} test --exe %{bin:catala} tests)))

View File

View File

@ -5,20 +5,18 @@
CATALA_OPTS?=
CLERK_OPTS?=--makeflags="$(MAKEFLAGS)"
CLERK=_build/default/build_system/clerk.exe test --exe "_build/default/compiler/catala.exe" \
CLERK=dune exec -- ../build_system/clerk.exe test \
$(CLERK_OPTS) $(if $(CATALA_OPTS),--catala-opts=$(CATALA_OPTS),)
# Forces all the tests to be redone
.FORCE:
%.catala_en %.catala_fr %.catala_pl: .FORCE
# Here we cd to the root of the Catala repository such that the paths \
# displayed in error messages start with `tests/` uniformly.
@cd ..; $(CLERK) tests/$@
$(CLERK) $@
pass_all_tests:
@cd ..; $(CLERK) tests
$(CLERK) .
reset_all_tests: CLERK_OPTS+=--reset
reset_all_tests:
@cd ..; $(CLERK) tests
$(CLERK) .