From b3252bdd6bc325be2dc4c1ba278bac649cd60928 Mon Sep 17 00:00:00 2001 From: chadcarlson Date: Wed, 1 Nov 2023 10:20:52 -0400 Subject: [PATCH 1/7] Basic design updates. --- frontend/src/App.tsx | 46 +++++++++++++------ .../src/assets/utility/unavailable_v2.svg | 33 +++++++++++++ frontend/src/components/Header.tsx | 6 +++ frontend/src/components/Sidebar.tsx | 26 ++++++++--- frontend/src/index.css | 8 +++- frontend/src/page/ErrorPage.tsx | 2 +- 6 files changed, 100 insertions(+), 21 deletions(-) create mode 100644 frontend/src/assets/utility/unavailable_v2.svg diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 01d8efb1..6e50892f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -5,6 +5,9 @@ import { ReactComponent as DoneIcon } from "./assets/utility/done.svg"; import { ReactComponent as MergeIcon } from "./assets/utility/merge.svg"; import { ReactComponent as BranchIcon } from "./assets/utility/branch.svg"; +import { ReactComponent as ProductionIcon } from "./assets/utility/production.svg"; +import { ReactComponent as StagingIcon } from "./assets/utility/staging.svg"; + import CopyButton from "./components/CopyButton"; import { API_BASE_URL } from "./config"; import ErrorPage from "./page/ErrorPage"; @@ -12,6 +15,7 @@ import Header from "./components/Header"; import Sidebar from "./components/Sidebar"; import FeatureStep from "./components/FeatureStep"; import { CodeBlock, dracula } from "react-code-blocks"; +import CopyBlock from "react-code-blocks/dist/components/CopyBlock"; function App() { const [environment, setEnvironment] = useState(null); @@ -102,17 +106,24 @@ services: if (fatalErrorMessage) return ( -

+

{" "} There was an error fetching data from your Python backend at{" "} - + {/* + {API_BASE_URL}/{ENVIRONMENT_PATH} + */} +

+

+ {API_BASE_URL}/{ENVIRONMENT_PATH}

-

+

{" "} Please check your app logs using{" "} - upsun environment:log +

+

+ upsun environment:log

); @@ -129,9 +140,17 @@ services: sessionStorageType={sessionStorageType} />
-
-
+
+ {/*
Welcome to your Upsun Demo Guide project, a Python and Node.js multiapp designed to run on Upsun and teach you about its unique features. +
*/} +
+ {environment?.toLowerCase() === "production" ? ( + + ) : ( + + )} +

{environment}

{currentStepProgress < 3 && } @@ -184,7 +203,7 @@ services: bugfixes.

- Before you make your first revision, let's create a new preview environment called staging. + Before you make your first revision, let's create a new preview environment called Staging.

Next Step

    @@ -227,7 +246,7 @@ services: data-testid="add-redis" ref={stepCreateService} icon={} - title={"3. Add a Redis service"} + title={"3. Add Redis to staging"} isDisabled={currentStep !== "redis"} hideContent={currentStepProgress < 2} > @@ -398,7 +417,7 @@ services: Migrate your application
  1. - Share your thoughts and connect with us on Discord. + Share your thoughts and connect with us on Discord.
  2. Explore Upsun's horizontal scalability features. @@ -428,6 +447,7 @@ const EnvironmentIntroduction: React.FC = ({ if (environment === null) return <>; return ( +
    <> {environment && environment.toLocaleLowerCase() === "production" ? ( @@ -435,21 +455,21 @@ const EnvironmentIntroduction: React.FC = ({ )} +
    ); }; const ProductionIntroduction = () => { return ( <> -

    +

    Congrats! You’ve deployed the Upsun Demo Guide project to a production environment 🎉

    -

    +

    This app is the React frontend of your demo project’s production environment, which is associated with the default branch of the repository: main. With it now deployed, we can add features, services, and runtimes in preview environments - - which are byte-for-byte copies of production.

    - Follow the steps below to get started! + which are byte-for-byte copies of production.

    ); diff --git a/frontend/src/assets/utility/unavailable_v2.svg b/frontend/src/assets/utility/unavailable_v2.svg new file mode 100644 index 00000000..37c30cc9 --- /dev/null +++ b/frontend/src/assets/utility/unavailable_v2.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx index 9bfda2e2..508f936e 100644 --- a/frontend/src/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -14,6 +14,12 @@ function Header() { Demo Guide Project + + | + + + Powered by Platform.sh +
diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index f4c29473..dd499a09 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -1,5 +1,5 @@ -import { ReactComponent as ProductionIcon } from "../assets/utility/production.svg"; -import { ReactComponent as StagingIcon } from "../assets/utility/staging.svg"; +// import { ReactComponent as ProductionIcon } from "../assets/utility/production.svg"; +// import { ReactComponent as StagingIcon } from "../assets/utility/staging.svg"; interface SidebarProps { environment: string | null; @@ -12,14 +12,28 @@ const Sidebar: React.FC = ({ }) => { return ( diff --git a/frontend/src/index.css b/frontend/src/index.css index 3b3c2dc0..1d7d60a4 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -16,6 +16,8 @@ @layer base { body { @apply bg-black text-default text-sm font-sans-soft; + font-size: 14px; + line-height: 24px; } h1 { @apply font-bold @@ -32,7 +34,7 @@ } code { - @apply p-0 font-mono inline-flex justify-center items-center rounded-md bg-upsun-black-800 text-xs text-upsun-yellow-400 leading-5 + @apply p-0 font-mono inline-flex justify-center items-center rounded-md bg-black text-xs text-upsun-yellow-400 leading-5 } .TooltipContent { @@ -48,6 +50,10 @@ @apply select-none pointer-events-none opacity-25 } + .is-disabled:hover { + @apply opacity-100 + } + .code-block > span > code { @apply block !font-mono !text-xs w-full text-left; } diff --git a/frontend/src/page/ErrorPage.tsx b/frontend/src/page/ErrorPage.tsx index 9dc4ba95..1a16e5f0 100644 --- a/frontend/src/page/ErrorPage.tsx +++ b/frontend/src/page/ErrorPage.tsx @@ -1,5 +1,5 @@ import React, { ReactNode } from "react"; -import { ReactComponent as Unavailable } from "../assets/utility/unavailable.svg"; +import { ReactComponent as Unavailable } from "../assets/utility/unavailable_v2.svg"; import { ReactComponent as Logo } from "../assets/logo/upsun_horizontal.svg"; interface ErrorPageProps { From 622b66720f53d4bb15e797b0a363c603ec47e9cb Mon Sep 17 00:00:00 2001 From: chadcarlson Date: Wed, 1 Nov 2023 11:42:17 -0400 Subject: [PATCH 2/7] Add a local switcher. --- frontend/package-lock.json | 167 ++++++++++++------------------------ frontend/src/App.tsx | 27 +++--- frontend/src/commands.json | 30 +++++++ frontend/src/config.js | 5 +- frontend/src/utility/api.ts | 39 ++++++++- 5 files changed, 136 insertions(+), 132 deletions(-) create mode 100644 frontend/src/commands.json diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f23f4bd4..4521cd45 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -153,11 +153,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -242,11 +243,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz", - "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -378,12 +379,12 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -588,9 +589,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -2112,31 +2113,19 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/traverse": { - "version": "7.22.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", - "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.7", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/types": "^7.22.5", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2145,12 +2134,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.19", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz", - "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.19", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2494,11 +2483,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.20.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", @@ -2513,17 +2497,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -2642,6 +2615,18 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -4192,11 +4177,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@svgr/core/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "node_modules/@svgr/core/node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -4222,17 +4202,6 @@ } } }, - "node_modules/@svgr/core/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@svgr/hast-util-to-babel-ast": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", @@ -4301,11 +4270,6 @@ "@svgr/core": "*" } }, - "node_modules/@svgr/plugin-svgo/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "node_modules/@svgr/plugin-svgo/node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -4331,17 +4295,6 @@ } } }, - "node_modules/@svgr/plugin-svgo/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@svgr/webpack": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", @@ -8642,11 +8595,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -8711,17 +8659,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12817,17 +12754,21 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, + "node_modules/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -14082,9 +14023,9 @@ } }, "node_modules/postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 6e50892f..6d51eee2 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -15,7 +15,10 @@ import Header from "./components/Header"; import Sidebar from "./components/Sidebar"; import FeatureStep from "./components/FeatureStep"; import { CodeBlock, dracula } from "react-code-blocks"; -import CopyBlock from "react-code-blocks/dist/components/CopyBlock"; + +import { PROJECT_ID } from "./config"; + +import commands from "./commands.json"; function App() { const [environment, setEnvironment] = useState(null); @@ -109,9 +112,6 @@ services:

{" "} There was an error fetching data from your Python backend at{" "} - {/* - {API_BASE_URL}/{ENVIRONMENT_PATH} - */}

@@ -123,7 +123,7 @@ services: Please check your app logs using{" "}

- upsun environment:log + {commands.error.user.get_logs}

); @@ -141,9 +141,6 @@ services: />
- {/*
- Welcome to your Upsun Demo Guide project, a Python and Node.js multiapp designed to run on Upsun and teach you about its unique features. -
*/}
{environment?.toLowerCase() === "production" ? ( @@ -174,11 +171,11 @@ services:
  • Created a project, the Upsun counterpart to a repository.
  • Installed the Upsun CLI
  • -
  • Cloned the demo: git clone git@github.com:platformsh/demo-project.git
  • -
  • Connected to Upsun: upsun project:set-remote {process.env.REACT_APP_PROJECT_ID}
  • -
  • Pushed to Upsun: upsun push
  • -
  • Defined deployment resources: upsun resources:set --size '*:0.1'
  • -
  • Retrieved the deployed environment URL: upsun url --primary
  • +
  • Cloned the demo: {commands.first_deploy.user.clone}
  • +
  • Connected to Upsun: {commands.first_deploy.user.set_remote} {PROJECT_ID}
  • +
  • Pushed to Upsun: {commands.first_deploy.user.push}
  • +
  • Defined deployment resources: {commands.first_deploy.user.resources_set}
  • +
  • Retrieved the deployed environment URL: {commands.first_deploy.user.get_url}

@@ -210,10 +207,10 @@ services:

  • Create environment - +

    diff --git a/frontend/src/commands.json b/frontend/src/commands.json new file mode 100644 index 00000000..36e5779c --- /dev/null +++ b/frontend/src/commands.json @@ -0,0 +1,30 @@ +{ + "first_deploy": { + "user": { + "clone": "git clone git@github.com:platformsh/demo-project.git", + "set_remote": "upsun project:set-remote", + "push": "upsun push", + "resources_set": "upsun resources:set --size '*:0.1'", + "get_url": "upsun url --primary" + } + }, + "error": { + "user": { + "get_logs": "upsun environment:log" + } + }, + "branch": { + "user": { + "branch": "upsun branch staging --type staging", + "get_url": "upsun url --primary" + }, + "test": { + "branch": "upsun branch staging --type staging", + "get_url": "upsun url --primary" + } + }, + "redis": false, + "merge-production": false, + "scale": false, + "complete": false +} \ No newline at end of file diff --git a/frontend/src/config.js b/frontend/src/config.js index 0c69f7e8..54153d66 100644 --- a/frontend/src/config.js +++ b/frontend/src/config.js @@ -1,6 +1,5 @@ /** The .environment file exports the relevant environment variable for you. */ -const BASE_PATH = process.env.REACT_APP_BACKEND_URL || 'http://localhost:8000/'; -// const BASE_PATH = window.APP_BASE_URL || 'http://localhost:8000/'; - +export const BASE_PATH = process.env.REACT_APP_BACKEND_URL || 'http://localhost:8000/'; export const API_BASE_PATH = `api/v1` export const API_BASE_URL = `${BASE_PATH}${API_BASE_PATH}`; +export const PROJECT_ID = process.env.REACT_APP_PROJECT_ID || 'XXX_ID_XXX'; diff --git a/frontend/src/utility/api.ts b/frontend/src/utility/api.ts index d63ad6d8..d5a2034a 100644 --- a/frontend/src/utility/api.ts +++ b/frontend/src/utility/api.ts @@ -1,4 +1,5 @@ import { API_BASE_URL } from "../config"; +import { BASE_PATH } from "../config"; export type EnvironmentResponseType = { "session_storage": "redis" | "file" | string, @@ -13,7 +14,43 @@ export const fetchEnvironment = async (): Promise => { if (!response.ok) { throw new Error('Failed to fetch environment'); } - const data = await response.json(); + + let data; + + // If updating the design locally, this variable can help you quickly switch between steps. + let override_state = "branch" + // let override_state = "redis" + // let override_state = "merge-production" + // let override_state = "scale" + // let override_state = "complete" + + if (BASE_PATH == "http://localhost:8000/") { + + if (override_state == "branch") { + data = { + "session_storage": "file", + "type": "production" + } + } else if (override_state == "redis") { + data = { + "session_storage": "file", + "type": "staging" + } + } else if (override_state == "merge-production") { + data = { + "session_storage": "redis", + "type": "staging" + } + } else if (override_state == "complete") { + data = { + "session_storage": "redis", + "type": "production" + } + } + + } else { + data = await response.json(); + } return data as EnvironmentResponseType; }; From 7389bf092cc66e0d71749a098d7bf1fd72169c17 Mon Sep 17 00:00:00 2001 From: chadcarlson Date: Wed, 1 Nov 2023 14:25:53 -0400 Subject: [PATCH 3/7] Leverage command lookup from json. Share commands between app and tests. --- .github/workflows/project.yaml | 50 +++++++++++++++++++------------ frontend/src/App.test.tsx | 8 ++--- frontend/src/App.tsx | 54 +++++++++++++++++++++------------- frontend/src/commands.json | 39 +++++++++++++++++++++--- frontend/src/utility/api.ts | 18 ++++++++---- readme.md | 28 ++++++++++++++++++ 6 files changed, 145 insertions(+), 52 deletions(-) diff --git a/.github/workflows/project.yaml b/.github/workflows/project.yaml index 6032dfa6..b810364c 100644 --- a/.github/workflows/project.yaml +++ b/.github/workflows/project.yaml @@ -80,9 +80,8 @@ jobs: - name: "[setup_repo] 1. Clone repository into runner." run: | echo "::notice::Cloning repo copy into runner." - git clone -b $DEFAULT_BRANCH \ - https://github.com/$PROJECT_REPO.git \ - $PROJECT_LOCALDIR + cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.test.clone") + eval "$cmd" - name: "[setup_repo] 2. Setup runner Git user." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | @@ -186,6 +185,8 @@ jobs: echo "::notice::First push to project." # @todo: Push through Git, not the CLI, so the exit doesn't break the workflow. git push --force upsun $DEFAULT_BRANCH + cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.test.push") + eval "$cmd" # upsun push -f -y - name: "[first_deploy] 2. Test: The first deploy activity should complete." working-directory: ${{ env.PROJECT_LOCALDIR }} @@ -201,7 +202,8 @@ jobs: - name: "[init_resources] 1. Set initial resources." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | - upsun resources:set --size '*:0.1' -y + cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.user.resources_set") + eval "$cmd" - name: "[init_resources] 2. Test: The update environment resources activity should complete." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | @@ -214,20 +216,26 @@ jobs: working-directory: ${{ env.PROJECT_LOCALDIR }} run: | EXPECTED_STATUS="200" - PROD_URL_FRONTEND=$(upsun url --primary --pipe) + cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.user.get_url") + eval "$cmd" + PROD_URL_FRONTEND=$(eval "$cmd --pipe") ./utils/tests/url_status.sh $PROD_URL_FRONTEND $EXPECTED_STATUS "production frontend deployment (init_resources)" - name: "[init_resources] 5. Test: Updating environment resources should result in a 200 on the backend production app." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | EXPECTED_STATUS="200" - PROD_URL_FRONTEND=$(upsun url --primary --pipe) + cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.user.get_url") + eval "$cmd" + PROD_URL_FRONTEND=$(eval "$cmd --pipe") PROD_URL_BACKEND=$PROD_URL_FRONTEND$BACKEND_PATH ./utils/tests/url_status.sh $PROD_URL_BACKEND $EXPECTED_STATUS "production backend deployment (init_resources)" - name: "[init_resources] 6. Test: endpoint data (session_storage)" working-directory: ${{ env.PROJECT_LOCALDIR }} run: | EXPECTED="file" - PROD_URL_FRONTEND=$(upsun url --primary --pipe) + cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.user.get_url") + eval "$cmd" + PROD_URL_FRONTEND=$(eval "$cmd --pipe") PROD_URL_BACKEND=$PROD_URL_FRONTEND$BACKEND_PATH RESULT=$(curl -s $PROD_URL_BACKEND | jq -r '.session_storage') ./$TEST_PATH/compare_strings.sh "$RESULT" "$EXPECTED" "PROD Backend data session_storage" @@ -235,7 +243,9 @@ jobs: working-directory: ${{ env.PROJECT_LOCALDIR }} run: | EXPECTED="production" - PROD_URL_FRONTEND=$(upsun url --primary --pipe) + cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.user.get_url") + eval "$cmd" + PROD_URL_FRONTEND=$(eval "$cmd --pipe") PROD_URL_BACKEND=$PROD_URL_FRONTEND$BACKEND_PATH RESULT=$(curl -s $PROD_URL_BACKEND | jq -r '.type') ./$TEST_PATH/compare_strings.sh "$RESULT" "$EXPECTED" "PROD Backend data environment_type" @@ -295,10 +305,11 @@ jobs: working-directory: ${{ env.PROJECT_LOCALDIR }} run: | ./utils/uncomment.sh .upsun/config.yaml add_service - git commit -am "Create a redis service." + cmd=$(cat frontend/src/commands.json | jq -r ".redis.user.commit") + eval "$cmd" # Push through Git, not the CLI, so the exit doesn't break the workflow. - git push --force upsun $STAGING_BRANCH - # upsun push -f -y + cmd=$(cat frontend/src/commands.json | jq -r ".redis.test.push") + eval "$cmd" - name: "[add_service] 2. Test: The add_service activity should complete." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | @@ -314,6 +325,8 @@ jobs: working-directory: ${{ env.PROJECT_LOCALDIR }} run: | upsun resources:set --size redis_persistent:0.1 --disk redis_persistent:512 + cmd=$(cat frontend/src/commands.json | jq -r ".redis.user.resources_set") + eval "$cmd" - name: "[add_service_resources] 2. Test: The add_service_resources activity should complete." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | @@ -357,11 +370,8 @@ jobs: - name: "[merge] 1. Merge staging into production." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | - git checkout $DEFAULT_BRANCH - git merge $STAGING_BRANCH - # Push through Git, not the CLI, so the exit doesn't break the workflow. - git push --force upsun $DEFAULT_BRANCH - # upsun merge staging -y + cmd=$(cat frontend/src/commands.json | jq -r ".merge_production.test.merge") + eval "$cmd" - name: "[merge] 2. Test: The merge activity should complete." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | @@ -376,7 +386,9 @@ jobs: - name: "[prod_service_resources] 1. Set Redis' resources on production." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | - upsun resources:set --size redis_persistent:0.1 --disk redis_persistent:512 -e $DEFAULT_BRANCH + # upsun resources:set --size redis_persistent:0.1 --disk redis_persistent:512 -e $DEFAULT_BRANCH + cmd=$(cat frontend/src/commands.json | jq -r ".merge_production.user.resources_set") + eval "$cmd" - name: "[prod_service_resources] 2. Test: The update environment resources activity should complete." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | @@ -420,4 +432,6 @@ jobs: - name: "[cleanup] 1. Delete project." working-directory: ${{ env.PROJECT_LOCALDIR }} run: | - upsun project:delete -y + # upsun project:delete -y + cmd=$(cat frontend/src/commands.json | jq -r ".complete.user.delete_project") + eval "$cmd" diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 75065bbc..a1328614 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -122,7 +122,7 @@ describe("", () => { ).not.toHaveClass("is-disabled"); expect( - screen.getByText("3. Add a Redis service").parentElement?.parentElement, + screen.getByText("3. Add Redis to staging").parentElement?.parentElement, ).toHaveClass("is-disabled"); expect( @@ -158,7 +158,7 @@ describe("", () => { ).toHaveClass("is-disabled"); expect( - screen.getByText("3. Add a Redis service").parentElement?.parentElement, + screen.getByText("3. Add Redis to staging").parentElement?.parentElement, ).not.toHaveClass("is-disabled"); expect( @@ -196,7 +196,7 @@ describe("", () => { ).toHaveClass("is-disabled"); expect( - screen.getByText("3. Add a Redis service").parentElement?.parentElement, + screen.getByText("3. Add Redis to staging").parentElement?.parentElement, ).toHaveClass("is-disabled"); expect( @@ -234,7 +234,7 @@ describe("", () => { ).toHaveClass("is-disabled"); expect( - screen.getByText("3. Add a Redis service").parentElement?.parentElement, + screen.getByText("3. Add Redis to staging").parentElement?.parentElement, ).toHaveClass("is-disabled"); expect( diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 6d51eee2..10370fd3 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -223,10 +223,10 @@ services: Once deployed, open environment in browser - +

    @@ -267,17 +267,31 @@ services: language='yaml' showLineNumbers={true} theme={dracula} - startingLineNumber={66} + startingLineNumber={67} />

  • - Commit and push - + Commit +

    +

    + +

    +
  • +
  • +

    + Push + +

    + @@ -288,10 +302,10 @@ services:

  • Allocate Redis resources - +

    @@ -336,10 +350,10 @@ services:

  • Deploy staging changes to production - +

    @@ -353,10 +367,10 @@ services:

    Allocate resources to Redis in production. - +

    @@ -367,10 +381,10 @@ services:

  • Open production frontend in your browser - +

    @@ -398,10 +412,10 @@ services:

    Delete this project when ready using: - +

    @@ -475,20 +489,20 @@ const ProductionIntroduction = () => { const StagingIntroduction = () => { return ( <> -

    +

    Congrats! You’ve created your staging environment 🎉

    -

    +

    This space represents your byte-for-byte copy of production. You can use staging and development environments to preview and share changes prior to pushing them to production.

    -

    +

    This app uses the Upsun environment variable{" "} $PLATFORM_ENVIRONMENT="staging" to modify the content of this page.

    -

    +

    Return to the steps below to continue adding your Redis service.

    diff --git a/frontend/src/commands.json b/frontend/src/commands.json index 36e5779c..78f94ec8 100644 --- a/frontend/src/commands.json +++ b/frontend/src/commands.json @@ -1,4 +1,9 @@ { + "test": { + "user": { + "list": "git clone -b $DEFAULT_BRANCH https://github.com/platformsh/demo-project.git $PROJECT_LOCALDIR" + } + }, "first_deploy": { "user": { "clone": "git clone git@github.com:platformsh/demo-project.git", @@ -6,6 +11,10 @@ "push": "upsun push", "resources_set": "upsun resources:set --size '*:0.1'", "get_url": "upsun url --primary" + }, + "test": { + "clone": "git clone -b $DEFAULT_BRANCH https://github.com/platformsh/demo-project.git $PROJECT_LOCALDIR", + "push": "git push --force upsun $DEFAULT_BRANCH" } }, "error": { @@ -19,12 +28,34 @@ "get_url": "upsun url --primary" }, "test": { - "branch": "upsun branch staging --type staging", + "branch": "upsun branch $STAGING_BRANCH --type staging", "get_url": "upsun url --primary" } }, - "redis": false, - "merge-production": false, + "redis": { + "user": { + "commit": "git commit -am \"Create a Redis service.\"", + "push": "upsun push", + "resources_set": "upsun resources:set --size redis_persistent:0.1 --disk redis_persistent:512" + }, + "test": { + "push": "git push --force upsun $STAGING_BRANCH" + } + }, + "merge_production": { + "user": { + "merge": "upsun merge staging", + "resources_set": "upsun resources:set \\\n\t--size redis_persistent:0.1 \\\n\t--disk redis_persistent:512 \\\n\t-e main", + "get_url": "upsun url --primary -e main" + }, + "test": { + "merge": "git checkout $DEFAULT_BRANCH && git merge $STAGING_BRANCH && git push --force upsun $DEFAULT_BRANCH" + } + }, "scale": false, - "complete": false + "complete": { + "user": { + "delete_project": "upsun project:delete" + } + } } \ No newline at end of file diff --git a/frontend/src/utility/api.ts b/frontend/src/utility/api.ts index d5a2034a..cb266515 100644 --- a/frontend/src/utility/api.ts +++ b/frontend/src/utility/api.ts @@ -18,15 +18,20 @@ export const fetchEnvironment = async (): Promise => { let data; // If updating the design locally, this variable can help you quickly switch between steps. - let override_state = "branch" - // let override_state = "redis" - // let override_state = "merge-production" - // let override_state = "scale" - // let override_state = "complete" + // Note: this value MUST be returned to "default" when pushed to the project repo, or else tests will fail. + // let override_state = "default"; + // let override_state = "branch"; + // let override_state = "redis"; + // let override_state = "merge-production"; + // let override_state = "scale"; + // let override_state = "error_state" + let override_state = "complete"; if (BASE_PATH == "http://localhost:8000/") { - if (override_state == "branch") { + if (override_state == "default") { + data = await response.json(); + } else if (override_state == "branch") { data = { "session_storage": "file", "type": "production" @@ -48,6 +53,7 @@ export const fetchEnvironment = async (): Promise => { } } + // Default behavior of the production app. } else { data = await response.json(); } diff --git a/readme.md b/readme.md index 5135fd31..c461987f 100644 --- a/readme.md +++ b/readme.md @@ -135,3 +135,31 @@ These commands will set up everything you need to get started, serving: > [!IMPORTANT] > If at any time you want to start over, run `npm run clean`. > This will delete everything you've done in the previous steps. + +When running locally, `npm run start` mimicks the backend connection in `frontend/src/utility/api.ts`. +That is, if you're looking to update steps (defined in `frontend/src/App.tsx`) or commands (defined in `frontend/src/commands.json`) +and view how they will appear to the user, which state is presented is defined in this file. + +In the `fetchEnvironment` method, you will see an `override_state` variable + +```jsx +// frontend/src/utility/api.ts + +let data; + +// If updating the design locally, this variable can help you quickly switch between steps. +// Note: this value MUST be returned to "default" when pushed to the project repo, or else tests will fail. +// let override_state = "default"; +let override_state = "branch" +// let override_state = "redis" +// let override_state = "merge-production" +// let override_state = "scale" +// let override_state = "complete" +``` + +Changing which state is commented out in this block for the `override_state` variable will allow you to quickly switch between states. + +> [!IMPORTANT] +> This switch is included to make design/command changes easy to visualize quickly. +> It is **required** that you reset this variable to `let override_state = "default"` before pushing to the repository. +> If you do not, tests will fail and the PR cannot be accepted. From 9c3de0c223df1136e07dc0c5b1b5d6101bd49e90 Mon Sep 17 00:00:00 2001 From: chadcarlson Date: Wed, 1 Nov 2023 15:05:22 -0400 Subject: [PATCH 4/7] Fix test failures. --- .github/workflows/test.yaml | 10 +--- backend/scripts/test.sh | 8 +++ frontend/src/App.tsx | 12 ++--- frontend/src/components/Sidebar.test.tsx | 17 +------ frontend/src/utility/api.ts | 4 +- package.json | 4 +- readme.md | 62 ++++++++++++++++++++++++ 7 files changed, 84 insertions(+), 33 deletions(-) create mode 100755 backend/scripts/test.sh diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 50d53f60..6958861b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -47,20 +47,14 @@ jobs: export CI=true npm install cross-env npm-run-all -g npm install - npm run test + npm run test:frontend ################################################################################################ # C. Ensure no vulnerabilities. - name: "5. Test: there should be no Python vulnerabilities." run: | echo "::notice::Checking for vulnerabilities in backend Python app dependencies." - cd backend - python3 -m venv env - source env/bin/activate - pip install --upgrade pip - pip install -r requirements.txt - # pip-audit will exit 1 if vulnerabilities found (https://github.com/pypa/pip-audit#exit-codes) - pip-audit -r requirements.txt + npm run test:backend - name: "6. Test: there should be no HIGH Node.js vulnerabilities." run: | echo "::notice::Checking for high vulnerabilities in frontend Node.js app dependencies." diff --git a/backend/scripts/test.sh b/backend/scripts/test.sh new file mode 100755 index 00000000..5929d6b9 --- /dev/null +++ b/backend/scripts/test.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +python3 -m venv env +source env/bin/activate +pip install --upgrade pip +pip install -r requirements.txt +# pip-audit will exit 1 if vulnerabilities found (https://github.com/pypa/pip-audit#exit-codes) +pip-audit -r requirements.txt diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 10370fd3..0a87c4b9 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -350,10 +350,10 @@ services:
  • Deploy staging changes to production - +

    @@ -367,10 +367,10 @@ services:

    Allocate resources to Redis in production. - +

    @@ -381,10 +381,10 @@ services:

  • Open production frontend in your browser - +

    diff --git a/frontend/src/components/Sidebar.test.tsx b/frontend/src/components/Sidebar.test.tsx index 4b53fe66..cb6a546c 100644 --- a/frontend/src/components/Sidebar.test.tsx +++ b/frontend/src/components/Sidebar.test.tsx @@ -31,7 +31,7 @@ jest.mock("../assets/utility/status_incomplete.svg", () => { }); describe("", () => { - test("title section renders production icon when environment is Production", () => { + test("title section renders About section correctly", () => { const props = { environment: "Production", sessionStorageType: "Redis", @@ -40,20 +40,7 @@ describe("", () => { render(); // Check if the production icon is rendered - expect(screen.getByText("production-svg")).toBeInTheDocument(); - expect(screen.getByText("Production")).toBeInTheDocument(); + expect(screen.getByText("About")).toBeInTheDocument(); }); - test("title section renders staging icon when environment is not Production", () => { - const props = { - environment: "Staging", - sessionStorageType: "Redis", - }; - - render(); - - // Check if the staging icon is rendered - expect(screen.getByText("staging-svg")).toBeInTheDocument(); - expect(screen.getByText("Staging")).toBeInTheDocument(); - }); }); diff --git a/frontend/src/utility/api.ts b/frontend/src/utility/api.ts index cb266515..ae5b7c17 100644 --- a/frontend/src/utility/api.ts +++ b/frontend/src/utility/api.ts @@ -19,13 +19,13 @@ export const fetchEnvironment = async (): Promise => { // If updating the design locally, this variable can help you quickly switch between steps. // Note: this value MUST be returned to "default" when pushed to the project repo, or else tests will fail. - // let override_state = "default"; + let override_state = "default"; // let override_state = "branch"; // let override_state = "redis"; // let override_state = "merge-production"; // let override_state = "scale"; // let override_state = "error_state" - let override_state = "complete"; + // let override_state = "complete"; if (BASE_PATH == "http://localhost:8000/") { diff --git a/package.json b/package.json index 19e3720d..00fa7b95 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "postinstall": "cross-env FORCE_COLOR=1 npm-run-all -l postinstall:*", "postinstall:backend": "cd backend && ./scripts/build.sh", "postinstall:frontend": "cd frontend && npm install", - "test": "cross-env FORCE_COLOR=1 npm-run-all -l test:*", - "test:frontend": "cd frontend && npm run test" + "test:frontend": "cd frontend && npm run test -- --watchAll", + "test:backend": "cd backend && ./scripts/test.sh" }, "repository": { "type": "git", diff --git a/readme.md b/readme.md index c461987f..e0e2f2d1 100644 --- a/readme.md +++ b/readme.md @@ -136,6 +136,8 @@ These commands will set up everything you need to get started, serving: > If at any time you want to start over, run `npm run clean`. > This will delete everything you've done in the previous steps. +### Testing individual steps of the demo + When running locally, `npm run start` mimicks the backend connection in `frontend/src/utility/api.ts`. That is, if you're looking to update steps (defined in `frontend/src/App.tsx`) or commands (defined in `frontend/src/commands.json`) and view how they will appear to the user, which state is presented is defined in this file. @@ -163,3 +165,63 @@ Changing which state is commented out in this block for the `override_state` var > This switch is included to make design/command changes easy to visualize quickly. > It is **required** that you reset this variable to `let override_state = "default"` before pushing to the repository. > If you do not, tests will fail and the PR cannot be accepted. +> +> You can usually tell if forgetting to reset this variable is the reason for failure from the following error message during a test run: +> ``` +> FAIL src/utility/api.test.tsx +> ● fetchEnvironment › fetches environment successfully +> ``` + +### Running tests + +This project goes through a number of tests on GitHub that must pass before it can be merged. +These tests are of two types: + +1. Code tests +1. Demo path tests + +#### Code tests + +Before pushing your changes to the repository (or if your PR is failing), please run the following steps locally: + +1. Install project dependencies + + ```bash + npm install + ``` + +1. Run backend Python app tests (check for vulnerabilities) + + ```bash + npm run test:backend + ``` + + > [!NOTE] + > This test will fail on GitHub if **any** vulnerabilities are found. + +1. Run frontend React tests. + + ```bash + npm run test:frontend + ``` + + > [!NOTE] + > This test will fail on GitHub if **any** React tests fail. + + Tips: + + - [Make sure that you have returned `override_step` to its previous value](#testing-individual-steps-of-the-demo) + - Changes to steps in the demo can fundamentally change test expectations. Update tests as you work. + +1. Audit frontend dependencies. + + ```bash + cd frontend && npm audit + ``` + + > [!NOTE] + > This test will pass on GitHub, so long as there are **no High or Critical vulnerabilities** found. + +#### Demo path tests + +_Coming soon_ From b2f72bbf144af7e86d9434b84f39f208c998a016 Mon Sep 17 00:00:00 2001 From: chadcarlson Date: Wed, 1 Nov 2023 15:26:13 -0400 Subject: [PATCH 5/7] Tweak tests. --- .github/workflows/project.yaml | 2 +- frontend/src/commands.json | 3 ++- package.json | 2 +- readme.md | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/project.yaml b/.github/workflows/project.yaml index b810364c..5c2e07f2 100644 --- a/.github/workflows/project.yaml +++ b/.github/workflows/project.yaml @@ -387,7 +387,7 @@ jobs: working-directory: ${{ env.PROJECT_LOCALDIR }} run: | # upsun resources:set --size redis_persistent:0.1 --disk redis_persistent:512 -e $DEFAULT_BRANCH - cmd=$(cat frontend/src/commands.json | jq -r ".merge_production.user.resources_set") + cmd=$(cat frontend/src/commands.json | jq -r ".merge_production.test.resources_set") eval "$cmd" - name: "[prod_service_resources] 2. Test: The update environment resources activity should complete." working-directory: ${{ env.PROJECT_LOCALDIR }} diff --git a/frontend/src/commands.json b/frontend/src/commands.json index 78f94ec8..e822a75d 100644 --- a/frontend/src/commands.json +++ b/frontend/src/commands.json @@ -49,7 +49,8 @@ "get_url": "upsun url --primary -e main" }, "test": { - "merge": "git checkout $DEFAULT_BRANCH && git merge $STAGING_BRANCH && git push --force upsun $DEFAULT_BRANCH" + "merge": "git checkout $DEFAULT_BRANCH && git merge $STAGING_BRANCH && git push --force upsun $DEFAULT_BRANCH", + "resources_set": "upsun resources:set \\\n\t--size redis_persistent:0.1 \\\n\t--disk redis_persistent:512" } }, "scale": false, diff --git a/package.json b/package.json index 00fa7b95..43807b1d 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "postinstall": "cross-env FORCE_COLOR=1 npm-run-all -l postinstall:*", "postinstall:backend": "cd backend && ./scripts/build.sh", "postinstall:frontend": "cd frontend && npm install", - "test:frontend": "cd frontend && npm run test -- --watchAll", + "test:frontend": "cd frontend && npm run test", "test:backend": "cd backend && ./scripts/test.sh" }, "repository": { diff --git a/readme.md b/readme.md index e0e2f2d1..b114ead7 100644 --- a/readme.md +++ b/readme.md @@ -202,7 +202,7 @@ Before pushing your changes to the repository (or if your PR is failing), please 1. Run frontend React tests. ```bash - npm run test:frontend + npm run test:frontend -- --watchAll ``` > [!NOTE] From 656be86036a96166c149352f7f3bb3f9d1b9f536 Mon Sep 17 00:00:00 2001 From: chadcarlson Date: Wed, 1 Nov 2023 15:37:14 -0400 Subject: [PATCH 6/7] clean up commands. --- frontend/src/commands.json | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/frontend/src/commands.json b/frontend/src/commands.json index e822a75d..90e85746 100644 --- a/frontend/src/commands.json +++ b/frontend/src/commands.json @@ -1,7 +1,8 @@ { - "test": { + "test": false, + "error": { "user": { - "list": "git clone -b $DEFAULT_BRANCH https://github.com/platformsh/demo-project.git $PROJECT_LOCALDIR" + "get_logs": "upsun environment:log" } }, "first_deploy": { @@ -17,11 +18,6 @@ "push": "git push --force upsun $DEFAULT_BRANCH" } }, - "error": { - "user": { - "get_logs": "upsun environment:log" - } - }, "branch": { "user": { "branch": "upsun branch staging --type staging", From d9b80fc6519ca886f40b1abe901c1ecf9749585a Mon Sep 17 00:00:00 2001 From: chadcarlson Date: Wed, 1 Nov 2023 15:42:30 -0400 Subject: [PATCH 7/7] Handle delete project default behavior. --- .github/workflows/project.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/project.yaml b/.github/workflows/project.yaml index 5c2e07f2..ba82dc0a 100644 --- a/.github/workflows/project.yaml +++ b/.github/workflows/project.yaml @@ -434,4 +434,4 @@ jobs: run: | # upsun project:delete -y cmd=$(cat frontend/src/commands.json | jq -r ".complete.user.delete_project") - eval "$cmd" + eval "$cmd -y"