diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index d016a61976..fa372cc469 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -28424,6 +28424,13 @@ paths: description: folder scoping the Hub project source (`{workspace}:{folder}`) schema: type: string + - name: version + in: query + required: false + description: id of a reviewed project version to export instead of the current one (see the hub's `/projects/{slug}/versions`) + schema: + type: integer + minimum: 1 responses: "200": description: raw Hub response body (status code is passed through from the Hub) diff --git a/backend/windmill-api/src/hub_publish.rs b/backend/windmill-api/src/hub_publish.rs index 633ad88a34..4e79aba943 100644 --- a/backend/windmill-api/src/hub_publish.rs +++ b/backend/windmill-api/src/hub_publish.rs @@ -536,14 +536,26 @@ async fn publish_migrations( .await } +#[derive(Deserialize)] +struct ExportQuery { + version: Option, +} + // Export is owner-scoped only when re-exporting your own draft; approved -// projects are public, so the folder scope is optional here. +// projects are public, so the folder scope is optional here. `version` pins one +// reviewed version instead of the current one; it is forwarded explicitly because +// the hub request is rebuilt rather than proxied, so an unforwarded param would +// silently export the current version instead. async fn get_project_export( ctx: HubPublishCtx, Path((_workspace, slug)): Path<(String, ProjectSlug)>, + Query(query): Query, ) -> Result { - ctx.get_maybe_unscoped(&format!("/projects/{}/export", slug)) - .await + let path = match query.version { + Some(v) => format!("/projects/{}/export?version={}", slug, v), + None => format!("/projects/{}/export", slug), + }; + ctx.get_maybe_unscoped(&path).await } async fn get_project_by_source(ctx: HubPublishCtx) -> Result {