Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,60 @@ on:

jobs:
build-and-test:
# Two compilers times two build modes, so four jobs.
#
# Both compilers, so a warning or a standard-library difference that only
# one of them notices still fails the build.
#
# Both modes, because -O2 and the sanitizers do not see the same program:
# the optimised build is what ships, and the sanitised one is the only
# thing that reports a read past the end of a buffer rather than returning
# whatever was next to it.
strategy:
fail-fast: false
matrix:
cxx: [g++, clang++]
mode: [optimised, sanitised]
include:
# -Werror lives here rather than in the Makefile on purpose: a
# warning should stop a change being merged, not stop a contributor
# building the thing at all. `make` on a clean checkout stays warm.
- mode: optimised
cxxflags: -std=c++17 -O2 -Wall -Wextra -Werror

# -fno-sanitize-recover=undefined is what makes this entry mean
# anything. UBSan's default is to print the diagnostic and carry on,
# exiting 0 -- so without it, a real finding is a green build and
# nobody reads the log of a job that passed.
- mode: sanitised
cxxflags: >-
-std=c++17 -O1 -g -Wall -Wextra -Werror
-fsanitize=address,undefined -fno-sanitize-recover=undefined
-fno-omit-frame-pointer

runs-on: ubuntu-latest

# Set for the job rather than passed to each make: the Makefile takes both
# with ?=, and the test and golden targets have to be built with the same
# flags as the objects they link against, which is easy to get wrong one
# step at a time.
env:
CXX: ${{ matrix.cxx }}
CXXFLAGS: ${{ matrix.cxxflags }}
# Names the source line rather than an address when something does fire.
UBSAN_OPTIONS: print_stacktrace=1

steps:
- uses: actions/checkout@v4

- name: Show compiler version
run: ${{ matrix.cxx }} --version

- name: Build
run: make CXX=${{ matrix.cxx }}
run: make

- name: Run tests
run: make test CXX=${{ matrix.cxx }}
run: make test

- name: Run golden end-to-end tests
run: make golden CXX=${{ matrix.cxx }}
run: make golden
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ detail, which is where the reasoning lives.
the merge and after it, and applying only the difference. A deck whose history
began before the log keeps it.

### Changed

- **CI builds under the sanitizers and with `-Werror`,** as a four-way matrix of
both compilers against an optimised and a sanitised build. Every pull request
so far was checked under `-fsanitize=address,undefined` by hand and came back
clean, which is the argument for making it a job rather than a habit.

`-Werror` is deliberately not in the Makefile: a warning should stop a change
being merged, not stop a contributor building the project at all. The
sanitised entry also compiles with `-fno-sanitize-recover=undefined`, without
which UBSan prints its diagnostic and exits 0 — so a real finding would have
been a green build that nobody reads the log of.

## 0.2.0 — 2026-08-17

Audio, a second test suite, and a review screen that fits in a terminal.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ cannot drive an app that insists on a tty.

## Contributing

Issues and pull requests are welcome. `make check` should pass before you open one; CI runs both suites on gcc and clang.
Issues and pull requests are welcome. `make check` should pass before you open one; CI runs both suites on gcc and clang, in an optimised build and again under `-fsanitize=address,undefined`, all four with `-Werror`. Warnings are deliberately not errors in the Makefile itself, so a warning never stops you building — it stops the change being merged.

Released versions and what changed in them are in [CHANGELOG.md](CHANGELOG.md).

Expand Down
Loading