Skip to content

Commit 078f7fa

Browse files
Alex Holmbergclaude
authored andcommitted
feat(42-01): add deployment types and API methods
Add deployment-related types (DeploymentConfig, TriggerDeploymentRequest, TriggerDeploymentResponse, DeploymentTaskStatus, DeployedService, PaginatedDeployments) and corresponding PlatformApiClient methods for: - list_deployment_configs - trigger_deployment - get_deployment_status - list_deployments Co-Authored-By: Claude <noreply@anthropic.com>
1 parent f259889 commit 078f7fa

3 files changed

Lines changed: 192 additions & 2 deletions

File tree

src/platform/api/client.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
//! organizations, projects, and other platform resources.
55
66
use super::error::{PlatformApiError, Result};
7-
use super::types::{ApiErrorResponse, CloudCredentialStatus, CloudProvider, Organization, Project, UserProfile};
7+
use super::types::{
8+
ApiErrorResponse, CloudCredentialStatus, CloudProvider, DeploymentConfig,
9+
DeploymentTaskStatus, GenericResponse, Organization, PaginatedDeployments, Project,
10+
TriggerDeploymentRequest, TriggerDeploymentResponse, UserProfile,
11+
};
812
use crate::auth::credentials;
913
use reqwest::Client;
1014
use serde::de::DeserializeOwned;
@@ -274,6 +278,65 @@ impl PlatformApiClient {
274278
);
275279
self.get_optional(&path).await
276280
}
281+
282+
// =========================================================================
283+
// Deployment API methods
284+
// =========================================================================
285+
286+
/// List deployment configurations for a project
287+
///
288+
/// Returns all deployment configs associated with the project, including
289+
/// service name, branch, target type, and auto-deploy settings.
290+
///
291+
/// Endpoint: GET /api/projects/:projectId/deployment-configs
292+
pub async fn list_deployment_configs(&self, project_id: &str) -> Result<Vec<DeploymentConfig>> {
293+
let response: GenericResponse<Vec<DeploymentConfig>> = self
294+
.get(&format!("/api/projects/{}/deployment-configs", project_id))
295+
.await?;
296+
Ok(response.data)
297+
}
298+
299+
/// Trigger a deployment using a deployment config
300+
///
301+
/// Starts a new deployment for the specified config. Optionally specify
302+
/// a commit SHA to deploy a specific version.
303+
///
304+
/// Endpoint: POST /api/deployment-configs/deploy
305+
pub async fn trigger_deployment(
306+
&self,
307+
request: &TriggerDeploymentRequest,
308+
) -> Result<TriggerDeploymentResponse> {
309+
self.post("/api/deployment-configs/deploy", request).await
310+
}
311+
312+
/// Get deployment task status
313+
///
314+
/// Returns the current status of a deployment task, including progress
315+
/// percentage, current step, and overall status.
316+
///
317+
/// Endpoint: GET /api/deployments/task/:taskId
318+
pub async fn get_deployment_status(&self, task_id: &str) -> Result<DeploymentTaskStatus> {
319+
self.get(&format!("/api/deployments/task/{}", task_id))
320+
.await
321+
}
322+
323+
/// List deployments for a project
324+
///
325+
/// Returns a paginated list of deployments for the project, sorted by
326+
/// creation time (most recent first).
327+
///
328+
/// Endpoint: GET /api/deployments/project/:projectId
329+
pub async fn list_deployments(
330+
&self,
331+
project_id: &str,
332+
limit: Option<i32>,
333+
) -> Result<PaginatedDeployments> {
334+
let path = match limit {
335+
Some(l) => format!("/api/deployments/project/{}?limit={}", project_id, l),
336+
None => format!("/api/deployments/project/{}", project_id),
337+
};
338+
self.get(&path).await
339+
}
277340
}
278341

279342
/// Get the API URL based on environment

src/platform/api/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,8 @@ pub mod types;
2929
// Re-export commonly used items
3030
pub use client::PlatformApiClient;
3131
pub use error::{PlatformApiError, Result};
32-
pub use types::{CloudCredentialStatus, CloudProvider, Organization, Project, ProjectMember, UserProfile};
32+
pub use types::{
33+
CloudCredentialStatus, CloudProvider, DeployedService, DeploymentConfig, DeploymentTaskStatus,
34+
Organization, PaginatedDeployments, PaginationInfo, Project, ProjectMember,
35+
TriggerDeploymentRequest, TriggerDeploymentResponse, UserProfile,
36+
};

src/platform/api/types.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,129 @@ pub struct CloudCredentialStatus {
188188
// NOTE: Never include tokens/secrets here - this is intentionally minimal
189189
}
190190

191+
// =============================================================================
192+
// Deployment Types
193+
// =============================================================================
194+
195+
/// Deployment configuration for a service
196+
#[derive(Debug, Clone, Serialize, Deserialize)]
197+
#[serde(rename_all = "camelCase")]
198+
pub struct DeploymentConfig {
199+
/// Unique identifier for this deployment config
200+
pub id: String,
201+
/// The project this config belongs to
202+
pub project_id: String,
203+
/// Repository ID (from GitHub/GitLab integration)
204+
pub repository_id: i64,
205+
/// Full repository name (e.g., "owner/repo")
206+
pub repository_full_name: String,
207+
/// Name of the service being deployed
208+
pub service_name: String,
209+
/// Environment ID for deployment
210+
pub environment_id: String,
211+
/// Target type: "kubernetes" or "cloud_runner"
212+
pub target_type: Option<String>,
213+
/// Branch to deploy from
214+
pub branch: String,
215+
/// Port the service listens on
216+
pub port: i32,
217+
/// Whether auto-deploy on push is enabled
218+
pub auto_deploy_enabled: bool,
219+
/// Deployment strategy (e.g., "rolling", "blue_green")
220+
pub deployment_strategy: Option<String>,
221+
/// When this config was created
222+
pub created_at: DateTime<Utc>,
223+
}
224+
225+
/// Request to trigger deployment
226+
#[derive(Debug, Clone, Serialize)]
227+
#[serde(rename_all = "camelCase")]
228+
pub struct TriggerDeploymentRequest {
229+
/// Project ID for the deployment
230+
pub project_id: String,
231+
/// Deployment config ID to use
232+
pub config_id: String,
233+
/// Optional specific commit SHA to deploy (defaults to latest)
234+
#[serde(skip_serializing_if = "Option::is_none")]
235+
pub commit_sha: Option<String>,
236+
}
237+
238+
/// Response from triggering a deployment
239+
#[derive(Debug, Clone, Deserialize)]
240+
#[serde(rename_all = "camelCase")]
241+
pub struct TriggerDeploymentResponse {
242+
/// The deployment config ID used
243+
pub config_id: String,
244+
/// Task ID to track deployment progress
245+
pub backstage_task_id: String,
246+
/// Initial status of the deployment
247+
pub status: String,
248+
/// Human-readable message about the deployment
249+
pub message: String,
250+
}
251+
252+
/// Deployment task status
253+
#[derive(Debug, Clone, Deserialize)]
254+
#[serde(rename_all = "camelCase")]
255+
pub struct DeploymentTaskStatus {
256+
/// Task status: "processing", "completed", "failed"
257+
pub status: String,
258+
/// Progress percentage (0-100)
259+
pub progress: i32,
260+
/// Current step description
261+
pub current_step: Option<String>,
262+
/// Overall deployment status: "generating", "building", "deploying", "healthy", "failed"
263+
pub overall_status: String,
264+
/// Human-readable overall message
265+
pub overall_message: String,
266+
/// Error message if deployment failed
267+
pub error: Option<String>,
268+
}
269+
270+
/// Deployed service info
271+
#[derive(Debug, Clone, Deserialize)]
272+
#[serde(rename_all = "camelCase")]
273+
pub struct DeployedService {
274+
/// Unique deployment ID
275+
pub id: String,
276+
/// Project this deployment belongs to
277+
pub project_id: String,
278+
/// Name of the deployed service
279+
pub service_name: String,
280+
/// Full repository name
281+
pub repository_full_name: String,
282+
/// Deployment status
283+
pub status: String,
284+
/// Task ID used for this deployment
285+
pub backstage_task_id: Option<String>,
286+
/// Commit SHA that was deployed
287+
pub commit_sha: Option<String>,
288+
/// Public URL of the deployed service
289+
pub public_url: Option<String>,
290+
/// When this deployment was created
291+
pub created_at: DateTime<Utc>,
292+
}
293+
294+
/// Paginated list of deployments
295+
#[derive(Debug, Clone, Deserialize)]
296+
#[serde(rename_all = "camelCase")]
297+
pub struct PaginatedDeployments {
298+
/// List of deployments
299+
pub data: Vec<DeployedService>,
300+
/// Pagination info
301+
pub pagination: PaginationInfo,
302+
}
303+
304+
/// Pagination information for list responses
305+
#[derive(Debug, Clone, Deserialize)]
306+
#[serde(rename_all = "camelCase")]
307+
pub struct PaginationInfo {
308+
/// Cursor for next page (if any)
309+
pub next_cursor: Option<String>,
310+
/// Whether there are more results
311+
pub has_more: bool,
312+
}
313+
191314
#[cfg(test)]
192315
mod tests {
193316
use super::*;

0 commit comments

Comments
 (0)