chore: release versions by googleworkspace-bot · Pull Request #614 · googleworkspace/cli · GitHub
Skip to content

chore: release versions#614

Merged
jpoehnelt merged 1 commit into
mainfrom
changeset-release/main
Mar 24, 2026
Merged

chore: release versions#614
jpoehnelt merged 1 commit into
mainfrom
changeset-release/main

Conversation

@googleworkspace-bot

Copy link
Copy Markdown
Collaborator

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@googleworkspace/cli@0.21.0

Minor Changes

  • 029e5de: Extract google-workspace library crate for programmatic Rust API access (closes feat: expose minimal library crate for programmatic API access #386)

    Introduces a Cargo workspace with a new google-workspace library crate (crates/google-workspace/)
    that exposes the core modules for use as a Rust dependency:

    • discovery — Discovery Document types and fetching
    • error — Structured GwsError type
    • services — Service registry and resolution
    • validate — Input validation and URL encoding
    • client — HTTP client with retry logic

    The gws binary crate re-exports all library types transparently — zero behavioral changes.

@googleworkspace-bot googleworkspace-bot added area: docs cla: yes This human has signed the Contributor License Agreement. labels Mar 24, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

@jpoehnelt jpoehnelt merged commit eacd436 into main Mar 24, 2026
23 checks passed
@jpoehnelt jpoehnelt deleted the changeset-release/main branch March 24, 2026 20:44

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request extracts core modules into a new google-workspace library crate, enabling programmatic Rust API access, and updates the project version to 0.21.0. A critical issue was identified in the new client module's retry logic, where the final error might be incorrectly discarded, making debugging difficult. A refactoring suggestion has been provided to ensure the most relevant error is always returned.

Comment thread CHANGELOG.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The retry logic in the new client module has a flaw that could mask the true cause of persistent failures. In crates/google-workspace/src/client.rs, the send_with_retry function incorrectly prioritizes a previous transient error over the error from the final retry attempt.

Specifically, on line 80, Err(last_err.unwrap_or(e)) will return last_err if it exists, discarding the more relevant final error e. This makes debugging difficult.

I recommend refactoring the function to remove the last_err variable and ensure the error from the very last attempt is always returned. Here is a suggested implementation:

pub async fn send_with_retry(
    build_request: impl Fn() -> reqwest::RequestBuilder,
) -> Result<reqwest::Response, reqwest::Error> {
    for attempt in 0..MAX_RETRIES {
        match build_request().send().await {
            Ok(resp) => {
                if resp.status() != reqwest::StatusCode::TOO_MANY_REQUESTS {
                    return Ok(resp);
                }

                let header_value = resp
                    .headers()
                    .get("retry-after")
                    .and_then(|v| v.to_str().ok());
                let retry_after = compute_retry_delay(header_value, attempt);
                tokio::time::sleep(std::time::Duration::from_secs(retry_after)).await;
            }
            Err(e) if e.is_connect() || e.is_timeout() => {
                let delay = compute_retry_delay(None, attempt);
                tokio::time::sleep(std::time::Duration::from_secs(delay)).await;
            }
            Err(e) => return Err(e), // Non-retryable error
        }
    }

    // Final attempt
    build_request().send().await
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: docs cla: yes This human has signed the Contributor License Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: expose minimal library crate for programmatic API access

2 participants