Skip to content

Commit

Permalink
chore: git pkg - mod fixes (#39255)
Browse files Browse the repository at this point in the history
## Description
- Introducing artifact aware permissions
- Better error handling for sagas
- New API contracts for local profile

Fixes #38505

## 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/13375089313>
> Commit: 13aa020
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13375089313&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Git`
> Spec:
> <hr>Mon, 17 Feb 2025 17:44:17 UTC
<!-- end of auto-generated comment: Cypress test results  -->


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


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

- **New Features**
- Enhanced Git integration with adaptive connection messages and success
modals that now reflect the type of artifact being handled.
- Added support for storing additional Git metadata to improve artifact
management.

- **Refactor**
- Streamlined error handling across Git operations to ensure more
reliable feedback.
- Updated permission structures and context management to deliver a more
robust and flexible Git experience.

- **Chores**
- Consolidated module organization and improved type consistency for
better maintainability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
brayn003 authored Feb 18, 2025
1 parent 88d3599 commit 242840d
Show file tree
Hide file tree
Showing 113 changed files with 1,144 additions and 853 deletions.
10 changes: 10 additions & 0 deletions app/client/src/ce/constants/PackageConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ export interface Package {
modifiedBy: string;
modifiedAt: string;
userPermissions: string[];
gitArtifactMetadata?: {
branchName: string;
defaultBranchName: string;
remoteUrl: string;
repoName: string;
browserSupportedUrl?: string;
isRepoPrivate?: boolean;
browserSupportedRemoteUrl: string;
defaultApplicationId: string;
};
}

export type PackageMetadata = Package;
13 changes: 9 additions & 4 deletions app/client/src/ce/constants/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1151,8 +1151,8 @@ export const NO_COPIED_SSH_KEY = () => "Could not copy SSH key";
// Git Branch Protection
export const UPDATE = () => "Update";
export const DEFAULT_BRANCH = () => "Default branch";
export const DEFAULT_BRANCH_DESC = () =>
"This is the base branch of the app. Users launching the app from the dashboard will see the deployed version from this branch.";
export const DEFAULT_BRANCH_DESC = (artifactNoun: string) =>
`This is the base branch of the ${artifactNoun}. Users launching the ${artifactNoun} from the dashboard will see the deployed version from this branch.`;
export const BRANCH_PROTECTION = () => "Branch protection";
export const BRANCH_PROTECTION_DESC = () =>
"Protected branches enable you to enforce Git workflows. Changes to the app are not allowed in the protected branches.";
Expand All @@ -1179,17 +1179,22 @@ export const BRANCH_PROTECTION_PROTECTED = () => "Protected";
export const GIT_CONNECT_SUCCESS_TITLE = () => "Successfully connected to Git";
export const GIT_CONNECT_SUCCESS_MESSAGE = () =>
"Now you can start collaborating with your team members by committing, merging and deploying your app";
export const GIT_CONNECT_SUCCESS_ACTION_CONTINUE = () =>
"Continue to edit application";
export const GIT_CONNECT_SUCCESS_ACTION_CONTINUE = (
artifactType: string = "applications",
) => `Continue to edit ${artifactType}`;
export const GIT_CONNECT_SUCCESS_ACTION_SETTINGS = () => "Protect your branch";
export const GIT_CONNECT_SUCCESS_PROTECTION_MSG = () =>
"We recommend protecting your default branch to have a seamless collaboration.";
export const GIT_CONNECT_SUCCESS_GENERIC_MESSAGE = (artifactType: string) =>
`You're all set! Your ${artifactType} is now connected to Git.`;
export const GIT_CONNECT_SUCCESS_REPO_NAME = () => "Repository name";
export const GIT_CONNECT_SUCCESS_DEFAULT_BRANCH = () => "Default branch";
export const GIT_CONNECT_SUCCESS_DEFAULT_BRANCH_TOOLTIP = () =>
"This is the base branch of the app. Users launching the app from the dashboard will see the deployed version from this branch.";
export const GIT_CONNECT_SUCCESS_PROTECTION_DOC_CTA = () =>
"Learn more about branch protection";
export const GIT_CONNECT_SUCCESS_GENERIC_DOC_CTA = () =>
"Learn more about how to work with Git.";
// Git Connection Success end

export const GENERAL = () => "General";
Expand Down
5 changes: 4 additions & 1 deletion app/client/src/ce/reducers/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ import type { ActiveField } from "reducers/uiReducers/activeFieldEditorReducer";
import type { SelectedWorkspaceReduxState } from "ee/reducers/uiReducers/selectedWorkspaceReducer";
import type { ConsolidatedPageLoadState } from "reducers/uiReducers/consolidatedPageLoadReducer";
import type { BuildingBlocksReduxState } from "reducers/uiReducers/buildingBlockReducer";
import type { GitArtifactRootReduxState, GitGlobalReduxState } from "git";
import type {
GitArtifactRootReduxState,
GitGlobalReduxState,
} from "git/store/types";
import { gitReducer } from "git/store";

export const reducerObject = {
Expand Down
16 changes: 0 additions & 16 deletions app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import {
import { create } from "mutative";
import { isEmpty } from "lodash";
import type { ApplicationPayload } from "entities/Application";
import { gitConnectSuccess, type GitConnectSuccessPayload } from "git";
import type { PayloadAction } from "@reduxjs/toolkit";

export const initialState: ApplicationsReduxState = {
isSavingAppName: false,
Expand Down Expand Up @@ -746,20 +744,6 @@ export const handlers = {
isSavingNavigationSetting: false,
};
},
// git
[gitConnectSuccess.type]: (
state: ApplicationsReduxState,
action: PayloadAction<GitConnectSuccessPayload>,
) => {
return {
...state,
currentApplication: {
...state.currentApplication,
gitApplicationMetadata:
action.payload.responseData.gitApplicationMetadata,
},
};
},
};

const applicationsReducer = createReducer(initialState, handlers);
Expand Down
4 changes: 3 additions & 1 deletion app/client/src/ce/sagas/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ import communityTemplateSagas from "sagas/CommunityTemplatesSagas";
import anvilSagas from "layoutSystems/anvil/integrations/sagas";
import ideSagas from "sagas/IDESaga";
import sendSideBySideWidgetHoverAnalyticsEventSaga from "sagas/AnalyticsSaga";
import gitSagas from "git/sagas";

/* Sagas that are registered by a module that is designed to be independent of the core platform */
import ternSagas from "sagas/TernSaga";
import gitSagas from "git/sagas";
import gitApplicationSagas from "git-artifact-helpers/application/sagas";

export const sagas = [
initSagas,
Expand Down Expand Up @@ -111,4 +112,5 @@ export const sagas = [
ideSagas,
sendSideBySideWidgetHoverAnalyticsEventSaga,
gitSagas,
gitApplicationSagas,
];
37 changes: 24 additions & 13 deletions app/client/src/ce/utils/permissionHelpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ export enum PERMISSION_TYPE {
MANAGE_ACTIONS = "manage:actions",
DELETE_ACTIONS = "delete:actions",
EXECUTE_ACTIONS = "execute:actions",
/* Git permissions */
CONNECT_TO_GIT = "connectToGit:applications",
MANAGE_PROTECTED_BRANCHES = "manageProtectedBranches:applications",
MANAGE_DEFAULT_BRANCH = "manageDefaultBranches:applications",
MANAGE_AUTO_COMMIT = "manageAutoCommit:applications",
/* Git application permissions */
GIT_APPLICATION_CONNECT = "connectToGit:applications",
GIT_APPLICATION_MANAGE_PROTECTED_BRANCHES = "manageProtectedBranches:applications",
GIT_APPLICATION_MANAGE_DEFAULT_BRANCH = "manageDefaultBranches:applications",
GIT_APPLICATION_MANAGE_AUTO_COMMIT = "manageAutoCommit:applications",
}

export enum LOGIC_FILTER {
Expand Down Expand Up @@ -119,22 +119,33 @@ export const hasManageWorkspaceEnvironmentPermission = (
_permissions?: string[],
) => false;

export const hasConnectToGitPermission = (permissions: string[] = []) => {
return isPermitted(permissions, PERMISSION_TYPE.CONNECT_TO_GIT);
export const hasGitAppConnectPermission = (permissions: string[] = []) => {
return isPermitted(permissions, PERMISSION_TYPE.GIT_APPLICATION_CONNECT);
};

export const hasManageProtectedBranchesPermission = (
export const hasGitAppManageProtectedBranchesPermission = (
permissions: string[] = [],
) => {
return isPermitted(permissions, PERMISSION_TYPE.MANAGE_PROTECTED_BRANCHES);
return isPermitted(
permissions,
PERMISSION_TYPE.GIT_APPLICATION_MANAGE_PROTECTED_BRANCHES,
);
};

export const hasManageDefaultBranchPermission = (
export const hasGitAppManageDefaultBranchPermission = (
permissions: string[] = [],
) => {
return isPermitted(permissions, PERMISSION_TYPE.MANAGE_DEFAULT_BRANCH);
return isPermitted(
permissions,
PERMISSION_TYPE.GIT_APPLICATION_MANAGE_DEFAULT_BRANCH,
);
};

export const hasManageAutoCommitPermission = (permissions: string[] = []) => {
return isPermitted(permissions, PERMISSION_TYPE.MANAGE_AUTO_COMMIT);
export const hasGitAppManageAutoCommitPermission = (
permissions: string[] = [],
) => {
return isPermitted(
permissions,
PERMISSION_TYPE.GIT_APPLICATION_MANAGE_AUTO_COMMIT,
);
};
16 changes: 14 additions & 2 deletions app/client/src/components/common/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useMemo } from "react";
import styled from "styled-components";
import { Card as BlueprintCard, Classes } from "@blueprintjs/core";
import { omit } from "lodash";
Expand All @@ -8,6 +8,8 @@ import type { HTMLDivProps, ICardProps } from "@blueprintjs/core";
import { Button, type MenuItemProps } from "@appsmith/ads";

import GitConnectedBadge from "./GitConnectedBadge";
import { GitCardBadge } from "git";
import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks";

type CardProps = PropsWithChildren<{
backgroundColor: string;
Expand Down Expand Up @@ -330,6 +332,16 @@ function Card({
title,
titleTestId,
}: CardProps) {
const isGitModEnabled = useGitModEnabled();

const gitBadge = useMemo(() => {
if (isGitModEnabled) {
return <GitCardBadge />;
}

return <GitConnectedBadge />;
}, [isGitModEnabled]);

return (
<Container isMobile={isMobile} onClick={primaryAction}>
<NameWrapper
Expand Down Expand Up @@ -383,7 +395,7 @@ function Card({
{Boolean(moreActionItems.length) && !isMobile && contextMenu}
</CardFooter>
</NameWrapper>
{showGitBadge && <GitConnectedBadge />}
{showGitBadge ? gitBadge : null}
</Container>
);
}
Expand Down
24 changes: 14 additions & 10 deletions app/client/src/entities/Engine/AppEditorEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { resetEditorSuccess } from "actions/initActions";
import {
fetchAllPageEntityCompletion,
setupPageAction,
updateAppStore,
} from "actions/pageActions";
import {
executePageLoadActions,
Expand Down Expand Up @@ -56,7 +57,6 @@ import type { Span } from "instrumentation/types";
import { endSpan, startNestedSpan } from "instrumentation/generateTraces";
import { getCurrentUser } from "selectors/usersSelectors";
import type { User } from "constants/userConstants";
import log from "loglevel";
import { gitArtifactActions } from "git/store/gitArtifactSlice";
import { restoreRecentEntitiesRequest } from "actions/globalSearchActions";
import {
Expand All @@ -74,7 +74,8 @@ import {
selectGitApplicationCurrentBranch,
selectGitModEnabled,
} from "selectors/gitModSelectors";
import { applicationArtifact } from "git/artifact-helpers/application";
import { getPersistentAppStore } from "constants/AppConstants";
import { applicationArtifact } from "git-artifact-helpers/application";

export default class AppEditorEngine extends AppEngine {
constructor(mode: APP_MODE) {
Expand Down Expand Up @@ -292,9 +293,8 @@ export default class AppEditorEngine extends AppEngine {
const currentApplication: ApplicationPayload = yield select(
getCurrentApplication,
);
const currentBranch: string | undefined = yield select(
selectGitApplicationCurrentBranch,
);
const currentBranch: string | undefined =
currentApplication?.gitApplicationMetadata?.branchName;

const isGitPersistBranchEnabled: boolean = yield select(
isGitPersistBranchEnabledSelector,
Expand All @@ -303,19 +303,23 @@ export default class AppEditorEngine extends AppEngine {
if (isGitPersistBranchEnabled) {
const currentUser: User = yield select(getCurrentUser);

if (currentUser?.email && currentApplication?.baseId && currentBranch) {
if (currentUser.email && currentApplication?.baseId && currentBranch) {
yield setLatestGitBranchInLocal(
currentUser.email,
currentApplication.baseId,
currentBranch,
);
} else {
log.error(
`There was an error setting the latest git branch in local - userEmail: ${!!currentUser?.email}, applicationId: ${currentApplication?.baseId}, branch: ${currentBranch}`,
);
}
}

if (currentApplication?.id) {
yield put(
updateAppStore(
getPersistentAppStore(currentApplication.id, currentBranch),
),
);
}

const [isAnotherEditorTabOpen, currentTabs] = yield call(
trackOpenEditorTabs,
currentApplication.id,
Expand Down
14 changes: 2 additions & 12 deletions app/client/src/entities/Engine/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { fetchApplication } from "ee/actions/applicationActions";
import { setAppMode, updateAppStore } from "actions/pageActions";
import { setAppMode } from "actions/pageActions";
import type { ApplicationPayload } from "entities/Application";
import {
ReduxActionErrorTypes,
ReduxActionTypes,
} from "ee/constants/ReduxActionConstants";
import { getPersistentAppStore } from "constants/AppConstants";
import type { APP_MODE } from "entities/App";
import log from "loglevel";
import { call, put, select } from "redux-saga/effects";
Expand All @@ -20,7 +19,6 @@ import { updateBranchLocally } from "actions/gitSyncActions";
import { restoreIDEEditorViewMode } from "actions/ideActions";
import type { Span } from "instrumentation/types";
import { endSpan, startNestedSpan } from "instrumentation/generateTraces";
import { selectGitApplicationCurrentBranch } from "selectors/gitModSelectors";

export interface AppEnginePayload {
applicationId?: string;
Expand Down Expand Up @@ -87,7 +85,7 @@ export default abstract class AppEngine {
rootSpan: Span,
) {
const loadAppDataSpan = startNestedSpan("AppEngine.loadAppData", rootSpan);
const { applicationId, basePageId, branch } = payload;
const { applicationId, basePageId } = payload;
const { pages } = allResponses;
const page = pages.data?.pages?.find((page) => page.baseId === basePageId);
const apiCalls: boolean = yield failFastApiCalls(
Expand All @@ -114,15 +112,7 @@ export default abstract class AppEngine {
}

const application: ApplicationPayload = yield select(getCurrentApplication);
const currentBranch: string | undefined = yield select(
selectGitApplicationCurrentBranch,
);

yield put(
updateAppStore(
getPersistentAppStore(application.id, branch || currentBranch),
),
);
const defaultPageId: string = yield select(getDefaultPageId);
const defaultPageBaseId: string = yield select(getDefaultBasePageId);
const toLoadPageId: string = page?.id || defaultPageId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GitArtifactType } from "git/constants/enums";
import type { GitArtifactDef } from "git/store/types";
import type { GitArtifactDef } from "git/types";

export default function applicationArtifact(
baseApplicationId: string,
Expand Down
Loading

0 comments on commit 242840d

Please sign in to comment.