release-tool 0.2.1

Configuration-driven release lifecycle for computed-parameter repositories
Documentation
use release_tool::config::{Config, PublisherConfig, TargetConfig};

#[test]
fn parses_target_and_publisher_adapters_without_duplicate_maven_coordinates() {
    let config = Config::parse(
        r#"
required_version = "0.1.0"

[repository]
github = "computed-parameter/sc-coordinator"
branch = "main"

[hooks]
preflight = ["just", "verify"]

[publishers.packages]
kind = "github_maven"
settings = ".mvn/settings.xml"
server_id = "github"

[[targets]]
name = "maven"
kind = "maven_reactor"
publisher = "packages"
default = true
wrapper = "./mvnw"
pom = "pom.xml"
projects = ["framework/java/coordinator-sdk", "jobs/cpe/cpe-job-model"]
also_make = true
remote_check = ["just", "_check-published-maven", "{version}"]
"#,
    )
    .unwrap();

    assert_eq!(config.hooks.preflight, vec!["just", "verify"]);
    assert!(matches!(
        config.publishers.get("packages"),
        Some(PublisherConfig::GithubMaven { server_id, .. }) if server_id == "github"
    ));
    assert!(matches!(
        &config.targets[0],
        TargetConfig::MavenReactor { projects, .. }
            if projects == &["framework/java/coordinator-sdk", "jobs/cpe/cpe-job-model"]
    ));
}

#[test]
fn command_hooks_must_be_argv_arrays() {
    let error = Config::parse(
        r#"
required_version = "0.1.0"

[repository]
github = "computed-parameter/example"
branch = "main"

[hooks]
preflight = "just verify && echo unsafe"
"#,
    )
    .unwrap_err();

    assert!(error.to_string().contains("config shape is invalid"));
}

#[test]
fn rejects_references_to_unknown_publishers_and_duplicate_target_names() {
    let error = Config::parse(
        r#"
required_version = "0.1.0"

[repository]
github = "computed-parameter/example"
branch = "main"

[publishers.release]
kind = "github_release"
title = "Example {version}"
prerelease = true

[[targets]]
name = "app"
kind = "docker_archive"
publisher = "missing"
default = true
platform = "linux/amd64"
image = "example:{version}"
asset = "example-{version}.tar.xz"
build = ["just", "build", "{image}"]
local_check = ["just", "check", "{image}"]

[[targets]]
name = "app"
kind = "docker_archive"
publisher = "release"
platform = "linux/amd64"
image = "example-other:{version}"
asset = "other-{version}.tar.xz"
build = ["just", "build", "{image}"]
local_check = ["just", "check", "{image}"]
"#,
    )
    .unwrap_err();

    assert!(error.to_string().contains("duplicate target name `app`"));
}

#[test]
fn rejects_incompatible_target_and_publisher_adapters() {
    let error = Config::parse(
        r#"required_version = "0.1.0"

[repository]
github = "computed-parameter/example"
branch = "main"

[publishers.packages]
kind = "github_maven"
settings = ".mvn/settings.xml"
server_id = "github"

[[targets]]
name = "app"
kind = "docker_archive"
publisher = "packages"
default = true
platform = "linux/amd64"
image = "example:{version}"
asset = "example-{version}.tar.xz"
build = ["just", "build", "{image}"]
local_check = ["just", "check", "{image}"]
"#,
    )
    .unwrap_err();

    assert!(
        error
            .to_string()
            .contains("target `app` is incompatible with publisher `packages`")
    );
}