* Add default workspace URL

* R1 WIP

* Improve help docs slightly

* Rework tracking state

* WIP Rework
Remaining bug: Not returning state-only files (no local file) from *getFiles()

* Create newly found files

* Finish ZIP & new tracking code

* Fix two minor bugs

* do not consider conflict if same content

* add more logs to cli writing

* progress

* progress

* iteration

* Add most basic App support

* fix folder frontend bug

* fix folder frontend bug

* init done by default

* sqlx merge

---------

Co-authored-by: Ruben Fiszel <ruben@rubenfiszel.com>
This commit is contained in:
Kai Jellinghaus
2023-02-21 10:13:21 +01:00
committed by GitHub
parent 7cee6e498d
commit 908e7e5ba2
15 changed files with 586 additions and 227 deletions

View File

@@ -9,6 +9,7 @@
use std::str::FromStr;
use crate::{
apps::AppWithLastVersion,
db::{UserDB, DB},
folders::Folder,
resources::{Resource, ResourceType},
@@ -24,6 +25,7 @@ use axum::{
routing::{delete, get, post},
Json, Router,
};
use serde_json::to_string_pretty;
use stripe::CustomerId;
use windmill_audit::{audit_log, ActionKind};
use windmill_common::{
@@ -1098,6 +1100,28 @@ struct ArchiveQueryParams {
archive_type: Option<String>,
}
#[inline]
pub fn to_string_without_metadata<T>(value: &T) -> Result<String>
where
T: ?Sized + Serialize,
{
let value = serde_json::to_value(value).map_err(to_anyhow)?;
value
.as_object()
.map(|obj| {
let mut obj = obj.clone();
for key in ["workspace_id", "path", "name"] {
if obj.contains_key(key) {
obj.remove(key);
}
}
serde_json::to_string_pretty(&obj).ok()
})
.flatten()
.ok_or_else(|| Error::BadRequest("Impossible to serialize value".to_string()))
}
async fn tarball_workspace(
authed: Authed,
Extension(db): Extension<DB>,
@@ -1129,7 +1153,7 @@ async fn tarball_workspace(
for folder in folders {
archive
.write_to_archive(
&serde_json::to_string_pretty(&folder).unwrap(),
&to_string_without_metadata(&folder).unwrap(),
&format!("f/{}/folder.meta.json", folder.name),
)
.await?;
@@ -1187,7 +1211,7 @@ async fn tarball_workspace(
.await?;
for resource in resources {
let resource_str = serde_json::to_string_pretty(&resource).unwrap();
let resource_str = &to_string_without_metadata(&resource).unwrap();
archive
.write_to_archive(&resource_str, &format!("{}.resource.json", resource.path))
.await?;
@@ -1204,7 +1228,7 @@ async fn tarball_workspace(
.await?;
for resource_type in resource_types {
let resource_str = serde_json::to_string_pretty(&resource_type).unwrap();
let resource_str = &to_string_without_metadata(&resource_type).unwrap();
archive
.write_to_archive(
&resource_str,
@@ -1223,7 +1247,7 @@ async fn tarball_workspace(
.await?;
for flow in flows {
let flow_str = serde_json::to_string_pretty(&flow).unwrap();
let flow_str = &to_string_without_metadata(&flow).unwrap();
archive
.write_to_archive(&flow_str, &format!("{}.flow.json", flow.path))
.await?;
@@ -1232,19 +1256,39 @@ async fn tarball_workspace(
{
let variables = sqlx::query_as::<_, ExportableListableVariable>(
"SELECT *, false as is_expired FROM variable WHERE workspace_id = $1 AND is_secret = false",
"SELECT *, false as is_expired FROM variable WHERE workspace_id = $1",
)
.bind(&w_id)
.fetch_all(&db)
.await?;
for var in variables {
let flow_str = serde_json::to_string_pretty(&var).unwrap();
let flow_str = &to_string_without_metadata(&var).unwrap();
archive
.write_to_archive(&flow_str, &format!("{}.variable.json", var.path))
.await?;
}
}
{
let apps = sqlx::query_as!(
AppWithLastVersion,
"SELECT app.id, app.path, app.summary, app.versions, app.policy,
app.extra_perms, app_version.value,
app_version.created_at, app_version.created_by from app, app_version
WHERE app.workspace_id = $1 AND app_version.id = app.versions[array_upper(app.versions, 1)]",
&w_id
)
.fetch_all(&db)
.await?;
for app in apps {
let flow_str = &to_string_pretty(&app).unwrap();
archive
.write_to_archive(&flow_str, &format!("{}.app.json", app.path))
.await?;
}
}
archive.finish().await?;
let file = tokio::fs::File::open(file_path).await?;