chore: git mod - migrating apis for git (#37984)

## Description
- Add application apis for git package

Fixes #37823


## Automation

/ok-to-test tags="@tag.Git"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/12194637717>
> Commit: e72e02f75e0c58ad1306776b3246c6de2431e9bf
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12194637717&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Git`
> Spec:
> <hr>Fri, 06 Dec 2024 08:23:16 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced various asynchronous functions for Git operations,
including:
		- `checkoutBranchRequest`
		- `commitRequest`
		- `connectRequest`
		- `createBranchRequest`
		- `deleteBranchRequest`
		- `fetchBranchesRequest`
		- `fetchGitMetadataRequest`
		- `fetchProtectedBranchesRequest`
		- `mergeRequest`
		- `pullRequest`
		- `toggleAutocommitRequest`
		- `triggerAutocommitRequest`
		- `updateGlobalConfigRequest`
		- `updateLocalConfigRequest`
		- `updateProtectedBranchesRequest`
- Added new enumeration `AutocommitStatus` and interfaces to enhance
type safety for Git operations.
- **Bug Fixes**
- Updated import paths for consistency and clarity across multiple
files.
- **Documentation**
- Enhanced type definitions for various request and response structures.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Rudraprasad Das 2024-12-06 16:35:46 +08:00 committed by GitHub
parent a4502261c7
commit fd9efb81a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
55 changed files with 587 additions and 4 deletions

View File

@ -3,7 +3,7 @@ import {
GitImportStep,
GitOpsTab,
GitSettingsTab,
} from "../../enums";
} from "../../constants/enums";
import type {
GitSingleArtifactAPIResponsesReduxState,
GitSingleArtifactUIReduxState,

View File

@ -2,7 +2,7 @@ import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import QuickActions from ".";
import { GitSettingsTab } from "git/enums";
import { GitSettingsTab } from "../../constants/enums";
import { GitSyncModalTab } from "entities/GitSync";
import { theme } from "constants/DefaultTheme";
import { ThemeProvider } from "styled-components";

View File

@ -12,7 +12,7 @@ import { GitSyncModalTab } from "entities/GitSync";
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import type { GitMetadata, GitStatus } from "../../types";
import { getPullBtnStatus } from "./helpers";
import { GitSettingsTab } from "../../enums";
import { GitSettingsTab } from "../../constants/enums";
import ConnectButton from "./ConnectButton";
import QuickActionButton from "./QuickActionButton";
import AutocommitStatusbar from "./AutocommitStatusbar";

View File

@ -25,3 +25,12 @@ export enum GitSettingsTab {
General = "General",
Branch = "Branch",
}
export enum AutocommitStatus {
IN_PROGRESS = "IN_PROGRESS",
LOCKED = "LOCKED",
PUBLISHED = "PUBLISHED",
IDLE = "IDLE",
NOT_REQUIRED = "NOT_REQUIRED",
NON_GIT_APP = "NON_GIT_APP",
}

View File

@ -0,0 +1,17 @@
import type { AxiosResponse } from "axios";
import type {
CheckoutBranchRequestParams,
CheckoutBranchResponse,
} from "./checkoutBranchRequest.types";
import { GIT_BASE_URL } from "./constants";
import Api from "api/Api";
export default async function checkoutBranchRequest(
branchedApplicationId: string,
params: CheckoutBranchRequestParams,
): Promise<AxiosResponse<CheckoutBranchResponse>> {
return Api.get(
`${GIT_BASE_URL}/checkout-branch/app/${branchedApplicationId}`,
params,
);
}

View File

@ -0,0 +1,8 @@
export interface CheckoutBranchRequestParams {
branchName: string;
}
export interface CheckoutBranchResponse {
id: string; // applicationId
baseId: string; // baseApplicationId
}

View File

@ -0,0 +1,17 @@
import Api from "api/Api";
import type {
CommitRequestParams,
CommitResponse,
} from "./commitRequest.types";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
export default async function commitRequest(
branchedApplicationId: string,
params: CommitRequestParams,
): Promise<AxiosResponse<CommitResponse>> {
return Api.post(
`${GIT_BASE_URL}/commit/app/${branchedApplicationId}`,
params,
);
}

View File

@ -0,0 +1,6 @@
export interface CommitRequestParams {
commitMessage: string;
doPush: boolean;
}
export type CommitResponse = string;

View File

@ -0,0 +1,14 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type {
ConnectRequestParams,
ConnectResponse,
} from "./connectRequest.types";
import type { AxiosResponse } from "axios";
export default async function connectRequest(
baseApplicationId: string,
params: ConnectRequestParams,
): Promise<AxiosResponse<ConnectResponse>> {
return Api.post(`${GIT_BASE_URL}/connect/app/${baseApplicationId}`, params);
}

View File

@ -0,0 +1,24 @@
export interface ConnectRequestParams {
remoteUrl: string;
gitProfile?: {
authorName: string;
authorEmail: string;
useDefaultProfile?: boolean;
};
}
export interface ConnectResponse {
id: string;
baseId: string;
gitApplicationMetadata: {
branchName: string;
browserSupportedRemoteUrl: string;
defaultApplicationId: string;
defaultArtifactId: string;
defaultBranchName: string;
isRepoPrivate: boolean;
lastCommitedAt: string;
remoteUrl: string;
repoName: string;
};
}

View File

@ -0,0 +1,2 @@
export const GIT_BASE_URL = "/v1/git";
export const APPLICATION_BASE_URL = "/v1/applications";

View File

@ -0,0 +1,17 @@
import type { AxiosResponse } from "axios";
import type {
CreateBranchRequestParams,
CreateBranchResponse,
} from "./createBranchRequest.types";
import { GIT_BASE_URL } from "./constants";
import Api from "api/Api";
export default async function createBranchRequest(
branchedApplicationId: string,
params: CreateBranchRequestParams,
): Promise<AxiosResponse<CreateBranchResponse>> {
return Api.post(
`${GIT_BASE_URL}/create-branch/app/${branchedApplicationId}`,
params,
);
}

View File

@ -0,0 +1,8 @@
export interface CreateBranchRequestParams {
branchName: string;
}
export interface CreateBranchResponse {
id: string; // applicationId
baseId: string; // baseApplicationId
}

View File

@ -0,0 +1,14 @@
import type { AxiosResponse } from "axios";
import type {
DeleteBranchRequestParams,
DeleteBranchResponse,
} from "./deleteBranchRequest.types";
import { GIT_BASE_URL } from "./constants";
import Api from "api/Api";
export default async function deleteBranchRequest(
baseApplicationId: string,
params: DeleteBranchRequestParams,
): Promise<AxiosResponse<DeleteBranchResponse>> {
return Api.delete(`${GIT_BASE_URL}/branch/app/${baseApplicationId}`, params);
}

View File

@ -0,0 +1,8 @@
export interface DeleteBranchRequestParams {
branchName: string;
}
export interface DeleteBranchResponse {
id: string; // applicationId
baseId: string; // baseApplicationId
}

View File

@ -0,0 +1,9 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
export default async function discardRequest(
branchedApplicationId: string,
): Promise<AxiosResponse<void>> {
return Api.put(`${GIT_BASE_URL}/discard/app/${branchedApplicationId}`);
}

View File

@ -0,0 +1,10 @@
import type { AxiosResponse } from "axios";
import { GIT_BASE_URL } from "./constants";
import type { DisconnectResponse } from "./disconnectRequest.types";
import Api from "api/Api";
export default async function disconnectRequest(
baseApplicationId: string,
): Promise<AxiosResponse<DisconnectResponse>> {
return Api.post(`${GIT_BASE_URL}/disconnect/app/${baseApplicationId}`);
}

View File

@ -0,0 +1,3 @@
export interface DisconnectResponse {
[key: string]: string;
}

View File

@ -0,0 +1,12 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
import type { FetchAutocommitProgressResponse } from "./fetchAutocommitProgressRequest.types";
export default async function fetchAutocommitProgressRequest(
baseApplicationId: string,
): Promise<AxiosResponse<FetchAutocommitProgressResponse>> {
return Api.get(
`${GIT_BASE_URL}/auto-commit/progress/app/${baseApplicationId}`,
);
}

View File

@ -0,0 +1,7 @@
import type { AutocommitStatus } from "../constants/enums";
export interface FetchAutocommitProgressResponse {
autoCommitResponse: AutocommitStatus;
progress: number;
branchName: string;
}

View File

@ -0,0 +1,21 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type {
FetchBranchesRequestParams,
FetchBranchesResponse,
} from "./fetchBranchesRequest.types";
import type { AxiosResponse } from "axios";
export default async function fetchBranchesRequest(
branchedApplicationId: string,
params?: FetchBranchesRequestParams,
): Promise<AxiosResponse<FetchBranchesResponse>> {
const queryParams = {} as FetchBranchesRequestParams;
if (params?.pruneBranches) queryParams.pruneBranches = true;
return Api.get(
`${GIT_BASE_URL}/branch/app/${branchedApplicationId}`,
queryParams,
);
}

View File

@ -0,0 +1,11 @@
export interface FetchBranchesRequestParams {
pruneBranches: boolean;
}
interface SingleBranch {
branchName: string;
createdFromLocal: string;
default: boolean;
}
export type FetchBranchesResponse = SingleBranch[];

View File

@ -0,0 +1,10 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
import type { FetchGitMetadataResponse } from "./fetchGitMetadataRequest.types";
export default async function fetchGitMetadataRequest(
baseApplicationId: string,
): Promise<AxiosResponse<FetchGitMetadataResponse>> {
return Api.get(`${GIT_BASE_URL}/metadata/app/${baseApplicationId}`);
}

View File

@ -0,0 +1,15 @@
export interface FetchGitMetadataResponse {
branchName: string;
defaultBranchName: string;
remoteUrl: string;
repoName: string;
browserSupportedUrl?: string;
isRepoPrivate?: boolean;
browserSupportedRemoteUrl: string;
defaultApplicationId: string;
isProtectedBranch: boolean;
autoCommitConfig: {
enabled: boolean;
};
isAutoDeploymentEnabled?: boolean;
}

View File

@ -0,0 +1,10 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
import type { FetchGlobalConfigResponse } from "./fetchGlobalConfigRequest.types";
export default async function fetchGlobalConfigRequest(): Promise<
AxiosResponse<FetchGlobalConfigResponse>
> {
return Api.get(`${GIT_BASE_URL}/profile/default`);
}

View File

@ -0,0 +1,4 @@
export interface FetchGlobalConfigResponse {
authorName: string;
authorEmail: string;
}

View File

@ -0,0 +1,10 @@
import Api from "api/Api";
import type { AxiosResponse } from "axios";
import { GIT_BASE_URL } from "./constants";
import type { FetchLocalConfigResponse } from "./fetchLocalConfigRequest.types";
export default async function fetchLocalConfigRequest(
baseApplicationId: string,
): Promise<AxiosResponse<FetchLocalConfigResponse>> {
return Api.get(`${GIT_BASE_URL}/profile/app/${baseApplicationId}`);
}

View File

@ -0,0 +1,5 @@
export interface FetchLocalConfigResponse {
authorName: string;
authorEmail: string;
useGlobalProfile: boolean;
}

View File

@ -0,0 +1,17 @@
import type { AxiosResponse } from "axios";
import type {
FetchMergeStatusRequestParams,
FetchMergeStatusResponse,
} from "./fetchMergeStatusRequest.types";
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
export default async function fetchMergeStatusRequest(
branchedApplicationId: string,
params: FetchMergeStatusRequestParams,
): Promise<AxiosResponse<FetchMergeStatusResponse>> {
return Api.post(
`${GIT_BASE_URL}/merge/status/app/${branchedApplicationId}`,
params,
);
}

View File

@ -0,0 +1,10 @@
export interface FetchMergeStatusRequestParams {
sourceBranch: string;
destinationBranch: string;
}
export interface FetchMergeStatusResponse {
isMergeAble: boolean;
status: string; // merge status
message: string;
}

View File

@ -0,0 +1,10 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
import type { FetchProtectedBranches } from "./fetchProtectedBranchesRequest.types";
export default async function fetchProtectedBranchesRequest(
baseApplicationId: string,
): Promise<AxiosResponse<FetchProtectedBranches>> {
return Api.get(`${GIT_BASE_URL}/branch/app/${baseApplicationId}/protected`);
}

View File

@ -0,0 +1 @@
export type FetchProtectedBranches = string[];

View File

@ -0,0 +1,10 @@
import type { AxiosResponse } from "axios";
import type { FetchSSHKeyResponse } from "./fetchSSHKeyRequest.types";
import Api from "api/Api";
import { APPLICATION_BASE_URL } from "./constants";
export default async function fetchSSHKeyRequest(
baseApplicationId: string,
): Promise<AxiosResponse<FetchSSHKeyResponse>> {
return Api.get(`${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}`);
}

View File

@ -0,0 +1,6 @@
export interface FetchSSHKeyResponse {
publicKey: string;
docUrl: string;
isRegeneratedKey: boolean;
regeneratedKey: boolean;
}

View File

@ -0,0 +1,14 @@
import Api from "api/Api";
import type {
FetchStatusRequestParams,
FetchStatusResponse,
} from "./fetchStatusRequest.types";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
export default async function fetchStatusRequest(
branchedApplicationId: string,
params: FetchStatusRequestParams,
): Promise<AxiosResponse<FetchStatusResponse>> {
return Api.get(`${GIT_BASE_URL}/status/app/${branchedApplicationId}`, params);
}

View File

@ -0,0 +1,38 @@
export interface FetchStatusRequestParams {
compareRemote: boolean;
}
export interface FetchStatusResponse {
added: string[];
aheadCount: number;
behindCount: number;
conflicting: string[];
datasourcesAdded: string[];
datasourcesModified: string[];
datasourcesRemoved: string[];
discardDocUrl: string;
isClean: boolean;
jsLibsAdded: string[];
jsLibsModified: string[];
jsLibsRemoved: string[];
jsObjectsAdded: string[];
jsObjectsModified: string[];
jsObjectsRemoved: string[];
migrationMessage: string;
modified: string[];
modifiedDatasources: number;
modifiedJSLibs: number;
modifiedJSObjects: number;
modifiedModuleInstances: number;
modifiedModules: number;
modifiedPages: number;
modifiedQueries: number;
pagesAdded: string[];
pagesModified: string[];
pagesRemoved: string[];
queriesAdded: string[];
queriesModified: string[];
queriesRemoved: string[];
remoteBranch: string;
removed: string[];
}

View File

@ -0,0 +1,18 @@
import type { AxiosResponse } from "axios";
import type {
GenerateSSHKeyRequestParams,
GenerateSSHKeyResponse,
} from "./generateSSHKeyRequest.types";
import { APPLICATION_BASE_URL, GIT_BASE_URL } from "./constants";
import Api from "api/Api";
export default async function generateSSHKeyRequest(
baseApplicationId: string,
params: GenerateSSHKeyRequestParams,
): Promise<AxiosResponse<GenerateSSHKeyResponse>> {
const url = params.isImporting
? `${GIT_BASE_URL}/import/keys?keyType=${params.keyType}`
: `${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}?keyType=${params.keyType}`;
return params.isImporting ? Api.get(url) : Api.post(url);
}

View File

@ -0,0 +1,11 @@
export interface GenerateSSHKeyRequestParams {
keyType: string;
isImporting: boolean;
}
export interface GenerateSSHKeyResponse {
publicKey: string;
docUrl: string;
isRegeneratedKey: boolean;
regeneratedKey: boolean;
}

View File

@ -0,0 +1,14 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type {
ImportGitRequestParams,
ImportGitResponse,
} from "./importGitRequest.types";
import type { AxiosResponse } from "axios";
export default async function importGitRequest(
workspaceId: string,
params: ImportGitRequestParams,
): Promise<AxiosResponse<ImportGitResponse>> {
return Api.post(`${GIT_BASE_URL}/import/${workspaceId}`, params);
}

View File

@ -0,0 +1,24 @@
export interface ImportGitRequestParams {
remoteUrl: string;
gitProfile?: {
authorName: string;
authorEmail: string;
useDefaultProfile?: boolean;
};
}
export interface ImportGitResponse {
id: string;
baseId: string;
gitApplicationMetadata: {
branchName: string;
browserSupportedRemoteUrl: string;
defaultApplicationId: string;
defaultArtifactId: string;
defaultBranchName: string;
isRepoPrivate: boolean;
lastCommitedAt: string;
remoteUrl: string;
repoName: string;
};
}

View File

@ -0,0 +1,11 @@
import Api from "api/Api";
import type { MergeRequestParams, MergeResponse } from "./mergeRequest.types";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
export default async function mergeRequest(
branchedApplicationId: string,
params: MergeRequestParams,
): Promise<AxiosResponse<MergeResponse>> {
return Api.post(`${GIT_BASE_URL}/merge/app/${branchedApplicationId}`, params);
}

View File

@ -0,0 +1,9 @@
export interface MergeRequestParams {
sourceBranch: string;
destinationBranch: string;
}
export interface MergeResponse {
isMergAble: boolean;
status: string; // merge status
}

View File

@ -0,0 +1,10 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
import type { PullRequestResponse } from "./pullRequest.types";
export default async function pullRequest(
branchedApplicationId: string,
): Promise<AxiosResponse<PullRequestResponse>> {
return Api.get(`${GIT_BASE_URL}/pull/app/${branchedApplicationId}`);
}

View File

@ -0,0 +1,6 @@
export interface PullRequestResponse {
mergeStatus: {
isMergeAble: boolean;
status: string; // pull merge status
};
}

View File

@ -0,0 +1,12 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
import type { ToggleAutocommitResponse } from "./toggleAutocommitRequest.types";
export default async function toggleAutocommitRequest(
baseApplicationId: string,
): Promise<AxiosResponse<ToggleAutocommitResponse>> {
return Api.patch(
`${GIT_BASE_URL}/auto-commit/toggle/app/${baseApplicationId}`,
);
}

View File

@ -0,0 +1 @@
export type ToggleAutocommitResponse = boolean;

View File

@ -0,0 +1,10 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type { AxiosResponse } from "axios";
import type { TriggerAutocommitResponse } from "./triggerAutocommitRequest.types";
export default async function triggerAutocommitRequest(
branchedApplicationId: string,
): Promise<AxiosResponse<TriggerAutocommitResponse>> {
return Api.post(`${GIT_BASE_URL}/auto-commit/app/${branchedApplicationId}`);
}

View File

@ -0,0 +1,7 @@
import type { AutocommitStatus } from "../constants/enums";
export interface TriggerAutocommitResponse {
autoCommitResponse: AutocommitStatus;
progress: number;
branchName: string;
}

View File

@ -0,0 +1,13 @@
import type { AxiosResponse } from "axios";
import type {
UpdateGlobalConfigRequestParams,
UpdateGlobalConfigResponse,
} from "./updateGlobalConfigRequest.types";
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
export default async function updateGlobalConfigRequest(
params: UpdateGlobalConfigRequestParams,
): Promise<AxiosResponse<UpdateGlobalConfigResponse>> {
return Api.post(`${GIT_BASE_URL}/profile/default`, params);
}

View File

@ -0,0 +1,11 @@
export interface UpdateGlobalConfigRequestParams {
authorName: string;
authorEmail: string;
}
export interface UpdateGlobalConfigResponse {
default: {
authorName: string;
authorEmail: string;
};
}

View File

@ -0,0 +1,14 @@
import type { AxiosResponse } from "axios";
import type {
UpdateLocalConfigRequestParams,
UpdateLocalConfigResponse,
} from "./updateLocalConfigRequest.types";
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
export default async function updateLocalConfigRequest(
baseApplicationId: string,
params: UpdateLocalConfigRequestParams,
): Promise<AxiosResponse<UpdateLocalConfigResponse>> {
return Api.put(`${GIT_BASE_URL}/profile/app/${baseApplicationId}`, params);
}

View File

@ -0,0 +1,13 @@
export interface UpdateLocalConfigRequestParams {
authorName: string;
authorEmail: string;
useGlobalProfile: boolean;
}
export interface UpdateLocalConfigResponse {
[baseApplicationId: string]: {
authorName: string;
authorEmail: string;
useGlobalProfile: boolean;
};
}

View File

@ -0,0 +1,17 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type {
UpdateProtectedBranchesRequestParams,
UpdateProtectedBranchesResponse,
} from "./updateProtectedBranchesRequest.types";
import type { AxiosResponse } from "axios";
export default async function updateProtectedBranchesRequest(
baseApplicationId: string,
params: UpdateProtectedBranchesRequestParams,
): Promise<AxiosResponse<UpdateProtectedBranchesResponse>> {
return Api.post(
`${GIT_BASE_URL}/branch/app/${baseApplicationId}/protected`,
params,
);
}

View File

@ -0,0 +1,5 @@
export interface UpdateProtectedBranchesRequestParams {
branchNames: string[];
}
export type UpdateProtectedBranchesResponse = string[];

View File

@ -5,7 +5,7 @@ import type {
GitImportStep,
GitOpsTab,
GitSettingsTab,
} from "./enums";
} from "./constants/enums";
// These will be updated when contracts are finalized
export type GitMetadata = Record<string, unknown>;