Просмотр исходного кода

Merge pull request #1216 from porter-dev/por-25-gha-on-launch-improvement

[POR-25] GitHub Action preview should be expanded optionally
jusrhee 4 лет назад
Родитель
Сommit
88ce8081a6

+ 1 - 0
dashboard/src/components/SaveButton.tsx

@@ -145,6 +145,7 @@ const ButtonWrapper = styled.div`
     const baseStyles = `
       display: flex;
       align-items: center;
+      z-index: 99;
     `;
 
     if (props.clearPosition) {

+ 2 - 1
dashboard/src/components/porter-form/PorterForm.tsx

@@ -42,6 +42,7 @@ interface Props {
   currentTab: string;
   setCurrentTab: (nt: string) => void;
   isLaunch?: boolean;
+  hideSpacer?: boolean;
 }
 
 const PorterForm: React.FC<Props> = (props) => {
@@ -204,7 +205,7 @@ const PorterForm: React.FC<Props> = (props) => {
       {props.showStateDebugger && (
         <Pre>{JSON.stringify(formState, undefined, 2)}</Pre>
       )}
-      <Spacer />
+      {!props.hideSpacer && <Spacer />}
     </>
   );
 };

+ 3 - 0
dashboard/src/components/porter-form/PorterFormWrapper.tsx

@@ -20,6 +20,7 @@ type PropsType = {
   showStateDebugger?: boolean;
   isLaunch?: boolean;
   includeHiddenFields?: boolean;
+  hideBottomSpacer?: boolean;
 };
 
 const PorterFormWrapper: React.FunctionComponent<PropsType> = ({
@@ -38,6 +39,7 @@ const PorterFormWrapper: React.FunctionComponent<PropsType> = ({
   showStateDebugger,
   isLaunch,
   includeHiddenFields,
+  hideBottomSpacer,
 }) => {
   const hashCode = (s: string) => {
     return s?.split("").reduce(function (a, b) {
@@ -90,6 +92,7 @@ const PorterFormWrapper: React.FunctionComponent<PropsType> = ({
           currentTab={currentTab}
           setCurrentTab={setCurrentTab}
           isLaunch={isLaunch}
+          hideSpacer={hideBottomSpacer}
         />
       </PorterFormContextProvider>
     </React.Fragment>

+ 5 - 20
dashboard/src/main/home/launch/launch-flow/LaunchFlow.tsx

@@ -135,8 +135,7 @@ const LaunchFlow: React.FC<PropsType> = (props) => {
         });
       })
       .catch((err) => {
-        let parsedErr =
-          err?.response?.data?.error;
+        let parsedErr = err?.response?.data?.error;
 
         err = parsedErr || err.message || JSON.stringify(err);
 
@@ -238,8 +237,7 @@ const LaunchFlow: React.FC<PropsType> = (props) => {
               resolve(res?.data?.external_url);
             })
             .catch((err) => {
-              let parsedErr =
-                err?.response?.data?.error;
+              let parsedErr = err?.response?.data?.error;
               err = parsedErr || err.message || JSON.stringify(err);
               setSaveValuesStatus(`Could not create subdomain: ${err}`);
 
@@ -291,8 +289,7 @@ const LaunchFlow: React.FC<PropsType> = (props) => {
         }, 1000);
       })
       .catch((err: any) => {
-        let parsedErr =
-          err?.response?.data?.error;
+        let parsedErr = err?.response?.data?.error;
         err = parsedErr || err.message || JSON.stringify(err);
         setSaveValuesStatus(`Could not deploy template: ${err}`);
         setCurrentError(err);
@@ -340,20 +337,7 @@ const LaunchFlow: React.FC<PropsType> = (props) => {
       setTemplateName(newTemplateName);
     }
 
-    if (currentPage === "workflow" && currentTab === "porter") {
-      const fullActionConfig = getFullActionConfig();
-      return (
-        <WorkflowPage
-          name={templateName}
-          namespace={selectedNamespace}
-          fullActionConfig={fullActionConfig}
-          shouldCreateWorkflow={shouldCreateWorkflow}
-          setShouldCreateWorkflow={setShouldCreateWorkflow}
-          setPage={setCurrentPage}
-        />
-      );
-    }
-
+    const fullActionConfig = getFullActionConfig();
     // Display main (non-source) settings page
     return (
       <SettingsPage
@@ -370,6 +354,7 @@ const LaunchFlow: React.FC<PropsType> = (props) => {
         form={form}
         valuesToOverride={valuesToOverride}
         clearValuesToOverride={() => setValuesToOverride(null)}
+        fullActionConfig={fullActionConfig}
       />
     );
   };

+ 21 - 2
dashboard/src/main/home/launch/launch-flow/SettingsPage.tsx

@@ -4,7 +4,7 @@ import api from "shared/api";
 
 import { Context } from "shared/Context";
 
-import { ChoiceType, ClusterType } from "shared/types";
+import { ChoiceType, ClusterType, FullActionConfigType } from "shared/types";
 
 import { isAlphanumeric } from "shared/common";
 
@@ -15,6 +15,7 @@ import PorterFormWrapper from "components/porter-form/PorterFormWrapper";
 import Selector from "components/Selector";
 import Loading from "components/Loading";
 import { withAuth, WithAuthProps } from "shared/auth/AuthorizationHoc";
+import WorkflowPage from "./WorkflowPage";
 
 type PropsType = WithAuthProps & {
   onSubmit: (x?: any) => void;
@@ -24,7 +25,7 @@ type PropsType = WithAuthProps & {
   form: any;
   valuesToOverride: any;
   clearValuesToOverride: () => void;
-
+  fullActionConfig: FullActionConfigType;
   templateName: string;
   setTemplateName: (x: string) => void;
   selectedNamespace: string;
@@ -157,6 +158,7 @@ class SettingsPage extends Component<PropsType, StateType> {
               console.log(val);
               onSubmit(val);
             }}
+            hideBottomSpacer={!!this.props.fullActionConfig?.git_repo}
           />
         </FadeWrapper>
       );
@@ -251,6 +253,7 @@ class SettingsPage extends Component<PropsType, StateType> {
         <StyledSettingsPage>
           {this.renderHeaderSection()}
           {this.props.isCloning && this.getNameInput()}
+
           <Heading>Destination</Heading>
           <Helper>
             Specify the cluster and namespace you would like to deploy your
@@ -295,6 +298,22 @@ class SettingsPage extends Component<PropsType, StateType> {
             />
           </ClusterSection>
           {this.renderSettingsRegion()}
+          {this.props.fullActionConfig?.git_repo && (
+            <WorkflowPage
+              fullActionConfig={{
+                git_repo: "jnfrati/cryptoshops",
+                branch: "master",
+                registry_id: 9,
+                dockerfile_path: null,
+                folder_path: "./",
+                image_repo_uri: "index.docker.io/jnfrati/porter",
+                git_repo_id: 19210609,
+                should_create_workflow: true,
+              }}
+              name={this.props.templateName}
+              namespace={this.props.selectedNamespace}
+            />
+          )}
         </StyledSettingsPage>
       </PaddingWrapper>
     );

+ 3 - 8
dashboard/src/main/home/launch/launch-flow/SourcePage.tsx

@@ -238,17 +238,12 @@ class SourcePage extends Component<PropsType, StateType> {
   };
 
   handleContinue = () => {
-    const { sourceType, setPage } = this.props;
-
-    if (sourceType === "repo") {
-      setPage("workflow");
-    } else {
-      setPage("settings");
-    }
+    const { setPage } = this.props;
+    setPage("settings");
   };
 
   render() {
-    let { templateName, setTemplateName, setPage } = this.props;
+    let { templateName, setTemplateName } = this.props;
 
     return (
       <StyledSourcePage>

+ 41 - 43
dashboard/src/main/home/launch/launch-flow/WorkflowPage.tsx

@@ -1,5 +1,4 @@
 import React, { useContext, useEffect, useState } from "react";
-import { RouteComponentProps } from "react-router";
 import { FullActionConfigType } from "../../../../shared/types";
 import api from "../../../../shared/api";
 import { Context } from "../../../../shared/Context";
@@ -7,16 +6,14 @@ import styled from "styled-components";
 import YamlEditor from "../../../../components/YamlEditor";
 import Loading from "../../../../components/Loading";
 import Helper from "../../../../components/form-components/Helper";
-import CheckboxRow from "../../../../components/form-components/CheckboxRow";
-import SaveButton from "../../../../components/SaveButton";
 
 type PropsType = {
   name: string;
   namespace: string;
   fullActionConfig: FullActionConfigType;
-  shouldCreateWorkflow: boolean;
-  setShouldCreateWorkflow: (x: (prevState: boolean) => boolean) => void;
-  setPage: (x: string) => void;
+  shouldCreateWorkflow?: boolean;
+  setShouldCreateWorkflow?: (x: (prevState: boolean) => boolean) => void;
+  setPage?: (x: string) => void;
 };
 
 const WorkflowPage: React.FC<PropsType> = (props) => {
@@ -25,10 +22,11 @@ const WorkflowPage: React.FC<PropsType> = (props) => {
   const [isLoading, setIsLoading] = useState(true);
   const [hasError, setHasError] = useState(false);
   const [workflowYAML, setWorkflowYAML] = useState("");
+  const [isExpanded, setIsExpanded] = useState(false);
 
   useEffect(() => {
     const { currentCluster, currentProject } = context;
-
+    let isSubscribed = true;
     api
       .getGHAWorkflowTemplate(
         "<token>",
@@ -43,12 +41,17 @@ const WorkflowPage: React.FC<PropsType> = (props) => {
         }
       )
       .then((res) => {
-        setWorkflowYAML(res.data);
-        setIsLoading(false);
+        if (isSubscribed) {
+          setWorkflowYAML(res.data);
+          setIsLoading(false);
+        }
       })
       .catch((err) => setHasError(true))
       .finally(() => setIsLoading(false));
-  }, []);
+    return () => {
+      isSubscribed = false;
+    };
+  }, [props.name, props.namespace, props.fullActionConfig]);
 
   const renderWorkflow = () => {
     if (isLoading) {
@@ -64,37 +67,35 @@ const WorkflowPage: React.FC<PropsType> = (props) => {
         </Placeholder>
       );
     }
-    return <YamlEditor value={workflowYAML} readOnly={true} />;
-  };
-
-  const getButtonHelper = () => {
-    if (props.shouldCreateWorkflow) {
-      return "Both secrets and workflow will be created";
-    } else {
-      return "Only secrets will be created";
-    }
+    return <AnimatedYamlEditor value={workflowYAML} readOnly={true} />;
   };
 
   return (
     <StyledWorkflowPage>
-      <BackButton width="155px" onClick={() => props.setPage("source")}>
-        <i className="material-icons">first_page</i>
-        Source Settings
-      </BackButton>
       <Heading>GitHub Actions</Heading>
       <Helper>
         To auto-deploy each time you push changes, Porter will write GitHub
         Secrets and this GitHub Actions workflow to your repository.
       </Helper>
-      {renderWorkflow()}
-      <CheckboxRow
-        toggle={() => props.setShouldCreateWorkflow((x: boolean) => !x)}
-        checked={props.shouldCreateWorkflow}
-        label="Create workflow file"
-      />
+      <ExpandableButton onClick={() => setIsExpanded((prev) => !prev)}>
+        Show Porter workflow{" "}
+        <i className="material-icons-outlined">
+          {isExpanded ? "keyboard_arrow_up" : "keyboard_arrow_down"}
+        </i>
+      </ExpandableButton>
+      {isExpanded && renderWorkflow()}
       <Helper>
-        You may copy the YAML to an existing workflow and uncheck this box to
-        prevent Porter from creating a new workflow file.
+        <GitHubActionLink show={!props.shouldCreateWorkflow}>
+          If you want to create a custom workflow file for your deployments, we
+          recommend you <b>deploy from docker instead</b>, and checkout this
+          guide:{" "}
+          <a
+            href="https://docs.porter.run/docs/auto-deploy-requirements#cicd-with-github-actions"
+            target="_blank"
+          >
+            CI/CD with GitHub Actions
+          </a>
+        </GitHubActionLink>
         <GitHubActionLink show={!props.shouldCreateWorkflow}>
           The GitHub Action can be found at{" "}
           <a
@@ -106,13 +107,6 @@ const WorkflowPage: React.FC<PropsType> = (props) => {
         </GitHubActionLink>
       </Helper>
       <Buffer />
-      <SaveButton
-        text="Continue"
-        makeFlush={true}
-        disabled={hasError}
-        onClick={() => props.setPage("settings")}
-        helper={getButtonHelper()}
-      />
     </StyledWorkflowPage>
   );
 };
@@ -158,19 +152,20 @@ const Buffer = styled.div`
   height: 35px;
 `;
 
-const BackButton = styled.div`
+const ExpandableButton = styled.div`
+  position: relative;
   display: flex;
   align-items: center;
   justify-content: space-between;
   cursor: pointer;
   font-size: 13px;
   margin-top: 25px;
-  height: 35px;
+  height: 40px;
   padding: 5px 13px;
   padding-right: 15px;
   border: 1px solid #ffffff55;
-  border-radius: 100px;
-  width: ${(props: { width: string }) => props.width};
+  border-radius: 5px;
+  width: 100%;
   color: white;
   background: #ffffff11;
 
@@ -180,12 +175,15 @@ const BackButton = styled.div`
 
   > i {
     color: white;
-    font-size: 16px;
+    font-size: 24px;
     margin-right: 6px;
     margin-left: -2px;
   }
 `;
 
+// This should carry animations for the yaml editor to be more gently introduce into the page
+const AnimatedYamlEditor = styled(YamlEditor)``;
+
 const GitHubActionLink = styled.p`
   visibility: ${(props: { show: boolean }) =>
     props.show ? "visible" : "hidden"};