Repository navigation
177 lines (169 loc) · 8.26 KB
/
Copy pathpython-app.yml
File metadata and controls
177 lines (169 loc) · 8.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
name: Install DeGeŠ
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: astral-sh/setup-uv
uses: astral-sh/setup-uv@v9.0.0
with:
python-version: "3.14"
- name: Install dependencies
run: uv sync --dev
# **`--no-install-recommends` silently drops `dvisvgm`**, which is why it is named here --
# the Containerfile carries the same note for the same reason. Without it the HTML maths
# tests do not skip, they die in `subprocess` with `No such file or directory: 'dvisvgm'`,
# because xelatex is installed further down and the guard used to ask only about that.
#
# `poppler-utils` is `pdftocairo`, which converts every picture for the web, and
# `gnuplot-nox` draws the plots. Both were absent, so `test_picture_svg.py` skipped itself
# and CI had never once exercised the picture pipeline.
#
# `mupdf-tools` is `mutool`, and it is dvisvgm's PDF reader now. Ghostscript dropped the
# interpreter dvisvgm drove in **10.01.0**, so on a runner carrying 10.05 every `--pdf`
# run ends in `To process PDF files, either Ghostscript < 10.01.0 or mutool is required` --
# which is the whole of the HTML maths, and it surfaced the moment those tests stopped
# skipping. dvisvgm picks mutool up by itself when it finds it; `DVISVGM_PDF_PROC` forces
# the choice. Ghostscript stays -- `pdfcrop` is Ghostscript, and dvisvgm still wants it for
# PostScript specials.
- name: "Install utilities"
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
librsvg2-bin lcdf-typetools dvisvgm ghostscript mupdf-tools poppler-utils gnuplot-nox
# MathJax is the other HTML maths engine, and it is node's. A hosted runner has node
# whether or not anyone installed the packages, which is exactly how CI reported
# `Cannot find module '@mathjax/mathjax-pagella-font/package.json'` from a test that should
# have skipped; `mathjax.available()` now asks about both, and this step supplies them.
- name: "Set up node"
uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- name: "Install MathJax"
run: npm ci
# The same script a developer runs from install.sh, so CI and a workstation cannot drift onto
# different pandocs. It pins the filter, asks the binary which pandoc it was built with,
# installs exactly that one and fails if the pair still disagrees; why, and how to bump the
# pair, is in install-pandoc.sh.
- name: "Set up pandoc and pandoc-crossref"
run: |
./install-pandoc.sh
# The script installs into ~/.local/bin, which is not on a runner's PATH. It verifies
# itself by absolute path, so this is for the later steps -- pytest and make shell out
# to `pandoc` by name. $GITHUB_PATH only affects subsequent steps, hence not before.
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
# Must precede FontPro: its scripts run tex, fontinst, vptovf, pltotf, mktexlsr and
# updmap-sys, and it installs into TEXMFLOCAL. This used to work by accident, because the
# pandoc action we no longer use dragged in a TeX distribution of its own.
#
# Installed with apt directly rather than through cache-apt-pkgs-action: that action restores
# files but never runs the packages' postinst, so a restored TeX has binaries yet no
# configuration -- no updmap.cfg under /var/lib/texmf, no ls-R -- and FontPro dies in
# `updmap-sys` after minutes of work. The one CI run that ever got past FontPro was the one
# that populated the cache, i.e. actually installed.
- name: "Install XeLaTeX"
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends texlive-full texlive-fonts-extra texlive-science
updmap-sys --version | head -1
kpsewhich -var-value=TEXMFLOCAL
# FontPro fails deep inside a TeX run when a tool is absent, and the apt steps above report
# success even when a stale cache restored nothing. Fail here instead, where the step name
# alone says what happened.
- name: "Verify FontPro prerequisites"
run: |
missing=""
for tool in tex fontinst vptovf pltotf otfinfo otftotfm cfftot1 kpsewhich mktexlsr updmap-sys perl; do
command -v "$tool" >/dev/null 2>&1 || missing="$missing $tool"
done
if [ -n "$missing" ]; then
echo "::error::missing tools:$missing"
exit 1
fi
kpsewhich -var-value=TEXMFLOCAL
- name: "Clone FontPro"
uses: actions/checkout@master
with:
repository: sebschub/FontPro
path: assets/fonts/FontPro
# Split into three, so a failure is identified by the step name -- the log is not readable
# without a token, and this one takes minutes before it dies.
- name: "FontPro: build MinionPro"
run: |
cd assets/fonts/FontPro
mkdir -p otf
cp ../../fonts/MinionPro/*.otf otf/
./scripts/makeall MinionPro
- name: "FontPro: install into TEXMFLOCAL"
run: |
cd assets/fonts/FontPro
yes | sudo ./scripts/install
- name: "FontPro: enable the map file"
run: |
yes | sudo updmap-sys --enable Map=MinionPro.map
kpsewhich MinionPro.map
- name: "Set up XeLaTeX"
run: |
DIR=$(dirname $0)
TEXHOME=`kpsewhich -var-value=TEXMFHOME`
mkdir -p $TEXHOME/tex/latex/
ln -s $PWD/core/latex/dgs.cls $TEXHOME/tex/latex/dgs.cls
# A tool that is absent makes its tests *skip*, which is a green run that tested nothing --
# which is how the picture pipeline went untested here for as long as it existed. Fail at a
# named step instead, the way "Verify FontPro prerequisites" above does.
- name: "Verify the HTML output's prerequisites"
run: |
missing=""
for tool in dvisvgm mutool pdftocairo gnuplot rsvg-convert; do
command -v "$tool" >/dev/null 2>&1 || missing="$missing $tool"
done
for package in mathjax @mathjax/mathjax-pagella-font; do
test -f "node_modules/$package/package.json" || missing="$missing $package"
done
if [ -n "$missing" ]; then
echo "::error::missing:$missing"
exit 1
fi
- name: Test with pytest
run: |
uv run python -m pytest -s -v
# `source/seminar/test`, which is where `modules/seminar/editor.yaml` says this repository
# goes. It was cloned to `.../testing` while nothing read it; a scope is named after the
# directory, so the two had to agree before anything could be built by name.
- name: "Clone testing repository"
uses: actions/checkout@master
with:
repository: TrojstenSK/dgs-seminar-testing
path: source/seminar/test
# The graph before the build, as its own step. It reads the whole source tree and writes
# every edge, so a generator that crashes or emits two different edges for one output fails
# here -- named, and in under two seconds -- rather than as a confusing Ninja parse error in
# the step below.
- name: "Generate the build graph"
run: |
uv run python -m tools.ninja.generate --scope all
# One real round, end to end: Jinja, pandoc, the pictures and two xelatex passes. The scope
# is read out of the graph rather than written here, because it is this repository's own
# layout and a path typed into CI is a second copy of it that goes stale silently -- which
# is exactly what the commented-out line this replaces had done.
- name: "Build a seminar round"
run: |
set -euo pipefail
scope=$(./dgs-build -t targets all \
| sed -n 's|^output/seminar/\(.*\)/all: phony.*|\1|p' | head -1)
if [ -z "$scope" ]; then
echo "::error::no seminar round in the graph; is source/seminar/test populated?"
exit 1
fi
echo "building output/seminar/$scope/all"
./dgs-build -k 0 "output/seminar/$scope/all"