Skip to content

Commit 5e17739

Browse files
authored
216 search by job name (#294)
* add job filter * add job filter * add jobs * fix rs * fix branch * add job filter for latest pipelines * fix branches * fix bug * add to schedules * fix filter * only fetch failed jobs * fix tests
1 parent e4c5886 commit 5e17739

38 files changed

+335
-77
lines changed

api/src/branch/pipeline_aggregator.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::branch::branch_service::BranchService;
22
use crate::error::ApiError;
3-
use crate::model::{Branch, BranchPipeline};
3+
use crate::job::JobService;
4+
use crate::model::{Branch, BranchPipeline, JobStatus, PipelineStatus};
45
use crate::pipeline;
56
use crate::pipeline::PipelineService;
67
use crate::util::iter::try_collect_with_buffer;
@@ -9,13 +10,19 @@ use pipeline::sort_by_updated_date;
910
pub struct PipelineAggregator {
1011
branch_service: BranchService,
1112
pipeline_service: PipelineService,
13+
job_service: JobService,
1214
}
1315

1416
impl PipelineAggregator {
15-
pub fn new(branch_service: BranchService, pipeline_service: PipelineService) -> Self {
17+
pub fn new(
18+
branch_service: BranchService,
19+
pipeline_service: PipelineService,
20+
job_service: JobService,
21+
) -> Self {
1622
Self {
1723
branch_service,
1824
pipeline_service,
25+
job_service,
1926
}
2027
}
2128
}
@@ -45,7 +52,21 @@ impl PipelineAggregator {
4552
.pipeline_service
4653
.get_latest_pipeline(project_id, branch.name.clone())
4754
.await?;
48-
Ok(BranchPipeline { branch, pipeline })
55+
56+
let failed_jobs = match pipeline {
57+
Some(ref p) if p.status == PipelineStatus::Failed => Some(
58+
self.job_service
59+
.get_jobs(p.project_id, p.id, &[JobStatus::Failed])
60+
.await?,
61+
),
62+
_ => None,
63+
};
64+
65+
Ok(BranchPipeline {
66+
branch,
67+
pipeline,
68+
failed_jobs,
69+
})
4970
})
5071
.await
5172
}

api/src/job/job_service.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ impl CacheKey {
2222
}
2323
}
2424

25+
#[derive(Clone)]
2526
pub struct JobService {
2627
cache: Cache<CacheKey, Vec<Job>>,
2728
client: Arc<dyn GitlabApi>,

api/src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,18 @@ async fn main() -> std::io::Result<()> {
8383
let project_aggr = Data::new(project::PipelineAggregator::new(
8484
project_service.get_ref().clone(),
8585
pipeline_service.get_ref().clone(),
86+
job_service.get_ref().clone(),
8687
));
8788
let branch_aggr = Data::new(branch::PipelineAggregator::new(
8889
branch_service.get_ref().clone(),
8990
pipeline_service.get_ref().clone(),
91+
job_service.get_ref().clone(),
9092
));
9193
let schedule_aggr = Data::new(schedule::PipelineAggregator::new(
9294
schedule::ScheduleService::new(gitlab_client.clone(), app_config.clone()),
9395
project_service.get_ref().clone(),
9496
pipeline_service.get_ref().clone(),
97+
job_service.get_ref().clone(),
9598
));
9699

97100
let prom = setup_prometheus();
@@ -245,15 +248,18 @@ mod tests {
245248
let project_aggr = Data::new(project::PipelineAggregator::new(
246249
project_service.get_ref().clone(),
247250
pipeline_service.get_ref().clone(),
251+
job_service.get_ref().clone(),
248252
));
249253
let branch_aggr = Data::new(branch::PipelineAggregator::new(
250254
branch_service.get_ref().clone(),
251255
pipeline_service.get_ref().clone(),
256+
job_service.get_ref().clone(),
252257
));
253258
let schedule_aggr = Data::new(schedule::PipelineAggregator::new(
254259
schedule::ScheduleService::new(gitlab_client.clone(), gcd_config.clone()),
255260
project_service.get_ref().clone(),
256261
pipeline_service.get_ref().clone(),
262+
job_service.get_ref().clone(),
257263
));
258264

259265
test::init_service(App::new().configure(configure_app(

api/src/model/branch.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use serde::{Deserialize, Serialize};
22

33
use crate::model::commit::Commit;
4-
use crate::model::Pipeline;
4+
use crate::model::{Job, Pipeline};
55

66
#[derive(Clone, Debug, Serialize, Deserialize)]
77
pub struct Branch {
@@ -19,13 +19,15 @@ pub struct BranchPipeline {
1919
pub branch: Branch,
2020
#[serde(skip_serializing_if = "Option::is_none")]
2121
pub pipeline: Option<Pipeline>,
22+
#[serde(skip_serializing_if = "Option::is_none")]
23+
pub failed_jobs: Option<Vec<Job>>,
2224
}
2325

2426
#[cfg(test)]
2527
mod tests {
2628
use serde_json::json;
2729

28-
use crate::model::{Branch, BranchPipeline, test};
30+
use crate::model::{test, Branch, BranchPipeline};
2931

3032
#[test]
3133
fn branch_deserialize() {
@@ -69,6 +71,7 @@ mod tests {
6971

7072
let json = serde_json::to_string(&value).unwrap();
7173
let expected = "{\"name\":\"branch-1\",\"merged\":false,\"protected\":false,\"default\":false,\"can_push\":false,\"web_url\":\"web_url\",\"commit\":{\"id\":\"id\",\"author_name\":\"author_name\",\"committer_name\":\"committer_name\",\"committed_date\":\"1970-01-01T00:00:00Z\",\"title\":\"title\",\"message\":\"message\"}}";
74+
7275
assert_eq!(expected, json);
7376
}
7477

@@ -77,10 +80,12 @@ mod tests {
7780
let value = BranchPipeline {
7881
branch: test::new_branch(),
7982
pipeline: None,
83+
failed_jobs: None,
8084
};
8185

8286
let json = serde_json::to_string(&value).unwrap();
8387
let expected = "{\"branch\":{\"name\":\"branch-1\",\"merged\":false,\"protected\":false,\"default\":false,\"can_push\":false,\"web_url\":\"web_url\",\"commit\":{\"id\":\"id\",\"author_name\":\"author_name\",\"committer_name\":\"committer_name\",\"committed_date\":\"1970-01-01T00:00:00Z\",\"title\":\"title\",\"message\":\"message\"}}}";
88+
8489
assert_eq!(expected, json);
8590
}
8691

@@ -89,10 +94,26 @@ mod tests {
8994
let value = BranchPipeline {
9095
branch: test::new_branch(),
9196
pipeline: Some(test::new_pipeline()),
97+
failed_jobs: None,
9298
};
9399

94100
let json = serde_json::to_string(&value).unwrap();
95101
let expected = "{\"branch\":{\"name\":\"branch-1\",\"merged\":false,\"protected\":false,\"default\":false,\"can_push\":false,\"web_url\":\"web_url\",\"commit\":{\"id\":\"id\",\"author_name\":\"author_name\",\"committer_name\":\"committer_name\",\"committed_date\":\"1970-01-01T00:00:00Z\",\"title\":\"title\",\"message\":\"message\"}},\"pipeline\":{\"id\":1,\"iid\":2,\"project_id\":3,\"sha\":\"sha\",\"ref\":\"branch\",\"status\":\"running\",\"source\":\"web\",\"created_at\":\"1970-01-01T00:00:00Z\",\"updated_at\":\"1970-01-01T00:00:00Z\",\"web_url\":\"web_url\"}}";
102+
103+
assert_eq!(expected, json);
104+
}
105+
106+
#[test]
107+
fn branch_pipeline_serialize_some_failed_jobs() {
108+
let value = BranchPipeline {
109+
branch: test::new_branch(),
110+
pipeline: None,
111+
failed_jobs: Some(vec![test::new_job()]),
112+
};
113+
114+
let json = serde_json::to_string(&value).unwrap();
115+
let expected = "{\"branch\":{\"name\":\"branch-1\",\"merged\":false,\"protected\":false,\"default\":false,\"can_push\":false,\"web_url\":\"web_url\",\"commit\":{\"id\":\"id\",\"author_name\":\"author_name\",\"committer_name\":\"committer_name\",\"committed_date\":\"1970-01-01T00:00:00Z\",\"title\":\"title\",\"message\":\"message\"}},\"failed_jobs\":[{\"id\":1,\"created_at\":\"1970-01-01T00:00:00Z\",\"allow_failure\":false,\"name\":\"name\",\"ref\":\"branch\",\"stage\":\"stage\",\"status\":\"success\",\"web_url\":\"web_url\",\"pipeline\":{\"id\":1,\"iid\":2,\"project_id\":3,\"sha\":\"sha\",\"ref\":\"branch\",\"status\":\"running\",\"source\":\"web\",\"created_at\":\"1970-01-01T00:00:00Z\",\"updated_at\":\"1970-01-01T00:00:00Z\",\"web_url\":\"web_url\"},\"commit\":{\"id\":\"id\",\"author_name\":\"author_name\",\"committer_name\":\"committer_name\",\"committed_date\":\"1970-01-01T00:00:00Z\",\"title\":\"title\",\"message\":\"message\"},\"user\":{\"id\":123,\"username\":\"username\",\"name\":\"name\",\"state\":\"state\",\"is_admin\":false}}]}";
116+
96117
assert_eq!(expected, json);
97118
}
98119
}

api/src/model/pipeline.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub struct Pipeline {
1616
pub web_url: String,
1717
}
1818

19-
#[derive(Clone, Debug, Serialize, Deserialize)]
19+
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
2020
#[serde(rename_all = "lowercase")]
2121
pub enum PipelineStatus {
2222
/// Currently running.

api/src/model/project.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use serde::{Deserialize, Serialize};
22

3-
use crate::model::Pipeline;
3+
use crate::model::{Job, Pipeline};
44

55
#[derive(Clone, Debug, Serialize, Deserialize)]
66
pub struct Project {
@@ -9,14 +9,14 @@ pub struct Project {
99
pub web_url: String,
1010
pub default_branch: Option<String>,
1111
pub topics: Vec<String>,
12-
pub namespace: Namespace
12+
pub namespace: Namespace,
1313
}
1414

1515
#[derive(Clone, Debug, Serialize, Deserialize)]
1616
pub struct Namespace {
1717
pub id: u64,
1818
pub name: String,
19-
pub path: String
19+
pub path: String,
2020
}
2121

2222
#[derive(Clone, Debug, Serialize, Deserialize)]
@@ -25,6 +25,8 @@ pub struct ProjectPipeline {
2525
pub project: Project,
2626
#[serde(skip_serializing_if = "Option::is_none")]
2727
pub pipeline: Option<Pipeline>,
28+
#[serde(skip_serializing_if = "Option::is_none")]
29+
pub failed_jobs: Option<Vec<Job>>,
2830
}
2931

3032
#[derive(Clone, Debug, Serialize, Deserialize)]
@@ -36,7 +38,7 @@ pub struct ProjectPipelines {
3638

3739
#[cfg(test)]
3840
mod tests {
39-
use crate::model::{Project, ProjectPipeline, ProjectPipelines, test};
41+
use crate::model::{test, Project, ProjectPipeline, ProjectPipelines};
4042

4143
#[test]
4244
fn project_deserialize() {
@@ -196,6 +198,7 @@ mod tests {
196198
group_id: 1,
197199
project: test::new_project(),
198200
pipeline: None,
201+
failed_jobs: None,
199202
};
200203

201204
let json = serde_json::to_string(&value).unwrap();
@@ -210,10 +213,27 @@ mod tests {
210213
group_id: 1,
211214
project: test::new_project(),
212215
pipeline: Some(test::new_pipeline()),
216+
failed_jobs: None,
213217
};
214218

215219
let json = serde_json::to_string(&value).unwrap();
216220
let expected = "{\"group_id\":1,\"project\":{\"id\":456,\"name\":\"name\",\"web_url\":\"web_url\",\"default_branch\":\"default_branch\",\"topics\":[\"topic\"],\"namespace\":{\"id\":123,\"name\":\"namespace\",\"path\":\"namespace\"}},\"pipeline\":{\"id\":1,\"iid\":2,\"project_id\":3,\"sha\":\"sha\",\"ref\":\"branch\",\"status\":\"running\",\"source\":\"web\",\"created_at\":\"1970-01-01T00:00:00Z\",\"updated_at\":\"1970-01-01T00:00:00Z\",\"web_url\":\"web_url\"}}";
221+
222+
assert_eq!(expected, json);
223+
}
224+
225+
#[test]
226+
fn project_pipeline_serialize_some_failed_jobs() {
227+
let value = ProjectPipeline {
228+
group_id: 1,
229+
project: test::new_project(),
230+
pipeline: None,
231+
failed_jobs: Some(vec![test::new_job()]),
232+
};
233+
234+
let json = serde_json::to_string(&value).unwrap();
235+
let expected = "{\"group_id\":1,\"project\":{\"id\":456,\"name\":\"name\",\"web_url\":\"web_url\",\"default_branch\":\"default_branch\",\"topics\":[\"topic\"],\"namespace\":{\"id\":123,\"name\":\"namespace\",\"path\":\"namespace\"}},\"failed_jobs\":[{\"id\":1,\"created_at\":\"1970-01-01T00:00:00Z\",\"allow_failure\":false,\"name\":\"name\",\"ref\":\"branch\",\"stage\":\"stage\",\"status\":\"success\",\"web_url\":\"web_url\",\"pipeline\":{\"id\":1,\"iid\":2,\"project_id\":3,\"sha\":\"sha\",\"ref\":\"branch\",\"status\":\"running\",\"source\":\"web\",\"created_at\":\"1970-01-01T00:00:00Z\",\"updated_at\":\"1970-01-01T00:00:00Z\",\"web_url\":\"web_url\"},\"commit\":{\"id\":\"id\",\"author_name\":\"author_name\",\"committer_name\":\"committer_name\",\"committed_date\":\"1970-01-01T00:00:00Z\",\"title\":\"title\",\"message\":\"message\"},\"user\":{\"id\":123,\"username\":\"username\",\"name\":\"name\",\"state\":\"state\",\"is_admin\":false}}]}";
236+
217237
assert_eq!(expected, json);
218238
}
219239

api/src/model/schedule.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use chrono::{DateTime, Utc};
22
use serde::{Deserialize, Serialize};
33

44
use crate::model::user::User;
5-
use crate::model::{Pipeline, Project};
5+
use crate::model::{Job, Pipeline, Project};
66
use crate::util::deserialize::from_ref;
77

88
#[derive(Clone, Debug, Serialize, Deserialize)]
@@ -27,6 +27,8 @@ pub struct ScheduleProjectPipeline {
2727
pub project: Project,
2828
#[serde(skip_serializing_if = "Option::is_none")]
2929
pub pipeline: Option<Pipeline>,
30+
#[serde(skip_serializing_if = "Option::is_none")]
31+
pub failed_jobs: Option<Vec<Job>>,
3032
}
3133

3234
#[cfg(test)]
@@ -68,6 +70,7 @@ mod tests {
6870

6971
let json = serde_json::to_string(&value).unwrap();
7072
let expected = "{\"id\":789,\"description\":\"description\",\"ref\":\"branch\",\"cron\":\"cron\",\"cron_timezone\":\"cron_timezone\",\"next_run_at\":\"1970-01-01T00:00:00Z\",\"active\":false,\"created_at\":\"1970-01-01T00:00:00Z\",\"updated_at\":\"1970-01-01T00:00:00Z\",\"owner\":{\"id\":123,\"username\":\"username\",\"name\":\"name\",\"state\":\"state\",\"is_admin\":false}}";
73+
7174
assert_eq!(expected, json);
7275
}
7376

@@ -78,6 +81,7 @@ mod tests {
7881
schedule: test::new_schedule(),
7982
project: test::new_project(),
8083
pipeline: None,
84+
failed_jobs: None,
8185
};
8286

8387
let json = serde_json::to_string(&value).unwrap();
@@ -93,11 +97,28 @@ mod tests {
9397
schedule: test::new_schedule(),
9498
project: test::new_project(),
9599
pipeline: Some(test::new_pipeline()),
100+
failed_jobs: None,
96101
};
97102

98103
let json = serde_json::to_string(&value).unwrap();
99104
let expected = "{\"group_id\":1,\"schedule\":{\"id\":789,\"description\":\"description\",\"ref\":\"branch\",\"cron\":\"cron\",\"cron_timezone\":\"cron_timezone\",\"next_run_at\":\"1970-01-01T00:00:00Z\",\"active\":false,\"created_at\":\"1970-01-01T00:00:00Z\",\"updated_at\":\"1970-01-01T00:00:00Z\",\"owner\":{\"id\":123,\"username\":\"username\",\"name\":\"name\",\"state\":\"state\",\"is_admin\":false}},\"project\":{\"id\":456,\"name\":\"name\",\"web_url\":\"web_url\",\"default_branch\":\"default_branch\",\"topics\":[\"topic\"],\"namespace\":{\"id\":123,\"name\":\"namespace\",\"path\":\"namespace\"}},\"pipeline\":{\"id\":1,\"iid\":2,\"project_id\":3,\"sha\":\"sha\",\"ref\":\"branch\",\"status\":\"running\",\"source\":\"web\",\"created_at\":\"1970-01-01T00:00:00Z\",\"updated_at\":\"1970-01-01T00:00:00Z\",\"web_url\":\"web_url\"}}";
100105

101106
assert_eq!(expected, json);
102107
}
108+
109+
#[test]
110+
fn schedule_project_pipeline_serialize_some_failed_jobs() {
111+
let value = ScheduleProjectPipeline {
112+
group_id: 1,
113+
schedule: test::new_schedule(),
114+
project: test::new_project(),
115+
pipeline: None,
116+
failed_jobs: Some(vec![test::new_job()]),
117+
};
118+
119+
let json = serde_json::to_string(&value).unwrap();
120+
let expected = "{\"group_id\":1,\"schedule\":{\"id\":789,\"description\":\"description\",\"ref\":\"branch\",\"cron\":\"cron\",\"cron_timezone\":\"cron_timezone\",\"next_run_at\":\"1970-01-01T00:00:00Z\",\"active\":false,\"created_at\":\"1970-01-01T00:00:00Z\",\"updated_at\":\"1970-01-01T00:00:00Z\",\"owner\":{\"id\":123,\"username\":\"username\",\"name\":\"name\",\"state\":\"state\",\"is_admin\":false}},\"project\":{\"id\":456,\"name\":\"name\",\"web_url\":\"web_url\",\"default_branch\":\"default_branch\",\"topics\":[\"topic\"],\"namespace\":{\"id\":123,\"name\":\"namespace\",\"path\":\"namespace\"}},\"failed_jobs\":[{\"id\":1,\"created_at\":\"1970-01-01T00:00:00Z\",\"allow_failure\":false,\"name\":\"name\",\"ref\":\"branch\",\"stage\":\"stage\",\"status\":\"success\",\"web_url\":\"web_url\",\"pipeline\":{\"id\":1,\"iid\":2,\"project_id\":3,\"sha\":\"sha\",\"ref\":\"branch\",\"status\":\"running\",\"source\":\"web\",\"created_at\":\"1970-01-01T00:00:00Z\",\"updated_at\":\"1970-01-01T00:00:00Z\",\"web_url\":\"web_url\"},\"commit\":{\"id\":\"id\",\"author_name\":\"author_name\",\"committer_name\":\"committer_name\",\"committed_date\":\"1970-01-01T00:00:00Z\",\"title\":\"title\",\"message\":\"message\"},\"user\":{\"id\":123,\"username\":\"username\",\"name\":\"name\",\"state\":\"state\",\"is_admin\":false}}]}";
121+
122+
assert_eq!(expected, json);
123+
}
103124
}

api/src/project/pipeline_aggregator.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
use crate::error::ApiError;
2-
use crate::model::{Project, ProjectPipeline, ProjectPipelines};
2+
use crate::job::JobService;
3+
use crate::model::{JobStatus, PipelineStatus, Project, ProjectPipeline, ProjectPipelines};
34
use crate::pipeline::{sort_by_updated_date, PipelineService};
45
use crate::project::ProjectService;
56
use crate::util::iter::try_collect_with_buffer;
67

78
pub struct PipelineAggregator {
89
project_service: ProjectService,
910
pipeline_service: PipelineService,
11+
job_service: JobService,
1012
}
1113

1214
impl PipelineAggregator {
13-
pub fn new(project_service: ProjectService, pipeline_service: PipelineService) -> Self {
15+
pub fn new(
16+
project_service: ProjectService,
17+
pipeline_service: PipelineService,
18+
job_service: JobService,
19+
) -> Self {
1420
Self {
1521
project_service,
1622
pipeline_service,
23+
job_service,
1724
}
1825
}
1926
}
@@ -53,10 +60,20 @@ impl PipelineAggregator {
5360
None
5461
};
5562

63+
let failed_jobs = match pipeline {
64+
Some(ref p) if p.status == PipelineStatus::Failed => Some(
65+
self.job_service
66+
.get_jobs(p.project_id, p.id, &[JobStatus::Failed])
67+
.await?,
68+
),
69+
_ => None,
70+
};
71+
5672
Ok(ProjectPipeline {
5773
group_id,
5874
project,
5975
pipeline,
76+
failed_jobs,
6077
})
6178
})
6279
.await
@@ -87,6 +104,7 @@ impl PipelineAggregator {
87104
} else {
88105
Vec::default()
89106
};
107+
90108
Ok(ProjectPipelines {
91109
group_id,
92110
project,

0 commit comments

Comments
 (0)