mirror of
https://github.com/orhun/git-cliff.git
synced 2024-11-25 12:42:41 +03:00
feat(codeberg): add Gitea support (#680)
* feat: add gitea integration * fix: several fixes to get gitea working, add test fixture * docs: update docs * fix: cargo fmt * fix: remove dbg trait * fix: tests * chore: remove vscode settings * refactor: cleanup implementation --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
This commit is contained in:
parent
5b58a3771d
commit
403d3dcd32
2
.github/ISSUE_TEMPLATE/integration.yml
vendored
2
.github/ISSUE_TEMPLATE/integration.yml
vendored
@ -1,5 +1,5 @@
|
||||
name: Integration ⚙️
|
||||
description: Report a bug or request a feature about an integration (e.g GitHub/GitLab/Bitbucket)
|
||||
description: Report a bug or request a feature about an integration (e.g GitHub/GitLab/Gitea/Bitbucket)
|
||||
labels: ["integration"]
|
||||
assignees:
|
||||
- orhun
|
||||
|
46
.github/fixtures/test-gitea-integration/cliff.toml
vendored
Normal file
46
.github/fixtures/test-gitea-integration/cliff.toml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
[remote.gitea]
|
||||
owner = "ThetaDev"
|
||||
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.gitea.username %} by @{{ commit.gitea.username }}{%- endif -%}
|
||||
{% if commit.gitea.pr_number %} in #{{ commit.gitea.pr_number }}{%- endif %}
|
||||
{%- endfor -%}
|
||||
|
||||
{% if gitea.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
|
||||
{% raw %}\n{% endraw -%}
|
||||
## New Contributors
|
||||
{%- endif %}\
|
||||
{% for contributor in gitea.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
.github/fixtures/test-gitea-integration/commit.sh
vendored
Executable file
6
.github/fixtures/test-gitea-integration/commit.sh
vendored
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
git remote add origin https://codeberg.org/ThetaDev/git-cliff-readme-example.git
|
||||
git pull origin master
|
||||
git fetch --tags
|
15
.github/fixtures/test-gitea-integration/expected.md
vendored
Normal file
15
.github/fixtures/test-gitea-integration/expected.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
## What's Changed
|
||||
* Initial commit by @ThetaDev
|
||||
* docs(project): add README.md by @ThetaDev
|
||||
* feat(parser): add ability to parse arrays by @ThetaDev
|
||||
* fix(args): rename help argument due to conflict by @ThetaDev
|
||||
* docs(example)!: add tested usage example by @ThetaDev
|
||||
* refactor(parser): expose string functions by @ThetaDev
|
||||
* chore(release): add release script by @ThetaDev
|
||||
* feat(config): support multiple file formats by @ThetaDev
|
||||
* feat(cache): use cache while fetching pages by @ThetaDev
|
||||
|
||||
## New Contributors
|
||||
* @ThetaDev made their first contribution
|
||||
|
||||
<!-- generated by -cliff -->
|
3
.github/workflows/test-fixtures.yml
vendored
3
.github/workflows/test-fixtures.yml
vendored
@ -18,6 +18,9 @@ jobs:
|
||||
include:
|
||||
- fixtures-name: new-fixture-template
|
||||
- fixtures-name: test-github-integration
|
||||
- fixtures-name: test-gitlab-integration
|
||||
- fixtures-name: test-gitea-integration
|
||||
- fixtures-name: test-bitbucket-integration
|
||||
- fixtures-name: test-ignore-tags
|
||||
- fixtures-name: test-topo-order
|
||||
command: --latest
|
||||
|
@ -17,36 +17,30 @@ default = ["repo"]
|
||||
## You can turn this off if you already have the commits to put in the
|
||||
## changelog and you don't need `git-cliff` to parse them.
|
||||
repo = ["dep:git2", "dep:glob", "dep:indexmap"]
|
||||
# Enable integration with remote repositories.
|
||||
remote = [
|
||||
"dep:reqwest",
|
||||
"dep:http-cache-reqwest",
|
||||
"dep:reqwest-middleware",
|
||||
"dep:tokio",
|
||||
"dep:futures",
|
||||
]
|
||||
## Enable integration with GitHub.
|
||||
## You can turn this off if you don't use GitHub and don't want
|
||||
## to make network requests to the GitHub API.
|
||||
github = [
|
||||
"dep:reqwest",
|
||||
"dep:http-cache-reqwest",
|
||||
"dep:reqwest-middleware",
|
||||
"dep:tokio",
|
||||
"dep:futures",
|
||||
]
|
||||
github = ["remote"]
|
||||
## Enable integration with GitLab.
|
||||
## You can turn this off if you don't use GitLab and don't want
|
||||
## to make network requests to the GitLab API.
|
||||
gitlab = [
|
||||
"dep:reqwest",
|
||||
"dep:http-cache-reqwest",
|
||||
"dep:reqwest-middleware",
|
||||
"dep:tokio",
|
||||
"dep:futures",
|
||||
]
|
||||
gitlab = ["remote"]
|
||||
## 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",
|
||||
]
|
||||
bitbucket = ["remote"]
|
||||
## Enable integration with Gitea.
|
||||
## You can turn this off if you don't use Gitea and don't want
|
||||
## to make network requests to the Gitea API.
|
||||
gitea = ["remote"]
|
||||
|
||||
[dependencies]
|
||||
glob = { workspace = true, optional = true }
|
||||
|
@ -10,6 +10,8 @@ use crate::release::{
|
||||
};
|
||||
#[cfg(feature = "bitbucket")]
|
||||
use crate::remote::bitbucket::BitbucketClient;
|
||||
#[cfg(feature = "gitea")]
|
||||
use crate::remote::gitea::GiteaClient;
|
||||
#[cfg(feature = "github")]
|
||||
use crate::remote::github::GitHubClient;
|
||||
#[cfg(feature = "gitlab")]
|
||||
@ -224,7 +226,10 @@ impl<'a> Changelog<'a> {
|
||||
github_client.get_pull_requests(),
|
||||
)?;
|
||||
debug!("Number of GitHub commits: {}", commits.len());
|
||||
debug!("Number of GitHub pull requests: {}", commits.len());
|
||||
debug!(
|
||||
"Number of GitHub pull requests: {}",
|
||||
pull_requests.len()
|
||||
);
|
||||
Ok((commits, pull_requests))
|
||||
});
|
||||
info!("{}", github::FINISHED_FETCHING_MSG);
|
||||
@ -300,6 +305,57 @@ impl<'a> Changelog<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the Gitea metadata needed for the changelog.
|
||||
///
|
||||
/// This function creates a multithread async runtime for handling the
|
||||
/// requests. The following are fetched from the GitHub REST API:
|
||||
///
|
||||
/// - Commits
|
||||
/// - Pull requests
|
||||
///
|
||||
/// Each of these are paginated requests so they are being run in parallel
|
||||
/// for speedup.
|
||||
///
|
||||
/// If no Gitea related variable is used in the template then this function
|
||||
/// returns empty vectors.
|
||||
#[cfg(feature = "gitea")]
|
||||
fn get_gitea_metadata(&self) -> Result<crate::remote::RemoteMetadata> {
|
||||
use crate::remote::gitea;
|
||||
if self
|
||||
.body_template
|
||||
.contains_variable(gitea::TEMPLATE_VARIABLES) ||
|
||||
self.footer_template
|
||||
.as_ref()
|
||||
.map(|v| v.contains_variable(gitea::TEMPLATE_VARIABLES))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
warn!("You are using an experimental feature! Please report bugs at <https://git-cliff.org/issues>");
|
||||
let gitea_client =
|
||||
GiteaClient::try_from(self.config.remote.gitea.clone())?;
|
||||
info!(
|
||||
"{} ({})",
|
||||
gitea::START_FETCHING_MSG,
|
||||
self.config.remote.gitea
|
||||
);
|
||||
let data = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()?
|
||||
.block_on(async {
|
||||
let (commits, pull_requests) = tokio::try_join!(
|
||||
gitea_client.get_commits(),
|
||||
gitea_client.get_pull_requests(),
|
||||
)?;
|
||||
debug!("Number of Gitea commits: {}", commits.len());
|
||||
debug!("Number of Gitea pull requests: {}", pull_requests.len());
|
||||
Ok((commits, pull_requests))
|
||||
});
|
||||
info!("{}", gitea::FINISHED_FETCHING_MSG);
|
||||
data
|
||||
} else {
|
||||
Ok((vec![], vec![]))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the Bitbucket metadata needed for the changelog.
|
||||
///
|
||||
/// This function creates a multithread async runtime for handling the
|
||||
@ -379,6 +435,13 @@ impl<'a> Changelog<'a> {
|
||||
} else {
|
||||
(vec![], vec![])
|
||||
};
|
||||
#[cfg(feature = "gitea")]
|
||||
let (gitea_commits, gitea_merge_request) = if self.config.remote.gitea.is_set() {
|
||||
self.get_gitea_metadata()
|
||||
.expect("Could not get gitea metadata")
|
||||
} else {
|
||||
(vec![], vec![])
|
||||
};
|
||||
#[cfg(feature = "bitbucket")]
|
||||
let (bitbucket_commits, bitbucket_pull_request) =
|
||||
if self.config.remote.bitbucket.is_set() {
|
||||
@ -398,6 +461,11 @@ impl<'a> Changelog<'a> {
|
||||
gitlab_commits.clone(),
|
||||
gitlab_merge_request.clone(),
|
||||
)?;
|
||||
#[cfg(feature = "gitea")]
|
||||
release.update_gitea_metadata(
|
||||
gitea_commits.clone(),
|
||||
gitea_merge_request.clone(),
|
||||
)?;
|
||||
#[cfg(feature = "bitbucket")]
|
||||
release.update_bitbucket_metadata(
|
||||
bitbucket_commits.clone(),
|
||||
@ -692,6 +760,11 @@ mod test {
|
||||
repo: String::from("awesome"),
|
||||
token: None,
|
||||
},
|
||||
gitea: Remote {
|
||||
owner: String::from("coolguy"),
|
||||
repo: String::from("awesome"),
|
||||
token: None,
|
||||
},
|
||||
bitbucket: Remote {
|
||||
owner: String::from("coolguy"),
|
||||
repo: String::from("awesome"),
|
||||
@ -771,6 +844,10 @@ mod test {
|
||||
gitlab: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "gitea")]
|
||||
gitea: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "bitbucket")]
|
||||
bitbucket: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
@ -826,6 +903,10 @@ mod test {
|
||||
gitlab: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "gitea")]
|
||||
gitea: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "bitbucket")]
|
||||
bitbucket: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
|
@ -128,6 +128,9 @@ pub struct Commit<'a> {
|
||||
/// GitLab metadata of the commit.
|
||||
#[cfg(feature = "gitlab")]
|
||||
pub gitlab: crate::remote::RemoteContributor,
|
||||
/// Gitea metadata of the commit.
|
||||
#[cfg(feature = "gitea")]
|
||||
pub gitea: crate::remote::RemoteContributor,
|
||||
/// Bitbucket metadata of the commit.
|
||||
#[cfg(feature = "bitbucket")]
|
||||
pub bitbucket: crate::remote::RemoteContributor,
|
||||
@ -446,6 +449,8 @@ impl Serialize for Commit<'_> {
|
||||
commit.serialize_field("github", &self.github)?;
|
||||
#[cfg(feature = "gitlab")]
|
||||
commit.serialize_field("gitlab", &self.gitlab)?;
|
||||
#[cfg(feature = "gitea")]
|
||||
commit.serialize_field("gitea", &self.gitea)?;
|
||||
#[cfg(feature = "bitbucket")]
|
||||
commit.serialize_field("bitbucket", &self.bitbucket)?;
|
||||
commit.end()
|
||||
|
@ -126,6 +126,9 @@ pub struct RemoteConfig {
|
||||
/// GitLab remote.
|
||||
#[serde(default)]
|
||||
pub gitlab: Remote,
|
||||
/// Gitea remote.
|
||||
#[serde(default)]
|
||||
pub gitea: Remote,
|
||||
/// Bitbucket remote.
|
||||
#[serde(default)]
|
||||
pub bitbucket: Remote,
|
||||
|
@ -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", feature = "bitbucket"))]
|
||||
#[cfg(feature = "remote")]
|
||||
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", feature = "bitbucket"))]
|
||||
#[cfg(feature = "remote")]
|
||||
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", feature = "bitbucket"))]
|
||||
#[cfg(feature = "remote")]
|
||||
HttpHeaderError(#[from] reqwest::header::InvalidHeaderValue),
|
||||
/// Error that may occur during handling pages.
|
||||
#[error("Pagination error: `{0}`")]
|
||||
|
@ -27,7 +27,7 @@ pub mod error;
|
||||
/// Common release type.
|
||||
pub mod release;
|
||||
/// Remote handler.
|
||||
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
|
||||
#[cfg(feature = "remote")]
|
||||
#[allow(async_fn_in_trait)]
|
||||
pub mod remote;
|
||||
/// Git repository.
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::commit::Commit;
|
||||
use crate::config::Bump;
|
||||
use crate::error::Result;
|
||||
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
|
||||
#[cfg(feature = "remote")]
|
||||
use crate::remote::{
|
||||
RemoteCommit,
|
||||
RemoteContributor,
|
||||
@ -37,6 +37,9 @@ pub struct Release<'a> {
|
||||
#[cfg(feature = "gitlab")]
|
||||
pub gitlab: RemoteReleaseMetadata,
|
||||
/// Contributors.
|
||||
#[cfg(feature = "gitea")]
|
||||
pub gitea: RemoteReleaseMetadata,
|
||||
/// Contributors.
|
||||
#[cfg(feature = "bitbucket")]
|
||||
pub bitbucket: RemoteReleaseMetadata,
|
||||
}
|
||||
@ -47,6 +50,9 @@ crate::update_release_metadata!(github, update_github_metadata);
|
||||
#[cfg(feature = "gitlab")]
|
||||
crate::update_release_metadata!(gitlab, update_gitlab_metadata);
|
||||
|
||||
#[cfg(feature = "gitea")]
|
||||
crate::update_release_metadata!(gitea, update_gitea_metadata);
|
||||
|
||||
#[cfg(feature = "bitbucket")]
|
||||
crate::update_release_metadata!(bitbucket, update_bitbucket_metadata);
|
||||
|
||||
@ -162,6 +168,10 @@ mod test {
|
||||
gitlab: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "gitea")]
|
||||
gitea: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "bitbucket")]
|
||||
bitbucket: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
@ -316,8 +326,8 @@ mod test {
|
||||
};
|
||||
|
||||
let mut release = Release {
|
||||
version: None,
|
||||
commits: vec![
|
||||
version: None,
|
||||
commits: vec![
|
||||
Commit::from(String::from(
|
||||
"1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add github \
|
||||
integration",
|
||||
@ -341,16 +351,22 @@ mod test {
|
||||
],
|
||||
commit_id: None,
|
||||
timestamp: 0,
|
||||
previous: Some(Box::new(Release {
|
||||
previous: Some(Box::new(Release {
|
||||
version: Some(String::from("1.0.0")),
|
||||
..Default::default()
|
||||
})),
|
||||
github: RemoteReleaseMetadata {
|
||||
github: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
gitlab: RemoteReleaseMetadata {
|
||||
#[cfg(feature = "gitlab")]
|
||||
gitlab: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "gitea")]
|
||||
gitea: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "bitbucket")]
|
||||
bitbucket: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
@ -595,8 +611,8 @@ mod test {
|
||||
};
|
||||
|
||||
let mut release = Release {
|
||||
version: None,
|
||||
commits: vec![
|
||||
version: None,
|
||||
commits: vec![
|
||||
Commit::from(String::from(
|
||||
"1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add github \
|
||||
integration",
|
||||
@ -620,16 +636,22 @@ mod test {
|
||||
],
|
||||
commit_id: None,
|
||||
timestamp: 0,
|
||||
previous: Some(Box::new(Release {
|
||||
previous: Some(Box::new(Release {
|
||||
version: Some(String::from("1.0.0")),
|
||||
..Default::default()
|
||||
})),
|
||||
github: RemoteReleaseMetadata {
|
||||
#[cfg(feature = "github")]
|
||||
github: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
gitlab: RemoteReleaseMetadata {
|
||||
gitlab: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "gitea")]
|
||||
gitea: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "bitbucket")]
|
||||
bitbucket: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
@ -920,4 +942,290 @@ mod test {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "gitea")]
|
||||
#[test]
|
||||
fn update_gitea_metadata() -> Result<()> {
|
||||
use crate::remote::gitea::{
|
||||
GiteaCommit,
|
||||
GiteaCommitAuthor,
|
||||
GiteaPullRequest,
|
||||
PullRequestLabel,
|
||||
};
|
||||
|
||||
let mut release = Release {
|
||||
version: None,
|
||||
commits: vec![
|
||||
Commit::from(String::from(
|
||||
"1d244937ee6ceb8e0314a4a201ba93a7a61f2071 add github \
|
||||
integration",
|
||||
)),
|
||||
Commit::from(String::from(
|
||||
"21f6aa587fcb772de13f2fde0e92697c51f84162 fix github \
|
||||
integration",
|
||||
)),
|
||||
Commit::from(String::from(
|
||||
"35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973 update metadata",
|
||||
)),
|
||||
Commit::from(String::from(
|
||||
"4d3ffe4753b923f4d7807c490e650e6624a12074 do some stuff",
|
||||
)),
|
||||
Commit::from(String::from(
|
||||
"5a55e92e5a62dc5bf9872ffb2566959fad98bd05 alright",
|
||||
)),
|
||||
Commit::from(String::from(
|
||||
"6c34967147560ea09658776d4901709139b4ad66 should be fine",
|
||||
)),
|
||||
],
|
||||
commit_id: None,
|
||||
timestamp: 0,
|
||||
previous: Some(Box::new(Release {
|
||||
version: Some(String::from("1.0.0")),
|
||||
..Default::default()
|
||||
})),
|
||||
#[cfg(feature = "github")]
|
||||
github: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "gitlab")]
|
||||
gitlab: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
gitea: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "bitbucket")]
|
||||
bitbucket: RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
};
|
||||
release.update_gitea_metadata(
|
||||
vec![
|
||||
GiteaCommit {
|
||||
sha: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
|
||||
author: Some(GiteaCommitAuthor {
|
||||
login: Some(String::from("orhun")),
|
||||
}),
|
||||
},
|
||||
GiteaCommit {
|
||||
sha: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
|
||||
author: Some(GiteaCommitAuthor {
|
||||
login: Some(String::from("orhun")),
|
||||
}),
|
||||
},
|
||||
GiteaCommit {
|
||||
sha: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
|
||||
author: Some(GiteaCommitAuthor {
|
||||
login: Some(String::from("nuhro")),
|
||||
}),
|
||||
},
|
||||
GiteaCommit {
|
||||
sha: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
|
||||
author: Some(GiteaCommitAuthor {
|
||||
login: Some(String::from("awesome_contributor")),
|
||||
}),
|
||||
},
|
||||
GiteaCommit {
|
||||
sha: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
|
||||
author: Some(GiteaCommitAuthor {
|
||||
login: Some(String::from("orhun")),
|
||||
}),
|
||||
},
|
||||
GiteaCommit {
|
||||
sha: String::from("6c34967147560ea09658776d4901709139b4ad66"),
|
||||
author: Some(GiteaCommitAuthor {
|
||||
login: Some(String::from("someone")),
|
||||
}),
|
||||
},
|
||||
GiteaCommit {
|
||||
sha: String::from("0c34967147560e809658776d4901709139b4ad68"),
|
||||
author: Some(GiteaCommitAuthor {
|
||||
login: Some(String::from("idk")),
|
||||
}),
|
||||
},
|
||||
GiteaCommit {
|
||||
sha: String::from("kk34967147560e809658776d4901709139b4ad68"),
|
||||
author: None,
|
||||
},
|
||||
GiteaCommit {
|
||||
sha: String::new(),
|
||||
author: None,
|
||||
},
|
||||
]
|
||||
.into_iter()
|
||||
.map(|v| Box::new(v) as Box<dyn RemoteCommit>)
|
||||
.collect(),
|
||||
vec![
|
||||
GiteaPullRequest {
|
||||
title: Some(String::from("1")),
|
||||
number: 42,
|
||||
merge_commit_sha: Some(String::from(
|
||||
"1d244937ee6ceb8e0314a4a201ba93a7a61f2071",
|
||||
)),
|
||||
labels: vec![PullRequestLabel {
|
||||
name: String::from("rust"),
|
||||
}],
|
||||
},
|
||||
GiteaPullRequest {
|
||||
title: Some(String::from("2")),
|
||||
number: 66,
|
||||
merge_commit_sha: Some(String::from(
|
||||
"21f6aa587fcb772de13f2fde0e92697c51f84162",
|
||||
)),
|
||||
labels: vec![PullRequestLabel {
|
||||
name: String::from("rust"),
|
||||
}],
|
||||
},
|
||||
GiteaPullRequest {
|
||||
title: Some(String::from("3")),
|
||||
number: 53,
|
||||
merge_commit_sha: Some(String::from(
|
||||
"35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973",
|
||||
)),
|
||||
labels: vec![PullRequestLabel {
|
||||
name: String::from("deps"),
|
||||
}],
|
||||
},
|
||||
GiteaPullRequest {
|
||||
title: Some(String::from("4")),
|
||||
number: 1000,
|
||||
merge_commit_sha: Some(String::from(
|
||||
"4d3ffe4753b923f4d7807c490e650e6624a12074",
|
||||
)),
|
||||
labels: vec![PullRequestLabel {
|
||||
name: String::from("deps"),
|
||||
}],
|
||||
},
|
||||
GiteaPullRequest {
|
||||
title: Some(String::from("5")),
|
||||
number: 999999,
|
||||
merge_commit_sha: Some(String::from(
|
||||
"5a55e92e5a62dc5bf9872ffb2566959fad98bd05",
|
||||
)),
|
||||
labels: vec![PullRequestLabel {
|
||||
name: String::from("github"),
|
||||
}],
|
||||
},
|
||||
]
|
||||
.into_iter()
|
||||
.map(|v| Box::new(v) as Box<dyn RemotePullRequest>)
|
||||
.collect(),
|
||||
)?;
|
||||
let expected_commits = vec![
|
||||
Commit {
|
||||
id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
|
||||
message: String::from("add github integration"),
|
||||
gitea: RemoteContributor {
|
||||
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,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Commit {
|
||||
id: String::from("21f6aa587fcb772de13f2fde0e92697c51f84162"),
|
||||
message: String::from("fix github integration"),
|
||||
gitea: RemoteContributor {
|
||||
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,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Commit {
|
||||
id: String::from("35d8c6b6329ecbcf131d7df02f93c3bbc5ba5973"),
|
||||
message: String::from("update metadata"),
|
||||
gitea: RemoteContributor {
|
||||
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,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Commit {
|
||||
id: String::from("4d3ffe4753b923f4d7807c490e650e6624a12074"),
|
||||
message: String::from("do some stuff"),
|
||||
gitea: RemoteContributor {
|
||||
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,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Commit {
|
||||
id: String::from("5a55e92e5a62dc5bf9872ffb2566959fad98bd05"),
|
||||
message: String::from("alright"),
|
||||
gitea: RemoteContributor {
|
||||
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,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Commit {
|
||||
id: String::from("6c34967147560ea09658776d4901709139b4ad66"),
|
||||
message: String::from("should be fine"),
|
||||
gitea: RemoteContributor {
|
||||
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
|
||||
.gitea
|
||||
.contributors
|
||||
.sort_by(|a, b| a.pr_number.cmp(&b.pr_number));
|
||||
|
||||
let expected_metadata = RemoteReleaseMetadata {
|
||||
contributors: vec![
|
||||
RemoteContributor {
|
||||
username: Some(String::from("someone")),
|
||||
pr_title: None,
|
||||
pr_number: None,
|
||||
pr_labels: vec![],
|
||||
is_first_time: true,
|
||||
},
|
||||
RemoteContributor {
|
||||
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,
|
||||
},
|
||||
RemoteContributor {
|
||||
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,
|
||||
},
|
||||
RemoteContributor {
|
||||
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.gitea);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
184
git-cliff-core/src/remote/gitea.rs
Normal file
184
git-cliff-core/src/remote/gitea.rs
Normal file
@ -0,0 +1,184 @@
|
||||
use crate::config::Remote;
|
||||
use crate::error::*;
|
||||
use reqwest_middleware::ClientWithMiddleware;
|
||||
use serde::{
|
||||
Deserialize,
|
||||
Serialize,
|
||||
};
|
||||
use std::env;
|
||||
|
||||
use super::*;
|
||||
|
||||
/// Gitea API url.
|
||||
const GITEA_API_URL: &str = "https://codeberg.org";
|
||||
|
||||
/// Environment variable for overriding the Gitea REST API url.
|
||||
const GITEA_API_URL_ENV: &str = "GITEA_API_URL";
|
||||
|
||||
/// Log message to show while fetching data from Gitea.
|
||||
pub const START_FETCHING_MSG: &str = "Retrieving data from Gitea...";
|
||||
|
||||
/// Log message to show when done fetching from Gitea.
|
||||
pub const FINISHED_FETCHING_MSG: &str = "Done fetching Gitea data.";
|
||||
|
||||
/// Template variables related to this remote.
|
||||
pub(crate) const TEMPLATE_VARIABLES: &[&str] = &["gitea", "commit.gitea"];
|
||||
|
||||
/// Representation of a single commit.
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct GiteaCommit {
|
||||
/// SHA.
|
||||
pub sha: String,
|
||||
/// Author of the commit.
|
||||
pub author: Option<GiteaCommitAuthor>,
|
||||
}
|
||||
|
||||
impl RemoteCommit for GiteaCommit {
|
||||
fn id(&self) -> String {
|
||||
self.sha.clone()
|
||||
}
|
||||
|
||||
fn username(&self) -> Option<String> {
|
||||
self.author.clone().and_then(|v| v.login)
|
||||
}
|
||||
}
|
||||
|
||||
impl RemoteEntry for GiteaCommit {
|
||||
fn url(_id: i64, api_url: &str, remote: &Remote, page: i32) -> String {
|
||||
format!(
|
||||
"{}/api/v1/repos/{}/{}/commits?limit={MAX_PAGE_SIZE}&page={page}",
|
||||
api_url, remote.owner, remote.repo
|
||||
)
|
||||
}
|
||||
fn buffer_size() -> usize {
|
||||
10
|
||||
}
|
||||
|
||||
fn early_exit(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Author of the commit.
|
||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct GiteaCommitAuthor {
|
||||
/// Username.
|
||||
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 GiteaPullRequest {
|
||||
/// Pull request number.
|
||||
pub number: i64,
|
||||
/// Pull request title.
|
||||
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 RemotePullRequest for GiteaPullRequest {
|
||||
fn number(&self) -> i64 {
|
||||
self.number
|
||||
}
|
||||
|
||||
fn title(&self) -> Option<String> {
|
||||
self.title.clone()
|
||||
}
|
||||
|
||||
fn labels(&self) -> Vec<String> {
|
||||
self.labels.iter().map(|v| v.name.clone()).collect()
|
||||
}
|
||||
|
||||
fn merge_commit(&self) -> Option<String> {
|
||||
self.merge_commit_sha.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl RemoteEntry for GiteaPullRequest {
|
||||
fn url(_id: i64, api_url: &str, remote: &Remote, page: i32) -> String {
|
||||
format!(
|
||||
"{}/api/v1/repos/{}/{}/pulls?limit={MAX_PAGE_SIZE}&page={page}&\
|
||||
state=closed",
|
||||
api_url, remote.owner, remote.repo
|
||||
)
|
||||
}
|
||||
|
||||
fn buffer_size() -> usize {
|
||||
5
|
||||
}
|
||||
|
||||
fn early_exit(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// HTTP client for handling Gitea REST API requests.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GiteaClient {
|
||||
/// Remote.
|
||||
remote: Remote,
|
||||
/// HTTP client.
|
||||
client: ClientWithMiddleware,
|
||||
}
|
||||
|
||||
/// Constructs a Gitea client from the remote configuration.
|
||||
impl TryFrom<Remote> for GiteaClient {
|
||||
type Error = Error;
|
||||
fn try_from(remote: Remote) -> Result<Self> {
|
||||
Ok(Self {
|
||||
client: create_remote_client(&remote, "application/json")?,
|
||||
remote,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl RemoteClient for GiteaClient {
|
||||
fn api_url() -> String {
|
||||
env::var(GITEA_API_URL_ENV)
|
||||
.ok()
|
||||
.unwrap_or_else(|| GITEA_API_URL.to_string())
|
||||
}
|
||||
|
||||
fn remote(&self) -> Remote {
|
||||
self.remote.clone()
|
||||
}
|
||||
|
||||
fn client(&self) -> ClientWithMiddleware {
|
||||
self.client.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl GiteaClient {
|
||||
/// Fetches the Gitea API and returns the commits.
|
||||
pub async fn get_commits(&self) -> Result<Vec<Box<dyn RemoteCommit>>> {
|
||||
Ok(self
|
||||
.fetch::<GiteaCommit>(0)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|v| Box::new(v) as Box<dyn RemoteCommit>)
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Fetches the Gitea API and returns the pull requests.
|
||||
pub async fn get_pull_requests(
|
||||
&self,
|
||||
) -> Result<Vec<Box<dyn RemotePullRequest>>> {
|
||||
Ok(self
|
||||
.fetch::<GiteaPullRequest>(0)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|v| Box::new(v) as Box<dyn RemotePullRequest>)
|
||||
.collect())
|
||||
}
|
||||
}
|
@ -10,6 +10,10 @@ pub mod gitlab;
|
||||
#[cfg(feature = "bitbucket")]
|
||||
pub mod bitbucket;
|
||||
|
||||
/// Gitea client.
|
||||
#[cfg(feature = "gitea")]
|
||||
pub mod gitea;
|
||||
|
||||
use crate::config::Remote;
|
||||
use crate::error::{
|
||||
Error,
|
||||
@ -43,6 +47,7 @@ use serde::{
|
||||
Deserialize,
|
||||
Serialize,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
use std::hash::{
|
||||
Hash,
|
||||
Hasher,
|
||||
|
@ -132,7 +132,7 @@ impl Template {
|
||||
}
|
||||
|
||||
/// Returns `true` if the template contains one of the given variables.
|
||||
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
|
||||
#[cfg(feature = "remote")]
|
||||
pub(crate) fn contains_variable(&self, variables: &[&str]) -> bool {
|
||||
variables
|
||||
.iter()
|
||||
@ -213,6 +213,10 @@ mod test {
|
||||
gitlab: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "gitea")]
|
||||
gitea: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "bitbucket")]
|
||||
bitbucket: crate::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
|
@ -196,6 +196,10 @@ fn generate_changelog() -> Result<()> {
|
||||
gitlab: git_cliff_core::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "gitea")]
|
||||
gitea: git_cliff_core::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "bitbucket")]
|
||||
bitbucket: git_cliff_core::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
@ -232,6 +236,10 @@ fn generate_changelog() -> Result<()> {
|
||||
gitlab: git_cliff_core::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "gitea")]
|
||||
gitea: git_cliff_core::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
},
|
||||
#[cfg(feature = "bitbucket")]
|
||||
bitbucket: git_cliff_core::remote::RemoteReleaseMetadata {
|
||||
contributors: vec![],
|
||||
|
@ -23,15 +23,19 @@ path = "src/bin/mangen.rs"
|
||||
|
||||
[features]
|
||||
# check for new versions
|
||||
default = ["update-informer", "github", "gitlab", "bitbucket"]
|
||||
default = ["update-informer", "github", "gitlab", "gitea", "bitbucket"]
|
||||
# inform about new releases
|
||||
update-informer = ["dep:update-informer"]
|
||||
# enable remote repository integration
|
||||
remote = ["dep:indicatif"]
|
||||
# enable GitHub integration
|
||||
github = ["git-cliff-core/github", "dep:indicatif"]
|
||||
github = ["remote", "git-cliff-core/github"]
|
||||
# enable GitLab integration
|
||||
gitlab = ["git-cliff-core/gitlab", "dep:indicatif"]
|
||||
gitlab = ["remote", "git-cliff-core/gitlab"]
|
||||
# enable Gitea integration
|
||||
gitea = ["remote", "git-cliff-core/gitea"]
|
||||
# enable Bitbucket integration
|
||||
bitbucket = ["git-cliff-core/bitbucket", "dep:indicatif"]
|
||||
bitbucket = ["remote", "git-cliff-core/bitbucket"]
|
||||
|
||||
[dependencies]
|
||||
glob.workspace = true
|
||||
|
@ -261,6 +261,24 @@ pub struct Opt {
|
||||
hide = !cfg!(feature = "gitlab"),
|
||||
)]
|
||||
pub gitlab_repo: Option<RemoteValue>,
|
||||
/// Sets the Gitea API token.
|
||||
#[arg(
|
||||
long,
|
||||
env = "GITEA_TOKEN",
|
||||
value_name = "TOKEN",
|
||||
hide_env_values = true,
|
||||
hide = !cfg!(feature = "gitea"),
|
||||
)]
|
||||
pub gitea_token: Option<SecretString>,
|
||||
/// Sets the GitLab repository.
|
||||
#[arg(
|
||||
long,
|
||||
env = "GITEA_REPO",
|
||||
value_parser = clap::value_parser!(RemoteValue),
|
||||
value_name = "OWNER/REPO",
|
||||
hide = !cfg!(feature = "gitea"),
|
||||
)]
|
||||
pub gitea_repo: Option<RemoteValue>,
|
||||
/// Sets the Bitbucket API token.
|
||||
#[arg(
|
||||
long,
|
||||
|
@ -134,6 +134,17 @@ fn process_repository<'a>(
|
||||
debug!("Failed to get remote from GitLab repository: {:?}", e);
|
||||
}
|
||||
}
|
||||
} else if !config.remote.gitea.is_set() {
|
||||
match repository.upstream_remote() {
|
||||
Ok(remote) => {
|
||||
debug!("No Gitea remote is set, using remote: {}", remote);
|
||||
config.remote.gitea.owner = remote.owner;
|
||||
config.remote.gitea.repo = remote.repo;
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("Failed to get remote from Gitea repository: {:?}", e);
|
||||
}
|
||||
}
|
||||
} else if !config.remote.bitbucket.is_set() {
|
||||
match repository.upstream_remote() {
|
||||
Ok(remote) => {
|
||||
@ -437,6 +448,9 @@ pub fn run(mut args: Opt) -> Result<()> {
|
||||
if args.gitlab_token.is_some() {
|
||||
config.remote.gitlab.token.clone_from(&args.gitlab_token);
|
||||
}
|
||||
if args.gitea_token.is_some() {
|
||||
config.remote.gitea.token.clone_from(&args.gitea_token);
|
||||
}
|
||||
if args.bitbucket_token.is_some() {
|
||||
config
|
||||
.remote
|
||||
|
@ -10,7 +10,7 @@ use git_cliff_core::error::{
|
||||
Error,
|
||||
Result,
|
||||
};
|
||||
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
|
||||
#[cfg(feature = "remote")]
|
||||
use indicatif::{
|
||||
ProgressBar,
|
||||
ProgressStyle,
|
||||
@ -66,7 +66,7 @@ fn colored_level(style: &mut Style, level: Level) -> StyledValue<'_, &'static st
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "github", feature = "gitlab", feature = "bitbucket"))]
|
||||
#[cfg(feature = "remote")]
|
||||
lazy_static::lazy_static! {
|
||||
/// Lazily initialized progress bar.
|
||||
pub static ref PROGRESS_BAR: ProgressBar = {
|
||||
@ -144,6 +144,23 @@ pub fn init() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gitea")]
|
||||
{
|
||||
let message = record.args().to_string();
|
||||
if message.starts_with(git_cliff_core::remote::gitea::START_FETCHING_MSG)
|
||||
{
|
||||
PROGRESS_BAR
|
||||
.enable_steady_tick(std::time::Duration::from_millis(80));
|
||||
PROGRESS_BAR.set_message(message);
|
||||
return Ok(());
|
||||
} else if message
|
||||
.starts_with(git_cliff_core::remote::gitea::FINISHED_FETCHING_MSG)
|
||||
{
|
||||
PROGRESS_BAR.finish_and_clear();
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bitbucket")]
|
||||
{
|
||||
let message = record.args().to_string();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
This section contains the Git remote related configuration options.
|
||||
|
||||
You can configure a remote for GitHub, GitLab or Bitbucket as follows:
|
||||
You can configure a remote for GitHub, GitLab, Gitea/Forgejo or Bitbucket as follows:
|
||||
|
||||
```toml
|
||||
[remote.github]
|
||||
@ -11,12 +11,13 @@ repo = "git-cliff"
|
||||
token = ""
|
||||
```
|
||||
|
||||
Change this to `remote.gitlab` or `remote.bitbucket` accordingly to your project.
|
||||
Change this to `remote.gitlab`, `remote.gitea` or `remote.bitbucket` accordingly to your project.
|
||||
|
||||
:::tip
|
||||
|
||||
- See the [GitHub integration](/docs/integration/github).
|
||||
- See the [GitLab integration](/docs/integration/gitlab).
|
||||
- See the [Gitea integration](/docs/integration/gitea).
|
||||
- See the [Bitbucket integration](/docs/integration/bitbucket).
|
||||
|
||||
:::
|
||||
@ -37,7 +38,7 @@ e.g.
|
||||
git cliff --github-repo orhun/git-cliff
|
||||
```
|
||||
|
||||
Same applies for GitLab/Bitbucket with `--gitlab-repo`/`--bitbucket-repo` and `GITLAB_REPO`/`BITBUCKET_REPO` environment variables.
|
||||
Same applies for GitLab/Bitbucket with `--gitlab-repo`/`--gitea-repo`/`--bitbucket-repo` and `GITLAB_REPO`/`GITEA_REPO`/`BITBUCKET_REPO` environment variables.
|
||||
|
||||
### token
|
||||
|
||||
@ -49,4 +50,4 @@ If you are using GitHub, then you can also pass this value via `--github-token`
|
||||
git cliff --github-token <TOKEN>
|
||||
```
|
||||
|
||||
Same applies for GitLab/Bitbucket with `--gitlab-token`/`--bitbucket-token` and `GITLAB_TOKEN`/`BITBUCKET_TOKEN` environment variables.
|
||||
Same applies for GitLab/Bitbucket with `--gitlab-token`/`--gitea-token`/`--bitbucket-token` and `GITLAB_TOKEN`/`GITEA_TOKEN`/`BITBUCKET_TOKEN` environment variables.
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Bitbucket Integration 📘
|
||||
|
179
website/docs/integration/gitea.md
Normal file
179
website/docs/integration/gitea.md
Normal file
@ -0,0 +1,179 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Gitea Integration 🍵
|
||||
|
||||
:::warning
|
||||
|
||||
This is still an experimental feature, please [report bugs](https://github.com/orhun/git-cliff/issues/new/choose).
|
||||
|
||||
:::
|
||||
|
||||
:::note
|
||||
|
||||
If you have built from source, enable the `gitea` feature flag for the integration to work.
|
||||
|
||||
:::
|
||||
|
||||
For projects hosted on Gitea/Forgejo, you can use **git-cliff** to add the following to your changelog:
|
||||
|
||||
- Gitea usernames
|
||||
- Contributors list (all contributors / first time)
|
||||
- Pull request links (associated with the commits)
|
||||
|
||||
## Setting up the remote
|
||||
|
||||
As default, remote upstream URL is automatically retrieved from the Git repository.
|
||||
|
||||
If that doesn't work or if you want to set a custom remote, there are a couple of ways of doing it:
|
||||
|
||||
- Use the [remote option](/docs/configuration/remote) in the configuration file:
|
||||
|
||||
```toml
|
||||
[remote.gitea]
|
||||
owner = "orhun"
|
||||
repo = "git-cliff"
|
||||
token = "***"
|
||||
```
|
||||
|
||||
- Use the `--gitea-repo` argument (takes values in `OWNER/REPO` format, e.g. "orhun/git-cliff")
|
||||
|
||||
- Use the `GITEA_REPO` environment variable (same format as `--gitea-repo`)
|
||||
|
||||
## Authentication
|
||||
|
||||
:::tip
|
||||
|
||||
[Gitea REST API](https://gitea.com/api/swagger) is being used to retrieve data from Gitea.
|
||||
It does not require authentication for public repositories. If your project uses a private
|
||||
repository, you need to create an access token under *Settings* > *Applications* > *Access tokens*.
|
||||
|
||||
:::
|
||||
|
||||
To set an access token, you can use the [configuration file](/docs/configuration/remote) (not recommended), `--gitea-token` argument or `GITEA_TOKEN` environment variable.
|
||||
|
||||
For example:
|
||||
|
||||
```bash
|
||||
GITEA_TOKEN="***" git cliff --gitea-repo "orhun/git-cliff"
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
You can use the `GITEA_API_URL` environment variable want to override the API URL. This is useful if you are using your own Gitea instance.
|
||||
|
||||
:::
|
||||
|
||||
## Templating
|
||||
|
||||
:::tip
|
||||
|
||||
See the [templating documentation](/docs/category/templating) for general information about how the template engine works.
|
||||
|
||||
:::
|
||||
|
||||
### Remote
|
||||
|
||||
You can use the following [context](/docs/templating/context) for adding the remote to the changelog:
|
||||
|
||||
```json
|
||||
{
|
||||
"gitea": {
|
||||
"owner": "orhun",
|
||||
"repo": "git-cliff"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```jinja2
|
||||
https://codeberg.org/{{ remote.gitea.owner }}/{{ remote.gitea.repo }}/commits/tag/{{ version }}
|
||||
```
|
||||
|
||||
### Commit authors
|
||||
|
||||
For each commit, Gitea related values are added as a nested object (named `gitea`) to the [template context](/docs/templating/context):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "8edec7fd50f703811d55f14a3c5f0fd02b43d9e7",
|
||||
"message": "refactor(config): remove unnecessary newline from configs\n",
|
||||
"group": "🚜 Refactor",
|
||||
|
||||
"...": "<strip>",
|
||||
|
||||
"gitea": {
|
||||
"username": "orhun",
|
||||
"pr_title": "some things have changed",
|
||||
"pr_number": 420,
|
||||
"pr_labels": ["rust"],
|
||||
"is_first_time": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This can be used in the template as follows:
|
||||
|
||||
```
|
||||
{% for commit in commits %}
|
||||
* {{ commit.message | split(pat="\n") | first | trim }}\
|
||||
{% if commit.gitea.username %} by @{{ commit.gitea.username }}{%- endif %}\
|
||||
{% if commit.gitea.pr_number %} in #{{ commit.gitea.pr_number }}{%- endif %}
|
||||
{%- endfor -%}
|
||||
```
|
||||
|
||||
The will result in:
|
||||
|
||||
```md
|
||||
- feat(commit): add merge_commit flag to the context by @orhun in #389
|
||||
- feat(args): set `CHANGELOG.md` as default missing value for output option by @sh-cho in #354
|
||||
```
|
||||
|
||||
### Contributors
|
||||
|
||||
For each release, following contributors data is added to the [template context](/docs/templating/context) as a nested object:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "v1.4.0",
|
||||
"commits": [],
|
||||
"commit_id": "0af9eb24888d1a8c9b2887fbe5427985582a0f26",
|
||||
"timestamp": 0,
|
||||
"previous": null,
|
||||
"gitea": {
|
||||
"contributors": [
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This can be used in the template as follows:
|
||||
|
||||
```
|
||||
{% for contributor in gitea.contributors | filter(attribute="is_first_time", value=true) %}
|
||||
* @{{ contributor.username }} made their first contribution in #{{ contributor.pr_number }}
|
||||
{%- endfor -%}
|
||||
```
|
||||
|
||||
The will result in:
|
||||
|
||||
```md
|
||||
- @orhun made their first contribution in #420
|
||||
- @cliffjumper made their first contribution in #999
|
||||
```
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# Python 🐍
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# Rust/Cargo 🦀
|
||||
|
Loading…
Reference in New Issue
Block a user