[O] Default allow changing branch rules
This commit is contained in:
@@ -59,6 +59,7 @@ fn parses_value_tokens() {
|
||||
Some("-archive$".to_string())
|
||||
);
|
||||
assert!(!config.mirrors[0].delete_missing);
|
||||
assert!(config.mirrors[0].allow_temporary_gitlab_force_push);
|
||||
let webhook = config.webhook.unwrap();
|
||||
assert!(webhook.install);
|
||||
assert_eq!(webhook.url, "https://mirror.example.test/webhook");
|
||||
@@ -116,6 +117,49 @@ fn mirror_defaults_to_deleting_missing_repos_for_existing_configs() {
|
||||
.unwrap();
|
||||
|
||||
assert!(config.mirrors[0].delete_missing);
|
||||
assert!(config.mirrors[0].allow_temporary_gitlab_force_push);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mirror_can_disable_temporary_gitlab_force_push() {
|
||||
let config: Config = toml::from_str(
|
||||
r#"
|
||||
[[mirrors]]
|
||||
name = "personal"
|
||||
allow_temporary_gitlab_force_push = false
|
||||
|
||||
[[mirrors.endpoints]]
|
||||
site = "github"
|
||||
kind = "user"
|
||||
namespace = "alice"
|
||||
|
||||
[[mirrors.endpoints]]
|
||||
site = "gitlab"
|
||||
kind = "group"
|
||||
namespace = "acme"
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(!config.mirrors[0].allow_temporary_gitlab_force_push);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mirror_serializes_temporary_gitlab_force_push_opt_out() {
|
||||
let mut mirror = mirror_config();
|
||||
mirror.allow_temporary_gitlab_force_push = false;
|
||||
let config = Config {
|
||||
jobs: crate::config::DEFAULT_JOBS,
|
||||
sites: vec![site("github", ProviderKind::Github)],
|
||||
mirrors: vec![mirror],
|
||||
webhook: None,
|
||||
};
|
||||
|
||||
let encoded = toml::to_string(&config).unwrap();
|
||||
let decoded: Config = toml::from_str(&encoded).unwrap();
|
||||
|
||||
assert!(encoded.contains("allow_temporary_gitlab_force_push = false"));
|
||||
assert!(!decoded.mirrors[0].allow_temporary_gitlab_force_push);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -137,6 +181,7 @@ fn validation_rejects_unknown_sites_and_single_endpoint_groups() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -167,6 +212,7 @@ fn validation_rejects_unknown_sites_and_single_endpoint_groups() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -272,6 +318,7 @@ fn validation_rejects_duplicate_mirror_endpoints() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -319,6 +366,7 @@ fn mirror_config() -> MirrorConfig {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -258,6 +258,7 @@ fn wizard_starts_existing_config_at_sync_group_menu() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -288,6 +289,7 @@ fn wizard_can_ask_to_run_full_sync_after_config() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -365,6 +367,7 @@ fn wizard_edits_existing_sync_group_from_menu() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Public,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -456,6 +459,7 @@ fn wizard_prefills_existing_sync_group_when_editing() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -521,6 +525,7 @@ fn wizard_deletes_existing_sync_group_from_menu() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -581,6 +586,7 @@ fn wizard_can_go_back_from_delete_menu() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
|
||||
@@ -79,6 +79,7 @@ where
|
||||
delete_missing,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
});
|
||||
prompt_webhook_setup(reader, writer, config)?;
|
||||
Ok(())
|
||||
|
||||
@@ -686,6 +686,119 @@ fn delete_repo_deletes_url_encoded_gitlab_project() {
|
||||
handle.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gitlab_protected_branch_allow_force_push_reads_setting() {
|
||||
let (api_url, handle) = one_request_server(
|
||||
"200 OK",
|
||||
r#"{"name":"main","allow_force_push":false}"#,
|
||||
|request| {
|
||||
assert!(
|
||||
request.starts_with("GET /projects/parent%2Falice%2Frepo/protected_branches/main "),
|
||||
"request was {request}"
|
||||
);
|
||||
assert!(
|
||||
request
|
||||
.to_ascii_lowercase()
|
||||
.contains("private-token: secret"),
|
||||
"request was {request}"
|
||||
);
|
||||
},
|
||||
);
|
||||
let site = SiteConfig {
|
||||
api_url: Some(api_url),
|
||||
..site(ProviderKind::Gitlab, None)
|
||||
};
|
||||
|
||||
let allow = ProviderClient::new(&site)
|
||||
.unwrap()
|
||||
.gitlab_protected_branch_allow_force_push(
|
||||
&EndpointConfig {
|
||||
site: "gitlab".to_string(),
|
||||
kind: NamespaceKind::Group,
|
||||
namespace: "parent/alice".to_string(),
|
||||
},
|
||||
"repo",
|
||||
"main",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(allow, Some(false));
|
||||
handle.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gitlab_protected_branch_allow_force_push_treats_404_as_unprotected() {
|
||||
let (api_url, handle) = one_request_server(
|
||||
"404 Not Found",
|
||||
r#"{"message":"404 Not found"}"#,
|
||||
|request| {
|
||||
assert!(
|
||||
request
|
||||
.starts_with("GET /projects/alice%2Frepo/protected_branches/feature%2Fsync "),
|
||||
"request was {request}"
|
||||
);
|
||||
},
|
||||
);
|
||||
let site = SiteConfig {
|
||||
api_url: Some(api_url),
|
||||
..site(ProviderKind::Gitlab, None)
|
||||
};
|
||||
|
||||
let allow = ProviderClient::new(&site)
|
||||
.unwrap()
|
||||
.gitlab_protected_branch_allow_force_push(
|
||||
&EndpointConfig {
|
||||
site: "gitlab".to_string(),
|
||||
kind: NamespaceKind::User,
|
||||
namespace: "alice".to_string(),
|
||||
},
|
||||
"repo",
|
||||
"feature/sync",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(allow, None);
|
||||
handle.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_gitlab_protected_branch_allow_force_push_patches_branch() {
|
||||
let (api_url, handle) = one_request_server(
|
||||
"200 OK",
|
||||
r#"{"name":"main","allow_force_push":true}"#,
|
||||
|request| {
|
||||
assert!(
|
||||
request
|
||||
.starts_with("PATCH /projects/parent%2Falice%2Frepo/protected_branches/main "),
|
||||
"request was {request}"
|
||||
);
|
||||
assert!(
|
||||
request.contains(r#"{"allow_force_push":true}"#),
|
||||
"request was {request}"
|
||||
);
|
||||
},
|
||||
);
|
||||
let site = SiteConfig {
|
||||
api_url: Some(api_url),
|
||||
..site(ProviderKind::Gitlab, None)
|
||||
};
|
||||
|
||||
ProviderClient::new(&site)
|
||||
.unwrap()
|
||||
.set_gitlab_protected_branch_allow_force_push(
|
||||
&EndpointConfig {
|
||||
site: "gitlab".to_string(),
|
||||
kind: NamespaceKind::Group,
|
||||
namespace: "parent/alice".to_string(),
|
||||
},
|
||||
"repo",
|
||||
"main",
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
handle.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delete_repo_deletes_gitea_repo() {
|
||||
let (api_url, handle) = one_request_server("204 No Content", "", |request| {
|
||||
|
||||
@@ -448,6 +448,73 @@ fn endpoint_remote_names_do_not_slug_collide() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn temporary_gitlab_force_push_targets_selects_only_gitlab_force_updates() {
|
||||
let mirror = MirrorConfig {
|
||||
endpoints: vec![endpoint("github"), endpoint("gitlab"), endpoint("gitea")],
|
||||
..test_mirror()
|
||||
};
|
||||
let config = Config {
|
||||
jobs: crate::config::DEFAULT_JOBS,
|
||||
sites: vec![
|
||||
site_config("github", crate::config::ProviderKind::Github),
|
||||
site_config("gitlab", crate::config::ProviderKind::Gitlab),
|
||||
site_config("gitea", crate::config::ProviderKind::Gitea),
|
||||
],
|
||||
mirrors: vec![mirror.clone()],
|
||||
webhook: None,
|
||||
};
|
||||
let context = RepoSyncContext {
|
||||
config: &config,
|
||||
mirror: &mirror,
|
||||
work_dir: Path::new("."),
|
||||
redactor: Redactor::new(Vec::new()),
|
||||
dry_run: false,
|
||||
jobs: crate::config::DEFAULT_JOBS,
|
||||
};
|
||||
let updates = vec![
|
||||
BranchUpdate {
|
||||
branch: "main".to_string(),
|
||||
sha: "a".repeat(40),
|
||||
target_remote: remote_key("gitlab"),
|
||||
force: true,
|
||||
},
|
||||
BranchUpdate {
|
||||
branch: "main".to_string(),
|
||||
sha: "a".repeat(40),
|
||||
target_remote: remote_key("gitlab"),
|
||||
force: true,
|
||||
},
|
||||
BranchUpdate {
|
||||
branch: "feature".to_string(),
|
||||
sha: "b".repeat(40),
|
||||
target_remote: remote_key("gitlab"),
|
||||
force: false,
|
||||
},
|
||||
BranchUpdate {
|
||||
branch: "main".to_string(),
|
||||
sha: "c".repeat(40),
|
||||
target_remote: remote_key("github"),
|
||||
force: true,
|
||||
},
|
||||
];
|
||||
let repos = vec![
|
||||
endpoint_repo("github"),
|
||||
endpoint_repo("gitlab"),
|
||||
endpoint_repo("gitea"),
|
||||
];
|
||||
|
||||
let targets = temporary_gitlab_force_push_targets(&context, &repos, &updates).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
targets,
|
||||
vec![GitlabForcePushTarget {
|
||||
endpoint: endpoint("gitlab"),
|
||||
branch: "main".to_string(),
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn targeted_endpoint_repos_synthesize_clone_urls_without_listing() {
|
||||
let mirror = MirrorConfig {
|
||||
@@ -464,6 +531,7 @@ fn targeted_endpoint_repos_synthesize_clone_urls_without_listing() {
|
||||
delete_missing: true,
|
||||
visibility: crate::config::Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
};
|
||||
let config = Config {
|
||||
jobs: crate::config::DEFAULT_JOBS,
|
||||
@@ -603,6 +671,7 @@ fn test_mirror() -> MirrorConfig {
|
||||
delete_missing: true,
|
||||
visibility: crate::config::Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,6 +687,17 @@ fn remote_key(site: &str) -> String {
|
||||
remote_name_for_endpoint(&endpoint(site))
|
||||
}
|
||||
|
||||
fn site_config(name: &str, provider: crate::config::ProviderKind) -> crate::config::SiteConfig {
|
||||
crate::config::SiteConfig {
|
||||
name: name.to_string(),
|
||||
provider,
|
||||
base_url: format!("https://{name}.invalid"),
|
||||
api_url: None,
|
||||
token: crate::config::TokenConfig::Value("token".to_string()),
|
||||
git_username: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn endpoint_repo(site: &str) -> EndpointRepo {
|
||||
EndpointRepo {
|
||||
endpoint: endpoint(site),
|
||||
|
||||
@@ -118,6 +118,7 @@ fn matches_jobs_by_provider_and_namespace() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -146,6 +147,7 @@ fn matching_jobs_respects_repo_name_filters() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
};
|
||||
let config = Config {
|
||||
jobs: crate::config::DEFAULT_JOBS,
|
||||
@@ -365,6 +367,7 @@ fn uninstall_webhooks_skips_blocked_provider_access() {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}],
|
||||
webhook: None,
|
||||
};
|
||||
@@ -719,6 +722,7 @@ fn filtered_mirror() -> MirrorConfig {
|
||||
delete_missing: true,
|
||||
visibility: Visibility::Private,
|
||||
conflict_resolution: ConflictResolutionStrategy::Fail,
|
||||
allow_temporary_gitlab_force_push: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user