chore: git api - adding new apis (#38681)

## Description
- Introduces new api contracts for git
- Adds feature flag `release_git_api_contracts_enabled`


Fixes https://github.com/appsmithorg/appsmith/issues/38500

## 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/12810595516>
> Commit: 8f05bbfb0b9259c3ee40464099416b75688a4bd1
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12810595516&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Git`
> Spec:
> <hr>Thu, 16 Jan 2025 15:05:20 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

## Release Notes

- **New Features**
    - Introduced a new feature flag `release_git_api_contracts_enabled`
    - Added support for enhanced Git API contract handling

- **Improvements**
    - Updated type definitions for Git-related operations
    - Refined request and response handling for Git artifacts
    - Improved type safety for Git references and branches

- **Changes**
- Modified several Git-related request and saga functions to support new
API contracts
    - Updated artifact type enum values to use lowercase representations
    - Introduced new interfaces for Git references and branches

- **Technical Updates**
    - Added conditional logic for feature flag-based request processing
    - Restructured type definitions across multiple Git-related modules
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Rudraprasad Das 2025-01-21 11:19:18 +01:00 committed by GitHub
parent 16e121ce73
commit 704e4735ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
73 changed files with 996 additions and 138 deletions

View File

@ -46,6 +46,7 @@ export const FEATURE_FLAG = {
release_gs_all_sheets_options_enabled: release_gs_all_sheets_options_enabled:
"release_gs_all_sheets_options_enabled", "release_gs_all_sheets_options_enabled",
release_git_modularisation_enabled: "release_git_modularisation_enabled", release_git_modularisation_enabled: "release_git_modularisation_enabled",
release_git_api_contracts_enabled: "release_git_api_contracts_enabled",
ab_premium_datasources_view_enabled: "ab_premium_datasources_view_enabled", ab_premium_datasources_view_enabled: "ab_premium_datasources_view_enabled",
kill_session_recordings_enabled: "kill_session_recordings_enabled", kill_session_recordings_enabled: "kill_session_recordings_enabled",
config_mask_session_recordings_enabled: config_mask_session_recordings_enabled:
@ -92,6 +93,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
release_table_html_column_type_enabled: false, release_table_html_column_type_enabled: false,
release_gs_all_sheets_options_enabled: false, release_gs_all_sheets_options_enabled: false,
release_git_modularisation_enabled: false, release_git_modularisation_enabled: false,
release_git_api_contracts_enabled: false,
ab_premium_datasources_view_enabled: false, ab_premium_datasources_view_enabled: false,
kill_session_recordings_enabled: false, kill_session_recordings_enabled: false,
config_user_session_recordings_enabled: true, config_user_session_recordings_enabled: true,

View File

@ -9,9 +9,9 @@ import { Button, Link, Option, Select, Text } from "@appsmith/ads";
import React, { useCallback, useEffect, useMemo, useState } from "react"; import React, { useCallback, useEffect, useMemo, useState } from "react";
import styled from "styled-components"; import styled from "styled-components";
import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import type { FetchBranchesResponseData } from "git/requests/fetchBranchesRequest.types";
import noop from "lodash/noop"; import noop from "lodash/noop";
import { useAppsmithEnterpriseUrl } from "git/hooks/useAppsmithEnterpriseUrl"; import { useAppsmithEnterpriseUrl } from "git/hooks/useAppsmithEnterpriseUrl";
import type { GitBranch } from "git/types";
const Container = styled.div` const Container = styled.div`
padding-top: 8px; padding-top: 8px;
@ -45,7 +45,7 @@ const StyledLink = styled(Link)`
`; `;
interface DefaultBranchViewProps { interface DefaultBranchViewProps {
branches: FetchBranchesResponseData | null; branches: GitBranch[] | null;
isGitProtectedFeatureLicensed: boolean; isGitProtectedFeatureLicensed: boolean;
updateDefaultBranch?: (branchName: string) => void; updateDefaultBranch?: (branchName: string) => void;
} }

View File

@ -33,8 +33,8 @@ import LocalBranchList from "./LocalBranchList";
import { useFilteredBranches } from "./hooks/useFilteredBranches"; import { useFilteredBranches } from "./hooks/useFilteredBranches";
import useActiveHoverIndex from "./hooks/useActiveHoverIndex"; import useActiveHoverIndex from "./hooks/useActiveHoverIndex";
import { Space } from "pages/Editor/gitSync/components/StyledComponents"; import { Space } from "pages/Editor/gitSync/components/StyledComponents";
import type { FetchBranchesResponseData } from "git/requests/fetchBranchesRequest.types";
import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types"; import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types";
import type { GitBranch } from "git/types";
const ListContainer = styled.div` const ListContainer = styled.div`
flex: 1; flex: 1;
@ -229,7 +229,7 @@ export function Header({
} }
interface BranchListViewProps { interface BranchListViewProps {
branches: FetchBranchesResponseData | null; branches: GitBranch[] | null;
checkoutBranch: (branch: string) => void; checkoutBranch: (branch: string) => void;
checkoutDestBranch: string | null; checkoutDestBranch: string | null;
createBranch: (branch: string) => void; createBranch: (branch: string) => void;

View File

@ -1,8 +1,8 @@
import type { Branch } from "entities/GitSync"; import type { GitBranch } from "git/types";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
export function useFilteredBranches( export function useFilteredBranches(
branches: Array<Branch>, branches: Array<GitBranch>,
searchText: string, searchText: string,
) { ) {
const lowercaseSearchText = searchText.toLowerCase(); const lowercaseSearchText = searchText.toLowerCase();
@ -10,15 +10,15 @@ export function useFilteredBranches(
useEffect( useEffect(
function setFilteredBranchesEffect() { function setFilteredBranchesEffect() {
const matched = branches.filter((b: Branch) => const matched = branches.filter((b) =>
lowercaseSearchText lowercaseSearchText
? b.branchName.toLowerCase().includes(lowercaseSearchText) ? b.branchName.toLowerCase().includes(lowercaseSearchText)
: true, : true,
); );
const branchNames = [ const branchNames = [
...matched.filter((b: Branch) => b.default), ...matched.filter((b) => b.default),
...matched.filter((b: Branch) => !b.default), ...matched.filter((b) => !b.default),
].map((b: Branch) => b.branchName); ].map((b) => b.branchName);
setFilteredBranches(branchNames); setFilteredBranches(branchNames);
}, },

View File

@ -31,7 +31,7 @@ export const useGitContext = () => {
interface GitContextProviderProps { interface GitContextProviderProps {
// artifact // artifact
artifactType: keyof typeof GitArtifactType | null; artifactType: GitArtifactType | null;
baseArtifactId: string | null; baseArtifactId: string | null;
artifact: ApplicationPayload | null; artifact: ApplicationPayload | null;
artifacts: ApplicationPayload[] | null; artifacts: ApplicationPayload[] | null;

View File

@ -31,10 +31,10 @@ import MergeStatus from "./MergeStatus";
import ConflictError from "git/components/ConflictError"; import ConflictError from "git/components/ConflictError";
import MergeSuccessIndicator from "./MergeSuccessIndicator"; import MergeSuccessIndicator from "./MergeSuccessIndicator";
import { noop } from "lodash"; import { noop } from "lodash";
import type { FetchBranchesResponseData } from "git/requests/fetchBranchesRequest.types";
import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types"; import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types";
import type { FetchMergeStatusResponseData } from "git/requests/fetchMergeStatusRequest.types"; import type { FetchMergeStatusResponseData } from "git/requests/fetchMergeStatusRequest.types";
import type { GitApiError } from "git/store/types"; import type { GitApiError } from "git/store/types";
import type { GitBranch } from "git/types";
const Container = styled.div` const Container = styled.div`
min-height: 360px; min-height: 360px;
@ -64,7 +64,7 @@ interface BranchOption {
} }
interface TabMergeViewProps { interface TabMergeViewProps {
branches: FetchBranchesResponseData | null; branches: GitBranch[] | null;
clearMergeStatus: () => void; clearMergeStatus: () => void;
currentBranch: string | null; currentBranch: string | null;
fetchBranches: () => void; fetchBranches: () => void;

View File

@ -13,10 +13,10 @@ import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import { DOCS_BRANCH_PROTECTION_URL } from "constants/ThirdPartyConstants"; import { DOCS_BRANCH_PROTECTION_URL } from "constants/ThirdPartyConstants";
import { GIT_REMOTE_BRANCH_PREFIX } from "git/constants/misc"; import { GIT_REMOTE_BRANCH_PREFIX } from "git/constants/misc";
import { useAppsmithEnterpriseUrl } from "git/hooks/useAppsmithEnterpriseUrl"; import { useAppsmithEnterpriseUrl } from "git/hooks/useAppsmithEnterpriseUrl";
import type { FetchBranchesResponseData } from "git/requests/fetchBranchesRequest.types";
import xor from "lodash/xor"; import xor from "lodash/xor";
import noop from "lodash/noop"; import noop from "lodash/noop";
import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types"; import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types";
import type { GitBranch } from "git/types";
const Container = styled.div` const Container = styled.div`
padding-top: 16px; padding-top: 16px;
@ -50,7 +50,7 @@ const StyledLink = styled(Link)`
`; `;
interface ProtectedBranchesViewProps { interface ProtectedBranchesViewProps {
branches: FetchBranchesResponseData | null; branches: GitBranch[] | null;
defaultBranch: string | null; defaultBranch: string | null;
isProtectedBranchesLicensed: boolean; isProtectedBranchesLicensed: boolean;
isUpdateProtectedBranchesLoading: boolean; isUpdateProtectedBranchesLoading: boolean;

View File

@ -1,7 +1,7 @@
export enum GitArtifactType { export enum GitArtifactType {
Application = "Application", Application = "applications",
Package = "Package", Package = "packages",
Workflow = "Workflow", Workflow = "workflows",
} }
export enum GitOpsTab { export enum GitOpsTab {

View File

@ -0,0 +1,8 @@
import type { GitBranch, GitRef } from "git/types";
export default function refToBranchList(refs: GitRef[]): GitBranch[] {
return refs.map((ref) => ({
branchName: ref.refName,
default: ref.default,
}));
}

View File

@ -9,9 +9,12 @@ import {
selectDeleteBranchState, selectDeleteBranchState,
selectCurrentBranch, selectCurrentBranch,
} from "git/store/selectors/gitArtifactSelectors"; } from "git/store/selectors/gitArtifactSelectors";
import { useCallback } from "react"; import { useCallback, useMemo } from "react";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import useArtifactSelector from "./useArtifactSelector"; import useArtifactSelector from "./useArtifactSelector";
import refToBranchList from "git/helpers/refToBranchList";
import useGitFeatureFlags from "./useGitFeatureFlags";
import type { GitBranch } from "git/types";
export default function useBranches() { export default function useBranches() {
const { artifact, artifactDef } = useGitContext(); const { artifact, artifactDef } = useGitContext();
@ -21,6 +24,20 @@ export default function useBranches() {
// fetch branches // fetch branches
const branchesState = useArtifactSelector(selectFetchBranchesState); const branchesState = useArtifactSelector(selectFetchBranchesState);
const { release_git_api_contracts_enabled: isGitApiContractsEnabled } =
useGitFeatureFlags();
const branches = useMemo(() => {
if (!Array.isArray(branchesState?.value)) {
return null;
}
if (!isGitApiContractsEnabled) {
return branchesState.value;
}
return refToBranchList(branchesState.value);
}, [branchesState?.value, isGitApiContractsEnabled]);
const fetchBranches = useCallback(() => { const fetchBranches = useCallback(() => {
if (artifactDef && artifactId) { if (artifactDef && artifactId) {
@ -106,7 +123,7 @@ export default function useBranches() {
); );
return { return {
branches: branchesState?.value ?? null, branches: branches as GitBranch[] | null,
isFetchBranchesLoading: branchesState?.loading ?? false, isFetchBranchesLoading: branchesState?.loading ?? false,
fetchBranchesError: branchesState?.error ?? null, fetchBranchesError: branchesState?.error ?? null,
fetchBranches, fetchBranches,

View File

@ -8,9 +8,13 @@ export default function useGitFeatureFlags() {
const license_git_continuous_delivery_enabled = useFeatureFlag( const license_git_continuous_delivery_enabled = useFeatureFlag(
FEATURE_FLAG.license_git_continuous_delivery_enabled, FEATURE_FLAG.license_git_continuous_delivery_enabled,
); );
const release_git_api_contracts_enabled = useFeatureFlag(
FEATURE_FLAG.release_git_api_contracts_enabled,
);
return { return {
license_git_branch_protection_enabled, license_git_branch_protection_enabled,
license_git_continuous_delivery_enabled, license_git_continuous_delivery_enabled,
release_git_api_contracts_enabled,
}; };
} }

View File

@ -6,7 +6,7 @@ import type {
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import Api from "api/Api"; import Api from "api/Api";
export default async function checkoutBranchRequest( export default async function checkoutBranchRequestOld(
branchedApplicationId: string, branchedApplicationId: string,
params: CheckoutBranchRequestParams, params: CheckoutBranchRequestParams,
): AxiosPromise<CheckoutBranchResponse> { ): AxiosPromise<CheckoutBranchResponse> {

View File

@ -0,0 +1,37 @@
import type { AxiosPromise } from "axios";
import { GIT_BASE_URL } from "./constants";
import Api from "api/Api";
import type { GitArtifactType } from "git/constants/enums";
import type {
CheckoutRefRequestParams,
CheckoutRefResponse,
} from "./checkoutRefRequest.types";
import checkoutBranchRequestOld from "./checkoutBranchRequest";
async function checkoutRefRequestNew(
artifactType: GitArtifactType,
refArtifactid: string,
params: CheckoutRefRequestParams,
): AxiosPromise<CheckoutRefResponse> {
return Api.post(
`${GIT_BASE_URL}/${artifactType}/${refArtifactid}/checkout-ref`,
params,
);
}
export default async function checkoutRefRequest(
artifactType: GitArtifactType,
refArtifactid: string,
params: CheckoutRefRequestParams,
isNew: boolean,
) {
if (isNew) {
return checkoutRefRequestNew(artifactType, refArtifactid, params);
} else {
const checkoutBranchParams = {
branchName: params.refName,
};
return checkoutBranchRequestOld(refArtifactid, checkoutBranchParams);
}
}

View File

@ -0,0 +1,12 @@
import type { ApiResponse } from "api/types";
import type { GitArtifact } from "git/store/types";
export interface CheckoutRefRequestParams {
refType: "branch" | "tag";
refName: string;
message?: string;
}
export type CheckoutRefResponseData = GitArtifact;
export type CheckoutRefResponse = ApiResponse<CheckoutRefResponseData>;

View File

@ -5,8 +5,9 @@ import type {
} from "./commitRequest.types"; } from "./commitRequest.types";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { GitArtifactType } from "git/constants/enums";
export default async function commitRequest( async function commitRequestOld(
branchedApplicationId: string, branchedApplicationId: string,
params: CommitRequestParams, params: CommitRequestParams,
): AxiosPromise<CommitResponse> { ): AxiosPromise<CommitResponse> {
@ -15,3 +16,27 @@ export default async function commitRequest(
params, params,
); );
} }
async function commitRequestNew(
artifactType: GitArtifactType,
refArtifactId: string,
params: CommitRequestParams,
): AxiosPromise<CommitResponse> {
return Api.post(
`${GIT_BASE_URL}/${artifactType}/${refArtifactId}/commit`,
params,
);
}
export default async function commitRequest(
artifactType: GitArtifactType,
refArtifactId: string,
params: CommitRequestParams,
isNew: boolean,
) {
if (isNew) {
return commitRequestNew(artifactType, refArtifactId, params);
} else {
return commitRequestOld(refArtifactId, params);
}
}

View File

@ -5,10 +5,35 @@ import type {
ConnectResponse, ConnectResponse,
} from "./connectRequest.types"; } from "./connectRequest.types";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { GitArtifactType } from "git/constants/enums";
export default async function connectRequest( async function connectRequestOld(
baseApplicationId: string, baseApplicationId: string,
params: ConnectRequestParams, params: ConnectRequestParams,
): AxiosPromise<ConnectResponse> { ): AxiosPromise<ConnectResponse> {
return Api.post(`${GIT_BASE_URL}/connect/app/${baseApplicationId}`, params); return Api.post(`${GIT_BASE_URL}/connect/app/${baseApplicationId}`, params);
} }
async function connectRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
params: ConnectRequestParams,
): AxiosPromise<ConnectResponse> {
return Api.post(
`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/connect`,
params,
);
}
export default async function connectRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
params: ConnectRequestParams,
isNew: boolean,
) {
if (isNew) {
return connectRequestNew(artifactType, baseArtifactId, params);
} else {
return connectRequestOld(baseArtifactId, params);
}
}

View File

@ -6,7 +6,7 @@ import type {
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import Api from "api/Api"; import Api from "api/Api";
export default async function createBranchRequest( export default async function createBranchRequestOld(
branchedApplicationId: string, branchedApplicationId: string,
params: CreateBranchRequestParams, params: CreateBranchRequestParams,
): AxiosPromise<CreateBranchResponse> { ): AxiosPromise<CreateBranchResponse> {

View File

@ -0,0 +1,37 @@
import type { AxiosPromise } from "axios";
import { GIT_BASE_URL } from "./constants";
import Api from "api/Api";
import type { GitArtifactType } from "git/constants/enums";
import type {
CreateRefRequestParams,
CreateRefResponse,
} from "./createRefRequest.types";
import createBranchRequestOld from "./createBranchRequest";
async function createRefRequestNew(
artifactType: GitArtifactType,
refArtifactId: string,
params: CreateRefRequestParams,
): AxiosPromise<CreateRefResponse> {
return Api.post(
`${GIT_BASE_URL}/${artifactType}/${refArtifactId}/create-ref`,
params,
);
}
export default async function createRefRequest(
artifactType: GitArtifactType,
refArtifactId: string,
params: CreateRefRequestParams,
isNew: boolean,
) {
if (isNew) {
return createRefRequestNew(artifactType, refArtifactId, params);
} else {
const createBranchParams = {
branchName: params.refName,
};
return createBranchRequestOld(refArtifactId, createBranchParams);
}
}

View File

@ -0,0 +1,11 @@
import type { ApiResponse } from "api/types";
import type { GitArtifact } from "git/store/types";
export interface CreateRefRequestParams {
refType: "branch" | "tag";
refName: string;
}
export type CreateRefResponseData = GitArtifact;
export type CreateRefResponse = ApiResponse<CreateRefResponseData>;

View File

@ -6,7 +6,7 @@ import type {
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import Api from "api/Api"; import Api from "api/Api";
export default async function deleteBranchRequest( export default async function deleteBranchRequestOld(
baseApplicationId: string, baseApplicationId: string,
params: DeleteBranchRequestParams, params: DeleteBranchRequestParams,
): AxiosPromise<DeleteBranchResponse> { ): AxiosPromise<DeleteBranchResponse> {

View File

@ -0,0 +1,37 @@
import type { AxiosPromise } from "axios";
import type {
DeleteRefRequestParams,
DeleteRefResponse,
} from "./deleteRefRequest.types";
import { GIT_BASE_URL } from "./constants";
import Api from "api/Api";
import type { GitArtifactType } from "git/constants/enums";
import deleteBranchRequestOld from "./deleteBranchRequest";
async function deleteRefRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
params: DeleteRefRequestParams,
): AxiosPromise<DeleteRefResponse> {
return Api.delete(
`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/ref`,
params,
);
}
export default async function deleteRefRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
params: DeleteRefRequestParams,
isNew: boolean,
) {
if (isNew) {
return deleteRefRequestNew(artifactType, baseArtifactId, params);
} else {
const deleteBranchParams = {
branchName: params.refName,
};
return deleteBranchRequestOld(baseArtifactId, deleteBranchParams);
}
}

View File

@ -0,0 +1,11 @@
import type { ApiResponse } from "api/types";
import type { GitArtifact } from "git/store/types";
export interface DeleteRefRequestParams {
refType: "branch" | "tag";
refName: string;
}
export type DeleteRefResponseData = GitArtifact;
export type DeleteRefResponse = ApiResponse<DeleteRefResponseData>;

View File

@ -2,9 +2,29 @@ import Api from "api/Api";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { DiscardResponse } from "./discardRequest.types"; import type { DiscardResponse } from "./discardRequest.types";
import type { GitArtifactType } from "git/constants/enums";
export default async function discardRequest( async function discardRequestOld(
branchedApplicationId: string, branchedApplicationId: string,
): AxiosPromise<DiscardResponse> { ): AxiosPromise<DiscardResponse> {
return Api.put(`${GIT_BASE_URL}/discard/app/${branchedApplicationId}`); return Api.put(`${GIT_BASE_URL}/discard/app/${branchedApplicationId}`);
} }
async function discardRequestNew(
artifactType: GitArtifactType,
refArtifactId: string,
): AxiosPromise<DiscardResponse> {
return Api.put(`${GIT_BASE_URL}/${artifactType}/${refArtifactId}/discard`);
}
export default async function discardRequest(
artifactType: GitArtifactType,
refArtifactId: string,
isNew: boolean,
) {
if (isNew) {
return discardRequestNew(artifactType, refArtifactId);
} else {
return discardRequestOld(refArtifactId);
}
}

View File

@ -1,4 +1,6 @@
import type { ApiResponse } from "api/types"; import type { ApiResponse } from "api/types";
import type { GitArtifact } from "git/store/types"; import type { GitArtifact } from "git/store/types";
export type DiscardResponse = ApiResponse<GitArtifact>; export type DiscardResponseData = GitArtifact;
export type DiscardResponse = ApiResponse<DiscardResponseData>;

View File

@ -2,9 +2,31 @@ import type { AxiosPromise } from "axios";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { DisconnectResponse } from "./disconnectRequest.types"; import type { DisconnectResponse } from "./disconnectRequest.types";
import Api from "api/Api"; import Api from "api/Api";
import type { GitArtifactType } from "git/constants/enums";
export default async function disconnectRequest( async function disconnectRequestOld(
baseApplicationId: string, baseApplicationId: string,
): AxiosPromise<DisconnectResponse> { ): AxiosPromise<DisconnectResponse> {
return Api.post(`${GIT_BASE_URL}/disconnect/app/${baseApplicationId}`); return Api.post(`${GIT_BASE_URL}/disconnect/app/${baseApplicationId}`);
} }
async function disconnectRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
): AxiosPromise<DisconnectResponse> {
return Api.post(
`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/disconnect`,
);
}
export default async function disconnectRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
isNew: boolean,
) {
if (isNew) {
return disconnectRequestNew(artifactType, baseArtifactId);
} else {
return disconnectRequestOld(baseArtifactId);
}
}

View File

@ -1,6 +1,6 @@
import type { ApiResponse } from "api/types"; import type { ApiResponse } from "api/types";
import type { ApplicationPayload } from "entities/Application"; import type { GitArtifact } from "git/store/types";
export interface DisconnectResponseData extends ApplicationPayload {} export type DisconnectResponseData = GitArtifact;
export type DisconnectResponse = ApiResponse<DisconnectResponseData>; export type DisconnectResponse = ApiResponse<DisconnectResponseData>;

View File

@ -2,11 +2,33 @@ import Api from "api/Api";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { FetchAutocommitProgressResponse } from "./fetchAutocommitProgressRequest.types"; import type { FetchAutocommitProgressResponse } from "./fetchAutocommitProgressRequest.types";
import type { GitArtifactType } from "git/constants/enums";
export default async function fetchAutocommitProgressRequest( async function fetchAutocommitProgressRequestOld(
baseApplicationId: string, baseApplicationId: string,
): AxiosPromise<FetchAutocommitProgressResponse> { ): AxiosPromise<FetchAutocommitProgressResponse> {
return Api.get( return Api.get(
`${GIT_BASE_URL}/auto-commit/progress/app/${baseApplicationId}`, `${GIT_BASE_URL}/auto-commit/progress/app/${baseApplicationId}`,
); );
} }
async function fetchAutocommitProgressRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
): AxiosPromise<FetchAutocommitProgressResponse> {
return Api.get(
`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/auto-commit/progress`,
);
}
export default async function fetchAutocommitProgressRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
isNew: boolean,
) {
if (isNew) {
return fetchAutocommitProgressRequestNew(artifactType, baseArtifactId);
} else {
return fetchAutocommitProgressRequestOld(baseArtifactId);
}
}

View File

@ -6,10 +6,29 @@ import type {
FetchGlobalSSHKeyResponse, FetchGlobalSSHKeyResponse,
} from "./fetchGlobalSSHKeyRequest.types"; } from "./fetchGlobalSSHKeyRequest.types";
export default async function fetchGlobalSSHKeyRequest( async function fetchGlobalSSHKeyRequestOld(
params: FetchGlobalSSHKeyRequestParams, params: FetchGlobalSSHKeyRequestParams,
): AxiosPromise<FetchGlobalSSHKeyResponse> { ): AxiosPromise<FetchGlobalSSHKeyResponse> {
const url = `${GIT_BASE_URL}/import/keys?keyType=${params.keyType}`; const url = `${GIT_BASE_URL}/import/keys?keyType=${params.keyType}`;
return Api.get(url); return Api.get(url);
} }
async function fetchGlobalSSHKeyRequestNew(
params: FetchGlobalSSHKeyRequestParams,
): AxiosPromise<FetchGlobalSSHKeyResponse> {
const url = `${GIT_BASE_URL}/artifacts/import/keys?keyType=${params.keyType}`;
return Api.get(url);
}
export default async function fetchGlobalSSHKeyRequest(
params: FetchGlobalSSHKeyRequestParams,
isNew: boolean,
): AxiosPromise<FetchGlobalSSHKeyResponse> {
if (isNew) {
return fetchGlobalSSHKeyRequestNew(params);
} else {
return fetchGlobalSSHKeyRequestOld(params);
}
}

View File

@ -2,9 +2,29 @@ import Api from "api/Api";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { FetchLocalProfileResponse } from "./fetchLocalProfileRequest.types"; import type { FetchLocalProfileResponse } from "./fetchLocalProfileRequest.types";
import type { GitArtifactType } from "git/constants/enums";
export default async function fetchLocalProfileRequest( async function fetchLocalProfileRequestOld(
baseApplicationId: string, baseApplicationId: string,
): AxiosPromise<FetchLocalProfileResponse> { ): AxiosPromise<FetchLocalProfileResponse> {
return Api.get(`${GIT_BASE_URL}/profile/app/${baseApplicationId}`); return Api.get(`${GIT_BASE_URL}/profile/app/${baseApplicationId}`);
} }
async function fetchLocalProfileRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
): AxiosPromise<FetchLocalProfileResponse> {
return Api.get(`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/profile`);
}
export default async function fetchLocalProfileRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
isNew: boolean,
): AxiosPromise<FetchLocalProfileResponse> {
if (isNew) {
return fetchLocalProfileRequestNew(artifactType, baseArtifactId);
} else {
return fetchLocalProfileRequestOld(baseArtifactId);
}
}

View File

@ -5,8 +5,9 @@ import type {
} from "./fetchMergeStatusRequest.types"; } from "./fetchMergeStatusRequest.types";
import Api from "api/Api"; import Api from "api/Api";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { GitArtifactType } from "git/constants/enums";
export default async function fetchMergeStatusRequest( async function fetchMergeStatusRequestOld(
branchedApplicationId: string, branchedApplicationId: string,
params: FetchMergeStatusRequestParams, params: FetchMergeStatusRequestParams,
): AxiosPromise<FetchMergeStatusResponse> { ): AxiosPromise<FetchMergeStatusResponse> {
@ -15,3 +16,27 @@ export default async function fetchMergeStatusRequest(
params, params,
); );
} }
async function fetchMergeStatusRequestNew(
artifactType: GitArtifactType,
refArtifactId: string,
params: FetchMergeStatusRequestParams,
): AxiosPromise<FetchMergeStatusResponse> {
return Api.post(
`${GIT_BASE_URL}/${artifactType}/${refArtifactId}/merge/status`,
params,
);
}
export default async function fetchMergeStatusRequest(
artifactType: GitArtifactType,
refArtifactId: string,
params: FetchMergeStatusRequestParams,
isNew: boolean,
): AxiosPromise<FetchMergeStatusResponse> {
if (isNew) {
return fetchMergeStatusRequestNew(artifactType, refArtifactId, params);
} else {
return fetchMergeStatusRequestOld(refArtifactId, params);
}
}

View File

@ -2,9 +2,29 @@ import Api from "api/Api";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { FetchMetadataResponse } from "./fetchMetadataRequest.types"; import type { FetchMetadataResponse } from "./fetchMetadataRequest.types";
import type { GitArtifactType } from "git/constants/enums";
export default async function fetchMetadataRequest( async function fetchMetadataRequestOld(
baseApplicationId: string, baseApplicationId: string,
): AxiosPromise<FetchMetadataResponse> { ): AxiosPromise<FetchMetadataResponse> {
return Api.get(`${GIT_BASE_URL}/metadata/app/${baseApplicationId}`); return Api.get(`${GIT_BASE_URL}/metadata/app/${baseApplicationId}`);
} }
async function fetchMetadataRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
): AxiosPromise<FetchMetadataResponse> {
return Api.get(`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/metadata`);
}
export default async function fetchMetadataRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
isNew: boolean,
): AxiosPromise<FetchMetadataResponse> {
if (isNew) {
return fetchMetadataRequestNew(artifactType, baseArtifactId);
} else {
return fetchMetadataRequestOld(baseArtifactId);
}
}

View File

@ -2,9 +2,29 @@ import Api from "api/Api";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { FetchProtectedBranchesResponse } from "./fetchProtectedBranchesRequest.types"; import type { FetchProtectedBranchesResponse } from "./fetchProtectedBranchesRequest.types";
import type { GitArtifactType } from "git/constants/enums";
export default async function fetchProtectedBranchesRequest( async function fetchProtectedBranchesRequestOld(
baseApplicationId: string, baseApplicationId: string,
): AxiosPromise<FetchProtectedBranchesResponse> { ): AxiosPromise<FetchProtectedBranchesResponse> {
return Api.get(`${GIT_BASE_URL}/branch/app/${baseApplicationId}/protected`); return Api.get(`${GIT_BASE_URL}/branch/app/${baseApplicationId}/protected`);
} }
async function fetchProtectedBranchesRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
): AxiosPromise<FetchProtectedBranchesResponse> {
return Api.get(`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/protected`);
}
export default async function fetchProtectedBranchesRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
isNew: boolean,
): AxiosPromise<FetchProtectedBranchesResponse> {
if (isNew) {
return fetchProtectedBranchesRequestNew(artifactType, baseArtifactId);
} else {
return fetchProtectedBranchesRequestOld(baseArtifactId);
}
}

View File

@ -0,0 +1,38 @@
import Api from "api/Api";
import { GIT_BASE_URL } from "./constants";
import type {
FetchRefsRequestParams,
FetchRefsResponse,
} from "./fetchRefsRequest.types";
import type { AxiosPromise } from "axios";
import type { GitArtifactType } from "git/constants/enums";
import fetchBranchesRequest from "./fetchBranchesRequest";
async function fetchRefsRequestNew(
artifactType: GitArtifactType,
refArtifactId: string,
params: FetchRefsRequestParams,
): AxiosPromise<FetchRefsResponse> {
return Api.get(
`${GIT_BASE_URL}/${artifactType}/${refArtifactId}/refs`,
undefined,
{ params },
);
}
export default async function fetchRefsRequest(
artifactType: GitArtifactType,
refArtifactId: string,
params: FetchRefsRequestParams,
isNew: boolean,
) {
if (isNew) {
return fetchRefsRequestNew(artifactType, refArtifactId, params);
} else {
const fetchBranchesParams = {
pruneBranches: params.pruneRefs,
};
return fetchBranchesRequest(refArtifactId, fetchBranchesParams);
}
}

View File

@ -0,0 +1,11 @@
import type { ApiResponse } from "api/types";
import type { GitRef } from "git/types";
export interface FetchRefsRequestParams {
pruneRefs: boolean;
refType: "branch" | "tag";
}
export type FetchRefsResponseData = GitRef[];
export type FetchRefsResponse = ApiResponse<FetchRefsResponseData>;

View File

@ -4,7 +4,7 @@ import Api from "api/Api";
import { APPLICATION_BASE_URL } from "./constants"; import { APPLICATION_BASE_URL } from "./constants";
export default async function fetchSSHKeyRequest( export default async function fetchSSHKeyRequest(
baseApplicationId: string, baseArtifactId: string,
): AxiosPromise<FetchSSHKeyResponse> { ): AxiosPromise<FetchSSHKeyResponse> {
return Api.get(`${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}`); return Api.get(`${APPLICATION_BASE_URL}/ssh-keypair/${baseArtifactId}`);
} }

View File

@ -5,10 +5,35 @@ import type {
} from "./fetchStatusRequest.types"; } from "./fetchStatusRequest.types";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { GitArtifactType } from "git/constants/enums";
export default async function fetchStatusRequest( async function fetchStatusRequestOld(
branchedApplicationId: string, branchedApplicationId: string,
params: FetchStatusRequestParams = { compareRemote: true }, params: FetchStatusRequestParams = { compareRemote: true },
): AxiosPromise<FetchStatusResponse> { ): AxiosPromise<FetchStatusResponse> {
return Api.get(`${GIT_BASE_URL}/status/app/${branchedApplicationId}`, params); return Api.get(`${GIT_BASE_URL}/status/app/${branchedApplicationId}`, params);
} }
async function fetchStatusRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
params: FetchStatusRequestParams,
): AxiosPromise<FetchStatusResponse> {
return Api.get(
`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/status`,
params,
);
}
export default async function fetchStatusRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
params: FetchStatusRequestParams,
isNew: boolean,
): AxiosPromise<FetchStatusResponse> {
if (isNew) {
return fetchStatusRequestNew(artifactType, baseArtifactId, params);
} else {
return fetchStatusRequestOld(baseArtifactId, params);
}
}

View File

@ -7,10 +7,10 @@ import { APPLICATION_BASE_URL } from "./constants";
import Api from "api/Api"; import Api from "api/Api";
export default async function generateSSHKeyRequest( export default async function generateSSHKeyRequest(
baseApplicationId: string, baseArtifactId: string,
params: GenerateSSHKeyRequestParams, params: GenerateSSHKeyRequestParams,
): AxiosPromise<GenerateSSHKeyResponse> { ): AxiosPromise<GenerateSSHKeyResponse> {
const url = `${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}?keyType=${params.keyType}`; const url = `${APPLICATION_BASE_URL}/ssh-keypair/${baseArtifactId}?keyType=${params.keyType}`;
return Api.post(url); return Api.post(url);
} }

View File

@ -6,9 +6,30 @@ import type {
} from "./gitImportRequest.types"; } from "./gitImportRequest.types";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
export default async function gitImportRequest( async function gitImportRequestOld(
workspaceId: string, workspaceId: string,
params: GitImportRequestParams, params: GitImportRequestParams,
): AxiosPromise<GitImportResponse> { ): AxiosPromise<GitImportResponse> {
return Api.post(`${GIT_BASE_URL}/import/${workspaceId}`, params); return Api.post(`${GIT_BASE_URL}/import/${workspaceId}`, params);
} }
async function gitImportRequestNew(
workspaceId: string,
params: GitImportRequestParams,
): AxiosPromise<GitImportResponse> {
return Api.post(`${GIT_BASE_URL}/artifacts/import`, params, {
params: { workspaceId },
});
}
export default async function gitImportRequest(
workspaceId: string,
params: GitImportRequestParams,
isNew: boolean,
): AxiosPromise<GitImportResponse> {
if (isNew) {
return gitImportRequestNew(workspaceId, params);
} else {
return gitImportRequestOld(workspaceId, params);
}
}

View File

@ -2,10 +2,35 @@ import Api from "api/Api";
import type { MergeRequestParams, MergeResponse } from "./mergeRequest.types"; import type { MergeRequestParams, MergeResponse } from "./mergeRequest.types";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { GitArtifactType } from "git/constants/enums";
export default async function mergeRequest( async function mergeRequestOld(
branchedApplicationId: string, branchedApplicationId: string,
params: MergeRequestParams, params: MergeRequestParams,
): AxiosPromise<MergeResponse> { ): AxiosPromise<MergeResponse> {
return Api.post(`${GIT_BASE_URL}/merge/app/${branchedApplicationId}`, params); return Api.post(`${GIT_BASE_URL}/merge/app/${branchedApplicationId}`, params);
} }
async function mergeRequestNew(
artifactType: GitArtifactType,
refArtifactId: string,
params: MergeRequestParams,
): AxiosPromise<MergeResponse> {
return Api.post(
`${GIT_BASE_URL}/${artifactType}/${refArtifactId}/merge`,
params,
);
}
export default async function mergeRequest(
artifactType: GitArtifactType,
refArtifactId: string,
params: MergeRequestParams,
isNew: boolean,
): AxiosPromise<MergeResponse> {
if (isNew) {
return mergeRequestNew(artifactType, refArtifactId, params);
} else {
return mergeRequestOld(refArtifactId, params);
}
}

View File

@ -2,9 +2,29 @@ import Api from "api/Api";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { PullResponse } from "./pullRequest.types"; import type { PullResponse } from "./pullRequest.types";
import type { GitArtifactType } from "git/constants/enums";
export default async function pullRequest( async function pullRequestOld(
branchedApplicationId: string, branchedApplicationId: string,
): AxiosPromise<PullResponse> { ): AxiosPromise<PullResponse> {
return Api.get(`${GIT_BASE_URL}/pull/app/${branchedApplicationId}`); return Api.get(`${GIT_BASE_URL}/pull/app/${branchedApplicationId}`);
} }
async function pullRequestNew(
artifactType: GitArtifactType,
refArtifactId: string,
): AxiosPromise<PullResponse> {
return Api.get(`${GIT_BASE_URL}/${artifactType}/${refArtifactId}/pull`);
}
export default async function pullRequest(
artifactType: GitArtifactType,
refArtifactId: string,
isNew: boolean,
): AxiosPromise<PullResponse> {
if (isNew) {
return pullRequestNew(artifactType, refArtifactId);
} else {
return pullRequestOld(refArtifactId);
}
}

View File

@ -2,11 +2,33 @@ import Api from "api/Api";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { ToggleAutocommitResponse } from "./toggleAutocommitRequest.types"; import type { ToggleAutocommitResponse } from "./toggleAutocommitRequest.types";
import type { GitArtifactType } from "git/constants/enums";
export default async function toggleAutocommitRequest( async function toggleAutocommitRequestOld(
baseApplicationId: string, baseApplicationId: string,
): AxiosPromise<ToggleAutocommitResponse> { ): AxiosPromise<ToggleAutocommitResponse> {
return Api.patch( return Api.patch(
`${GIT_BASE_URL}/auto-commit/toggle/app/${baseApplicationId}`, `${GIT_BASE_URL}/auto-commit/toggle/app/${baseApplicationId}`,
); );
} }
async function toggleAutocommitRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
): AxiosPromise<ToggleAutocommitResponse> {
return Api.patch(
`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/auto-commit/toggle`,
);
}
export default async function toggleAutocommitRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
isNew: boolean,
): AxiosPromise<ToggleAutocommitResponse> {
if (isNew) {
return toggleAutocommitRequestNew(artifactType, baseArtifactId);
} else {
return toggleAutocommitRequestOld(baseArtifactId);
}
}

View File

@ -2,9 +2,31 @@ import Api from "api/Api";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { TriggerAutocommitResponse } from "./triggerAutocommitRequest.types"; import type { TriggerAutocommitResponse } from "./triggerAutocommitRequest.types";
import type { GitArtifactType } from "git/constants/enums";
export default async function triggerAutocommitRequest( async function triggerAutocommitRequestOld(
branchedApplicationId: string, branchedApplicationId: string,
): AxiosPromise<TriggerAutocommitResponse> { ): AxiosPromise<TriggerAutocommitResponse> {
return Api.post(`${GIT_BASE_URL}/auto-commit/app/${branchedApplicationId}`); return Api.post(`${GIT_BASE_URL}/auto-commit/app/${branchedApplicationId}`);
} }
async function triggerAutocommitRequestNew(
artifactType: GitArtifactType,
refArtifactId: string,
): AxiosPromise<TriggerAutocommitResponse> {
return Api.post(
`${GIT_BASE_URL}/${artifactType}/${refArtifactId}/auto-commit`,
);
}
export default async function triggerAutocommitRequest(
artifactType: GitArtifactType,
refArtifactId: string,
isNew: boolean,
): AxiosPromise<TriggerAutocommitResponse> {
if (isNew) {
return triggerAutocommitRequestNew(artifactType, refArtifactId);
} else {
return triggerAutocommitRequestOld(refArtifactId);
}
}

View File

@ -5,10 +5,35 @@ import type {
} from "./updateLocalProfileRequest.types"; } from "./updateLocalProfileRequest.types";
import Api from "api/Api"; import Api from "api/Api";
import { GIT_BASE_URL } from "./constants"; import { GIT_BASE_URL } from "./constants";
import type { GitArtifactType } from "git/constants/enums";
export default async function updateLocalProfileRequest( async function updateLocalProfileRequestOld(
baseApplicationId: string, baseApplicationId: string,
params: UpdateLocalProfileRequestParams, params: UpdateLocalProfileRequestParams,
): AxiosPromise<UpdateLocalProfileResponse> { ): AxiosPromise<UpdateLocalProfileResponse> {
return Api.put(`${GIT_BASE_URL}/profile/app/${baseApplicationId}`, params); return Api.put(`${GIT_BASE_URL}/profile/app/${baseApplicationId}`, params);
} }
async function updateLocalProfileRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
params: UpdateLocalProfileRequestParams,
): AxiosPromise<UpdateLocalProfileResponse> {
return Api.put(
`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/profile`,
params,
);
}
export default async function updateLocalProfileRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
params: UpdateLocalProfileRequestParams,
isNew: boolean,
): AxiosPromise<UpdateLocalProfileResponse> {
if (isNew) {
return updateLocalProfileRequestNew(artifactType, baseArtifactId, params);
} else {
return updateLocalProfileRequestOld(baseArtifactId, params);
}
}

View File

@ -5,8 +5,9 @@ import type {
UpdateProtectedBranchesResponse, UpdateProtectedBranchesResponse,
} from "./updateProtectedBranchesRequest.types"; } from "./updateProtectedBranchesRequest.types";
import type { AxiosPromise } from "axios"; import type { AxiosPromise } from "axios";
import type { GitArtifactType } from "git/constants/enums";
export default async function updateProtectedBranchesRequest( async function updateProtectedBranchesRequestOld(
baseApplicationId: string, baseApplicationId: string,
params: UpdateProtectedBranchesRequestParams, params: UpdateProtectedBranchesRequestParams,
): AxiosPromise<UpdateProtectedBranchesResponse> { ): AxiosPromise<UpdateProtectedBranchesResponse> {
@ -15,3 +16,31 @@ export default async function updateProtectedBranchesRequest(
params, params,
); );
} }
async function updateProtectedBranchesRequestNew(
artifactType: GitArtifactType,
baseArtifactId: string,
params: UpdateProtectedBranchesRequestParams,
): AxiosPromise<UpdateProtectedBranchesResponse> {
return Api.post(
`${GIT_BASE_URL}/${artifactType}/${baseArtifactId}/protected`,
params,
);
}
export default async function updateProtectedBranchesRequest(
artifactType: GitArtifactType,
baseArtifactId: string,
params: UpdateProtectedBranchesRequestParams,
isNew: boolean,
): AxiosPromise<UpdateProtectedBranchesResponse> {
if (isNew) {
return updateProtectedBranchesRequestNew(
artifactType,
baseArtifactId,
params,
);
} else {
return updateProtectedBranchesRequestOld(baseArtifactId, params);
}
}

View File

@ -1,13 +1,15 @@
import { call, put, select, take } from "redux-saga/effects"; import { call, put, select, take } from "redux-saga/effects";
import type { CheckoutBranchInitPayload } from "../store/actions/checkoutBranchActions"; import type { CheckoutBranchInitPayload } from "../store/actions/checkoutBranchActions";
import { GitArtifactType } from "../constants/enums"; import { GitArtifactType } from "../constants/enums";
import checkoutBranchRequest from "../requests/checkoutBranchRequest";
import type {
CheckoutBranchRequestParams,
CheckoutBranchResponse,
} from "../requests/checkoutBranchRequest.types";
import { gitArtifactActions } from "../store/gitArtifactSlice"; import { gitArtifactActions } from "../store/gitArtifactSlice";
import type { GitArtifactPayloadAction } from "../store/types"; import type { GitArtifactPayloadAction } from "../store/types";
import log from "loglevel";
import { captureException } from "@sentry/react";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type {
CheckoutRefRequestParams,
CheckoutRefResponse,
} from "git/requests/checkoutRefRequest.types";
// internal dependencies // internal dependencies
import { builderURL } from "ee/RouteBuilder"; import { builderURL } from "ee/RouteBuilder";
@ -19,21 +21,30 @@ import { FocusEntity, identifyEntityFromPath } from "navigation/FocusEntity";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
import history from "utils/history"; import history from "utils/history";
import type { JSCollectionDataState } from "ee/reducers/entityReducers/jsActionsReducer"; import type { JSCollectionDataState } from "ee/reducers/entityReducers/jsActionsReducer";
import log from "loglevel"; import checkoutRefRequest from "git/requests/checkoutRefRequest";
import { captureException } from "@sentry/react";
export default function* checkoutBranchSaga( export default function* checkoutBranchSaga(
action: GitArtifactPayloadAction<CheckoutBranchInitPayload>, action: GitArtifactPayloadAction<CheckoutBranchInitPayload>,
) { ) {
const { artifactDef, artifactId, branchName } = action.payload; const { artifactDef, artifactId, branchName } = action.payload;
let response: CheckoutBranchResponse | undefined; let response: CheckoutRefResponse | undefined;
try { try {
const params: CheckoutBranchRequestParams = { const params: CheckoutRefRequestParams = {
branchName, refType: "branch",
refName: branchName,
}; };
const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(checkoutBranchRequest, artifactId, params); response = yield call(
checkoutRefRequest,
artifactDef.artifactType,
artifactId,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -17,6 +17,7 @@ import { gitGlobalActions } from "git/store/gitGlobalSlice";
import type { ApplicationPayload } from "entities/Application"; import type { ApplicationPayload } from "entities/Application";
import { getCurrentApplication } from "ee/selectors/applicationSelectors"; import { getCurrentApplication } from "ee/selectors/applicationSelectors";
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
export default function* commitSaga( export default function* commitSaga(
action: GitArtifactPayloadAction<CommitInitPayload>, action: GitArtifactPayloadAction<CommitInitPayload>,
@ -30,8 +31,17 @@ export default function* commitSaga(
commitMessage: action.payload.commitMessage, commitMessage: action.payload.commitMessage,
doPush: action.payload.doPush, doPush: action.payload.doPush,
}; };
const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(commitRequest, artifactId, params); response = yield call(
commitRequest,
artifactDef.artifactType,
artifactId,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response, false); const isValidResponse: boolean = yield validateResponse(response, false);

View File

@ -22,6 +22,7 @@ import { gitGlobalActions } from "git/store/gitGlobalSlice";
import { getCurrentApplication } from "ee/selectors/applicationSelectors"; import { getCurrentApplication } from "ee/selectors/applicationSelectors";
import type { ApplicationPayload } from "entities/Application"; import type { ApplicationPayload } from "entities/Application";
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
export default function* connectSaga( export default function* connectSaga(
action: GitArtifactPayloadAction<ConnectInitPayload>, action: GitArtifactPayloadAction<ConnectInitPayload>,
@ -36,7 +37,17 @@ export default function* connectSaga(
gitProfile: action.payload.gitProfile, gitProfile: action.payload.gitProfile,
}; };
response = yield call(connectRequest, artifactDef.baseArtifactId, params); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
connectRequest,
artifactDef.artifactType,
artifactDef.baseArtifactId,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response, false); const isValidResponse: boolean = yield validateResponse(response, false);

View File

@ -1,10 +1,5 @@
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import type { CreateBranchInitPayload } from "../store/actions/createBranchActions"; import type { CreateBranchInitPayload } from "../store/actions/createBranchActions";
import createBranchRequest from "../requests/createBranchRequest";
import type {
CreateBranchRequestParams,
CreateBranchResponse,
} from "../requests/createBranchRequest.types";
import { gitArtifactActions } from "../store/gitArtifactSlice"; import { gitArtifactActions } from "../store/gitArtifactSlice";
import type { GitArtifactPayloadAction } from "../store/types"; import type { GitArtifactPayloadAction } from "../store/types";
@ -12,29 +7,46 @@ import type { GitArtifactPayloadAction } from "../store/types";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
import { captureException } from "@sentry/react"; import { captureException } from "@sentry/react";
import log from "loglevel"; import log from "loglevel";
import createRefRequest from "git/requests/createRefRequest";
import type {
CreateRefRequestParams,
CreateRefResponse,
} from "git/requests/createRefRequest.types";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
export default function* createBranchSaga( export default function* createBranchSaga(
action: GitArtifactPayloadAction<CreateBranchInitPayload>, action: GitArtifactPayloadAction<CreateBranchInitPayload>,
) { ) {
const { artifactDef, artifactId } = action.payload; const { artifactDef, artifactId } = action.payload;
let response: CreateBranchResponse | undefined; let response: CreateRefResponse | undefined;
try { try {
const params: CreateBranchRequestParams = { const params: CreateRefRequestParams = {
branchName: action.payload.branchName, refType: "branch",
refName: action.payload.branchName,
}; };
response = yield call(createBranchRequest, artifactId, params); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
createRefRequest,
artifactDef.artifactType,
artifactId,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (isValidResponse) { if (isValidResponse) {
// yield put( yield put(
// gitArtifactActions.fetchBranchesInit({ gitArtifactActions.fetchBranchesInit({
// artifactDef, artifactDef,
// artifactId, artifactId,
// pruneBranches: true, pruneBranches: true,
// }), }),
// ); );
yield put( yield put(
gitArtifactActions.checkoutBranchInit({ gitArtifactActions.checkoutBranchInit({
artifactDef, artifactDef,

View File

@ -1,35 +1,41 @@
import type { DeleteBranchInitPayload } from "../store/actions/deleteBranchActions"; import type { DeleteBranchInitPayload } from "../store/actions/deleteBranchActions";
import deleteBranchRequest from "../requests/deleteBranchRequest";
import type {
DeleteBranchRequestParams,
DeleteBranchResponse,
} from "../requests/deleteBranchRequest.types";
import { gitArtifactActions } from "../store/gitArtifactSlice"; import { gitArtifactActions } from "../store/gitArtifactSlice";
import type { GitArtifactPayloadAction } from "../store/types"; import type { GitArtifactPayloadAction } from "../store/types";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
// internal dependencies
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
import log from "loglevel"; import log from "loglevel";
import { captureException } from "@sentry/react"; import { captureException } from "@sentry/react";
import { toast } from "@appsmith/ads"; import { toast } from "@appsmith/ads";
import { createMessage, DELETE_BRANCH_SUCCESS } from "ee/constants/messages"; import { createMessage, DELETE_BRANCH_SUCCESS } from "ee/constants/messages";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import deleteRefRequest from "git/requests/deleteRefRequest";
import type {
DeleteRefRequestParams,
DeleteRefResponse,
} from "git/requests/deleteRefRequest.types";
export default function* deleteBranchSaga( export default function* deleteBranchSaga(
action: GitArtifactPayloadAction<DeleteBranchInitPayload>, action: GitArtifactPayloadAction<DeleteBranchInitPayload>,
) { ) {
const { artifactDef, artifactId } = action.payload; const { artifactDef, artifactId } = action.payload;
let response: DeleteBranchResponse | undefined; let response: DeleteRefResponse | undefined;
try { try {
const params: DeleteBranchRequestParams = { const params: DeleteRefRequestParams = {
branchName: action.payload.branchName, refType: "branch",
refName: action.payload.branchName,
}; };
const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call( response = yield call(
deleteBranchRequest, deleteRefRequest,
artifactDef.artifactType,
artifactDef.baseArtifactId, artifactDef.baseArtifactId,
params, params,
isGitApiContractsEnabled,
); );
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);

View File

@ -6,9 +6,10 @@ import discardRequest from "git/requests/discardRequest";
import type { DiscardResponse } from "git/requests/discardRequest.types"; import type { DiscardResponse } from "git/requests/discardRequest.types";
import type { DiscardInitPayload } from "git/store/actions/discardActions"; import type { DiscardInitPayload } from "git/store/actions/discardActions";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, delay, put } from "redux-saga/effects"; import { call, delay, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
export default function* discardSaga( export default function* discardSaga(
@ -19,7 +20,16 @@ export default function* discardSaga(
let response: DiscardResponse | undefined; let response: DiscardResponse | undefined;
try { try {
response = yield call(discardRequest, artifactId); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
discardRequest,
artifactDef.artifactType,
artifactId,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -6,6 +6,7 @@ import disconnectRequest from "git/requests/disconnectRequest";
import type { DisconnectResponse } from "git/requests/disconnectRequest.types"; import type { DisconnectResponse } from "git/requests/disconnectRequest.types";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { selectDisconnectArtifactDef } from "git/store/selectors/gitArtifactSelectors"; import { selectDisconnectArtifactDef } from "git/store/selectors/gitArtifactSelectors";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactDef, GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactDef, GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, put, select } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
@ -21,9 +22,15 @@ export default function* disconnectSaga(action: GitArtifactPayloadAction) {
let response: DisconnectResponse | undefined; let response: DisconnectResponse | undefined;
try { try {
const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call( response = yield call(
disconnectRequest, disconnectRequest,
disconnectArtifactDef.artifactType,
disconnectArtifactDef.baseArtifactId, disconnectArtifactDef.baseArtifactId,
isGitApiContractsEnabled,
); );
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);

View File

@ -1,28 +1,40 @@
import type { FetchBranchesInitPayload } from "../store/actions/fetchBranchesActions"; import type { FetchBranchesInitPayload } from "../store/actions/fetchBranchesActions";
import fetchBranchesRequest from "git/requests/fetchBranchesRequest";
import type {
FetchBranchesRequestParams,
FetchBranchesResponse,
} from "git/requests/fetchBranchesRequest.types";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import type { GitArtifactPayloadAction } from "../store/types"; import type { GitArtifactPayloadAction } from "../store/types";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
import log from "loglevel"; import log from "loglevel";
import { captureException } from "@sentry/react"; import { captureException } from "@sentry/react";
import fetchRefsRequest from "git/requests/fetchRefsRequest";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type {
FetchRefsRequestParams,
FetchRefsResponse,
} from "git/requests/fetchRefsRequest.types";
export default function* fetchBranchesSaga( export default function* fetchBranchesSaga(
action: GitArtifactPayloadAction<FetchBranchesInitPayload>, action: GitArtifactPayloadAction<FetchBranchesInitPayload>,
) { ) {
const { artifactDef, artifactId } = action.payload; const { artifactDef, artifactId } = action.payload;
let response: FetchBranchesResponse | undefined; let response: FetchRefsResponse | undefined;
try { try {
const params: FetchBranchesRequestParams = { const params: FetchRefsRequestParams = {
pruneBranches: action.payload.pruneBranches, refType: "branch",
pruneRefs: action.payload.pruneBranches ?? true,
}; };
response = yield call(fetchBranchesRequest, artifactId, params); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
fetchRefsRequest,
artifactDef.artifactType,
artifactId,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response, false); const isValidResponse: boolean = yield validateResponse(response, false);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -6,9 +6,10 @@ import type {
} from "git/requests/generateSSHKeyRequest.types"; } from "git/requests/generateSSHKeyRequest.types";
import type { FetchGlobalSSHKeyInitPayload } from "git/store/actions/fetchGlobalSSHKeyActions"; import type { FetchGlobalSSHKeyInitPayload } from "git/store/actions/fetchGlobalSSHKeyActions";
import { gitGlobalActions } from "git/store/gitGlobalSlice"; import { gitGlobalActions } from "git/store/gitGlobalSlice";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
export function* fetchGlobalSSHKeySaga( export function* fetchGlobalSSHKeySaga(
@ -21,7 +22,15 @@ export function* fetchGlobalSSHKeySaga(
keyType: action.payload.keyType, keyType: action.payload.keyType,
}; };
response = yield call(fetchGlobalSSHKeyRequest, params); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
fetchGlobalSSHKeyRequest,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -2,10 +2,11 @@ import fetchLocalProfileRequest from "git/requests/fetchLocalProfileRequest";
import type { FetchLocalProfileResponse } from "git/requests/fetchLocalProfileRequest.types"; import type { FetchLocalProfileResponse } from "git/requests/fetchLocalProfileRequest.types";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import type { GitArtifactPayloadAction } from "../store/types"; import type { GitArtifactPayloadAction } from "../store/types";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
import log from "loglevel"; import log from "loglevel";
import { captureException } from "@sentry/react"; import { captureException } from "@sentry/react";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
export default function* fetchLocalProfileSaga( export default function* fetchLocalProfileSaga(
action: GitArtifactPayloadAction, action: GitArtifactPayloadAction,
@ -14,7 +15,16 @@ export default function* fetchLocalProfileSaga(
let response: FetchLocalProfileResponse | undefined; let response: FetchLocalProfileResponse | undefined;
try { try {
response = yield call(fetchLocalProfileRequest, artifactDef.baseArtifactId); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
fetchLocalProfileRequest,
artifactDef.artifactType,
artifactDef.baseArtifactId,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -6,9 +6,10 @@ import type {
} from "git/requests/fetchMergeStatusRequest.types"; } from "git/requests/fetchMergeStatusRequest.types";
import type { FetchMergeStatusInitPayload } from "git/store/actions/fetchMergeStatusActions"; import type { FetchMergeStatusInitPayload } from "git/store/actions/fetchMergeStatusActions";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
export default function* fetchMergeStatusSaga( export default function* fetchMergeStatusSaga(
@ -23,7 +24,17 @@ export default function* fetchMergeStatusSaga(
sourceBranch: action.payload.sourceBranch, sourceBranch: action.payload.sourceBranch,
}; };
response = yield call(fetchMergeStatusRequest, artifactId, params); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
fetchMergeStatusRequest,
artifactDef.artifactType,
artifactId,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -2,9 +2,10 @@ import { captureException } from "@sentry/react";
import fetchMetadataRequest from "git/requests/fetchMetadataRequest"; import fetchMetadataRequest from "git/requests/fetchMetadataRequest";
import type { FetchMetadataResponse } from "git/requests/fetchMetadataRequest.types"; import type { FetchMetadataResponse } from "git/requests/fetchMetadataRequest.types";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
export default function* fetchMetadataSaga(action: GitArtifactPayloadAction) { export default function* fetchMetadataSaga(action: GitArtifactPayloadAction) {
@ -12,7 +13,16 @@ export default function* fetchMetadataSaga(action: GitArtifactPayloadAction) {
let response: FetchMetadataResponse | undefined; let response: FetchMetadataResponse | undefined;
try { try {
response = yield call(fetchMetadataRequest, artifactDef.baseArtifactId); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
fetchMetadataRequest,
artifactDef.artifactType,
artifactDef.baseArtifactId,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response, false); const isValidResponse: boolean = yield validateResponse(response, false);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -2,9 +2,10 @@ import { captureException } from "@sentry/react";
import fetchProtectedBranchesRequest from "git/requests/fetchProtectedBranchesRequest"; import fetchProtectedBranchesRequest from "git/requests/fetchProtectedBranchesRequest";
import type { FetchProtectedBranchesResponse } from "git/requests/fetchProtectedBranchesRequest.types"; import type { FetchProtectedBranchesResponse } from "git/requests/fetchProtectedBranchesRequest.types";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
export default function* fetchProtectedBranchesSaga( export default function* fetchProtectedBranchesSaga(
@ -14,9 +15,15 @@ export default function* fetchProtectedBranchesSaga(
let response: FetchProtectedBranchesResponse | undefined; let response: FetchProtectedBranchesResponse | undefined;
try { try {
const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call( response = yield call(
fetchProtectedBranchesRequest, fetchProtectedBranchesRequest,
artifactDef.artifactType,
artifactDef.baseArtifactId, artifactDef.baseArtifactId,
isGitApiContractsEnabled,
); );
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);

View File

@ -3,9 +3,10 @@ import fetchStatusRequest from "git/requests/fetchStatusRequest";
import type { FetchStatusResponse } from "git/requests/fetchStatusRequest.types"; import type { FetchStatusResponse } from "git/requests/fetchStatusRequest.types";
import type { FetchStatusInitPayload } from "git/store/actions/fetchStatusActions"; import type { FetchStatusInitPayload } from "git/store/actions/fetchStatusActions";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
export default function* fetchStatusSaga( export default function* fetchStatusSaga(
@ -15,7 +16,18 @@ export default function* fetchStatusSaga(
let response: FetchStatusResponse | undefined; let response: FetchStatusResponse | undefined;
try { try {
response = yield call(fetchStatusRequest, artifactId); const params = { compareRemote: true };
const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
fetchStatusRequest,
artifactDef.artifactType,
artifactId,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -16,6 +16,7 @@ import { showReconnectDatasourceModal } from "ee/actions/applicationActions";
import type { Workspace } from "ee/constants/workspaceConstants"; import type { Workspace } from "ee/constants/workspaceConstants";
import { getFetchedWorkspaces } from "ee/selectors/workspaceSelectors"; import { getFetchedWorkspaces } from "ee/selectors/workspaceSelectors";
import { GitErrorCodes } from "git/constants/enums"; import { GitErrorCodes } from "git/constants/enums";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
export default function* gitImportSaga( export default function* gitImportSaga(
action: PayloadAction<GitImportInitPayload>, action: PayloadAction<GitImportInitPayload>,
@ -26,7 +27,16 @@ export default function* gitImportSaga(
let response: GitImportResponse | undefined; let response: GitImportResponse | undefined;
try { try {
response = yield call(gitImportRequest, workspaceId, params); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
gitImportRequest,
workspaceId,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -3,9 +3,10 @@ import mergeRequest from "git/requests/mergeRequest";
import type { MergeResponse } from "git/requests/mergeRequest.types"; import type { MergeResponse } from "git/requests/mergeRequest.types";
import type { MergeInitPayload } from "git/store/actions/mergeActions"; import type { MergeInitPayload } from "git/store/actions/mergeActions";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
export default function* mergeSaga( export default function* mergeSaga(
@ -20,7 +21,17 @@ export default function* mergeSaga(
destinationBranch: action.payload.destinationBranch, destinationBranch: action.payload.destinationBranch,
}; };
response = yield call(mergeRequest, artifactId, params); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
mergeRequest,
artifactDef.artifactType,
artifactId,
params,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);

View File

@ -13,6 +13,7 @@ import { initEditorAction } from "actions/initActions";
import { APP_MODE } from "entities/App"; import { APP_MODE } from "entities/App";
import log from "loglevel"; import log from "loglevel";
import { captureException } from "@sentry/react"; import { captureException } from "@sentry/react";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
export default function* pullSaga( export default function* pullSaga(
action: GitArtifactPayloadAction<PullInitPayload>, action: GitArtifactPayloadAction<PullInitPayload>,
@ -21,7 +22,16 @@ export default function* pullSaga(
let response: PullResponse | undefined; let response: PullResponse | undefined;
try { try {
response = yield call(pullRequest, artifactId); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
pullRequest,
artifactDef.artifactType,
artifactId,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (response && isValidResponse) { if (response && isValidResponse) {

View File

@ -2,9 +2,10 @@ import { captureException } from "@sentry/react";
import toggleAutocommitRequest from "git/requests/toggleAutocommitRequest"; import toggleAutocommitRequest from "git/requests/toggleAutocommitRequest";
import type { ToggleAutocommitResponse } from "git/requests/toggleAutocommitRequest.types"; import type { ToggleAutocommitResponse } from "git/requests/toggleAutocommitRequest.types";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
export default function* toggleAutocommitSaga( export default function* toggleAutocommitSaga(
@ -14,7 +15,16 @@ export default function* toggleAutocommitSaga(
let response: ToggleAutocommitResponse | undefined; let response: ToggleAutocommitResponse | undefined;
try { try {
response = yield call(toggleAutocommitRequest, artifactDef.baseArtifactId); const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call(
toggleAutocommitRequest,
artifactDef.artifactType,
artifactDef.baseArtifactId,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);
if (isValidResponse) { if (isValidResponse) {

View File

@ -27,6 +27,7 @@ import type { Task } from "redux-saga";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
import log from "loglevel"; import log from "loglevel";
import { captureException } from "@sentry/react"; import { captureException } from "@sentry/react";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
const AUTOCOMMIT_POLL_DELAY = 1000; const AUTOCOMMIT_POLL_DELAY = 1000;
const AUTOCOMMIT_WHITELISTED_STATES = [ const AUTOCOMMIT_WHITELISTED_STATES = [
@ -56,8 +57,17 @@ function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) {
const { artifactDef, artifactId } = params; const { artifactDef, artifactId } = params;
let triggerResponse: TriggerAutocommitResponse | undefined; let triggerResponse: TriggerAutocommitResponse | undefined;
const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
try { try {
triggerResponse = yield call(triggerAutocommitRequest, artifactId); triggerResponse = yield call(
triggerAutocommitRequest,
artifactDef.artifactType,
artifactId,
isGitApiContractsEnabled,
);
const isValidResponse: boolean = yield validateResponse(triggerResponse); const isValidResponse: boolean = yield validateResponse(triggerResponse);
if (triggerResponse && isValidResponse) { if (triggerResponse && isValidResponse) {
@ -88,9 +98,12 @@ function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) {
yield put( yield put(
gitArtifactActions.fetchAutocommitProgressInit({ artifactDef }), gitArtifactActions.fetchAutocommitProgressInit({ artifactDef }),
); );
progressResponse = yield call( progressResponse = yield call(
fetchAutocommitProgressRequest, fetchAutocommitProgressRequest,
artifactDef.artifactType,
artifactDef.baseArtifactId, artifactDef.baseArtifactId,
isGitApiContractsEnabled,
); );
const isValidResponse: boolean = const isValidResponse: boolean =
yield validateResponse(progressResponse); yield validateResponse(progressResponse);

View File

@ -6,10 +6,11 @@ import type {
} from "git/requests/updateLocalProfileRequest.types"; } from "git/requests/updateLocalProfileRequest.types";
import { gitArtifactActions } from "../store/gitArtifactSlice"; import { gitArtifactActions } from "../store/gitArtifactSlice";
import type { GitArtifactPayloadAction } from "../store/types"; import type { GitArtifactPayloadAction } from "../store/types";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
import log from "loglevel"; import log from "loglevel";
import { captureException } from "@sentry/react"; import { captureException } from "@sentry/react";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
export default function* updateLocalProfileSaga( export default function* updateLocalProfileSaga(
action: GitArtifactPayloadAction<UpdateLocalProfileInitPayload>, action: GitArtifactPayloadAction<UpdateLocalProfileInitPayload>,
@ -24,10 +25,16 @@ export default function* updateLocalProfileSaga(
useGlobalProfile: action.payload.useGlobalProfile, useGlobalProfile: action.payload.useGlobalProfile,
}; };
const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call( response = yield call(
updateLocalProfileRequest, updateLocalProfileRequest,
artifactDef.artifactType,
artifactDef.baseArtifactId, artifactDef.baseArtifactId,
params, params,
isGitApiContractsEnabled,
); );
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);

View File

@ -6,9 +6,10 @@ import type {
} from "git/requests/updateProtectedBranchesRequest.types"; } from "git/requests/updateProtectedBranchesRequest.types";
import type { UpdateProtectedBranchesInitPayload } from "git/store/actions/updateProtectedBranchesActions"; import type { UpdateProtectedBranchesInitPayload } from "git/store/actions/updateProtectedBranchesActions";
import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { selectGitApiContractsEnabled } from "git/store/selectors/gitFeatureFlagSelectors";
import type { GitArtifactPayloadAction } from "git/store/types"; import type { GitArtifactPayloadAction } from "git/store/types";
import log from "loglevel"; import log from "loglevel";
import { call, put } from "redux-saga/effects"; import { call, put, select } from "redux-saga/effects";
import { validateResponse } from "sagas/ErrorSagas"; import { validateResponse } from "sagas/ErrorSagas";
export default function* updateProtectedBranchesSaga( export default function* updateProtectedBranchesSaga(
@ -22,10 +23,16 @@ export default function* updateProtectedBranchesSaga(
branchNames: action.payload.branchNames, branchNames: action.payload.branchNames,
}; };
const isGitApiContractsEnabled: boolean = yield select(
selectGitApiContractsEnabled,
);
response = yield call( response = yield call(
updateProtectedBranchesRequest, updateProtectedBranchesRequest,
artifactDef.artifactType,
artifactDef.baseArtifactId, artifactDef.baseArtifactId,
params, params,
isGitApiContractsEnabled,
); );
const isValidResponse: boolean = yield validateResponse(response); const isValidResponse: boolean = yield validateResponse(response);

View File

@ -1,9 +1,9 @@
import { createArtifactAction } from "../helpers/createArtifactAction"; import { createArtifactAction } from "../helpers/createArtifactAction";
import type { GitAsyncErrorPayload } from "../types"; import type { GitAsyncErrorPayload } from "../types";
import type { CheckoutBranchRequestParams } from "git/requests/checkoutBranchRequest.types";
export interface CheckoutBranchInitPayload extends CheckoutBranchRequestParams { export interface CheckoutBranchInitPayload {
artifactId: string; artifactId: string;
branchName: string;
} }
export const checkoutBranchInitAction = export const checkoutBranchInitAction =

View File

@ -1,9 +1,9 @@
import { createArtifactAction } from "../helpers/createArtifactAction"; import { createArtifactAction } from "../helpers/createArtifactAction";
import type { GitAsyncErrorPayload } from "../types"; import type { GitAsyncErrorPayload } from "../types";
import type { CreateBranchRequestParams } from "git/requests/createBranchRequest.types";
export interface CreateBranchInitPayload extends CreateBranchRequestParams { export interface CreateBranchInitPayload {
artifactId: string; artifactId: string;
branchName: string;
} }
export const createBranchInitAction = export const createBranchInitAction =

View File

@ -1,9 +1,9 @@
import { createArtifactAction } from "../helpers/createArtifactAction"; import { createArtifactAction } from "../helpers/createArtifactAction";
import type { GitAsyncErrorPayload } from "../types"; import type { GitAsyncErrorPayload } from "../types";
import type { DeleteBranchRequestParams } from "../../requests/deleteBranchRequest.types";
export interface DeleteBranchInitPayload extends DeleteBranchRequestParams { export interface DeleteBranchInitPayload {
artifactId: string; artifactId: string;
branchName: string;
} }
export const deleteBranchInitAction = export const deleteBranchInitAction =

View File

@ -1,12 +1,10 @@
import type {
FetchBranchesRequestParams,
FetchBranchesResponseData,
} from "../../requests/fetchBranchesRequest.types";
import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types";
import { createArtifactAction } from "../helpers/createArtifactAction"; import { createArtifactAction } from "../helpers/createArtifactAction";
import type { FetchRefsResponseData } from "git/requests/fetchRefsRequest.types";
export interface FetchBranchesInitPayload extends FetchBranchesRequestParams { export interface FetchBranchesInitPayload {
artifactId: string; artifactId: string;
pruneBranches?: boolean;
} }
export const fetchBranchesInitAction = export const fetchBranchesInitAction =
@ -18,7 +16,7 @@ export const fetchBranchesInitAction =
}); });
export const fetchBranchesSuccessAction = createArtifactAction< export const fetchBranchesSuccessAction = createArtifactAction<
GitAsyncSuccessPayload<FetchBranchesResponseData> GitAsyncSuccessPayload<FetchRefsResponseData>
>((state, action) => { >((state, action) => {
state.apiResponses.branches.loading = false; state.apiResponses.branches.loading = false;
state.apiResponses.branches.value = action.payload.responseData; state.apiResponses.branches.value = action.payload.responseData;

View File

@ -0,0 +1,9 @@
import { createSelector } from "reselect";
import { selectFeatureFlags } from "ee/selectors/featureFlagsSelectors";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
export const selectGitApiContractsEnabled = createSelector(
selectFeatureFlags,
(featureFlags) =>
featureFlags[FEATURE_FLAG.release_git_api_contracts_enabled] ?? false,
);

View File

@ -5,7 +5,6 @@ import type {
GitSettingsTab, GitSettingsTab,
} from "../constants/enums"; } from "../constants/enums";
import type { FetchGlobalProfileResponseData } from "../requests/fetchGlobalProfileRequest.types"; import type { FetchGlobalProfileResponseData } from "../requests/fetchGlobalProfileRequest.types";
import type { FetchBranchesResponseData } from "../requests/fetchBranchesRequest.types";
import type { FetchLocalProfileResponseData } from "../requests/fetchLocalProfileRequest.types"; import type { FetchLocalProfileResponseData } from "../requests/fetchLocalProfileRequest.types";
import type { FetchStatusResponseData } from "git/requests/fetchStatusRequest.types"; import type { FetchStatusResponseData } from "git/requests/fetchStatusRequest.types";
import type { FetchMergeStatusResponseData } from "git/requests/fetchMergeStatusRequest.types"; import type { FetchMergeStatusResponseData } from "git/requests/fetchMergeStatusRequest.types";
@ -19,6 +18,7 @@ import type {
} from "git/ee/store/types"; } from "git/ee/store/types";
import type { FetchGlobalSSHKeyResponseData } from "git/requests/fetchGlobalSSHKeyRequest.types"; import type { FetchGlobalSSHKeyResponseData } from "git/requests/fetchGlobalSSHKeyRequest.types";
import type { ApplicationPayload } from "entities/Application"; import type { ApplicationPayload } from "entities/Application";
import type { FetchRefsResponseData } from "git/requests/fetchRefsRequest.types";
export interface GitApiError extends ApiResponseError { export interface GitApiError extends ApiResponseError {
errorType?: string; errorType?: string;
@ -45,7 +45,7 @@ export interface GitArtifactAPIResponsesReduxState
discard: GitAsyncStateWithoutValue; discard: GitAsyncStateWithoutValue;
mergeStatus: GitAsyncState<FetchMergeStatusResponseData>; mergeStatus: GitAsyncState<FetchMergeStatusResponseData>;
merge: GitAsyncStateWithoutValue; merge: GitAsyncStateWithoutValue;
branches: GitAsyncState<FetchBranchesResponseData>; branches: GitAsyncState<FetchRefsResponseData>;
checkoutBranch: GitAsyncStateWithoutValue; checkoutBranch: GitAsyncStateWithoutValue;
createBranch: GitAsyncStateWithoutValue; createBranch: GitAsyncStateWithoutValue;
deleteBranch: GitAsyncStateWithoutValue; deleteBranch: GitAsyncStateWithoutValue;
@ -68,7 +68,7 @@ export interface GitArtifactUIReduxState
connectModalOpen: boolean; connectModalOpen: boolean;
connectSuccessModalOpen: boolean; connectSuccessModalOpen: boolean;
disconnectBaseArtifactId: string | null; disconnectBaseArtifactId: string | null;
disconnectArtifactType: keyof typeof GitArtifactType | null; disconnectArtifactType: GitArtifactType | null;
disconnectArtifactName: string | null; disconnectArtifactName: string | null;
branchPopupOpen: boolean; branchPopupOpen: boolean;
checkoutDestBranch: string | null; checkoutDestBranch: string | null;
@ -85,7 +85,7 @@ export interface GitArtifactUIReduxState
export type GitArtifact = ApplicationPayload; export type GitArtifact = ApplicationPayload;
export interface GitArtifactDef { export interface GitArtifactDef {
artifactType: keyof typeof GitArtifactType; artifactType: GitArtifactType;
baseArtifactId: string; baseArtifactId: string;
} }
export interface GitArtifactReduxState { export interface GitArtifactReduxState {

View File

@ -0,0 +1,11 @@
export interface GitRef {
refName: string;
refType: string;
createdFromLocal: string;
default: boolean;
}
export interface GitBranch {
branchName: string;
default: boolean;
}