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
128 changes: 128 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: benchmark

# Reusable performance benchmark + regression alert for BOTH tiers. Sets up the
# toolchain, runs a caller bench command that writes an output file, then
# github-action-benchmark compares against history and fails on regression.
# History is stored on a gh-pages branch, so the caller grants contents: write.

on:
workflow_call:
inputs:
runner:
type: string
default: 'ubuntu-latest'
language:
description: 'Toolchain to set up: python, rust, node, go, or none.'
type: string
default: 'python'
working_directory:
type: string
default: '.'
python_version:
type: string
default: '3.13'
node_version:
type: string
default: '22'
rust_toolchain:
type: string
default: 'stable'
go_version:
type: string
default: 'stable'
bench_command:
description: 'Command that runs benchmarks and writes output_file_path.'
type: string
default: ''
tool:
description: 'github-action-benchmark tool: cargo, pytest, benchmarkjs, go, googlecpp, ...'
type: string
default: 'pytest'
output_file_path:
type: string
default: 'output.json'
alert_threshold:
type: string
default: '200%'
fail_on_alert:
type: boolean
default: true
auto_push:
description: 'Store history on gh-pages (requires contents: write).'
type: boolean
default: true
enable_harden_runner:
type: boolean
default: true
timeout_minutes:
type: number
default: 30

permissions: {}

defaults:
run:
shell: bash

jobs:
benchmark:
name: benchmark (${{ inputs.language }})
runs-on: ${{ inputs.runner }}
timeout-minutes: ${{ inputs.timeout_minutes }}
permissions:
contents: write
defaults:
run:
working-directory: ${{ inputs.working_directory }}
steps:
- name: Harden runner
if: ${{ inputs.enable_harden_runner }}
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Set up Python
if: ${{ inputs.language == 'python' }}
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ inputs.python_version }}

- name: Set up Node.js
if: ${{ inputs.language == 'node' }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ inputs.node_version }}

- name: Set up Rust
if: ${{ inputs.language == 'rust' }}
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
toolchain: ${{ inputs.rust_toolchain }}

- name: Set up Go
if: ${{ inputs.language == 'go' }}
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version: ${{ inputs.go_version }}

- name: Run benchmarks
if: ${{ inputs.bench_command != '' }}
env:
BENCH_COMMAND: ${{ inputs.bench_command }}
run: bash -c "$BENCH_COMMAND"

- name: Compare and alert
uses: benchmark-action/github-action-benchmark@52576c92bccf6ac60c8223ec7eb2565637cae9ba # v1.22.1
with:
tool: ${{ inputs.tool }}
output-file-path: ${{ inputs.output_file_path }}
github-token: ${{ secrets.GITHUB_TOKEN }}
alert-threshold: ${{ inputs.alert_threshold }}
fail-on-alert: ${{ inputs.fail_on_alert }}
auto-push: ${{ inputs.auto_push }}
comment-on-alert: false
99 changes: 99 additions & 0 deletions .github/workflows/coverage-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: coverage-gate

# Reusable coverage upload for BOTH tiers: harden-runner, a caller-provided
# coverage command, and a Codecov upload (free on public; token-gated on
# private) with an optional Coveralls upload. Coverage thresholds are enforced by
# the caller's codecov.yml, not here.

on:
workflow_call:
inputs:
runner:
type: string
default: 'ubuntu-latest'
working_directory:
type: string
default: '.'
coverage_command:
description: 'Command (bash) that produces a coverage report. Empty to skip.'
type: string
default: ''
files:
description: 'Coverage file(s) to upload (comma-separated). Empty lets Codecov search.'
type: string
default: ''
flags:
type: string
default: ''
fail_ci_if_error:
type: boolean
default: true
use_codecov:
type: boolean
default: true
use_coveralls:
type: boolean
default: false
coveralls_file:
description: 'Coverage file for Coveralls, e.g. coverage/lcov.info.'
type: string
default: ''
enable_harden_runner:
type: boolean
default: true
timeout_minutes:
type: number
default: 20
secrets:
codecov_token:
required: false

permissions: {}

defaults:
run:
shell: bash

jobs:
coverage:
name: coverage
runs-on: ${{ inputs.runner }}
timeout-minutes: ${{ inputs.timeout_minutes }}
permissions:
contents: read
defaults:
run:
working-directory: ${{ inputs.working_directory }}
steps:
- name: Harden runner
if: ${{ inputs.enable_harden_runner }}
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Produce coverage
if: ${{ inputs.coverage_command != '' }}
env:
COVERAGE_COMMAND: ${{ inputs.coverage_command }}
run: bash -c "$COVERAGE_COMMAND"

- name: Upload to Codecov
if: ${{ inputs.use_codecov }}
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
token: ${{ secrets.codecov_token }}
files: ${{ inputs.files }}
flags: ${{ inputs.flags }}
fail_ci_if_error: ${{ inputs.fail_ci_if_error }}

- name: Upload to Coveralls
if: ${{ inputs.use_coveralls }}
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ inputs.coveralls_file }}
140 changes: 140 additions & 0 deletions .github/workflows/cpp-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: cpp-ci

# Reusable C/C++ CI for BOTH tiers: harden-runner, optional apt packages and
# ccache, clang-format + cppcheck static gates, and caller-provided
# configure/build/test commands passed via env. Defaults target a CMake project;
# override the commands for Make/Meson/Bazel.

on:
workflow_call:
inputs:
runner:
type: string
default: 'ubuntu-latest'
working_directory:
type: string
default: '.'
apt_packages:
description: 'Extra apt packages (space-separated), e.g. "cppcheck clang-tidy ninja-build".'
type: string
default: ''
enable_ccache:
description: 'Restore/save a ccache cache (wire -DCMAKE_CXX_COMPILER_LAUNCHER=ccache to use it).'
type: boolean
default: false
ccache_key:
type: string
default: 'cpp-ci'
configure_command:
description: 'Configure command (bash). Empty to skip.'
type: string
default: 'cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug'
build_command:
description: 'Build command (bash). Empty to skip.'
type: string
default: 'cmake --build build --parallel'
test_command:
description: 'Test command (bash). Empty to skip.'
type: string
default: 'ctest --test-dir build --output-on-failure'
format_check:
description: 'Run clang-format --dry-run -Werror over format_paths.'
type: boolean
default: false
format_paths:
description: 'Space-separated globs for clang-format when format_check is true.'
type: string
default: 'src/**/*.cpp src/**/*.hpp'
cppcheck:
description: 'Run cppcheck (add "cppcheck" to apt_packages).'
type: boolean
default: false
cppcheck_args:
type: string
default: '--enable=warning,portability --error-exitcode=1 .'
enable_harden_runner:
type: boolean
default: true
timeout_minutes:
type: number
default: 30

permissions: {}

defaults:
run:
shell: bash

jobs:
cpp:
name: cpp
runs-on: ${{ inputs.runner }}
timeout-minutes: ${{ inputs.timeout_minutes }}
permissions:
contents: read
defaults:
run:
working-directory: ${{ inputs.working_directory }}
steps:
- name: Harden runner
if: ${{ inputs.enable_harden_runner }}
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Install apt packages
if: ${{ inputs.apt_packages != '' }}
env:
APT_PACKAGES: ${{ inputs.apt_packages }}
run: |
sudo apt-get update
# shellcheck disable=SC2086
sudo apt-get install -y --no-install-recommends $APT_PACKAGES

- name: Set up ccache
if: ${{ inputs.enable_ccache }}
uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23
with:
key: ${{ inputs.ccache_key }}

- name: Format check
if: ${{ inputs.format_check }}
env:
FORMAT_PATHS: ${{ inputs.format_paths }}
run: |
# shellcheck disable=SC2086
clang-format --dry-run -Werror $FORMAT_PATHS

- name: Configure
if: ${{ inputs.configure_command != '' }}
env:
CONFIGURE_COMMAND: ${{ inputs.configure_command }}
run: bash -c "$CONFIGURE_COMMAND"

- name: Build
if: ${{ inputs.build_command != '' }}
env:
BUILD_COMMAND: ${{ inputs.build_command }}
run: bash -c "$BUILD_COMMAND"

- name: cppcheck
if: ${{ inputs.cppcheck }}
env:
CPPCHECK_ARGS: ${{ inputs.cppcheck_args }}
run: |
# shellcheck disable=SC2086
cppcheck $CPPCHECK_ARGS

- name: Test
if: ${{ inputs.test_command != '' }}
env:
TEST_COMMAND: ${{ inputs.test_command }}
run: bash -c "$TEST_COMMAND"

- name: Summary
run: echo "C/C++ CI (configure + build + test) passed." >> "$GITHUB_STEP_SUMMARY"
Loading