pub struct Generator { /* private fields */ }Expand description
Builder for a CI workflow document.
Methods are pure setters; configuration is committed only when
generate is called. Calling generate multiple
times against the same Generator returns byte-identical output.
§Example
use dev_ci::{Generator, PathDep, Target};
let yaml = Generator::new()
.target(Target::GitHubActions)
.workflow_name("CI")
.branches(["main", "release/*"])
.matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
.with_clippy()
.with_fmt()
.with_docs()
.with_msrv("1.85")
.with_no_default_features_build()
.with_all_features_build()
.with_path_dep(PathDep::new("dev-report", "https://github.com/jamesgober/dev-report.git"))
.generate();
assert!(yaml.contains("name: CI"));
assert!(yaml.contains("actions/checkout@v5"));Implementations§
Source§impl Generator
impl Generator
Sourcepub fn new() -> Self
pub fn new() -> Self
Begin a new generator with default settings.
Defaults: target = GitHubActions, workflow name = "CI",
branches = ["main"], matrix = ["ubuntu-latest"], cache
enabled, no extra jobs.
Examples found in repository?
More examples
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}16fn main() {
17 let yaml = Generator::new()
18 .with_clippy()
19 .with_fmt()
20 .with_docs()
21 .with_msrv("1.85")
22 .generate();
23
24 let target = std::env::var("DEV_CI_WRITE_TARGET")
25 .map(PathBuf::from)
26 .unwrap_or_else(|_| std::env::temp_dir().join("dev-ci-example/ci.yml"));
27
28 if let Some(parent) = target.parent() {
29 std::fs::create_dir_all(parent).expect("create parent dir");
30 }
31 std::fs::write(&target, yaml).expect("write yaml");
32 println!("wrote {}", target.display());
33}11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
15 .with_path_dep(PathDep::new(
16 "dev-report",
17 "https://github.com/jamesgober/dev-report.git",
18 ))
19 .with_path_dep(PathDep::new(
20 "dev-tools",
21 "https://github.com/jamesgober/dev-tools.git",
22 ))
23 .with_clippy()
24 .with_fmt()
25 .with_docs()
26 .with_msrv("1.85")
27 .generate();
28
29 println!("{yaml}");
30}Sourcepub fn target(self, target: Target) -> Self
pub fn target(self, target: Target) -> Self
Select the target CI platform.
Examples found in repository?
More examples
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
15 .with_path_dep(PathDep::new(
16 "dev-report",
17 "https://github.com/jamesgober/dev-report.git",
18 ))
19 .with_path_dep(PathDep::new(
20 "dev-tools",
21 "https://github.com/jamesgober/dev-tools.git",
22 ))
23 .with_clippy()
24 .with_fmt()
25 .with_docs()
26 .with_msrv("1.85")
27 .generate();
28
29 println!("{yaml}");
30}Sourcepub fn target_kind(&self) -> Target
pub fn target_kind(&self) -> Target
Selected target.
Sourcepub fn workflow_name(self, name: impl Into<String>) -> Self
pub fn workflow_name(self, name: impl Into<String>) -> Self
Set the workflow name: field. Defaults to "CI".
Examples found in repository?
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}Sourcepub fn branches<I, S>(self, branches: I) -> Self
pub fn branches<I, S>(self, branches: I) -> Self
Set the push / pull_request branch filter list.
Defaults to ["main"]. Glob patterns are passed through unchanged.
Examples found in repository?
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}Sourcepub fn matrix_os<I, S>(self, os_list: I) -> Self
pub fn matrix_os<I, S>(self, os_list: I) -> Self
Set the OS matrix for the test job. Defaults to a single
ubuntu-latest runner.
Common multi-OS configuration:
["ubuntu-latest", "macos-latest", "windows-latest"].
Examples found in repository?
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}More examples
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
15 .with_path_dep(PathDep::new(
16 "dev-report",
17 "https://github.com/jamesgober/dev-report.git",
18 ))
19 .with_path_dep(PathDep::new(
20 "dev-tools",
21 "https://github.com/jamesgober/dev-tools.git",
22 ))
23 .with_clippy()
24 .with_fmt()
25 .with_docs()
26 .with_msrv("1.85")
27 .generate();
28
29 println!("{yaml}");
30}Sourcepub fn with_cache(self, enabled: bool) -> Self
pub fn with_cache(self, enabled: bool) -> Self
Toggle the Swatinem/rust-cache@v2 action. Default: enabled.
Sourcepub fn with_workspace(self) -> Self
pub fn with_workspace(self) -> Self
Pass --workspace to every cargo invocation.
Examples found in repository?
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}Sourcepub fn features(self, features: impl Into<String>) -> Self
pub fn features(self, features: impl Into<String>) -> Self
Pass --features <list> to every cargo invocation.
Mutually exclusive with with_all_features_build
only in the sense that --all-features overrides --features
in cargo itself; the generator emits both flags as configured.
Sourcepub fn with_no_default_features_build(self) -> Self
pub fn with_no_default_features_build(self) -> Self
Emit an additional build step under the test job that passes
--no-default-features. Useful for crates with optional
features that should compile cleanly under the bare configuration.
Examples found in repository?
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}Sourcepub fn with_all_features_build(self) -> Self
pub fn with_all_features_build(self) -> Self
Emit an additional build + test step under the test job that
passes --all-features.
Examples found in repository?
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}Sourcepub fn with_path_dep(self, dep: PathDep) -> Self
pub fn with_path_dep(self, dep: PathDep) -> Self
Declare a sibling path-dependency that the workflow must
git clone into ../<name> before running cargo.
Matches the pattern the existing dev-* suite uses for its own
CI (each crate clones its siblings into ..). May be called
repeatedly.
Examples found in repository?
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
15 .with_path_dep(PathDep::new(
16 "dev-report",
17 "https://github.com/jamesgober/dev-report.git",
18 ))
19 .with_path_dep(PathDep::new(
20 "dev-tools",
21 "https://github.com/jamesgober/dev-tools.git",
22 ))
23 .with_clippy()
24 .with_fmt()
25 .with_docs()
26 .with_msrv("1.85")
27 .generate();
28
29 println!("{yaml}");
30}Sourcepub fn with_clippy(self) -> Self
pub fn with_clippy(self) -> Self
Include a clippy job.
Examples found in repository?
More examples
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}16fn main() {
17 let yaml = Generator::new()
18 .with_clippy()
19 .with_fmt()
20 .with_docs()
21 .with_msrv("1.85")
22 .generate();
23
24 let target = std::env::var("DEV_CI_WRITE_TARGET")
25 .map(PathBuf::from)
26 .unwrap_or_else(|_| std::env::temp_dir().join("dev-ci-example/ci.yml"));
27
28 if let Some(parent) = target.parent() {
29 std::fs::create_dir_all(parent).expect("create parent dir");
30 }
31 std::fs::write(&target, yaml).expect("write yaml");
32 println!("wrote {}", target.display());
33}11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
15 .with_path_dep(PathDep::new(
16 "dev-report",
17 "https://github.com/jamesgober/dev-report.git",
18 ))
19 .with_path_dep(PathDep::new(
20 "dev-tools",
21 "https://github.com/jamesgober/dev-tools.git",
22 ))
23 .with_clippy()
24 .with_fmt()
25 .with_docs()
26 .with_msrv("1.85")
27 .generate();
28
29 println!("{yaml}");
30}Sourcepub fn with_fmt(self) -> Self
pub fn with_fmt(self) -> Self
Include a rustfmt-check job.
Examples found in repository?
More examples
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}16fn main() {
17 let yaml = Generator::new()
18 .with_clippy()
19 .with_fmt()
20 .with_docs()
21 .with_msrv("1.85")
22 .generate();
23
24 let target = std::env::var("DEV_CI_WRITE_TARGET")
25 .map(PathBuf::from)
26 .unwrap_or_else(|_| std::env::temp_dir().join("dev-ci-example/ci.yml"));
27
28 if let Some(parent) = target.parent() {
29 std::fs::create_dir_all(parent).expect("create parent dir");
30 }
31 std::fs::write(&target, yaml).expect("write yaml");
32 println!("wrote {}", target.display());
33}11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
15 .with_path_dep(PathDep::new(
16 "dev-report",
17 "https://github.com/jamesgober/dev-report.git",
18 ))
19 .with_path_dep(PathDep::new(
20 "dev-tools",
21 "https://github.com/jamesgober/dev-tools.git",
22 ))
23 .with_clippy()
24 .with_fmt()
25 .with_docs()
26 .with_msrv("1.85")
27 .generate();
28
29 println!("{yaml}");
30}Sourcepub fn with_docs(self) -> Self
pub fn with_docs(self) -> Self
Include a cargo doc job with RUSTDOCFLAGS="-D warnings".
Examples found in repository?
More examples
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}16fn main() {
17 let yaml = Generator::new()
18 .with_clippy()
19 .with_fmt()
20 .with_docs()
21 .with_msrv("1.85")
22 .generate();
23
24 let target = std::env::var("DEV_CI_WRITE_TARGET")
25 .map(PathBuf::from)
26 .unwrap_or_else(|_| std::env::temp_dir().join("dev-ci-example/ci.yml"));
27
28 if let Some(parent) = target.parent() {
29 std::fs::create_dir_all(parent).expect("create parent dir");
30 }
31 std::fs::write(&target, yaml).expect("write yaml");
32 println!("wrote {}", target.display());
33}11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
15 .with_path_dep(PathDep::new(
16 "dev-report",
17 "https://github.com/jamesgober/dev-report.git",
18 ))
19 .with_path_dep(PathDep::new(
20 "dev-tools",
21 "https://github.com/jamesgober/dev-tools.git",
22 ))
23 .with_clippy()
24 .with_fmt()
25 .with_docs()
26 .with_msrv("1.85")
27 .generate();
28
29 println!("{yaml}");
30}Sourcepub fn with_msrv(self, version: impl Into<String>) -> Self
pub fn with_msrv(self, version: impl Into<String>) -> Self
Include an MSRV job pinned to the given Rust version.
Examples found in repository?
More examples
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}16fn main() {
17 let yaml = Generator::new()
18 .with_clippy()
19 .with_fmt()
20 .with_docs()
21 .with_msrv("1.85")
22 .generate();
23
24 let target = std::env::var("DEV_CI_WRITE_TARGET")
25 .map(PathBuf::from)
26 .unwrap_or_else(|_| std::env::temp_dir().join("dev-ci-example/ci.yml"));
27
28 if let Some(parent) = target.parent() {
29 std::fs::create_dir_all(parent).expect("create parent dir");
30 }
31 std::fs::write(&target, yaml).expect("write yaml");
32 println!("wrote {}", target.display());
33}11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
15 .with_path_dep(PathDep::new(
16 "dev-report",
17 "https://github.com/jamesgober/dev-report.git",
18 ))
19 .with_path_dep(PathDep::new(
20 "dev-tools",
21 "https://github.com/jamesgober/dev-tools.git",
22 ))
23 .with_clippy()
24 .with_fmt()
25 .with_docs()
26 .with_msrv("1.85")
27 .generate();
28
29 println!("{yaml}");
30}Sourcepub fn generate(&self) -> String
pub fn generate(&self) -> String
Render the workflow document.
Output is byte-deterministic for a given configuration.
Examples found in repository?
More examples
11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .workflow_name("CI")
15 .branches(["main"])
16 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
17 .with_workspace()
18 .with_no_default_features_build()
19 .with_all_features_build()
20 .with_clippy()
21 .with_fmt()
22 .with_docs()
23 .with_msrv("1.85")
24 .generate();
25
26 println!("{yaml}");
27}16fn main() {
17 let yaml = Generator::new()
18 .with_clippy()
19 .with_fmt()
20 .with_docs()
21 .with_msrv("1.85")
22 .generate();
23
24 let target = std::env::var("DEV_CI_WRITE_TARGET")
25 .map(PathBuf::from)
26 .unwrap_or_else(|_| std::env::temp_dir().join("dev-ci-example/ci.yml"));
27
28 if let Some(parent) = target.parent() {
29 std::fs::create_dir_all(parent).expect("create parent dir");
30 }
31 std::fs::write(&target, yaml).expect("write yaml");
32 println!("wrote {}", target.display());
33}11fn main() {
12 let yaml = Generator::new()
13 .target(Target::GitHubActions)
14 .matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
15 .with_path_dep(PathDep::new(
16 "dev-report",
17 "https://github.com/jamesgober/dev-report.git",
18 ))
19 .with_path_dep(PathDep::new(
20 "dev-tools",
21 "https://github.com/jamesgober/dev-tools.git",
22 ))
23 .with_clippy()
24 .with_fmt()
25 .with_docs()
26 .with_msrv("1.85")
27 .generate();
28
29 println!("{yaml}");
30}