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
12 changes: 10 additions & 2 deletions .github/actions/run-system-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,22 @@ inputs:
ruby:
description: 'Ruby version (used in failure artifact name)'
required: true
coverage:
description: "Set to 'system' to instrument each system-test child process with coverage (see spec/support/system/simplecov_boot.rb) -- the literal value matters, not just truthiness, so this same run's own outer rspec process doesn't also claim the unit suite's SimpleCov resultset entry"
required: false
default: 'false'

runs:
using: "composite"
steps:
# Download HTML docs bundle built by generate-docs job.
# Required by system tests that exercise Ceedling documentation features.
# Unit tests (run as a separate job step before this action) do not need the docs bundle.
# Pinned to the latest major (not v4) for Node 24 runner support --
# GitHub Actions runners now force Node 24 regardless, and v4 still
# targets the deprecated Node 20. Same reasoning below for upload-artifact.
- name: Download HTML Documentation Bundle
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: gem-docs-site-local
path: site-local/
Expand All @@ -41,14 +48,15 @@ runs:
shell: bash
env:
CI_RSPEC_PROGRESS_FORMAT: true
CEEDLING_TEST_COVERAGE: ${{ inputs.coverage }}
run: rake specs:system:debug

# Upload system test failure logs and temp project directories on test job failure.
# In 'failures' mode, passing artifacts are never created, so there is nothing to clean up
# before uploading — the systests/ directory contains only failure data.
- name: Upload system test failure artifacts
if: failure()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: systest-failures-${{ runner.os }}-ruby-${{ inputs.ruby }}
path: systests/
Expand Down
5 changes: 4 additions & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ inputs:
runs:
using: "composite"
steps:
- uses: actions/cache@v4
# Pinned to the latest major (not v4) for Node 24 runner support --
# GitHub Actions runners now force Node 24 regardless, and v4 still
# targets the deprecated Node 20.
- uses: actions/cache@v6
with:
path: vendor/bundle
key: bundle-use-ruby-${{ runner.os }}-${{ inputs.ruby }}-${{ hashFiles('**/Gemfile.lock') }}
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/_generate-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,19 @@ jobs:
steps:
# Use a cache for our tools to speed up builds
# No matrix here; Ruby version is hardcoded to match the cache key format used by test jobs
- uses: actions/cache@v4
#
# cache/checkout/upload-artifact below are pinned to their latest majors (not v4) for
# Node 24 runner support -- GitHub Actions runners now force Node 24 regardless, and v4
# still targets the deprecated Node 20.
- uses: actions/cache@v6
with:
path: vendor/bundle
key: bundle-use-ruby-${{ runner.os }}-3.3-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
bundle-use-ruby-${{ runner.os }}-3.3-

- name: Checkout Latest Repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
submodules: recursive

Expand All @@ -68,7 +72,7 @@ jobs:
rake docs:build:local --trace

- name: Upload HTML Documentation Bundle
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: gem-docs-site-local
path: site-local/
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/_publish-gem.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,19 @@ jobs:
steps:
# Use a cache for our tools to speed up builds
# No matrix here; Ruby version is hardcoded to match the cache key format used by test jobs
- uses: actions/cache@v4
#
# cache/checkout/download-artifact below are pinned to their latest majors (not v4) for
# Node 24 runner support -- GitHub Actions runners now force Node 24 regardless, and v4
# still targets the deprecated Node 20.
- uses: actions/cache@v6
with:
path: vendor/bundle
key: bundle-use-ruby-${{ runner.os }}-3.3-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
bundle-use-ruby-${{ runner.os }}-3.3-

- name: Checkout Latest Repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
submodules: recursive

Expand Down Expand Up @@ -122,7 +126,7 @@ jobs:
# Download HTML docs bundle built by _generate-docs.yml
# Artifacts are shared within the same workflow run by run_id
- name: Download HTML Documentation Bundle
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: gem-docs-site-local
path: site-local/
Expand Down
89 changes: 71 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,14 @@ on:

# Cancel any in-progress run for the same unit of work when a new event arrives.
# A push to a branch that also has an open PR fires both the push and pull_request
# triggers for the very same commit; grouping by PR number when one exists (falling
# back to the ref otherwise) means those two runs share one group instead of two,
# so the second one to start cancels the first rather than both running to completion.
# triggers for the very same commit; github.head_ref carries the bare source branch
# name for a pull_request event and is empty for a push, while github.ref_name carries
# that same bare branch name for a push (and an unrelated merge-ref name for a
# pull_request, which is why it's only ever reached as the fallback here) -- so
# `head_ref || ref_name` resolves to the identical string for both event types on the
# same branch, landing both runs in one group so the second to start cancels the first.
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
group: ci-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true


Expand All @@ -80,8 +83,12 @@ jobs:
ruby: ['3.0', '3.1', '3.2', '3.3', '3.4', '3.5']
steps:
# Checks out repository under $GITHUB_WORKSPACE — must come first to enable local action access
#
# checkout/cache/upload-artifact/download-artifact throughout this workflow are pinned
# to their latest majors (not v4) for Node 24 runner support -- GitHub Actions runners
# now force Node 24 regardless, and v4 still targets the deprecated Node 20.
- name: Checkout Latest Repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
submodules: recursive

Expand All @@ -108,9 +115,18 @@ jobs:
# Run unit tests immediately after gem install — before the slower external tool
# installation steps — so unit failures surface as quickly as possible.
# Unit tests have no dependency on gdb, valgrind, cppcheck, gcovr, or ReportGenerator.
#
# Coverage instrumentation (CEEDLING_TEST_COVERAGE) only runs on one leg of this
# matrix -- Ruby 3.3, matching the other Linux-only singleton jobs' pinned version
# -- rather than a separate job, so the combined unit+system report reuses the
# tool installs this job already pays for instead of duplicating them. The value
# ('units' here, 'system' on the Run System Tests step below) tells spec_helper.rb
# which suite is instrumenting -- see spec_helper.rb's own comment for why a bare
# on/off flag isn't enough.
- name: Run Unit Tests
env:
CI_RSPEC_PROGRESS_FORMAT: true
CEEDLING_TEST_COVERAGE: ${{ matrix.ruby == '3.3' && 'units' || 'false' }}
run: rake specs:units

# Install gdb for backtrace feature testing
Expand All @@ -128,9 +144,23 @@ jobs:
# Build cppcheck from source at a pinned version so all plugin options
# (including SARIF, which requires 2.16+) are available for testing.
# The installed binary is cached by version to avoid rebuilding on every run.
#
# actions/cache's restore step runs unprivileged and needs write access to recreate
# cached paths on a fresh runner VM. /usr/local/bin is already writable on this runner
# image, but /usr/local/share is not -- extracting the cached cppcheck subtree into it
# fails with "Cannot mkdir: Permission denied" otherwise. This has to run before every
# restore, on every run, since each job starts on a fresh ephemeral VM with the base
# image's permissions reset -- nothing from a prior run's chown carries forward. Saving
# the cache itself only ever needed read access (root-owned files are world-readable),
# so this doesn't change how or where cppcheck ultimately gets installed below.
- name: Ensure cppcheck Cache Destination Is Writable
run: |
sudo mkdir -p /usr/local/share/cppcheck
sudo chown -R "$(id -u):$(id -g)" /usr/local/share/cppcheck

- name: Cache cppcheck binary and data files
id: cache-cppcheck
uses: actions/cache@v4
uses: actions/cache@v6
with:
path: |
/usr/local/bin/cppcheck
Expand Down Expand Up @@ -171,6 +201,22 @@ jobs:
uses: ./.github/actions/run-system-tests
with:
ruby: ${{ matrix.ruby }}
coverage: ${{ matrix.ruby == '3.3' && 'system' || 'false' }}

# Merges the resultset both prior steps accumulated (see Run Unit Tests above)
# into one HTML report and uploads it, downloadable from this run's own Actions
# summary page. Ruby-3.3-only, same leg the two steps above instrumented.
- name: Generate Combined Coverage Report
if: matrix.ruby == '3.3'
run: rake coverage:report

- name: Upload Combined Coverage Report
if: matrix.ruby == '3.3'
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: coverage/
if-no-files-found: error

# Common plugin test steps
- name: Run Plugin Tests
Expand All @@ -190,7 +236,7 @@ jobs:
steps:
# Checks out repository under $GITHUB_WORKSPACE — must come first to enable local action access
- name: Checkout Latest Repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
submodules: recursive

Expand Down Expand Up @@ -272,7 +318,7 @@ jobs:
steps:
# Checks out repository under $GITHUB_WORKSPACE — must come first to enable local action access
- name: Checkout Latest Repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
submodules: recursive

Expand Down Expand Up @@ -305,8 +351,15 @@ jobs:
# valgrind is unavailable on macOS — valgrind specs already skip via @valgrind_available guard

# Install cppcheck via Homebrew
#
# aws/tap is pre-tapped on GitHub's hosted macOS runner image (unrelated to anything
# this repo uses) -- newer Homebrew warns about every untrusted tap present on any
# `brew install`, not just ones involved in that install, so it's untapped here rather
# than trusted or having tap-trust checks disabled outright. `|| true` in case a future
# runner image doesn't have it pre-tapped.
- name: "Install cppcheck for Tests of Ceedling Plugin: Cppcheck"
run: |
brew untap aws/tap || true
brew install cppcheck

# --break-system-packages required on macOS 14+ (PEP 668 prevents pip from installing
Expand Down Expand Up @@ -346,15 +399,15 @@ jobs:
name: "Linux Test Suite (ja_JP.UTF-8 Locale)"
runs-on: ubuntu-latest
steps:
- uses: actions/cache@v4
- uses: actions/cache@v6
with:
path: vendor/bundle
key: bundle-use-ruby-${{ runner.os }}-3.3-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
bundle-use-ruby-${{ runner.os }}-3.3-

- name: Checkout Latest Repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
submodules: recursive

Expand Down Expand Up @@ -399,7 +452,7 @@ jobs:
# Upload system test failure logs and temp project directories on test job failure
- name: Upload system test failure artifacts
if: failure()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: systest-failures-locale-ruby-3.3
path: systests/
Expand All @@ -417,15 +470,15 @@ jobs:
name: "Linux Encoding Stress Test (C/POSIX)"
runs-on: ubuntu-latest
steps:
- uses: actions/cache@v4
- uses: actions/cache@v6
with:
path: vendor/bundle
key: bundle-use-ruby-${{ runner.os }}-3.3-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
bundle-use-ruby-${{ runner.os }}-3.3-

- name: Checkout Latest Repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
submodules: recursive

Expand Down Expand Up @@ -471,7 +524,7 @@ jobs:
# Upload system test failure logs and temp project directories on test job failure
- name: Upload system test failure artifacts
if: failure()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: systest-failures-encoding-stress-ruby-3.3
path: systests/
Expand All @@ -494,15 +547,15 @@ jobs:
steps:
# Use a cache for our tools to speed up builds
# No matrix here; Ruby version is hardcoded to match the cache key format used by test jobs
- uses: actions/cache@v4
- uses: actions/cache@v6
with:
path: vendor/bundle
key: bundle-use-ruby-${{ runner.os }}-3.3-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
bundle-use-ruby-${{ runner.os }}-3.3-

- name: Checkout Latest Repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
submodules: recursive

Expand All @@ -517,7 +570,7 @@ jobs:

# Download HTML docs bundle built by generate-docs job to validate docs ingestion in gem build
- name: Download HTML Documentation Bundle
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: gem-docs-site-local
path: site-local/
Expand All @@ -528,7 +581,7 @@ jobs:

# Upload the built gem as a workflow artifact (downloadable from the Actions UI)
- name: Upload Built Gem Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: ceedling-gem
path: ceedling-*.gem
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ systest.pass.*
systest.fail.*
systests/

# Coverage report output (CEEDLING_TEST_COVERAGE test runs)
/coverage/

# Generated documentation site builds
site-web/
site-local/
Expand Down
39 changes: 39 additions & 0 deletions .simplecov
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# =========================================================================
# Ceedling - Test-Centered Build System for C
# ThrowTheSwitch.org
# Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
# SPDX-License-Identifier: MIT
# =========================================================================

# Shared SimpleCov configuration. The unit-test suite picks this up through
# SimpleCov's own upward-directory-search autoload (its CWD is this repo). The
# system-test suite's own subprocess boot (spec/support/system/simplecov_boot.rb)
# loads this file explicitly by absolute path instead, since that subprocess's CWD
# is a throwaway deployed project directory, not this repo, when it starts -- the
# autoload search would walk straight past it and find nothing.
#
# track_files (rather than only reporting files a run actually happened to require)
# means a file no test ever touches still shows up at 0% instead of being silently
# absent from the total -- lib/, bin/, and plugins/ are what the gem actually ships
# and what both test suites exercise; vendor/ is CMock/Unity/CException's own
# separately tested source, not this repo's. The /spec/ and /vendor/ filters below
# also cover the handful of plugins with their own nested spec/vendor code (e.g.
# plugins/fff/spec/, plugins/fff/vendor/fff/), not just this repo's own top-level
# spec/ and vendor/.
#
# One track_files call with a brace-glob covering all three trees, not three
# separate calls -- track_files stores a single glob rather than accumulating one,
# so each call replaces whatever the previous call set rather than adding to it.
#
# Grouped into the same three trees as a report's own tabs, so a report reads as
# "how well is each shipped piece covered" rather than one flat file list.
SimpleCov.start do
track_files '{lib,bin,plugins}/**/*.rb'

add_filter '/spec/'
add_filter '/vendor/'

add_group 'bin', '/bin/'
add_group 'lib', '/lib/'
add_group 'plugins', '/plugins/'
end
Loading
Loading