From c3ba590b8f5f07b1b2c7c77cb75c81d87ef30578 Mon Sep 17 00:00:00 2001 From: Erik Chou Date: Tue, 27 Jan 2026 13:13:10 -0800 Subject: [PATCH 1/5] refactor(config): rename config fields and use environment enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update wavedash.toml config format: - org_slug → org - game_slug → game - branch_slug → environment (enum: production, demo, sandbox) Also update: - API endpoint URLs to use /environments/ instead of /branches/ - URL param from gbrslug to genv New config format: ```toml org = "my-org" game = "my-game" environment = "production" upload_dir = "./builds/webgl" ``` Co-Authored-By: Claude Sonnet 4.5 --- src/builds.rs | 32 ++++++++++++++++---------------- src/config.rs | 31 ++++++++++++++++++++++++++++--- src/dev/sandbox.rs | 10 +++++----- src/dev/url_params.rs | 2 +- 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/builds.rs b/src/builds.rs index 65a8727..3ca0dc5 100644 --- a/src/builds.rs +++ b/src/builds.rs @@ -47,9 +47,9 @@ struct TempCredsResponse { } async fn get_temp_credentials( - org_slug: &str, - game_slug: &str, - branch_slug: &str, + org: &str, + game: &str, + environment: &str, engine: &str, engine_version: &str, entrypoint: Option<&str>, @@ -59,8 +59,8 @@ async fn get_temp_credentials( let api_host = config::get("api_host")?; let url = format!( - "{}/api/organizations/{}/games/{}/branches/{}/builds/create-temp-r2-creds", - api_host, org_slug, game_slug, branch_slug + "{}/api/organizations/{}/games/{}/environments/{}/builds/create-temp-r2-creds", + api_host, org, game, environment ); let mut request_body = serde_json::json!({ @@ -101,9 +101,9 @@ async fn get_temp_credentials( } async fn notify_upload_complete( - org_slug: &str, - game_slug: &str, - branch_slug: &str, + org: &str, + game: &str, + environment: &str, build_id: &str, api_key: &str, ) -> Result<()> { @@ -111,8 +111,8 @@ async fn notify_upload_complete( let api_host = config::get("api_host")?; let url = format!( - "{}/api/organizations/{}/games/{}/branches/{}/builds/{}/upload-completed", - api_host, org_slug, game_slug, branch_slug, build_id + "{}/api/organizations/{}/games/{}/environments/{}/builds/{}/upload-completed", + api_host, org, game, environment, build_id ); let response = client @@ -167,9 +167,9 @@ pub async fn handle_build_push(config_path: PathBuf, verbose: bool) -> Result<() // Get temporary R2 credentials let engine_kind = wavedash_config.engine_type()?; let creds = get_temp_credentials( - &wavedash_config.org_slug, - &wavedash_config.game_slug, - &wavedash_config.branch_slug, + &wavedash_config.org, + &wavedash_config.game, + wavedash_config.environment.as_str(), engine_kind.as_config_key(), wavedash_config.version()?, wavedash_config.entrypoint(), @@ -199,9 +199,9 @@ pub async fn handle_build_push(config_path: PathBuf, verbose: bool) -> Result<() // Notify the server that upload is complete notify_upload_complete( - &wavedash_config.org_slug, - &wavedash_config.game_slug, - &wavedash_config.branch_slug, + &wavedash_config.org, + &wavedash_config.game, + wavedash_config.environment.as_str(), &creds.game_build_id, &api_key, ) diff --git a/src/config.rs b/src/config.rs index 0f78c2c..0dbb532 100644 --- a/src/config.rs +++ b/src/config.rs @@ -102,11 +102,36 @@ pub struct CustomSection { pub entrypoint: String, } +/// The cloud environment for the game build +#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum Environment { + Production, + Demo, + Sandbox, +} + +impl Environment { + pub fn as_str(&self) -> &'static str { + match self { + Environment::Production => "production", + Environment::Demo => "demo", + Environment::Sandbox => "sandbox", + } + } +} + +impl std::fmt::Display for Environment { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + #[derive(Debug, Deserialize)] pub struct WavedashConfig { - pub org_slug: String, - pub game_slug: String, - pub branch_slug: String, + pub org: String, + pub game: String, + pub environment: Environment, pub upload_dir: PathBuf, #[serde(rename = "godot")] diff --git a/src/dev/sandbox.rs b/src/dev/sandbox.rs index 4690fd5..bd803b5 100644 --- a/src/dev/sandbox.rs +++ b/src/dev/sandbox.rs @@ -18,15 +18,15 @@ pub fn build_sandbox_url( let base = host.trim_end_matches('/'); // First, build the game URL (what will be the rdurl parameter) - let game_url_full = format!("{}/play/{}", base, wavedash_config.game_slug); + let game_url_full = format!("{}/play/{}", base, wavedash_config.game); let mut game_url = Url::parse(&game_url_full) .with_context(|| format!("Unable to parse website host {}", game_url_full))?; { let mut pairs = game_url.query_pairs_mut(); - pairs.append_pair(UrlParams::GAME_SUBDOMAIN, &wavedash_config.game_slug); - pairs.append_pair(UrlParams::GAME_BRANCH_SLUG, &wavedash_config.branch_slug); - pairs.append_pair(UrlParams::GAME_CLOUD_ID, &wavedash_config.org_slug); + pairs.append_pair(UrlParams::GAME_SUBDOMAIN, &wavedash_config.game); + pairs.append_pair(UrlParams::GAME_ENVIRONMENT, wavedash_config.environment.as_str()); + pairs.append_pair(UrlParams::GAME_CLOUD_ID, &wavedash_config.org); pairs.append_pair(UrlParams::LOCAL_ORIGIN, local_origin); pairs.append_pair(UrlParams::SANDBOX, "true"); pairs.append_pair(UrlParams::ENGINE, engine_label); @@ -47,7 +47,7 @@ pub fn build_sandbox_url( let host_url = Url::parse(&format!("https://{}", base.trim_start_matches("https://").trim_start_matches("http://")))?; let main_host = host_url.host_str().ok_or_else(|| anyhow::anyhow!("Could not extract host"))?; - let subdomain = format!("{}.sandbox.{}", wavedash_config.game_slug, main_host); + let subdomain = format!("{}.sandbox.{}", wavedash_config.game, main_host); let permission_grant_url = format!("https://{}/sandbox/permission-grant", subdomain); let mut url = Url::parse(&permission_grant_url)?; diff --git a/src/dev/url_params.rs b/src/dev/url_params.rs index e48474a..34d2703 100644 --- a/src/dev/url_params.rs +++ b/src/dev/url_params.rs @@ -2,7 +2,7 @@ pub struct UrlParams; impl UrlParams { pub const GAME_SUBDOMAIN: &'static str = "gsdomain"; - pub const GAME_BRANCH_SLUG: &'static str = "gbrslug"; + pub const GAME_ENVIRONMENT: &'static str = "genv"; pub const GAME_CLOUD_ID: &'static str = "gcid"; pub const SANDBOX: &'static str = "sandbox"; pub const LOCAL_ORIGIN: &'static str = "localorigin"; From 54765e113dfecbb7b49736459c0c396c0416f9ca Mon Sep 17 00:00:00 2001 From: Erik Chou Date: Tue, 27 Jan 2026 13:20:46 -0800 Subject: [PATCH 2/5] feat(config): add deprecation warnings for legacy field names - Warn users when org_slug, game_slug, or branch_slug are used - Guide users to use new field names: org, game, environment Co-Authored-By: Claude Sonnet 4.5 --- src/config.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/config.rs b/src/config.rs index 0dbb532..8051390 100644 --- a/src/config.rs +++ b/src/config.rs @@ -111,6 +111,36 @@ pub enum Environment { Sandbox, } +/// Custom deserializer that handles both new environment values and legacy branch_slug values +fn deserialize_environment<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + let s = String::deserialize(deserializer)?; + + // Try direct environment values first + match s.as_str() { + "production" => return Ok(Environment::Production), + "demo" => return Ok(Environment::Demo), + "sandbox" => return Ok(Environment::Sandbox), + _ => {} + } + + // Legacy branch_slug mapping + if s.starts_with("internal") { + Ok(Environment::Sandbox) + } else if s.starts_with("production") { + Ok(Environment::Production) + } else if s.starts_with("demo") { + Ok(Environment::Demo) + } else { + Err(serde::de::Error::custom(format!( + "Invalid environment '{}'. Expected: production, demo, sandbox (or legacy: internal-*, production-*, demo-*)", + s + ))) + } +} + impl Environment { pub fn as_str(&self) -> &'static str { match self { @@ -129,9 +159,19 @@ impl std::fmt::Display for Environment { #[derive(Debug, Deserialize)] pub struct WavedashConfig { + /// Organization slug (supports legacy "org_slug" field) + #[serde(alias = "org_slug")] pub org: String, + + /// Game slug (supports legacy "game_slug" field) + #[serde(alias = "game_slug")] pub game: String, + + /// Environment (supports legacy "branch_slug" field for backwards compatibility) + /// Old branch_slug values are mapped: "internal-*" -> sandbox, "production-*" -> production, "demo-*" -> demo + #[serde(alias = "branch_slug", deserialize_with = "deserialize_environment")] pub environment: Environment, + pub upload_dir: PathBuf, #[serde(rename = "godot")] @@ -179,6 +219,23 @@ impl WavedashConfig { ) })?; + // Check for deprecated field names and warn users + let raw_toml: toml::Value = toml::from_str(&config_content) + .map_err(|e| anyhow::anyhow!("Failed to parse config file: {}", e))?; + + if let Some(table) = raw_toml.as_table() { + if table.contains_key("org_slug") { + eprintln!("WARNING: 'org_slug' is deprecated. Please use 'org' instead."); + } + if table.contains_key("game_slug") { + eprintln!("WARNING: 'game_slug' is deprecated. Please use 'game' instead."); + } + if table.contains_key("branch_slug") { + eprintln!("WARNING: 'branch_slug' is deprecated. Please use 'environment' instead."); + eprintln!(" Valid values: production, demo, sandbox"); + } + } + let config: WavedashConfig = toml::from_str(&config_content) .map_err(|e| anyhow::anyhow!("Failed to parse config file: {}", e))?; From 373d2b0732a9a797917976efab2012718eb83cba Mon Sep 17 00:00:00 2001 From: Erik Chou Date: Wed, 28 Jan 2026 12:47:15 -0800 Subject: [PATCH 3/5] feat: add semantic versioning support and remove legacy config - Add `version` field to wavedash.toml for semantic versioning (major.minor.patch) - Validate version format with regex - Send build version to API when pushing builds - Rename version() to engine_version() for clarity - Add get_build_version() method - Remove legacy field aliases (org_slug, game_slug, branch_slug) - Remove deprecated field warnings - Add regex dependency Co-Authored-By: Claude Sonnet 4.5 --- Cargo.lock | 39 +++++++++++++++++++++++++ Cargo.toml | 3 ++ src/builds.rs | 9 +++++- src/config.rs | 78 ++++++++++++++++---------------------------------- src/dev/mod.rs | 2 +- 5 files changed, 76 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1379939..ff3849a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -1720,6 +1729,35 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + [[package]] name = "reqsign" version = "0.16.5" @@ -3138,6 +3176,7 @@ dependencies = [ "open", "opendal", "rcgen", + "regex", "reqwest", "rustls", "semver", diff --git a/Cargo.toml b/Cargo.toml index 503c79a..23637cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,9 @@ toml = "0.8" # Error Handling anyhow = "1.0" +# Regex +regex = "1.10" + # Progress & UI indicatif = "0.17" diff --git a/src/builds.rs b/src/builds.rs index 3ca0dc5..f7addcd 100644 --- a/src/builds.rs +++ b/src/builds.rs @@ -52,6 +52,7 @@ async fn get_temp_credentials( environment: &str, engine: &str, engine_version: &str, + build_version: Option<&str>, entrypoint: Option<&str>, api_key: &str, ) -> Result { @@ -68,6 +69,11 @@ async fn get_temp_credentials( "engineVersion": engine_version }); + // Add build version if provided (semantic version: major.minor.patch) + if let Some(v) = build_version { + request_body["version"] = serde_json::json!(v); + } + // Add entrypoint if provided if let Some(ep) = entrypoint { request_body["entrypoint"] = serde_json::json!(ep); @@ -171,7 +177,8 @@ pub async fn handle_build_push(config_path: PathBuf, verbose: bool) -> Result<() &wavedash_config.game, wavedash_config.environment.as_str(), engine_kind.as_config_key(), - wavedash_config.version()?, + wavedash_config.engine_version()?, + wavedash_config.get_build_version(), wavedash_config.entrypoint(), &api_key, ) diff --git a/src/config.rs b/src/config.rs index 8051390..dd37f9c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ use anyhow::Result; use directories::BaseDirs; +use regex::Regex; use serde::Deserialize; use std::path::PathBuf; @@ -111,36 +112,6 @@ pub enum Environment { Sandbox, } -/// Custom deserializer that handles both new environment values and legacy branch_slug values -fn deserialize_environment<'de, D>(deserializer: D) -> Result -where - D: serde::Deserializer<'de>, -{ - let s = String::deserialize(deserializer)?; - - // Try direct environment values first - match s.as_str() { - "production" => return Ok(Environment::Production), - "demo" => return Ok(Environment::Demo), - "sandbox" => return Ok(Environment::Sandbox), - _ => {} - } - - // Legacy branch_slug mapping - if s.starts_with("internal") { - Ok(Environment::Sandbox) - } else if s.starts_with("production") { - Ok(Environment::Production) - } else if s.starts_with("demo") { - Ok(Environment::Demo) - } else { - Err(serde::de::Error::custom(format!( - "Invalid environment '{}'. Expected: production, demo, sandbox (or legacy: internal-*, production-*, demo-*)", - s - ))) - } -} - impl Environment { pub fn as_str(&self) -> &'static str { match self { @@ -159,19 +130,20 @@ impl std::fmt::Display for Environment { #[derive(Debug, Deserialize)] pub struct WavedashConfig { - /// Organization slug (supports legacy "org_slug" field) - #[serde(alias = "org_slug")] + /// Organization slug pub org: String, - /// Game slug (supports legacy "game_slug" field) - #[serde(alias = "game_slug")] + /// Game slug pub game: String, - /// Environment (supports legacy "branch_slug" field for backwards compatibility) - /// Old branch_slug values are mapped: "internal-*" -> sandbox, "production-*" -> production, "demo-*" -> demo - #[serde(alias = "branch_slug", deserialize_with = "deserialize_environment")] + /// Environment: production, demo, or sandbox pub environment: Environment, + /// Build version in semantic versioning format (major.minor.patch) + /// Example: "1.0.0", "2.1.3" + #[serde(rename = "version")] + pub build_version: Option, + pub upload_dir: PathBuf, #[serde(rename = "godot")] @@ -219,26 +191,20 @@ impl WavedashConfig { ) })?; - // Check for deprecated field names and warn users - let raw_toml: toml::Value = toml::from_str(&config_content) + let config: WavedashConfig = toml::from_str(&config_content) .map_err(|e| anyhow::anyhow!("Failed to parse config file: {}", e))?; - if let Some(table) = raw_toml.as_table() { - if table.contains_key("org_slug") { - eprintln!("WARNING: 'org_slug' is deprecated. Please use 'org' instead."); - } - if table.contains_key("game_slug") { - eprintln!("WARNING: 'game_slug' is deprecated. Please use 'game' instead."); - } - if table.contains_key("branch_slug") { - eprintln!("WARNING: 'branch_slug' is deprecated. Please use 'environment' instead."); - eprintln!(" Valid values: production, demo, sandbox"); + // Validate build_version format if provided + if let Some(ref version) = config.build_version { + let semver_regex = Regex::new(r"^\d+\.\d+\.\d+$").unwrap(); + if !semver_regex.is_match(version) { + anyhow::bail!( + "Invalid version '{}'. Must be in semantic version format: major.minor.patch (e.g., 1.0.0, 2.1.3)", + version + ); } } - let config: WavedashConfig = toml::from_str(&config_content) - .map_err(|e| anyhow::anyhow!("Failed to parse config file: {}", e))?; - Ok(config) } @@ -257,7 +223,8 @@ impl WavedashConfig { } } - pub fn version(&self) -> Result<&str> { + /// Get the engine version (e.g., Godot version, Unity version) + pub fn engine_version(&self) -> Result<&str> { if let Some(ref godot) = self.godot { Ok(&godot.version) } else if let Some(ref unity) = self.unity { @@ -269,6 +236,11 @@ impl WavedashConfig { } } + /// Get the build version (semantic version: major.minor.patch) + pub fn get_build_version(&self) -> Option<&str> { + self.build_version.as_deref() + } + pub fn entrypoint(&self) -> Option<&str> { self.custom.as_ref().map(|c| c.entrypoint.as_str()) } diff --git a/src/dev/mod.rs b/src/dev/mod.rs index 6224015..238ac9c 100644 --- a/src/dev/mod.rs +++ b/src/dev/mod.rs @@ -113,7 +113,7 @@ pub async fn handle_dev(config_path: Option, verbose: bool, no_open: bo let sandbox_url = build_sandbox_url( &wavedash_config, engine_label, - wavedash_config.version()?, + wavedash_config.engine_version()?, &local_origin, entrypoint.as_deref(), entrypoint_params.as_ref(), From fee89beb544a9254757c79b0d3d671b00c470210 Mon Sep 17 00:00:00 2001 From: Erik Chou Date: Wed, 28 Jan 2026 17:03:57 -0800 Subject: [PATCH 4/5] feat(config): make version field required The `version` field in wavedash.toml is now required instead of optional. This ensures all builds have a semantic version that can be matched to releases in the developer portal. - Change `build_version` from `Option` to `String` - Always include version in API request body - Update getter to return `&str` instead of `Option<&str>` Co-Authored-By: Claude Opus 4.5 --- src/builds.rs | 10 +++------- src/config.rs | 23 +++++++++++------------ 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/builds.rs b/src/builds.rs index f7addcd..65ee926 100644 --- a/src/builds.rs +++ b/src/builds.rs @@ -52,7 +52,7 @@ async fn get_temp_credentials( environment: &str, engine: &str, engine_version: &str, - build_version: Option<&str>, + build_version: &str, entrypoint: Option<&str>, api_key: &str, ) -> Result { @@ -66,14 +66,10 @@ async fn get_temp_credentials( let mut request_body = serde_json::json!({ "engine": engine, - "engineVersion": engine_version + "engineVersion": engine_version, + "version": build_version }); - // Add build version if provided (semantic version: major.minor.patch) - if let Some(v) = build_version { - request_body["version"] = serde_json::json!(v); - } - // Add entrypoint if provided if let Some(ep) = entrypoint { request_body["entrypoint"] = serde_json::json!(ep); diff --git a/src/config.rs b/src/config.rs index dd37f9c..de234e7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -141,8 +141,9 @@ pub struct WavedashConfig { /// Build version in semantic versioning format (major.minor.patch) /// Example: "1.0.0", "2.1.3" + /// Required - must match a release version to be selectable #[serde(rename = "version")] - pub build_version: Option, + pub build_version: String, pub upload_dir: PathBuf, @@ -194,15 +195,13 @@ impl WavedashConfig { let config: WavedashConfig = toml::from_str(&config_content) .map_err(|e| anyhow::anyhow!("Failed to parse config file: {}", e))?; - // Validate build_version format if provided - if let Some(ref version) = config.build_version { - let semver_regex = Regex::new(r"^\d+\.\d+\.\d+$").unwrap(); - if !semver_regex.is_match(version) { - anyhow::bail!( - "Invalid version '{}'. Must be in semantic version format: major.minor.patch (e.g., 1.0.0, 2.1.3)", - version - ); - } + // Validate build_version format (required, must be semver) + let semver_regex = Regex::new(r"^\d+\.\d+\.\d+$").unwrap(); + if !semver_regex.is_match(&config.build_version) { + anyhow::bail!( + "Invalid version '{}'. Must be in semantic version format: major.minor.patch (e.g., 1.0.0, 2.1.3)", + config.build_version + ); } Ok(config) @@ -237,8 +236,8 @@ impl WavedashConfig { } /// Get the build version (semantic version: major.minor.patch) - pub fn get_build_version(&self) -> Option<&str> { - self.build_version.as_deref() + pub fn get_build_version(&self) -> &str { + &self.build_version } pub fn entrypoint(&self) -> Option<&str> { From bd0de1aa3eabd356c84acfbf9a53a0be2272ff81 Mon Sep 17 00:00:00 2001 From: Erik Chou Date: Thu, 29 Jan 2026 07:25:44 -0800 Subject: [PATCH 5/5] feat(cli): add -m flag for build message Add support for passing a build message when pushing builds, similar to git commit -m. The message is stored with the build and can be displayed in the developer portal. Usage: wvdsh build push -m "Fixed player collision bug" Co-Authored-By: Claude Opus 4.5 --- src/builds.rs | 9 ++++++++- src/main.rs | 6 ++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/builds.rs b/src/builds.rs index 65ee926..fb685cc 100644 --- a/src/builds.rs +++ b/src/builds.rs @@ -54,6 +54,7 @@ async fn get_temp_credentials( engine_version: &str, build_version: &str, entrypoint: Option<&str>, + build_message: Option<&str>, api_key: &str, ) -> Result { let client = config::create_http_client()?; @@ -75,6 +76,11 @@ async fn get_temp_credentials( request_body["entrypoint"] = serde_json::json!(ep); } + // Add build message if provided + if let Some(msg) = build_message { + request_body["buildMessage"] = serde_json::json!(msg); + } + let response = client .post(&url) .header("Authorization", format!("Bearer {}", api_key)) @@ -142,7 +148,7 @@ async fn notify_upload_complete( Ok(()) } -pub async fn handle_build_push(config_path: PathBuf, verbose: bool) -> Result<()> { +pub async fn handle_build_push(config_path: PathBuf, message: Option, verbose: bool) -> Result<()> { // Load wavedash.toml config let wavedash_config = WavedashConfig::load(&config_path)?; @@ -176,6 +182,7 @@ pub async fn handle_build_push(config_path: PathBuf, verbose: bool) -> Result<() wavedash_config.engine_version()?, wavedash_config.get_build_version(), wavedash_config.entrypoint(), + message.as_deref(), &api_key, ) .await?; diff --git a/src/main.rs b/src/main.rs index 40ff81f..0bf30fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,6 +75,8 @@ enum BuildCommands { default_value = "./wavedash.toml" )] config: PathBuf, + #[arg(short = 'm', long = "message", help = "Build message (like a commit message)")] + message: Option, }, } @@ -144,8 +146,8 @@ async fn main() -> Result<()> { } } Commands::Build { action } => match action { - BuildCommands::Push { config } => { - handle_build_push(config, cli.verbose).await?; + BuildCommands::Push { config, message } => { + handle_build_push(config, message, cli.verbose).await?; } }, Commands::Dev { config, no_open } => {