1use std::collections::HashMap;
2
3use next_version::{NextVersion as NextVersionTrait, VersionUpdater};
4use semver::Version;
5use serde::{Deserialize, Serialize};
6use serde_json::value::Value;
7
8use crate::commit::{Commit, Range, commits_to_conventional_commits};
9use crate::config::{Bump, BumpType};
10use crate::error::Result;
11use crate::statistics::Statistics;
12#[cfg(feature = "remote")]
13use crate::{
14 contributor::RemoteContributor,
15 remote::{RemoteCommit, RemotePullRequest, RemoteReleaseMetadata},
16};
17
18#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
20#[serde(rename_all(serialize = "camelCase"))]
21pub struct Release<'a> {
22 pub version: Option<String>,
24 pub message: Option<String>,
26 #[serde(deserialize_with = "commits_to_conventional_commits")]
28 pub commits: Vec<Commit<'a>>,
29 #[serde(rename = "commit_id")]
31 pub commit_id: Option<String>,
32 pub timestamp: Option<i64>,
34 pub previous: Option<Box<Release<'a>>>,
36 pub repository: Option<String>,
38 #[serde(rename = "commit_range")]
40 pub commit_range: Option<Range>,
41 #[serde(rename = "submodule_commits")]
45 pub submodule_commits: HashMap<String, Vec<Commit<'a>>>,
46 pub statistics: Option<Statistics>,
48 pub extra: Option<Value>,
50 #[serde(rename = "bump_type")]
52 pub bump_type: Option<BumpType>,
53 #[cfg(feature = "github")]
55 pub github: RemoteReleaseMetadata,
56 #[cfg(feature = "gitlab")]
58 pub gitlab: RemoteReleaseMetadata,
59 #[cfg(feature = "gitea")]
61 pub gitea: RemoteReleaseMetadata,
62 #[cfg(feature = "bitbucket")]
64 pub bitbucket: RemoteReleaseMetadata,
65 #[cfg(feature = "azure_devops")]
67 #[serde(rename = "azure_devops")]
68 pub azure_devops: RemoteReleaseMetadata,
69}
70
71#[cfg(feature = "github")]
72crate::update_release_metadata!(github, update_github_metadata);
73
74#[cfg(feature = "gitlab")]
75crate::update_release_metadata!(gitlab, update_gitlab_metadata);
76
77#[cfg(feature = "gitea")]
78crate::update_release_metadata!(gitea, update_gitea_metadata);
79
80#[cfg(feature = "bitbucket")]
81crate::update_release_metadata!(bitbucket, update_bitbucket_metadata);
82
83#[cfg(feature = "azure_devops")]
84crate::update_release_metadata!(azure_devops, update_azure_devops_metadata);
85
86impl Release<'_> {
87 #[cfg_attr(
92 feature = "tracing",
93 tracing::instrument(
94 skip_all,
95 fields(
96 version = self.version.as_deref().unwrap_or("unreleased"),
97 commits = self.commits.len()
98 )
99 )
100 )]
101 pub fn calculate_next_version(&self) -> Result<NextVersion> {
102 crate::set_progress_message!("Calculating the next version from commits");
103 self.calculate_next_version_with_config(&Bump::default())
104 }
105
106 #[must_use]
112 pub fn with_statistics(mut self) -> Self {
113 self.statistics = Some((&self).into());
114 self
115 }
116
117 #[cfg_attr(
122 feature = "tracing",
123 tracing::instrument(
124 skip_all,
125 fields(
126 version = self.version.as_deref().unwrap_or("unreleased"),
127 commits = self.commits.len()
128 )
129 )
130 )]
131 pub(super) fn calculate_next_version_with_config(&self, config: &Bump) -> Result<NextVersion> {
132 crate::set_progress_message!(
133 "Calculating the next version from commits with custom bump rules"
134 );
135 match self
136 .previous
137 .as_ref()
138 .and_then(|release| release.version.clone())
139 {
140 Some(version) => {
141 let mut semver = Version::parse(&version);
142 let mut prefix = None;
143 if semver.is_err() && version.split('.').count() >= 2 {
144 let mut found_numeric = false;
145 for (i, c) in version.char_indices() {
146 if c.is_numeric() && !found_numeric {
147 found_numeric = true;
148 let version_prefix = version[..i].to_string();
149 let remaining = version[i..].to_string();
150 let version = Version::parse(&remaining);
151 if version.is_ok() {
152 semver = version;
153 prefix = Some(version_prefix);
154 break;
155 }
156 } else if !c.is_numeric() && found_numeric {
157 found_numeric = false;
158 }
159 }
160 }
161 let mut next_version = VersionUpdater::new()
162 .with_features_always_increment_minor(
163 config.features_always_bump_minor.unwrap_or(true),
164 )
165 .with_breaking_always_increment_major(
166 config.breaking_always_bump_major.unwrap_or(true),
167 );
168 if let Some(custom_major_increment_regex) = &config.custom_major_increment_regex {
169 next_version = next_version
170 .with_custom_major_increment_regex(custom_major_increment_regex)?;
171 }
172 if let Some(custom_minor_increment_regex) = &config.custom_minor_increment_regex {
173 next_version = next_version
174 .with_custom_minor_increment_regex(custom_minor_increment_regex)?;
175 }
176 let old_semver = semver?;
177 let (next_version, determined_bump_type) =
178 if let Some(bump_type) = &config.bump_type {
179 let v = match bump_type {
180 BumpType::Major => old_semver.increment_major().to_string(),
181 BumpType::Minor => old_semver.increment_minor().to_string(),
182 BumpType::Patch => old_semver.increment_patch().to_string(),
183 };
184 (v, Some(*bump_type))
185 } else {
186 let new_semver = next_version.increment(
187 &old_semver,
188 self.commits
189 .iter()
190 .map(|commit| commit.message.trim_end().to_string())
191 .collect::<Vec<String>>(),
192 );
193 let bump_type = determine_bump_type(&old_semver, &new_semver);
194 (new_semver.to_string(), bump_type)
195 };
196 let version = if let Some(prefix) = prefix {
197 format!("{prefix}{next_version}")
198 } else {
199 next_version
200 };
201 Ok(NextVersion {
202 version,
203 bump_type: determined_bump_type,
204 })
205 }
206 None => Ok(NextVersion {
207 version: config.get_initial_tag(),
208 bump_type: None,
209 }),
210 }
211 }
212}
213
214#[derive(Debug, Clone, PartialEq)]
216pub struct NextVersion {
217 pub version: String,
219 pub bump_type: Option<BumpType>,
221}
222
223fn determine_bump_type(old: &Version, new: &Version) -> Option<BumpType> {
225 if new.major != old.major {
226 Some(BumpType::Major)
227 } else if new.minor != old.minor {
228 Some(BumpType::Minor)
229 } else if new.patch != old.patch {
230 Some(BumpType::Patch)
231 } else {
232 None
233 }
234}
235
236#[derive(Serialize)]
238pub struct Releases<'a> {
239 pub releases: &'a Vec<Release<'a>>,
241}
242
243impl Releases<'_> {
244 pub fn as_json(&self) -> Result<String> {
246 Ok(serde_json::to_string(self.releases)?)
247 }
248}
249
250#[cfg(test)]
251mod test {
252 use pretty_assertions::assert_eq;
253
254 use super::*;
255 #[test]
256 fn bump_version() -> Result<()> {
257 fn build_release<'a>(version: &str, commits: &'a [&str]) -> Release<'a> {
258 Release {
259 version: None,
260 message: None,
261 extra: None,
262 commits: commits
263 .iter()
264 .map(|v| Commit::from((*v).to_string()))
265 .collect(),
266 commit_range: None,
267 commit_id: None,
268 timestamp: None,
269 previous: Some(Box::new(Release {
270 version: Some(String::from(version)),
271 ..Default::default()
272 })),
273 repository: Some(String::from("/root/repo")),
274 submodule_commits: HashMap::new(),
275 statistics: None,
276 bump_type: None,
277 #[cfg(feature = "github")]
278 github: crate::remote::RemoteReleaseMetadata {
279 contributors: vec![],
280 },
281 #[cfg(feature = "gitlab")]
282 gitlab: crate::remote::RemoteReleaseMetadata {
283 contributors: vec![],
284 },
285 #[cfg(feature = "gitea")]
286 gitea: crate::remote::RemoteReleaseMetadata {
287 contributors: vec![],
288 },
289 #[cfg(feature = "bitbucket")]
290 bitbucket: crate::remote::RemoteReleaseMetadata {
291 contributors: vec![],
292 },
293 #[cfg(feature = "azure_devops")]
294 azure_devops: crate::remote::RemoteReleaseMetadata {
295 contributors: vec![],
296 },
297 }
298 }
299
300 let test_shared = [
301 ("1.0.0", "1.1.0", vec!["feat: add xyz", "fix: fix xyz"]),
302 ("1.0.0", "1.0.1", vec!["fix: add xyz", "fix: aaaaaa"]),
303 ("1.0.0", "2.0.0", vec!["feat!: add xyz", "feat: zzz"]),
304 ("1.0.0", "2.0.0", vec!["feat!: add xyz\n", "feat: zzz\n"]),
305 ("2.0.0", "2.0.1", vec!["fix: something"]),
306 ("foo/1.0.0", "foo/1.1.0", vec![
307 "feat: add xyz",
308 "fix: fix xyz",
309 ]),
310 ("bar/1.0.0", "bar/2.0.0", vec![
311 "fix: add xyz",
312 "fix!: aaaaaa",
313 ]),
314 ("zzz-123/test/1.0.0", "zzz-123/test/1.0.1", vec![
315 "fix: aaaaaa",
316 ]),
317 ("v100.0.0", "v101.0.0", vec!["feat!: something"]),
318 ("v1.0.0-alpha.1", "v1.0.0-alpha.2", vec!["fix: minor"]),
319 ("testing/v1.0.0-beta.1", "testing/v1.0.0-beta.2", vec![
320 "feat: nice",
321 ]),
322 ("tauri-v1.5.4", "tauri-v1.6.0", vec!["feat: something"]),
323 (
324 "rocket/rocket-v4.0.0-rc.1",
325 "rocket/rocket-v4.0.0-rc.2",
326 vec!["chore!: wow"],
327 ),
328 (
329 "aaa#/@#$@9384!#%^#@#@!#!239432413-idk-9999.2200.5932-alpha.419",
330 "aaa#/@#$@9384!#%^#@#@!#!239432413-idk-9999.2200.5932-alpha.420",
331 vec!["feat: damn this is working"],
332 ),
333 ];
334
335 for (version, expected_version, commits) in test_shared.iter().chain(
336 [
337 ("0.0.1", "0.0.2", vec!["fix: fix xyz"]),
338 ("0.0.1", "0.1.0", vec!["feat: add xyz", "fix: fix xyz"]),
339 ("0.0.1", "1.0.0", vec!["feat!: add xyz", "feat: zzz"]),
340 ("0.1.0", "0.1.1", vec!["fix: fix xyz"]),
341 ("0.1.0", "0.2.0", vec!["feat: add xyz", "fix: fix xyz"]),
342 ("0.1.0", "1.0.0", vec!["feat!: add xyz", "feat: zzz"]),
343 ]
344 .iter(),
345 ) {
346 let release = build_release(version, commits);
347 let next_version = release.calculate_next_version()?.version;
348 assert_eq!(expected_version, &next_version);
349 let next_version = release
350 .calculate_next_version_with_config(&Bump::default())?
351 .version;
352 assert_eq!(expected_version, &next_version);
353 }
354
355 for (version, expected_version, commits) in test_shared.iter().chain(
356 [
357 ("0.0.1", "0.0.2", vec!["fix: fix xyz"]),
358 ("0.0.1", "0.0.2", vec!["feat: add xyz", "fix: fix xyz"]),
359 ("0.0.1", "0.0.2", vec!["feat!: add xyz", "feat: zzz"]),
360 ("0.1.0", "0.1.1", vec!["fix: fix xyz"]),
361 ("0.1.0", "0.1.1", vec!["feat: add xyz", "fix: fix xyz"]),
362 ("0.1.0", "0.2.0", vec!["feat!: add xyz", "feat: zzz"]),
363 ]
364 .iter(),
365 ) {
366 let release = build_release(version, commits);
367 let next_version = release
368 .calculate_next_version_with_config(&Bump {
369 features_always_bump_minor: Some(false),
370 breaking_always_bump_major: Some(false),
371 initial_tag: None,
372 custom_major_increment_regex: None,
373 custom_minor_increment_regex: None,
374 bump_type: None,
375 })?
376 .version;
377 assert_eq!(expected_version, &next_version);
378 }
379
380 for (version, expected_version, commits) in test_shared.iter().chain(
381 [
382 ("0.0.1", "0.0.2", vec!["fix: fix xyz"]),
383 ("0.0.1", "0.1.0", vec!["feat: add xyz", "fix: fix xyz"]),
384 ("0.0.1", "0.1.0", vec!["feat!: add xyz", "feat: zzz"]),
385 ("0.1.0", "0.1.1", vec!["fix: fix xyz"]),
386 ("0.1.0", "0.2.0", vec!["feat: add xyz", "fix: fix xyz"]),
387 ("0.1.0", "0.2.0", vec!["feat!: add xyz", "feat: zzz"]),
388 ]
389 .iter(),
390 ) {
391 let release = build_release(version, commits);
392 let next_version = release
393 .calculate_next_version_with_config(&Bump {
394 features_always_bump_minor: Some(true),
395 breaking_always_bump_major: Some(false),
396 initial_tag: None,
397 custom_major_increment_regex: None,
398 custom_minor_increment_regex: None,
399 bump_type: None,
400 })?
401 .version;
402 assert_eq!(expected_version, &next_version);
403 }
404
405 for (version, expected_version, commits) in test_shared.iter().chain(
406 [
407 ("0.0.1", "0.0.2", vec!["fix: fix xyz"]),
408 ("0.0.1", "0.0.2", vec!["feat: add xyz", "fix: fix xyz"]),
409 ("0.0.1", "1.0.0", vec!["feat!: add xyz", "feat: zzz"]),
410 ("0.1.0", "0.1.1", vec!["fix: fix xyz"]),
411 ("0.1.0", "0.1.1", vec!["feat: add xyz", "fix: fix xyz"]),
412 ("0.1.0", "1.0.0", vec!["feat!: add xyz", "feat: zzz"]),
413 ]
414 .iter(),
415 ) {
416 let release = build_release(version, commits);
417 let next_version = release
418 .calculate_next_version_with_config(&Bump {
419 features_always_bump_minor: Some(false),
420 breaking_always_bump_major: Some(true),
421 initial_tag: None,
422 custom_major_increment_regex: None,
423 custom_minor_increment_regex: None,
424 bump_type: None,
425 })?
426 .version;
427 assert_eq!(expected_version, &next_version);
428 }
429
430 let empty_release = Release {
431 previous: Some(Box::new(Release {
432 version: None,
433 ..Default::default()
434 })),
435 ..Default::default()
436 };
437 let result = empty_release.calculate_next_version()?;
438 assert_eq!("0.1.0", result.version);
439 assert_eq!(None, result.bump_type);
440 for (features_always_bump_minor, breaking_always_bump_major) in
441 [(true, true), (true, false), (false, true), (false, false)]
442 {
443 let result = empty_release.calculate_next_version_with_config(&Bump {
444 features_always_bump_minor: Some(features_always_bump_minor),
445 breaking_always_bump_major: Some(breaking_always_bump_major),
446 initial_tag: None,
447 custom_major_increment_regex: None,
448 custom_minor_increment_regex: None,
449 bump_type: None,
450 })?;
451 assert_eq!("0.1.0", result.version);
452 assert_eq!(None, result.bump_type);
453 }
454 Ok(())
455 }
456
457 #[test]
458 fn bump_version_type() -> Result<()> {
459 fn build_release<'a>(version: &str, commits: &'a [&str]) -> Release<'a> {
460 Release {
461 version: None,
462 commits: commits
463 .iter()
464 .map(|v| Commit::from((*v).to_string()))
465 .collect(),
466 previous: Some(Box::new(Release {
467 version: Some(String::from(version)),
468 ..Default::default()
469 })),
470 ..Default::default()
471 }
472 }
473
474 let release = build_release("1.0.0", &["fix: something"]);
475 let result = release.calculate_next_version()?;
476 assert_eq!(Some(BumpType::Patch), result.bump_type);
477
478 let release = build_release("1.0.0", &["feat: add xyz"]);
479 let result = release.calculate_next_version()?;
480 assert_eq!(Some(BumpType::Minor), result.bump_type);
481
482 let release = build_release("1.0.0", &["feat!: breaking change"]);
483 let result = release.calculate_next_version()?;
484 assert_eq!(Some(BumpType::Major), result.bump_type);
485
486 let release = build_release("1.0.0", &["fix: something"]);
487 let result = release.calculate_next_version_with_config(&Bump {
488 bump_type: Some(BumpType::Minor),
489 ..Default::default()
490 })?;
491 assert_eq!("1.1.0", result.version);
492 assert_eq!(Some(BumpType::Minor), result.bump_type);
493
494 let release = Release {
495 previous: Some(Box::new(Release {
496 version: None,
497 ..Default::default()
498 })),
499 ..Default::default()
500 };
501 let result = release.calculate_next_version()?;
502 assert_eq!(None, result.bump_type);
503
504 Ok(())
505 }
506
507 #[test]
508 fn with_statistics() {
509 let release = Release {
510 commits: vec![],
511 timestamp: Some(1_649_373_910),
512 previous: Some(Box::new(Release {
513 timestamp: Some(1_649_201_110),
514 ..Default::default()
515 })),
516 repository: Some(String::from("/root/repo")),
517 ..Default::default()
518 };
519
520 assert!(release.statistics.is_none());
521 let release = release.with_statistics();
522 assert!(release.statistics.is_some());
523 }
524
525 #[cfg(feature = "github")]
526 #[test]
527 fn update_github_metadata() -> Result<()> {
528 use crate::remote::github::{
529 GitHubCommit, GitHubCommitAuthor, GitHubCommitDetails, GitHubCommitDetailsAuthor,
530 GitHubPullRequest, PullRequestLabel,
531 };
532
533 let mut release = Release {
534 version: None,
535 message: None,
536 extra: None,
537 commits: vec![
538 Commit::from(String::from(
539 "1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add github integration",
540 )),
541 Commit::from(String::from(
542 "21f6aa587fcb772de13f2fde0e92697c51f84162 fix github integration",
543 )),
544 Commit::from(String::from(
545 "35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973 update metadata",
546 )),
547 Commit::from(String::from(
548 "4d3ffe4753b923f4d7807c490e650e6624a12074 do some stuff",
549 )),
550 Commit::from(String::from(
551 "5a55e92e5a62dc5bf9872ffb2566959fad98bd05 alright",
552 )),
553 Commit::from(String::from(
554 "6c34967147560ea09658776d4901709139b4ad66 should be fine",
555 )),
556 ],
557 commit_range: None,
558 commit_id: None,
559 timestamp: None,
560 previous: Some(Box::new(Release {
561 version: Some(String::from("1.0.0")),
562 ..Default::default()
563 })),
564 repository: Some(String::from("/root/repo")),
565 submodule_commits: HashMap::new(),
566 statistics: None,
567 bump_type: None,
568 github: RemoteReleaseMetadata {
569 contributors: vec![],
570 },
571 #[cfg(feature = "gitlab")]
572 gitlab: RemoteReleaseMetadata {
573 contributors: vec![],
574 },
575 #[cfg(feature = "gitea")]
576 gitea: RemoteReleaseMetadata {
577 contributors: vec![],
578 },
579 #[cfg(feature = "bitbucket")]
580 bitbucket: RemoteReleaseMetadata {
581 contributors: vec![],
582 },
583 #[cfg(feature = "azure_devops")]
584 azure_devops: RemoteReleaseMetadata {
585 contributors: vec![],
586 },
587 };
588 release.update_github_metadata(
589 vec![
590 GitHubCommit {
591 sha: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
592 author: Some(GitHubCommitAuthor {
593 login: Some(String::from("orhun")),
594 }),
595 commit: Some(GitHubCommitDetails {
596 author: GitHubCommitDetailsAuthor {
597 date: String::from("2021-07-18T15:14:39+03:00"),
598 },
599 }),
600 },
601 GitHubCommit {
602 sha: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
603 author: Some(GitHubCommitAuthor {
604 login: Some(String::from("orhun")),
605 }),
606 commit: Some(GitHubCommitDetails {
607 author: GitHubCommitDetailsAuthor {
608 date: String::from("2021-07-18T15:12:19+03:00"),
609 },
610 }),
611 },
612 GitHubCommit {
613 sha: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
614 author: Some(GitHubCommitAuthor {
615 login: Some(String::from("nuhro")),
616 }),
617 commit: Some(GitHubCommitDetails {
618 author: GitHubCommitDetailsAuthor {
619 date: String::from("2021-07-18T15:07:23+03:00"),
620 },
621 }),
622 },
623 GitHubCommit {
624 sha: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
625 author: Some(GitHubCommitAuthor {
626 login: Some(String::from("awesome_contributor")),
627 }),
628 commit: Some(GitHubCommitDetails {
629 author: GitHubCommitDetailsAuthor {
630 date: String::from("2021-07-18T15:05:10+03:00"),
631 },
632 }),
633 },
634 GitHubCommit {
635 sha: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
636 author: Some(GitHubCommitAuthor {
637 login: Some(String::from("orhun")),
638 }),
639 commit: Some(GitHubCommitDetails {
640 author: GitHubCommitDetailsAuthor {
641 date: String::from("2021-07-18T15:03:30+03:00"),
642 },
643 }),
644 },
645 GitHubCommit {
646 sha: String::from("6c34967147560ea09658776d4901709139b4ad66"),
647 author: Some(GitHubCommitAuthor {
648 login: Some(String::from("someone")),
649 }),
650 commit: Some(GitHubCommitDetails {
651 author: GitHubCommitDetailsAuthor {
652 date: String::from("2021-07-18T15:00:38+03:00"),
653 },
654 }),
655 },
656 GitHubCommit {
657 sha: String::from("0c34967147560e809658776d4901709139b4ad68"),
658 author: Some(GitHubCommitAuthor {
659 login: Some(String::from("idk")),
660 }),
661 commit: Some(GitHubCommitDetails {
662 author: GitHubCommitDetailsAuthor {
663 date: String::from("2021-07-18T15:00:38+03:00"),
664 },
665 }),
666 },
667 GitHubCommit {
668 sha: String::from("kk34967147560e809658776d4901709139b4ad68"),
669 author: None,
670 commit: None,
671 },
672 GitHubCommit {
673 sha: String::new(),
674 author: None,
675 commit: None,
676 },
677 ]
678 .into_iter()
679 .map(|v| Box::new(v) as Box<dyn RemoteCommit>)
680 .collect(),
681 vec![
682 GitHubPullRequest {
683 title: Some(String::from("1")),
684 number: 42,
685 merge_commit_sha: Some(String::from(
686 "1d244937ee6ceb8e0314a4a201ba93a7a61f2071",
687 )),
688 labels: vec![PullRequestLabel {
689 name: String::from("rust"),
690 }],
691 },
692 GitHubPullRequest {
693 title: Some(String::from("2")),
694 number: 66,
695 merge_commit_sha: Some(String::from(
696 "21f6aa587fcb772de13f2fde0e92697c51f84162",
697 )),
698 labels: vec![PullRequestLabel {
699 name: String::from("rust"),
700 }],
701 },
702 GitHubPullRequest {
703 title: Some(String::from("3")),
704 number: 53,
705 merge_commit_sha: Some(String::from(
706 "35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973",
707 )),
708 labels: vec![PullRequestLabel {
709 name: String::from("deps"),
710 }],
711 },
712 GitHubPullRequest {
713 title: Some(String::from("4")),
714 number: 1_000,
715 merge_commit_sha: Some(String::from(
716 "4d3ffe4753b923f4d7807c490e650e6624a12074",
717 )),
718 labels: vec![PullRequestLabel {
719 name: String::from("deps"),
720 }],
721 },
722 GitHubPullRequest {
723 title: Some(String::from("5")),
724 number: 999_999,
725 merge_commit_sha: Some(String::from(
726 "5a55e92e5a62dc5bf9872ffb2566959fad98bd05",
727 )),
728 labels: vec![PullRequestLabel {
729 name: String::from("github"),
730 }],
731 },
732 ]
733 .into_iter()
734 .map(|v| Box::new(v) as Box<dyn RemotePullRequest>)
735 .collect(),
736 )?;
737 #[allow(deprecated)]
738 let expected_commits = vec![
739 Commit {
740 id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
741 message: String::from("add github integration"),
742 github: RemoteContributor {
743 username: Some(String::from("orhun")),
744 pr_title: Some(String::from("1")),
745 pr_number: Some(42),
746 pr_labels: vec![String::from("rust")],
747 is_first_time: false,
748 },
749 remote: Some(RemoteContributor {
750 username: Some(String::from("orhun")),
751 pr_title: Some(String::from("1")),
752 pr_number: Some(42),
753 pr_labels: vec![String::from("rust")],
754 is_first_time: false,
755 }),
756 ..Default::default()
757 },
758 Commit {
759 id: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
760 message: String::from("fix github integration"),
761 github: RemoteContributor {
762 username: Some(String::from("orhun")),
763 pr_title: Some(String::from("2")),
764 pr_number: Some(66),
765 pr_labels: vec![String::from("rust")],
766 is_first_time: false,
767 },
768 remote: Some(RemoteContributor {
769 username: Some(String::from("orhun")),
770 pr_title: Some(String::from("2")),
771 pr_number: Some(66),
772 pr_labels: vec![String::from("rust")],
773 is_first_time: false,
774 }),
775 ..Default::default()
776 },
777 Commit {
778 id: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
779 message: String::from("update metadata"),
780 github: RemoteContributor {
781 username: Some(String::from("nuhro")),
782 pr_title: Some(String::from("3")),
783 pr_number: Some(53),
784 pr_labels: vec![String::from("deps")],
785 is_first_time: false,
786 },
787 remote: Some(RemoteContributor {
788 username: Some(String::from("nuhro")),
789 pr_title: Some(String::from("3")),
790 pr_number: Some(53),
791 pr_labels: vec![String::from("deps")],
792 is_first_time: false,
793 }),
794 ..Default::default()
795 },
796 Commit {
797 id: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
798 message: String::from("do some stuff"),
799 github: RemoteContributor {
800 username: Some(String::from("awesome_contributor")),
801 pr_title: Some(String::from("4")),
802 pr_number: Some(1_000),
803 pr_labels: vec![String::from("deps")],
804 is_first_time: false,
805 },
806 remote: Some(RemoteContributor {
807 username: Some(String::from("awesome_contributor")),
808 pr_title: Some(String::from("4")),
809 pr_number: Some(1_000),
810 pr_labels: vec![String::from("deps")],
811 is_first_time: false,
812 }),
813 ..Default::default()
814 },
815 Commit {
816 id: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
817 message: String::from("alright"),
818 github: RemoteContributor {
819 username: Some(String::from("orhun")),
820 pr_title: Some(String::from("5")),
821 pr_number: Some(999_999),
822 pr_labels: vec![String::from("github")],
823 is_first_time: false,
824 },
825 remote: Some(RemoteContributor {
826 username: Some(String::from("orhun")),
827 pr_title: Some(String::from("5")),
828 pr_number: Some(999_999),
829 pr_labels: vec![String::from("github")],
830 is_first_time: false,
831 }),
832 ..Default::default()
833 },
834 Commit {
835 id: String::from("6c34967147560ea09658776d4901709139b4ad66"),
836 message: String::from("should be fine"),
837 github: RemoteContributor {
838 username: Some(String::from("someone")),
839 pr_title: None,
840 pr_number: None,
841 pr_labels: vec![],
842 is_first_time: false,
843 },
844 remote: Some(RemoteContributor {
845 username: Some(String::from("someone")),
846 pr_title: None,
847 pr_number: None,
848 pr_labels: vec![],
849 is_first_time: false,
850 }),
851 ..Default::default()
852 },
853 ];
854 assert_eq!(expected_commits, release.commits);
855
856 release
857 .github
858 .contributors
859 .sort_by(|a, b| a.pr_number.cmp(&b.pr_number));
860
861 let expected_metadata = RemoteReleaseMetadata {
862 contributors: vec![
863 RemoteContributor {
864 username: Some(String::from("someone")),
865 pr_title: None,
866 pr_number: None,
867 pr_labels: vec![],
868 is_first_time: true,
869 },
870 RemoteContributor {
871 username: Some(String::from("orhun")),
872 pr_title: Some(String::from("1")),
873 pr_number: Some(42),
874 pr_labels: vec![String::from("rust")],
875 is_first_time: true,
876 },
877 RemoteContributor {
878 username: Some(String::from("nuhro")),
879 pr_title: Some(String::from("3")),
880 pr_number: Some(53),
881 pr_labels: vec![String::from("deps")],
882 is_first_time: true,
883 },
884 RemoteContributor {
885 username: Some(String::from("awesome_contributor")),
886 pr_title: Some(String::from("4")),
887 pr_number: Some(1_000),
888 pr_labels: vec![String::from("deps")],
889 is_first_time: true,
890 },
891 ],
892 };
893 assert_eq!(expected_metadata, release.github);
894
895 Ok(())
896 }
897
898 #[cfg(feature = "gitlab")]
899 #[test]
900 fn update_gitlab_metadata() -> Result<()> {
901 use crate::remote::gitlab::{GitLabCommit, GitLabMergeRequest, GitLabUser};
902
903 let mut release = Release {
904 version: None,
905 message: None,
906 extra: None,
907 commits: vec![
908 Commit::from(String::from(
909 "1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add github integration",
910 )),
911 Commit::from(String::from(
912 "21f6aa587fcb772de13f2fde0e92697c51f84162 fix github integration",
913 )),
914 Commit::from(String::from(
915 "35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973 update metadata",
916 )),
917 Commit::from(String::from(
918 "4d3ffe4753b923f4d7807c490e650e6624a12074 do some stuff",
919 )),
920 Commit::from(String::from(
921 "5a55e92e5a62dc5bf9872ffb2566959fad98bd05 alright",
922 )),
923 Commit::from(String::from(
924 "6c34967147560ea09658776d4901709139b4ad66 should be fine",
925 )),
926 ],
927 commit_range: None,
928 commit_id: None,
929 timestamp: None,
930 previous: Some(Box::new(Release {
931 version: Some(String::from("1.0.0")),
932 ..Default::default()
933 })),
934 repository: Some(String::from("/root/repo")),
935 submodule_commits: HashMap::new(),
936 statistics: None,
937 bump_type: None,
938 #[cfg(feature = "github")]
939 github: RemoteReleaseMetadata {
940 contributors: vec![],
941 },
942 #[cfg(feature = "gitlab")]
943 gitlab: RemoteReleaseMetadata {
944 contributors: vec![],
945 },
946 #[cfg(feature = "gitea")]
947 gitea: RemoteReleaseMetadata {
948 contributors: vec![],
949 },
950 #[cfg(feature = "bitbucket")]
951 bitbucket: RemoteReleaseMetadata {
952 contributors: vec![],
953 },
954 #[cfg(feature = "azure_devops")]
955 azure_devops: RemoteReleaseMetadata {
956 contributors: vec![],
957 },
958 };
959 release.update_gitlab_metadata(
960 vec![
961 GitLabCommit {
962 id: Some(String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071")),
963 author_name: Some(String::from("orhun")),
964 short_id: Some(String::new()),
965 title: Some(String::new()),
966 author_email: Some(String::new()),
967 authored_date: Some(String::new()),
968 committer_name: Some(String::new()),
969 committer_email: Some(String::new()),
970 committed_date: Some(String::new()),
971 created_at: Some(String::new()),
972 message: Some(String::new()),
973 parent_ids: vec![],
974 web_url: Some(String::new()),
975 },
976 GitLabCommit {
977 id: Some(String::from("21f6aa587fcb772de13f2fde0e92697c51f84162")),
978 author_name: Some(String::from("orhun")),
979 short_id: Some(String::new()),
980 title: Some(String::new()),
981 author_email: Some(String::new()),
982 authored_date: Some(String::new()),
983 committer_name: Some(String::new()),
984 committer_email: Some(String::new()),
985 committed_date: Some(String::new()),
986 created_at: Some(String::new()),
987 message: Some(String::new()),
988 parent_ids: vec![],
989 web_url: Some(String::new()),
990 },
991 GitLabCommit {
992 id: Some(String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973")),
993 author_name: Some(String::from("nuhro")),
994 short_id: Some(String::new()),
995 title: Some(String::new()),
996 author_email: Some(String::new()),
997 authored_date: Some(String::new()),
998 committer_name: Some(String::new()),
999 committer_email: Some(String::new()),
1000 committed_date: Some(String::new()),
1001 created_at: Some(String::new()),
1002 message: Some(String::new()),
1003 parent_ids: vec![],
1004 web_url: Some(String::new()),
1005 },
1006 GitLabCommit {
1007 id: Some(String::from("4d3ffe4753b923f4d7807c490e650e6624a12074")),
1008 author_name: Some(String::from("awesome_contributor")),
1009 short_id: Some(String::new()),
1010 title: Some(String::new()),
1011 author_email: Some(String::new()),
1012 authored_date: Some(String::new()),
1013 committer_name: Some(String::new()),
1014 committer_email: Some(String::new()),
1015 committed_date: Some(String::new()),
1016 created_at: Some(String::new()),
1017 message: Some(String::new()),
1018 parent_ids: vec![],
1019 web_url: Some(String::new()),
1020 },
1021 GitLabCommit {
1022 id: Some(String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05")),
1023 author_name: Some(String::from("orhun")),
1024 short_id: Some(String::new()),
1025 title: Some(String::new()),
1026 author_email: Some(String::new()),
1027 authored_date: Some(String::new()),
1028 committer_name: Some(String::new()),
1029 committer_email: Some(String::new()),
1030 committed_date: Some(String::new()),
1031 created_at: Some(String::new()),
1032 message: Some(String::new()),
1033 parent_ids: vec![],
1034 web_url: Some(String::new()),
1035 },
1036 GitLabCommit {
1037 id: Some(String::from("6c34967147560ea09658776d4901709139b4ad66")),
1038 author_name: Some(String::from("someone")),
1039 short_id: Some(String::new()),
1040 title: Some(String::new()),
1041 author_email: Some(String::new()),
1042 authored_date: Some(String::new()),
1043 committer_name: Some(String::new()),
1044 committer_email: Some(String::new()),
1045 committed_date: Some(String::new()),
1046 created_at: Some(String::new()),
1047 message: Some(String::new()),
1048 parent_ids: vec![],
1049 web_url: Some(String::new()),
1050 },
1051 GitLabCommit {
1052 id: Some(String::from("0c34967147560e809658776d4901709139b4ad68")),
1053 author_name: Some(String::from("idk")),
1054 short_id: Some(String::new()),
1055 title: Some(String::new()),
1056 author_email: Some(String::new()),
1057 authored_date: Some(String::new()),
1058 committer_name: Some(String::new()),
1059 committer_email: Some(String::new()),
1060 committed_date: Some(String::new()),
1061 created_at: Some(String::new()),
1062 message: Some(String::new()),
1063 parent_ids: vec![],
1064 web_url: Some(String::new()),
1065 },
1066 GitLabCommit {
1067 id: Some(String::from("kk34967147560e809658776d4901709139b4ad68")),
1068 author_name: Some(String::from("orhun")),
1069 short_id: Some(String::new()),
1070 title: Some(String::new()),
1071 author_email: Some(String::new()),
1072 authored_date: Some(String::new()),
1073 committer_name: Some(String::new()),
1074 committer_email: Some(String::new()),
1075 committed_date: Some(String::new()),
1076 created_at: Some(String::new()),
1077 message: Some(String::new()),
1078 parent_ids: vec![],
1079 web_url: Some(String::new()),
1080 },
1081 ]
1082 .into_iter()
1083 .map(|v| Box::new(v) as Box<dyn RemoteCommit>)
1084 .collect(),
1085 vec![Box::new(GitLabMergeRequest {
1086 title: Some(String::from("1")),
1087 merge_commit_sha: Some(String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071")),
1088 id: Some(1),
1089 iid: Some(1),
1090 project_id: Some(1),
1091 description: Some(String::new()),
1092 state: Some(String::new()),
1093 created_at: Some(String::new()),
1094 author: Some(GitLabUser {
1095 id: Some(1),
1096 name: Some(String::from("42")),
1097 username: Some(String::from("42")),
1098 state: Some(String::from("42")),
1099 avatar_url: None,
1100 web_url: Some(String::from("42")),
1101 }),
1102 sha: Some(String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071")),
1103 web_url: Some(String::new()),
1104 squash_commit_sha: None,
1105 labels: vec![String::from("rust")],
1106 })],
1107 )?;
1108 #[allow(deprecated)]
1109 let expected_commits = vec![
1110 Commit {
1111 id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
1112 message: String::from("add github integration"),
1113 gitlab: RemoteContributor {
1114 username: Some(String::from("orhun")),
1115 pr_title: Some(String::from("1")),
1116 pr_number: Some(1),
1117 pr_labels: vec![String::from("rust")],
1118 is_first_time: false,
1119 },
1120 remote: Some(RemoteContributor {
1121 username: Some(String::from("orhun")),
1122 pr_title: Some(String::from("1")),
1123 pr_number: Some(1),
1124 pr_labels: vec![String::from("rust")],
1125 is_first_time: false,
1126 }),
1127 ..Default::default()
1128 },
1129 Commit {
1130 id: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
1131 message: String::from("fix github integration"),
1132 gitlab: RemoteContributor {
1133 username: Some(String::from("orhun")),
1134 pr_title: None,
1135 pr_number: None,
1136 pr_labels: vec![],
1137 is_first_time: false,
1138 },
1139 remote: Some(RemoteContributor {
1140 username: Some(String::from("orhun")),
1141 pr_title: None,
1142 pr_number: None,
1143 pr_labels: vec![],
1144 is_first_time: false,
1145 }),
1146 ..Default::default()
1147 },
1148 Commit {
1149 id: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
1150 message: String::from("update metadata"),
1151 gitlab: RemoteContributor {
1152 username: Some(String::from("nuhro")),
1153 pr_title: None,
1154 pr_number: None,
1155 pr_labels: vec![],
1156 is_first_time: false,
1157 },
1158 remote: Some(RemoteContributor {
1159 username: Some(String::from("nuhro")),
1160 pr_title: None,
1161 pr_number: None,
1162 pr_labels: vec![],
1163 is_first_time: false,
1164 }),
1165 ..Default::default()
1166 },
1167 Commit {
1168 id: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
1169 message: String::from("do some stuff"),
1170 gitlab: RemoteContributor {
1171 username: Some(String::from("awesome_contributor")),
1172 pr_title: None,
1173 pr_number: None,
1174 pr_labels: vec![],
1175 is_first_time: false,
1176 },
1177 remote: Some(RemoteContributor {
1178 username: Some(String::from("awesome_contributor")),
1179 pr_title: None,
1180 pr_number: None,
1181 pr_labels: vec![],
1182 is_first_time: false,
1183 }),
1184 ..Default::default()
1185 },
1186 Commit {
1187 id: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
1188 message: String::from("alright"),
1189 gitlab: RemoteContributor {
1190 username: Some(String::from("orhun")),
1191 pr_title: None,
1192 pr_number: None,
1193 pr_labels: vec![],
1194 is_first_time: false,
1195 },
1196 remote: Some(RemoteContributor {
1197 username: Some(String::from("orhun")),
1198 pr_title: None,
1199 pr_number: None,
1200 pr_labels: vec![],
1201 is_first_time: false,
1202 }),
1203 ..Default::default()
1204 },
1205 Commit {
1206 id: String::from("6c34967147560ea09658776d4901709139b4ad66"),
1207 message: String::from("should be fine"),
1208 gitlab: RemoteContributor {
1209 username: Some(String::from("someone")),
1210 pr_title: None,
1211 pr_number: None,
1212 pr_labels: vec![],
1213 is_first_time: false,
1214 },
1215 remote: Some(RemoteContributor {
1216 username: Some(String::from("someone")),
1217 pr_title: None,
1218 pr_number: None,
1219 pr_labels: vec![],
1220 is_first_time: false,
1221 }),
1222 ..Default::default()
1223 },
1224 ];
1225 assert_eq!(expected_commits, release.commits);
1226
1227 release
1228 .github
1229 .contributors
1230 .sort_by(|a, b| a.pr_number.cmp(&b.pr_number));
1231
1232 let expected_metadata = RemoteReleaseMetadata {
1233 contributors: vec![
1234 RemoteContributor {
1235 username: Some(String::from("orhun")),
1236 pr_title: Some(String::from("1")),
1237 pr_number: Some(1),
1238 pr_labels: vec![String::from("rust")],
1239 is_first_time: false,
1240 },
1241 RemoteContributor {
1242 username: Some(String::from("nuhro")),
1243 pr_title: None,
1244 pr_number: None,
1245 pr_labels: vec![],
1246 is_first_time: true,
1247 },
1248 RemoteContributor {
1249 username: Some(String::from("awesome_contributor")),
1250 pr_title: None,
1251 pr_number: None,
1252 pr_labels: vec![],
1253 is_first_time: true,
1254 },
1255 RemoteContributor {
1256 username: Some(String::from("someone")),
1257 pr_title: None,
1258 pr_number: None,
1259 pr_labels: vec![],
1260 is_first_time: true,
1261 },
1262 ],
1263 };
1264 assert_eq!(expected_metadata, release.gitlab);
1265
1266 Ok(())
1267 }
1268
1269 #[cfg(feature = "gitea")]
1270 #[test]
1271 fn update_gitea_metadata() -> Result<()> {
1272 use crate::remote::gitea::{
1273 GiteaCommit, GiteaCommitAuthor, GiteaPullRequest, PullRequestLabel,
1274 };
1275
1276 let mut release = Release {
1277 version: None,
1278 message: None,
1279 extra: None,
1280 commits: vec![
1281 Commit::from(String::from(
1282 "1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add github integration",
1283 )),
1284 Commit::from(String::from(
1285 "21f6aa587fcb772de13f2fde0e92697c51f84162 fix github integration",
1286 )),
1287 Commit::from(String::from(
1288 "35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973 update metadata",
1289 )),
1290 Commit::from(String::from(
1291 "4d3ffe4753b923f4d7807c490e650e6624a12074 do some stuff",
1292 )),
1293 Commit::from(String::from(
1294 "5a55e92e5a62dc5bf9872ffb2566959fad98bd05 alright",
1295 )),
1296 Commit::from(String::from(
1297 "6c34967147560ea09658776d4901709139b4ad66 should be fine",
1298 )),
1299 ],
1300 commit_range: None,
1301 commit_id: None,
1302 timestamp: None,
1303 previous: Some(Box::new(Release {
1304 version: Some(String::from("1.0.0")),
1305 ..Default::default()
1306 })),
1307 repository: Some(String::from("/root/repo")),
1308 submodule_commits: HashMap::new(),
1309 statistics: None,
1310 bump_type: None,
1311 #[cfg(feature = "github")]
1312 github: RemoteReleaseMetadata {
1313 contributors: vec![],
1314 },
1315 #[cfg(feature = "gitlab")]
1316 gitlab: RemoteReleaseMetadata {
1317 contributors: vec![],
1318 },
1319 #[cfg(feature = "gitea")]
1320 gitea: RemoteReleaseMetadata {
1321 contributors: vec![],
1322 },
1323 #[cfg(feature = "bitbucket")]
1324 bitbucket: RemoteReleaseMetadata {
1325 contributors: vec![],
1326 },
1327 #[cfg(feature = "azure_devops")]
1328 azure_devops: RemoteReleaseMetadata {
1329 contributors: vec![],
1330 },
1331 };
1332 release.update_gitea_metadata(
1333 vec![
1334 GiteaCommit {
1335 sha: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
1336 author: Some(GiteaCommitAuthor {
1337 login: Some(String::from("orhun")),
1338 }),
1339 created: String::from("2021-07-18T15:14:39+03:00"),
1340 },
1341 GiteaCommit {
1342 sha: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
1343 author: Some(GiteaCommitAuthor {
1344 login: Some(String::from("orhun")),
1345 }),
1346 created: String::from("2021-07-18T15:12:19+03:00"),
1347 },
1348 GiteaCommit {
1349 sha: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
1350 author: Some(GiteaCommitAuthor {
1351 login: Some(String::from("nuhro")),
1352 }),
1353 created: String::from("2021-07-18T15:07:23+03:00"),
1354 },
1355 GiteaCommit {
1356 sha: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
1357 author: Some(GiteaCommitAuthor {
1358 login: Some(String::from("awesome_contributor")),
1359 }),
1360 created: String::from("2021-07-18T15:05:10+03:00"),
1361 },
1362 GiteaCommit {
1363 sha: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
1364 author: Some(GiteaCommitAuthor {
1365 login: Some(String::from("orhun")),
1366 }),
1367 created: String::from("2021-07-18T15:03:30+03:00"),
1368 },
1369 GiteaCommit {
1370 sha: String::from("6c34967147560ea09658776d4901709139b4ad66"),
1371 author: Some(GiteaCommitAuthor {
1372 login: Some(String::from("someone")),
1373 }),
1374 created: String::from("2021-07-18T15:00:38+03:00"),
1375 },
1376 GiteaCommit {
1377 sha: String::from("0c34967147560e809658776d4901709139b4ad68"),
1378 author: Some(GiteaCommitAuthor {
1379 login: Some(String::from("idk")),
1380 }),
1381 created: String::from("2021-07-18T15:00:38+03:00"),
1382 },
1383 GiteaCommit {
1384 sha: String::from("kk34967147560e809658776d4901709139b4ad68"),
1385 author: None,
1386 created: String::new(),
1387 },
1388 GiteaCommit {
1389 sha: String::new(),
1390 author: None,
1391 created: String::new(),
1392 },
1393 ]
1394 .into_iter()
1395 .map(|v| Box::new(v) as Box<dyn RemoteCommit>)
1396 .collect(),
1397 vec![
1398 GiteaPullRequest {
1399 title: Some(String::from("1")),
1400 number: 42,
1401 merge_commit_sha: Some(String::from(
1402 "1d244937ee6ceb8e0314a4a201ba93a7a61f2071",
1403 )),
1404 labels: vec![PullRequestLabel {
1405 name: String::from("rust"),
1406 }],
1407 },
1408 GiteaPullRequest {
1409 title: Some(String::from("2")),
1410 number: 66,
1411 merge_commit_sha: Some(String::from(
1412 "21f6aa587fcb772de13f2fde0e92697c51f84162",
1413 )),
1414 labels: vec![PullRequestLabel {
1415 name: String::from("rust"),
1416 }],
1417 },
1418 GiteaPullRequest {
1419 title: Some(String::from("3")),
1420 number: 53,
1421 merge_commit_sha: Some(String::from(
1422 "35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973",
1423 )),
1424 labels: vec![PullRequestLabel {
1425 name: String::from("deps"),
1426 }],
1427 },
1428 GiteaPullRequest {
1429 title: Some(String::from("4")),
1430 number: 1_000,
1431 merge_commit_sha: Some(String::from(
1432 "4d3ffe4753b923f4d7807c490e650e6624a12074",
1433 )),
1434 labels: vec![PullRequestLabel {
1435 name: String::from("deps"),
1436 }],
1437 },
1438 GiteaPullRequest {
1439 title: Some(String::from("5")),
1440 number: 999_999,
1441 merge_commit_sha: Some(String::from(
1442 "5a55e92e5a62dc5bf9872ffb2566959fad98bd05",
1443 )),
1444 labels: vec![PullRequestLabel {
1445 name: String::from("github"),
1446 }],
1447 },
1448 ]
1449 .into_iter()
1450 .map(|v| Box::new(v) as Box<dyn RemotePullRequest>)
1451 .collect(),
1452 )?;
1453 #[allow(deprecated)]
1454 let expected_commits = vec![
1455 Commit {
1456 id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
1457 message: String::from("add github integration"),
1458 gitea: RemoteContributor {
1459 username: Some(String::from("orhun")),
1460 pr_title: Some(String::from("1")),
1461 pr_number: Some(42),
1462 pr_labels: vec![String::from("rust")],
1463 is_first_time: false,
1464 },
1465 remote: Some(RemoteContributor {
1466 username: Some(String::from("orhun")),
1467 pr_title: Some(String::from("1")),
1468 pr_number: Some(42),
1469 pr_labels: vec![String::from("rust")],
1470 is_first_time: false,
1471 }),
1472 ..Default::default()
1473 },
1474 Commit {
1475 id: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
1476 message: String::from("fix github integration"),
1477 gitea: RemoteContributor {
1478 username: Some(String::from("orhun")),
1479 pr_title: Some(String::from("2")),
1480 pr_number: Some(66),
1481 pr_labels: vec![String::from("rust")],
1482 is_first_time: false,
1483 },
1484 remote: Some(RemoteContributor {
1485 username: Some(String::from("orhun")),
1486 pr_title: Some(String::from("2")),
1487 pr_number: Some(66),
1488 pr_labels: vec![String::from("rust")],
1489 is_first_time: false,
1490 }),
1491 ..Default::default()
1492 },
1493 Commit {
1494 id: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
1495 message: String::from("update metadata"),
1496 gitea: RemoteContributor {
1497 username: Some(String::from("nuhro")),
1498 pr_title: Some(String::from("3")),
1499 pr_number: Some(53),
1500 pr_labels: vec![String::from("deps")],
1501 is_first_time: false,
1502 },
1503 remote: Some(RemoteContributor {
1504 username: Some(String::from("nuhro")),
1505 pr_title: Some(String::from("3")),
1506 pr_number: Some(53),
1507 pr_labels: vec![String::from("deps")],
1508 is_first_time: false,
1509 }),
1510 ..Default::default()
1511 },
1512 Commit {
1513 id: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
1514 message: String::from("do some stuff"),
1515 gitea: RemoteContributor {
1516 username: Some(String::from("awesome_contributor")),
1517 pr_title: Some(String::from("4")),
1518 pr_number: Some(1_000),
1519 pr_labels: vec![String::from("deps")],
1520 is_first_time: false,
1521 },
1522 remote: Some(RemoteContributor {
1523 username: Some(String::from("awesome_contributor")),
1524 pr_title: Some(String::from("4")),
1525 pr_number: Some(1_000),
1526 pr_labels: vec![String::from("deps")],
1527 is_first_time: false,
1528 }),
1529 ..Default::default()
1530 },
1531 Commit {
1532 id: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
1533 message: String::from("alright"),
1534 gitea: RemoteContributor {
1535 username: Some(String::from("orhun")),
1536 pr_title: Some(String::from("5")),
1537 pr_number: Some(999_999),
1538 pr_labels: vec![String::from("github")],
1539 is_first_time: false,
1540 },
1541 remote: Some(RemoteContributor {
1542 username: Some(String::from("orhun")),
1543 pr_title: Some(String::from("5")),
1544 pr_number: Some(999_999),
1545 pr_labels: vec![String::from("github")],
1546 is_first_time: false,
1547 }),
1548 ..Default::default()
1549 },
1550 Commit {
1551 id: String::from("6c34967147560ea09658776d4901709139b4ad66"),
1552 message: String::from("should be fine"),
1553 gitea: RemoteContributor {
1554 username: Some(String::from("someone")),
1555 pr_title: None,
1556 pr_number: None,
1557 pr_labels: vec![],
1558 is_first_time: false,
1559 },
1560 remote: Some(RemoteContributor {
1561 username: Some(String::from("someone")),
1562 pr_title: None,
1563 pr_number: None,
1564 pr_labels: vec![],
1565 is_first_time: false,
1566 }),
1567 ..Default::default()
1568 },
1569 ];
1570 assert_eq!(expected_commits, release.commits);
1571
1572 release
1573 .gitea
1574 .contributors
1575 .sort_by(|a, b| a.pr_number.cmp(&b.pr_number));
1576
1577 let expected_metadata = RemoteReleaseMetadata {
1578 contributors: vec![
1579 RemoteContributor {
1580 username: Some(String::from("someone")),
1581 pr_title: None,
1582 pr_number: None,
1583 pr_labels: vec![],
1584 is_first_time: true,
1585 },
1586 RemoteContributor {
1587 username: Some(String::from("orhun")),
1588 pr_title: Some(String::from("1")),
1589 pr_number: Some(42),
1590 pr_labels: vec![String::from("rust")],
1591 is_first_time: true,
1592 },
1593 RemoteContributor {
1594 username: Some(String::from("nuhro")),
1595 pr_title: Some(String::from("3")),
1596 pr_number: Some(53),
1597 pr_labels: vec![String::from("deps")],
1598 is_first_time: true,
1599 },
1600 RemoteContributor {
1601 username: Some(String::from("awesome_contributor")),
1602 pr_title: Some(String::from("4")),
1603 pr_number: Some(1_000),
1604 pr_labels: vec![String::from("deps")],
1605 is_first_time: true,
1606 },
1607 ],
1608 };
1609 assert_eq!(expected_metadata, release.gitea);
1610
1611 Ok(())
1612 }
1613
1614 #[cfg(feature = "bitbucket")]
1615 #[test]
1616 fn update_bitbucket_metadata() -> Result<()> {
1617 use crate::remote::bitbucket::{
1618 BitbucketCommit, BitbucketCommitAuthor, BitbucketPullRequest,
1619 BitbucketPullRequestMergeCommit,
1620 };
1621
1622 let mut release = Release {
1623 version: None,
1624 message: None,
1625 extra: None,
1626 commits: vec![
1627 Commit::from(String::from(
1628 "1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add bitbucket integration",
1629 )),
1630 Commit::from(String::from(
1631 "21f6aa587fcb772de13f2fde0e92697c51f84162 fix bitbucket integration",
1632 )),
1633 Commit::from(String::from(
1634 "35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973 update metadata",
1635 )),
1636 Commit::from(String::from(
1637 "4d3ffe4753b923f4d7807c490e650e6624a12074 do some stuff",
1638 )),
1639 Commit::from(String::from(
1640 "5a55e92e5a62dc5bf9872ffb2566959fad98bd05 alright",
1641 )),
1642 Commit::from(String::from(
1643 "6c34967147560ea09658776d4901709139b4ad66 should be fine",
1644 )),
1645 ],
1646 commit_range: None,
1647 commit_id: None,
1648 timestamp: None,
1649 previous: Some(Box::new(Release {
1650 version: Some(String::from("1.0.0")),
1651 ..Default::default()
1652 })),
1653 repository: Some(String::from("/root/repo")),
1654 submodule_commits: HashMap::new(),
1655 statistics: None,
1656 bump_type: None,
1657 #[cfg(feature = "github")]
1658 github: RemoteReleaseMetadata {
1659 contributors: vec![],
1660 },
1661 #[cfg(feature = "gitlab")]
1662 gitlab: RemoteReleaseMetadata {
1663 contributors: vec![],
1664 },
1665 #[cfg(feature = "gitea")]
1666 gitea: RemoteReleaseMetadata {
1667 contributors: vec![],
1668 },
1669 #[cfg(feature = "bitbucket")]
1670 bitbucket: RemoteReleaseMetadata {
1671 contributors: vec![],
1672 },
1673 #[cfg(feature = "azure_devops")]
1674 azure_devops: RemoteReleaseMetadata {
1675 contributors: vec![],
1676 },
1677 };
1678 release.update_bitbucket_metadata(
1679 vec![
1680 BitbucketCommit {
1681 hash: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
1682 author: Some(BitbucketCommitAuthor {
1683 login: Some(String::from("orhun")),
1684 }),
1685 date: String::from("2021-07-18T15:14:39+03:00"),
1686 },
1687 BitbucketCommit {
1688 hash: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
1689 author: Some(BitbucketCommitAuthor {
1690 login: Some(String::from("orhun")),
1691 }),
1692 date: String::from("2021-07-18T15:12:19+03:00"),
1693 },
1694 BitbucketCommit {
1695 hash: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
1696 author: Some(BitbucketCommitAuthor {
1697 login: Some(String::from("nuhro")),
1698 }),
1699 date: String::from("2021-07-18T15:07:23+03:00"),
1700 },
1701 BitbucketCommit {
1702 hash: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
1703 author: Some(BitbucketCommitAuthor {
1704 login: Some(String::from("awesome_contributor")),
1705 }),
1706 date: String::from("2021-07-18T15:05:10+03:00"),
1707 },
1708 BitbucketCommit {
1709 hash: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
1710 author: Some(BitbucketCommitAuthor {
1711 login: Some(String::from("orhun")),
1712 }),
1713 date: String::from("2021-07-18T15:03:30+03:00"),
1714 },
1715 BitbucketCommit {
1716 hash: String::from("6c34967147560ea09658776d4901709139b4ad66"),
1717 author: Some(BitbucketCommitAuthor {
1718 login: Some(String::from("someone")),
1719 }),
1720 date: String::from("2021-07-18T15:00:38+03:00"),
1721 },
1722 BitbucketCommit {
1723 hash: String::from("0c34967147560e809658776d4901709139b4ad68"),
1724 author: Some(BitbucketCommitAuthor {
1725 login: Some(String::from("idk")),
1726 }),
1727 date: String::from("2021-07-18T15:00:01+03:00"),
1728 },
1729 BitbucketCommit {
1730 hash: String::from("kk34967147560e809658776d4901709139b4ad68"),
1731 author: Some(BitbucketCommitAuthor {
1732 login: Some(String::from("orhun")),
1733 }),
1734 date: String::from("2021-07-14T21:25:24+03:00"),
1735 },
1736 ]
1737 .into_iter()
1738 .map(|v| Box::new(v) as Box<dyn RemoteCommit>)
1739 .collect(),
1740 vec![Box::new(BitbucketPullRequest {
1741 id: 1,
1742 title: Some(String::from("1")),
1743 author: BitbucketCommitAuthor {
1744 login: Some(String::from("42")),
1745 },
1746 merge_commit: BitbucketPullRequestMergeCommit {
1747 hash: String::from("1d244937ee6c"),
1749 },
1750 })],
1751 )?;
1752 #[allow(deprecated)]
1753 let expected_commits = vec![
1754 Commit {
1755 id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
1756 message: String::from("add bitbucket integration"),
1757 bitbucket: RemoteContributor {
1758 username: Some(String::from("orhun")),
1759 pr_title: Some(String::from("1")),
1760 pr_number: Some(1),
1761 pr_labels: vec![],
1762 is_first_time: false,
1763 },
1764 remote: Some(RemoteContributor {
1765 username: Some(String::from("orhun")),
1766 pr_title: Some(String::from("1")),
1767 pr_number: Some(1),
1768 pr_labels: vec![],
1769 is_first_time: false,
1770 }),
1771 ..Default::default()
1772 },
1773 Commit {
1774 id: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
1775 message: String::from("fix bitbucket integration"),
1776 bitbucket: RemoteContributor {
1777 username: Some(String::from("orhun")),
1778 pr_title: None,
1779 pr_number: None,
1780 pr_labels: vec![],
1781 is_first_time: false,
1782 },
1783 remote: Some(RemoteContributor {
1784 username: Some(String::from("orhun")),
1785 pr_title: None,
1786 pr_number: None,
1787 pr_labels: vec![],
1788 is_first_time: false,
1789 }),
1790 ..Default::default()
1791 },
1792 Commit {
1793 id: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
1794 message: String::from("update metadata"),
1795 bitbucket: RemoteContributor {
1796 username: Some(String::from("nuhro")),
1797 pr_title: None,
1798 pr_number: None,
1799 pr_labels: vec![],
1800 is_first_time: false,
1801 },
1802 remote: Some(RemoteContributor {
1803 username: Some(String::from("nuhro")),
1804 pr_title: None,
1805 pr_number: None,
1806 pr_labels: vec![],
1807 is_first_time: false,
1808 }),
1809 ..Default::default()
1810 },
1811 Commit {
1812 id: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
1813 message: String::from("do some stuff"),
1814 bitbucket: RemoteContributor {
1815 username: Some(String::from("awesome_contributor")),
1816 pr_title: None,
1817 pr_number: None,
1818 pr_labels: vec![],
1819 is_first_time: false,
1820 },
1821 remote: Some(RemoteContributor {
1822 username: Some(String::from("awesome_contributor")),
1823 pr_title: None,
1824 pr_number: None,
1825 pr_labels: vec![],
1826 is_first_time: false,
1827 }),
1828 ..Default::default()
1829 },
1830 Commit {
1831 id: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
1832 message: String::from("alright"),
1833 bitbucket: RemoteContributor {
1834 username: Some(String::from("orhun")),
1835 pr_title: None,
1836 pr_number: None,
1837 pr_labels: vec![],
1838 is_first_time: false,
1839 },
1840 remote: Some(RemoteContributor {
1841 username: Some(String::from("orhun")),
1842 pr_title: None,
1843 pr_number: None,
1844 pr_labels: vec![],
1845 is_first_time: false,
1846 }),
1847 ..Default::default()
1848 },
1849 Commit {
1850 id: String::from("6c34967147560ea09658776d4901709139b4ad66"),
1851 message: String::from("should be fine"),
1852 bitbucket: RemoteContributor {
1853 username: Some(String::from("someone")),
1854 pr_title: None,
1855 pr_number: None,
1856 pr_labels: vec![],
1857 is_first_time: false,
1858 },
1859 remote: Some(RemoteContributor {
1860 username: Some(String::from("someone")),
1861 pr_title: None,
1862 pr_number: None,
1863 pr_labels: vec![],
1864 is_first_time: false,
1865 }),
1866 ..Default::default()
1867 },
1868 ];
1869 assert_eq!(expected_commits, release.commits);
1870
1871 release
1872 .bitbucket
1873 .contributors
1874 .sort_by(|a, b| a.pr_number.cmp(&b.pr_number));
1875
1876 let expected_metadata = RemoteReleaseMetadata {
1877 contributors: vec![
1878 RemoteContributor {
1879 username: Some(String::from("nuhro")),
1880 pr_title: None,
1881 pr_number: None,
1882 pr_labels: vec![],
1883 is_first_time: true,
1884 },
1885 RemoteContributor {
1886 username: Some(String::from("awesome_contributor")),
1887 pr_title: None,
1888 pr_number: None,
1889 pr_labels: vec![],
1890 is_first_time: true,
1891 },
1892 RemoteContributor {
1893 username: Some(String::from("someone")),
1894 pr_title: None,
1895 pr_number: None,
1896 pr_labels: vec![],
1897 is_first_time: true,
1898 },
1899 RemoteContributor {
1900 username: Some(String::from("orhun")),
1901 pr_title: Some(String::from("1")),
1902 pr_number: Some(1),
1903 pr_labels: vec![],
1904 is_first_time: false,
1905 },
1906 ],
1907 };
1908 assert_eq!(expected_metadata, release.bitbucket);
1909
1910 Ok(())
1911 }
1912
1913 #[cfg(feature = "azure_devops")]
1914 #[test]
1915 fn update_azure_devops_metadata() -> Result<()> {
1916 use crate::remote::azure_devops::{
1917 AzureDevOpsCommit, AzureDevOpsCommitAuthor, AzureDevOpsCommitRef,
1918 AzureDevOpsPullRequest,
1919 };
1920
1921 let mut release = Release {
1922 version: None,
1923 message: None,
1924 extra: None,
1925 commits: vec![
1926 Commit::from(String::from(
1927 "1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add azure devops integration",
1928 )),
1929 Commit::from(String::from(
1930 "21f6aa587fcb772de13f2fde0e92697c51f84162 fix azure devops integration",
1931 )),
1932 Commit::from(String::from(
1933 "35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973 update metadata",
1934 )),
1935 Commit::from(String::from(
1936 "4d3ffe4753b923f4d7807c490e650e6624a12074 do some stuff",
1937 )),
1938 Commit::from(String::from(
1939 "5a55e92e5a62dc5bf9872ffb2566959fad98bd05 alright",
1940 )),
1941 Commit::from(String::from(
1942 "6c34967147560ea09658776d4901709139b4ad66 should be fine",
1943 )),
1944 ],
1945 commit_range: None,
1946 commit_id: None,
1947 timestamp: None,
1948 previous: Some(Box::new(Release {
1949 version: Some(String::from("1.0.0")),
1950 ..Default::default()
1951 })),
1952 repository: Some(String::from("/root/repo")),
1953 submodule_commits: HashMap::new(),
1954 statistics: None,
1955 bump_type: None,
1956 #[cfg(feature = "github")]
1957 github: RemoteReleaseMetadata {
1958 contributors: vec![],
1959 },
1960 #[cfg(feature = "gitlab")]
1961 gitlab: RemoteReleaseMetadata {
1962 contributors: vec![],
1963 },
1964 #[cfg(feature = "gitea")]
1965 gitea: RemoteReleaseMetadata {
1966 contributors: vec![],
1967 },
1968 #[cfg(feature = "bitbucket")]
1969 bitbucket: RemoteReleaseMetadata {
1970 contributors: vec![],
1971 },
1972 #[cfg(feature = "azure_devops")]
1973 azure_devops: RemoteReleaseMetadata {
1974 contributors: vec![],
1975 },
1976 };
1977 release.update_azure_devops_metadata(
1978 vec![
1979 AzureDevOpsCommit {
1980 commit_id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
1981 author: Some(AzureDevOpsCommitAuthor {
1982 name: Some(String::from("orhun")),
1983 email: Some(String::from("orhun@example.com")),
1984 date: Some(String::from("2021-07-18T15:14:39+03:00")),
1985 }),
1986 committer: None,
1987 },
1988 AzureDevOpsCommit {
1989 commit_id: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
1990 author: Some(AzureDevOpsCommitAuthor {
1991 name: Some(String::from("orhun")),
1992 email: Some(String::from("orhun@example.com")),
1993 date: Some(String::from("2021-07-18T15:12:19+03:00")),
1994 }),
1995 committer: None,
1996 },
1997 AzureDevOpsCommit {
1998 commit_id: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
1999 author: Some(AzureDevOpsCommitAuthor {
2000 name: Some(String::from("nuhro")),
2001 email: Some(String::from("nuhro@example.com")),
2002 date: Some(String::from("2021-07-18T15:07:23+03:00")),
2003 }),
2004 committer: None,
2005 },
2006 AzureDevOpsCommit {
2007 commit_id: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
2008 author: Some(AzureDevOpsCommitAuthor {
2009 name: Some(String::from("awesome_contributor")),
2010 email: Some(String::from("awesome@example.com")),
2011 date: Some(String::from("2021-07-18T15:05:10+03:00")),
2012 }),
2013 committer: None,
2014 },
2015 AzureDevOpsCommit {
2016 commit_id: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
2017 author: Some(AzureDevOpsCommitAuthor {
2018 name: Some(String::from("orhun")),
2019 email: Some(String::from("orhun@example.com")),
2020 date: Some(String::from("2021-07-18T15:03:30+03:00")),
2021 }),
2022 committer: None,
2023 },
2024 AzureDevOpsCommit {
2025 commit_id: String::from("6c34967147560ea09658776d4901709139b4ad66"),
2026 author: Some(AzureDevOpsCommitAuthor {
2027 name: Some(String::from("someone")),
2028 email: Some(String::from("someone@example.com")),
2029 date: Some(String::from("2021-07-18T15:00:38+03:00")),
2030 }),
2031 committer: None,
2032 },
2033 AzureDevOpsCommit {
2034 commit_id: String::from("0c34967147560e809658776d4901709139b4ad68"),
2035 author: Some(AzureDevOpsCommitAuthor {
2036 name: Some(String::from("idk")),
2037 email: Some(String::from("idk@example.com")),
2038 date: Some(String::from("2021-07-18T15:00:01+03:00")),
2039 }),
2040 committer: None,
2041 },
2042 AzureDevOpsCommit {
2043 commit_id: String::from("kk34967147560e809658776d4901709139b4ad68"),
2044 author: Some(AzureDevOpsCommitAuthor {
2045 name: Some(String::from("orhun")),
2046 email: Some(String::from("orhun@example.com")),
2047 date: Some(String::from("2021-07-14T21:25:24+03:00")),
2048 }),
2049 committer: None,
2050 },
2051 ]
2052 .into_iter()
2053 .map(|v| Box::new(v) as Box<dyn RemoteCommit>)
2054 .collect(),
2055 vec![Box::new(AzureDevOpsPullRequest {
2056 pull_request_id: 42,
2057 title: Some(String::from("1")),
2058 status: String::from("completed"),
2059 created_by: None,
2060 last_merge_commit: Some(AzureDevOpsCommitRef {
2061 commit_id: Some(String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071")),
2062 }),
2063 labels: vec![],
2064 })],
2065 )?;
2066 #[allow(deprecated)]
2067 let expected_commits = vec![
2068 Commit {
2069 id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
2070 message: String::from("add azure devops integration"),
2071 azure_devops: RemoteContributor {
2072 username: Some(String::from("orhun")),
2073 pr_title: Some(String::from("1")),
2074 pr_number: Some(42),
2075 pr_labels: vec![],
2076 is_first_time: false,
2077 },
2078 remote: Some(RemoteContributor {
2079 username: Some(String::from("orhun")),
2080 pr_title: Some(String::from("1")),
2081 pr_number: Some(42),
2082 pr_labels: vec![],
2083 is_first_time: false,
2084 }),
2085 ..Default::default()
2086 },
2087 Commit {
2088 id: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
2089 message: String::from("fix azure devops integration"),
2090 azure_devops: RemoteContributor {
2091 username: Some(String::from("orhun")),
2092 pr_title: None,
2093 pr_number: None,
2094 pr_labels: vec![],
2095 is_first_time: false,
2096 },
2097 remote: Some(RemoteContributor {
2098 username: Some(String::from("orhun")),
2099 pr_title: None,
2100 pr_number: None,
2101 pr_labels: vec![],
2102 is_first_time: false,
2103 }),
2104 ..Default::default()
2105 },
2106 Commit {
2107 id: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
2108 message: String::from("update metadata"),
2109 azure_devops: RemoteContributor {
2110 username: Some(String::from("nuhro")),
2111 pr_title: None,
2112 pr_number: None,
2113 pr_labels: vec![],
2114 is_first_time: false,
2115 },
2116 remote: Some(RemoteContributor {
2117 username: Some(String::from("nuhro")),
2118 pr_title: None,
2119 pr_number: None,
2120 pr_labels: vec![],
2121 is_first_time: false,
2122 }),
2123 ..Default::default()
2124 },
2125 Commit {
2126 id: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
2127 message: String::from("do some stuff"),
2128 azure_devops: RemoteContributor {
2129 username: Some(String::from("awesome_contributor")),
2130 pr_title: None,
2131 pr_number: None,
2132 pr_labels: vec![],
2133 is_first_time: false,
2134 },
2135 remote: Some(RemoteContributor {
2136 username: Some(String::from("awesome_contributor")),
2137 pr_title: None,
2138 pr_number: None,
2139 pr_labels: vec![],
2140 is_first_time: false,
2141 }),
2142 ..Default::default()
2143 },
2144 Commit {
2145 id: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
2146 message: String::from("alright"),
2147 azure_devops: RemoteContributor {
2148 username: Some(String::from("orhun")),
2149 pr_title: None,
2150 pr_number: None,
2151 pr_labels: vec![],
2152 is_first_time: false,
2153 },
2154 remote: Some(RemoteContributor {
2155 username: Some(String::from("orhun")),
2156 pr_title: None,
2157 pr_number: None,
2158 pr_labels: vec![],
2159 is_first_time: false,
2160 }),
2161 ..Default::default()
2162 },
2163 Commit {
2164 id: String::from("6c34967147560ea09658776d4901709139b4ad66"),
2165 message: String::from("should be fine"),
2166 azure_devops: RemoteContributor {
2167 username: Some(String::from("someone")),
2168 pr_title: None,
2169 pr_number: None,
2170 pr_labels: vec![],
2171 is_first_time: false,
2172 },
2173 remote: Some(RemoteContributor {
2174 username: Some(String::from("someone")),
2175 pr_title: None,
2176 pr_number: None,
2177 pr_labels: vec![],
2178 is_first_time: false,
2179 }),
2180 ..Default::default()
2181 },
2182 ];
2183 assert_eq!(expected_commits, release.commits);
2184
2185 release
2186 .azure_devops
2187 .contributors
2188 .sort_by(|a, b| a.pr_number.cmp(&b.pr_number));
2189
2190 let expected_metadata = RemoteReleaseMetadata {
2191 contributors: vec![
2192 RemoteContributor {
2193 username: Some(String::from("nuhro")),
2194 pr_title: None,
2195 pr_number: None,
2196 pr_labels: vec![],
2197 is_first_time: true,
2198 },
2199 RemoteContributor {
2200 username: Some(String::from("awesome_contributor")),
2201 pr_title: None,
2202 pr_number: None,
2203 pr_labels: vec![],
2204 is_first_time: true,
2205 },
2206 RemoteContributor {
2207 username: Some(String::from("someone")),
2208 pr_title: None,
2209 pr_number: None,
2210 pr_labels: vec![],
2211 is_first_time: true,
2212 },
2213 RemoteContributor {
2214 username: Some(String::from("orhun")),
2215 pr_title: Some(String::from("1")),
2216 pr_number: Some(42),
2217 pr_labels: vec![],
2218 is_first_time: false,
2219 },
2220 ],
2221 };
2222 assert_eq!(expected_metadata, release.azure_devops);
2223
2224 Ok(())
2225 }
2226}