Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
09a5307
circus-evaluator: migrate evix 0.3.3 -> 1.0.2
NotAShelf Jun 27, 2026
1ea64db
various: add `eval_workers` config field instead of hardcoding worker…
NotAShelf Jun 27, 2026
f0795e6
nix: set VM test OOM from worker subprocesses; increase memory size
NotAShelf Jun 27, 2026
b126a66
circus-evaluator: cap the GC initial heap so eval workers survive swa…
amaanq Jun 28, 2026
07f22af
nix: drop the VM memory bump now that the GC heap is bounded
amaanq Jun 28, 2026
9d9e689
circus-evaluator: bump evix 1.0.2 -> 2.0.0
amaanq Jul 2, 2026
ea775bb
circus-evaluator: keep vendored libgit2 out of the dynamic symbol table
amaanq Jul 3, 2026
10adecd
circus-common: add `Cancelled` and `TimedOut` evaluation status variants
NotAShelf Jul 12, 2026
1fba0c6
circus-common: rename `update_status` to `finish_running`; add restar…
NotAShelf Jul 12, 2026
e21afad
circus-config: allow configuring evaluation timeout
NotAShelf Jul 12, 2026
8d5e8af
circus-evaluator: plumb `CancellationToken` through nix eval; add can…
NotAShelf Jul 12, 2026
00780c6
circus-server: add cancel and restart admin routes; allow cancel/rest…
NotAShelf Jul 12, 2026
b3643a9
circus-error: show raw `error_message` instead of parsed `error_lines`
NotAShelf Jul 12, 2026
8b6aae3
circus-evaluator: bump evix 2.0.0 -> 2.0.1
NotAShelf Jul 13, 2026
46f3d3d
circus-evaluator: pin flake evaluation to checkout commit
NotAShelf Jul 13, 2026
91228a7
nix/tests: assert commits produce new derivations
NotAShelf Jul 13, 2026
012b81a
various: fix evaluator cancellation and retry lifecycles
NotAShelf Jul 15, 2026
3189d47
various: fix evaluator restart handling for inactive jobsets
NotAShelf Jul 16, 2026
b1a8ff4
circus-evaluator: fix processing of restarted interval evaluations
NotAShelf Jul 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ exceptions = [
{ allow = [
"EUPL-1.2",
], crate = "evix" },
{ allow = [
"EUPL-1.2",
], crate = "evix-protocol" },
{ allow = [
"EUPL-1.2",
], crate = "cognos" },
Expand Down
143 changes: 105 additions & 38 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ jsonwebtoken = { version = "10.4.0", default-features = false }

# In-house crates and Nix utilities
cognos = "1.0.0"
evix = { version = "0.3.3", features = [ "flake" ] }
evix = { version = "2.0.1", features = [ "flake" ] }

# Workspace Clippy lints. All workspace crates must inherit them in individual
# manifests for subcrates. The below list is a rather pedantic list of lints
Expand Down
9 changes: 5 additions & 4 deletions circus.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ enabled = true
# text = "#0f172a"

[evaluator]
allow_ifd = false
auto_allowed_uris = true
git_timeout = 600
nix_timeout = 1800
allow_ifd = false
auto_allowed_uris = true
git_timeout = 600
nix_timeout = 1800
# max_eval_time = 3600
poll_interval = 60
require_locked_flake = false
restrict_eval = true
Expand Down
6 changes: 6 additions & 0 deletions crates/circus/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
// Keep the vendored git2 copy from interposing nix-bindings' libgit2.so.
if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("linux") {
println!("cargo:rustc-link-arg-bins=-Wl,--exclude-libs,ALL");
}
}
19 changes: 16 additions & 3 deletions crates/common/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@ pub struct Evaluation {
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::Type)]
#[serde(rename_all = "lowercase")]
#[sqlx(type_name = "text", rename_all = "lowercase")]
#[serde(rename_all = "snake_case")]
#[sqlx(type_name = "text", rename_all = "snake_case")]
pub enum EvaluationStatus {
Pending,
Running,
Completed,
Failed,
Cancelled,
TimedOut,
Comment thread
NotAShelf marked this conversation as resolved.
}

impl EvaluationStatus {
Expand All @@ -82,6 +84,8 @@ impl EvaluationStatus {
match self {
Self::Completed => ("Completed", "completed"),
Self::Failed => ("Failed", "failed"),
Self::Cancelled => ("Cancelled", "cancelled"),
Self::TimedOut => ("Timed out", "timed-out"),
Self::Running => ("Running", "running"),
Self::Pending => ("Pending", "pending"),
}
Expand Down Expand Up @@ -509,7 +513,7 @@ impl<'r> sqlx::Decode<'r, sqlx::Postgres> for BuildStatus {

#[cfg(test)]
mod build_status_tests {
use super::BuildStatus;
use super::{BuildStatus, EvaluationStatus};

#[test]
fn build_status_i32_round_trips() {
Expand Down Expand Up @@ -540,6 +544,15 @@ mod build_status_tests {
assert_eq!(BuildStatus::from_i32(-1), None);
assert_eq!(BuildStatus::from_i32(15), None);
}

#[test]
fn timed_out_status_uses_database_spelling() {
assert_eq!(
serde_json::to_string(&EvaluationStatus::TimedOut)
.expect("EvaluationStatus serializes"),
"\"timed_out\""
);
}
}

#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
Expand Down
28 changes: 26 additions & 2 deletions crates/common/src/repo/build_dependencies.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use sqlx::PgPool;
use sqlx::{Executor, PgPool, Postgres, Transaction};
use uuid::Uuid;

use crate::{
Expand All @@ -17,13 +17,37 @@ pub async fn create(
build_id: Uuid,
dependency_build_id: Uuid,
) -> Result<BuildDependency> {
create_with(pool, build_id, dependency_build_id).await
}

/// Create a build dependency relationship within an existing transaction.
///
/// # Errors
///
/// Returns an error if database insert fails or dependency already exists.
pub async fn create_in_transaction(
tx: &mut Transaction<'_, Postgres>,
build_id: Uuid,
dependency_build_id: Uuid,
) -> Result<BuildDependency> {
create_with(&mut **tx, build_id, dependency_build_id).await
}

async fn create_with<'e, E>(
executor: E,
build_id: Uuid,
dependency_build_id: Uuid,
) -> Result<BuildDependency>
where
E: Executor<'e, Database = Postgres>,
{
sqlx::query_as::<_, BuildDependency>(
"INSERT INTO build_dependencies (build_id, dependency_build_id) VALUES \
($1, $2) RETURNING *",
)
.bind(build_id)
.bind(dependency_build_id)
.fetch_one(pool)
.fetch_one(executor)
.await
.on_unique_violation(|| {
format!(
Expand Down
Loading