chore: remove git release feature flags (#30962)
## Description Removes git related feature flags - `release_git_connct_v2_enabled` - `release_git_status_lite_enabled` #### PR fixes following issue(s) Fixes #30961 #### Media #### Type of change - Chore (housekeeping or task changes that don't impact user perception) > > > ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] JUnit - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced Git synchronization features including better handling of workspace creation, DSL additions, and branch protection settings. - **Refactor** - Updated Git connection methods and deployment processes for improved efficiency and reliability. - Introduced new variables and methods for more precise control over Git settings and operations. - **Tests** - Added and refactored Cypress end-to-end tests to validate new Git functionalities and synchronization processes. - **Style** - Updated components to include `data-testId` attributes for improved testability. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
d22b63277d
commit
5c74768afc
|
|
@ -80,15 +80,12 @@ describe("Git import flow ", { tags: ["@tag.Git"] }, function () {
|
|||
it("2. Import the previous app connected to Git and reconnect Postgres, MySQL and Mongo db ", () => {
|
||||
homePage.NavigateToHome();
|
||||
cy.createWorkspace();
|
||||
let newWorkspaceName;
|
||||
cy.wait("@createWorkspace").then((interception) => {
|
||||
const newWorkspaceName = interception.response.body.data.name;
|
||||
newWorkspaceName = interception.response.body.data.name;
|
||||
cy.CreateAppForWorkspace(newWorkspaceName, "gitImport");
|
||||
});
|
||||
cy.get(homePageLocators.homeIcon).click();
|
||||
agHelper.GetNClick(homePageLocators.createNew, 0);
|
||||
cy.get(homePageLocators.workspaceImportAppOption).click({ force: true });
|
||||
cy.get(".t--import-json-card").next().click();
|
||||
cy.importAppFromGit(repoName);
|
||||
gitSync.ImportAppFromGit(newWorkspaceName, repoName);
|
||||
cy.wait(5000);
|
||||
cy.get(reconnectDatasourceModal.Modal).should("be.visible");
|
||||
cy.ReconnectDatasource("TEDPostgres");
|
||||
|
|
|
|||
|
|
@ -22,17 +22,19 @@ describe("Git import empty repository", { tags: ["@tag.Git"] }, function () {
|
|||
});
|
||||
|
||||
it("1. Bug #12749 Git Import - Empty Repo NullPointerException", () => {
|
||||
cy.get(homePage.homeIcon).click();
|
||||
_.agHelper.GetNClick(homePage.createNew, 0);
|
||||
cy.get(homePage.workspaceImportAppOption).click({ force: true });
|
||||
cy.get(".t--import-json-card").next().click();
|
||||
cy.generateUUID().then((uid) => {
|
||||
repoName = uid;
|
||||
//cy.createTestGithubRepo(repoName);
|
||||
_.gitSync.CreateTestGiteaRepo(repoName);
|
||||
cy.importAppFromGit(repoName, true, failureMessage);
|
||||
_.gitSync.ImportAppFromGit(undefined, repoName, false);
|
||||
cy.wait("@importFromGit").then((interception) => {
|
||||
const status = interception.response.body.responseMeta.status;
|
||||
const message = interception.response.body.responseMeta.error.message;
|
||||
expect(status).to.be.gte(400);
|
||||
expect(message).to.contain(failureMessage);
|
||||
cy.get(gitSyncLocators.closeGitSyncModal).click();
|
||||
});
|
||||
});
|
||||
cy.get(gitSyncLocators.closeGitSyncModal).click();
|
||||
});
|
||||
after(() => {
|
||||
_.gitSync.DeleteTestGithubRepo(repoName);
|
||||
|
|
|
|||
|
|
@ -1,247 +0,0 @@
|
|||
import gitSyncLocators from "../../../../../locators/gitSyncLocators";
|
||||
import homePage from "../../../../../locators/HomePage";
|
||||
import * as _ from "../../../../../support/Objects/ObjectsCore";
|
||||
|
||||
const httpsRepoURL = "https://github.com/test/test.git";
|
||||
const invalidURL = "test";
|
||||
const invalidURLDetectedOnTheBackend = "test@";
|
||||
const invalidEmail = "test";
|
||||
const invalidEmailWithAmp = "test@hello";
|
||||
|
||||
let repoName;
|
||||
let generatedKey;
|
||||
let windowOpenSpy;
|
||||
const owner = Cypress.env("TEST_GITHUB_USER_NAME");
|
||||
describe("Git sync modal: connect tab", { tags: ["@tag.Git"] }, function () {
|
||||
before(() => {
|
||||
_.homePage.NavigateToHome();
|
||||
cy.createWorkspace();
|
||||
cy.wait("@createWorkspace").then((interception) => {
|
||||
const newWorkspaceName = interception.response.body.data.name;
|
||||
cy.CreateAppForWorkspace(newWorkspaceName, newWorkspaceName);
|
||||
});
|
||||
cy.generateUUID().then((uid) => {
|
||||
repoName = uid;
|
||||
_.gitSync.CreateTestGiteaRepo(repoName);
|
||||
//cy.createTestGithubRepo(repoName);
|
||||
});
|
||||
});
|
||||
|
||||
it("1. validates repo URL", function () {
|
||||
// open gitSync modal
|
||||
cy.get(homePage.deployPopupOptionTrigger).click({ force: true });
|
||||
cy.get(homePage.connectToGitBtn).click({ force: true });
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(`{selectAll}${httpsRepoURL}`);
|
||||
cy.contains(Cypress.env("MESSAGES").PASTE_SSH_URL_INFO());
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).should("not.exist");
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(`{selectAll}${invalidURL}`);
|
||||
cy.contains(Cypress.env("MESSAGES").PASTE_SSH_URL_INFO());
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).should("not.exist");
|
||||
|
||||
// generate key button should be disappeared if empty repo
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(`{selectAll}${""}`);
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).should("not.exist");
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(
|
||||
`{selectAll}${_.dataManager.GITEA_API_URL_TED}/${repoName}.git`,
|
||||
);
|
||||
cy.contains(Cypress.env("MESSAGES").PASTE_SSH_URL_INFO()).should(
|
||||
"not.exist",
|
||||
);
|
||||
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).should("not.be.disabled");
|
||||
|
||||
cy.intercept("POST", "/api/v1/applications/ssh-keypair/*").as(
|
||||
"generateKey",
|
||||
);
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).click();
|
||||
|
||||
cy.wait("@generateKey").then((result) => {
|
||||
generatedKey = result.response.body.data.publicKey;
|
||||
});
|
||||
});
|
||||
|
||||
it("2. validates copy key and validates repo url input after key generation", function () {
|
||||
cy.window().then((win) => {
|
||||
cy.stub(win, "prompt").returns(win.prompt).as("copyToClipboardPrompt");
|
||||
});
|
||||
|
||||
cy.get(gitSyncLocators.copySshKey).click();
|
||||
cy.wait(2000);
|
||||
cy.get(gitSyncLocators.gitRepoInput).clear().type(`${httpsRepoURL}`);
|
||||
cy.contains(Cypress.env("MESSAGES").PASTE_SSH_URL_INFO());
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).should("be.disabled");
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(`{selectAll}${invalidURL}`);
|
||||
cy.contains(Cypress.env("MESSAGES").PASTE_SSH_URL_INFO());
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).should("be.disabled");
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(
|
||||
`{selectAll}${_.dataManager.GITEA_API_URL_TED}/${repoName}.git`,
|
||||
);
|
||||
cy.contains(Cypress.env("MESSAGES").PASTE_SSH_URL_INFO()).should(
|
||||
"not.exist",
|
||||
);
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).should("not.be.disabled");
|
||||
});
|
||||
|
||||
it("3. validates git user config", function () {
|
||||
cy.get(gitSyncLocators.useGlobalGitConfig).click({ force: true });
|
||||
|
||||
// name empty invalid
|
||||
cy.get(gitSyncLocators.gitConfigNameInput).clear();
|
||||
cy.get(gitSyncLocators.gitConfigEmailInput).clear();
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).click();
|
||||
cy.contains(Cypress.env("MESSAGES").AUTHOR_NAME_CANNOT_BE_EMPTY());
|
||||
cy.contains(Cypress.env("MESSAGES").FORM_VALIDATION_INVALID_EMAIL());
|
||||
|
||||
cy.get(gitSyncLocators.gitConfigNameInput).type(`{selectAll}${owner}`);
|
||||
cy.get(gitSyncLocators.gitConfigEmailInput).clear();
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).click();
|
||||
cy.contains(Cypress.env("MESSAGES").FORM_VALIDATION_INVALID_EMAIL());
|
||||
|
||||
cy.get(gitSyncLocators.gitConfigEmailInput).type(
|
||||
`{selectAll}${Cypress.env("USERNAME")}`,
|
||||
);
|
||||
cy.get(gitSyncLocators.gitConfigNameInput).clear();
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).click();
|
||||
cy.contains(Cypress.env("MESSAGES").AUTHOR_NAME_CANNOT_BE_EMPTY());
|
||||
|
||||
// validate email
|
||||
cy.get(gitSyncLocators.gitConfigNameInput).type(`{selectAll}${owner}`);
|
||||
cy.get(gitSyncLocators.gitConfigEmailInput).type(
|
||||
`{selectAll}${invalidEmail}`,
|
||||
);
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).click();
|
||||
cy.contains(Cypress.env("MESSAGES").FORM_VALIDATION_INVALID_EMAIL());
|
||||
|
||||
cy.get(gitSyncLocators.gitConfigEmailInput).type(
|
||||
`{selectAll}${invalidEmailWithAmp}`,
|
||||
);
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).click();
|
||||
cy.contains(Cypress.env("MESSAGES").FORM_VALIDATION_INVALID_EMAIL());
|
||||
|
||||
cy.get(gitSyncLocators.gitConfigEmailInput).type(
|
||||
`{selectAll}${Cypress.env("USERNAME")}`,
|
||||
);
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).click();
|
||||
cy.contains(Cypress.env("MESSAGES").AUTHOR_NAME_CANNOT_BE_EMPTY()).should(
|
||||
"not.exist",
|
||||
);
|
||||
cy.contains(Cypress.env("MESSAGES").FORM_VALIDATION_INVALID_EMAIL()).should(
|
||||
"not.exist",
|
||||
);
|
||||
|
||||
// check git global config
|
||||
cy.get(gitSyncLocators.useGlobalGitConfig).click({ force: true });
|
||||
cy.get(gitSyncLocators.gitConfigNameInput).should("be.disabled");
|
||||
cy.get(gitSyncLocators.gitConfigEmailInput).should("be.disabled");
|
||||
|
||||
cy.window()
|
||||
.its("store")
|
||||
.invoke("getState")
|
||||
.then((state) => {
|
||||
const { authorEmail, authorName } = state.ui.gitSync.globalGitConfig;
|
||||
cy.get(gitSyncLocators.gitConfigNameInput).should(
|
||||
"have.value",
|
||||
authorName,
|
||||
);
|
||||
cy.get(gitSyncLocators.gitConfigEmailInput).should(
|
||||
"have.value",
|
||||
authorEmail,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("4. validates submit errors", function () {
|
||||
cy.get(gitSyncLocators.useGlobalGitConfig).click({ force: true });
|
||||
cy.get(gitSyncLocators.gitConfigNameInput)
|
||||
.scrollIntoView()
|
||||
.type(`{selectAll}${owner}`);
|
||||
cy.get(gitSyncLocators.gitConfigEmailInput).type(
|
||||
`{selectAll}${Cypress.env("USERNAME")}`,
|
||||
);
|
||||
cy.wait(200);
|
||||
// cy.get(gitSyncLocators.gitConnectionContainer)
|
||||
// .scrollTo("top")
|
||||
// .should("be.visible");
|
||||
cy.get(gitSyncLocators.gitRepoInput)
|
||||
.click({ force: true })
|
||||
.type(`{selectAll}${invalidURLDetectedOnTheBackend}`);
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).scrollIntoView();
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).should("be.visible");
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput)
|
||||
.scrollIntoView()
|
||||
.type(`{selectAll}${_.dataManager.GITEA_API_URL_TED}/${repoName}.git`, {
|
||||
force: true,
|
||||
});
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).scrollIntoView().click();
|
||||
cy.get(gitSyncLocators.connetStatusbar).should("exist");
|
||||
cy.wait("@connectGitLocalRepo").then((interception) => {
|
||||
const status = interception.response.body.responseMeta.status;
|
||||
expect(status).to.be.gte(400);
|
||||
// todo check for error msg based on the context
|
||||
});
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput)
|
||||
.scrollIntoView()
|
||||
.type(`{selectAll}${_.dataManager.GITEA_API_URL_TED}/${repoName}.git`, {
|
||||
force: true,
|
||||
});
|
||||
|
||||
// cy.request({
|
||||
// method: "POST",
|
||||
// url: `${GITHUB_API_BASE}/repos/${Cypress.env(
|
||||
// "TEST_GITHUB_USER_NAME",
|
||||
// )}/${repoName}/keys`,
|
||||
// headers: {
|
||||
// Authorization: `token ${Cypress.env("GITHUB_PERSONAL_ACCESS_TOKEN")}`,
|
||||
// },
|
||||
// body: {
|
||||
// title: "key0",
|
||||
// key: generatedKey,
|
||||
// read_only: true,
|
||||
// },
|
||||
// });
|
||||
|
||||
cy.request({
|
||||
method: "POST",
|
||||
url: `${_.dataManager.GITEA_API_BASE_TED}:${_.dataManager.GITEA_API_PORT_TED}/api/v1/repos/Cypress/${repoName}/keys`,
|
||||
headers: {
|
||||
Authorization: `token ${Cypress.env("GITEA_TOKEN")}`,
|
||||
},
|
||||
body: {
|
||||
title: "key1",
|
||||
key: generatedKey,
|
||||
read_only: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.get(gitSyncLocators.connectSubmitBtn).scrollIntoView().click();
|
||||
// cy.get(gitSyncLocators.connetStatusbar).should("exist");
|
||||
cy.wait("@connectGitLocalRepo").then((interception) => {
|
||||
const status = interception.response.body.responseMeta.status;
|
||||
expect(status).to.be.gte(400);
|
||||
// todo check for error msg based on the context
|
||||
});
|
||||
|
||||
// read document clicking test
|
||||
cy.get(gitSyncLocators.errorCallout).contains("Learn more");
|
||||
cy.window().then((window) => {
|
||||
windowOpenSpy = cy.stub(window, "open").callsFake((url) => {
|
||||
// todo: check if we can improve this
|
||||
expect(!!url).to.be.true;
|
||||
windowOpenSpy.restore();
|
||||
});
|
||||
});
|
||||
cy.get(gitSyncLocators.errorCallout).contains("Learn more").click();
|
||||
cy.get(gitSyncLocators.closeGitSyncModal).click();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
_.gitSync.DeleteTestGithubRepo(repoName);
|
||||
});
|
||||
});
|
||||
|
|
@ -23,10 +23,7 @@ describe("Git sync modal: deploy tab", { tags: ["@tag.Git"] }, function () {
|
|||
// The deploy preview Link should be displayed only after the first commit done
|
||||
cy.get(gitSyncLocators.bottomBarCommitButton).click();
|
||||
|
||||
// comment text input should not empty
|
||||
cy.get(gitSyncLocators.commitCommentInput)
|
||||
.should("be.disabled")
|
||||
.and("not.be.empty");
|
||||
cy.get(gitSyncLocators.commitCommentInput).should("be.disabled");
|
||||
cy.get(gitSyncLocators.commitButton).should("be.disabled");
|
||||
cy.get(gitSyncLocators.closeGitSyncModal).click();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,19 +11,20 @@ describe("Git disconnect modal:", { tags: ["@tag.Git"] }, function () {
|
|||
const newWorkspaceName = interception.response.body.data.name;
|
||||
cy.CreateAppForWorkspace(newWorkspaceName, newWorkspaceName);
|
||||
});
|
||||
cy.generateUUID().then((uid) => {
|
||||
repoName = uid;
|
||||
_.gitSync.CreateTestGiteaRepo(repoName);
|
||||
});
|
||||
});
|
||||
|
||||
it("1. should be opened with proper components", function () {
|
||||
_.gitSync.AuthorizeKeyToGitea(repoName);
|
||||
cy.get(gitSyncLocators.bottomBarCommitButton).click();
|
||||
cy.get("[data-testid=t--tab-GIT_CONNECTION]").click();
|
||||
cy.generateUUID().then((uid) => {
|
||||
_.gitSync.CreateNConnectToGit(uid);
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName = repName;
|
||||
});
|
||||
});
|
||||
cy.get(_.gitSync._bottomSettingsBtn).click();
|
||||
cy.get(_.gitSync._settingsTabGeneral).click();
|
||||
// after clicked disconnect on connection modal,
|
||||
// it should be closed and disconnect modal should be opened
|
||||
cy.get(gitSyncLocators.disconnectIcon).click();
|
||||
cy.get(_.gitSync._disconnectGitBtn).click();
|
||||
cy.get(gitSyncLocators.gitSyncModal).should("not.exist");
|
||||
cy.get(gitSyncLocators.disconnectGitModal).should("exist");
|
||||
|
||||
|
|
@ -60,12 +61,12 @@ describe("Git disconnect modal:", { tags: ["@tag.Git"] }, function () {
|
|||
});
|
||||
|
||||
it("2. should have disconnect repo button", function () {
|
||||
cy.get(gitSyncLocators.bottomBarCommitButton).click();
|
||||
cy.get("[data-testid=t--tab-GIT_CONNECTION]").click();
|
||||
cy.get(_.gitSync._bottomSettingsBtn).click();
|
||||
cy.get(_.gitSync._settingsTabGeneral).click();
|
||||
|
||||
// after clicked disconnect on connection modal,
|
||||
// it should be closed and disconnect modal should be opened
|
||||
cy.get(gitSyncLocators.disconnectIcon).click();
|
||||
cy.get(_.gitSync._disconnectGitBtn).click();
|
||||
cy.get(gitSyncLocators.disconnectButton).should("be.disabled");
|
||||
|
||||
cy.get(gitSyncLocators.disconnectAppNameInput).type(
|
||||
|
|
|
|||
|
|
@ -17,9 +17,6 @@ describe("Git Branch Protection", { tags: ["@tag.Git"] }, function () {
|
|||
const appName = "GitBranchProtect-2" + uid;
|
||||
_.homePage.CreateNewWorkspace(wsName, true);
|
||||
_.homePage.CreateAppInWorkspace(wsName, appName);
|
||||
featureFlagIntercept({
|
||||
release_git_connect_v2_enabled: true,
|
||||
});
|
||||
cy.wait(1000);
|
||||
|
||||
cy.intercept({
|
||||
|
|
@ -27,7 +24,7 @@ describe("Git Branch Protection", { tags: ["@tag.Git"] }, function () {
|
|||
url: /\/api\/v1\/git\/branch\/app\/.*\/protected/,
|
||||
}).as("gitProtectApi");
|
||||
|
||||
_.gitSync.CreateNConnectToGitV2();
|
||||
_.gitSync.CreateNConnectToGit("repoprotect", true, true, false);
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName = repName;
|
||||
cy.wait("@gitProtectApi").then((res1) => {
|
||||
|
|
|
|||
|
|
@ -21,10 +21,9 @@ const tempBranch = "feat/tempBranch";
|
|||
const tempBranch0 = "tempBranch0";
|
||||
const mainBranch = "master";
|
||||
const jsObject = "JSObject1";
|
||||
let repoName;
|
||||
|
||||
describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
||||
let repoName;
|
||||
|
||||
beforeEach(() => {
|
||||
agHelper.RestoreLocalStorageCache();
|
||||
});
|
||||
|
|
@ -33,20 +32,17 @@ describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
|||
agHelper.SaveLocalStorageCache();
|
||||
});
|
||||
|
||||
before(() => {
|
||||
it("1. Bug:10773 When user delete a resource form the child branch and merge it back to parent branch, still the deleted resource will show up in the newly created branch", () => {
|
||||
homePage.NavigateToHome();
|
||||
cy.createWorkspace();
|
||||
cy.wait("@createWorkspace").then((interception) => {
|
||||
const newWorkspaceName = interception.response.body.data.name;
|
||||
cy.CreateAppForWorkspace(newWorkspaceName, newWorkspaceName);
|
||||
cy.CreateAppForWorkspace(newWorkspaceName, "app-1");
|
||||
gitSync.CreateNConnectToGit();
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName = repName;
|
||||
});
|
||||
});
|
||||
gitSync.CreateNConnectToGit(repoName);
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName = repName;
|
||||
});
|
||||
});
|
||||
|
||||
it("1. Bug:10773 When user delete a resource form the child branch and merge it back to parent branch, still the deleted resource will show up in the newly created branch", () => {
|
||||
// adding a new page "ChildPage" to master
|
||||
cy.Createpage(pagename);
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
|
|
@ -75,6 +71,7 @@ describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
|||
gitSync.CreateGitBranch(tempBranch0, false);
|
||||
PageLeftPane.expandCollapseItem("Pages");
|
||||
PageLeftPane.assertAbsence(pagename);
|
||||
gitSync.DeleteTestGithubRepo(repoName);
|
||||
});
|
||||
|
||||
it("2. Connect app to git, clone the Page ,verify JSobject duplication should not happen and validate data binding in deploy mode and edit mode", () => {
|
||||
|
|
@ -82,14 +79,15 @@ describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
|||
cy.createWorkspace();
|
||||
cy.wait("@createWorkspace").then((interception) => {
|
||||
const newWorkspaceName = interception.response.body.data.name;
|
||||
cy.CreateAppForWorkspace(newWorkspaceName, newWorkspaceName);
|
||||
cy.CreateAppForWorkspace(newWorkspaceName, "app-2");
|
||||
agHelper.AddDsl("JsObjecWithGitdsl");
|
||||
// connect app to git
|
||||
gitSync.CreateNConnectToGit();
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName = repName;
|
||||
});
|
||||
});
|
||||
// connect app to git
|
||||
gitSync.CreateNConnectToGit(repoName);
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName = repName;
|
||||
});
|
||||
|
||||
// create JS Object and validate its data on Page1
|
||||
jsEditor.CreateJSObject('return "Success";');
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
|
|
@ -201,7 +199,7 @@ describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
|||
const commitInputDisabled =
|
||||
state.ui.gitSync.gitStatus?.isClean ||
|
||||
state.ui.gitSync.isCommitting;
|
||||
cy.log("commitInputDisabled is " + commitInputDisabled);
|
||||
|
||||
if (!commitInputDisabled) {
|
||||
cy.commitAndPush();
|
||||
}
|
||||
|
|
@ -254,30 +252,19 @@ describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
|||
cy.CreateAppForWorkspace(newWorkspaceName, `${newWorkspaceName}app`);
|
||||
|
||||
cy.generateUUID().then((uid) => {
|
||||
const owner = Cypress.env("TEST_GITHUB_USER_NAME");
|
||||
repoName = uid;
|
||||
gitSync.CreateTestGiteaRepo(repoName);
|
||||
//cy.createTestGithubRepo(repoName);
|
||||
gitSync.OpenGitSyncModal();
|
||||
|
||||
// open gitSync modal
|
||||
cy.get(homePageLocators.deployPopupOptionTrigger).click();
|
||||
cy.get(homePageLocators.connectToGitBtn).click({ force: true });
|
||||
agHelper.GetNClick(gitSync.providerRadioOthers);
|
||||
agHelper.GetNClick(gitSync.existingEmptyRepoYes);
|
||||
agHelper.GetNClick(gitSync.gitConnectNextBtn);
|
||||
agHelper.TypeText(
|
||||
gitSync.remoteUrlInput,
|
||||
`${dataManager.GITEA_API_URL_TED}/${repoName}.git`,
|
||||
);
|
||||
agHelper.GetNClick(gitSync.gitConnectNextBtn);
|
||||
|
||||
cy.intercept(
|
||||
{
|
||||
url: "api/v1/git/connect/*",
|
||||
hostname: window.location.host,
|
||||
},
|
||||
(req) => {
|
||||
req.headers["origin"] = "Cypress";
|
||||
},
|
||||
);
|
||||
cy.intercept("POST", "/api/v1/applications/ssh-keypair/*").as(
|
||||
`generateKey-${repoName}`,
|
||||
);
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(
|
||||
`{selectAll}${dataManager.GITEA_API_URL_TED}/${repoName}.git`,
|
||||
);
|
||||
// abort git flow after generating key
|
||||
cy.get(gitSyncLocators.closeGitSyncModal).click();
|
||||
});
|
||||
|
|
@ -288,9 +275,4 @@ describe("Git sync Bug #10773", { tags: ["@tag.Git"] }, function () {
|
|||
cy.SearchApp(`${newWorkspaceName}app`);
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
//clean up
|
||||
gitSync.DeleteTestGithubRepo(repoName);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,11 +25,7 @@ describe("Git Connect V2", { tags: ["@tag.Git"] }, function () {
|
|||
});
|
||||
|
||||
it("Testing connect to git flow - V2", function () {
|
||||
featureFlagIntercept({
|
||||
release_git_connect_v2_enabled: true,
|
||||
});
|
||||
|
||||
_.gitSync.CreateNConnectToGitV2();
|
||||
_.gitSync.CreateNConnectToGit();
|
||||
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName = repName;
|
||||
|
|
@ -37,10 +33,6 @@ describe("Git Connect V2", { tags: ["@tag.Git"] }, function () {
|
|||
});
|
||||
|
||||
it("Testing import via git flow - V2", function () {
|
||||
featureFlagIntercept({
|
||||
release_git_connect_v2_enabled: true,
|
||||
});
|
||||
|
||||
_.gitSync.CreateGitBranch("test", true);
|
||||
cy.get("@gitbranchName").then((bName) => {
|
||||
branchName = bName;
|
||||
|
|
@ -49,7 +41,7 @@ describe("Git Connect V2", { tags: ["@tag.Git"] }, function () {
|
|||
_.propPane.UpdatePropertyFieldValue("Text", "Hello World");
|
||||
_.gitSync.CommitAndPush();
|
||||
|
||||
_.gitSync.ImportAppFromGitV2(ws2Name, repoName);
|
||||
_.gitSync.ImportAppFromGit(ws2Name, repoName);
|
||||
_.gitSync.SwitchGitBranch(branchName);
|
||||
EditorNavigation.SelectEntityByName("MyText", EntityType.Widget);
|
||||
_.propPane.ValidatePropertyFieldValue("Text", "Hello World");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { featureFlagIntercept } from "../../../../../support/Objects/FeatureFlags";
|
||||
import * as _ from "../../../../../support/Objects/ObjectsCore";
|
||||
|
||||
let wsName: string;
|
||||
|
|
@ -20,41 +19,7 @@ describe("Git Connect V2", { tags: ["@tag.Git"] }, function () {
|
|||
});
|
||||
});
|
||||
|
||||
it("Issue 26038 - 1 : Simultaneous git status and remote compare api calls on commit modal", function () {
|
||||
featureFlagIntercept({
|
||||
release_git_status_lite_enabled: true,
|
||||
});
|
||||
|
||||
cy.wait(1000);
|
||||
|
||||
cy.intercept({
|
||||
method: "GET",
|
||||
url: "/api/v1/git/fetch/remote/app/**",
|
||||
}).as("gitRemoteStatusApi");
|
||||
|
||||
cy.intercept({
|
||||
method: "GET",
|
||||
url: "/api/v1/git/status/app/**",
|
||||
query: { compareRemote: "false" },
|
||||
}).as("gitStatusApi");
|
||||
|
||||
_.agHelper.GetNClick(_.locators._publishButton);
|
||||
|
||||
cy.wait("@gitRemoteStatusApi").then((res1) => {
|
||||
expect(res1.response).to.have.property("statusCode", 200);
|
||||
cy.wait("@gitStatusApi").then((res2) => {
|
||||
expect(res2.response).to.have.property("statusCode", 200);
|
||||
|
||||
_.agHelper.GetNClick(_.locators._dialogCloseButton);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Issue 26038 - 2 : Simultaneous git status and remote compare api calls on commit modal", function () {
|
||||
featureFlagIntercept({
|
||||
release_git_status_lite_enabled: false,
|
||||
});
|
||||
|
||||
it("Issue 26038 : No simultaneous git status and remote compare api calls on commit modal", function () {
|
||||
cy.wait(1000);
|
||||
|
||||
cy.intercept({
|
||||
|
|
@ -71,34 +36,6 @@ describe("Git Connect V2", { tags: ["@tag.Git"] }, function () {
|
|||
});
|
||||
});
|
||||
|
||||
it("Issue 28462 : Simultaneous git status and remote compare api calls on canvas load", function () {
|
||||
featureFlagIntercept({
|
||||
release_git_status_lite_enabled: true,
|
||||
});
|
||||
|
||||
cy.wait(1000);
|
||||
|
||||
cy.intercept({
|
||||
method: "GET",
|
||||
url: "/api/v1/git/fetch/remote/app/**",
|
||||
}).as("gitRemoteStatusApi");
|
||||
|
||||
cy.intercept({
|
||||
method: "GET",
|
||||
url: "/api/v1/git/status/app/**",
|
||||
query: { compareRemote: "false" },
|
||||
}).as("gitStatusApi");
|
||||
|
||||
cy.reload();
|
||||
|
||||
cy.wait("@gitRemoteStatusApi").then((res1) => {
|
||||
expect(res1.response).to.have.property("statusCode", 200);
|
||||
cy.wait("@gitStatusApi").then((res2) => {
|
||||
expect(res2.response).to.have.property("statusCode", 200);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
_.gitSync.DeleteTestGithubRepo(repoName);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
import gitSyncLocators from "../../../../../locators/gitSyncLocators";
|
||||
import homePage from "../../../../../locators/HomePage";
|
||||
import * as _ from "../../../../../support/Objects/ObjectsCore";
|
||||
|
||||
const httpsRepoURL = "https://github.com/test/test.git";
|
||||
const invalidURL = "test";
|
||||
|
||||
let repoName: string;
|
||||
let generatedKey;
|
||||
let windowOpenSpy: any;
|
||||
describe(
|
||||
"Git sync modal: Learn more links",
|
||||
{ tags: ["@tag.Git"] },
|
||||
function () {
|
||||
it("1. validates repo URL", function () {
|
||||
// open gitSync modal
|
||||
cy.get(homePage.deployPopupOptionTrigger).click({ force: true });
|
||||
cy.get(homePage.connectToGitBtn).click({ force: true });
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(`{selectAll}${httpsRepoURL}`);
|
||||
cy.contains(Cypress.env("MESSAGES").PASTE_SSH_URL_INFO());
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).should("not.exist");
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(`{selectAll}${invalidURL}`);
|
||||
cy.contains(Cypress.env("MESSAGES").PASTE_SSH_URL_INFO());
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).should("not.exist");
|
||||
|
||||
// generate key button should be disappeared if empty repo
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(`{selectAll}${""}`);
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).should("not.exist");
|
||||
|
||||
cy.get(gitSyncLocators.gitRepoInput).type(
|
||||
`{selectAll}${_.dataManager.GITEA_API_URL_TED}/${repoName}.git`,
|
||||
);
|
||||
cy.contains(Cypress.env("MESSAGES").PASTE_SSH_URL_INFO()).should(
|
||||
"not.exist",
|
||||
);
|
||||
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).should("not.be.disabled");
|
||||
|
||||
cy.intercept("POST", "/api/v1/applications/ssh-keypair/*").as(
|
||||
"generateKey",
|
||||
);
|
||||
|
||||
// Stubbing window.open
|
||||
// cy.window().then((window) => {
|
||||
// windowOpenSpy = cy.stub(window, "open").callsFake((url) => {
|
||||
// expect(url.startsWith("https://docs.appsmith.com/")).to.be.true;
|
||||
// windowOpenSpy.restore();
|
||||
// });
|
||||
// });
|
||||
|
||||
cy.window().then((window) => {
|
||||
windowOpenSpy = cy.stub(window, "open").callsFake((url) => {
|
||||
if (
|
||||
url.includes(
|
||||
"/version-control-with-git/connecting-to-git-repository",
|
||||
)
|
||||
) {
|
||||
expect(url).to.contain(
|
||||
"/version-control-with-git/connecting-to-git-repository",
|
||||
);
|
||||
} else if (url.includes("overview/managing-deploy-keys")) {
|
||||
expect(url).to.contain("overview/managing-deploy-keys");
|
||||
}
|
||||
windowOpenSpy.restore();
|
||||
});
|
||||
});
|
||||
|
||||
// Click the "Learn more" link
|
||||
cy.get(gitSyncLocators.learnMoreSshUrl).click();
|
||||
cy.get(gitSyncLocators.generateDeployKeyBtn).click();
|
||||
|
||||
cy.wait("@generateKey").then((result: any) => {
|
||||
generatedKey = result.response.body.data.publicKey;
|
||||
});
|
||||
cy.xpath(gitSyncLocators.learnMoreDeployKey).click({ force: true });
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
@ -30,14 +30,11 @@ describe("Pre git connection spec:", { tags: ["@tag.Git"] }, function () {
|
|||
|
||||
// connect to git
|
||||
_.agHelper.GetNClick(homePage.connectToGitBtn);
|
||||
|
||||
cy.get(gitSyncLocators.gitSyncModal);
|
||||
cy.contains("Git connection").should("have.attr", "aria-selected", "true");
|
||||
|
||||
_.agHelper.AssertElementVisibility(gitSyncLocators.gitSyncModal);
|
||||
cy.get(gitSyncLocators.closeGitSyncModal).click();
|
||||
|
||||
cy.get(gitSyncLocators.connectGitBottomBar).click();
|
||||
cy.get(gitSyncLocators.gitSyncModal);
|
||||
cy.contains("Git connection").should("have.attr", "aria-selected", "true");
|
||||
_.agHelper.AssertElementVisibility(gitSyncLocators.gitSyncModal);
|
||||
cy.get(gitSyncLocators.closeGitSyncModal).click();
|
||||
});
|
||||
});
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
import gitSyncLocators from "../../../../../locators/gitSyncLocators";
|
||||
import {
|
||||
agHelper,
|
||||
homePage,
|
||||
gitSync,
|
||||
} from "../../../../../support/Objects/ObjectsCore";
|
||||
|
||||
describe("Git regenerate SSH key flow", { tags: ["@tag.Git"] }, function () {
|
||||
let repoName;
|
||||
|
||||
it("1. Verify SSH key regeneration flow ", () => {
|
||||
homePage.NavigateToHome();
|
||||
agHelper.GenerateUUID();
|
||||
cy.get("@guid").then((uid) => {
|
||||
homePage.CreateNewWorkspace("ssh_" + uid);
|
||||
homePage.CreateAppInWorkspace("ssh_" + uid);
|
||||
});
|
||||
gitSync.CreateNConnectToGit(repoName);
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName = repName;
|
||||
cy.regenerateSSHKey(repoName);
|
||||
});
|
||||
agHelper.ClickOutside();
|
||||
cy.wait(2000);
|
||||
});
|
||||
|
||||
it("2. Verify error meesage is displayed when ssh key is not added to github and verify RSA SSH key regeneration flow", () => {
|
||||
cy.wait(2000);
|
||||
cy.get(gitSyncLocators.bottomBarCommitButton).click();
|
||||
cy.get('[data-testid="t--tab-GIT_CONNECTION"]').click();
|
||||
cy.wait(2000);
|
||||
cy.get(gitSyncLocators.SSHKeycontextmenu).eq(2).click();
|
||||
cy.get(gitSyncLocators.regenerateSSHKeyECDSA).click();
|
||||
cy.contains(Cypress.env("MESSAGES").REGENERATE_KEY_CONFIRM_MESSAGE());
|
||||
cy.xpath(gitSyncLocators.confirmButton).click();
|
||||
agHelper.RefreshPage();
|
||||
cy.wait(2000);
|
||||
cy.validateToastMessage(Cypress.env("MESSAGES").ERROR_GIT_AUTH_FAIL());
|
||||
cy.wait("@gitStatus");
|
||||
cy.wait("@gitStatus").should(
|
||||
"have.nested.property",
|
||||
"response.body.responseMeta.status",
|
||||
400,
|
||||
);
|
||||
cy.regenerateSSHKey(repoName, true, "RSA");
|
||||
cy.get("body").click(0, 0, { force: true });
|
||||
cy.wait(2000);
|
||||
});
|
||||
after(() => {
|
||||
gitSync.DeleteTestGithubRepo(repoName);
|
||||
cy.DeleteAppByApi();
|
||||
});
|
||||
});
|
||||
|
|
@ -32,26 +32,26 @@ describe(
|
|||
homePage.NavigateToHome();
|
||||
homePage.CreateNewApplication();
|
||||
onboarding.closeIntroModal();
|
||||
gitSync.CreateNConnectToGit(repoName1, true, true);
|
||||
gitSync.CreateNConnectToGit(repoName1, true, true, false);
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName1 = repName;
|
||||
});
|
||||
homePage.NavigateToHome();
|
||||
homePage.CreateNewApplication();
|
||||
onboarding.closeIntroModal();
|
||||
gitSync.CreateNConnectToGit(repoName2, true, true);
|
||||
gitSync.CreateNConnectToGit(repoName2, true, true, false);
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName2 = repName;
|
||||
});
|
||||
homePage.NavigateToHome();
|
||||
homePage.CreateNewApplication();
|
||||
gitSync.CreateNConnectToGit(repoName3, true, true);
|
||||
gitSync.CreateNConnectToGit(repoName3, true, true, false);
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName3 = repName;
|
||||
});
|
||||
homePage.NavigateToHome();
|
||||
homePage.CreateNewApplication();
|
||||
gitSync.CreateNConnectToGit(repoName4, false, true);
|
||||
gitSync.CreateNConnectToGit(repoName4, false, true, false);
|
||||
cy.get("@gitRepoName").then((repName) => {
|
||||
repoName4 = repName;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ export class GitSync {
|
|||
public _gitSyncModal = "[data-testid=t--git-sync-modal]";
|
||||
private _closeGitSyncModal =
|
||||
"//div[@data-testid='t--git-sync-modal']//button[@aria-label='Close']";
|
||||
private _closeGitSettingsModal =
|
||||
"//div[@data-testid='t--git-settings-modal']//button[@aria-label='Close']";
|
||||
//private _closeGitSyncModal = ".ads-v2-modal__content-header-close-button";
|
||||
private _gitRepoInput =
|
||||
"//label[text()='Remote URL']/following-sibling::div//input";
|
||||
|
|
@ -54,6 +56,14 @@ export class GitSync {
|
|||
"[data-testid='t--git-protected-branches-select']";
|
||||
public _protectedBranchesUpdateBtn =
|
||||
"[data-testid='t--git-protected-branches-update-btn']";
|
||||
public _settingsTabBranch = "[data-testid='t--tab-BRANCH']";
|
||||
public _settingsTabGeneral = "[data-testid='t--tab-GENERAL']";
|
||||
public _branchProtectionSelectDropdown =
|
||||
"[data-testid='t--git-protected-branches-select']";
|
||||
public _branchProtectionUpdateBtn =
|
||||
"[data-testid='t--git-protected-branches-update-btn']";
|
||||
public _disconnectGitBtn = "[data-testid='t--git-disconnect-btn']";
|
||||
public _mergeLoader = "[data-testid='t--git-merge-loader']";
|
||||
|
||||
OpenGitSyncModal() {
|
||||
this.agHelper.GetNClick(this._connectGitBottomBar);
|
||||
|
|
@ -65,24 +75,6 @@ export class GitSync {
|
|||
this.agHelper.AssertElementAbsence(this._gitSyncModal);
|
||||
}
|
||||
|
||||
CreateNConnectToGit(
|
||||
repoName = "Repo",
|
||||
assertConnect = true,
|
||||
privateFlag = false,
|
||||
) {
|
||||
this.agHelper.GenerateUUID();
|
||||
cy.get("@guid").then((uid) => {
|
||||
repoName += uid;
|
||||
this.CreateTestGiteaRepo(repoName, privateFlag);
|
||||
//this.CreateLocalGithubRepo(repoName);
|
||||
this.AuthorizeKeyToGitea(repoName, assertConnect);
|
||||
// cy.get("@remoteUrl").then((remoteUrl: any) => {
|
||||
// this.AuthorizeLocalGitSSH(remoteUrl);
|
||||
// });
|
||||
cy.wrap(repoName).as("gitRepoName");
|
||||
});
|
||||
}
|
||||
|
||||
public CreateTestGiteaRepo(repo: string, privateFlag = false) {
|
||||
cy.request({
|
||||
method: "POST",
|
||||
|
|
@ -97,86 +89,6 @@ export class GitSync {
|
|||
});
|
||||
}
|
||||
|
||||
public AuthorizeKeyToGitea(
|
||||
repo: string,
|
||||
assertConnect = true,
|
||||
importFlow = false,
|
||||
) {
|
||||
let generatedKey,
|
||||
submitBtnName = importFlow ? "Import" : "Connect";
|
||||
if (!importFlow) {
|
||||
this.OpenGitSyncModal();
|
||||
cy.intercept("POST", "/api/v1/applications/ssh-keypair/*").as(
|
||||
`generateKey-${repo}`,
|
||||
);
|
||||
} else {
|
||||
cy.intercept("GET", "api/v1/git/import/keys?keyType=ECDSA").as(
|
||||
`generateKey-${repo}`,
|
||||
);
|
||||
}
|
||||
this.agHelper.AssertAttribute(
|
||||
this._gitRepoInput,
|
||||
"placeholder",
|
||||
"git@example.com:user/repository.git",
|
||||
);
|
||||
this.agHelper.TypeText(
|
||||
this._gitRepoInput,
|
||||
`${this.dataManager.GITEA_API_URL_TED}/${repo}.git`,
|
||||
//`git@github.com:${owner}/${repo}.git`,
|
||||
);
|
||||
|
||||
this.agHelper.ClickButton("Generate key");
|
||||
this.agHelper.GenerateUUID();
|
||||
cy.get("@guid").then((uid) => {
|
||||
this.assertHelper.AssertNetworkStatus("@generateKey-" + repo, [200, 201]);
|
||||
cy.get(`@generateKey-${repo}`).then((result: any) => {
|
||||
generatedKey = result.response.body.data.publicKey;
|
||||
generatedKey = generatedKey.slice(0, generatedKey.length - 1);
|
||||
// fetch the generated key and post to the github repo
|
||||
cy.request({
|
||||
method: "POST",
|
||||
url: `${this.dataManager.GITEA_API_BASE_TED}:${this.dataManager.GITEA_API_PORT_TED}/api/v1/repos/Cypress/${repo}/keys`,
|
||||
headers: {
|
||||
Authorization: `token ${Cypress.env("GITEA_TOKEN")}`,
|
||||
},
|
||||
body: {
|
||||
title: "key_" + uid,
|
||||
key: generatedKey,
|
||||
read_only: false,
|
||||
},
|
||||
}).then((resp: any) => {
|
||||
cy.log("Deploy Key Id ", resp.body.key_id);
|
||||
cy.wrap(resp.body.key_id).as("deployKeyId");
|
||||
});
|
||||
});
|
||||
});
|
||||
this.agHelper.GetNClick(this._useDefaultConfig); //Uncheck the Use default configuration
|
||||
this.agHelper.TypeText(
|
||||
this._gitConfigNameInput,
|
||||
"testusername",
|
||||
//`{selectall}${testUsername}`,
|
||||
);
|
||||
this.agHelper.TypeText(this._gitConfigEmailInput, "test@test.com");
|
||||
|
||||
this.agHelper.ClickButton(submitBtnName);
|
||||
|
||||
if (assertConnect) {
|
||||
if (!importFlow) {
|
||||
this.assertHelper.AssertNetworkStatus("@connectGitLocalRepo");
|
||||
this.agHelper.AssertElementExist(this._bottomBarCommit, 0, 30000);
|
||||
this.CloseGitSyncModal();
|
||||
this.agHelper.Sleep(2000); //for generatedKey to be available in CI runs
|
||||
this.assertHelper.AssertNetworkStatus("@generatedKey", 201);
|
||||
} else {
|
||||
this.assertHelper.AssertContains(
|
||||
"Error while accessing the file system",
|
||||
"not.exist",
|
||||
);
|
||||
this.assertHelper.AssertNetworkStatus("@importFromGit", 201);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private providerRadioOthers = "[data-testid='t--git-provider-radio-others']";
|
||||
private existingEmptyRepoYes = "[data-testid='t--existing-empty-repo-yes']";
|
||||
private gitConnectNextBtn = "[data-testid='t--git-connect-next-button']";
|
||||
|
|
@ -187,10 +99,11 @@ export class GitSync {
|
|||
"[data-testid='t--git-success-modal-start-using-git-cta']";
|
||||
private existingRepoCheckbox = "[data-testid='t--existing-repo-checkbox']";
|
||||
|
||||
CreateNConnectToGitV2(
|
||||
CreateNConnectToGit(
|
||||
repoName = "Repo",
|
||||
assertConnect = true,
|
||||
privateFlag = false,
|
||||
removeDefaultBranchProtection = true,
|
||||
) {
|
||||
this.agHelper.GenerateUUID();
|
||||
cy.get("@guid").then((uid) => {
|
||||
|
|
@ -201,6 +114,14 @@ export class GitSync {
|
|||
`generateKey-${repoName}`,
|
||||
);
|
||||
|
||||
cy.intercept("GET", "/api/v1/git/branch/app/*/protected").as(
|
||||
`protected-${repoName}`,
|
||||
);
|
||||
|
||||
cy.intercept("GET", "/api/v1/git/branch/app/*").as(
|
||||
`branches-${repoName}`,
|
||||
);
|
||||
|
||||
this.OpenGitSyncModal();
|
||||
|
||||
this.agHelper.GetNClick(this.providerRadioOthers);
|
||||
|
|
@ -249,11 +170,24 @@ export class GitSync {
|
|||
this.agHelper.AssertElementExist(this._bottomBarCommit, 0, 30000);
|
||||
}
|
||||
|
||||
if (removeDefaultBranchProtection) {
|
||||
cy.wait([`@protected-${repoName}`, `@branches-${repoName}`]).then(
|
||||
(interceptions) => {
|
||||
if (
|
||||
interceptions[0]?.response?.statusCode === 200 &&
|
||||
interceptions[1]?.response?.statusCode === 200
|
||||
) {
|
||||
this.clearBranchProtection();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
cy.wrap(repoName).as("gitRepoName");
|
||||
});
|
||||
}
|
||||
|
||||
public ImportAppFromGitV2(
|
||||
public ImportAppFromGit(
|
||||
workspaceName: string,
|
||||
repoName: string,
|
||||
assertConnect = true,
|
||||
|
|
@ -309,13 +243,21 @@ export class GitSync {
|
|||
}
|
||||
}
|
||||
|
||||
public ImportAppFromGit(
|
||||
workspaceName: string,
|
||||
repo: string,
|
||||
assertConnect = true,
|
||||
) {
|
||||
this.homePage.ImportGitApp(workspaceName);
|
||||
this.AuthorizeKeyToGitea(repo, assertConnect, true);
|
||||
public clearBranchProtection() {
|
||||
this.agHelper.GetNClick(this._bottomSettingsBtn);
|
||||
this.agHelper.GetNClick(this._settingsTabBranch);
|
||||
this.agHelper.GetNClick(this._branchProtectionSelectDropdown);
|
||||
// const dropdownEl = this.agHelper.GetElement(this._protectedBranchesSelect);
|
||||
const selectedOptionsEl = this.agHelper.GetElement(
|
||||
".rc-select-dropdown .rc-select-item-option-active",
|
||||
);
|
||||
console.log("ss", selectedOptionsEl);
|
||||
selectedOptionsEl.each((el) => {
|
||||
el.trigger("click");
|
||||
});
|
||||
|
||||
this.agHelper.GetNClick(this._branchProtectionUpdateBtn);
|
||||
this.agHelper.GetNClick(this._closeGitSettingsModal);
|
||||
}
|
||||
|
||||
DeleteTestGithubRepo(repo: any) {
|
||||
|
|
|
|||
|
|
@ -623,8 +623,8 @@ export class HomePage {
|
|||
.GetElement(this._leftPanel)
|
||||
.contains("span", intoWorkspaceName)
|
||||
.click();
|
||||
this.agHelper.GetNClick(this._newIcon);
|
||||
} else this.agHelper.GetNClick(this._optionsIcon);
|
||||
}
|
||||
this.agHelper.GetNClick(this._newIcon);
|
||||
this.agHelper.GetNClick(this._workspaceImport, 0, true);
|
||||
this.agHelper.AssertElementVisibility(this._workspaceImportAppModal);
|
||||
this.agHelper.GetNClick(this._importFromGitBtn);
|
||||
|
|
|
|||
|
|
@ -295,6 +295,11 @@ Cypress.Commands.add(
|
|||
|
||||
Cypress.Commands.add("merge", (destinationBranch) => {
|
||||
agHelper.AssertElementExist(gitSync._bottomBarPull);
|
||||
|
||||
cy.intercept("GET", "/api/v1/git/status/app/*").as(`gitStatus`);
|
||||
|
||||
cy.intercept("GET", "/api/v1/git/branch/app/*").as(`gitBranches`);
|
||||
|
||||
cy.get(gitSyncLocators.bottomBarMergeButton).click({ force: true });
|
||||
//cy.wait(6000); // wait for git status call to finish
|
||||
/*cy.wait("@gitStatus").should(
|
||||
|
|
@ -308,21 +313,28 @@ Cypress.Commands.add("merge", (destinationBranch) => {
|
|||
0,
|
||||
false,
|
||||
);
|
||||
cy.wait(6000);
|
||||
cy.get(gitSyncLocators.mergeBranchDropdownDestination).click();
|
||||
cy.get(commonLocators.dropdownmenu).contains(destinationBranch).click();
|
||||
agHelper.AssertElementAbsence(gitSync._checkMergeability, 35000);
|
||||
assertHelper.WaitForNetworkCall("mergeStatus");
|
||||
cy.get("@mergeStatus").should(
|
||||
"have.nested.property",
|
||||
"response.body.data.isMergeAble",
|
||||
true,
|
||||
);
|
||||
cy.wait(2000);
|
||||
cy.contains(Cypress.env("MESSAGES").NO_MERGE_CONFLICT());
|
||||
cy.get(gitSyncLocators.mergeCTA).click();
|
||||
assertHelper.AssertNetworkStatus("mergeBranch", 200);
|
||||
agHelper.AssertContains(Cypress.env("MESSAGES").MERGED_SUCCESSFULLY());
|
||||
agHelper.WaitUntilEleDisappear(gitSync._mergeLoader);
|
||||
cy.wait(["@gitBranches", "@gitStatus"]).then((interceptions) => {
|
||||
if (
|
||||
interceptions[0]?.response?.statusCode === 200 &&
|
||||
interceptions[1]?.response?.statusCode === 200
|
||||
) {
|
||||
cy.get(gitSyncLocators.mergeBranchDropdownDestination).click();
|
||||
cy.get(commonLocators.dropdownmenu).contains(destinationBranch).click();
|
||||
agHelper.AssertElementAbsence(gitSync._checkMergeability, 35000);
|
||||
assertHelper.WaitForNetworkCall("mergeStatus");
|
||||
cy.get("@mergeStatus").should(
|
||||
"have.nested.property",
|
||||
"response.body.data.isMergeAble",
|
||||
true,
|
||||
);
|
||||
cy.wait(2000);
|
||||
cy.contains(Cypress.env("MESSAGES").NO_MERGE_CONFLICT());
|
||||
cy.get(gitSyncLocators.mergeCTA).click();
|
||||
assertHelper.AssertNetworkStatus("mergeBranch", 200);
|
||||
agHelper.AssertContains(Cypress.env("MESSAGES").MERGED_SUCCESSFULLY());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add(
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ import type { GitConfig, GitSyncModalTab, MergeStatus } from "entities/GitSync";
|
|||
import type { GitApplicationMetadata } from "@appsmith/api/ApplicationApi";
|
||||
import {
|
||||
type GitStatusData,
|
||||
type GitRemoteStatusData,
|
||||
GitSettingsTab,
|
||||
} from "reducers/uiReducers/gitSyncReducer";
|
||||
import type { ResponseMeta } from "api/ApiResponses";
|
||||
import { noop } from "lodash";
|
||||
|
||||
export interface GitStatusParams {
|
||||
compareRemote?: boolean;
|
||||
onSuccessCallback?: (data: any) => void;
|
||||
onErrorCallback?: (error: Error, response?: any) => void;
|
||||
}
|
||||
|
||||
export const setIsGitSyncModalOpen = (payload: {
|
||||
|
|
@ -183,20 +183,6 @@ export const fetchGitStatusSuccess = (payload: GitStatusData) => ({
|
|||
payload,
|
||||
});
|
||||
|
||||
export const fetchGitRemoteStatusInit = ({
|
||||
onErrorCallback = noop,
|
||||
onSuccessCallback = noop,
|
||||
} = {}) => ({
|
||||
type: ReduxActionTypes.FETCH_GIT_REMOTE_STATUS_INIT,
|
||||
onSuccessCallback,
|
||||
onErrorCallback,
|
||||
});
|
||||
|
||||
export const fetchGitRemoteStatusSuccess = (payload: GitRemoteStatusData) => ({
|
||||
type: ReduxActionTypes.FETCH_GIT_REMOTE_STATUS_SUCCESS,
|
||||
payload,
|
||||
});
|
||||
|
||||
export const discardChanges = (
|
||||
payload: { successToastMessage?: string } | undefined | null = {},
|
||||
) => ({
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export interface ConnectToGitPayload {
|
|||
interface GitStatusParam {
|
||||
applicationId: string;
|
||||
branch: string;
|
||||
compareRemote: "true" | "false";
|
||||
compareRemote: boolean;
|
||||
}
|
||||
|
||||
interface GitRemoteStatusParam {
|
||||
|
|
@ -143,7 +143,7 @@ class GitSyncAPI extends Api {
|
|||
static async getGitStatus({
|
||||
applicationId,
|
||||
branch,
|
||||
compareRemote = "true",
|
||||
compareRemote = true,
|
||||
}: GitStatusParam) {
|
||||
return Api.get(
|
||||
`${GitSyncAPI.baseURL}/status/app/${applicationId}`,
|
||||
|
|
|
|||
|
|
@ -85,8 +85,6 @@ const ActionTypes = {
|
|||
MERGE_BRANCH_SUCCESS: "MERGE_BRANCH_SUCCESS",
|
||||
FETCH_GIT_STATUS_INIT: "FETCH_GIT_STATUS_INIT",
|
||||
FETCH_GIT_STATUS_SUCCESS: "FETCH_GIT_STATUS_SUCCESS",
|
||||
FETCH_GIT_REMOTE_STATUS_INIT: "FETCH_GIT_REMOTE_STATUS_INIT",
|
||||
FETCH_GIT_REMOTE_STATUS_SUCCESS: "FETCH_GIT_REMOTE_STATUS_SUCCESS",
|
||||
UPDATE_BRANCH_LOCALLY: "UPDATE_BRANCH_LOCALLY",
|
||||
FETCH_BRANCHES_INIT: "FETCH_BRANCHES_INIT",
|
||||
FETCH_BRANCHES_SUCCESS: "FETCH_BRANCHES_SUCCESS",
|
||||
|
|
@ -926,7 +924,6 @@ export const ReduxActionErrorTypes = {
|
|||
FETCH_MERGE_STATUS_ERROR: "FETCH_MERGE_STATUS_ERROR",
|
||||
MERGE_BRANCH_ERROR: "MERGE_BRANCH_ERROR",
|
||||
FETCH_GIT_STATUS_ERROR: "FETCH_GIT_STATUS_ERROR",
|
||||
FETCH_GIT_REMOTE_STATUS_ERROR: "FETCH_GIT_REMOTE_STATUS_ERROR",
|
||||
CREATE_NEW_BRANCH_ERROR: "CREATE_NEW_BRANCH_ERROR",
|
||||
CHECKOUT_BRANCH_ERROR: "CHECKOUT_BRANCH_ERROR",
|
||||
FETCH_BRANCHES_ERROR: "FETCH_BRANCHES_ERROR",
|
||||
|
|
|
|||
|
|
@ -11,10 +11,8 @@ export const FEATURE_FLAG = {
|
|||
release_table_serverside_filtering_enabled:
|
||||
"release_table_serverside_filtering_enabled",
|
||||
license_branding_enabled: "license_branding_enabled",
|
||||
release_git_status_lite_enabled: "release_git_status_lite_enabled",
|
||||
license_sso_saml_enabled: "license_sso_saml_enabled",
|
||||
license_sso_oidc_enabled: "license_sso_oidc_enabled",
|
||||
release_git_connect_v2_enabled: "release_git_connect_v2_enabled",
|
||||
license_private_embeds_enabled: "license_private_embeds_enabled",
|
||||
release_show_publish_app_to_community_enabled:
|
||||
"release_show_publish_app_to_community_enabled",
|
||||
|
|
@ -65,10 +63,8 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
|
|||
ab_wds_enabled: false,
|
||||
release_table_serverside_filtering_enabled: false,
|
||||
license_branding_enabled: false,
|
||||
release_git_status_lite_enabled: false,
|
||||
license_sso_saml_enabled: false,
|
||||
license_sso_oidc_enabled: false,
|
||||
release_git_connect_v2_enabled: false,
|
||||
license_private_embeds_enabled: false,
|
||||
release_show_publish_app_to_community_enabled: false,
|
||||
license_gac_enabled: false,
|
||||
|
|
|
|||
|
|
@ -12758,10 +12758,8 @@ export const defaultAppState = {
|
|||
release_table_serverside_filtering_enabled: false,
|
||||
release_custom_echarts_enabled: false,
|
||||
license_branding_enabled: false,
|
||||
release_git_status_lite_enabled: false,
|
||||
license_sso_saml_enabled: false,
|
||||
license_sso_oidc_enabled: false,
|
||||
release_git_connect_v2_enabled: true,
|
||||
deprecate_custom_fusioncharts_enabled: false,
|
||||
ab_mock_mongo_schema_enabled: true,
|
||||
license_private_embeds_enabled: false,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { fetchMockDatasources } from "actions/datasourceActions";
|
||||
import {
|
||||
fetchGitRemoteStatusInit,
|
||||
fetchGitProtectedBranchesInit,
|
||||
fetchGitStatusInit,
|
||||
remoteUrlInputValue,
|
||||
|
|
@ -32,10 +31,7 @@ import {
|
|||
waitForWidgetConfigBuild,
|
||||
} from "sagas/InitSagas";
|
||||
import { getCurrentApplication } from "selectors/editorSelectors";
|
||||
import {
|
||||
getCurrentGitBranch,
|
||||
getIsGitStatusLiteEnabled,
|
||||
} from "selectors/gitSyncSelectors";
|
||||
import { getCurrentGitBranch } from "selectors/gitSyncSelectors";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import history from "utils/history";
|
||||
import PerformanceTracker, {
|
||||
|
|
@ -296,21 +292,12 @@ export default class AppEditorEngine extends AppEngine {
|
|||
}
|
||||
|
||||
private *loadGitInBackground() {
|
||||
const isGitStatusLiteEnabled: boolean = yield select(
|
||||
getIsGitStatusLiteEnabled,
|
||||
);
|
||||
|
||||
yield put(fetchBranchesInit());
|
||||
yield put(fetchGitProtectedBranchesInit());
|
||||
yield put(fetchGitProtectedBranchesInit());
|
||||
yield put(getGitMetadataInitAction());
|
||||
|
||||
if (isGitStatusLiteEnabled) {
|
||||
yield put(fetchGitRemoteStatusInit());
|
||||
yield put(fetchGitStatusInit({ compareRemote: false }));
|
||||
} else {
|
||||
yield put(fetchGitStatusInit({ compareRemote: true }));
|
||||
}
|
||||
yield put(fetchGitStatusInit({ compareRemote: true }));
|
||||
|
||||
yield put(startAutocommitProgressPolling());
|
||||
yield put(resetPullMergeStatus());
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import {
|
|||
setDisconnectingGitApplication,
|
||||
setGitSettingsModalOpenAction,
|
||||
setIsDisconnectGitModalOpen,
|
||||
setIsGitSyncModalOpen,
|
||||
} from "actions/gitSyncActions";
|
||||
import {
|
||||
Button,
|
||||
|
|
@ -34,15 +33,9 @@ import {
|
|||
} from "@appsmith/constants/messages";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import { Space } from "./components/StyledComponents";
|
||||
import { GitSyncModalTab } from "entities/GitSync";
|
||||
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
||||
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
|
||||
import { GitSettingsTab } from "reducers/uiReducers/gitSyncReducer";
|
||||
|
||||
function DisconnectGitModal() {
|
||||
const isGitConnectV2Enabled = useFeatureFlag(
|
||||
FEATURE_FLAG.release_git_connect_v2_enabled,
|
||||
);
|
||||
const dispatch = useDispatch();
|
||||
const isModalOpen = useSelector(getIsDisconnectGitModalOpen);
|
||||
const disconnectingApp = useSelector(getDisconnectingGitApplication);
|
||||
|
|
@ -52,21 +45,12 @@ function DisconnectGitModal() {
|
|||
|
||||
const handleClickOnBack = useCallback(() => {
|
||||
dispatch(setIsDisconnectGitModalOpen(false));
|
||||
if (isGitConnectV2Enabled) {
|
||||
dispatch(
|
||||
setGitSettingsModalOpenAction({
|
||||
open: true,
|
||||
tab: GitSettingsTab.GENERAL,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
dispatch(
|
||||
setIsGitSyncModalOpen({
|
||||
isOpen: true,
|
||||
tab: GitSyncModalTab.GIT_CONNECTION,
|
||||
}),
|
||||
);
|
||||
}
|
||||
dispatch(
|
||||
setGitSettingsModalOpenAction({
|
||||
open: true,
|
||||
tab: GitSettingsTab.GENERAL,
|
||||
}),
|
||||
);
|
||||
dispatch(setDisconnectingGitApplication({ id: "", name: "" }));
|
||||
}, [dispatch]);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import {
|
|||
toggleAutocommitEnabledInit,
|
||||
setIsAutocommitModalOpen,
|
||||
setIsDisconnectGitModalOpen,
|
||||
setIsGitSyncModalOpen,
|
||||
setGitSettingsModalOpenAction,
|
||||
} from "actions/gitSyncActions";
|
||||
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
|
||||
import { Button, Divider, Text } from "design-system";
|
||||
|
|
@ -68,7 +68,7 @@ const StyledDivider = styled(Divider)`
|
|||
margin-bottom: 16px;
|
||||
`;
|
||||
|
||||
function GitDisconnect() {
|
||||
function DangerZone() {
|
||||
const isConnectToGitPermitted = useHasConnectToGitPermission();
|
||||
const isManageAutoCommitPermitted = useHasManageAutoCommitPermission();
|
||||
const isAutocommitFeatureEnabled = useFeatureFlag(
|
||||
|
|
@ -86,7 +86,7 @@ function GitDisconnect() {
|
|||
AnalyticsUtil.logEvent("GS_DISCONNECT_GIT_CLICK", {
|
||||
source: "GIT_CONNECTION_MODAL",
|
||||
});
|
||||
dispatch(setIsGitSyncModalOpen({ isOpen: false }));
|
||||
dispatch(setGitSettingsModalOpenAction({ open: false }));
|
||||
dispatch(
|
||||
setDisconnectingGitApplication({
|
||||
id: currentApp?.id || "",
|
||||
|
|
@ -98,7 +98,7 @@ function GitDisconnect() {
|
|||
|
||||
const handleToggleAutocommit = () => {
|
||||
if (isAutocommitEnabled) {
|
||||
dispatch(setIsGitSyncModalOpen({ isOpen: false }));
|
||||
dispatch(setGitSettingsModalOpenAction({ open: false }));
|
||||
dispatch(setIsAutocommitModalOpen(true));
|
||||
} else {
|
||||
dispatch(toggleAutocommitEnabledInit());
|
||||
|
|
@ -164,4 +164,4 @@ function GitDisconnect() {
|
|||
);
|
||||
}
|
||||
|
||||
export default GitDisconnect;
|
||||
export default DangerZone;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
|
||||
import React from "react";
|
||||
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
|
||||
import GitSyncModalV1 from "./GitSyncModalV1";
|
||||
import GitSyncModalV2 from "./GitSyncModalV2";
|
||||
|
||||
interface GitSyncModalProps {
|
||||
|
|
@ -9,15 +6,7 @@ interface GitSyncModalProps {
|
|||
}
|
||||
|
||||
function GitSyncModal(props: GitSyncModalProps) {
|
||||
const isGitConnectV2Enabled = useFeatureFlag(
|
||||
FEATURE_FLAG.release_git_connect_v2_enabled,
|
||||
);
|
||||
|
||||
return isGitConnectV2Enabled ? (
|
||||
<GitSyncModalV2 {...props} />
|
||||
) : (
|
||||
<GitSyncModalV1 {...props} />
|
||||
);
|
||||
return <GitSyncModalV2 {...props} />;
|
||||
}
|
||||
|
||||
export default GitSyncModal;
|
||||
|
|
|
|||
|
|
@ -303,10 +303,6 @@ export default function QuickGitActions() {
|
|||
const showPullLoadingState = isPullInProgress || isFetchingGitStatus;
|
||||
const changesToCommit = useSelector(getCountOfChangesToCommit);
|
||||
|
||||
const isGitConnectV2Enabled = useFeatureFlag(
|
||||
FEATURE_FLAG.release_git_connect_v2_enabled,
|
||||
);
|
||||
|
||||
const isAutocommitFeatureEnabled = useFeatureFlag(
|
||||
FEATURE_FLAG.release_git_autocommit_feature_enabled,
|
||||
);
|
||||
|
|
@ -325,22 +321,12 @@ export default function QuickGitActions() {
|
|||
});
|
||||
},
|
||||
settings: () => {
|
||||
if (isGitConnectV2Enabled) {
|
||||
dispatch(
|
||||
setGitSettingsModalOpenAction({
|
||||
open: true,
|
||||
tab: GitSettingsTab.GENERAL,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
dispatch(
|
||||
setIsGitSyncModalOpen({
|
||||
isOpen: true,
|
||||
tab: GitSyncModalTab.GIT_CONNECTION,
|
||||
isDeploying: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
dispatch(
|
||||
setGitSettingsModalOpenAction({
|
||||
open: true,
|
||||
tab: GitSettingsTab.GENERAL,
|
||||
}),
|
||||
);
|
||||
AnalyticsUtil.logEvent("GS_SETTING_CLICK", {
|
||||
source: "BOTTOM_BAR_GIT_SETTING_BUTTON",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -31,9 +31,7 @@ import {
|
|||
getIsCommitSuccessful,
|
||||
getIsCommittingInProgress,
|
||||
getIsDiscardInProgress,
|
||||
getIsFetchingGitRemoteStatus,
|
||||
getIsFetchingGitStatus,
|
||||
getIsGitStatusLiteEnabled,
|
||||
getIsPullingProgress,
|
||||
getPullFailed,
|
||||
getUpstreamErrorDocUrl,
|
||||
|
|
@ -48,7 +46,6 @@ import {
|
|||
clearDiscardErrorState,
|
||||
commitToRepoInit,
|
||||
discardChanges,
|
||||
fetchGitRemoteStatusInit,
|
||||
fetchGitStatusInit,
|
||||
gitPullInit,
|
||||
} from "actions/gitSyncActions";
|
||||
|
|
@ -107,7 +104,6 @@ function Deploy() {
|
|||
const gitMetaData = useSelector(getCurrentAppGitMetaData);
|
||||
const gitStatus = useSelector(getGitStatus) as GitStatusData;
|
||||
const isFetchingGitStatus = useSelector(getIsFetchingGitStatus);
|
||||
const remoteStatusLoading = useSelector(getIsFetchingGitRemoteStatus);
|
||||
const isPullingProgress = useSelector(getIsPullingProgress);
|
||||
const isCommitAndPushSuccessful = useSelector(getIsCommitSuccessful);
|
||||
const hasChangesToCommit = !gitStatus?.isClean;
|
||||
|
|
@ -129,7 +125,6 @@ function Deploy() {
|
|||
const currentApplication = useSelector(getCurrentApplication);
|
||||
const { changeReasonText, isAutoUpdate, isManualUpdate } =
|
||||
changeInfoSinceLastCommit(currentApplication);
|
||||
const isGitStatusLiteEnabled = useSelector(getIsGitStatusLiteEnabled);
|
||||
|
||||
const handleCommit = (doPush: boolean) => {
|
||||
setShowDiscardWarning(false);
|
||||
|
|
@ -160,12 +155,7 @@ function Deploy() {
|
|||
const commitButtonText = createMessage(COMMIT_AND_PUSH);
|
||||
|
||||
useEffect(() => {
|
||||
if (isGitStatusLiteEnabled) {
|
||||
dispatch(fetchGitRemoteStatusInit());
|
||||
dispatch(fetchGitStatusInit({ compareRemote: false }));
|
||||
} else {
|
||||
dispatch(fetchGitStatusInit({ compareRemote: true }));
|
||||
}
|
||||
dispatch(fetchGitStatusInit({ compareRemote: true }));
|
||||
return () => {
|
||||
dispatch(clearCommitSuccessfulState());
|
||||
};
|
||||
|
|
@ -346,7 +336,7 @@ function Deploy() {
|
|||
value={commitMessageDisplay}
|
||||
/>
|
||||
</SubmitWrapper>
|
||||
{(isFetchingGitStatus || remoteStatusLoading) && (
|
||||
{isFetchingGitStatus && (
|
||||
<StatusLoader loaderMsg={createMessage(FETCH_GIT_STATUS)} />
|
||||
)}
|
||||
{/* <Space size={11} /> */}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import {
|
|||
getGitStatus,
|
||||
getIsFetchingGitStatus,
|
||||
getIsFetchingMergeStatus,
|
||||
getIsGitStatusLiteEnabled,
|
||||
getIsMergeInProgress,
|
||||
getMergeError,
|
||||
getMergeStatus,
|
||||
|
|
@ -31,7 +30,6 @@ import {
|
|||
import type { DropdownOptions } from "../../GeneratePage/components/constants";
|
||||
import {
|
||||
fetchBranchesInit,
|
||||
fetchGitRemoteStatusInit,
|
||||
fetchGitStatusInit,
|
||||
fetchMergeStatusInit,
|
||||
mergeBranchInit,
|
||||
|
|
@ -82,7 +80,6 @@ function MergeSuccessIndicator() {
|
|||
export default function Merge() {
|
||||
const dispatch = useDispatch();
|
||||
const gitMetaData = useSelector(getCurrentAppGitMetaData);
|
||||
const isGitStatusLiteEnabled = useSelector(getIsGitStatusLiteEnabled);
|
||||
const gitBranches = useSelector(getGitBranches);
|
||||
const isFetchingBranches = useSelector(getFetchingBranches);
|
||||
const isFetchingMergeStatus = useSelector(getIsFetchingMergeStatus);
|
||||
|
|
@ -180,17 +177,12 @@ export default function Merge() {
|
|||
}, [currentBranch, selectedBranchOption?.value, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isGitStatusLiteEnabled) {
|
||||
dispatch(fetchGitRemoteStatusInit());
|
||||
dispatch(fetchGitStatusInit({ compareRemote: false }));
|
||||
} else {
|
||||
dispatch(fetchGitStatusInit({ compareRemote: true }));
|
||||
}
|
||||
dispatch(fetchGitStatusInit({ compareRemote: true }));
|
||||
dispatch(fetchBranchesInit());
|
||||
return () => {
|
||||
dispatch(resetMergeStatus());
|
||||
};
|
||||
}, [isGitStatusLiteEnabled]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// when user selects a branch to merge
|
||||
|
|
|
|||
|
|
@ -3,11 +3,8 @@ import styled from "styled-components";
|
|||
import { Colors } from "constants/Colors";
|
||||
import { useSelector } from "react-redux";
|
||||
import {
|
||||
getGitRemoteStatus,
|
||||
getGitStatus,
|
||||
getIsFetchingGitStatus,
|
||||
getIsFetchingGitRemoteStatus,
|
||||
getIsGitStatusLiteEnabled,
|
||||
} from "selectors/gitSyncSelectors";
|
||||
import type { GitStatusData } from "reducers/uiReducers/gitSyncReducer";
|
||||
import {
|
||||
|
|
@ -222,24 +219,15 @@ export function gitRemoteChangeListData(
|
|||
|
||||
export default function GitChangesList() {
|
||||
const status = useSelector(getGitStatus);
|
||||
const remoteStatus = useSelector(getGitRemoteStatus);
|
||||
const isGitStatusLiteEnabled = useSelector(getIsGitStatusLiteEnabled);
|
||||
|
||||
const derivedStatus: Partial<GitStatusData> = {
|
||||
...status,
|
||||
aheadCount: isGitStatusLiteEnabled
|
||||
? remoteStatus?.aheadCount
|
||||
: status?.aheadCount,
|
||||
behindCount: isGitStatusLiteEnabled
|
||||
? remoteStatus?.behindCount
|
||||
: status?.behindCount,
|
||||
remoteBranch: isGitStatusLiteEnabled
|
||||
? remoteStatus?.remoteTrackingBranch
|
||||
: status?.remoteBranch,
|
||||
aheadCount: status?.aheadCount,
|
||||
behindCount: status?.behindCount,
|
||||
remoteBranch: status?.remoteBranch,
|
||||
};
|
||||
|
||||
const statusLoading = useSelector(getIsFetchingGitStatus);
|
||||
const remoteStatusLoading = useSelector(getIsFetchingGitRemoteStatus);
|
||||
|
||||
const statusChanges = gitChangeListData(derivedStatus);
|
||||
const remoteStatusChanges = gitRemoteChangeListData(derivedStatus);
|
||||
|
|
@ -256,22 +244,7 @@ export default function GitChangesList() {
|
|||
/>,
|
||||
);
|
||||
}
|
||||
return isGitStatusLiteEnabled ? (
|
||||
<>
|
||||
<Changes data-testid={"t--git-change-statuses"}>
|
||||
{!statusLoading ? statusChanges : null}
|
||||
{!remoteStatusLoading ? remoteStatusChanges : null}
|
||||
{status?.migrationMessage ? (
|
||||
<CalloutContainer>
|
||||
<Callout kind="info">{status.migrationMessage}</Callout>
|
||||
</CalloutContainer>
|
||||
) : null}
|
||||
</Changes>
|
||||
{statusLoading || remoteStatusLoading ? (
|
||||
<DummyChange data-testid={"t--git-change-loading-dummy"} />
|
||||
) : null}
|
||||
</>
|
||||
) : (
|
||||
return (
|
||||
// disabling for better redability
|
||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { fetchGitRemoteStatusInit } from "actions/gitSyncActions";
|
||||
import { Callout, Text, toast } from "design-system";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
|
@ -14,6 +13,7 @@ import {
|
|||
NO_COPIED_SSH_KEY,
|
||||
createMessage,
|
||||
} from "@appsmith/constants/messages";
|
||||
import { fetchGitStatusInit } from "actions/gitSyncActions";
|
||||
|
||||
const NumberedList = styled.ol`
|
||||
list-style-type: decimal;
|
||||
|
|
@ -32,7 +32,7 @@ function ReconnectSSHError() {
|
|||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
fetchGitRemoteStatusInit({
|
||||
fetchGitStatusInit({
|
||||
onErrorCallback: (error, response) => {
|
||||
setErrorData({ error, response });
|
||||
},
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const LoaderWrapper = styled.div`
|
|||
|
||||
function StatusLoader({ loaderMsg }: { loaderMsg: string }) {
|
||||
return (
|
||||
<LoaderWrapper>
|
||||
<LoaderWrapper data-testId="t--git-merge-loader">
|
||||
<SpinnerLoader size="md" />
|
||||
<Text kind={"body-m"} style={{ marginLeft: 8 }}>
|
||||
{loaderMsg}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ const initialState: GitSyncReducerState = {
|
|||
activeGitSyncModalTab: GitSyncModalTab.GIT_CONNECTION,
|
||||
isErrorPopupVisible: false,
|
||||
isFetchingGitStatus: false,
|
||||
isFetchingGitRemoteStatus: false,
|
||||
isFetchingMergeStatus: false,
|
||||
globalGitConfig: { authorEmail: "", authorName: "" },
|
||||
branches: [],
|
||||
|
|
@ -292,27 +291,6 @@ const gitSyncReducer = createReducer(initialState, {
|
|||
...state,
|
||||
isFetchingGitStatus: false,
|
||||
}),
|
||||
[ReduxActionTypes.FETCH_GIT_REMOTE_STATUS_INIT]: (
|
||||
state: GitSyncReducerState,
|
||||
) => ({
|
||||
...state,
|
||||
isFetchingGitRemoteStatus: true,
|
||||
gitRemoteStatus: undefined,
|
||||
}),
|
||||
[ReduxActionTypes.FETCH_GIT_REMOTE_STATUS_SUCCESS]: (
|
||||
state: GitSyncReducerState,
|
||||
action: ReduxAction<GitStatusData | undefined>,
|
||||
) => ({
|
||||
...state,
|
||||
gitRemoteStatus: action.payload,
|
||||
isFetchingGitRemoteStatus: false,
|
||||
}),
|
||||
[ReduxActionErrorTypes.FETCH_GIT_REMOTE_STATUS_ERROR]: (
|
||||
state: GitSyncReducerState,
|
||||
) => ({
|
||||
...state,
|
||||
isFetchingGitRemoteStatus: false,
|
||||
}),
|
||||
[ReduxActionErrorTypes.DISCONNECT_TO_GIT_ERROR]: (
|
||||
state: GitSyncReducerState,
|
||||
) => ({
|
||||
|
|
@ -694,12 +672,6 @@ export interface GitStatusData {
|
|||
migrationMessage?: string;
|
||||
}
|
||||
|
||||
export interface GitRemoteStatusData {
|
||||
aheadCount: number;
|
||||
behindCount: number;
|
||||
remoteTrackingBranch: string;
|
||||
}
|
||||
|
||||
interface GitErrorPayloadType {
|
||||
code: number | string;
|
||||
errorType?: string;
|
||||
|
|
@ -781,7 +753,6 @@ export type GitSyncReducerState = GitBranchDeleteState & {
|
|||
isFetchingLocalGitConfig: boolean;
|
||||
|
||||
isFetchingGitStatus: boolean;
|
||||
isFetchingGitRemoteStatus: boolean;
|
||||
isFetchingMergeStatus: boolean;
|
||||
|
||||
activeGitSyncModalTab: GitSyncModalTab;
|
||||
|
|
@ -792,7 +763,6 @@ export type GitSyncReducerState = GitBranchDeleteState & {
|
|||
|
||||
localGitConfig: GitConfig;
|
||||
gitStatus?: GitStatusData;
|
||||
gitRemoteStatus?: GitRemoteStatusData;
|
||||
mergeStatus?: MergeStatus;
|
||||
connectError?: GitErrorType;
|
||||
commitAndPushError?: GitErrorType;
|
||||
|
|
|
|||
|
|
@ -36,10 +36,8 @@ import type {
|
|||
GitStatusParams,
|
||||
} from "actions/gitSyncActions";
|
||||
import {
|
||||
fetchGitRemoteStatusInit,
|
||||
fetchGitProtectedBranchesInit,
|
||||
updateGitProtectedBranchesInit,
|
||||
fetchGitRemoteStatusSuccess,
|
||||
clearCommitSuccessfulState,
|
||||
} from "actions/gitSyncActions";
|
||||
import {
|
||||
|
|
@ -103,8 +101,6 @@ import { addBranchParam, GIT_BRANCH_QUERY_KEY } from "constants/routes";
|
|||
import {
|
||||
getCurrentGitBranch,
|
||||
getDisconnectingGitApplication,
|
||||
getIsGitConnectV2Enabled,
|
||||
getIsGitStatusLiteEnabled,
|
||||
} from "selectors/gitSyncSelectors";
|
||||
import { initEditor } from "actions/initActions";
|
||||
import { fetchPage } from "actions/pageActions";
|
||||
|
|
@ -148,9 +144,7 @@ function* commitToGitRepoSaga(
|
|||
let response: ApiResponse | undefined;
|
||||
try {
|
||||
const applicationId: string = yield select(getCurrentApplicationId);
|
||||
const isGitStatusLiteEnabled: boolean = yield select(
|
||||
getIsGitStatusLiteEnabled,
|
||||
);
|
||||
|
||||
const gitMetaData: GitApplicationMetadata = yield select(
|
||||
getCurrentAppGitMetaData,
|
||||
);
|
||||
|
|
@ -178,12 +172,7 @@ function* commitToGitRepoSaga(
|
|||
payload: curApplication,
|
||||
});
|
||||
}
|
||||
if (isGitStatusLiteEnabled) {
|
||||
yield put(fetchGitRemoteStatusInit());
|
||||
yield put(fetchGitStatusInit({ compareRemote: false }));
|
||||
} else {
|
||||
yield put(fetchGitStatusInit({ compareRemote: true }));
|
||||
}
|
||||
yield put(fetchGitStatusInit({ compareRemote: true }));
|
||||
} else {
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.COMMIT_TO_GIT_REPO_ERROR,
|
||||
|
|
@ -226,9 +215,6 @@ function* connectToGitSaga(action: ConnectToGitReduxAction) {
|
|||
const applicationId: string = yield select(getCurrentApplicationId);
|
||||
const currentPageId: string = yield select(getCurrentPageId);
|
||||
response = yield GitSyncAPI.connect(action.payload, applicationId);
|
||||
const isGitConnectV2Enabled: boolean = yield select(
|
||||
getIsGitConnectV2Enabled,
|
||||
);
|
||||
|
||||
const isValidResponse: boolean = yield validateResponse(
|
||||
response,
|
||||
|
|
@ -241,13 +227,11 @@ function* connectToGitSaga(action: ConnectToGitReduxAction) {
|
|||
yield put(connectToGitSuccess(response?.data));
|
||||
const defaultBranch = response?.data?.gitApplicationMetadata?.branchName;
|
||||
|
||||
if (isGitConnectV2Enabled) {
|
||||
yield put(
|
||||
updateGitProtectedBranchesInit({
|
||||
protectedBranches: defaultBranch ? [defaultBranch] : [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
yield put(
|
||||
updateGitProtectedBranchesInit({
|
||||
protectedBranches: defaultBranch ? [defaultBranch] : [],
|
||||
}),
|
||||
);
|
||||
|
||||
yield put(fetchPage(currentPageId));
|
||||
if (action.onSuccessCallback) {
|
||||
|
|
@ -570,11 +554,6 @@ function* updateLocalGitConfig(action: ReduxAction<GitConfig>) {
|
|||
}
|
||||
|
||||
function* fetchGitStatusSaga(action: ReduxAction<GitStatusParams>) {
|
||||
const isLiteEnabled: boolean = yield select(getIsGitStatusLiteEnabled);
|
||||
const shouldCompareRemote = isLiteEnabled
|
||||
? !!action.payload?.compareRemote
|
||||
: true;
|
||||
|
||||
let response: ApiResponse | undefined;
|
||||
try {
|
||||
const applicationId: string = yield select(getCurrentApplicationId);
|
||||
|
|
@ -584,7 +563,7 @@ function* fetchGitStatusSaga(action: ReduxAction<GitStatusParams>) {
|
|||
response = yield GitSyncAPI.getGitStatus({
|
||||
applicationId,
|
||||
branch: gitMetaData?.branchName || "",
|
||||
compareRemote: shouldCompareRemote ? "true" : "false",
|
||||
compareRemote: action.payload.compareRemote ?? true,
|
||||
});
|
||||
const isValidResponse: boolean = yield validateResponse(
|
||||
response,
|
||||
|
|
@ -595,6 +574,9 @@ function* fetchGitStatusSaga(action: ReduxAction<GitStatusParams>) {
|
|||
// @ts-expect-error: response is of type unknown
|
||||
yield put(fetchGitStatusSuccess(response?.data));
|
||||
}
|
||||
if (typeof action.payload.onSuccessCallback === "function") {
|
||||
action.payload.onSuccessCallback(response?.data);
|
||||
}
|
||||
} catch (error) {
|
||||
const payload = { error, show: true };
|
||||
if ((error as Error)?.message?.includes("Auth fail")) {
|
||||
|
|
@ -608,56 +590,8 @@ function* fetchGitStatusSaga(action: ReduxAction<GitStatusParams>) {
|
|||
payload,
|
||||
});
|
||||
|
||||
// non api error
|
||||
if (!response || response?.responseMeta?.success) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface FetchRemoteStatusSagaAction extends ReduxAction<undefined> {
|
||||
onSuccessCallback?: (data: any) => void;
|
||||
onErrorCallback?: (error: Error, response?: any) => void;
|
||||
}
|
||||
|
||||
function* fetchGitRemoteStatusSaga(action: FetchRemoteStatusSagaAction) {
|
||||
let response: ApiResponse | undefined;
|
||||
try {
|
||||
const applicationId: string = yield select(getCurrentApplicationId);
|
||||
const gitMetaData: GitApplicationMetadata = yield select(
|
||||
getCurrentAppGitMetaData,
|
||||
);
|
||||
response = yield GitSyncAPI.getGitRemoteStatus({
|
||||
applicationId,
|
||||
branch: gitMetaData?.branchName || "",
|
||||
});
|
||||
const isValidResponse: boolean = yield validateResponse(
|
||||
response,
|
||||
false,
|
||||
getLogToSentryFromResponse(response),
|
||||
);
|
||||
if (isValidResponse) {
|
||||
// @ts-expect-error: response is of type unknown
|
||||
yield put(fetchGitRemoteStatusSuccess(response?.data));
|
||||
}
|
||||
if (typeof action?.onSuccessCallback === "function") {
|
||||
action.onSuccessCallback(response?.data);
|
||||
}
|
||||
} catch (error) {
|
||||
const payload = { error, show: !action?.onErrorCallback };
|
||||
if ((error as Error)?.message?.includes("Auth fail")) {
|
||||
payload.error = new Error(createMessage(ERROR_GIT_AUTH_FAIL));
|
||||
} else if ((error as Error)?.message?.includes("Invalid remote: origin")) {
|
||||
payload.error = new Error(createMessage(ERROR_GIT_INVALID_REMOTE));
|
||||
}
|
||||
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.FETCH_GIT_REMOTE_STATUS_ERROR,
|
||||
payload,
|
||||
});
|
||||
|
||||
if (typeof action?.onErrorCallback === "function") {
|
||||
action.onErrorCallback(error as Error, response);
|
||||
if (typeof action.payload.onErrorCallback === "function") {
|
||||
action.payload.onErrorCallback(error as Error, response);
|
||||
}
|
||||
|
||||
// non api error
|
||||
|
|
@ -1302,7 +1236,6 @@ const gitRequestNonBlockingActions: Record<
|
|||
[ReduxActionTypes.FETCH_GLOBAL_GIT_CONFIG_INIT]: fetchGlobalGitConfig,
|
||||
[ReduxActionTypes.FETCH_LOCAL_GIT_CONFIG_INIT]: fetchLocalGitConfig,
|
||||
[ReduxActionTypes.FETCH_GIT_STATUS_INIT]: fetchGitStatusSaga,
|
||||
[ReduxActionTypes.FETCH_GIT_REMOTE_STATUS_INIT]: fetchGitRemoteStatusSaga,
|
||||
[ReduxActionTypes.SHOW_CONNECT_GIT_MODAL]: showConnectGitModal,
|
||||
[ReduxActionTypes.FETCH_SSH_KEY_PAIR_INIT]: getSSHKeyPairSaga,
|
||||
[ReduxActionTypes.GIT_FETCH_PROTECTED_BRANCHES_INIT]:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import {
|
|||
getCurrentApplication,
|
||||
} from "@appsmith/selectors/applicationSelectors";
|
||||
import type { Branch } from "entities/GitSync";
|
||||
import { selectFeatureFlags } from "@appsmith/selectors/featureFlagsSelectors";
|
||||
|
||||
export const getGitSyncState = (state: AppState): GitSyncReducerState =>
|
||||
state.ui.gitSync;
|
||||
|
|
@ -65,9 +64,6 @@ export const getIsFetchingLocalGitConfig = (state: AppState) =>
|
|||
|
||||
export const getGitStatus = (state: AppState) => state.ui.gitSync.gitStatus;
|
||||
|
||||
export const getGitRemoteStatus = (state: AppState) =>
|
||||
state.ui.gitSync.gitRemoteStatus;
|
||||
|
||||
export const getGitConnectError = (state: AppState) =>
|
||||
state.ui.gitSync.connectError?.error;
|
||||
|
||||
|
|
@ -86,9 +82,6 @@ export const getGitDiscardError = (state: AppState) =>
|
|||
export const getIsFetchingGitStatus = (state: AppState) =>
|
||||
state.ui.gitSync.isFetchingGitStatus;
|
||||
|
||||
export const getIsFetchingGitRemoteStatus = (state: AppState) =>
|
||||
state.ui.gitSync.isFetchingGitRemoteStatus;
|
||||
|
||||
export const getIsPullingProgress = (state: AppState) =>
|
||||
state.ui.gitSync.pullInProgress;
|
||||
|
||||
|
|
@ -206,17 +199,6 @@ export const getBranchSwitchingDetails = (state: AppState) => ({
|
|||
switchingToBranch: state.ui.gitSync.switchingToBranch,
|
||||
});
|
||||
|
||||
// feature flag selectors
|
||||
export const getIsGitStatusLiteEnabled = createSelector(
|
||||
selectFeatureFlags,
|
||||
(flags) => !!flags?.release_git_status_lite_enabled,
|
||||
);
|
||||
|
||||
export const getIsGitConnectV2Enabled = createSelector(
|
||||
selectFeatureFlags,
|
||||
(flags) => !!flags?.release_git_connect_v2_enabled,
|
||||
);
|
||||
|
||||
export const getProtectedBranchesSelector = (state: AppState) =>
|
||||
state.ui.gitSync.protectedBranches;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user