mirror of
https://github.com/encounter/decomp.dev.git
synced 2026-07-10 03:18:48 -07:00
Allow refreshing projects without existing reports
This commit is contained in:
+5
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n projects.id AS \"project_id!\",\n owner AS \"owner!\",\n repo AS \"repo!\",\n name,\n short_name,\n default_version,\n platform,\n git_commit AS \"git_commit!\",\n MAX(timestamp) AS \"timestamp: chrono::NaiveDateTime\",\n JSON_GROUP_ARRAY(version ORDER BY version) AS versions\n FROM projects JOIN reports ON projects.id = reports.project_id\n WHERE timestamp = (\n SELECT MAX(timestamp)\n FROM reports\n WHERE project_id = projects.id\n )\n GROUP BY projects.id\n ORDER BY MAX(timestamp) DESC\n ",
|
||||
"query": "\n SELECT\n projects.id AS \"project_id!\",\n owner AS \"owner!\",\n repo AS \"repo!\",\n name,\n short_name,\n default_version,\n platform,\n git_commit,\n MAX(timestamp) AS \"timestamp: chrono::NaiveDateTime\",\n JSON_GROUP_ARRAY(version ORDER BY version)\n FILTER (WHERE version IS NOT NULL) AS versions\n FROM projects LEFT JOIN reports ON (\n reports.project_id = projects.id\n AND reports.timestamp = (\n SELECT MAX(timestamp)\n FROM reports\n WHERE project_id = projects.id\n )\n )\n GROUP BY projects.id\n ORDER BY MAX(timestamp) DESC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -39,7 +39,7 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "git_commit!",
|
||||
"name": "git_commit",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
@@ -66,9 +66,9 @@
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "33ef6c68364ca0148a0cec67caba762484635c8e9881fe29b7f0e75cff235b31"
|
||||
"hash": "1c5ea45ed729197e046adfd9a9129de3479799b64556826043d6dd909c314429"
|
||||
}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT git_commit\n FROM reports\n WHERE project_id = ? AND timestamp > ?\n ORDER BY timestamp\n LIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "git_commit",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "6550bd96a82a16800fe801be26a52297907c2c3de6ea88951495175e81094343"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT git_commit\n FROM reports\n WHERE project_id = ? AND timestamp < ?\n ORDER BY timestamp DESC\n LIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "git_commit",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "6c9bea8b05a4bd3bdfc6f4a1381079bfc26fdd49db6e1abc215516b44d3ce183"
|
||||
}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT git_commit\n FROM reports\n WHERE project_id = ? AND timestamp < ?\n ORDER BY timestamp DESC\n LIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "git_commit",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "7418a824fbb682e0044774c586a14643065ae66bc008a649cf6669988c738f04"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT git_commit\n FROM reports\n WHERE project_id = ? AND timestamp > ?\n ORDER BY timestamp\n LIMIT 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "git_commit",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "750fca04470de49bd9fa4cf77c19aa579d3556cf20994a618f5c04241ab65e20"
|
||||
}
|
||||
+9
-2
@@ -1,4 +1,4 @@
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context, Result};
|
||||
use tokio_cron_scheduler::{Job, JobScheduler};
|
||||
|
||||
use crate::{github, AppState};
|
||||
@@ -21,7 +21,14 @@ pub async fn create(state: AppState) -> Result<Scheduler> {
|
||||
|
||||
pub async fn refresh_projects(state: &mut AppState) -> Result<()> {
|
||||
for project_info in state.db.get_projects().await? {
|
||||
github::run(state, &project_info.project.owner, &project_info.project.repo, 0).await?;
|
||||
github::run(state, &project_info.project.owner, &project_info.project.repo, 0)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to refresh {}/{}",
|
||||
project_info.project.owner, project_info.project.repo
|
||||
)
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+64
-49
@@ -345,49 +345,53 @@ impl Database {
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let Some(first_report) = reports.first() else {
|
||||
return Ok(None);
|
||||
};
|
||||
// Fetch previous and next commits
|
||||
let timestamp = first_report.timestamp.and_utc();
|
||||
let prev_commit = sqlx::query!(
|
||||
r#"
|
||||
SELECT git_commit
|
||||
FROM reports
|
||||
WHERE project_id = ? AND timestamp < ?
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT 1
|
||||
"#,
|
||||
project_id,
|
||||
timestamp,
|
||||
)
|
||||
.fetch_optional(&mut *conn)
|
||||
.await?
|
||||
.map(|row| row.git_commit);
|
||||
let next_commit = sqlx::query!(
|
||||
r#"
|
||||
SELECT git_commit
|
||||
FROM reports
|
||||
WHERE project_id = ? AND timestamp > ?
|
||||
ORDER BY timestamp
|
||||
LIMIT 1
|
||||
"#,
|
||||
project_id,
|
||||
timestamp,
|
||||
)
|
||||
.fetch_optional(&mut *conn)
|
||||
.await?
|
||||
.map(|row| row.git_commit);
|
||||
Ok(Some(ProjectInfo {
|
||||
let mut info = ProjectInfo {
|
||||
project,
|
||||
commit: Commit {
|
||||
commit: None,
|
||||
report_versions: reports.iter().map(|r| r.version.clone()).collect(),
|
||||
prev_commit: None,
|
||||
next_commit: None,
|
||||
};
|
||||
if let Some(first_report) = reports.first() {
|
||||
// Fetch previous and next commits
|
||||
let timestamp = first_report.timestamp.and_utc();
|
||||
let prev_commit = sqlx::query!(
|
||||
r#"
|
||||
SELECT git_commit
|
||||
FROM reports
|
||||
WHERE project_id = ? AND timestamp < ?
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT 1
|
||||
"#,
|
||||
project_id,
|
||||
timestamp,
|
||||
)
|
||||
.fetch_optional(&mut *conn)
|
||||
.await?
|
||||
.map(|row| row.git_commit);
|
||||
let next_commit = sqlx::query!(
|
||||
r#"
|
||||
SELECT git_commit
|
||||
FROM reports
|
||||
WHERE project_id = ? AND timestamp > ?
|
||||
ORDER BY timestamp
|
||||
LIMIT 1
|
||||
"#,
|
||||
project_id,
|
||||
timestamp,
|
||||
)
|
||||
.fetch_optional(&mut *conn)
|
||||
.await?
|
||||
.map(|row| row.git_commit);
|
||||
|
||||
info.commit = Some(Commit {
|
||||
sha: first_report.git_commit.clone(),
|
||||
timestamp: first_report.timestamp.and_utc(),
|
||||
},
|
||||
report_versions: reports.iter().map(|r| r.version.clone()).collect(),
|
||||
prev_commit,
|
||||
next_commit,
|
||||
}))
|
||||
});
|
||||
info.prev_commit = prev_commit;
|
||||
info.next_commit = next_commit;
|
||||
}
|
||||
Ok(Some(info))
|
||||
}
|
||||
|
||||
pub async fn get_projects(&self) -> Result<Vec<ProjectInfo>> {
|
||||
@@ -402,14 +406,17 @@ impl Database {
|
||||
short_name,
|
||||
default_version,
|
||||
platform,
|
||||
git_commit AS "git_commit!",
|
||||
git_commit,
|
||||
MAX(timestamp) AS "timestamp: chrono::NaiveDateTime",
|
||||
JSON_GROUP_ARRAY(version ORDER BY version) AS versions
|
||||
FROM projects JOIN reports ON projects.id = reports.project_id
|
||||
WHERE timestamp = (
|
||||
SELECT MAX(timestamp)
|
||||
FROM reports
|
||||
WHERE project_id = projects.id
|
||||
JSON_GROUP_ARRAY(version ORDER BY version)
|
||||
FILTER (WHERE version IS NOT NULL) AS versions
|
||||
FROM projects LEFT JOIN reports ON (
|
||||
reports.project_id = projects.id
|
||||
AND reports.timestamp = (
|
||||
SELECT MAX(timestamp)
|
||||
FROM reports
|
||||
WHERE project_id = projects.id
|
||||
)
|
||||
)
|
||||
GROUP BY projects.id
|
||||
ORDER BY MAX(timestamp) DESC
|
||||
@@ -428,8 +435,16 @@ impl Database {
|
||||
default_version: row.default_version,
|
||||
platform: row.platform,
|
||||
},
|
||||
commit: Commit { sha: row.git_commit, timestamp: row.timestamp.and_utc() },
|
||||
report_versions: serde_json::from_str(&row.versions).unwrap_or_default(),
|
||||
commit: match (row.git_commit, row.timestamp) {
|
||||
(Some(sha), Some(timestamp)) => {
|
||||
Some(Commit { sha, timestamp: timestamp.and_utc() })
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
report_versions: row
|
||||
.versions
|
||||
.and_then(|s| serde_json::from_str(&s).ok())
|
||||
.unwrap_or_default(),
|
||||
prev_commit: None,
|
||||
next_commit: None,
|
||||
})
|
||||
|
||||
+20
-9
@@ -77,7 +77,11 @@ impl GitHub {
|
||||
|
||||
pub async fn run(state: &mut AppState, owner: &str, repo: &str, stop_run_id: u64) -> Result<()> {
|
||||
tracing::info!("Refreshing project {}/{}", owner, repo);
|
||||
let existing = state.db.get_project_info(owner, repo, None).await?;
|
||||
let existing = state
|
||||
.db
|
||||
.get_project_info(owner, repo, None)
|
||||
.await
|
||||
.context("Failed to fetch project info")?;
|
||||
let repo =
|
||||
state.github.client.repos(owner, repo).get().await.context("Failed to fetch repo")?;
|
||||
let branch = repo.default_branch.as_deref().unwrap_or("main");
|
||||
@@ -107,15 +111,22 @@ pub async fn run(state: &mut AppState, owner: &str, repo: &str, stop_run_id: u64
|
||||
.status("completed")
|
||||
.exclude_pull_requests(true)
|
||||
.page(page)
|
||||
// .per_page(10)
|
||||
.send()
|
||||
.await?;
|
||||
if result.items.is_empty() {
|
||||
break;
|
||||
}
|
||||
for run in result.items {
|
||||
if let Some(existing) = existing.as_ref() {
|
||||
if run.head_sha == existing.commit.sha {
|
||||
.await;
|
||||
let items = match result {
|
||||
Ok(result) if result.items.is_empty() => break,
|
||||
Ok(result) => result.items,
|
||||
Err(octocrab::Error::GitHub {
|
||||
source: GitHubError { status_code: StatusCode::NOT_FOUND, .. },
|
||||
..
|
||||
}) => break,
|
||||
Err(e) => {
|
||||
return Err(e).with_context(|| format!("Failed to fetch workflows page {}", page));
|
||||
}
|
||||
};
|
||||
for run in items {
|
||||
if let Some(commit) = existing.as_ref().and_then(|e| e.commit.as_ref()) {
|
||||
if run.head_sha == commit.sha {
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-13
@@ -60,17 +60,20 @@ pub async fn get_projects(
|
||||
let projects = state.db.get_projects().await?;
|
||||
let mut out = projects
|
||||
.iter()
|
||||
.map(|p| ProjectInfoContext {
|
||||
id: p.project.id,
|
||||
path: format!("/{}/{}", p.project.owner, p.project.repo),
|
||||
owner: p.project.owner.clone(),
|
||||
repo: p.project.repo.clone(),
|
||||
name: p.project.name().into_owned(),
|
||||
short_name: p.project.short_name().to_owned(),
|
||||
commit: p.commit.sha.clone(),
|
||||
timestamp: p.commit.timestamp,
|
||||
measures: Default::default(),
|
||||
platform: p.project.platform.clone(),
|
||||
.filter_map(|p| {
|
||||
let commit = p.commit.as_ref()?;
|
||||
Some(ProjectInfoContext {
|
||||
id: p.project.id,
|
||||
path: format!("/{}/{}", p.project.owner, p.project.repo),
|
||||
owner: p.project.owner.clone(),
|
||||
repo: p.project.repo.clone(),
|
||||
name: p.project.name().into_owned(),
|
||||
short_name: p.project.short_name().to_owned(),
|
||||
commit: commit.sha.clone(),
|
||||
timestamp: commit.timestamp,
|
||||
measures: Default::default(),
|
||||
platform: p.project.platform.clone(),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -85,14 +88,15 @@ pub async fn get_projects(
|
||||
let Some(version) = info.default_version() else {
|
||||
return (info, Err(anyhow!("No report version found")));
|
||||
};
|
||||
let commit = info.commit.as_ref().unwrap();
|
||||
let report = state
|
||||
.db
|
||||
.get_report(&info.project.owner, &info.project.repo, &info.commit.sha, version)
|
||||
.get_report(&info.project.owner, &info.project.repo, &commit.sha, version)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to fetch report for {}/{} sha {} version {}",
|
||||
info.project.owner, info.project.repo, info.commit.sha, version
|
||||
info.project.owner, info.project.repo, commit.sha, version
|
||||
)
|
||||
});
|
||||
(info, report)
|
||||
|
||||
@@ -208,6 +208,9 @@ pub async fn get_report(
|
||||
else {
|
||||
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
||||
};
|
||||
let Some(commit) = project_info.commit.as_ref() else {
|
||||
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
||||
};
|
||||
let version = if let Some(version) = ¶ms.version {
|
||||
if version.eq_ignore_ascii_case("default") {
|
||||
project_info.default_version().ok_or(AppError::Status(StatusCode::NOT_FOUND))?
|
||||
@@ -220,7 +223,7 @@ pub async fn get_report(
|
||||
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
||||
};
|
||||
let Some(report) =
|
||||
state.db.get_report(¶ms.owner, ¶ms.repo, &project_info.commit.sha, version).await?
|
||||
state.db.get_report(¶ms.owner, ¶ms.repo, &commit.sha, version).await?
|
||||
else {
|
||||
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
||||
};
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ impl Project {
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
|
||||
pub struct ProjectInfo {
|
||||
pub project: Project,
|
||||
pub commit: Commit,
|
||||
pub commit: Option<Commit>,
|
||||
pub report_versions: Vec<String>,
|
||||
pub prev_commit: Option<String>,
|
||||
pub next_commit: Option<String>,
|
||||
|
||||
Reference in New Issue
Block a user