Skip to main content

ephemeris_forge_forgejo/api/model/
branch_rules.rs

1use facet::Facet;
2
3use crate::PushAccess;
4
5/// The subset of the `BranchProtection` response the CLI reads.
6///
7/// Open in the same way as [`super::Repository`]. `created_at` is deliberately
8/// not vendored: the response already arrives in the order Forgejo consults the
9/// rules in, so nothing here has to reconstruct it from a timestamp.
10#[derive(Clone, Debug, Default, Facet)]
11pub struct BranchProtection {
12    /// The rule's name.
13    #[facet(default)]
14    pub rule_name: String,
15    /// Whether the protection also applies to repository administrators.
16    pub apply_to_admins: Option<bool>,
17    /// The teams whose approvals count, when the approvals whitelist is on.
18    pub approvals_whitelist_teams: Option<Vec<String>>,
19    /// The users whose approvals count, when the approvals whitelist is on.
20    pub approvals_whitelist_username: Option<Vec<String>>,
21    /// Whether an official code owner review request blocks merging until
22    /// resolved.
23    pub block_on_official_review_requests: Option<bool>,
24    /// Whether merging is blocked while the branch is behind its base.
25    pub block_on_outdated_branch: Option<bool>,
26    /// Whether a requested change blocks merging until it is resolved.
27    pub block_on_rejected_reviews: Option<bool>,
28    /// Whether a new commit dismisses existing approvals.
29    pub dismiss_stale_approvals: Option<bool>,
30    /// Whether only the approvals whitelist counts toward the required
31    /// approvals.
32    pub enable_approvals_whitelist: Option<bool>,
33    /// Whether only the merge whitelist may merge.
34    pub enable_merge_whitelist: Option<bool>,
35    /// Whether direct pushes to the branch are allowed at all.
36    pub enable_push: Option<bool>,
37    /// Whether only the push whitelist may push.
38    pub enable_push_whitelist: Option<bool>,
39    /// Whether status checks must pass before merging.
40    pub enable_status_check: Option<bool>,
41    /// Whether approvals on an outdated commit stop counting.
42    pub ignore_stale_approvals: Option<bool>,
43    /// The teams that may merge, when the merge whitelist is on.
44    pub merge_whitelist_teams: Option<Vec<String>>,
45    /// The users that may merge, when the merge whitelist is on.
46    pub merge_whitelist_usernames: Option<Vec<String>>,
47    /// Semicolon separated glob patterns for files that only whitelisted
48    /// pushers may change.
49    pub protected_file_patterns: Option<String>,
50    /// Whether deploy keys may push, when the push whitelist is on.
51    pub push_whitelist_deploy_keys: Option<bool>,
52    /// The teams that may push, when the push whitelist is on.
53    pub push_whitelist_teams: Option<Vec<String>>,
54    /// The users that may push, when the push whitelist is on.
55    pub push_whitelist_usernames: Option<Vec<String>>,
56    /// Whether every commit on the branch must be signed.
57    pub require_signed_commits: Option<bool>,
58    /// The number of approving reviews required before merging.
59    pub required_approvals: Option<i64>,
60    /// The status check contexts that must report success.
61    pub status_check_contexts: Option<Vec<String>>,
62    /// Semicolon separated glob patterns for files that any pusher may
63    /// change despite the protected patterns.
64    pub unprotected_file_patterns: Option<String>,
65}
66
67impl BranchProtection {
68    /// The push access the two wire flags describe, when Forgejo reported both.
69    #[must_use]
70    pub fn push_access(&self) -> Option<PushAccess> {
71        Some(PushAccess::from_flags(
72            self.enable_push?,
73            self.enable_push_whitelist?,
74        ))
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::BranchProtection;
81
82    #[test]
83    fn unknown_properties_are_ignored() {
84        let raw = r#"{"rule_name": "main", "branch_name": "main", "created_at": "now"}"#;
85        let rule: BranchProtection = facet_json::from_str(raw).expect("parses");
86        assert_eq!(rule.rule_name, "main");
87        assert_eq!(rule.enable_push, None);
88    }
89}