Skip to content

Commit 15b5a9b

Browse files
authored
Merge branch 'main' into cod-1742-codspeed-go-flamegraph-not-shown-for-many-benchmarks
2 parents b26947d + 66c66d7 commit 15b5a9b

File tree

22 files changed

+504
-40
lines changed

22 files changed

+504
-40
lines changed

CHANGELOG.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,36 @@
55

66

77

8+
## [4.4.1] - 2025-11-21
9+
10+
### <!-- 0 -->🚀 Features
11+
- Display oidc as announcement by @fargito
12+
- Add --allow-empty run option by @GuillaumeLagrange in [#160](https://github.com/CodSpeedHQ/runner/pull/160)
13+
14+
### <!-- 1 -->🐛 Bug Fixes
15+
- Do not espace trailing newlines in logger by @fargito
16+
- Make multiline logs appear correctly in summary by @fargito in [#162](https://github.com/CodSpeedHQ/runner/pull/162)
17+
- Request OIDC token just before upload by @fargito
18+
- Update docs links to oidc by @fargito in [#159](https://github.com/CodSpeedHQ/runner/pull/159)
19+
20+
21+
## [4.4.0] - 2025-11-19
22+
23+
### <!-- 0 -->🚀 Features
24+
- Add support for oidc token authentication by @fargito in [#156](https://github.com/CodSpeedHQ/runner/pull/156)
25+
- Accept simulation as runner mode by @GuillaumeLagrange in [#152](https://github.com/CodSpeedHQ/runner/pull/152)
26+
- Add a comment explaining why we do not check for emptiness in valgrind teardown by @GuillaumeLagrange in [#157](https://github.com/CodSpeedHQ/runner/pull/157)
27+
- Validate walltime results before uploading by @GuillaumeLagrange
28+
- Import walltime_results from monorepo by @GuillaumeLagrange
29+
30+
### <!-- 1 -->🐛 Bug Fixes
31+
- Dont start perf unless it's not already started by @not-matthias in [#158](https://github.com/CodSpeedHQ/runner/pull/158)
32+
- Use a line buffer when reading stdout/stderr streams by @GuillaumeLagrange
33+
34+
### <!-- 7 -->⚙️ Internals
35+
- Update AGENTS.md to use cargo nextest if available by @GuillaumeLagrange
36+
37+
838
## [4.3.4] - 2025-11-10
939

1040
### <!-- 0 -->🚀 Features
@@ -580,6 +610,8 @@
580610
- Add linting components to the toolchain by @art049
581611

582612

613+
[4.4.1]: https://github.com/CodSpeedHQ/runner/compare/v4.4.0..v4.4.1
614+
[4.4.0]: https://github.com/CodSpeedHQ/runner/compare/v4.3.4..v4.4.0
583615
[4.3.4]: https://github.com/CodSpeedHQ/runner/compare/v4.3.3..v4.3.4
584616
[4.3.3]: https://github.com/CodSpeedHQ/runner/compare/v4.3.2..v4.3.3
585617
[4.3.2]: https://github.com/CodSpeedHQ/runner/compare/v4.3.1..v4.3.2

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "codspeed-runner"
3-
version = "4.3.4"
3+
version = "4.4.1"
44
edition = "2024"
55
repository = "https://github.com/CodSpeedHQ/runner"
66
publish = false

src/app.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub struct Cli {
6060
#[derive(Subcommand, Debug)]
6161
enum Commands {
6262
/// Run the bench command and upload the results to CodSpeed
63-
Run(run::RunArgs),
63+
Run(Box<run::RunArgs>),
6464
/// Manage the CLI authentication state
6565
Auth(auth::AuthArgs),
6666
/// Pre-install the codspeed executors
@@ -88,7 +88,7 @@ pub async fn run() -> Result<()> {
8888

8989
match cli.command {
9090
Commands::Run(args) => {
91-
run::run(args, &api_client, &codspeed_config, setup_cache_dir).await?
91+
run::run(*args, &api_client, &codspeed_config, setup_cache_dir).await?
9292
}
9393
Commands::Auth(args) => auth::run(args, &api_client, cli.config_name.as_deref()).await?,
9494
Commands::Setup => setup::setup(setup_cache_dir).await?,

src/logger.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/// This target is used exclusively to handle group events.
22
pub const GROUP_TARGET: &str = "codspeed::group";
33
pub const OPENED_GROUP_TARGET: &str = "codspeed::group::opened";
4+
pub const ANNOUNCEMENT_TARGET: &str = "codspeed::announcement";
45

56
#[macro_export]
67
/// Start a new log group. All logs between this and the next `end_group!` will be grouped together.
@@ -43,6 +44,15 @@ macro_rules! end_group {
4344
};
4445
}
4546

47+
#[macro_export]
48+
/// Logs at the announcement level. This is intended for important announcements like new features,
49+
/// that do not require immediate user action.
50+
macro_rules! announcement {
51+
($name:expr) => {
52+
log::log!(target: $crate::logger::ANNOUNCEMENT_TARGET, log::Level::Info, "{}", $name);
53+
};
54+
}
55+
4656
pub enum GroupEvent {
4757
Start(String),
4858
StartOpened(String),
@@ -72,6 +82,14 @@ pub(super) fn get_group_event(record: &log::Record) -> Option<GroupEvent> {
7282
}
7383
}
7484

85+
pub(super) fn get_announcement_event(record: &log::Record) -> Option<String> {
86+
if record.target() != ANNOUNCEMENT_TARGET {
87+
return None;
88+
}
89+
90+
Some(record.args().to_string())
91+
}
92+
7593
#[macro_export]
7694
/// Log a structured JSON output
7795
macro_rules! log_json {

src/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pub use crate::{end_group, log_json, start_group, start_opened_group};
1+
pub use crate::{announcement, end_group, log_json, start_group, start_opened_group};
22
#[allow(unused_imports)]
33
pub use anyhow::{Context, Error, Result, anyhow, bail, ensure};
44
pub use itertools::Itertools;

src/request_client.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ use reqwest_middleware::{ClientBuilder as ClientWithMiddlewareBuilder, ClientWit
44
use reqwest_retry::{RetryTransientMiddleware, policies::ExponentialBackoff};
55

66
const UPLOAD_RETRY_COUNT: u32 = 3;
7+
const OIDC_RETRY_COUNT: u32 = 10;
8+
const USER_AGENT: &str = "codspeed-runner";
79

810
lazy_static! {
911
pub static ref REQUEST_CLIENT: ClientWithMiddleware = ClientWithMiddlewareBuilder::new(
1012
ClientBuilder::new()
11-
.user_agent("codspeed-runner")
13+
.user_agent(USER_AGENT)
1214
.build()
1315
.unwrap()
1416
)
@@ -19,7 +21,19 @@ lazy_static! {
1921

2022
// Client without retry middleware for streaming uploads (can't be cloned)
2123
pub static ref STREAMING_CLIENT: reqwest::Client = ClientBuilder::new()
22-
.user_agent("codspeed-runner")
24+
.user_agent(USER_AGENT)
2325
.build()
2426
.unwrap();
27+
28+
// Client with retry middleware for OIDC token requests
29+
pub static ref OIDC_CLIENT: ClientWithMiddleware = ClientWithMiddlewareBuilder::new(
30+
ClientBuilder::new()
31+
.user_agent(USER_AGENT)
32+
.build()
33+
.unwrap()
34+
)
35+
.with(RetryTransientMiddleware::new_with_policy(
36+
ExponentialBackoff::builder().build_with_max_retries(OIDC_RETRY_COUNT)
37+
))
38+
.build();
2539
}

src/run/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub struct Config {
2525
pub skip_upload: bool,
2626
pub skip_run: bool,
2727
pub skip_setup: bool,
28+
pub allow_empty: bool,
2829
}
2930

3031
#[derive(Debug, PartialEq, Clone)]
@@ -58,6 +59,7 @@ impl Config {
5859
skip_upload: false,
5960
skip_run: false,
6061
skip_setup: false,
62+
allow_empty: false,
6163
}
6264
}
6365
}
@@ -97,6 +99,7 @@ impl TryFrom<RunArgs> for Config {
9799
skip_upload: args.skip_upload,
98100
skip_run: args.skip_run,
99101
skip_setup: args.skip_setup,
102+
allow_empty: args.allow_empty,
100103
})
101104
}
102105
}
@@ -131,6 +134,7 @@ mod tests {
131134
skip_upload: false,
132135
skip_run: false,
133136
skip_setup: false,
137+
allow_empty: false,
134138
perf_run_args: PerfRunArgs {
135139
enable_perf: false,
136140
perf_unwinding_mode: None,
@@ -146,6 +150,7 @@ mod tests {
146150
assert!(!config.skip_upload);
147151
assert!(!config.skip_run);
148152
assert!(!config.skip_setup);
153+
assert!(!config.allow_empty);
149154
assert_eq!(config.command, "cargo codspeed bench");
150155
}
151156

@@ -165,6 +170,7 @@ mod tests {
165170
skip_upload: true,
166171
skip_run: true,
167172
skip_setup: true,
173+
allow_empty: true,
168174
perf_run_args: PerfRunArgs {
169175
enable_perf: false,
170176
perf_unwinding_mode: Some(UnwindingMode::FramePointer),
@@ -199,6 +205,7 @@ mod tests {
199205
assert!(config.skip_upload);
200206
assert!(config.skip_run);
201207
assert!(config.skip_setup);
208+
assert!(config.allow_empty);
202209
assert_eq!(config.command, "cargo codspeed bench");
203210
}
204211

src/run/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ pub struct RunArgs {
6868
pub upload_url: Option<String>,
6969

7070
/// The token to use for uploading the results,
71+
///
72+
/// It can be either a CodSpeed token retrieved from the repository setting
73+
/// or an OIDC token issued by the identity provider.
7174
#[arg(long, env = "CODSPEED_TOKEN")]
7275
pub token: Option<String>,
7376

@@ -127,6 +130,10 @@ pub struct RunArgs {
127130
#[arg(long, default_value = "false", hide = true)]
128131
pub skip_setup: bool,
129132

133+
/// Allow runs without any benchmarks to succeed instead of failing
134+
#[arg(long, default_value = "false", hide = true)]
135+
pub allow_empty: bool,
136+
130137
#[command(flatten)]
131138
pub perf_run_args: PerfRunArgs,
132139

@@ -166,6 +173,7 @@ impl RunArgs {
166173
skip_upload: false,
167174
skip_run: false,
168175
skip_setup: false,
176+
allow_empty: false,
169177
perf_run_args: PerfRunArgs {
170178
enable_perf: false,
171179
perf_unwinding_mode: None,
@@ -183,7 +191,7 @@ pub async fn run(
183191
) -> Result<()> {
184192
let output_json = args.message_format == Some(MessageFormat::Json);
185193
let mut config = Config::try_from(args)?;
186-
let provider = run_environment::get_provider(&config)?;
194+
let mut provider = run_environment::get_provider(&config)?;
187195
let logger = Logger::new(&provider)?;
188196

189197
#[allow(deprecated)]
@@ -205,6 +213,8 @@ pub async fn run(
205213
}
206214
debug!("Using the token from the CodSpeed configuration file");
207215
config.set_token(codspeed_config.auth.token.clone());
216+
} else {
217+
provider.check_oidc_configuration(&config)?;
208218
}
209219

210220
let system_info = SystemInfo::new()?;
@@ -255,6 +265,12 @@ pub async fn run(
255265
};
256266

257267
if !config.skip_upload {
268+
if provider.get_run_environment() != RunEnvironment::Local {
269+
// If relevant, set the OIDC token for authentication
270+
// Note: OIDC tokens can expire quickly, so we set it just before the upload
271+
provider.set_oidc_token(&mut config).await?;
272+
}
273+
258274
start_group!("Uploading performance data");
259275
let upload_result =
260276
uploader::upload(&config, &system_info, &provider, &run_data, executor.name()).await?;

src/run/run_environment/buildkite/logger.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
logger::{GroupEvent, get_group_event, get_json_event},
2+
logger::{GroupEvent, get_announcement_event, get_group_event, get_json_event},
33
run::run_environment::logger::should_provider_logger_handle_record,
44
};
55
use log::*;
@@ -53,6 +53,11 @@ impl Log for BuildkiteLogger {
5353
return;
5454
}
5555

56+
if let Some(announcement) = get_announcement_event(record) {
57+
println!("[ANNOUNCEMENT] {announcement}");
58+
return;
59+
}
60+
5661
if level > self.log_level {
5762
return;
5863
}

0 commit comments

Comments
 (0)