Skip to content

Commit

Permalink
chore: git api - adding new apis (#38681)
Browse files Browse the repository at this point in the history
## Description
- Introduces new api contracts for git
- Adds feature flag `release_git_api_contracts_enabled`


Fixes #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: 8f05bbf
> <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 -->
  • Loading branch information
brayn003 authored Jan 21, 2025
1 parent 16e121c commit 704e473
Show file tree
Hide file tree
Showing 73 changed files with 997 additions and 139 deletions.
2 changes: 2 additions & 0 deletions app/client/src/ce/entities/FeatureFlag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const FEATURE_FLAG = {
release_gs_all_sheets_options_enabled:
"release_gs_all_sheets_options_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",
kill_session_recordings_enabled: "kill_session_recordings_enabled",
config_mask_session_recordings_enabled:
Expand Down Expand Up @@ -92,6 +93,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
release_table_html_column_type_enabled: false,
release_gs_all_sheets_options_enabled: false,
release_git_modularisation_enabled: false,
release_git_api_contracts_enabled: false,
ab_premium_datasources_view_enabled: false,
kill_session_recordings_enabled: false,
config_user_session_recordings_enabled: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { Button, Link, Option, Select, Text } from "@appsmith/ads";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import styled from "styled-components";
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import type { FetchBranchesResponseData } from "git/requests/fetchBranchesRequest.types";
import noop from "lodash/noop";
import { useAppsmithEnterpriseUrl } from "git/hooks/useAppsmithEnterpriseUrl";
import type { GitBranch } from "git/types";

const Container = styled.div`
padding-top: 8px;
Expand Down Expand Up @@ -45,7 +45,7 @@ const StyledLink = styled(Link)`
`;

interface DefaultBranchViewProps {
branches: FetchBranchesResponseData | null;
branches: GitBranch[] | null;
isGitProtectedFeatureLicensed: boolean;
updateDefaultBranch?: (branchName: string) => void;
}
Expand Down
4 changes: 2 additions & 2 deletions app/client/src/git/components/BranchList/BranchListView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ import LocalBranchList from "./LocalBranchList";
import { useFilteredBranches } from "./hooks/useFilteredBranches";
import useActiveHoverIndex from "./hooks/useActiveHoverIndex";
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 { GitBranch } from "git/types";

const ListContainer = styled.div`
flex: 1;
Expand Down Expand Up @@ -229,7 +229,7 @@ export function Header({
}

interface BranchListViewProps {
branches: FetchBranchesResponseData | null;
branches: GitBranch[] | null;
checkoutBranch: (branch: string) => void;
checkoutDestBranch: string | null;
createBranch: (branch: string) => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import type { Branch } from "entities/GitSync";
import type { GitBranch } from "git/types";
import { useEffect, useState } from "react";

export function useFilteredBranches(
branches: Array<Branch>,
branches: Array<GitBranch>,
searchText: string,
) {
const lowercaseSearchText = searchText.toLowerCase();
const [filteredBranches, setFilteredBranches] = useState<Array<string>>([]);

useEffect(
function setFilteredBranchesEffect() {
const matched = branches.filter((b: Branch) =>
const matched = branches.filter((b) =>
lowercaseSearchText
? b.branchName.toLowerCase().includes(lowercaseSearchText)
: true,
);
const branchNames = [
...matched.filter((b: Branch) => b.default),
...matched.filter((b: Branch) => !b.default),
].map((b: Branch) => b.branchName);
...matched.filter((b) => b.default),
...matched.filter((b) => !b.default),
].map((b) => b.branchName);

setFilteredBranches(branchNames);
},
Expand Down
2 changes: 1 addition & 1 deletion app/client/src/git/components/GitContextProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const useGitContext = () => {

interface GitContextProviderProps {
// artifact
artifactType: keyof typeof GitArtifactType | null;
artifactType: GitArtifactType | null;
baseArtifactId: string | null;
artifact: ApplicationPayload | null;
artifacts: ApplicationPayload[] | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import MergeStatus from "./MergeStatus";
import ConflictError from "git/components/ConflictError";
import MergeSuccessIndicator from "./MergeSuccessIndicator";
import { noop } from "lodash";
import type { FetchBranchesResponseData } from "git/requests/fetchBranchesRequest.types";
import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types";
import type { FetchMergeStatusResponseData } from "git/requests/fetchMergeStatusRequest.types";
import type { GitApiError } from "git/store/types";
import type { GitBranch } from "git/types";

const Container = styled.div`
min-height: 360px;
Expand Down Expand Up @@ -64,7 +64,7 @@ interface BranchOption {
}

interface TabMergeViewProps {
branches: FetchBranchesResponseData | null;
branches: GitBranch[] | null;
clearMergeStatus: () => void;
currentBranch: string | null;
fetchBranches: () => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import { DOCS_BRANCH_PROTECTION_URL } from "constants/ThirdPartyConstants";
import { GIT_REMOTE_BRANCH_PREFIX } from "git/constants/misc";
import { useAppsmithEnterpriseUrl } from "git/hooks/useAppsmithEnterpriseUrl";
import type { FetchBranchesResponseData } from "git/requests/fetchBranchesRequest.types";
import xor from "lodash/xor";
import noop from "lodash/noop";
import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types";
import type { GitBranch } from "git/types";

const Container = styled.div`
padding-top: 16px;
Expand Down Expand Up @@ -50,7 +50,7 @@ const StyledLink = styled(Link)`
`;

interface ProtectedBranchesViewProps {
branches: FetchBranchesResponseData | null;
branches: GitBranch[] | null;
defaultBranch: string | null;
isProtectedBranchesLicensed: boolean;
isUpdateProtectedBranchesLoading: boolean;
Expand Down
6 changes: 3 additions & 3 deletions app/client/src/git/constants/enums.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export enum GitArtifactType {
Application = "Application",
Package = "Package",
Workflow = "Workflow",
Application = "applications",
Package = "packages",
Workflow = "workflows",
}

export enum GitOpsTab {
Expand Down
8 changes: 8 additions & 0 deletions app/client/src/git/helpers/refToBranchList.ts
Original file line number Diff line number Diff line change
@@ -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,
}));
}
21 changes: 19 additions & 2 deletions app/client/src/git/hooks/useBranches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import {
selectDeleteBranchState,
selectCurrentBranch,
} from "git/store/selectors/gitArtifactSelectors";
import { useCallback } from "react";
import { useCallback, useMemo } from "react";
import { useDispatch } from "react-redux";
import useArtifactSelector from "./useArtifactSelector";
import refToBranchList from "git/helpers/refToBranchList";
import useGitFeatureFlags from "./useGitFeatureFlags";
import type { GitBranch } from "git/types";

export default function useBranches() {
const { artifact, artifactDef } = useGitContext();
Expand All @@ -21,6 +24,20 @@ export default function useBranches() {

// fetch branches
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(() => {
if (artifactDef && artifactId) {
Expand Down Expand Up @@ -106,7 +123,7 @@ export default function useBranches() {
);

return {
branches: branchesState?.value ?? null,
branches: branches as GitBranch[] | null,
isFetchBranchesLoading: branchesState?.loading ?? false,
fetchBranchesError: branchesState?.error ?? null,
fetchBranches,
Expand Down
4 changes: 4 additions & 0 deletions app/client/src/git/hooks/useGitFeatureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ export default function useGitFeatureFlags() {
const license_git_continuous_delivery_enabled = useFeatureFlag(
FEATURE_FLAG.license_git_continuous_delivery_enabled,
);
const release_git_api_contracts_enabled = useFeatureFlag(
FEATURE_FLAG.release_git_api_contracts_enabled,
);

return {
license_git_branch_protection_enabled,
license_git_continuous_delivery_enabled,
release_git_api_contracts_enabled,
};
}
2 changes: 1 addition & 1 deletion app/client/src/git/requests/checkoutBranchRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
import { GIT_BASE_URL } from "./constants";
import Api from "api/Api";

export default async function checkoutBranchRequest(
export default async function checkoutBranchRequestOld(
branchedApplicationId: string,
params: CheckoutBranchRequestParams,
): AxiosPromise<CheckoutBranchResponse> {
Expand Down
37 changes: 37 additions & 0 deletions app/client/src/git/requests/checkoutRefRequest.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}
12 changes: 12 additions & 0 deletions app/client/src/git/requests/checkoutRefRequest.types.ts
Original file line number Diff line number Diff line change
@@ -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>;
27 changes: 26 additions & 1 deletion app/client/src/git/requests/commitRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import type {
} from "./commitRequest.types";
import { GIT_BASE_URL } from "./constants";
import type { AxiosPromise } from "axios";
import type { GitArtifactType } from "git/constants/enums";

export default async function commitRequest(
async function commitRequestOld(
branchedApplicationId: string,
params: CommitRequestParams,
): AxiosPromise<CommitResponse> {
Expand All @@ -15,3 +16,27 @@ export default async function commitRequest(
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);
}
}
27 changes: 26 additions & 1 deletion app/client/src/git/requests/connectRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,35 @@ import type {
ConnectResponse,
} from "./connectRequest.types";
import type { AxiosPromise } from "axios";
import type { GitArtifactType } from "git/constants/enums";

export default async function connectRequest(
async function connectRequestOld(
baseApplicationId: string,
params: ConnectRequestParams,
): AxiosPromise<ConnectResponse> {
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);
}
}
2 changes: 1 addition & 1 deletion app/client/src/git/requests/createBranchRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
import { GIT_BASE_URL } from "./constants";
import Api from "api/Api";

export default async function createBranchRequest(
export default async function createBranchRequestOld(
branchedApplicationId: string,
params: CreateBranchRequestParams,
): AxiosPromise<CreateBranchResponse> {
Expand Down
37 changes: 37 additions & 0 deletions app/client/src/git/requests/createRefRequest.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading

0 comments on commit 704e473

Please sign in to comment.