US-38B + US-38C: anonymous enum + unnamed generate block detection #50
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: | |
| pull_request: | |
| jobs: | |
| format-check: | |
| runs-on: ubuntu-latest | |
| env: | |
| PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| PUSH_BEFORE_SHA: ${{ github.event.before }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 # need history for diff against base | |
| - name: Install clang-format and clang-format-diff | |
| run: | | |
| sudo apt-get update | |
| # Ubuntu's clang-format package ships /usr/bin/clang-format-diff, | |
| # but the version-suffixed binaries (clang-format-diff-NN) come | |
| # with the corresponding clang-format-NN package on some images. | |
| sudo apt-get install -y clang-format | |
| # Locate clang-format-diff; fail loudly if absent so the format | |
| # gate cannot silently succeed when the tool is missing. | |
| # Using compgen -G avoids the "ls | head" pipeline whose exit code | |
| # is dominated by `head` (always 0), which would mask a glob miss. | |
| if ! command -v clang-format-diff >/dev/null 2>&1 \ | |
| && ! compgen -G '/usr/bin/clang-format-diff-*' >/dev/null; then | |
| echo "::error::clang-format-diff not found after apt install; the format gate cannot run." | |
| exit 1 | |
| fi | |
| - name: Determine base ref | |
| id: base | |
| run: | | |
| # Empty-tree SHA used by git as a stand-in when there is no parent commit. | |
| EMPTY_TREE="4b825dc642cb6eb9a060e54bf8d69288fbee4904" | |
| if [ "$EVENT_NAME" = "pull_request" ]; then | |
| BASE="$PR_BASE_SHA" | |
| else | |
| BASE="$PUSH_BEFORE_SHA" | |
| if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ]; then | |
| # New branch / first push: try HEAD~1, fall back to empty tree. | |
| if git rev-parse --verify HEAD~1 >/dev/null 2>&1; then | |
| BASE="HEAD~1" | |
| else | |
| BASE="$EMPTY_TREE" | |
| fi | |
| fi | |
| fi | |
| echo "base=$BASE" >> "$GITHUB_OUTPUT" | |
| - name: Check format on changed lines only | |
| env: | |
| BASE: ${{ steps.base.outputs.base }} | |
| run: | | |
| set -euo pipefail | |
| echo "Checking format vs $BASE" | |
| CHANGED=$(git diff --name-only --diff-filter=AM "$BASE" -- 'src/*.cpp' 'src/*.h' 'src/**/*.cpp' 'src/**/*.h' 'include/**/*.h' 'tests/*.cpp' 'tests/**/*.cpp' 'fuzz/*.cpp' || true) | |
| if [ -z "$CHANGED" ]; then | |
| echo "No C++ source changes; nothing to format-check." | |
| exit 0 | |
| fi | |
| echo "Changed C++ files:" | |
| echo "$CHANGED" | |
| DIFFCMD=$(command -v clang-format-diff \ | |
| || command -v clang-format-diff-19 \ | |
| || command -v clang-format-diff-18 \ | |
| || command -v clang-format-diff-17 \ | |
| || command -v clang-format-diff-16 \ | |
| || command -v clang-format-diff-15 \ | |
| || command -v clang-format-diff-14 \ | |
| || true) | |
| if [ -z "$DIFFCMD" ]; then | |
| # Hard fail rather than silently passing: see the install step's | |
| # earlier guard, this branch should be unreachable in CI. | |
| echo "::error::clang-format-diff still not found at format-check time; aborting." | |
| exit 1 | |
| fi | |
| OUT=$(git diff -U0 "$BASE" -- $CHANGED | "$DIFFCMD" -p1 -style=file) | |
| if [ -n "$OUT" ]; then | |
| echo "::error::clang-format found violations on changed lines:" | |
| echo "$OUT" | |
| exit 1 | |
| fi | |
| echo "format-check passed (changed lines only)" | |
| coverage: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install coverage prerequisites | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| build-essential \ | |
| cmake \ | |
| git \ | |
| python3 \ | |
| ccache \ | |
| gcovr \ | |
| catch2 \ | |
| libyaml-cpp-dev | |
| - name: Cache slang install | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.local | |
| key: ${{ runner.os }}-svlens-slang-${{ hashFiles('scripts/setup-deps.sh') }} | |
| - name: Stage slang dependency | |
| run: | | |
| ./scripts/setup-deps.sh --prefix "$HOME/.local" | |
| - name: Configure with coverage instrumentation | |
| run: | | |
| cmake -B build-cov \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DCMAKE_PREFIX_PATH="$HOME/.local" \ | |
| -DSVLENS_FETCH_DEPS=OFF \ | |
| -DSVLENS_ENABLE_COVERAGE=ON | |
| - name: Build (coverage) | |
| run: | | |
| cmake --build build-cov -j"$(nproc)" | |
| - name: Run tests | |
| run: | | |
| ctest --test-dir build-cov --output-on-failure | |
| - name: Generate coverage report | |
| run: | | |
| gcovr --root . \ | |
| --xml-pretty --output build-cov/coverage.xml \ | |
| --html-details build-cov/coverage.html \ | |
| --print-summary \ | |
| --exclude 'tests/.*' \ | |
| --exclude 'build-cov/.*' \ | |
| --exclude '_deps/.*' \ | |
| build-cov | |
| - name: Upload coverage to Codecov | |
| if: github.repository == 'babyworm/svlens' # skip on forks (no token) | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: build-cov/coverage.xml | |
| fail_ci_if_error: false | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| - name: Upload coverage HTML artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-html | |
| path: build-cov/coverage.html | |
| build-and-test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Cache slang install | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.local | |
| key: ${{ runner.os }}-svlens-slang-${{ hashFiles('scripts/setup-deps.sh') }} | |
| - name: Install build prerequisites | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential cmake git python3 ccache | |
| - name: Cache ccache | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/ccache | |
| key: ${{ runner.os }}-svlens-ccache-${{ github.ref_name }}-${{ hashFiles('CMakeLists.txt', 'src/**', 'include/**', 'tests/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-svlens-ccache-${{ github.ref_name }}- | |
| ${{ runner.os }}-svlens-ccache- | |
| - name: Install slang | |
| run: | | |
| ./scripts/setup-deps.sh --prefix "$HOME/.local" | |
| - name: Build | |
| run: | | |
| make build CMAKE_PREFIX_PATH="$HOME/.local" | |
| - name: Test | |
| run: | | |
| make test CMAKE_PREFIX_PATH="$HOME/.local" | |
| portable-smoke: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Ubuntu prerequisites | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| build-essential \ | |
| cmake \ | |
| git \ | |
| python3 \ | |
| ccache \ | |
| catch2 \ | |
| libyaml-cpp-dev | |
| - name: Install macOS prerequisites | |
| if: runner.os == 'macOS' | |
| run: | | |
| brew install catch2 yaml-cpp fmt ccache | |
| - name: Cache slang install | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.local | |
| key: ${{ runner.os }}-svlens-slang-${{ hashFiles('scripts/setup-deps.sh') }} | |
| - name: Stage slang dependency | |
| run: | | |
| ./scripts/setup-deps.sh --prefix "$HOME/.local" | |
| - name: Configure portable smoke build | |
| run: | | |
| cmake -B build-smoke \ | |
| -DCMAKE_PREFIX_PATH="$HOME/.local;/opt/homebrew" \ | |
| -DSVLENS_FETCH_DEPS=OFF | |
| - name: Build portable smoke binary | |
| run: | | |
| cmake --build build-smoke -j"$(nproc 2>/dev/null || sysctl -n hw.ncpu)" | |
| - name: Run portable smoke contract bundle | |
| run: | | |
| ctest --test-dir build-smoke --output-on-failure \ | |
| -R "install_smoke|help_contract|schema_contract|integration_shell|integration_svlens|integration_cdc_golden" | |
| preinstalled-offline-smoke: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install build prerequisites and preinstalled deps | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| build-essential \ | |
| cmake \ | |
| git \ | |
| python3 \ | |
| ccache \ | |
| catch2 \ | |
| libyaml-cpp-dev | |
| - name: Cache slang install | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.local | |
| key: ${{ runner.os }}-svlens-slang-${{ hashFiles('scripts/setup-deps.sh') }} | |
| - name: Stage slang dependency | |
| run: | | |
| ./scripts/setup-deps.sh --prefix "$HOME/.local" | |
| - name: Configure offline with preinstalled deps only | |
| run: | | |
| cmake -B build-offline \ | |
| -DCMAKE_PREFIX_PATH="$HOME/.local" \ | |
| -DSVLENS_FETCH_DEPS=OFF | |
| - name: Build offline | |
| run: | | |
| cmake --build build-offline -j"$(nproc)" | |
| - name: Prove no-network install/html smoke | |
| run: | | |
| ctest --test-dir build-offline -R "install_smoke|HtmlReport" --output-on-failure | |
| macos-offline-smoke: | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install preinstalled dependencies | |
| run: | | |
| brew update | |
| brew install catch2 yaml-cpp fmt ccache | |
| - name: Cache slang install | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.local | |
| key: ${{ runner.os }}-svlens-slang-${{ hashFiles('scripts/setup-deps.sh') }} | |
| - name: Stage slang dependency | |
| run: | | |
| ./scripts/setup-deps.sh --prefix "$HOME/.local" | |
| - name: Configure offline with preinstalled deps | |
| run: | | |
| cmake -B build-macos \ | |
| -DCMAKE_PREFIX_PATH="$HOME/.local;/opt/homebrew" \ | |
| -DSVLENS_FETCH_DEPS=OFF | |
| - name: Build offline | |
| run: | | |
| cmake --build build-macos -j"$(sysctl -n hw.ncpu)" | |
| - name: Run contract smoke bundle | |
| run: | | |
| ctest --test-dir build-macos -R "install_smoke|help_contract|schema_contract|integration_shell|integration_svlens|integration_cdc_golden|HtmlReport" --output-on-failure |