Skip to content

Commit

Permalink
feat(template): support using PR labels in the GitHub template (#467)
Browse files Browse the repository at this point in the history
  • Loading branch information
orhun committed Jan 28, 2024
1 parent fe9a74e commit 30d15bb
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 112 deletions.
20 changes: 13 additions & 7 deletions git-cliff-core/src/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ pub struct GitHubCommitAuthor {
pub login: Option<String>,
}

/// Label of the pull request.
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PullRequestLabel {
/// Name of the label.
pub name: String,
}

/// Representation of a single pull request.
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GitHubPullRequest {
Expand All @@ -102,6 +110,8 @@ pub struct GitHubPullRequest {
pub title: Option<String>,
/// SHA of the merge commit.
pub merge_commit_sha: Option<String>,
/// Labels of the pull request.
pub labels: Vec<PullRequestLabel>,
}

impl GitHubEntry for GitHubPullRequest {
Expand All @@ -126,24 +136,20 @@ pub struct GitHubReleaseMetadata {
}

/// Representation of a GitHub contributor.
#[derive(Debug, Default, Clone, Eq, Deserialize, Serialize)]
#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub struct GitHubContributor {
/// Username.
pub username: Option<String>,
/// Title of the pull request.
pub pr_title: Option<String>,
/// The pull request that the user created.
pub pr_number: Option<i64>,
/// Labels of the pull request.
pub pr_labels: Vec<String>,
/// Whether if the user contributed for the first time.
pub is_first_time: bool,
}

impl PartialEq for GitHubContributor {
fn eq(&self, other: &Self) -> bool {
self.username == other.username
}
}

impl Hash for GitHubContributor {
fn hash<H: Hasher>(&self, state: &mut H) {
self.username.hash(state);
Expand Down
240 changes: 135 additions & 105 deletions git-cliff-core/src/release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl<'a> Release<'a> {
mut github_commits: Vec<GitHubCommit>,
github_pull_requests: Vec<GitHubPullRequest>,
) -> Result<()> {
let mut contributors = std::collections::HashSet::new();
let mut contributors: Vec<GitHubContributor> = Vec::new();
// retain the commits that are not a part of this release for later on
// checking the first contributors.
github_commits.retain(|v| {
Expand All @@ -63,12 +63,21 @@ impl<'a> Release<'a> {
commit.github.username = v.author.clone().and_then(|v| v.login);
commit.github.pr_number = pull_request.map(|v| v.number);
commit.github.pr_title = pull_request.and_then(|v| v.title.clone());
contributors.insert(GitHubContributor {
username: v.author.clone().and_then(|v| v.login),
pr_title: commit.github.pr_title.clone(),
pr_number: commit.github.pr_number,
is_first_time: false,
});
commit.github.pr_labels = pull_request
.map(|v| v.labels.iter().map(|v| v.name.clone()).collect())
.unwrap_or_default();
if !contributors
.iter()
.any(|v| commit.github.username == v.username)
{
contributors.push(GitHubContributor {
username: commit.github.username.clone(),
pr_title: commit.github.pr_title.clone(),
pr_number: commit.github.pr_number,
pr_labels: commit.github.pr_labels.clone(),
is_first_time: false,
});
}
false
} else {
true
Expand Down Expand Up @@ -230,6 +239,7 @@ mod test {
#[test]
fn update_github_metadata() -> Result<()> {
use crate::github::GitHubCommitAuthor;
use crate::github::PullRequestLabel;

let mut release = Release {
version: None,
Expand Down Expand Up @@ -325,146 +335,166 @@ mod test {
merge_commit_sha: Some(String::from(
"1d244937ee6ceb8e0314a4a201ba93a7a61f2071",
)),
labels: vec![PullRequestLabel {
name: String::from("rust"),
}],
},
GitHubPullRequest {
title: Some(String::from("2")),
number: 66,
merge_commit_sha: Some(String::from(
"21f6aa587fcb772de13f2fde0e92697c51f84162",
)),
labels: vec![PullRequestLabel {
name: String::from("rust"),
}],
},
GitHubPullRequest {
title: Some(String::from("3")),
number: 53,
merge_commit_sha: Some(String::from(
"35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973",
)),
labels: vec![PullRequestLabel {
name: String::from("deps"),
}],
},
GitHubPullRequest {
title: Some(String::from("4")),
number: 1000,
merge_commit_sha: Some(String::from(
"4d3ffe4753b923f4d7807c490e650e6624a12074",
)),
labels: vec![PullRequestLabel {
name: String::from("deps"),
}],
},
GitHubPullRequest {
title: Some(String::from("5")),
number: 999999,
merge_commit_sha: Some(String::from(
"5a55e92e5a62dc5bf9872ffb2566959fad98bd05",
)),
labels: vec![PullRequestLabel {
name: String::from("github"),
}],
},
],
)?;

assert_eq!(
vec![
Commit {
id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
message: String::from("add github integration"),
github: GitHubContributor {
username: Some(String::from("orhun")),
pr_title: Some(String::from("1")),
pr_number: Some(42),
is_first_time: false,
},
..Default::default()
let expected_commits = vec![
Commit {
id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
message: String::from("add github integration"),
github: GitHubContributor {
username: Some(String::from("orhun")),
pr_title: Some(String::from("1")),
pr_number: Some(42),
pr_labels: vec![String::from("rust")],
is_first_time: false,
},
Commit {
id: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
message: String::from("fix github integration"),
github: GitHubContributor {
username: Some(String::from("orhun")),
pr_title: Some(String::from("2")),
pr_number: Some(66),
is_first_time: false,
},
..Default::default()
..Default::default()
},
Commit {
id: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
message: String::from("fix github integration"),
github: GitHubContributor {
username: Some(String::from("orhun")),
pr_title: Some(String::from("2")),
pr_number: Some(66),
pr_labels: vec![String::from("rust")],
is_first_time: false,
},
Commit {
id: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
message: String::from("update metadata"),
github: GitHubContributor {
username: Some(String::from("nuhro")),
pr_title: Some(String::from("3")),
pr_number: Some(53),
is_first_time: false,
},
..Default::default()
..Default::default()
},
Commit {
id: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
message: String::from("update metadata"),
github: GitHubContributor {
username: Some(String::from("nuhro")),
pr_title: Some(String::from("3")),
pr_number: Some(53),
pr_labels: vec![String::from("deps")],
is_first_time: false,
},
Commit {
id: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
message: String::from("do some stuff"),
github: GitHubContributor {
username: Some(String::from("awesome_contributor")),
pr_title: Some(String::from("4")),
pr_number: Some(1000),
is_first_time: false,
},
..Default::default()
..Default::default()
},
Commit {
id: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
message: String::from("do some stuff"),
github: GitHubContributor {
username: Some(String::from("awesome_contributor")),
pr_title: Some(String::from("4")),
pr_number: Some(1000),
pr_labels: vec![String::from("deps")],
is_first_time: false,
},
Commit {
id: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
message: String::from("alright"),
github: GitHubContributor {
username: Some(String::from("orhun")),
pr_title: Some(String::from("5")),
pr_number: Some(999999),
is_first_time: false,
},
..Default::default()
..Default::default()
},
Commit {
id: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
message: String::from("alright"),
github: GitHubContributor {
username: Some(String::from("orhun")),
pr_title: Some(String::from("5")),
pr_number: Some(999999),
pr_labels: vec![String::from("github")],
is_first_time: false,
},
Commit {
id: String::from("6c34967147560ea09658776d4901709139b4ad66"),
message: String::from("should be fine"),
github: GitHubContributor {
username: Some(String::from("someone")),
pr_title: Some(String::from("6")),
pr_number: None,
is_first_time: false,
},
..Default::default()
}
],
release.commits
);
..Default::default()
},
Commit {
id: String::from("6c34967147560ea09658776d4901709139b4ad66"),
message: String::from("should be fine"),
github: GitHubContributor {
username: Some(String::from("someone")),
pr_title: None,
pr_number: None,
pr_labels: vec![],
is_first_time: false,
},
..Default::default()
},
];
assert_eq!(expected_commits, release.commits);

release
.github
.contributors
.sort_by(|a, b| a.pr_number.cmp(&b.pr_number));

assert_eq!(
GitHubReleaseMetadata {
contributors: vec![
GitHubContributor {
username: Some(String::from("someone")),
pr_title: Some(String::from("6")),
pr_number: None,
is_first_time: true,
},
GitHubContributor {
username: Some(String::from("orhun")),
pr_title: Some(String::from("5")),
pr_number: Some(42),
is_first_time: true,
},
GitHubContributor {
username: Some(String::from("nuhro")),
pr_title: Some(String::from("3")),
pr_number: Some(53),
is_first_time: true,
},
GitHubContributor {
username: Some(String::from("awesome_contributor")),
pr_title: Some(String::from("4")),
pr_number: Some(1000),
is_first_time: true,
},
],
},
release.github
);
let expected_metadata = GitHubReleaseMetadata {
contributors: vec![
GitHubContributor {
username: Some(String::from("someone")),
pr_title: None,
pr_number: None,
pr_labels: vec![],
is_first_time: true,
},
GitHubContributor {
username: Some(String::from("orhun")),
pr_title: Some(String::from("1")),
pr_number: Some(42),
pr_labels: vec![String::from("rust")],
is_first_time: true,
},
GitHubContributor {
username: Some(String::from("nuhro")),
pr_title: Some(String::from("3")),
pr_number: Some(53),
pr_labels: vec![String::from("deps")],
is_first_time: true,
},
GitHubContributor {
username: Some(String::from("awesome_contributor")),
pr_title: Some(String::from("4")),
pr_number: Some(1000),
pr_labels: vec![String::from("deps")],
is_first_time: true,
},
],
};
assert_eq!(expected_metadata, release.github);

Ok(())
}
Expand Down
4 changes: 4 additions & 0 deletions website/docs/integration/github.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
sidebar_position: 1
---

# GitHub Integration 🆕

:::warning
Expand Down Expand Up @@ -105,6 +106,7 @@ For each commit, GitHub related values are added as a nested object (named `gith
"username": "orhun",
"pr_title": "some things have changed",
"pr_number": 420,
"pr_labels": ["rust"],
"is_first_time": false
}
}
Expand Down Expand Up @@ -144,12 +146,14 @@ For each release, following contributors data is added to the [template context]
"username": "orhun",
"pr_title": "some things have changed",
"pr_number": 420,
"pr_labels": ["rust"],
"is_first_time": true
},
{
"username": "cliffjumper",
"pr_title": "I love jumping",
"pr_number": 999,
"pr_labels": ["rust"],
"is_first_time": true
}
]
Expand Down

0 comments on commit 30d15bb

Please sign in to comment.