feat: add predicate DefaultBranch

Signed-off-by: Lars Wirzenius <liw@liw.fi>
This commit is contained in:
Lars Wirzenius
2025-02-04 16:59:22 +02:00
parent 14ad23cc83
commit 2ef02467f8
2 changed files with 82 additions and 1 deletions
+36
View File
@@ -1194,6 +1194,42 @@ triggers:
~~~
## Filter predicate `DefaultBranch`
_Want:_ We can allow an event if the event refers to the default
branch.
_Why:_ This is so that the user doesn't need to spell out the name
explicitly.
~~~scenario
given a Radicle node, with CI configured with broker.yaml and adapter dummy.sh
given a Git repository xyzzy in the Radicle node
given file config.yaml from filter-defaultbranch.yaml
when I run cibtool --db ci-broker.db event add --repo xyzzy --ref main --commit HEAD --kind branch-created
when I run cibtool --db ci-broker.db event add --repo xyzzy --ref oksa --commit HEAD --kind branch-created
when I run ./env.sh cib --config config.yaml queued
when I run cibtool --db ci-broker.db run list --json
then stdout contains "main"
then stdout doesn't contain "oksa"
~~~
~~~{#filter-defaultbranch.yaml .file .json}
db: ci-broker.db
adapters:
default:
command: ./adapter.sh
triggers:
- adapter: default
filters:
- !DefaultBranch
~~~
# Acceptance criteria for test tooling
The event synthesizer is a helper to feed the CI broker node events in
+46 -1
View File
@@ -2,7 +2,13 @@ use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use radicle::{cob::patch::PatchId, git::RefString, node::NodeId, prelude::RepoId};
use radicle::{
cob::patch::PatchId,
git::RefString,
node::NodeId,
prelude::{Profile, RepoId},
storage::git::Repository,
};
use radicle_git_ext::Oid;
use crate::{
@@ -49,6 +55,9 @@ pub enum EventFilter {
/// Event is for a specific branch.
Branch(RefString),
/// Event if for the default branch for the repository.
DefaultBranch,
/// Branch was created.
BranchCreated,
@@ -113,6 +122,7 @@ impl EventFilter {
Self::Node(wantedc) => from_node == wantedc,
Self::Repository(wanted) => repo == wanted,
Self::Branch(wanted) => branch == wanted,
Self::DefaultBranch => is_default_branch(repo, branch),
Self::BranchCreated => true,
_ => false,
},
@@ -125,6 +135,7 @@ impl EventFilter {
Self::Node(wanted) => from_node == wanted,
Self::Repository(wanted) => repo == wanted,
Self::Branch(wanted) => branch == wanted,
Self::DefaultBranch => is_default_branch(repo, branch),
Self::BranchUpdated => true,
_ => false,
},
@@ -137,6 +148,7 @@ impl EventFilter {
Self::Node(wanted) => from_node == wanted,
Self::Repository(wanted) => repo == wanted,
Self::Branch(wanted) => branch == wanted,
Self::DefaultBranch => is_default_branch(repo, branch),
Self::BranchDeleted => true,
_ => false,
},
@@ -176,6 +188,39 @@ impl EventFilter {
}
}
fn is_default_branch(repo_id: &RepoId, wanted: &str) -> bool {
let res = get_default_branch(repo_id);
logger::debug2(format!("is_default_branch: res={res:?}"));
if let Ok(actual) = res {
logger::debug2(format!(
"is_default_branch: actual={actual} wanted={wanted}"
));
actual == wanted
} else {
logger::debug("is_default_branch: could not get actual");
false
}
}
fn get_default_branch(repo_id: &RepoId) -> Result<String, Box<dyn std::error::Error>> {
let profile = Profile::load()?;
logger::debug("loaded profile");
let path = profile.storage.path().join(repo_id.canonical());
logger::debug2(format!("path={}", path.display()));
let repo = Repository::open(path, *repo_id)?;
logger::debug("loaded repo");
let proj = repo.project()?;
logger::debug("loaded project");
let def = format!(
"{}/refs/heads/{}",
profile.id().to_namespace(),
proj.default_branch()
);
Ok(def)
}
#[derive(Deserialize)]
struct Filters {
filters: Vec<EventFilter>,