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

ci: Devops cli #3050

Closed
wants to merge 4 commits into from
Closed
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ VERSION
.env
.vscode/
vendor/
*.tmp
*.tmp
CHANGELOG-generated.md
28 changes: 28 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ members = [
"crates/cdk",
"crates/cargo-builder",
"connector/json-test-connector",
"connector/sink-test-connector"
"connector/sink-test-connector",
"release-tools/devops-cli",
]

exclude = ["smartmodule/regex-filter"]
Expand Down
26 changes: 13 additions & 13 deletions cliff.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# configuration file for git-cliff (0.1.0)

[changelog]
# changelog header
header = """
# Changelog\n
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n
"""
## changelog header
#header = """
## Changelog\n
#All notable changes to this project will be documented in this file.
#
#The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
#and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n
#"""
# template for the changelog body
# https://tera.netlify.app/docs/#introduction
body = """
Expand All @@ -27,9 +27,9 @@ body = """
# remove the leading and trailing whitespace from the template
trim = true
# changelog footer
footer = """
<!-- generated by git-cliff -->
"""
#footer = """
#<!-- generated by git-cliff -->
#"""

[git]
# parse the commits based on https://www.conventionalcommits.org
Expand Down Expand Up @@ -108,11 +108,11 @@ commit_parsers = [

]
# filter out the commits that are not matched by commit parsers
filter_commits = true
filter_commits = false
# glob pattern for matching git tags
tag_pattern = "v[0-9]*"
# regex for skipping tags
skip_tags = ".*-rc|.*-alpha|.*-beta"
#skip_tags = ".*-rc|.*-alpha|.*-beta"
# regex for ignoring tags
ignore_tags = ""
# sort the tags chronologically
Expand Down
21 changes: 21 additions & 0 deletions release-tools/devops-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "devops-cli"
version = "0.0.0"
edition = "2021"
publish = false

[dependencies]
anyhow = { workspace = true }
subprocess = "0.2"
semver = "1.0"
clap = { workspace = true , features = ["derive"] }
tracing-subscriber = { version ="0.3.16", features = ["env-filter"] }
tracing = "0.1"
strum = { version = "0.24", features = ["derive"] }

#strum_macros = "0.24"

serde = { version = "1.0.148", features = ["derive"] }
serde_json = "1.0.89"
#thiserror = "1.0.37"
#toml = "0.5"
142 changes: 142 additions & 0 deletions release-tools/devops-cli/src/changelog/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
use std::fs;
use std::path::PathBuf;

use anyhow::{Result};
use subprocess::{Exec, Redirection};
use semver::{Version, Prerelease, BuildMetadata};
use clap::Parser;
use tracing::info;

#[derive(Debug, Parser)]
pub struct UpdateChangelogOpt {
/// Path to git-cliff config
#[clap(long, default_value = "./cliff.toml")]
git_cliff_config: PathBuf,

/// Release version to use. Defaults to VERSION
#[clap(long)]
release_version: Option<String>,

/// Previous version to use. Defaults to previous stable patch version
#[clap(long)]
prev_version: Option<String>,

/// Git commit range start for git-cliff. Defaults to previous stable
#[clap(long)]
range_start: Option<String>,

/// Git commit range end for git-cliff. Defaults to HEAD
#[clap(long)]
range_end: Option<String>,

/// Target path to generated changelog
#[clap(long, default_value = "CHANGELOG-generated.md", group = "output")]
changelog_out: PathBuf,

/// Generate output as json to stdout
#[clap(long, action, group = "output")]
json: bool,

/// Print out debugging info
#[clap(long, action, group = "output")]
verbose: bool,
}

impl UpdateChangelogOpt {
pub fn execute(&self) -> Result<()> {
let version_str = self.get_target_version()?;
let version: Version = version_str.parse()?;
let previous_stable = self.get_previous_stable(&version)?;
let (range_start, range_end) = self.get_commit_range(&previous_stable);
let tag_range = format!("{range_start}..{range_end}");
let changelog_path: String = self.changelog_out.display().to_string();
let git_cliff_config = self.git_cliff_config.display().to_string();

let cmd = "git";
let mut args = vec![
"cliff",
"--config",
&git_cliff_config,
"--tag",
&version_str,
&tag_range,
];

if self.json {
args.push("--context")
} else {
args.push("-o");
args.push(&changelog_path);
}

// We want to be able to pipe json output to `jq`,
if self.verbose {
info!("Previous: v{previous_stable}");
info!("Current v{version}");
info!("Range: {tag_range}");
info!("Output file: {changelog_path}");
info!("Git-cliff config: {git_cliff_config}");

args.push("--verbose");
}

if !self.json {
info!("Generating changelog {tag_range}")
}

let stream = Exec::cmd(cmd)
.args(&args)
.stdout(Redirection::Pipe)
.stderr(Redirection::Merge)
.capture()?
.stdout_str();

println!("{stream}");

Ok(())
}

/// Return the release version of the previous patch release, unless `--prev-version` is used
fn get_previous_stable(&self, version: &Version) -> Result<Version> {
let previous_stable: Version = if let Some(prev) = &self.prev_version {
prev.parse()?
} else {
Version {
major: version.major,
minor: version.minor,
patch: version.patch - 1,
pre: Prerelease::EMPTY,
build: BuildMetadata::EMPTY,
}
};
Ok(previous_stable)
}

/// Read the version from VERSION file, unless `--release-version` used
fn get_target_version(&self) -> Result<String> {
let version_str: String = if let Some(v) = &self.release_version {
v.to_string()
} else {
fs::read_to_string("VERSION")?
};
Ok(version_str)
}

/// Returns range of `v<current-release - 1>..HEAD`,
/// unless we override with `--range-start` or `--range-end`
fn get_commit_range(&self, previous_stable: &Version) -> (String, String) {
let range_start = if let Some(start) = &self.range_start {
start.to_string()
} else {
format!("v{previous_stable}")
};

let range_end = if let Some(end) = &self.range_end {
end.to_string()
} else {
"HEAD".to_string()
};

(range_start, range_end)
}
}
45 changes: 45 additions & 0 deletions release-tools/devops-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
mod changelog;
use changelog::UpdateChangelogOpt;

mod repo_version;
use repo_version::UpdateVersionOpt;

use anyhow::{Result};
use clap::Parser;

use tracing_subscriber::filter::{EnvFilter, LevelFilter};

#[derive(Debug, Parser)]
struct FluvioDevOpsOpt {
#[clap(subcommand)]
command: FluvioDevOpsCmd,
}

#[derive(Debug, Parser)]
enum FluvioDevOpsCmd {
/// Generates the most recent changelog for the repo using `git cliff`.
UpdateChangelog(UpdateChangelogOpt),
/// Modify the version
UpdateVersion(UpdateVersionOpt),
}

fn main() -> Result<()> {
let _ = tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env().add_directive(LevelFilter::INFO.into()))
.try_init();

let opt = FluvioDevOpsOpt::parse();

opt.command.execute()?;

Ok(())
}

impl FluvioDevOpsCmd {
pub fn execute(&self) -> Result<()> {
match self {
Self::UpdateChangelog(update_changelog_opt) => update_changelog_opt.execute(),
Self::UpdateVersion(update_version_opt) => update_version_opt.execute(),
}
}
}
Loading