1use super::model::*;
7use std::collections::BTreeMap;
8
9const MAIN_REGEX: &str = "^master$|^main$";
10const DEVELOP_REGEX: &str = "^dev(elop)?(ment)?$";
11const RELEASE_REGEX: &str = r"^releases?[\/-](?<BranchName>.+)";
12const FEATURE_REGEX: &str = r"^features?[\/-](?<BranchName>.+)";
13const PR_REGEX: &str = r"^(pull-requests|pull|pr)[\/-](?<Number>\d*)";
14const HOTFIX_REGEX: &str = r"^hotfix(es)?[\/-](?<BranchName>.+)";
15const SUPPORT_REGEX: &str = r"^support[\/-](?<BranchName>.+)";
16const UNKNOWN_REGEX: &str = "(?<BranchName>.+)";
17
18const MAJOR_BUMP: &str = r"\+semver:\s?(breaking|major)";
19const MINOR_BUMP: &str = r"\+semver:\s?(feature|minor)";
20const PATCH_BUMP: &str = r"\+semver:\s?(fix|patch)";
21const NO_BUMP: &str = r"\+semver:\s?(none|skip)";
22
23fn prevent(
24 of_merged: Option<bool>,
25 when_merged: Option<bool>,
26 when_tagged: Option<bool>,
27) -> PreventIncrement {
28 PreventIncrement {
29 of_merged_branch: of_merged,
30 when_branch_merged: when_merged,
31 when_current_commit_tagged: when_tagged,
32 }
33}
34
35fn global_base(mode: DeploymentMode, strategies: Vec<VersionStrategy>) -> GitVersionConfiguration {
37 GitVersionConfiguration {
38 assembly_versioning_scheme: Some(VersioningScheme::MajorMinorPatch),
39 assembly_file_versioning_scheme: Some(VersioningScheme::MajorMinorPatch),
40 assembly_informational_format: Some("{InformationalVersion}".into()),
41 tag_prefix: Some("[vV]?".into()),
42 version_in_branch_pattern: Some(r"(?<version>[vV]?\d+(\.\d+)?(\.\d+)?).*".into()),
43 major_version_bump_message: Some(MAJOR_BUMP.into()),
44 minor_version_bump_message: Some(MINOR_BUMP.into()),
45 patch_version_bump_message: Some(PATCH_BUMP.into()),
46 no_bump_message: Some(NO_BUMP.into()),
47 tag_pre_release_weight: Some(60000),
48 commit_date_format: Some("yyyy-MM-dd".into()),
49 semantic_version_format: Some(SemanticVersionFormat::Strict),
50 update_build_number: Some(true),
51 strategies,
52 increment: Some(IncrementStrategy::Inherit),
53 mode: Some(mode),
54 label: Some("{BranchName}".into()),
55 regex: Some(String::new()),
56 commit_message_incrementing: Some(CommitMessageIncrementMode::Enabled),
57 prevent_increment: Some(prevent(Some(false), Some(false), Some(true))),
58 track_merge_target: Some(false),
59 track_merge_message: Some(true),
60 tracks_release_branches: Some(false),
61 is_release_branch: Some(false),
62 is_main_branch: Some(false),
63 ..Default::default()
64 }
65}
66
67fn branch(regex: &str) -> BranchConfiguration {
68 BranchConfiguration {
69 regex: Some(regex.into()),
70 ..Default::default()
71 }
72}
73
74fn default_strategies() -> Vec<VersionStrategy> {
76 vec![
77 VersionStrategy::Fallback,
78 VersionStrategy::ConfiguredNextVersion,
79 VersionStrategy::MergeMessage,
80 VersionStrategy::TaggedCommit,
81 VersionStrategy::TrackReleaseBranches,
82 VersionStrategy::VersionInBranchName,
83 ]
84}
85
86pub fn gitflow() -> GitVersionConfiguration {
88 let mut c = global_base(DeploymentMode::ContinuousDelivery, default_strategies());
89 let mut b: BTreeMap<String, BranchConfiguration> = BTreeMap::new();
90
91 b.insert(
92 "develop".into(),
93 BranchConfiguration {
94 increment: Some(IncrementStrategy::Minor),
95 mode: Some(DeploymentMode::ContinuousDelivery),
96 label: Some("alpha".into()),
97 source_branches: vec!["main".into()],
98 prevent_increment: Some(prevent(None, None, Some(false))),
99 track_merge_target: Some(true),
100 track_merge_message: Some(true),
101 tracks_release_branches: Some(true),
102 is_main_branch: Some(false),
103 is_release_branch: Some(false),
104 pre_release_weight: Some(0),
105 ..branch(DEVELOP_REGEX)
106 },
107 );
108 b.insert(
109 "main".into(),
110 BranchConfiguration {
111 increment: Some(IncrementStrategy::Patch),
112 label: Some(String::new()),
113 source_branches: vec![],
114 prevent_increment: Some(prevent(Some(true), None, None)),
115 track_merge_target: Some(false),
116 track_merge_message: Some(true),
117 is_main_branch: Some(true),
118 pre_release_weight: Some(55000),
119 ..branch(MAIN_REGEX)
120 },
121 );
122 b.insert(
123 "release".into(),
124 BranchConfiguration {
125 increment: Some(IncrementStrategy::Minor),
126 mode: Some(DeploymentMode::ManualDeployment),
127 label: Some("beta".into()),
128 source_branches: vec!["main".into(), "support".into()],
129 prevent_increment: Some(prevent(Some(true), None, Some(false))),
130 track_merge_target: Some(false),
131 is_release_branch: Some(true),
132 pre_release_weight: Some(30000),
133 ..branch(RELEASE_REGEX)
134 },
135 );
136 b.insert(
137 "feature".into(),
138 BranchConfiguration {
139 increment: Some(IncrementStrategy::Inherit),
140 mode: Some(DeploymentMode::ManualDeployment),
141 label: Some("{BranchName}".into()),
142 source_branches: vec![
143 "develop".into(),
144 "main".into(),
145 "release".into(),
146 "support".into(),
147 "hotfix".into(),
148 ],
149 prevent_increment: Some(prevent(None, None, Some(false))),
150 track_merge_message: Some(true),
151 pre_release_weight: Some(30000),
152 ..branch(FEATURE_REGEX)
153 },
154 );
155 b.insert(
156 "pull-request".into(),
157 BranchConfiguration {
158 increment: Some(IncrementStrategy::Inherit),
159 mode: Some(DeploymentMode::ContinuousDelivery),
160 label: Some("PullRequest{Number}".into()),
161 source_branches: vec![
162 "develop".into(),
163 "main".into(),
164 "release".into(),
165 "feature".into(),
166 "support".into(),
167 "hotfix".into(),
168 ],
169 prevent_increment: Some(prevent(Some(true), None, Some(false))),
170 track_merge_message: Some(true),
171 pre_release_weight: Some(30000),
172 ..branch(PR_REGEX)
173 },
174 );
175 b.insert(
176 "hotfix".into(),
177 BranchConfiguration {
178 increment: Some(IncrementStrategy::Inherit),
179 mode: Some(DeploymentMode::ManualDeployment),
180 label: Some("beta".into()),
181 source_branches: vec!["main".into(), "support".into()],
182 prevent_increment: Some(prevent(None, None, Some(false))),
183 is_release_branch: Some(true),
184 pre_release_weight: Some(30000),
185 ..branch(HOTFIX_REGEX)
186 },
187 );
188 b.insert(
189 "support".into(),
190 BranchConfiguration {
191 increment: Some(IncrementStrategy::Patch),
192 label: Some(String::new()),
193 source_branches: vec!["main".into()],
194 prevent_increment: Some(prevent(Some(true), None, None)),
195 track_merge_target: Some(false),
196 is_main_branch: Some(true),
197 pre_release_weight: Some(55000),
198 ..branch(SUPPORT_REGEX)
199 },
200 );
201 b.insert(
202 "unknown".into(),
203 BranchConfiguration {
204 increment: Some(IncrementStrategy::Inherit),
205 mode: Some(DeploymentMode::ManualDeployment),
206 label: Some("{BranchName}".into()),
207 source_branches: vec![
208 "main".into(),
209 "develop".into(),
210 "release".into(),
211 "feature".into(),
212 "pull-request".into(),
213 "support".into(),
214 "hotfix".into(),
215 ],
216 ..branch(UNKNOWN_REGEX)
217 },
218 );
219
220 c.branches = b;
221 c
222}
223
224pub fn githubflow() -> GitVersionConfiguration {
226 let mut c = global_base(DeploymentMode::ContinuousDelivery, default_strategies());
227 let mut b: BTreeMap<String, BranchConfiguration> = BTreeMap::new();
228
229 b.insert(
230 "main".into(),
231 BranchConfiguration {
232 increment: Some(IncrementStrategy::Patch),
233 label: Some(String::new()),
234 source_branches: vec![],
235 prevent_increment: Some(prevent(Some(true), None, None)),
236 is_main_branch: Some(true),
237 pre_release_weight: Some(55000),
238 ..branch(MAIN_REGEX)
239 },
240 );
241 b.insert(
242 "release".into(),
243 BranchConfiguration {
244 increment: Some(IncrementStrategy::Patch),
245 mode: Some(DeploymentMode::ManualDeployment),
246 label: Some("beta".into()),
247 source_branches: vec!["main".into()],
248 prevent_increment: Some(prevent(Some(true), Some(false), Some(false))),
249 track_merge_target: Some(false),
250 track_merge_message: Some(true),
251 is_release_branch: Some(true),
252 pre_release_weight: Some(30000),
253 ..branch(RELEASE_REGEX)
254 },
255 );
256 b.insert(
257 "feature".into(),
258 BranchConfiguration {
259 increment: Some(IncrementStrategy::Inherit),
260 mode: Some(DeploymentMode::ManualDeployment),
261 label: Some("{BranchName}".into()),
262 source_branches: vec!["main".into(), "release".into()],
263 prevent_increment: Some(prevent(None, None, Some(false))),
264 pre_release_weight: Some(30000),
265 ..branch(FEATURE_REGEX)
266 },
267 );
268 b.insert(
269 "pull-request".into(),
270 BranchConfiguration {
271 increment: Some(IncrementStrategy::Inherit),
272 mode: Some(DeploymentMode::ContinuousDelivery),
273 label: Some("PullRequest{Number}".into()),
274 source_branches: vec!["main".into(), "release".into(), "feature".into()],
275 prevent_increment: Some(prevent(Some(true), None, Some(false))),
276 pre_release_weight: Some(30000),
277 ..branch(PR_REGEX)
278 },
279 );
280 b.insert(
281 "unknown".into(),
282 BranchConfiguration {
283 increment: Some(IncrementStrategy::Inherit),
284 mode: Some(DeploymentMode::ManualDeployment),
285 label: Some("{BranchName}".into()),
286 source_branches: vec![
287 "main".into(),
288 "release".into(),
289 "feature".into(),
290 "pull-request".into(),
291 ],
292 prevent_increment: Some(prevent(None, None, Some(false))),
293 track_merge_message: Some(false),
294 ..branch(UNKNOWN_REGEX)
295 },
296 );
297
298 c.branches = b;
299 c
300}
301
302pub fn trunkbased() -> GitVersionConfiguration {
304 let mut c = global_base(
305 DeploymentMode::ContinuousDelivery,
306 vec![
307 VersionStrategy::ConfiguredNextVersion,
308 VersionStrategy::Mainline,
309 ],
310 );
311 let mut b: BTreeMap<String, BranchConfiguration> = BTreeMap::new();
312
313 b.insert(
314 "main".into(),
315 BranchConfiguration {
316 increment: Some(IncrementStrategy::Patch),
317 mode: Some(DeploymentMode::ContinuousDeployment),
318 label: Some(String::new()),
319 source_branches: vec![],
320 prevent_increment: Some(prevent(Some(true), None, None)),
321 is_main_branch: Some(true),
322 pre_release_weight: Some(55000),
323 ..branch(MAIN_REGEX)
324 },
325 );
326 b.insert(
327 "feature".into(),
328 BranchConfiguration {
329 increment: Some(IncrementStrategy::Minor),
330 mode: Some(DeploymentMode::ContinuousDelivery),
331 label: Some("{BranchName}".into()),
332 source_branches: vec!["main".into()],
333 prevent_increment: Some(prevent(None, None, Some(false))),
334 pre_release_weight: Some(30000),
335 ..branch(FEATURE_REGEX)
336 },
337 );
338 b.insert(
339 "hotfix".into(),
340 BranchConfiguration {
341 increment: Some(IncrementStrategy::Patch),
342 mode: Some(DeploymentMode::ContinuousDelivery),
343 label: Some("{BranchName}".into()),
344 source_branches: vec!["main".into()],
345 prevent_increment: Some(prevent(None, None, Some(false))),
346 is_release_branch: Some(true),
347 pre_release_weight: Some(30000),
348 ..branch(HOTFIX_REGEX)
349 },
350 );
351 b.insert(
352 "pull-request".into(),
353 BranchConfiguration {
354 increment: Some(IncrementStrategy::Inherit),
355 mode: Some(DeploymentMode::ContinuousDelivery),
356 label: Some("PullRequest{Number}".into()),
357 source_branches: vec!["main".into(), "feature".into(), "hotfix".into()],
358 prevent_increment: Some(prevent(Some(true), None, Some(false))),
359 pre_release_weight: Some(30000),
360 ..branch(PR_REGEX)
361 },
362 );
363 b.insert(
364 "unknown".into(),
365 BranchConfiguration {
366 increment: Some(IncrementStrategy::Patch),
367 mode: Some(DeploymentMode::ContinuousDelivery),
368 label: Some("{BranchName}".into()),
369 source_branches: vec!["main".into()],
370 prevent_increment: Some(prevent(None, None, Some(false))),
371 pre_release_weight: Some(30000),
372 ..branch(UNKNOWN_REGEX)
373 },
374 );
375
376 c.branches = b;
377 c
378}
379
380pub fn for_workflow(workflow: Option<&str>) -> GitVersionConfiguration {
382 match workflow.map(|w| w.to_ascii_lowercase()) {
383 Some(w) if w.starts_with("githubflow") => githubflow(),
384 Some(w) if w.starts_with("trunkbased") || w.starts_with("mainline") => trunkbased(),
385 _ => gitflow(),
386 }
387}