Skip to content

Commit 71e2d77

Browse files
feat: check for repository existence before run in local runs
1 parent 57ce03e commit 71e2d77

11 files changed

Lines changed: 262 additions & 176 deletions

File tree

src/api_client.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,24 @@ nest! {
218218
}
219219
}
220220

221+
#[derive(Serialize, Clone)]
222+
#[serde(rename_all = "camelCase")]
223+
pub struct GetRepositoryVars {
224+
pub owner: String,
225+
pub name: String,
226+
pub provider: RepositoryProvider,
227+
}
228+
229+
nest! {
230+
#[derive(Debug, Deserialize, Serialize)]*
231+
#[serde(rename_all = "camelCase")]*
232+
struct GetRepositoryData {
233+
repository: Option<pub struct GetRepositoryPayload {
234+
pub id: String,
235+
}>
236+
}
237+
}
238+
221239
impl CodSpeedAPIClient {
222240
pub async fn create_login_session(&self) -> Result<CreateLoginSessionPayload> {
223241
let response = self
@@ -294,6 +312,31 @@ impl CodSpeedAPIClient {
294312
Err(err) => bail!("Failed to get or create project repository: {err}"),
295313
}
296314
}
315+
316+
/// Check if a repository exists in CodSpeed.
317+
/// Returns Some(payload) if the repository exists, None otherwise.
318+
pub async fn get_repository(
319+
&self,
320+
vars: GetRepositoryVars,
321+
) -> Result<Option<GetRepositoryPayload>> {
322+
let response = self
323+
.gql_client
324+
.query_with_vars_unwrap::<GetRepositoryData, GetRepositoryVars>(
325+
include_str!("queries/GetRepository.gql"),
326+
vars.clone(),
327+
)
328+
.await;
329+
match response {
330+
Ok(response) => Ok(response.repository),
331+
Err(err) if err.contains_error_code("REPOSITORY_NOT_FOUND") => Ok(None),
332+
Err(err) if err.contains_error_code("UNAUTHENTICATED") => {
333+
bail!("Your session has expired, please login again using `codspeed auth login`")
334+
}
335+
Err(err) => {
336+
bail!("Failed to get repository: {err}")
337+
}
338+
}
339+
}
297340
}
298341

299342
impl CodSpeedAPIClient {

src/cli/exec/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,10 @@ pub async fn execute_with_harness(
9696
codspeed_config: &CodSpeedConfig,
9797
setup_cache_dir: Option<&Path>,
9898
) -> Result<()> {
99-
let mut execution_context = executor::ExecutionContext::try_from((config, codspeed_config))?;
99+
let mut execution_context =
100+
executor::ExecutionContext::new(config, codspeed_config, api_client).await?;
100101

101-
if execution_context.is_local() {
102+
if !execution_context.is_local() {
102103
super::show_banner();
103104
}
104105

@@ -128,7 +129,6 @@ pub async fn execute_with_harness(
128129
&mut execution_context,
129130
setup_cache_dir,
130131
poll_results_fn,
131-
api_client,
132132
)
133133
.await?;
134134

src/cli/run/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub async fn run(
144144

145145
// Create execution context
146146
let mut execution_context =
147-
executor::ExecutionContext::try_from((config, codspeed_config))?;
147+
executor::ExecutionContext::new(config, codspeed_config, api_client).await?;
148148

149149
if !execution_context.is_local() {
150150
super::show_banner();
@@ -162,7 +162,6 @@ pub async fn run(
162162
&mut execution_context,
163163
setup_cache_dir,
164164
poll_results_fn,
165-
api_client,
166165
)
167166
.await?;
168167
}

src/executor/execution_context.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::Config;
2+
use crate::api_client::CodSpeedAPIClient;
23
use crate::cli::run::logger::Logger;
34
use crate::config::CodSpeedConfig;
45
use crate::prelude::*;
@@ -29,15 +30,13 @@ impl ExecutionContext {
2930
pub fn is_local(&self) -> bool {
3031
self.provider.get_run_environment() == RunEnvironment::Local
3132
}
32-
}
33-
34-
impl TryFrom<(Config, &CodSpeedConfig)> for ExecutionContext {
35-
type Error = anyhow::Error;
3633

37-
fn try_from(
38-
(mut config, codspeed_config): (Config, &CodSpeedConfig),
39-
) -> Result<Self, Self::Error> {
40-
let provider = run_environment::get_provider(&config)?;
34+
pub async fn new(
35+
mut config: Config,
36+
codspeed_config: &CodSpeedConfig,
37+
api_client: &CodSpeedAPIClient,
38+
) -> Result<Self> {
39+
let provider = run_environment::get_provider(&config, api_client).await?;
4140
let system_info = SystemInfo::new()?;
4241
system::check_system(&system_info)?;
4342
let logger = Logger::new(provider.as_ref())?;

src/executor/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ mod tests;
1111
mod valgrind;
1212
mod wall_time;
1313

14-
use crate::api_client::CodSpeedAPIClient;
1514
use crate::instruments::mongo_tracer::{MongoTracer, install_mongodb_tracer};
1615
use crate::prelude::*;
1716
use crate::runner_mode::RunnerMode;
@@ -89,7 +88,6 @@ pub async fn execute_benchmarks<F>(
8988
execution_context: &mut ExecutionContext,
9089
setup_cache_dir: Option<&Path>,
9190
poll_results: F,
92-
api_client: &CodSpeedAPIClient,
9391
) -> Result<()>
9492
where
9593
F: AsyncFn(&UploadResult) -> Result<()>,
@@ -150,8 +148,7 @@ where
150148
}
151149

152150
start_group!("Uploading results");
153-
let upload_result =
154-
crate::upload::upload(execution_context, executor.name(), api_client).await?;
151+
let upload_result = crate::upload::upload(execution_context, executor.name()).await?;
155152

156153
if execution_context.is_local() {
157154
poll_results(&upload_result).await?;

src/executor/tests.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,15 @@ fn exec_harness_test_cases() -> Vec<&'static str> {
132132
fn env_test_cases(#[case] env_case: (&str, &str)) {}
133133

134134
async fn create_test_setup(config: Config) -> (ExecutionContext, TempDir) {
135+
use crate::api_client::CodSpeedAPIClient;
135136
use crate::config::CodSpeedConfig;
136137
use crate::executor::config::RepositoryOverride;
137138
use crate::run_environment::interfaces::RepositoryProvider;
138139

139140
let temp_dir = TempDir::new().unwrap();
140141

141-
// Use try_from to create a proper ExecutionContext with all fields
142142
let codspeed_config = CodSpeedConfig::default();
143+
let api_client = CodSpeedAPIClient::create_test_client();
143144
let mut config_with_folder = config;
144145
config_with_folder.profile_folder = Some(temp_dir.path().to_path_buf());
145146

@@ -159,7 +160,8 @@ async fn create_test_setup(config: Config) -> (ExecutionContext, TempDir) {
159160
}
160161

161162
let execution_context =
162-
ExecutionContext::try_from((config_with_folder, &codspeed_config_with_token))
163+
ExecutionContext::new(config_with_folder, &codspeed_config_with_token, &api_client)
164+
.await
163165
.expect("Failed to create ExecutionContext for test");
164166

165167
(execution_context, temp_dir)

src/queries/GetRepository.gql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
query Repository(
2+
$owner: String!
3+
$name: String!
4+
$provider: RepositoryProvider
5+
) {
6+
repository(owner: $owner, name: $name, provider: $provider) {
7+
id
8+
}
9+
}

0 commit comments

Comments
 (0)