summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <git@iximeow.net>2022-12-27 23:54:01 +0000
committeriximeow <git@iximeow.net>2022-12-27 23:54:01 +0000
commitf60c18aadd8d776751cb61140eef578424f8cffc (patch)
tree1c839ce819b939a908994a8999a1357779ef12bb
parent018c655304bfc185740b3a163b369ead7d5131e8 (diff)
add more information to commit status pages, support short commit strings
-rw-r--r--src/main.rs117
1 files changed, 75 insertions, 42 deletions
diff --git a/src/main.rs b/src/main.rs
index ce01ecc..71b9a04 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -168,10 +168,14 @@ async fn handle_commit_status(Path(path): Path<(String, String, String)>, State(
let remote_path = format!("{}/{}", path.0, path.1);
let sha = path.2;
- let commit_id: Option<u64> = ctx.conn.lock().unwrap()
- .query_row("select id from commits where sha=?1;", [&sha], |row| row.get(0))
- .optional()
- .expect("can query");
+ let commit_id: Option<u64> = if sha.len() >= 7 {
+ ctx.conn.lock().unwrap()
+ .query_row("select id from commits where sha like ?1;", [&format!("{}%", sha)], |row| row.get(0))
+ .optional()
+ .expect("can query")
+ } else {
+ None
+ };
let commit_id: u64 = match commit_id {
Some(commit_id) => {
@@ -186,8 +190,8 @@ async fn handle_commit_status(Path(path): Path<(String, String, String)>, State(
.query_row("select id, repo_id from remotes where remote_path=?1;", [&remote_path], |row| Ok((row.get_unwrap(0), row.get_unwrap(1))))
.expect("can query");
- let (job_id, state): (u64, u8) = ctx.conn.lock().unwrap()
- .query_row("select id, state from jobs where commit_id=?1;", [commit_id], |row| Ok((row.get_unwrap(0), row.get_unwrap(1))))
+ let (job_id, state, build_result, result_desc): (u64, u8, Option<u8>, Option<String>) = ctx.conn.lock().unwrap()
+ .query_row("select id, state, build_result, final_status from jobs where commit_id=?1;", [commit_id], |row| Ok((row.get_unwrap(0), row.get_unwrap(1), row.get_unwrap(2), row.get_unwrap(3))))
.expect("can query");
let state: sql::JobState = unsafe { std::mem::transmute(state) };
@@ -198,45 +202,74 @@ async fn handle_commit_status(Path(path): Path<(String, String, String)>, State(
let deployed = false;
- let time = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .expect("now is before epoch");
-
- let resp = format!("\
- <html>\n\
- <head>\n\
- <title>ci.butactuallyin.space - {}</title>\n\
- </head>\n\
- <body>\n\
- <pre>\n\
- repo: {}\n\
- commit: <a href='https://www.github.com/{}/commit/{}'>{}</a>\n \
- status: {}\n \
- deployed: {}\n\
- </pre>\n\
- </body>\n\
- </html>\n",
- repo_name,
- repo_name,
- &remote_path, &sha, &sha,
- match state {
- JobState::Pending | JobState::Started => {
- "<span style='color:#660;'>pending</span>"
- },
- JobState::Complete => {
- "<span style='color:green;'>pass</span>"
- },
- JobState::Error => {
- "<span style='color:red;'>pass</span>"
- }
- JobState::Invalid => {
- "<span style='color:red;'>(server error)</span>"
+ let head = format!("<head><title>ci.butactuallin.space - {}</title></head>", repo_name);
+ let remote_commit_elem = format!("<a href=\"https://www.github.com/{}/commit/{}\">{}</a>", &remote_path, &sha, &sha);
+ let status_elem = match state {
+ JobState::Pending | JobState::Started => {
+ "<span style='color:#660;'>pending</span>"
+ },
+ JobState::Finished => {
+ if let Some(build_result) = build_result {
+ if build_result == 0 {
+ "<span style='color:green;'>pass</span>"
+ } else {
+ "<span style='color:red;'>failed</span>"
+ }
+ } else {
+ eprintln!("job {} for commit {} is missing a build result but is reportedly finished (old data)?", job_id, commit_id);
+ "<span style='color:red;'>unreported</span>"
}
},
- deployed,
- );
+ JobState::Error => {
+ "<span style='color:red;'>error</span>"
+ }
+ JobState::Invalid => {
+ "<span style='color:red;'>(server error)</span>"
+ }
+ };
+
+ let output = if state == JobState::Finished && build_result == Some(1) || state == JobState::Error {
+ // collect stderr/stdout from the last artifacts, then the last 10kb of each, insert it in
+ // the page...
+ let artifacts = ctx.artifacts_for_job(job_id).unwrap();
+ if artifacts.len() > 0 {
+ let mut streams = String::new();
+ for artifact in artifacts.iter() {
+ eprintln!("found artifact {:?} for job {:?}", artifact, job_id);
+ streams.push_str(&format!("<div>step: <pre style='display:inline;'>{}</pre></div>\n", &artifact.name));
+ streams.push_str("<pre>");
+ streams.push_str(&std::fs::read_to_string(format!("./jobs/{}/{}", artifact.job_id, artifact.id)).unwrap());
+ streams.push_str("</pre>");
+ }
+ Some(streams)
+ } else {
+ None
+ }
+ } else {
+ None
+ };
+
+ let mut html = String::new();
+ html.push_str("<html>\n");
+ html.push_str(&format!(" {}\n", head));
+ html.push_str(" <body>\n");
+ html.push_str(" <pre>\n");
+ html.push_str(&format!("repo: {}\n", repo_name));
+ html.push_str(&format!("commit: {}\n", remote_commit_elem));
+ html.push_str(&format!("status: {}\n", status_elem));
+ if let Some(desc) = result_desc {
+ html.push_str(&format!(" description: {}\n ", desc));
+ }
+ html.push_str(&format!("deployed: {}\n", deployed));
+ html.push_str(" </pre>\n");
+ if let Some(output) = output {
+ html.push_str(" <div>last build output</div>\n");
+ html.push_str(&format!(" {}\n", output));
+ }
+ html.push_str(" </body>\n");
+ html.push_str("</html>");
- (StatusCode::OK, Html(resp))
+ (StatusCode::OK, Html(html))
}
async fn handle_repo_event(Path(path): Path<(String, String)>, headers: HeaderMap, State(ctx): State<Arc<DbCtx>>, body: Bytes) -> impl IntoResponse {