[snowpatch] [PATCH] Implement tunable preservation of remote branches
Andrew Donnellan
ajd at linux.ibm.com
Tue Oct 29 10:09:23 AEDT 2019
From: Russell Currey <ruscur at russell.cc>
A new parameter, branch_preserve_policy, allows users to specify whether
they want to preserve all remote branches, just full series or
standalone patches, or none (default, current behaviour). In addition,
users can specify a separate remote to push to, allowing branches to be
preserved while still deleting them from the main remote used for
testing.
Signed-off-by: Russell Currey <ruscur at russell.cc>
[ajd: rebase on master]
Signed-off-by: Andrew Donnellan <ajd at linux.ibm.com>
---
docs/configuration.md | 18 ++++++++++++++++--
examples/openpower.toml | 2 ++
src/main.rs | 25 +++++++++++++++++++++++--
src/settings.rs | 27 +++++++++++++++++++++++++++
4 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/docs/configuration.md b/docs/configuration.md
index d4c383fefe9e..0a49b00ed502 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -147,7 +147,21 @@ Example:
- `base_remote_name`: the name of the remote where base branches are retrieved
from (Optional, defaults to value of remote_name)
-- `push_results`: whether test results should be pushed to Patchwork for this project
+- `push_results`: whether test results should be pushed to Patchwork for this
+ project
+
+- `branch_preserve_policy`: set the policy for how snowpatch will handle
+ branches on git remotes after tests have run.
+
+ "ALL": preserves all branches on the remote.
+ "SERIES": only preserves full series or standalone patches.
+ "NONE": deletes branches on the remote after testing.
+
+ (Optional, defaults to NONE)
+
+- `branch_preserve_remote`: only valid if `branch_preserve_policy` is not NONE.
+ Specify the name of a git remote that will only be used for branch
+ preservation. If set, branches will be deleted on the main remote. (Optional)
Individual jobs contain the following:
@@ -172,4 +186,4 @@ Individual jobs contain the following:
- `warn_on_fail`: if true, this job will return a warning rather than a failure
if it fails (Optional, defaults to false)
-- Any further parameters will be passed to Jenkins as build parameters
\ No newline at end of file
+- Any further parameters will be passed to Jenkins as build parameters
diff --git a/examples/openpower.toml b/examples/openpower.toml
index d72d47ad7c69..a85f9f916981 100644
--- a/examples/openpower.toml
+++ b/examples/openpower.toml
@@ -43,6 +43,8 @@ token = "33333333333333333333333333333333"
remote_uri = "git at github.com:ruscur/skiboot.git"
base_remote_name = "origin"
push_results = false
+ branch_preserve_policy = "SERIES" # defaults to NONE
+ branch_preserve_remote = "gitlab" # branch to push to, but not delete from
[[projects.skiboot.jobs]]
job = "skiboot-compile-test-snowpatch"
diff --git a/src/main.rs b/src/main.rs
index 999b16cbdabe..ad1733a23a95 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -65,7 +65,7 @@ mod jenkins;
use jenkins::JenkinsBackend;
mod settings;
-use settings::{Config, Job, Project};
+use settings::{BranchPreservePolicy, Config, Job, Project};
mod git;
@@ -194,6 +194,9 @@ fn test_patch(
hefty_tests: bool,
) -> Vec<TestResult> {
let repo = project.get_repo().unwrap();
+ let preserve_policy = project
+ .branch_preserve_policy
+ .unwrap_or(BranchPreservePolicy::None);
let mut results: Vec<TestResult> = Vec::new();
if !path.is_file() {
return results;
@@ -206,6 +209,7 @@ fn test_patch(
_ => &project.remote_name,
})
.unwrap();
+ let preserve_remote = &project.branch_preserve_remote;
let mut push_callbacks = RemoteCallbacks::new();
push_callbacks.credentials(|_, _, _| git::cred_from_settings(&settings.git));
@@ -244,6 +248,18 @@ fn test_patch(
if output.is_ok() {
git::push_to_remote(&mut remote, &branch, false, &mut push_opts).unwrap();
+ if preserve_remote.is_some()
+ && (preserve_policy == BranchPreservePolicy::All
+ || (preserve_policy == BranchPreservePolicy::Series && hefty_tests))
+ {
+ git::push_to_remote(
+ &mut repo.find_remote(preserve_remote.as_ref().unwrap()).unwrap(),
+ &branch,
+ false,
+ &mut push_opts,
+ )
+ .unwrap();
+ }
}
git::delete_branch(&repo, &tag).unwrap_or_else(|err| {
@@ -323,7 +339,12 @@ fn test_patch(
results.append(&mut thread.join().unwrap());
// Delete the remote branch now it's not needed any more
- git::push_to_remote(&mut remote, &branch, true, &mut push_opts).unwrap();
+ if preserve_remote.is_some()
+ || preserve_policy == BranchPreservePolicy::None
+ || (preserve_policy == BranchPreservePolicy::Series && !hefty_tests)
+ {
+ git::push_to_remote(&mut remote, &branch, true, &mut push_opts).unwrap();
+ }
}
if !successfully_applied {
diff --git a/src/settings.rs b/src/settings.rs
index e20d2e856834..b3b82894a876 100644
--- a/src/settings.rs
+++ b/src/settings.rs
@@ -29,6 +29,13 @@ use std::io::Read;
// TODO: Give more informative error messages when we fail to parse.
+#[derive(Deserialize, Clone, PartialEq, Copy)]
+pub enum BranchPreservePolicy {
+ All,
+ Series,
+ None,
+}
+
#[derive(Deserialize, Clone)]
pub struct Git {
pub user: String,
@@ -68,6 +75,10 @@ pub struct Project {
pub base_remote_name: Option<String>,
pub jobs: Vec<Job>,
pub push_results: bool,
+ #[serde(default)] // necessary for serde to treat as optional
+ #[serde(deserialize_with = "parse_preserve_policy")]
+ pub branch_preserve_policy: Option<BranchPreservePolicy>,
+ pub branch_preserve_remote: Option<String>,
pub category: Option<String>,
}
@@ -89,6 +100,22 @@ pub struct Job {
pub parameters: BTreeMap<String, String>,
}
+fn parse_preserve_policy<'de, D>(deserializer: D) -> Result<Option<BranchPreservePolicy>, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ let s = String::deserialize(deserializer)?;
+
+ match s.as_ref() {
+ "ALL" => Ok(Some(BranchPreservePolicy::All)),
+ "SERIES" => Ok(Some(BranchPreservePolicy::Series)),
+ "NONE" => Ok(Some(BranchPreservePolicy::None)),
+ _ => Err(serde::de::Error::custom(
+ "branch_preserve_policy not one of ALL, SERIES, NONE",
+ )),
+ }
+}
+
impl<'de> Deserialize<'de> for Job {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
--
2.20.1
More information about the snowpatch
mailing list