diff --git a/jupiter/src/storage/issue_storage.rs b/jupiter/src/storage/issue_storage.rs index e9a931893..11df409d3 100644 --- a/jupiter/src/storage/issue_storage.rs +++ b/jupiter/src/storage/issue_storage.rs @@ -8,7 +8,9 @@ use sea_orm::{ PaginatorTrait, QueryFilter, QuerySelect, RelationTrait, Set, TransactionTrait, }; -use callisto::{issue_mr_references, item_assignees, item_labels, label, mega_conversation, mega_issue}; +use callisto::{ + issue_mr_references, item_assignees, item_labels, label, mega_conversation, mega_issue, +}; use common::errors::MegaError; use common::model::Pagination; diff --git a/mono/src/api/conversation/mod.rs b/mono/src/api/conversation/mod.rs index 4ac0d1866..1111680ad 100644 --- a/mono/src/api/conversation/mod.rs +++ b/mono/src/api/conversation/mod.rs @@ -117,7 +117,7 @@ impl From for ConvType { ConvTypeEnum::Reopen => ConvType::Reopen, ConvTypeEnum::Label => ConvType::Label, ConvTypeEnum::Assignee => ConvType::Assignee, - ConvTypeEnum::Mention => ConvType::Mention + ConvTypeEnum::Mention => ConvType::Mention, } } } diff --git a/mono/src/api/mr/mod.rs b/mono/src/api/mr/mod.rs index d5a9a38c9..5ae380ee9 100644 --- a/mono/src/api/mr/mod.rs +++ b/mono/src/api/mr/mod.rs @@ -51,12 +51,6 @@ impl From for MRDetailRes { } } -#[derive(Serialize, ToSchema)] -pub struct FilesChangedList { - pub mui_trees: Vec, - pub content: Vec, -} - #[derive(Serialize, ToSchema)] pub struct FilesChangedPage { pub mui_trees: Vec, diff --git a/mono/src/api/mr/mr_router.rs b/mono/src/api/mr/mr_router.rs index bbb2f6fe2..7db8088b8 100644 --- a/mono/src/api/mr/mr_router.rs +++ b/mono/src/api/mr/mr_router.rs @@ -21,7 +21,7 @@ use crate::api::{ conversation::ContentPayload, issue::ItemRes, label::LabelUpdatePayload, - mr::{Condition, FilesChangedList, MRDetailRes, MergeBoxRes, MrFilesRes, MuiTreeNode}, + mr::{Condition, MRDetailRes, MergeBoxRes, MrFilesRes, MuiTreeNode}, oauth::model::LoginUser, }; use crate::api::{mr::FilesChangedPage, MonoApiServiceState}; @@ -39,7 +39,6 @@ pub fn routers() -> OpenApiRouter { .routes(routes!(close_mr)) .routes(routes!(reopen_mr)) .routes(routes!(mr_files_changed_by_page)) - .routes(routes!(mr_files_changed)) .routes(routes!(mr_files_list)) .routes(routes!(save_comment)) .routes(routes!(labels)) @@ -259,33 +258,6 @@ async fn mr_detail( Ok(Json(CommonResult::success(Some(mr_details)))) } -/// Get List of All Changed Files in Merge Request -#[utoipa::path( - get, - params( - ("link", description = "MR link"), - ), - path = "/{link}/files-changed", - responses( - (status = 200, body = CommonResult, content_type = "application/json") - ), - tag = MR_TAG -)] -async fn mr_files_changed( - Path(link): Path, - state: State, -) -> Result>, ApiError> { - let diff_res = state.monorepo().content_diff(&link).await?; - - let paths = diff_res.iter().map(|i| i.path.clone()).collect(); - let mui_trees = build_forest(paths); - let res = CommonResult::success(Some(FilesChangedList { - mui_trees, - content: diff_res, - })); - Ok(Json(res)) -} - /// Get Merge Request file changed list in Pagination #[utoipa::path( post, @@ -515,7 +487,6 @@ fn build_forest(paths: Vec) -> Vec { #[cfg(test)] mod test { use crate::api::mr::mr_router::build_forest; - use crate::api::mr::FilesChangedList; use neptune::model::diff_model::DiffItem; use std::collections::HashMap; @@ -638,19 +609,13 @@ mod test { assert!(root_labels.contains(&"src")); assert!(root_labels.contains(&"README.md")); - let content = vec![DiffItem { + let content = [DiffItem { data: sample_diff_output.to_string(), path: "diff_output.txt".to_string(), }]; - // Test the complete response structure - let files_changed_list = FilesChangedList { mui_trees, content }; - - assert!(!files_changed_list.mui_trees.is_empty()); - assert_eq!( - files_changed_list.content.first().unwrap().data, - sample_diff_output - ); + assert!(!mui_trees.is_empty()); + assert_eq!(content.first().unwrap().data, sample_diff_output); } #[test] diff --git a/moon/packages/types/generated.ts b/moon/packages/types/generated.ts index 269b918d9..4b3be3fb5 100644 --- a/moon/packages/types/generated.ts +++ b/moon/packages/types/generated.ts @@ -3118,15 +3118,6 @@ export type CommonResultCommonPageLabelItem = { req_result: boolean } -export type CommonResultFilesChangedList = { - data?: { - content: DiffItem[] - mui_trees: MuiTreeNode[] - } - err_message: string - req_result: boolean -} - export type CommonResultFilesChangedPage = { data?: { mui_trees: MuiTreeNode[] @@ -3136,12 +3127,6 @@ export type CommonResultFilesChangedPage = { req_result: boolean } -export type CommonResultHashMapStringBool = { - data?: Record - err_message: string - req_result: boolean -} - export type CommonResultIssueDetailRes = { data?: { assignees: string[] @@ -3333,7 +3318,8 @@ export enum ConvType { Closed = 'Closed', Reopen = 'Reopen', Label = 'Label', - Assignee = 'Assignee' + Assignee = 'Assignee', + Mention = 'Mention' } export type ConversationItem = { @@ -3358,22 +3344,12 @@ export type CreateFileInfo = { path: string } -export type DiffItem = { - data: string - path: string -} - export type FileTreeItem = { /** @min 0 */ total_count: number tree_items: TreeBriefItem[] } -export type FilesChangedList = { - content: DiffItem[] - mui_trees: MuiTreeNode[] -} - export type FilesChangedPage = { mui_trees: MuiTreeNode[] page: CommonPageDiffItem @@ -3525,8 +3501,6 @@ export type MuiTreeNode = { } export type NewGpgRequest = { - /** @format int32 */ - expires_days?: number | null gpg_content: string } @@ -3639,6 +3613,104 @@ export type UserInfo = { display_name: string } +/** Request payload for creating a new build task */ +export type BuildRequest = { + args?: any[] | null + buck_hash: string + buckconfig_hash: string + mr?: string | null + repo: string +} + +/** Log segment read result */ +export type LogSegment = { + /** build id / log file name */ + build_id: string + /** UTF-8 (lossy) decoded data slice */ + data: string + /** Whether we reached end of file */ + eof: boolean + /** + * Total file size in bytes + * @format int64 + * @min 0 + */ + file_size: number + /** + * Bytes actually read + * @min 0 + */ + len: number + /** + * Next offset (offset + len) + * @format int64 + * @min 0 + */ + next_offset: number + /** + * Requested starting offset + * @format int64 + * @min 0 + */ + offset: number +} + +/** Data transfer object for build information in API responses */ +export type TaskDTO = { + arguments: string + build_ids: any + end_at?: string | null + /** @format int32 */ + exit_code?: number | null + mr: string + output_files: any + repo_name: string + start_at: string + target: string + task_id: string +} + +/** Task information including current status */ +export type TaskInfoDTO = { + arguments: string + build_id: any + end_at?: string | null + /** @format int32 */ + exit_code?: number | null + mr: string + output_files: any + repo_name: string + start_at: string + /** Enumeration of possible task statuses */ + status: TaskStatusEnum + target: string +} + +/** Response structure for task status queries */ +export type TaskRequest = { + mr?: string | null + repo: string +} + +/** Response structure for task status queries */ +export type TaskStatus = { + /** @format int32 */ + exit_code?: number | null + message?: string | null + /** Enumeration of possible task statuses */ + status: TaskStatusEnum +} + +/** Enumeration of possible task statuses */ +export enum TaskStatusEnum { + Pending = 'Pending', + Building = 'Building', + Interrupted = 'Interrupted', + Failed = 'Failed', + Completed = 'Completed', + NotFound = 'NotFound' +} + export type PostActivityViewsData = UserNotificationCounts export type GetAttachmentsCommentersData = OrganizationMember[] @@ -4843,8 +4915,6 @@ export type PostApiMrCommentData = CommonResultString export type GetApiMrDetailData = CommonResultMRDetailRes -export type GetApiMrFilesChangedData = CommonResultFilesChangedList - export type PostApiMrFilesChangedData = CommonResultFilesChangedPage export type GetApiMrFilesListData = CommonResultVecMrFilesRes @@ -4859,8 +4929,6 @@ export type PostApiMrReopenData = CommonResultString export type PostApiMrTitleData = CommonResultString -export type GetApiMrVerifySignatureData = CommonResultHashMapStringBool - export type GetApiOrganizationsNotesSyncStateData = ShowResponse export type PatchApiOrganizationsNotesSyncStateData = any @@ -4913,6 +4981,43 @@ export type GetApiUserTokenListData = CommonResultVecListToken export type DeleteApiUserTokenByKeyIdData = CommonResultString +export type GetMrTaskByMrData = TaskDTO[] + +export type PostTaskData = any + +export type GetTaskBuildListByIdData = string[] + +export type PostTaskBuildByIdData = any + +export type GetTaskHistoryOutputByIdParams = { + /** + * The type of log retrieval: "full" indicates full retrieval, while "segment" indicates retrieval of segments. + * @example "full" + */ + type: string + /** + * Start line number (1-based) + * @format int64 + * @min 0 + */ + offset?: number + /** + * Max number of lines to return + * @min 0 + */ + limit?: number + /** Build ID whose log to read */ + id: string +} + +export type GetTaskHistoryOutputByIdData = any + +export type GetTaskOutputByIdData = any + +export type GetTaskStatusByIdData = TaskStatus + +export type GetTasksByMrData = TaskInfoDTO[] + export type QueryParamsType = Record export type ResponseFormat = keyof Omit @@ -5196,6 +5301,32 @@ function dataTaggedQueryKey(key: unknown) { * @version 2.0.0 */ export class Api extends HttpClient { + /** + * No description + * + * @tags api + * @name PostTask + * @summary Creates a new build task and either assigns it immediately or queues it for later processing +Returns task ID and status information upon successful creation + * @request POST:/task + */ + postTask = () => { + const base = 'POST:/task' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: () => dataTaggedQueryKey([base]), + request: (data: TaskRequest, params: RequestParams = {}) => + this.request({ + path: `/task`, + method: 'POST', + body: data, + type: ContentType.Json, + ...params + }) + } + } + organizations = { /** * No description @@ -13894,29 +14025,6 @@ export class Api extends HttpClient { - const base = 'GET:/api/v1/mr/{link}/files-changed' as const - - return { - baseKey: dataTaggedQueryKey([base]), - requestKey: (link: string) => dataTaggedQueryKey([base, link]), - request: (link: string, params: RequestParams = {}) => - this.request({ - path: `/api/v1/mr/${link}/files-changed`, - method: 'GET', - ...params - }) - } - }, - /** * No description * @@ -14083,28 +14191,6 @@ It's for local testing purposes. } }, - /** - * No description - * - * @tags merge_request - * @name GetApiMrVerifySignature - * @request GET:/api/v1/mr/{link}/verify-signature - */ - getApiMrVerifySignature: () => { - const base = 'GET:/api/v1/mr/{link}/verify-signature' as const - - return { - baseKey: dataTaggedQueryKey([base]), - requestKey: (link: string) => dataTaggedQueryKey([base, link]), - request: (link: string, params: RequestParams = {}) => - this.request({ - path: `/api/v1/mr/${link}/verify-signature`, - method: 'GET', - ...params - }) - } - }, - /** * No description * @@ -14439,4 +14525,173 @@ It's for local testing purposes. } } } + mr = { + /** + * No description + * + * @tags api + * @name GetMrTaskByMr + * @summary Retrieves all build tasks associated with a specific merge request +Returns a list of task filtered by MR number + * @request GET:/mr-task/{mr} + */ + getMrTaskByMr: () => { + const base = 'GET:/mr-task/{mr}' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (mr: string) => dataTaggedQueryKey([base, mr]), + request: (mr: string, params: RequestParams = {}) => + this.request({ + path: `/mr-task/${mr}`, + method: 'GET', + ...params + }) + } + }, + + /** + * No description + * + * @tags api + * @name GetTasksByMr + * @summary Return all tasks with their current status (combining /mr-task and /task-status logic) + * @request GET:/tasks/{mr} + */ + getTasksByMr: () => { + const base = 'GET:/tasks/{mr}' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (mr: string) => dataTaggedQueryKey([base, mr]), + request: (mr: string, params: RequestParams = {}) => + this.request({ + path: `/tasks/${mr}`, + method: 'GET', + ...params + }) + } + } + } + id = { + /** + * No description + * + * @tags api + * @name GetTaskBuildListById + * @request GET:/task-build-list/{id} + */ + getTaskBuildListById: () => { + const base = 'GET:/task-build-list/{id}' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (id: string) => dataTaggedQueryKey([base, id]), + request: (id: string, params: RequestParams = {}) => + this.request({ + path: `/task-build-list/${id}`, + method: 'GET', + ...params + }) + } + }, + + /** + * No description + * + * @tags api + * @name PostTaskBuildById + * @request POST:/task-build/{id} + */ + postTaskBuildById: () => { + const base = 'POST:/task-build/{id}' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (id: string) => dataTaggedQueryKey([base, id]), + request: (id: string, data: BuildRequest, params: RequestParams = {}) => + this.request({ + path: `/task-build/${id}`, + method: 'POST', + body: data, + type: ContentType.Json, + ...params + }) + } + }, + + /** + * No description + * + * @tags api + * @name GetTaskHistoryOutputById + * @summary Provides the ability to read historical task logs +supporting either retrieving the entire log at once or segmenting it by line count. + * @request GET:/task-history-output/{id} + */ + getTaskHistoryOutputById: () => { + const base = 'GET:/task-history-output/{id}' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (params: GetTaskHistoryOutputByIdParams) => + dataTaggedQueryKey([base, params]), + request: ({ id, ...query }: GetTaskHistoryOutputByIdParams, params: RequestParams = {}) => + this.request({ + path: `/task-history-output/${id}`, + method: 'GET', + query: query, + ...params + }) + } + }, + + /** + * No description + * + * @tags api + * @name GetTaskOutputById + * @summary Streams build output logs in real-time using Server-Sent Events (SSE) +Continuously monitors the log file and streams new content as it becomes available + * @request GET:/task-output/{id} + */ + getTaskOutputById: () => { + const base = 'GET:/task-output/{id}' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (id: string) => dataTaggedQueryKey([base, id]), + request: (id: string, params: RequestParams = {}) => + this.request({ + path: `/task-output/${id}`, + method: 'GET', + ...params + }) + } + }, + + /** + * No description + * + * @tags api + * @name GetTaskStatusById + * @summary Retrieves the current status of a build task by its ID +Returns status information including exit code and current state + * @request GET:/task-status/{id} + */ + getTaskStatusById: () => { + const base = 'GET:/task-status/{id}' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (id: string) => dataTaggedQueryKey([base, id]), + request: (id: string, params: RequestParams = {}) => + this.request({ + path: `/task-status/${id}`, + method: 'GET', + ...params + }) + } + } + } }