Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
test_build
*.code-workspace
.env
.claude/settings.local.json
5 changes: 4 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
## Project Purpose
- The goal of this repository is to create the wavedash cli, which helps game developers upload their assets to the site (similar to steams "steampipe" cli).
- The goal of this repository is to create the wavedash cli, which helps game developers upload their assets to the site (similar to steams "steampipe" cli).

## Development
- Environment variables are managed by Doppler. Always use `doppler run --` as a prefix when running cargo commands (build, check, clippy, run, test, etc.). For example: `doppler run -- cargo check`, `doppler run -- cargo clippy`.
43 changes: 25 additions & 18 deletions src/builds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,21 @@ struct TempCredsResponse {
}

async fn get_temp_credentials(
org_slug: &str,
game_slug: &str,
branch_slug: &str,
game_id: &str,
branch: &str,
engine: &str,
engine_version: &str,
entrypoint: Option<&str>,
message: Option<&str>,
version: &str,
api_key: &str,
) -> Result<TempCredsResponse> {
let client = config::create_http_client()?;
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/games/{}/branches/{}/builds/create-temp-r2-creds",
api_host, game_id, branch
);

let mut request_body = serde_json::json!({
Expand All @@ -73,6 +74,13 @@ async fn get_temp_credentials(
request_body["entrypoint"] = serde_json::json!(ep);
}

// Add build message if provided
if let Some(msg) = message {
request_body["buildMessage"] = serde_json::json!(msg);
}

request_body["version"] = serde_json::json!(version);

let response = client
.post(&url)
.header("Authorization", format!("Bearer {}", api_key))
Expand Down Expand Up @@ -101,18 +109,17 @@ async fn get_temp_credentials(
}

async fn notify_upload_complete(
org_slug: &str,
game_slug: &str,
branch_slug: &str,
game_id: &str,
branch: &str,
build_id: &str,
api_key: &str,
) -> Result<()> {
let client = config::create_http_client()?;
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/games/{}/branches/{}/builds/{}/upload-completed",
api_host, game_id, branch, build_id
);

let response = client
Expand Down Expand Up @@ -140,7 +147,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, verbose: bool, message: Option<String>) -> Result<()> {
// Load wavedash.toml config
let wavedash_config = WavedashConfig::load(&config_path)?;

Expand All @@ -167,12 +174,13 @@ 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.game_id,
&wavedash_config.branch,
engine_kind.as_config_key(),
wavedash_config.version()?,
wavedash_config.engine_version()?,
wavedash_config.entrypoint(),
message.as_deref(),
&wavedash_config.version,
&api_key,
)
.await?;
Expand All @@ -199,9 +207,8 @@ 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.game_id,
&wavedash_config.branch,
&creds.game_build_id,
&api_key,
)
Expand Down
8 changes: 4 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ pub struct CustomSection {

#[derive(Debug, Deserialize)]
pub struct WavedashConfig {
pub org_slug: String,
pub game_slug: String,
pub branch_slug: String,
pub game_id: String,
pub branch: String,
pub upload_dir: PathBuf,
pub version: String,

#[serde(rename = "godot")]
pub godot: Option<GodotSection>,
Expand Down Expand Up @@ -175,7 +175,7 @@ impl WavedashConfig {
}
}

pub fn version(&self) -> Result<&str> {
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 {
Expand Down
2 changes: 1 addition & 1 deletion src/dev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub async fn handle_dev(config_path: Option<PathBuf>, 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(),
Expand Down
8 changes: 4 additions & 4 deletions src/dev/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ pub fn build_sandbox_url(

// First, build the game URL (what will be the rdurl parameter)
// Local builds always use the sandbox environment for safety
let game_url_full = format!("{}/play/{}/sandbox", base, wavedash_config.game_slug);
let game_url_full = format!("{}/play/{}/sandbox", base, wavedash_config.game_id);
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_CLOUD_ID, &wavedash_config.org_slug);
pairs.append_pair(UrlParams::GAME_SUBDOMAIN, &wavedash_config.game_id);
pairs.append_pair(UrlParams::GAME_CLOUD_ID, &wavedash_config.game_id);
pairs.append_pair(UrlParams::LOCAL_ORIGIN, local_origin);
pairs.append_pair(UrlParams::LOCAL_BUILD, "true");
pairs.append_pair(UrlParams::ENGINE, engine_label);
Expand All @@ -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_id, main_host);
let permission_grant_url = format!("https://{}/sandbox/permission-grant", subdomain);

let mut url = Url::parse(&permission_grant_url)?;
Expand Down
6 changes: 4 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ enum BuildCommands {
default_value = "./wavedash.toml"
)]
config: PathBuf,
#[arg(short = 'm', long = "message", help = "Build message")]
message: Option<String>,
},
}

Expand Down Expand Up @@ -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, cli.verbose, message).await?;
}
},
Commands::Dev { config, no_open } => {
Expand Down