use std::process::ExitCode;
use clap::Args;
use log::{debug, info};
use crate::model::changeset::Changeset;
use crate::model::config::Config;
use crate::package_manager::filter_projects_by_name;
use super::{PrepareArgs, PublishArgs, cmd_prepare, cmd_publish};
#[derive(Args, Default)]
pub struct CiArgs {
#[arg(short = 'p', long = "package")]
pub packages: Vec<String>,
#[arg(long)]
pub branch: Option<String>,
#[arg(long)]
pub no_git: bool,
}
pub(crate) async fn cmd_ci(
args: &CiArgs,
dry_run: bool,
env: &crate::Env,
config: Config,
) -> anyhow::Result<ExitCode> {
let git = env.git();
let changesets = Changeset::read_all(env).await?;
if !changesets.is_empty() {
info!("ci: pending changesets found, running prepare");
let prepare_args = PrepareArgs {
packages: args.packages.clone(),
no_git: args.no_git,
branch: args.branch.clone(),
};
return cmd_prepare(&prepare_args, dry_run, env, config).await;
}
if config.git.enabled() && !args.no_git {
let projects = config.load_projects(env).await?;
let selected = filter_projects_by_name(&projects, &args.packages)?;
let is_multi = projects.len() > 1;
let mut any_tag_missing = false;
for project in &selected {
if !env
.fs()
.exists(&project.path().child("CHANGELOG.md"))
.await?
{
debug!("skipping tag check for {}", project.name());
continue;
}
let version = project.version();
let tag = config.git.tag_format.tag(project.name(), version, is_multi);
if !git.tag_exists(&tag).await.unwrap_or(false) {
any_tag_missing = true;
break;
}
}
if any_tag_missing {
info!("ci: no changesets but unpublished tags detected, running publish");
let publish_args = PublishArgs {
packages: args.packages.clone(),
no_git: args.no_git,
};
return cmd_publish(&publish_args, dry_run, env, config).await;
}
}
info!("ci: nothing to do");
Ok(ExitCode::SUCCESS)
}