From d56a143869c1ef5b970c59dcd61f4d83c7e16ef3 Mon Sep 17 00:00:00 2001 From: phil-accelbyte <225106921+phil-accelbyte@users.noreply.github.com> Date: Mon, 4 May 2026 22:51:27 +0800 Subject: [PATCH 1/3] chore(release): prepare v0.1.0-rc1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6abe2c..c8d466b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "accelbyte-ags-cli" -version = "0.1.0" +version = "0.1.0-rc1" dependencies = [ "anstream", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 18c22b2..2f0be8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "accelbyte-ags-cli" -version = "0.1.0" +version = "0.1.0-rc1" edition = "2021" description = "Unified CLI for AccelByte Gaming Services" license = "MIT" From ef015ba0730f2ea35bcadf27e7ae60e0965fa9bd Mon Sep 17 00:00:00 2001 From: phil-accelbyte <225106921+phil-accelbyte@users.noreply.github.com> Date: Mon, 4 May 2026 23:02:23 +0800 Subject: [PATCH 2/3] fix(ci): apply cargo fmt and drop redundant cargo-deny --config arg - Reformatted 8 files to satisfy cargo fmt --check on CI - deny.toml is cargo-deny's default config path, so the action's arguments: --config deny.toml line was both redundant and broken (the new cargo-deny CLI rejects --config before the subcommand) --- .github/workflows/ci.yml | 1 - src/invocation/commands/auth/mod.rs | 4 +- src/runtime/auth/locking.rs | 2 +- src/runtime/config/errors.rs | 2 +- src/runtime/config/store.rs | 4 +- src/runtime/dispatch/execute.rs | 11 ++- src/runtime/dispatch/http.rs | 5 +- src/runtime/execution.rs | 121 +++++++++++++--------------- src/support/strings.rs | 8 +- 9 files changed, 74 insertions(+), 84 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ba54d0..294c072 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,4 +68,3 @@ jobs: - uses: EmbarkStudios/cargo-deny-action@91bf2b620e09e18d6eb78b92e7861937469acedb # v2 with: command: check - arguments: --config deny.toml diff --git a/src/invocation/commands/auth/mod.rs b/src/invocation/commands/auth/mod.rs index f8f0332..735831c 100644 --- a/src/invocation/commands/auth/mod.rs +++ b/src/invocation/commands/auth/mod.rs @@ -320,9 +320,7 @@ async fn await_callback( let spinner_message = |remaining: u64| -> String { if remaining == 0 { - format!( - "Listening on http://127.0.0.1:{callback_port} for browser callback... waiting" - ) + format!("Listening on http://127.0.0.1:{callback_port} for browser callback... waiting") } else { format!( "Listening on http://127.0.0.1:{callback_port} for browser callback... {remaining}s remaining" diff --git a/src/runtime/auth/locking.rs b/src/runtime/auth/locking.rs index 0957d1f..6f560c0 100644 --- a/src/runtime/auth/locking.rs +++ b/src/runtime/auth/locking.rs @@ -84,7 +84,7 @@ fn lock_from_path(path: &std::path::Path) -> Result { message: e.to_string(), details: None, hint: None, - trace: None, + trace: None, }) } diff --git a/src/runtime/config/errors.rs b/src/runtime/config/errors.rs index 7e2973b..afbbe52 100644 --- a/src/runtime/config/errors.rs +++ b/src/runtime/config/errors.rs @@ -9,6 +9,6 @@ pub(crate) fn internal_error(message: impl Into) -> RuntimeError { message: message.into(), details: None, hint: None, - trace: None, + trace: None, } } diff --git a/src/runtime/config/store.rs b/src/runtime/config/store.rs index a7d5ad8..d2d78c7 100644 --- a/src/runtime/config/store.rs +++ b/src/runtime/config/store.rs @@ -392,7 +392,7 @@ pub fn validate_profile_name(name: &str) -> Result { message: "Profile name cannot be empty.".to_string(), details: None, hint: Some("Use a name like 'default', 'staging', or 'prod-us'.".to_string()), - trace: None, + trace: None, }); } let valid = normalised @@ -452,7 +452,7 @@ pub fn resolve_profile_name(flag: Option<&str>) -> Result "Run 'ags profile create ' and 'ags profile use ' to get started." .to_string(), ), - trace: None, + trace: None, }) } diff --git a/src/runtime/dispatch/execute.rs b/src/runtime/dispatch/execute.rs index 52e7524..c8d86de 100644 --- a/src/runtime/dispatch/execute.rs +++ b/src/runtime/dispatch/execute.rs @@ -248,16 +248,15 @@ pub(crate) async fn execute_operation( // the raw body as `errorMessage` so classify still produces the right // status-based message + suggestion (instead of falling back to a // bare "HTTP N error." with an empty Detail line). - let error_object = serde_json::from_str::(&body_text).unwrap_or_else( - |_| { + let error_object = + serde_json::from_str::(&body_text).unwrap_or_else(|_| { let cleaned = strip_terminal_control_sequences(&body_text); if cleaned.is_empty() { serde_json::Value::Null } else { serde_json::json!({ "errorMessage": cleaned }) } - }, - ); + }); let mut runtime_error = crate::runtime::dispatch::classify::classify_to_runtime_error( status, &error_object, @@ -305,14 +304,14 @@ fn map_cli_error_to_runtime_error(err: crate::errors::CliError) -> RuntimeError message, details: None, hint: None, - trace: None, + trace: None, }, other => RuntimeError { kind: RuntimeErrorKind::Internal, message: other.to_string(), details: None, hint: None, - trace: None, + trace: None, }, } } diff --git a/src/runtime/dispatch/http.rs b/src/runtime/dispatch/http.rs index 74ff59c..678e326 100644 --- a/src/runtime/dispatch/http.rs +++ b/src/runtime/dispatch/http.rs @@ -166,7 +166,7 @@ pub(crate) async fn read_response_body( message: "Response body is not valid UTF-8.".to_string(), details: None, hint: None, - trace: None, + trace: None, }) } @@ -193,8 +193,7 @@ pub(crate) async fn read_response_body_tagged( // no meaningful media type. Classifying them as Binary would route them // through the binary-output path and suppress the success summary and the // verbose request/response trace. - let is_text_body = - bytes.is_empty() || status >= 400 || is_text_content_type(&content_type); + let is_text_body = bytes.is_empty() || status >= 400 || is_text_content_type(&content_type); if is_text_body { return match String::from_utf8(bytes) { diff --git a/src/runtime/execution.rs b/src/runtime/execution.rs index 4a11f1f..8a716c4 100644 --- a/src/runtime/execution.rs +++ b/src/runtime/execution.rs @@ -173,71 +173,66 @@ impl ExecutionContext { access_token_source, access_token_expiry, access_token_warnings, - ) = - if input.is_dry_run { - let (url, source) = auth::credentials::resolve_base_url(&profile) - .map(|(url, source)| { - let mapped = match source { - auth::credentials::CredentialSource::Environment => { - BaseUrlSource::Environment - } - auth::credentials::CredentialSource::Configuration => { - BaseUrlSource::Configuration - } - auth::credentials::CredentialSource::Keystore => { - BaseUrlSource::Keystore - } - }; - (url, mapped) - }) - .unwrap_or(("https://".to_string(), BaseUrlSource::Default)); - ( - url, - source, - "dry-run-token".to_string(), - AccessTokenSource::DryRun, - None, - vec![], - ) - } else { - let (url, source) = auth::credentials::resolve_base_url(&profile) - .map(|(url, source)| { - let mapped = match source { - auth::credentials::CredentialSource::Environment => { - BaseUrlSource::Environment - } - auth::credentials::CredentialSource::Configuration => { - BaseUrlSource::Configuration - } - auth::credentials::CredentialSource::Keystore => { - BaseUrlSource::Keystore - } - }; - (url, mapped) - }) - .ok_or_else(|| RuntimeError::from(auth::errors::AuthError::BaseUrlMissing))?; + ) = if input.is_dry_run { + let (url, source) = auth::credentials::resolve_base_url(&profile) + .map(|(url, source)| { + let mapped = match source { + auth::credentials::CredentialSource::Environment => { + BaseUrlSource::Environment + } + auth::credentials::CredentialSource::Configuration => { + BaseUrlSource::Configuration + } + auth::credentials::CredentialSource::Keystore => BaseUrlSource::Keystore, + }; + (url, mapped) + }) + .unwrap_or(("https://".to_string(), BaseUrlSource::Default)); + ( + url, + source, + "dry-run-token".to_string(), + AccessTokenSource::DryRun, + None, + vec![], + ) + } else { + let (url, source) = auth::credentials::resolve_base_url(&profile) + .map(|(url, source)| { + let mapped = match source { + auth::credentials::CredentialSource::Environment => { + BaseUrlSource::Environment + } + auth::credentials::CredentialSource::Configuration => { + BaseUrlSource::Configuration + } + auth::credentials::CredentialSource::Keystore => BaseUrlSource::Keystore, + }; + (url, mapped) + }) + .ok_or_else(|| RuntimeError::from(auth::errors::AuthError::BaseUrlMissing))?; - let resolution = auth::session::resolve_access_token(http, &profile).await?; - let token_source = match resolution.source { - auth::session::TokenSource::Environment => AccessTokenSource::Environment, - auth::session::TokenSource::Stored => AccessTokenSource::Stored, - auth::session::TokenSource::Refreshed => AccessTokenSource::Refreshed, - auth::session::TokenSource::ClientCredentials => { - AccessTokenSource::ClientCredentials - } - }; - let expiry = resolution - .expires_in_secs - .map(crate::support::format_duration); - ( - url, - source, - resolution.token, - token_source, - expiry, - resolution.warnings, - ) + let resolution = auth::session::resolve_access_token(http, &profile).await?; + let token_source = match resolution.source { + auth::session::TokenSource::Environment => AccessTokenSource::Environment, + auth::session::TokenSource::Stored => AccessTokenSource::Stored, + auth::session::TokenSource::Refreshed => AccessTokenSource::Refreshed, + auth::session::TokenSource::ClientCredentials => { + AccessTokenSource::ClientCredentials + } }; + let expiry = resolution + .expires_in_secs + .map(crate::support::format_duration); + ( + url, + source, + resolution.token, + token_source, + expiry, + resolution.warnings, + ) + }; // Namespace resolution: input override -> env -> profile config. // Namespace is optional — missing namespace is not an error at this layer. diff --git a/src/support/strings.rs b/src/support/strings.rs index 0a8472a..cd8558c 100644 --- a/src/support/strings.rs +++ b/src/support/strings.rs @@ -224,7 +224,7 @@ pub fn encode_url_path_segment(value: &str, param_name: &str) -> Result Result Result Result Date: Mon, 4 May 2026 23:07:56 +0800 Subject: [PATCH 3/3] fix(clippy): convert sequential OR patterns to ranges Satisfies clippy::manual_range_patterns under -D warnings: - 31142|31143|31144 -> 31142..=31144 (entitlement not found) - 39142..=39148 (platform IAP config not found) --- src/runtime/dispatch/error_codes/platform.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/dispatch/error_codes/platform.rs b/src/runtime/dispatch/error_codes/platform.rs index 7ba95b7..447deb6 100644 --- a/src/runtime/dispatch/error_codes/platform.rs +++ b/src/runtime/dispatch/error_codes/platform.rs @@ -413,7 +413,7 @@ pub(super) fn lookup(error_code: i64) -> Option { suggestion: Some("Verify the entitlement ID and retry."), tip: None, }), - 31142 | 31143 | 31144 => Some(ErrorMapping { + 31142..=31144 => Some(ErrorMapping { message: "Entitlement not found.", reason: Some("No entitlement matches the supplied lookup key."), suggestion: Some("Verify the appId, SKU, or itemId and retry."), @@ -1057,7 +1057,7 @@ pub(super) fn lookup(error_code: i64) -> Option { suggestion: Some("Verify the transaction ID and product ID."), tip: None, }), - 39142 | 39143 | 39144 | 39145 | 39146 | 39147 | 39148 => Some(ErrorMapping { + 39142..=39148 => Some(ErrorMapping { message: "Platform IAP config not found in this namespace.", reason: Some("The platform's IAP configuration is missing."), suggestion: Some("Configure the platform IAP for this namespace."),