docs: write for a reader who is not a programmer #42
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: test | |
| # release.yml runs this through workflow_call, so a tag cannot publish | |
| # something the suite has not passed. It has to be a call and not a | |
| # dependency: `needs` only names jobs within one workflow, so a release job | |
| # cannot wait on a job declared over here. | |
| on: | |
| push: | |
| branches: [master] | |
| pull_request: | |
| workflow_dispatch: | |
| workflow_call: | |
| # A release pushes master and then its tag, seconds apart, and the tag names | |
| # the commit master's head already is. Both pushes land here, so without the | |
| # condition below the suite covers one tree twice, six jobs to say what three | |
| # say. The tag's run is the one release.yml waits on before it publishes, so | |
| # the branch push is the half to drop, and only for the commit release.py | |
| # writes. | |
| # | |
| # By the ref, and not by cancelling a run in flight. A concurrency group would | |
| # have the two races to see which cancels which, and losing that race takes the | |
| # release job down with the suite it needs. | |
| # | |
| # The subject is spelled out in both jobs below. A job's `if` cannot read the | |
| # `env` context, so there is nowhere above them to put it once. It is written | |
| # by release.py in fb2xt, as `chore(release): {tag}`. | |
| jobs: | |
| test: | |
| # A tag always runs it: refs/tags is where the gate lives. So does any | |
| # branch push whose head is not a release commit, and every pull request | |
| # and dispatch, where head_commit is absent and reads as empty. | |
| if: >- | |
| startsWith(github.ref, 'refs/tags/') | |
| || !startsWith(github.event.head_commit.message, 'chore(release): ') | |
| strategy: | |
| # Both, always. One of them going red is the interesting case, and | |
| # stopping the other run is how that gets read as a fluke. | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Forward slashes on both: these reach a bash `test` as well as | |
| # Python, and a backslash does not survive the first of those. | |
| - os: ubuntu-latest | |
| font: /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf | |
| italic: /usr/share/fonts/truetype/dejavu/DejaVuSans-Oblique.ttf | |
| - os: windows-latest | |
| font: C:/Windows/Fonts/arial.ttf | |
| italic: C:/Windows/Fonts/ariali.ttf | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| # git normalizes nothing in the wrappers, so a checkout carries whatever | |
| # was committed. What this catches is an editor that flattened one half | |
| # of the polyglot, which breaks the interpreter nobody who did it runs. | |
| - name: The wrappers kept their line endings | |
| shell: bash | |
| run: sh tools/check-line-endings.sh | |
| # A third of the suite reads a real face and skips without one, silently. | |
| # A runner image that stopped shipping this font would otherwise leave a | |
| # green run that says nothing at all about rendering. | |
| - name: The faces the suite needs are here | |
| shell: bash | |
| run: test -f "${{ matrix.font }}" && test -f "${{ matrix.italic }}" | |
| # Through the wrapper rather than a setup action, which is what a user | |
| # runs: every CI run then verifies the pinned uv against its checksum on | |
| # both platforms, and .python-version puts it on the interpreter this | |
| # release was built and tested against. | |
| # | |
| # -rs prints what skipped. CROSSGLYPH_TEST_OTF wants a CFF face with | |
| # ligatures and a pnum feature, which neither image ships, so those stay | |
| # skipped here and are named in the log rather than passing unnoticed. | |
| - name: The suite | |
| run: tools/uv.cmd run pytest -n auto -q -rs | |
| env: | |
| CROSSGLYPH_TEST_FONT: ${{ matrix.font }} | |
| CROSSGLYPH_TEST_ITALIC: ${{ matrix.italic }} | |
| # The page has no browser test. This links its modules against a stub DOM | |
| # and is where a module reading a name it never imported fails. | |
| - name: The page | |
| run: node --experimental-vm-modules tests/preview_persistence.mjs | |
| container: | |
| # As above: the tag's run covers this commit, so the branch push skips it. | |
| if: >- | |
| startsWith(github.ref, 'refs/tags/') | |
| || !startsWith(github.event.head_commit.message, 'chore(release): ') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Build the container image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| load: true | |
| tags: crossglyph:test | |
| - name: Run the preview and a command-line build | |
| shell: bash | |
| run: | | |
| workspace="$(mktemp -d)" | |
| trap 'docker rm -f crossglyph-smoke >/dev/null 2>&1 || true; rm -rf "$workspace"' EXIT | |
| mkdir "$workspace/conf" | |
| cp /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf "$workspace/" | |
| printf 'fallbacks = no\nsizes = 12\n' >"$workspace/conf/all.conf" | |
| common=( | |
| --read-only --tmpfs /tmp | |
| --cap-drop ALL --security-opt no-new-privileges | |
| --user "$(id -u):$(id -g)" | |
| --mount "type=bind,source=$workspace,target=/workspace" | |
| ) | |
| docker run --rm "${common[@]}" crossglyph:test build | |
| test -n "$(find "$workspace/cpfonts" -name '*.cpfont' -print -quit)" | |
| docker run -d --name crossglyph-smoke "${common[@]}" \ | |
| -p 127.0.0.1:18000:8000 crossglyph:test preview --no-open | |
| for attempt in {1..30}; do | |
| if curl --fail --silent --output /dev/null \ | |
| http://127.0.0.1:18000/; then | |
| exit 0 | |
| fi | |
| sleep 1 | |
| done | |
| docker logs crossglyph-smoke | |
| exit 1 |