From 6777ed8f5d667e802aea7464254b8fc663e2e320 Mon Sep 17 00:00:00 2001 From: Zack Fu Zi Xiang Date: Wed, 25 Sep 2024 14:46:26 +0800 Subject: [PATCH 1/8] feat: add database listings --- libs/client-api/src/http_collab.rs | 19 +++++ libs/shared-entity/src/dto/workspace_dto.rs | 13 +++ src/api/workspace.rs | 18 ++++ src/biz/collab/ops.rs | 95 +++++++++++++++++++++ tests/workspace/workspace_crud.rs | 33 +++++++ 5 files changed, 178 insertions(+) diff --git a/libs/client-api/src/http_collab.rs b/libs/client-api/src/http_collab.rs index cdeb6f06..52106271 100644 --- a/libs/client-api/src/http_collab.rs +++ b/libs/client-api/src/http_collab.rs @@ -1,6 +1,7 @@ use crate::http::log_request_id; use crate::{blocking_brotli_compress, Client}; use app_error::AppError; +use client_api_entity::workspace_dto::AFDatabase; use client_api_entity::{ BatchQueryCollabParams, BatchQueryCollabResult, CreateCollabParams, DeleteCollabParams, QueryCollab, @@ -103,6 +104,7 @@ impl Client { .await? .into_data() } + #[instrument(level = "info", skip_all, err)] pub async fn delete_collab(&self, params: DeleteCollabParams) -> Result<(), AppResponseError> { let url = format!( @@ -118,4 +120,21 @@ impl Client { log_request_id(&resp); AppResponse::<()>::from_response(resp).await?.into_error() } + + #[instrument(level = "info", skip_all, err)] + pub async fn list_databases( + &self, + workspace_id: &str, + ) -> Result, AppResponseError> { + let url = format!("{}/api/workspace/{}/database", self.base_url, workspace_id); + let resp = self + .http_client_with_auth(Method::GET, &url) + .await? + .send() + .await?; + log_request_id(&resp); + AppResponse::from_response(resp) + .await? + .into_data() + } } diff --git a/libs/shared-entity/src/dto/workspace_dto.rs b/libs/shared-entity/src/dto/workspace_dto.rs index ff6d2c67..11ef9978 100644 --- a/libs/shared-entity/src/dto/workspace_dto.rs +++ b/libs/shared-entity/src/dto/workspace_dto.rs @@ -215,3 +215,16 @@ pub struct PublishedView { pub extra: Option, pub children: Vec, } + +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub struct AFDatabase { + pub id: String, + pub name: String, + pub fields: Vec, +} + +#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct AFDatabaseField { + pub name: String, + pub field_type: String, +} diff --git a/src/api/workspace.rs b/src/api/workspace.rs index d7e371a0..b0e12f8c 100644 --- a/src/api/workspace.rs +++ b/src/api/workspace.rs @@ -205,6 +205,7 @@ pub fn workspace_scope() -> Scope { // Web browser can't carry payload when using GET method, so for browser compatibility, we use POST method .route(web::post().to(batch_get_collab_handler)), ) + .service(web::resource("/{workspace_id}/database").route(web::get().to(list_database_handler))) } pub fn collab_scope() -> Scope { @@ -1450,6 +1451,23 @@ async fn get_workspace_publish_outline_handler( Ok(Json(AppResponse::Ok().with_data(published_view))) } +async fn list_database_handler( + user_uuid: UserUuid, + workspace_id: web::Path, + state: Data, +) -> Result>>> { + let uid = state.user_cache.get_user_uid(&user_uuid).await?; + let workspace_id = workspace_id.into_inner(); + let dbs = biz::collab::ops::list_database( + &state.pg_pool, + &state.collab_access_control_storage, + uid, + workspace_id, + ) + .await?; + Ok(Json(AppResponse::Ok().with_data(dbs))) +} + #[inline] async fn parser_realtime_msg( payload: Bytes, diff --git a/src/biz/collab/ops.rs b/src/biz/collab/ops.rs index f81dea24..ec345901 100644 --- a/src/biz/collab/ops.rs +++ b/src/biz/collab/ops.rs @@ -2,14 +2,22 @@ use std::sync::Arc; use app_error::AppError; use appflowy_collaborate::collab::storage::CollabAccessControlStorage; +use collab::preclude::Collab; +use collab_database::database::DatabaseBody; +use collab_database::entity::FieldType; +use collab_database::workspace_database::WorkspaceDatabaseBody; use collab_entity::CollabType; use collab_entity::EncodedCollab; use collab_folder::SectionItem; use collab_folder::{CollabOrigin, Folder}; +use database::collab::select_workspace_database_oid; use database::collab::{CollabStorage, GetCollabOrigin}; use database::publish::select_published_view_ids_for_workspace; use database::publish::select_workspace_id_for_publish_namespace; +use database_entity::dto::QueryCollabResult; use database_entity::dto::{QueryCollab, QueryCollabParams}; +use shared_entity::dto::workspace_dto::AFDatabase; +use shared_entity::dto::workspace_dto::AFDatabaseField; use sqlx::PgPool; use std::ops::DerefMut; @@ -347,3 +355,90 @@ pub async fn get_published_view( collab_folder_to_published_outline(&workspace_id.to_string(), &folder, &publish_view_ids)?; Ok(published_view) } + +pub async fn list_database( + pg_pool: &PgPool, + collab_storage: &Arc, + uid: i64, + workspace_uuid_str: String, +) -> Result, AppError> { + let workspace_uuid: Uuid = workspace_uuid_str.as_str().parse()?; + let ws_db_oid = select_workspace_database_oid(pg_pool, &workspace_uuid).await?; + + let ec = get_latest_collab_encoded( + collab_storage.clone(), + GetCollabOrigin::Server, + &workspace_uuid_str, + &ws_db_oid, + CollabType::WorkspaceDatabase, + ) + .await?; + let mut collab: Collab = + Collab::new_with_source(CollabOrigin::Server, &ws_db_oid, ec.into(), vec![], false).map_err( + |e| { + AppError::Internal(anyhow::anyhow!( + "Failed to create collab from encoded collab: {:?}", + e + )) + }, + )?; + + let ws_body = WorkspaceDatabaseBody::open(&mut collab); + let db_metas = ws_body.get_all_database_meta(&collab.transact()); + let query_collabs: Vec = db_metas + .into_iter() + .map(|meta| QueryCollab { + object_id: meta.database_id.clone(), + collab_type: CollabType::Database, + }) + .collect(); + let results = collab_storage.batch_get_collab(&uid, query_collabs).await; + + let txn = collab.transact(); + let mut af_databases: Vec = Vec::with_capacity(results.len()); + for (oid, result) in results { + match result { + QueryCollabResult::Success { encode_collab_v1 } => { + match EncodedCollab::decode_from_bytes(&encode_collab_v1) { + Ok(ec) => { + match Collab::new_with_source(CollabOrigin::Server, &oid, ec.into(), vec![], false) { + Ok(db_collab) => match DatabaseBody::from_collab(&db_collab) { + Some(db_body) => match db_body.metas.get_inline_view_id(&txn) { + Some(iid) => match db_body.views.get_view(&txn, &iid) { + Some(iview) => { + let name = iview.name; + + let db_fields = db_body.fields.get_all_fields(&txn); + let mut af_fields: Vec = Vec::with_capacity(db_fields.len()); + for db_field in db_fields { + af_fields.push(AFDatabaseField { + name: db_field.name, + field_type: format!("{:?}", FieldType::from(db_field.field_type)), + }); + } + af_databases.push(AFDatabase { + id: db_body.get_database_id(&txn), + name, + fields: af_fields, + }); + }, + None => tracing::warn!("Failed to get inline view: {}", iid), + }, + None => tracing::error!("Failed to get inline view id for database: {}", oid), + }, + None => tracing::error!("Failed to create db_body from db_collab, oid: {}", oid), + }, + Err(err) => tracing::error!("Failed to create db_collab: {:?}", err), + } + }, + Err(err) => tracing::error!("Failed to decode collab: {:?}", err), + } + }, + QueryCollabResult::Failed { error } => { + tracing::warn!("Failed to get collab: {:?}", error) + }, + } + } + + Ok(af_databases) +} diff --git a/tests/workspace/workspace_crud.rs b/tests/workspace/workspace_crud.rs index 5f484ae7..da1a668f 100644 --- a/tests/workspace/workspace_crud.rs +++ b/tests/workspace/workspace_crud.rs @@ -1,9 +1,42 @@ use client_api_test::generate_unique_registered_user_client; use collab_entity::CollabType; use database_entity::dto::QueryCollabParams; +use shared_entity::dto::workspace_dto::AFDatabaseField; use shared_entity::dto::workspace_dto::CreateWorkspaceParam; use shared_entity::dto::workspace_dto::PatchWorkspaceParam; +#[tokio::test] +async fn workspace_list_database() { + let (c, _user) = generate_unique_registered_user_client().await; + let workspace_id = c.get_workspaces().await.unwrap()[0].workspace_id; + let dbs = c.list_databases(&workspace_id.to_string()).await.unwrap(); + assert_eq!(dbs.len(), 1); + + let db = &dbs[0]; + + assert_eq!(db.name, "Untitled"); + assert!(db.fields.contains(&AFDatabaseField { + name: "Last modified".to_string(), + field_type: "LastEditedTime".to_string(), + })); + assert!(db.fields.contains(&AFDatabaseField { + name: "Multiselect".to_string(), + field_type: "MultiSelect".to_string(), + })); + assert!(db.fields.contains(&AFDatabaseField { + name: "Tasks".to_string(), + field_type: "Checklist".to_string(), + })); + assert!(db.fields.contains(&AFDatabaseField { + name: "Status".to_string(), + field_type: "SingleSelect".to_string(), + })); + assert!(db.fields.contains(&AFDatabaseField { + name: "Description".to_string(), + field_type: "RichText".to_string(), + })); +} + #[tokio::test] async fn add_and_delete_workspace_for_user() { let (c, _user) = generate_unique_registered_user_client().await; From 30dff6c25bd645217d1d2938df9c10ef31b2aff3 Mon Sep 17 00:00:00 2001 From: Zack Fu Zi Xiang Date: Thu, 7 Nov 2024 16:33:27 +0800 Subject: [PATCH 2/8] chore: add missing imports --- libs/client-api/src/http_view.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/client-api/src/http_view.rs b/libs/client-api/src/http_view.rs index d2c7656b..25e51331 100644 --- a/libs/client-api/src/http_view.rs +++ b/libs/client-api/src/http_view.rs @@ -1,4 +1,4 @@ -use client_api_entity::workspace_dto::{CreatePageParams, Page, PageCollab}; +use client_api_entity::workspace_dto::{CreatePageParams, Page, PageCollab, UpdatePageParams}; use reqwest::Method; use serde_json::json; use shared_entity::response::{AppResponse, AppResponseError}; From 867ee8eeffaec98126d660e19e50ccf2ee42d033 Mon Sep 17 00:00:00 2001 From: Zack Fu Zi Xiang Date: Thu, 7 Nov 2024 17:08:17 +0800 Subject: [PATCH 3/8] chore: cargo fmt --- libs/client-api/src/http_collab.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libs/client-api/src/http_collab.rs b/libs/client-api/src/http_collab.rs index 0d44d468..bafa0540 100644 --- a/libs/client-api/src/http_collab.rs +++ b/libs/client-api/src/http_collab.rs @@ -153,8 +153,6 @@ impl Client { .send() .await?; log_request_id(&resp); - AppResponse::from_response(resp) - .await? - .into_data() + AppResponse::from_response(resp).await?.into_data() } } From fa771815c9230ffe9a2eb688d76875143271b540 Mon Sep 17 00:00:00 2001 From: Zack Fu Zi Xiang Date: Thu, 7 Nov 2024 20:19:45 +0800 Subject: [PATCH 4/8] chore: fix test case --- tests/workspace/workspace_crud.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/workspace/workspace_crud.rs b/tests/workspace/workspace_crud.rs index da1a668f..76e01385 100644 --- a/tests/workspace/workspace_crud.rs +++ b/tests/workspace/workspace_crud.rs @@ -14,7 +14,7 @@ async fn workspace_list_database() { let db = &dbs[0]; - assert_eq!(db.name, "Untitled"); + assert_eq!(db.name, ""); assert!(db.fields.contains(&AFDatabaseField { name: "Last modified".to_string(), field_type: "LastEditedTime".to_string(), From f3604edf2e4c3799b0a5e17380a757f00f607d96 Mon Sep 17 00:00:00 2001 From: khorshuheng Date: Fri, 8 Nov 2024 13:52:23 +0800 Subject: [PATCH 5/8] feat: api for restore all pages from trash --- libs/client-api/src/http_view.rs | 17 +++++++++ src/api/workspace.rs | 25 ++++++++++++- src/biz/workspace/page_view.rs | 42 +++++++++++++++++++++ tests/workspace/page_view.rs | 64 +++++++++++++++++++++++--------- 4 files changed, 128 insertions(+), 20 deletions(-) diff --git a/libs/client-api/src/http_view.rs b/libs/client-api/src/http_view.rs index dc179b4a..14101253 100644 --- a/libs/client-api/src/http_view.rs +++ b/libs/client-api/src/http_view.rs @@ -58,6 +58,23 @@ impl Client { AppResponse::<()>::from_response(resp).await?.into_error() } + pub async fn restore_all_workspace_page_views_from_trash( + &self, + workspace_id: Uuid, + ) -> Result<(), AppResponseError> { + let url = format!( + "{}/api/workspace/{}/restore-all-pages-from-trash", + self.base_url, workspace_id + ); + let resp = self + .http_client_with_auth(Method::POST, &url) + .await? + .json(&json!({})) + .send() + .await?; + AppResponse::<()>::from_response(resp).await?.into_error() + } + pub async fn update_workspace_page_view( &self, workspace_id: Uuid, diff --git a/src/api/workspace.rs b/src/api/workspace.rs index ad9b31dd..7aa29c82 100644 --- a/src/api/workspace.rs +++ b/src/api/workspace.rs @@ -49,8 +49,8 @@ use crate::biz::workspace::ops::{ get_reactions_on_published_view, remove_comment_on_published_view, remove_reaction_on_comment, }; use crate::biz::workspace::page_view::{ - create_page, get_page_view_collab, move_page_to_trash, restore_page_from_trash, update_page, - update_page_collab_data, + create_page, get_page_view_collab, move_page_to_trash, restore_all_pages_from_trash, + restore_page_from_trash, update_page, update_page_collab_data, }; use crate::biz::workspace::publish::get_workspace_default_publish_view_info_meta; use crate::domain::compression::{ @@ -143,6 +143,10 @@ pub fn workspace_scope() -> Scope { web::resource("/{workspace_id}/page-view/{view_id}/restore-from-trash") .route(web::post().to(restore_page_from_trash_handler)), ) + .service( + web::resource("/{workspace_id}/restore-all-pages-from-trash") + .route(web::post().to(restore_all_pages_from_trash_handler)), + ) .service( web::resource("/{workspace_id}/batch/collab") .route(web::post().to(batch_create_collab_handler)), @@ -941,6 +945,23 @@ async fn restore_page_from_trash_handler( Ok(Json(AppResponse::Ok())) } +async fn restore_all_pages_from_trash_handler( + user_uuid: UserUuid, + path: web::Path, + state: Data, +) -> Result>> { + let uid = state.user_cache.get_user_uid(&user_uuid).await?; + let workspace_uuid = path.into_inner(); + restore_all_pages_from_trash( + &state.pg_pool, + &state.collab_access_control_storage, + uid, + workspace_uuid, + ) + .await?; + Ok(Json(AppResponse::Ok())) +} + async fn update_page_view_handler( user_uuid: UserUuid, path: web::Path<(Uuid, String)>, diff --git a/src/biz/workspace/page_view.rs b/src/biz/workspace/page_view.rs index 30d9cf11..b6e1fd9a 100644 --- a/src/biz/workspace/page_view.rs +++ b/src/biz/workspace/page_view.rs @@ -164,6 +164,25 @@ async fn move_view_out_from_trash( }) } +async fn move_all_views_out_from_trash(folder: &mut Folder) -> Result { + let encoded_update = { + let mut txn = folder.collab.transact_mut(); + if let Some(op) = folder + .body + .section + .section_op(&txn, collab_folder::Section::Trash) + { + op.clear(&mut txn); + }; + txn.encode_update_v1() + }; + + Ok(FolderUpdate { + updated_encoded_collab: folder_to_encoded_collab(folder)?, + encoded_updates: encoded_update, + }) +} + fn folder_to_encoded_collab(folder: &Folder) -> Result, AppError> { let collab_type = CollabType::Folder; let encoded_folder_collab = folder @@ -297,6 +316,29 @@ pub async fn restore_page_from_trash( Ok(()) } +pub async fn restore_all_pages_from_trash( + pg_pool: &PgPool, + collab_storage: &CollabAccessControlStorage, + uid: i64, + workspace_id: Uuid, +) -> Result<(), AppError> { + let collab_origin = GetCollabOrigin::User { uid }; + let mut folder = + get_latest_collab_folder(collab_storage, collab_origin, &workspace_id.to_string()).await?; + let folder_update = move_all_views_out_from_trash(&mut folder).await?; + let mut transaction = pg_pool.begin().await?; + insert_and_broadcast_workspace_folder_update( + uid, + workspace_id, + folder_update, + collab_storage, + &mut transaction, + ) + .await?; + transaction.commit().await?; + Ok(()) +} + #[allow(clippy::too_many_arguments)] pub async fn update_page( pg_pool: &PgPool, diff --git a/tests/workspace/page_view.rs b/tests/workspace/page_view.rs index 2e3d9cfb..d4e92239 100644 --- a/tests/workspace/page_view.rs +++ b/tests/workspace/page_view.rs @@ -1,4 +1,4 @@ -use std::time::Duration; +use std::{collections::HashSet, time::Duration}; use client_api::entity::{QueryCollab, QueryCollabParams}; use client_api_test::{ @@ -146,40 +146,49 @@ async fn move_page_to_trash() { .into_iter() .find(|v| v.name == "General") .unwrap(); - let view_id_to_be_deleted = general_space.children[0].view_id.clone(); + let view_ids_to_be_deleted = [ + general_space.children[0].view_id.clone(), + general_space.children[1].view_id.clone(), + ]; app_client.open_workspace_collab(&workspace_id).await; app_client .wait_object_sync_complete(&workspace_id) .await .unwrap(); - web_client - .api_client - .move_workspace_page_view_to_trash( - Uuid::parse_str(&workspace_id).unwrap(), - view_id_to_be_deleted.clone(), - ) - .await - .unwrap(); + for view_id in view_ids_to_be_deleted.iter() { + app_client + .api_client + .move_workspace_page_view_to_trash(Uuid::parse_str(&workspace_id).unwrap(), view_id.clone()) + .await + .unwrap(); + } let folder = get_latest_folder(&app_client, &workspace_id).await; - assert!(folder + let views_in_trash_for_app = folder .get_my_trash_sections() .iter() - .any(|v| v.id == view_id_to_be_deleted.clone())); - let view_found = web_client + .map(|v| v.id.clone()) + .collect::>(); + for view_id in view_ids_to_be_deleted.iter() { + assert!(views_in_trash_for_app.contains(view_id)); + } + let views_in_trash_for_web = web_client .api_client .get_workspace_trash(&workspace_id) .await .unwrap() .views .iter() - .any(|v| v.view.view_id == view_id_to_be_deleted.clone()); - assert!(view_found); + .map(|v| v.view.view_id.clone()) + .collect::>(); + for view_id in view_ids_to_be_deleted.iter() { + assert!(views_in_trash_for_web.contains(view_id)); + } web_client .api_client .restore_workspace_page_view_from_trash( Uuid::parse_str(&workspace_id).unwrap(), - &view_id_to_be_deleted, + &view_ids_to_be_deleted[0], ) .await .unwrap(); @@ -187,7 +196,7 @@ async fn move_page_to_trash() { assert!(!folder .get_my_trash_sections() .iter() - .any(|v| v.id == view_id_to_be_deleted.clone())); + .any(|v| v.id == view_ids_to_be_deleted[0])); let view_found = web_client .api_client .get_workspace_trash(&workspace_id) @@ -195,7 +204,26 @@ async fn move_page_to_trash() { .unwrap() .views .iter() - .any(|v| v.view.view_id == view_id_to_be_deleted.clone()); + .any(|v| v.view.view_id == view_ids_to_be_deleted[0]); + assert!(!view_found); + web_client + .api_client + .restore_all_workspace_page_views_from_trash(Uuid::parse_str(&workspace_id).unwrap()) + .await + .unwrap(); + let folder = get_latest_folder(&app_client, &workspace_id).await; + assert!(!folder + .get_my_trash_sections() + .iter() + .any(|v| v.id == view_ids_to_be_deleted[1])); + let view_found = web_client + .api_client + .get_workspace_trash(&workspace_id) + .await + .unwrap() + .views + .iter() + .any(|v| v.view.view_id == view_ids_to_be_deleted[1]); assert!(!view_found); } From 40576fe675d06ab1f7619b2514596fbe4c7cca51 Mon Sep 17 00:00:00 2001 From: Zack Fu Zi Xiang Date: Fri, 8 Nov 2024 17:59:24 +0800 Subject: [PATCH 6/8] chore: add admin frontend to test matrix --- .github/workflows/integration_test.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 9282acd9..8024cb7e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -44,20 +44,23 @@ jobs: - name: Build Docker Images run: | export DOCKER_DEFAULT_PLATFORM=linux/amd64 - docker compose build appflowy_cloud appflowy_history appflowy_worker + docker compose build appflowy_cloud appflowy_history appflowy_worker admin_frontend - name: Push docker images to docker hub run: | docker tag appflowyinc/appflowy_cloud appflowyinc/appflowy_cloud:${GITHUB_SHA} docker tag appflowyinc/appflowy_history appflowyinc/appflowy_history:${GITHUB_SHA} docker tag appflowyinc/appflowy_worker appflowyinc/appflowy_worker:${GITHUB_SHA} + docker tag appflowyinc/admin_frontend appflowyinc/admin_frontend:${GITHUB_SHA} echo ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | docker login --username appflowyinc --password-stdin docker push appflowyinc/appflowy_cloud:${GITHUB_SHA} docker push appflowyinc/appflowy_history:${GITHUB_SHA} docker push appflowyinc/appflowy_worker:${GITHUB_SHA} + docker push appflowyinc/admin_frontend:${GITHUB_SHA} APPFLOWY_HISTORY_VERSION=${GITHUB_SHA} APPFLOWY_WORKER_VERSION=${GITHUB_SHA} APPFLOWY_CLOUD_VERSION=${GITHUB_SHA} + APPFLOWY_ADMIN_FRONTEND_VERSION=${GITHUB_SHA} test: name: Integration Tests @@ -72,6 +75,8 @@ jobs: test_cmd: "-p appflowy-history" - test_service: "appflowy_worker" test_cmd: "-p appflowy-worker" + - test_service: "admin_frontend" + test_cmd: "-p admin_frontend" steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable @@ -113,7 +118,7 @@ jobs: export APPFLOWY_ADMIN_FRONTEND_VERSION=${GITHUB_SHA} docker compose -f docker-compose-ci.yml up -d docker ps -a - + container_id=$(docker ps --filter name=appflowy-cloud-ai-1 -q) if [ -n "$container_id" ]; then echo "Displaying logs for the AppFlowy-AI container..." @@ -122,7 +127,7 @@ jobs: echo "No running container found to display logs." fi - - name: install prerequisites + - name: Install prerequisites run: | sudo apt-get update sudo apt-get install protobuf-compiler @@ -130,8 +135,7 @@ jobs: - name: Run Tests run: | echo "Running tests for ${{ matrix.test_service }} with flags: ${{ matrix.test_cmd }}" - RUST_LOG="info" DISABLE_CI_TEST_LOG="true" cargo test ${{ matrix.test_cmd }} - RUST_LOG="info" DISABLE_CI_TEST_LOG="true" cargo test -p admin_frontend ${{ matrix.test_cmd }} + RUST_LOG="info" DISABLE_CI_TEST_LOG="true" cargo test --workspace cleanup: name: Cleanup Docker Images From c436d8733ed17c19c956c0aa4eb795927c2fd7a7 Mon Sep 17 00:00:00 2001 From: Zack Fu Zi Xiang Date: Fri, 8 Nov 2024 18:10:41 +0800 Subject: [PATCH 7/8] chore: add new line to trigger ci --- src/api/workspace.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/workspace.rs b/src/api/workspace.rs index 6e78ffe3..d1a6a86a 100644 --- a/src/api/workspace.rs +++ b/src/api/workspace.rs @@ -1392,6 +1392,7 @@ async fn post_published_duplicate_handler( params.dest_view_id, ) .await?; + Ok(Json(AppResponse::Ok())) } From 2a102dcdbf9a6d86bbfae4ed5a33724f811f27b7 Mon Sep 17 00:00:00 2001 From: Zack Fu Zi Xiang Date: Sat, 9 Nov 2024 12:41:30 +0800 Subject: [PATCH 8/8] fix: test cmd --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 8024cb7e..53bd66bd 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -135,7 +135,7 @@ jobs: - name: Run Tests run: | echo "Running tests for ${{ matrix.test_service }} with flags: ${{ matrix.test_cmd }}" - RUST_LOG="info" DISABLE_CI_TEST_LOG="true" cargo test --workspace + RUST_LOG="info" DISABLE_CI_TEST_LOG="true" cargo test ${{ matrix.test_cmd }} cleanup: name: Cleanup Docker Images