Skip to content
Open
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
29 changes: 29 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Nothing here is `force = true`, so a shell exporting `CFLAGS` or `CPATH` wins
# and breaks the musl build.
#
# `libbpf-sys` vendors elfutils, whose `configure` looks for `argp`, `obstack`
# and `fts`; musl has none of them, so it stops before libelf even though a
# libelf-only build never calls them. Pre-seeding the cache skips the checks.
# Only autoconf reads these names, so a gnu build is unaffected.
# Upstream tracks this at https://github.com/libbpf/libbpf-sys/issues/153.
[env]
ac_cv_search_argp_parse = "none required"
ac_cv_search__obstack_free = "none required"
ac_cv_search_fts_close = "none required"

# The `argp.h` stub. `CPATH` and not a `-I` in the flags below, because
# `relative = true` only works on a bare path. It is therefore global to the
# build, so the stub defers to the real header wherever one exists.
CPATH = { value = "crates/memtrack/musl", relative = true }

# Debian's musl-gcc runs with -nostdinc, so the kernel UAPI headers libbpf needs
# have to be added back, last so they never shadow the toolchain's own. Scoped
# per target: cc-rs looks up `CFLAGS_<target>` before `CFLAGS`, and libbpf-sys
# builds zlib, elfutils and libbpf from `cc::Tool::cflags_env()`.
CFLAGS_x86_64_unknown_linux_musl = "-idirafter /usr/include/x86_64-linux-gnu -idirafter /usr/include"
CFLAGS_aarch64_unknown_linux_musl = "-idirafter /usr/include/aarch64-linux-gnu -idirafter /usr/include"

# rustc links with `-nodefaultlibs`; libbpf's C code needs the outline-atomic
# helpers from libgcc on aarch64.
[target.aarch64-unknown-linux-musl]
rustflags = ["-C", "link-arg=-lgcc"]
55 changes: 38 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ jobs:
- uses: ./.github/actions/install-rust
with:
components: rustfmt, clippy
# Building the runner builds memtrack's vendored libbpf-sys with it.
- uses: ./.github/actions/install-bpf-deps
if: matrix.os == 'ubuntu-latest'
Comment thread
moha-bekh marked this conversation as resolved.
- uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4
with:
extra-args: --all-files
Expand Down Expand Up @@ -77,6 +80,7 @@ jobs:
with:
submodules: true
- uses: ./.github/actions/install-rust
- uses: ./.github/actions/install-bpf-deps
- name: Run tests
run: cargo run -- exec -m simulation,walltime,memory --warmup-time 0s --max-rounds 5 -- sleep 1

Expand All @@ -87,10 +91,6 @@ jobs:
with:
submodules: true
- uses: ./.github/actions/install-rust
- name: Install exec-harness
run: |
cargo install --path crates/exec-harness --locked

- name: Run tests
env:
# Profiling system commands (e.g. `ls`) with samply is not yet supported on MacOS
Expand Down Expand Up @@ -209,13 +209,6 @@ jobs:
- uses: ./.github/actions/install-rust
- uses: ./.github/actions/install-bpf-deps

- name: Install memtrack
uses: baptiste0928/cargo-install@8195d4f734a149db85385bb4102b42efcd373759 # v3.5.0
with:
crate: memtrack
git: https://github.com/CodSpeedHQ/codspeed
commit: ${{ env.CODSPEED_REV }}

- name: Install codspeed-runner
uses: baptiste0928/cargo-install@8195d4f734a149db85385bb4102b42efcd373759 # v3.5.0
with:
Expand All @@ -229,16 +222,17 @@ jobs:
- name: Reuse the cached runner install
run: echo "CARGO_INSTALL_ROOT=$HOME/.cargo-install/codspeed-runner" >> "$GITHUB_ENV"

- name: Verify installed binaries
- name: Verify the installed binary
run: |
which codspeed codspeed-memtrack
which codspeed
codspeed --version
codspeed-memtrack --version

# The benchmarked command is memtrack itself, which needs file capabilities
# to load its eBPF programs even though the runner measures walltime.
# The benchmarked command is memtrack, a subcommand of the runner binary,
# which needs file capabilities to load its eBPF programs even though the
# runner measures walltime. `setup --mode memory` would grant them to a
# private copy, not to the binary the benchmarks call.
- name: Grant memtrack file capabilities
run: codspeed setup --mode memory
run: sudo setcap cap_dac_read_search,cap_sys_admin,cap_perfmon,cap_bpf,cap_sys_resource+ep "$(which codspeed)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the way to do it. We are duplicating the capabilities list

I want us to keep the codspeed setup --mode memory path here, we just need to find a way for the benchmark to properly use the setcapped binary.

Whatever is chosen as a solution, it will be better than this


# The write benchmarks overwrite these files every round; creating them
# inside a measured round would time one-off disk allocation.
Expand All @@ -256,6 +250,32 @@ jobs:
runner-version: rev:${{ env.CODSPEED_REV }}
skip-hash-check-warning: true

musl-build:
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-latest
target: x86_64-unknown-linux-musl
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: true
- uses: ./.github/actions/install-rust
with:
cache-key: ${{ matrix.target }}
- uses: ./.github/actions/install-bpf-deps
- name: Install the musl toolchain
run: |
sudo apt-get install -y musl-tools linux-libc-dev
rustup target add "${{ matrix.target }}"

- name: Build
run: cargo build --bin codspeed --target "${{ matrix.target }}"

check:
runs-on: ubuntu-latest
if: always()
Expand All @@ -267,6 +287,7 @@ jobs:
- basic-run-test
- macos-basic-run-test
- bpf-tests
- musl-build
- benchmarks
- memtrack-benchmarks
steps:
Expand Down
50 changes: 10 additions & 40 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,24 @@ prek install

## Release Process

This repository is a Cargo workspace containing multiple crates. The release process differs depending on which crate you're releasing.
This repository is a Cargo workspace, but only the main runner is released. The other crates
are linked into its binary.

### Workspace Structure

- **`codspeed-runner`**: The main CLI binary (`codspeed`)
- **`memtrack`**: Memory tracking binary (`codspeed-memtrack`)
- **`exec-harness`**: Execution harness binary
- **`memtrack`**: Memory tracker, reached as `codspeed memtrack`
- **`exec-harness`**: Execution harness, reached as `codspeed exec-harness`
- **`runner-shared`**: Shared library used by other crates

### Releasing Support Crates (memtrack, exec-harness, runner-shared)

For any crate other than the main runner:

```bash
cargo release -p <PACKAGE_NAME> --execute <VERSION_BUMP>
```

Where `<VERSION_BUMP>` is one of: `alpha`, `beta`, `patch`, `minor`, or `major`.

**Examples:**

```bash
# Release a new patch version of memtrack
cargo release -p memtrack --execute patch

# Release a beta version of exec-harness
cargo release -p exec-harness --execute beta
```

#### Post-Release: Update Version References

After releasing `memtrack` or `exec-harness`, you **must** update the version references in the runner code:

1. **For memtrack**: Update the `MEMTRACK_INSTALLER` pin record in `src/binary_pins.rs` (see [Pinned binary hashes](#pinned-binary-hashes) below).

2. **For exec-harness**: Update the `EXEC_HARNESS_INSTALLER` pin record in `src/binary_pins.rs`.

These constants are used by the runner to download and install the correct versions of the binaries from GitHub releases.
`memtrack` and `exec-harness` keep a `version` in their `Cargo.toml` — what
`codspeed exec-harness --version` reports — but bumping it is a plain edit, not a release.
Comment on lines +23 to +24

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can remove this statement, does not bring much value


### Pinned binary hashes

Every binary the runner downloads at install time is SHA-256-pinned. The pins live in two places:

- **`src/binary_pins.rs`** — the patched valgrind `.deb`, the memtrack installer, the exec-harness installer, and the mongo-tracer installer. Each artifact keeps its version, URL template, and hash together in a pin record.
- **`src/binary_pins.rs`** — the patched valgrind `.deb` and the mongo-tracer installer. Each artifact keeps its version, URL template, and hash together in a pin record.
- **`src/executor/helpers/introspected_golang/go.sh`** — the go-runner installer published by [CodSpeedHQ/codspeed-go](https://github.com/CodSpeedHQ/codspeed-go), one `<version> <sha256>` row per release in the `GO_RUNNER_INSTALLER_SHA256S` table. `DEFAULT_GO_RUNNER_VERSION` (just below the table) selects the row used by default.

When you bump a pinned version (or add a new go-runner row), update the matching pin record / table row with the new version and its SHA-256.
Expand Down Expand Up @@ -84,16 +58,12 @@ These tests also run in CI, but running them locally before opening the PR avoid

### Releasing the Main Runner

The main runner (`codspeed-runner`) should be released after ensuring all dependency versions are correct.
The main runner (`codspeed-runner`) is the only crate that is released.

#### Pre-Release Check

**Verify binary version references**: Check that version constants in the runner code match the released versions:

- `MEMTRACK_VERSION` in `src/binary_pins.rs`
- `EXEC_HARNESS_VERSION` in `src/binary_pins.rs`

Also confirm the SHA-256 entries in the pin records in `src/binary_pins.rs` match the released artifacts.
Confirm the SHA-256 entries in the pin records in `src/binary_pins.rs` match the released
artifacts they point at.

#### Release Command

Expand Down
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 20 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "codspeed-runner"
version = "5.4.0"
version.workspace = true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only codspeed-runner gets released, so every crate should keep a literal version = "x.y.z" in its own Cargo.toml: revert this since it breaks cargo-release (try cargo release patch -p codspeed-runner

Any other crate with a binary must keep [package.metadata.dist] dist = false so cargo-dist only ships codspeed. Please restore the old versions, keep the dist opt-outs.

Disregard my previous comment about unifying versions, we do not care it's okay, just make sure the non codspeed-runner binaries are properly opted out from cargo dist.

edition = "2024"
repository = "https://github.com/CodSpeedHQ/codspeed"
publish = false
Expand Down Expand Up @@ -77,12 +77,13 @@ uuid = { version = "1.23.1", features = ["v4"] }
which = "8.0.2"
crc32fast = "1.5.0"
samply = { path = "crates/samply-codspeed/samply" }
mimalloc = "0.1"

# Memory profiling (memtrack) and the capability handling around it are Linux-only.
[target.'cfg(target_os = "linux")'.dependencies]
procfs = "0.18"
caps = "0.5"
memtrack = { path = "crates/memtrack", default-features = false }
memtrack = { path = "crates/memtrack" }
ipc-channel = { workspace = true }

[dev-dependencies]
Expand All @@ -95,6 +96,9 @@ assert_cmd = "2.2"
predicates = "3.1.4"
strum = { version = "0.28.0", features = ["derive"] }

[workspace.package]
version = "5.4.0"

[workspace]
members = [
"crates/runner-shared",
Expand Down Expand Up @@ -145,3 +149,17 @@ targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-musl", "x86_64-unknown
binaries.aarch64-apple-darwin = ["codspeed"]
binaries.aarch64-unknown-linux-musl = ["codspeed"]
binaries.x86_64-unknown-linux-musl = ["codspeed"]

# memtrack's vendored libbpf/elfutils build runs as part of this package.
[package.metadata.dist.dependencies.apt]
build-essential = "*"
pkgconf = "*"
zlib1g-dev = "*"
libbpf-dev = "*"
musl-tools = "*"
linux-libc-dev = "*"

# Required for the vendored feature
autopoint = "*"
bison = "*"
flex = "*"
5 changes: 3 additions & 2 deletions crates/exec-harness/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "exec-harness"
version = "1.3.0"
version.workspace = true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this, it's okay keep the old version we dont care

edition = "2024"
repository = "https://github.com/CodSpeedHQ/codspeed"
publish = false
Expand Down Expand Up @@ -28,5 +28,6 @@ rstest = { workspace = true }
[build-dependencies]
cc = "1"

# Bundled in the runner binary, not released on its own.
[package.metadata.dist]
targets = ["aarch64-unknown-linux-gnu", "x86_64-unknown-linux-gnu"]
dist = false
Loading
Loading