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
10 changes: 10 additions & 0 deletions .github/actions/rust-install/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: "Install Rust toolchain"
description: "Install the Rust toolchain from rust-toolchain.toml and cache cargo artifacts"

runs:
using: "composite"
steps:
- name: Install rust-toolchain.toml
shell: bash
run: rustup show
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
35 changes: 24 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
with:
submodules: true
- uses: actions/setup-go@v5
- uses: moonrepo/setup-rust@v1
- uses: ./.github/actions/rust-install
- uses: pre-commit/action@v3.0.1
with:
extra_args: --all-files
Expand All @@ -36,7 +36,7 @@
go-version: ${{ matrix.go-version }}
- uses: taiki-e/install-action@cargo-nextest

- uses: moonrepo/setup-rust@v1
- uses: ./.github/actions/rust-install
- run: |
cd go-runner
cargo nextest run --all
Expand All @@ -53,9 +53,7 @@
with:
submodules: true
- uses: actions/setup-go@v5
- uses: moonrepo/setup-rust@v1
with:
cache-target: release
- uses: ./.github/actions/rust-install

- name: Run the benchmarks
uses: CodSpeedHQ/action@main
Expand All @@ -66,19 +64,33 @@
working-directory: example
run: cargo r --release --manifest-path ../go-runner/Cargo.toml -- test -bench=. ${{ matrix.target }}

example-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-go@v6
with:
go-version: '1.25.x'
- uses: ./.github/actions/rust-install

- name: Run the benchmarks
run: cargo r --release --manifest-path ../go-runner/Cargo.toml -- test -bench=. example
working-directory: example
env:
CODSPEED_GO_PKG_VERSION: ${{ github.head_ref || github.ref_name }}

go-runner-benchmarks:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
runs-on: codspeed-macro
steps:
- uses: actions/checkout@v4
with:
lfs: true
submodules: true
- name: Setup rust toolchain, cache and cargo-codspeed binary
uses: moonrepo/setup-rust@v1
with:
channel: stable
cache-target: release
bins: cargo-codspeed
- uses: ./.github/actions/rust-install
- name: Install cargo-codspeed
run: cargo install cargo-codspeed

- uses: actions/setup-go@v5
with:
Expand All @@ -100,6 +112,7 @@
- lint
- tests
- compat-integration-test-walltime
- example-macos
- go-runner-benchmarks
steps:
- uses: re-actors/alls-green@release/v1
Expand Down
38 changes: 19 additions & 19 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,17 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
persist-credentials: false
submodules: recursive
- name: Install dist
# we specify bash to get pipefail; it guards against the `curl` command
# failing. otherwise `sh` won't catch that `curl` returned non-0
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.29.0/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.31.0/cargo-dist-installer.sh | sh"
- name: Cache dist
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: cargo-dist-cache
path: ~/.cargo/bin/dist
Expand All @@ -82,7 +82,7 @@ jobs:
cat plan-dist-manifest.json
echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: artifacts-plan-dist-manifest
path: plan-dist-manifest.json
Expand Down Expand Up @@ -116,7 +116,7 @@ jobs:
- name: enable windows longpaths
run: |
git config --global core.longpaths true
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
persist-credentials: false
submodules: recursive
Expand All @@ -131,7 +131,7 @@ jobs:
run: ${{ matrix.install_dist.run }}
# Get the dist-manifest
- name: Fetch local artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
pattern: artifacts-*
path: target/distrib/
Expand All @@ -158,7 +158,7 @@ jobs:

cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: artifacts-build-local-${{ join(matrix.targets, '_') }}
path: |
Expand All @@ -175,19 +175,19 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
- name: Fetch local artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
pattern: artifacts-*
path: target/distrib/
Expand All @@ -205,7 +205,7 @@ jobs:

cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: artifacts-build-global
path: |
Expand All @@ -217,27 +217,27 @@ jobs:
- plan
- build-local-artifacts
- build-global-artifacts
# Only run if we're "publishing", and only if local and global didn't fail (skipped is fine)
if: ${{ always() && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }}
# Only run if we're "publishing", and only if plan, local and global didn't fail (skipped is fine)
if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
runs-on: "ubuntu-22.04"
outputs:
val: ${{ steps.host.outputs.manifest }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
pattern: artifacts-*
path: target/distrib/
Expand All @@ -250,14 +250,14 @@ jobs:
cat dist-manifest.json
echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
# Overwrite the previous copy
name: artifacts-dist-manifest
path: dist-manifest.json
# Create a GitHub Release while uploading all files to it
- name: "Download GitHub Artifacts"
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
pattern: artifacts-*
path: artifacts
Expand Down Expand Up @@ -290,7 +290,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
persist-credentials: false
submodules: recursive
4 changes: 2 additions & 2 deletions dist-workspace.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ members = ["cargo:."]
# Whether to consider the binaries in a package for distribution (defaults true)
dist = true
# The preferred dist version to use in CI (Cargo.toml SemVer syntax)
cargo-dist-version = "0.29.0"
cargo-dist-version = "0.31.0"
# CI backends to support
ci = "github"
# The installers to generate for each app
installers = ["shell"]
# Target platforms to build apps for (Rust target-triple syntax)
targets = ["aarch64-unknown-linux-musl", "x86_64-unknown-linux-musl"]
targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-musl", "x86_64-unknown-linux-musl"]
# Path that installers should place binaries in
install-path = "CARGO_HOME"
# Whether to install an updater program
Expand Down
6 changes: 6 additions & 0 deletions go-runner/overlay/codspeed.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ func ensureBenchmarkIsStopped(b *B) {
}

func (b *B) AddBenchmarkMarkers(endTimestamp uint64) {
// When instrument hooks are stubs (e.g. on macOS), CurrentTimestamp returns 0.
// Skip marker collection in that case — timestamps are only meaningful when instrumented.
if b.startTimestamp == 0 && endTimestamp == 0 {
return
}

if b.startTimestamp >= endTimestamp {
// This should never happen, unless we have a bug in the timer logic.
panic(fmt.Sprintf("Invalid benchmark timestamps: start timestamp (%d) is greater than or equal to end timestamp (%d)", b.startTimestamp, endTimestamp))
Expand Down
10 changes: 3 additions & 7 deletions go-runner/overlay/instrument-hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ package testing
/*
#cgo CFLAGS: -I@@INSTRUMENT_HOOKS_DIR@@/includes -Wno-format -Wno-format-security
#include "@@INSTRUMENT_HOOKS_DIR@@/dist/core.c"

#define MARKER_TYPE_BENCHMARK_START c_MARKER_TYPE_BENCHMARK_START__247
#define MARKER_TYPE_BENCHMARK_END c_MARKER_TYPE_BENCHMARK_END__248
typedef struct instrument_hooks_InstrumentHooks__547 InstrumentHooks;
*/
import "C"
import (
Expand Down Expand Up @@ -51,7 +47,7 @@ func (i *InstrumentHooks) SetIntegration(name, version string) {
defer C.free(unsafe.Pointer(nameC))
defer C.free(unsafe.Pointer(versionC))

C.instrument_hooks_set_integration(i.hooks, (*C.uint8_t)(unsafe.Pointer(nameC)), (*C.uint8_t)(unsafe.Pointer(versionC)))
C.instrument_hooks_set_integration(i.hooks, nameC, versionC)
}

func (i *InstrumentHooks) StartBenchmark() {
Expand All @@ -73,7 +69,7 @@ func (i *InstrumentHooks) SetExecutedBenchmark(pid uint32, name string) {
nameC := C.CString(name)
defer C.free(unsafe.Pointer(nameC))

C.instrument_hooks_set_executed_benchmark(i.hooks, C.uint(pid), (*C.uint8_t)(unsafe.Pointer(nameC)))
C.instrument_hooks_set_executed_benchmark(i.hooks, C.uint(pid), nameC)
}

func (i *InstrumentHooks) IsInstrumented() bool {
Expand Down Expand Up @@ -107,7 +103,7 @@ func (i *InstrumentHooks) SetEnvironment(sectionName, key, value string) {
defer C.free(unsafe.Pointer(keyC))
defer C.free(unsafe.Pointer(valueC))

C.instrument_hooks_set_environment(i.hooks, (*C.uint8_t)(unsafe.Pointer(sectionNameC)), (*C.uint8_t)(unsafe.Pointer(keyC)), (*C.uint8_t)(unsafe.Pointer(valueC)))
C.instrument_hooks_set_environment(i.hooks, sectionNameC, keyC, valueC)
}

func (i *InstrumentHooks) WriteEnvironment(pid uint32) {
Expand Down
14 changes: 13 additions & 1 deletion go-runner/src/runner/overlay/instrument_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,23 @@ use tar::Archive;
use tempfile::TempDir;

const INSTRUMENT_HOOKS_REPO: &str = "CodSpeedHQ/instrument-hooks";
const INSTRUMENT_HOOKS_COMMIT: &str = "0c971823b17cb5a3bbd0cce4411cbee2c6fe4317";
const INSTRUMENT_HOOKS_COMMIT: &str = "662fbd3b90eed7b52018bc8b9b6bf493e102bd6f";

/// Get the instrument-hooks directory, downloading if necessary
/// Downloads to /tmp/codspeed-instrument-hooks-{commit}/
pub fn download_instrument_hooks(temp_dir: &TempDir) -> Result<PathBuf> {
// Allow overriding with a local path for development
if let Ok(local_path) = std::env::var("CODSPEED_INSTRUMENT_HOOKS_DIR") {
let path = PathBuf::from(local_path);
ensure!(
path.exists(),
"CODSPEED_INSTRUMENT_HOOKS_DIR path does not exist: {:?}",
path
);
debug!("Using local instrument-hooks at {:?}", path);
return Ok(path);
}

let hooks_dir = temp_dir
.path()
.join(format!("instrument-hooks-{}", INSTRUMENT_HOOKS_COMMIT));
Expand Down
Loading