forge-guard 0.1.8

Pre-deployment smart contract auditing framework for Foundry
Documentation
//! `forge-guard ci` — generate CI/CD pipeline configurations.

use crate::ci::CiGenerator;

use super::CiArgs;
use anyhow::{Context, Result};
use colored::*;

/// Generate CI/CD pipeline configurations.
pub fn run(args: &CiArgs) -> Result<()> {
    let generator = CiGenerator::new(&args.platform);

    eprintln!("{}", "🔧 Forge Guard — CI/CD Generator".bold());
    eprintln!("   Platform: {}", args.platform.bold());

    // Generate the CI config
    let config = generator.generate(args.include_deploy)?;

    // Write to output directory
    let output_path = args.output.join(generator.filename());
    std::fs::create_dir_all(&args.output)?;

    if output_path.exists() && !args.overwrite {
        anyhow::bail!(
            "{} already exists. Use --overwrite to replace.",
            output_path.display()
        );
    }

    std::fs::write(&output_path, &config).context("Failed to write CI config")?;

    eprintln!(
        "{} CI config written to {}",
        "".green(),
        output_path.display()
    );
    println!("{}", config);

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ci_arg_defaults() {
        let args = CiArgs {
            shared: super::super::SharedFlags {
                chain: "ethereum".into(),
                project: std::path::PathBuf::from("."),
                json: false,
                markdown: false,
                html: false,
                strict: false,
                offline: false,
                production: false,
                report: false,
                parallelism: 4,
            },
            platform: "github".into(),
            output: std::path::PathBuf::from(".github/workflows"),
            include_deploy: false,
            overwrite: false,
        };
        assert_eq!(args.platform, "github");
        assert_eq!(args.output, std::path::PathBuf::from(".github/workflows"));
        assert!(!args.include_deploy);
        assert!(!args.overwrite);
    }

    #[test]
    fn test_ci_generator_can_create_instances() {
        let gen = CiGenerator::new("github");
        assert_eq!(gen.filename(), "audit.yml");
    }

    #[test]
    fn test_ci_generator_gitlab_filename() {
        let gen = CiGenerator::new("gitlab");
        assert_eq!(gen.filename(), ".gitlab-ci.yml");
    }

    #[test]
    fn test_ci_generator_unsupported_platform_errs() {
        let gen = CiGenerator::new("circleci");
        let result = gen.generate(false);
        assert!(result.is_err());
    }
}