## Description - Adds server endpoints for getting and setting protected branches - Adds protected canvas view for branch protection - Adds default branch and protected branch in git modal settings #### PR fixes following issue(s) Fixes #28434, #28056 #### Media Protected View - <img width="1728" alt="image" src="https://github.com/appsmithorg/appsmith/assets/8724051/4fb26450-61e1-4fc0-a66d-0ebaa28ff90c"> Branch Protection Settings - <img width="1728" alt="image" src="https://github.com/appsmithorg/appsmith/assets/8724051/fb6d16b6-0a3c-42fd-be1a-9b3677048663"> #### Type of change - New feature (non-breaking change which adds functionality) ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] JUnit - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed --------- Co-authored-by: Nayan <nayan@appsmith.com>
222 lines
5.5 KiB
TypeScript
222 lines
5.5 KiB
TypeScript
import type { AxiosPromise } from "axios";
|
|
import Api from "api/Api";
|
|
import type { ApiResponse } from "./ApiResponses";
|
|
import type { GitConfig } from "entities/GitSync";
|
|
import ApplicationApi from "@appsmith/api/ApplicationApi";
|
|
|
|
export interface CommitPayload {
|
|
applicationId: string;
|
|
commitMessage: string;
|
|
doPush: boolean;
|
|
branch: string;
|
|
}
|
|
|
|
export interface MergeBranchPayload {
|
|
applicationId: string;
|
|
sourceBranch: string;
|
|
destinationBranch: string;
|
|
}
|
|
|
|
export interface MergeStatusPayload {
|
|
applicationId: string;
|
|
sourceBranch: string;
|
|
destinationBranch: string;
|
|
}
|
|
|
|
export interface ConnectToGitPayload {
|
|
remoteUrl: string;
|
|
gitProfile?: {
|
|
authorName: string;
|
|
authorEmail: string;
|
|
useDefaultProfile?: boolean;
|
|
};
|
|
}
|
|
|
|
interface GitStatusParam {
|
|
applicationId: string;
|
|
branch: string;
|
|
compareRemote: "true" | "false";
|
|
}
|
|
|
|
interface GitRemoteStatusParam {
|
|
applicationId: string;
|
|
branch: string;
|
|
}
|
|
|
|
class GitSyncAPI extends Api {
|
|
static baseURL = `/v1/git`;
|
|
|
|
static async commit({
|
|
applicationId,
|
|
branch,
|
|
commitMessage,
|
|
doPush,
|
|
}: CommitPayload): Promise<AxiosPromise<ApiResponse>> {
|
|
return Api.post(
|
|
`${GitSyncAPI.baseURL}/commit/app/${applicationId}?branchName=${branch}`,
|
|
{
|
|
commitMessage,
|
|
doPush,
|
|
},
|
|
);
|
|
}
|
|
|
|
static async merge({
|
|
applicationId,
|
|
destinationBranch,
|
|
sourceBranch,
|
|
}: MergeBranchPayload): Promise<AxiosPromise<ApiResponse>> {
|
|
return Api.post(`${GitSyncAPI.baseURL}/merge/app/${applicationId}`, {
|
|
sourceBranch,
|
|
destinationBranch,
|
|
});
|
|
}
|
|
|
|
static async getMergeStatus({
|
|
applicationId,
|
|
destinationBranch,
|
|
sourceBranch,
|
|
}: MergeStatusPayload) {
|
|
return Api.post(`${GitSyncAPI.baseURL}/merge/status/app/${applicationId}`, {
|
|
sourceBranch,
|
|
destinationBranch,
|
|
});
|
|
}
|
|
|
|
static async pull({ applicationId }: { applicationId: string }) {
|
|
return Api.get(`${GitSyncAPI.baseURL}/pull/app/${applicationId}`);
|
|
}
|
|
|
|
static async connect(payload: ConnectToGitPayload, applicationId: string) {
|
|
return Api.post(
|
|
`${GitSyncAPI.baseURL}/connect/app/${applicationId}`,
|
|
payload,
|
|
);
|
|
}
|
|
|
|
static async getGlobalConfig() {
|
|
return Api.get(`${GitSyncAPI.baseURL}/profile/default`);
|
|
}
|
|
|
|
static async setGlobalConfig(payload: GitConfig) {
|
|
return Api.post(`${GitSyncAPI.baseURL}/profile/default`, payload);
|
|
}
|
|
|
|
static async fetchBranches(applicationId: string, pruneBranches?: boolean) {
|
|
const queryParams = {} as { pruneBranches?: boolean };
|
|
if (pruneBranches) queryParams.pruneBranches = true;
|
|
return Api.get(
|
|
`${GitSyncAPI.baseURL}/branch/app/${applicationId}`,
|
|
queryParams,
|
|
);
|
|
}
|
|
|
|
static async checkoutBranch(applicationId: string, branch: string) {
|
|
return Api.get(
|
|
`${GitSyncAPI.baseURL}/checkout-branch/app/${applicationId}`,
|
|
{
|
|
branchName: branch,
|
|
},
|
|
);
|
|
}
|
|
|
|
static async createNewBranch(applicationId: string, branch: string) {
|
|
return Api.post(
|
|
`${GitSyncAPI.baseURL}/create-branch/app/${applicationId}`,
|
|
{
|
|
branchName: branch,
|
|
},
|
|
);
|
|
}
|
|
|
|
static async getLocalConfig(applicationId: string) {
|
|
return Api.get(`${GitSyncAPI.baseURL}/profile/app/${applicationId}`);
|
|
}
|
|
|
|
static async setLocalConfig(payload: GitConfig, applicationId: string) {
|
|
return Api.put(
|
|
`${GitSyncAPI.baseURL}/profile/app/${applicationId}`,
|
|
payload,
|
|
);
|
|
}
|
|
|
|
static async getGitStatus({
|
|
applicationId,
|
|
branch,
|
|
compareRemote = "true",
|
|
}: GitStatusParam) {
|
|
return Api.get(
|
|
`${GitSyncAPI.baseURL}/status/app/${applicationId}`,
|
|
{ compareRemote },
|
|
{ headers: { branchName: branch } },
|
|
);
|
|
}
|
|
|
|
static async getGitRemoteStatus({
|
|
applicationId,
|
|
branch,
|
|
}: GitRemoteStatusParam) {
|
|
return Api.get(
|
|
`${GitSyncAPI.baseURL}/fetch/remote/app/${applicationId}`,
|
|
{},
|
|
{ headers: { branchName: branch } },
|
|
);
|
|
}
|
|
|
|
static async revokeGit({ applicationId }: { applicationId: string }) {
|
|
return Api.post(`${GitSyncAPI.baseURL}/disconnect/app/${applicationId}`);
|
|
}
|
|
|
|
static async importApp(payload: ConnectToGitPayload, workspaceId: string) {
|
|
return Api.post(`${GitSyncAPI.baseURL}/import/${workspaceId}`, payload);
|
|
}
|
|
|
|
static async getSSHKeyPair(
|
|
applicationId: string,
|
|
): Promise<AxiosPromise<ApiResponse>> {
|
|
return Api.get(ApplicationApi.baseURL + "/ssh-keypair/" + applicationId);
|
|
}
|
|
|
|
static async generateSSHKeyPair(
|
|
applicationId: string,
|
|
keyType: string,
|
|
isImporting?: boolean,
|
|
): Promise<AxiosPromise<ApiResponse>> {
|
|
const url = isImporting
|
|
? `v1/git/import/keys?keyType=${keyType}`
|
|
: `${ApplicationApi.baseURL}/ssh-keypair/${applicationId}?keyType=${keyType}`;
|
|
return isImporting ? Api.get(url) : Api.post(url);
|
|
}
|
|
|
|
static async deleteBranch(
|
|
applicationId: string,
|
|
branchName: string,
|
|
): Promise<AxiosPromise<ApiResponse>> {
|
|
return Api.delete(GitSyncAPI.baseURL + "/branch/app/" + applicationId, {
|
|
branchName,
|
|
});
|
|
}
|
|
|
|
static async discardChanges(applicationId: string) {
|
|
return Api.put(`${GitSyncAPI.baseURL}/discard/app/${applicationId}`);
|
|
}
|
|
|
|
static async getProtectedBranches(applicationId: string) {
|
|
return Api.get(
|
|
`${GitSyncAPI.baseURL}/branch/app/${applicationId}/protected`,
|
|
);
|
|
}
|
|
|
|
static async updateProtectedBranches(
|
|
applicationId: string,
|
|
branchNames: string[],
|
|
) {
|
|
return Api.post(
|
|
`${GitSyncAPI.baseURL}/branch/app/${applicationId}/protected`,
|
|
{ branchNames },
|
|
);
|
|
}
|
|
}
|
|
|
|
export default GitSyncAPI;
|