auths_cli/commands/
publish.rs1use anyhow::Result;
2use auths_sdk::registration::DEFAULT_REGISTRY_URL;
3use std::path::PathBuf;
4
5use crate::commands::artifact::publish::handle_publish;
6use crate::commands::executable::ExecutableCommand;
7use crate::config::CliConfig;
8
9#[derive(Debug, clap::Args)]
11#[command(
12 about = "Publish a signed artifact attestation to the Auths registry.",
13 after_help = "Examples:
14 auths publish package.tar.gz # Sign and publish
15 auths publish --signature package.tar.gz.auths.json # Publish existing signature
16 auths publish package.tar.gz --package npm:react@18.3.0
17
18Related:
19 auths sign — Sign an artifact without publishing
20 auths verify — Verify a signed artifact"
21)]
22pub struct PublishCommand {
23 #[arg(help = "Artifact file to sign and publish.")]
25 pub file: Option<PathBuf>,
26
27 #[arg(long, value_name = "PATH")]
29 pub signature: Option<PathBuf>,
30
31 #[arg(long)]
33 pub package: Option<String>,
34
35 #[arg(long, env = "AUTHS_REGISTRY_URL", default_value = DEFAULT_REGISTRY_URL)]
37 pub registry: String,
38}
39
40impl ExecutableCommand for PublishCommand {
41 fn execute(&self, ctx: &CliConfig) -> Result<()> {
42 let sig_path = match (&self.signature, &self.file) {
43 (Some(sig), _) => sig.clone(),
44 (None, Some(file)) => {
45 let mut p = file.clone();
46 p.set_file_name(format!(
47 "{}.auths.json",
48 p.file_name().unwrap_or_default().to_string_lossy()
49 ));
50 if !p.exists() {
51 crate::commands::artifact::sign::handle_sign(
52 file,
53 None,
54 None,
55 &crate::commands::key_detect::auto_detect_device_key(
56 ctx.repo_path.as_deref(),
57 &ctx.env_config,
58 )?,
59 None,
60 None,
61 crate::commands::git_helpers::resolve_head_silent(),
62 ctx.repo_path.clone(),
63 ctx.passphrase_provider.clone(),
64 &ctx.env_config,
65 &None,
66 false,
67 )?;
68 }
69 p
70 }
71 (None, None) => anyhow::bail!("Provide an artifact file or --signature path"),
72 };
73
74 handle_publish(&sig_path, self.package.as_deref(), &self.registry)
75 }
76}