Repository navigation
Prepare sample_data for go-cart.io curated maps #198
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: CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # TODO: We might want to later fix the version of clang-format so that future checks | |
| # don't mysteriously fail when a new version is released. | |
| style-check: | |
| name: Style check (clang-format) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install clang-format | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y clang-format | |
| echo "CLANG_FORMAT=clang-format" >> $GITHUB_ENV | |
| - name: Check formatting | |
| run: | | |
| mapfile -t FILES < <(git ls-files '*.[ch]pp' '*.c' '*.h') | |
| if [ ${#FILES[@]} -eq 0 ]; then | |
| echo "No source files to check"; exit 0 | |
| fi | |
| echo "clang-format version: $($CLANG_FORMAT --version)" | |
| echo "Running clang-format diff..." | |
| bad_files=() | |
| for f in "${FILES[@]}"; do | |
| CF_CMD="$CLANG_FORMAT -style=file $f" | |
| if ! diff -u "$f" <($CF_CMD); then | |
| echo "::group::❌ $f" | |
| echo "Command: $CF_CMD" | |
| diff -u "$f" <($CF_CMD) || true | |
| echo "::endgroup::" | |
| bad_files+=("$f") | |
| fi | |
| done | |
| if [ ${#bad_files[@]} -ne 0 ]; then | |
| file_list=$(printf '%s\n' "${bad_files[@]}") | |
| file_list_escaped=${file_list//$'\n'/%0A} | |
| echo "::error::clang-format issues detected in the following files:%0A${file_list_escaped}%0ARun 'clang-format -i' to fix." | |
| exit 1 | |
| fi | |
| docs-check: | |
| name: Docs check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install tools | |
| run: | | |
| sudo apt-get update -y | |
| sudo npm install -g markdown-link-check@^3 markdownlint-cli2@^0 cspell@^8 | |
| - name: Check broken links | |
| run: | | |
| markdown-link-check -q -c .markdown-link-check.json README.md | |
| - name: Check typos | |
| run: | | |
| if ! npx cspell "README.md" --no-progress --no-summary; then | |
| echo "::error::cspell found unknown words. \ | |
| If a word is correct, add it to .cspell.json under \"words\"." | |
| exit 1 | |
| fi | |
| - name: Check formatting | |
| run: | | |
| markdownlint-cli2 README.md | |
| build: | |
| name: "Build (${{ matrix.name }})" | |
| runs-on: ${{ matrix.os }} | |
| needs: [style-check, docs-check] | |
| strategy: | |
| fail-fast: false # Make sure if one build fails, others can still run | |
| matrix: | |
| include: | |
| # Linux | |
| - os: ubuntu-latest | |
| compiler: gcc | |
| version: 13 | |
| build_type: Release | |
| name: ubuntu-release-gcc | |
| - os: ubuntu-latest | |
| compiler: clang | |
| version: 16 | |
| build_type: Release | |
| name: ubuntu-release-clang | |
| - os: ubuntu-latest | |
| compiler: gcc | |
| version: 13 | |
| build_type: Debug | |
| name: ubuntu-debug-gcc | |
| - os: ubuntu-latest | |
| compiler: clang | |
| version: 16 | |
| build_type: Debug | |
| name: ubuntu-debug-clang | |
| # macOS | |
| - os: macos-14 | |
| compiler: apple-clang | |
| version: "" | |
| build_type: Release | |
| name: macos-release-appleclang | |
| - os: macos-14 | |
| compiler: apple-clang | |
| version: "" | |
| build_type: Debug | |
| name: macos-debug-appleclang | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Python & Conan | |
| run: | | |
| python3 -m venv .venv | |
| source .venv/bin/activate | |
| pip install -U pip wheel conan==2.16.1 cmake==3.30.0 | |
| conan remote update conancenter --url=https://center2.conan.io | |
| conan profile detect | |
| - name: Install compiler (Linux only) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| if [[ "${{ matrix.compiler }}" == "gcc" ]]; then | |
| sudo apt-get install -y gcc-${{ matrix.version }} g++-${{ matrix.version }} | |
| echo "CC=gcc-${{ matrix.version }}" >> $GITHUB_ENV | |
| echo "CXX=g++-${{ matrix.version }}" >> $GITHUB_ENV | |
| else | |
| sudo apt-get install -y clang-${{ matrix.version }} lld | |
| echo "CC=clang-${{ matrix.version }}" >> $GITHUB_ENV | |
| echo "CXX=clang++-${{ matrix.version }}" >> $GITHUB_ENV | |
| fi | |
| # We only perform static builds so the output can be exported as an artifact | |
| # for testing on a clean system without installing dependencies. | |
| - name: Download Dependencies | |
| run: | | |
| source .venv/bin/activate | |
| conan install . \ | |
| --output-folder build \ | |
| --build=missing \ | |
| -s build_type=${{ matrix.build_type }} \ | |
| -s compiler.cppstd=20 \ | |
| -o "*:shared=False" \ | |
| -o "*:fPIC=False" | |
| - name: Configure & build | |
| run: | | |
| source .venv/bin/activate | |
| if [[ "${{ runner.os }}" == "Linux" ]]; then | |
| FIND_SUFFIX='-DCMAKE_FIND_LIBRARY_SUFFIXES=.a' | |
| EXE_FLAGS='-static -static-libstdc++ -static-libgcc -pthread' | |
| else | |
| FIND_SUFFIX='' | |
| EXE_FLAGS='' | |
| fi | |
| cmake -S . -B build \ | |
| -DCMAKE_TOOLCHAIN_FILE=build/build/${{ matrix.build_type }}/generators/conan_toolchain.cmake \ | |
| -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ | |
| -DBUILD_SHARED_LIBS=OFF \ | |
| -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ | |
| ${FIND_SUFFIX} \ | |
| -DCMAKE_EXE_LINKER_FLAGS="${EXE_FLAGS}" | |
| cmake --build build -j$(nproc || sysctl -n hw.ncpu) | |
| - name: Package build folder | |
| run: tar -czf build-${{ matrix.name }}.tar.gz build | |
| - name: Upload artefact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.name }} | |
| path: build-${{ matrix.name }}.tar.gz | |
| build-sanitize: | |
| name: "Build (${{ matrix.san }})" | |
| runs-on: ubuntu-latest | |
| needs: [style-check, docs-check] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # ASan and UBSan can be used together, but TSan is incompatible with ASan. | |
| # But we keep ASan and UBSan builds separate separate because it isolates | |
| # memory- and UB-errors for clearer diagnostics. | |
| - san: asan # AddressSanitizer + LeakSanitizer (ASan + LSAn) | |
| flag: address,leak | |
| - san: ubsan # UndefinedBehaviorSanitizer | |
| flag: undefined | |
| - san: tsan # ThreadSanitizer | |
| flag: thread | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Python & Conan | |
| run: | | |
| python3 -m venv .venv | |
| source .venv/bin/activate | |
| pip install -U pip wheel conan==2.16.1 cmake==3.30.0 | |
| conan remote update conancenter --url=https://center2.conan.io | |
| conan profile detect | |
| # We only run sanitizers on Linux with Clang, since GCC's support is less mature | |
| # and sanitizer support on macOS is incomplete. | |
| - name: Install clang-16 | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y clang-16 lld-16 | |
| echo "CC=clang-16" >> $GITHUB_ENV | |
| echo "CXX=clang++-16" >> $GITHUB_ENV | |
| - name: Download dependencies | |
| run: | | |
| source .venv/bin/activate | |
| conan install . \ | |
| --output-folder build \ | |
| --build=missing \ | |
| -s build_type=Debug \ | |
| -s compiler.cppstd=20 \ | |
| -o "*:shared=False" | |
| - name: Configure & build | |
| run: | | |
| source .venv/bin/activate | |
| cmake -S . -B build \ | |
| -DCMAKE_TOOLCHAIN_FILE=build/build/Debug/generators/conan_toolchain.cmake \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DBUILD_SHARED_LIBS=OFF \ | |
| -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ | |
| -DCMAKE_CXX_FLAGS="-fsanitize=${{ matrix.flag }} -fno-omit-frame-pointer" \ | |
| -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=${{ matrix.flag }}" | |
| cmake --build build -j$(nproc) | |
| - name: Package build folder | |
| run: tar -czf build-${{ matrix.san }}.tar.gz build | |
| - name: Upload artefact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.san }} | |
| path: build-${{ matrix.san }}.tar.gz | |
| # ─────────────────────────── Unit Tests ─────────────────────────── | |
| unit-tests: | |
| name: "Unit tests (${{ matrix.target }})" | |
| needs: [build, build-sanitize] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - ubuntu-release-gcc | |
| - ubuntu-release-clang | |
| - ubuntu-debug-gcc | |
| - ubuntu-debug-clang | |
| - macos-release-appleclang | |
| - macos-debug-appleclang | |
| - asan | |
| - ubsan | |
| - tsan | |
| runs-on: "${{ contains(matrix.target, 'mac') && 'macos-14' || 'ubuntu-latest' }}" | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ matrix.target }} | |
| - name: Unpack build folder | |
| run: tar -xzf build-${{ matrix.target }}.tar.gz | |
| - name: Unit tests | |
| run: | | |
| ctest --test-dir build -L unit --output-on-failure | |
| # ────────────────────────── Stress Tests ────────────────────────── | |
| stress-tests: | |
| name: "Stress tests (${{ matrix.target }})" | |
| needs: [build, build-sanitize] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - ubuntu-release-gcc | |
| - ubuntu-release-clang | |
| - ubuntu-debug-gcc | |
| - ubuntu-debug-clang | |
| - macos-release-appleclang | |
| - macos-debug-appleclang | |
| - asan | |
| - ubsan | |
| - tsan | |
| runs-on: "${{ contains(matrix.target, 'mac') && 'macos-14' || 'ubuntu-latest' }}" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ matrix.target }} | |
| - name: Unpack build folder | |
| run: tar -xzf build-${{ matrix.target }}.tar.gz | |
| - name: Stress tests | |
| run: | | |
| ctest --test-dir build -L stress --output-on-failure | |
| # ──────────────────── Performance comparison ──────────────────── | |
| perf-tests: | |
| if: github.event_name == 'pull_request' | |
| name: Performance comparison (main, ${{ matrix.name }}) | |
| needs: build | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| compiler: clang | |
| version: 16 | |
| build_type: Release | |
| name: ubuntu-release-clang | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| # PR artefact from the build job | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ matrix.name }} | |
| - name: Unpack PR artefact | |
| run: | | |
| mkdir -p build-pr | |
| tar -xzf build-${{ matrix.name }}.tar.gz -C build-pr | |
| chmod +x build-pr/build/cartogram | |
| # Only designed to work on Linux | |
| - name: Setup Python & Conan | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| ${{ matrix.compiler }}-${{ matrix.version }} \ | |
| lld hyperfine python3-venv | |
| echo "CC=${{ matrix.compiler }}-${{ matrix.version }}" >> $GITHUB_ENV | |
| echo "CXX=${{ matrix.compiler }}++-${{ matrix.version }}" >> $GITHUB_ENV | |
| - name: Build baseline (origin/main) | |
| run: | | |
| git fetch --depth 1 --no-tags origin main | |
| git worktree add ../baseline origin/main | |
| pushd ../baseline | |
| python3 -m venv .venv | |
| source .venv/bin/activate | |
| pip install --upgrade pip wheel conan==2.16.1 cmake==3.30.0 | |
| conan remote update conancenter --url=https://center2.conan.io | |
| conan profile detect | |
| conan install . --output-folder build \ | |
| --build missing \ | |
| -s build_type=${{ matrix.build_type }} \ | |
| -s compiler.cppstd=20 \ | |
| -o "*:shared=False" | |
| cmake -S . -B build \ | |
| -DCMAKE_TOOLCHAIN_FILE=build/build/${{ matrix.build_type }}/generators/conan_toolchain.cmake \ | |
| -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ | |
| -DBUILD_SHARED_LIBS=OFF | |
| cmake --build build -j"$(nproc)" | |
| popd | |
| # Benchmarks | |
| - name: Benchmark sample_data maps | |
| run: | | |
| python3 -m venv .venv | |
| source .venv/bin/activate | |
| bash .github/scripts/benchmark_maps.sh \ | |
| build-pr/build/cartogram \ | |
| ../baseline/build/cartogram \ | |
| results.json | |
| # Generate performance report | |
| - name: Create performance report | |
| run: | | |
| source .venv/bin/activate | |
| pip install --upgrade scipy | |
| python .github/scripts/gen_perf_comment.py results.json comment.md | |
| # When PR is made from fork, the pull_request will be empty during workflow_run in | |
| # pr-comment.yml. So, we also pass the PR number as artifact | |
| - name: Save PR number | |
| run: echo "${{ github.event.number }}" > pr_number.txt | |
| # Upload report for the pr-comment.yml workflow | |
| - name: Upload performance report & PR number | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: perf-comment # If this name changes, update the pr-comment.yml workflow too | |
| path: | | |
| comment.md | |
| pr_number.txt | |
| # ─────────────────────────── Fuzzer Tests ───────────────────────── | |
| # fuzzer-tests: | |
| # needs: [build] | |
| # strategy: | |
| # fail-fast: false | |
| # matrix: | |
| # target: | |
| # - ubuntu-release-gcc | |
| # - ubuntu-release-clang | |
| # - macos-release-appleclang | |
| # runs-on: "${{ contains(matrix.target, 'mac') && 'macos-14' || 'ubuntu-latest' }}" | |
| # steps: | |
| # - uses: actions/checkout@v4 | |
| # - uses: actions/download-artifact@v4 | |
| # with: | |
| # name: ${{ matrix.target }} | |
| # - name: Install Python in venv | |
| # run: | | |
| # python3 -m venv .venv | |
| # source .venv/bin/activate | |
| # pip install -U pip | |
| # - name: Unpack build folder | |
| # run: tar -xzf build-${{ matrix.target }}.tar.gz | |
| # - name: Fuzzer tests | |
| # run: | | |
| # ctest --test-dir build -L fuzzer --verbose |