Skip to content
Closed
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
41 changes: 41 additions & 0 deletions rust/src/application/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,18 @@ impl ApplicationClient {
.await
}

pub async fn activate_release(
&self,
application_id: &str,
release_id: &str,
) -> Result<Value, ClientError> {
self.query(json!({
"query": "mutation ActivateRelease($applicationId: ID!, $releaseId: ID!) { activateRelease(applicationId: $applicationId, releaseId: $releaseId) { id version description status activatedAt createdAt updatedAt } }",
"variables": { "applicationId": application_id, "releaseId": release_id }
}))
.await
}

pub async fn enable_application(&self, input: Value) -> Result<Value, ClientError> {
self.query(json!({
"query": "mutation EnableApplication($input: MutationEnableStoreApplicationInput!) { enableStoreApplication(input: $input) { id } }",
Expand Down Expand Up @@ -243,4 +255,33 @@ mod tests {
// may point the default at an http:// local proxy).
assert!(url.contains("://"), "{url:?}");
}

#[tokio::test]
async fn activate_release_sends_ids_and_returns_data() {
use httpmock::prelude::*;
use serde_json::json;

let server = MockServer::start();
let mock = server.mock(|when, then| {
when.method(POST)
.path("/v1/apps/app-registry-subgraph")
.body_contains("activateRelease")
.body_contains("app-1")
.body_contains("rel-9");
then.status(200).header("content-type", "application/json").json_body(json!({
"data": { "activateRelease": { "id": "rel-9", "version": "1.0.0", "status": "ACTIVE" } }
}));
});

let client = super::ApplicationClient::new(server.base_url(), "test-token");
let data = client
.activate_release("app-1", "rel-9")
.await
.expect("activate_release should succeed");

// The mutation was sent with both IDs, and the response data is returned.
mock.assert();
assert_eq!(data["activateRelease"]["status"], "ACTIVE");
assert_eq!(data["activateRelease"]["id"], "rel-9");
}
}
28 changes: 27 additions & 1 deletion rust/src/application/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -817,8 +817,34 @@ fn deploy_command() -> RuntimeCommandSpec {
.await?;
}

// Activate the release, then set the application ACTIVE. This runs
// regardless of extension count — without it the app stays INACTIVE
// and can't be enabled, so a deploy that only uploads artifacts is
// effectively a no-op. (Parity with the TS deploy flow / PR #77.)
sender
.send(json!({ "type": "step", "name": "deploy", "status": "completed", "name": name, "extensions": total }))
.send(json!({ "type": "step", "name": "release.activate", "status": "started", "releaseId": release_id }))
.await;
client
.activate_release(&application_id, &release_id)
.await
.map_err(client_err)?;
sender
.send(json!({ "type": "step", "name": "release.activate", "status": "completed", "releaseId": release_id }))
.await;

sender
.send(json!({ "type": "step", "name": "application.activate", "status": "started", "id": application_id }))
.await;
client
.update_application(&application_id, json!({ "status": "ACTIVE" }))
.await
.map_err(client_err)?;
sender
.send(json!({ "type": "step", "name": "application.activate", "status": "completed", "id": application_id }))
.await;

sender
.send(json!({ "type": "step", "name": "deploy", "status": "completed", "name": name, "extensions": total, "status_after": "ACTIVE" }))
.await;
Ok(())
},
Expand Down