Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bitbucket): add Bitbucket support #663

Merged
merged 2 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/integration.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Integration ⚙️
description: Report a bug or request a feature about GitHub/GitLab integration
description: Report a bug or request a feature about an integration (e.g GitHub/GitLab/Bitbucket)
labels: ["integration"]
assignees:
- orhun
Expand All @@ -8,7 +8,7 @@ body:
attributes:
value: |
Thanks for taking the time to fill out this bug report!
Please see https://git-cliff.org/docs/category/integration for more information about GitHub/GitLab integration.
Please see https://git-cliff.org/docs/category/integration for more information about integrations.
- type: checkboxes
id: new-bug
attributes:
Expand Down
46 changes: 46 additions & 0 deletions .github/fixtures/test-bitbucket-integration/cliff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[remote.bitbucket]
owner = "orhunp"
repo = "git-cliff-readme-example"

[changelog]
# template for the changelog body
# https://keats.github.io/tera/docs/#introduction
body = """
## What's Changed
{%- if version %} in {{ version }}{%- endif -%}
{% for commit in commits %}
* {{ commit.message | split(pat="\n") | first | trim }}\
{% if commit.bitbucket.username %} by @{{ commit.bitbucket.username }}{%- endif -%}
{% if commit.bitbucket.pr_number %} in #{{ commit.bitbucket.pr_number }}{%- endif %}
{%- endfor -%}

{% if bitbucket.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
{% raw %}\n{% endraw -%}
## New Contributors
{%- endif %}\
{% for contributor in bitbucket.contributors | filter(attribute="is_first_time", value=true) %}
* @{{ contributor.username }} made their first contribution
{%- if contributor.pr_number %} in \
[#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
{%- endif %}
{%- endfor -%}
{% raw %}\n\n{% endraw -%}
"""
# remove the leading and trailing whitespace from the template
trim = true
# changelog footer
footer = """
<!-- generated by -cliff -->
"""

[git]
# parse the commits based on https://www.conventionalcommits.org
conventional_commits = false
# filter out the commits that are not conventional
filter_unconventional = true
# process each line of a commit as an individual commit
split_commits = false
# regex for preprocessing the commit messages
commit_preprocessors = [{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" }]
# protect breaking changes from being skipped due to matching a skipping commit_parser
protect_breaking_commits = false
6 changes: 6 additions & 0 deletions .github/fixtures/test-bitbucket-integration/commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -e

git remote add origin https://bitbucket.org/orhunp/git-cliff-readme-example
git pull origin master
git fetch --tags
16 changes: 16 additions & 0 deletions .github/fixtures/test-bitbucket-integration/expected.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## What's Changed
* feat(config): support multiple file formats by @orhun <orhun@archlinux.org>
* feat(cache): use cache while fetching pages by @orhun <orhun@archlinux.org>

## What's Changed in v1.0.1
* refactor(parser): expose string functions by @orhun <orhun@archlinux.org>
* chore(release): add release script by @orhun <orhun@archlinux.org>

## What's Changed in v1.0.0
* Initial commit by @orhun <orhun@archlinux.org>
* docs(project): add README.md by @orhun <orhun@archlinux.org>
* feat(parser): add ability to parse arrays by @orhun <orhun@archlinux.org>
* fix(args): rename help argument due to conflict by @orhun <orhun@archlinux.org>
* docs(example)!: add tested usage example by @orhun <orhun@archlinux.org>

<!-- generated by -cliff -->
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ COPY --from=planner /app/recipe.json recipe.json
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
RUN cargo chef cook --release --recipe-path recipe.json
COPY . .
RUN cargo build --release --locked --no-default-features --features github --features gitlab
RUN cargo build --release --locked --no-default-features --features github --features gitlab --features bitbucket
RUN rm -f target/release/deps/git_cliff*

FROM debian:buster-slim as runner
Expand Down
10 changes: 10 additions & 0 deletions git-cliff-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ gitlab = [
"dep:tokio",
"dep:futures",
]
## Enable integration with Bitbucket.
## You can turn this off if you don't use Bitbucket and don't want
## to make network requests to the Bitbucket API.
bitbucket = [
"dep:reqwest",
"dep:http-cache-reqwest",
"dep:reqwest-middleware",
"dep:tokio",
"dep:futures",
]

[dependencies]
glob = { workspace = true, optional = true }
Expand Down
88 changes: 86 additions & 2 deletions git-cliff-core/src/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use crate::release::{
Release,
Releases,
};
#[cfg(feature = "bitbucket")]
use crate::remote::bitbucket::BitbucketClient;
#[cfg(feature = "github")]
use crate::remote::github::GitHubClient;
#[cfg(feature = "gitlab")]
Expand Down Expand Up @@ -297,6 +299,62 @@ impl<'a> Changelog<'a> {
}
}

/// Returns the Bitbucket metadata needed for the changelog.
///
/// This function creates a multithread async runtime for handling the
///
/// requests. The following are fetched from the bitbucket REST API:
///
/// - Commits
/// - Pull requests
///
/// Each of these are paginated requests so they are being run in parallel
/// for speedup.
///
///
/// If no bitbucket related variable is used in the template then this
/// function returns empty vectors.
#[cfg(feature = "bitbucket")]
fn get_bitbucket_metadata(&self) -> Result<crate::remote::RemoteMetadata> {
use crate::remote::bitbucket;
if self
.body_template
.contains_variable(bitbucket::TEMPLATE_VARIABLES) ||
self.footer_template
.as_ref()
.map(|v| v.contains_variable(bitbucket::TEMPLATE_VARIABLES))
.unwrap_or(false)
{
warn!("You are using an experimental feature! Please report bugs at <https://git-cliff.org/issues>");
let bitbucket_client =
BitbucketClient::try_from(self.config.remote.bitbucket.clone())?;
info!(
"{} ({})",
bitbucket::START_FETCHING_MSG,
self.config.remote.bitbucket
);
let data = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?
.block_on(async {
let (commits, pull_requests) = tokio::try_join!(
bitbucket_client.get_commits(),
bitbucket_client.get_pull_requests()
)?;
debug!("Number of Bitbucket commits: {}", commits.len());
debug!(
"Number of Bitbucket pull requests: {}",
pull_requests.len()
);
Ok((commits, pull_requests))
});
info!("{}", bitbucket::FINISHED_FETCHING_MSG);
data
} else {
Ok((vec![], vec![]))
}
}

/// Increments the version for the unreleased changes based on semver.
pub fn bump_version(&mut self) -> Result<Option<String>> {
if let Some(ref mut last_release) = self.releases.iter_mut().next() {
Expand Down Expand Up @@ -337,6 +395,14 @@ impl<'a> Changelog<'a> {
} else {
(vec![], vec![])
};
#[cfg(feature = "bitbucket")]
let (bitbucket_commits, bitbucket_pull_request) =
if self.config.remote.bitbucket.is_set() {
self.get_bitbucket_metadata()
.expect("Could not get bitbucket metadata")
} else {
(vec![], vec![])
};
let postprocessors = self
.config
.changelog
Expand All @@ -363,6 +429,11 @@ impl<'a> Changelog<'a> {
gitlab_commits.clone(),
gitlab_merge_request.clone(),
)?;
#[cfg(feature = "bitbucket")]
release.update_bitbucket_metadata(
bitbucket_commits.clone(),
bitbucket_pull_request.clone(),
)?;
let write_result = write!(
out,
"{}",
Expand Down Expand Up @@ -601,12 +672,17 @@ mod test {
limit_commits: None,
},
remote: RemoteConfig {
github: Remote {
github: Remote {
owner: String::from("coolguy"),
repo: String::from("awesome"),
token: None,
},
gitlab: Remote {
gitlab: Remote {
owner: String::from("coolguy"),
repo: String::from("awesome"),
token: None,
},
bitbucket: Remote {
owner: String::from("coolguy"),
repo: String::from("awesome"),
token: None,
Expand Down Expand Up @@ -685,6 +761,10 @@ mod test {
gitlab: crate::remote::RemoteReleaseMetadata {
contributors: vec![],
},
#[cfg(feature = "bitbucket")]
bitbucket: crate::remote::RemoteReleaseMetadata {
contributors: vec![],
},
};
let releases = vec![
test_release.clone(),
Expand Down Expand Up @@ -736,6 +816,10 @@ mod test {
gitlab: crate::remote::RemoteReleaseMetadata {
contributors: vec![],
},
#[cfg(feature = "bitbucket")]
bitbucket: crate::remote::RemoteReleaseMetadata {
contributors: vec![],
},
},
];
(config, releases)
Expand Down
5 changes: 5 additions & 0 deletions git-cliff-core/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ pub struct Commit<'a> {
/// GitLab metadata of the commit.
#[cfg(feature = "gitlab")]
pub gitlab: crate::remote::RemoteContributor,
/// Bitbucket metadata of the commit.
#[cfg(feature = "bitbucket")]
pub bitbucket: crate::remote::RemoteContributor,
}

impl<'a> From<String> for Commit<'a> {
Expand Down Expand Up @@ -443,6 +446,8 @@ impl Serialize for Commit<'_> {
commit.serialize_field("github", &self.github)?;
#[cfg(feature = "gitlab")]
commit.serialize_field("gitlab", &self.gitlab)?;
#[cfg(feature = "bitbucket")]
commit.serialize_field("bitbucket", &self.bitbucket)?;
commit.end()
}
}
Expand Down
7 changes: 5 additions & 2 deletions git-cliff-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,13 @@ pub struct GitConfig {
pub struct RemoteConfig {
/// GitHub remote.
#[serde(default)]
pub github: Remote,
pub github: Remote,
/// GitLab remote.
#[serde(default)]
pub gitlab: Remote,
pub gitlab: Remote,
/// Bitbucket remote.
#[serde(default)]
pub bitbucket: Remote,
}

/// A single remote.
Expand Down
6 changes: 3 additions & 3 deletions git-cliff-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,17 @@ pub enum Error {
SemverError(#[from] semver::Error),
/// The errors that may occur when processing a HTTP request.
#[error("HTTP client error: `{0}`")]
#[cfg(any(feature = "github", feature = "gitlab"))]
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
HttpClientError(#[from] reqwest::Error),
/// The errors that may occur while constructing the HTTP client with
/// middleware.
#[error("HTTP client with middleware error: `{0}`")]
#[cfg(any(feature = "github", feature = "gitlab"))]
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
HttpClientMiddlewareError(#[from] reqwest_middleware::Error),
/// A possible error when converting a HeaderValue from a string or byte
/// slice.
#[error("HTTP header error: `{0}`")]
#[cfg(any(feature = "github", feature = "gitlab"))]
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
HttpHeaderError(#[from] reqwest::header::InvalidHeaderValue),
/// Error that may occur during handling pages.
#[error("Pagination error: `{0}`")]
Expand Down
2 changes: 1 addition & 1 deletion git-cliff-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub mod error;
/// Common release type.
pub mod release;
/// Remote handler.
#[cfg(any(feature = "github", feature = "gitlab"))]
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
#[allow(async_fn_in_trait)]
pub mod remote;
/// Git repository.
Expand Down
18 changes: 17 additions & 1 deletion git-cliff-core/src/release.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::commit::Commit;
use crate::config::Bump;
use crate::error::Result;
#[cfg(any(feature = "github", feature = "gitlab"))]
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
use crate::remote::{
RemoteCommit,
RemoteContributor,
Expand Down Expand Up @@ -36,6 +36,9 @@ pub struct Release<'a> {
/// Contributors.
#[cfg(feature = "gitlab")]
pub gitlab: RemoteReleaseMetadata,
/// Contributors.
#[cfg(feature = "bitbucket")]
pub bitbucket: RemoteReleaseMetadata,
}

#[cfg(feature = "github")]
Expand All @@ -44,6 +47,9 @@ crate::update_release_metadata!(github, update_github_metadata);
#[cfg(feature = "gitlab")]
crate::update_release_metadata!(gitlab, update_gitlab_metadata);

#[cfg(feature = "bitbucket")]
crate::update_release_metadata!(bitbucket, update_bitbucket_metadata);

impl<'a> Release<'a> {
/// Calculates the next version based on the commits.
///
Expand Down Expand Up @@ -156,6 +162,10 @@ mod test {
gitlab: crate::remote::RemoteReleaseMetadata {
contributors: vec![],
},
#[cfg(feature = "bitbucket")]
bitbucket: crate::remote::RemoteReleaseMetadata {
contributors: vec![],
},
}
}

Expand Down Expand Up @@ -341,6 +351,9 @@ mod test {
gitlab: RemoteReleaseMetadata {
contributors: vec![],
},
bitbucket: RemoteReleaseMetadata {
contributors: vec![],
},
};
release.update_github_metadata(
vec![
Expand Down Expand Up @@ -617,6 +630,9 @@ mod test {
gitlab: RemoteReleaseMetadata {
contributors: vec![],
},
bitbucket: RemoteReleaseMetadata {
contributors: vec![],
},
};
release.update_gitlab_metadata(
vec![
Expand Down
Loading
Loading