-
Notifications
You must be signed in to change notification settings - Fork 1
Enable GitHub Actions CI #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Run cppcheck static analysis on libx11-compat source files. | ||
| # Scope is src/*.c; tests, examples, and the generated upstream tree | ||
| # under build/upstream/ are out of scope (tests use stubs, examples are | ||
| # downstream Xlib clients, and the upstream snapshot is reviewed at | ||
| # import time). | ||
|
|
||
| set -e -u -o pipefail | ||
|
|
||
| mapfile -t SOURCES < <(git ls-files -z -- 'src/*.c' | tr '\0' '\n') | ||
|
|
||
| if [ ${#SOURCES[@]} -eq 0 ]; then | ||
| echo "No tracked C source files found." | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Run with a hard timeout so a runaway analysis cannot stall CI. | ||
| # --max-configs=1 keeps the CI invocation fast; deep analysis stays in | ||
| # the developer's hands locally. | ||
| timeout 180 cppcheck \ | ||
| -Iinclude -Isrc \ | ||
| --platform=unix64 \ | ||
| --enable=warning \ | ||
| --max-configs=1 --error-exitcode=1 --inline-suppr \ | ||
| --suppress=checkersReport --suppress=unmatchedSuppression \ | ||
| --suppress=missingIncludeSystem --suppress=noValidConfiguration \ | ||
| --suppress=normalCheckLevelMaxBranches \ | ||
| --suppress=preprocessorErrorDirective \ | ||
| -DNARROWPROTO -DXTHREADS \ | ||
| "${SOURCES[@]}" |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Verify clang-format-20 conformance for tracked C/H files under | ||
| # include/, src/, and tests/. Examples are excluded because | ||
| # examples/x11perf/ ships verbatim from xorg and intentionally keeps | ||
| # upstream style. | ||
| # | ||
| # clang-format-20 is required: older releases produce different output | ||
| # for the .clang-format style used in this tree. | ||
|
|
||
| set -e -u -o pipefail | ||
|
|
||
| if [ -z "${CLANG_FORMAT:-}" ]; then | ||
| if command -v clang-format-20 >/dev/null 2>&1; then | ||
| CLANG_FORMAT="clang-format-20" | ||
| else | ||
| echo "Error: clang-format-20 is required (older versions differ in style)" >&2 | ||
| exit 1 | ||
| fi | ||
| fi | ||
|
|
||
| # Reject anything that isn't clang-format 20.x. | ||
| version=$("$CLANG_FORMAT" --version 2>/dev/null | grep -oE 'version [0-9]+' | awk '{print $2}') | ||
| if [ "$version" != "20" ]; then | ||
| echo "Error: \$CLANG_FORMAT ($CLANG_FORMAT) reports version '$version', expected 20" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| ret=0 | ||
| while IFS= read -r -d '' file; do | ||
| expected=$(mktemp) | ||
| "$CLANG_FORMAT" "$file" >"$expected" | ||
| if ! diff -u -p --label="$file" --label="expected coding style" "$file" "$expected"; then | ||
| ret=1 | ||
| fi | ||
| rm -f "$expected" | ||
| done < <(git ls-files -z -- \ | ||
| 'include/*.h' 'include/**/*.h' \ | ||
| 'src/*.c' 'src/*.h' \ | ||
| 'tests/*.c' 'tests/*.h') | ||
|
|
||
| exit $ret |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Ensure all tracked C/H files end with a newline. | ||
|
|
||
| set -e -u -o pipefail | ||
|
|
||
| ret=0 | ||
| while IFS= read -rd '' f; do | ||
| if file --mime-encoding "$f" | grep -qv binary; then | ||
| if [ -n "$(tail -c1 <"$f")" ]; then | ||
| echo "Warning: No newline at end of file $f" | ||
| ret=1 | ||
| fi | ||
| fi | ||
| done < <(git ls-files -z -- '*.c' '*.h') | ||
|
|
||
| exit $ret |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Security checks for libx11-compat sources. Scope is src/ and the | ||
| # compatibility headers under include/X11/. Examples and tests are | ||
| # excluded -- examples mirror upstream Xlib clients and tests | ||
| # legitimately exercise corner-case APIs. | ||
| # | ||
| # 1. Banned functions -- unsafe libc calls with safer alternatives. | ||
| # 2. Credential / secret patterns -- catch accidental key leaks. | ||
| # 3. Dangerous preprocessor -- detect disabled security features. | ||
|
|
||
| set -u -o pipefail | ||
|
|
||
| failed=0 | ||
|
|
||
| banned='(^|[^[:alnum:]_])(gets|sprintf|vsprintf|strcpy|stpcpy|strcat|atoi|atol|atoll|atof|mktemp|tmpnam|tempnam)[[:space:]]*\(' | ||
| secrets='(password|secret|api_key|private_key|token)[[:space:]]*=[[:space:]]*"[^"]+' | ||
| # Dangerous preprocessor: catch both `#define _FORTIFY_SOURCE 0` and the | ||
| # bare `#undef _FORTIFY_SOURCE` form, plus any define/undef of __SSP__. | ||
| # An earlier version of this regex required `_FORTIFY_SOURCE` to be | ||
| # followed by `[[:space:]]+0`, which silently let `#undef _FORTIFY_SOURCE` | ||
| # pass. | ||
| dangerous_pp='#[[:space:]]*((undef|define)[[:space:]]+__SSP__|undef[[:space:]]+_FORTIFY_SOURCE|define[[:space:]]+_FORTIFY_SOURCE[[:space:]]+0)' | ||
| # Skip block-comment continuation lines (` * ...`, ` */`, blank ` *`) | ||
| # without dropping code that begins with `*` like `*p = strdup(s);`. | ||
| # The `*` must be followed by whitespace, `/`, or end of line to count | ||
| # as a comment marker. | ||
| comment_only='^[[:space:]]*(//|/\*|\*([[:space:]/]|$))' | ||
|
|
||
| while IFS= read -r -d '' f; do | ||
| code=$(grep -vE "$comment_only" "$f") | ||
|
|
||
| if echo "$code" | grep -qE "$banned"; then | ||
| echo "Banned function in $f:" | ||
| grep -nE "$banned" "$f" | grep -vE "$comment_only" | ||
| failed=1 | ||
| fi | ||
| if echo "$code" | grep -iqE "$secrets"; then | ||
| echo "Possible hardcoded secret in $f:" | ||
| grep -inE "$secrets" "$f" | grep -vE "$comment_only" | ||
| failed=1 | ||
| fi | ||
| if echo "$code" | grep -qE "$dangerous_pp"; then | ||
| echo "Dangerous preprocessor directive in $f:" | ||
| grep -nE "$dangerous_pp" "$f" | grep -vE "$comment_only" | ||
| failed=1 | ||
| fi | ||
| done < <(git ls-files -z -- 'src/*.c' 'src/*.h' 'include/X11/*.h' 'include/X11/**/*.h') | ||
|
|
||
| if [ $failed -eq 0 ]; then | ||
| echo "Security checks passed." | ||
| fi | ||
|
|
||
| exit $failed |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| root = true | ||
|
|
||
| [*] | ||
| end_of_line = lf | ||
| insert_final_newline = true | ||
| trim_trailing_whitespace = true | ||
|
|
||
| [Makefile] | ||
| indent_style = tab | ||
| indent_size = 4 | ||
|
|
||
| # shfmt reads these properties at parse time when no formatting flags | ||
| # are passed on the command line. mk/format.mk relies on that to keep | ||
| # the .ci/ shell scripts on a single style without duplicating flags. | ||
| [*.sh] | ||
| indent_style = space | ||
| indent_size = 4 | ||
| shell_variant = bash | ||
| binary_next_line = true | ||
| switch_case_indent = true | ||
|
|
||
| [mk/*] | ||
| indent_style = tab | ||
| indent_size = 4 | ||
|
|
||
| [*.[ch]] | ||
| indent_style = space | ||
| indent_size = 4 | ||
| max_line_length = 80 | ||
|
|
||
| [*.py] | ||
| indent_style = space | ||
| indent_size = 4 | ||
|
|
||
| [*.sh] | ||
| indent_style = space | ||
| indent_size = 4 | ||
|
|
||
| [*.hook] | ||
| indent_style = space | ||
| indent_size = 4 | ||
|
|
||
| [*.yml] | ||
| indent_style = space | ||
| indent_size = 2 | ||
| # test | ||
| # test | ||
| # test | ||
| # test | ||
| # x |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| # Build libx11-compat, run the regression suite, and gate on lint / | ||
| # sanitizer findings. Action versions track the latest major release | ||
| # (no SHA pinning); the LLVM apt repo is added so clang-format-20 is | ||
| # available on ubuntu-24.04 (which ships clang-format-18 by default). | ||
| name: CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main, cicd] | ||
| pull_request: | ||
| branches: [main] | ||
|
|
||
| jobs: | ||
| # ---- Lint: formatting, newline, security, cppcheck ---- | ||
| lint: | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Install LLVM 20 apt source | ||
| # Drop the GPG key in /usr/share/keyrings/ and reference it with | ||
| # signed-by= so trust is scoped to the LLVM repo instead of every | ||
| # other source apt sees. Use the HTTPS endpoint so the package | ||
| # download itself isn't sent in the clear. | ||
| run: | | ||
| set -e | ||
| sudo install -d -m 0755 /usr/share/keyrings | ||
| curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key \ | ||
| | sudo tee /usr/share/keyrings/llvm-archive-keyring.asc >/dev/null | ||
| sudo chmod 0644 /usr/share/keyrings/llvm-archive-keyring.asc | ||
| codename=$(. /etc/os-release && echo "$VERSION_CODENAME") | ||
| echo "deb [signed-by=/usr/share/keyrings/llvm-archive-keyring.asc] https://apt.llvm.org/${codename}/ llvm-toolchain-${codename}-20 main" \ | ||
| | sudo tee /etc/apt/sources.list.d/llvm-20.list >/dev/null | ||
|
|
||
| - name: Install lint tooling | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y --no-install-recommends \ | ||
| clang-format-20 cppcheck file shfmt | ||
|
|
||
| - name: Confirm tool versions | ||
| run: | | ||
| clang-format-20 --version | ||
| shfmt --version | ||
|
|
||
| - name: Check trailing newline | ||
| run: .ci/check-newline.sh | ||
|
|
||
| - name: Check clang-format | ||
| env: | ||
| CLANG_FORMAT: clang-format-20 | ||
| run: .ci/check-format.sh | ||
|
|
||
| - name: Check shell formatting (shfmt) | ||
| # shfmt picks up the [*.sh] section of .editorconfig so the | ||
| # style stays in lockstep with `make check-format`. | ||
| run: shfmt -d $(git ls-files -- '*.sh') | ||
|
|
||
| - name: Security checks | ||
| run: .ci/check-security.sh | ||
|
|
||
| - name: Static analysis (cppcheck) | ||
| # Pre-existing findings (memleak / doubleFree / va_end / syntaxError on | ||
| # SDL_VERSION_ATLEAST) still need triage. Keep the step non-blocking | ||
| # for now so the report surfaces in CI logs; flip to required once | ||
| # the backlog is cleared or suppressed inline. | ||
| continue-on-error: true | ||
| run: .ci/check-cppcheck.sh | ||
|
|
||
| # ---- Build the shared library and run the regression suite ---- | ||
| build: | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Install build dependencies | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y --no-install-recommends \ | ||
| clang make pkg-config python3 \ | ||
| libsdl2-dev libsdl2-ttf-dev libpixman-1-dev | ||
|
|
||
| - name: Build libX11-compat.so | ||
| run: make -j"$(nproc)" | ||
|
|
||
| - name: Run regression tests (make check) | ||
| env: | ||
| SDL_VIDEODRIVER: dummy | ||
| run: make check | ||
|
|
||
| - name: Build bundled examples | ||
| run: make examples -j"$(nproc)" | ||
|
|
||
| - name: Build with DEBUG_LIBX11_COMPAT | ||
| run: | | ||
| make clean | ||
| make CFLAGS_EXTRA=-DDEBUG_LIBX11_COMPAT -j"$(nproc)" | ||
|
|
||
| # ---- Run make check with AddressSanitizer + UndefinedBehaviorSanitizer ---- | ||
| sanitize: | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Install build dependencies | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y --no-install-recommends \ | ||
| clang make pkg-config python3 \ | ||
| libsdl2-dev libsdl2-ttf-dev libpixman-1-dev | ||
|
|
||
| - name: Build and test with ASan + UBSan | ||
| env: | ||
| # Both library and test binaries are compiled with the same | ||
| # sanitizer flags so the runtime loaded by the test binary | ||
| # services the .so as well. -fno-sanitize-recover=undefined | ||
| # turns UBSan findings into hard failures. | ||
| SAN_FLAGS: "-fsanitize=address,undefined -fno-sanitize-recover=undefined -fno-omit-frame-pointer -g -O1" | ||
| SDL_VIDEODRIVER: dummy | ||
| # SDL2's dummy driver retains pools across XCloseDisplay, so | ||
| # leak detection produces unrelated noise. Keep memory-error | ||
| # detection on; revisit leaks separately. | ||
| ASAN_OPTIONS: detect_leaks=0:abort_on_error=1:strict_string_checks=1 | ||
| UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1 | ||
| run: | | ||
| make CFLAGS_EXTRA="$SAN_FLAGS" LDFLAGS="$SAN_FLAGS" -j"$(nproc)" | ||
| make CFLAGS_EXTRA="$SAN_FLAGS" LDFLAGS="$SAN_FLAGS" check | ||
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
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
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.