diff --git a/packages/cli/package.json b/packages/cli/package.json index e1f51be5b7..7f84217ec5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -38,7 +38,7 @@ "@rollup/plugin-json": "^4.0.2", "@rollup/plugin-node-resolve": "^8.1.0", "@rollup/plugin-yaml": "^2.1.1", - "@spotify/eslint-config": "^7.0.1", + "@spotify/eslint-config": "^8.1.0", "@sucrase/webpack-loader": "^2.0.0", "@svgr/plugin-jsx": "5.4.x", "@svgr/plugin-svgo": "5.4.x", diff --git a/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx b/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx index 390f35d516..d03c2d6be8 100644 --- a/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx +++ b/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx @@ -30,13 +30,13 @@ import { import React, { Suspense } from 'react'; import { useDownloadWorkflowRunLogs } from './useDownloadWorkflowRunLogs'; -import LinePart from 'react-lazylog/build/LinePart'; import { useProjectName } from '../useProjectName'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import DescriptionIcon from '@material-ui/icons/Description'; import { Entity } from '@backstage/catalog-model'; const LazyLog = React.lazy(() => import('react-lazylog/build/LazyLog')); +const LinePart = React.lazy(() => import('react-lazylog/build/LinePart')); const useStyles = makeStyles(() => ({ button: { diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 0eaa33e1f8..a53dc96aee 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -23,6 +23,7 @@ "@backstage/backend-common": "^0.1.1-alpha.22", "@backstage/catalog-model": "^0.1.1-alpha.22", "@backstage/config": "^0.1.1-alpha.22", + "@backstage/plugin-github-actions": "^0.1.1-alpha.22", "@gitbeaker/core": "^23.5.0", "@gitbeaker/node": "^23.5.0", "@octokit/rest": "^18.0.0", diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml b/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml index 2c8b3b3d6d..c5b500c701 100644 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml +++ b/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml @@ -18,6 +18,7 @@ spec: required: - component_id - use_typescript + - description properties: component_id: title: Name @@ -32,3 +33,9 @@ spec: type: boolean description: Include typescript default: true + use_github_actions: + title: Use Github Actions workflows to build this component + type: boolean + description: Use Github Actions + default: true + diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/index.ts similarity index 73% rename from plugins/scaffolder-backend/src/scaffolder/stages/templater/cra.ts rename to plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/index.ts index da33149c24..e771ada8c3 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/index.ts @@ -14,17 +14,19 @@ * limitations under the License. */ import fs from 'fs-extra'; -import { runDockerContainer } from './helpers'; -import { TemplaterBase, TemplaterRunOptions } from '.'; +import { runDockerContainer } from '../helpers'; +import { TemplaterBase, TemplaterRunOptions } from '..'; import path from 'path'; -import { TemplaterRunResult } from './types'; +import { TemplaterRunResult } from '../types'; import * as yaml from 'yaml'; +import { GITHUB_ACTIONS_ANNOTATION } from '@backstage/plugin-github-actions'; export class CreateReactAppTemplater implements TemplaterBase { public async run(options: TemplaterRunOptions): Promise { const { component_id: componentName, use_typescript: withTypescript, + use_github_actions: withGithubActions, description, owner, } = options.values; @@ -48,6 +50,23 @@ export class CreateReactAppTemplater implements TemplaterBase { }, }); + const extraAnnotations: Record = {}; + const finalDir = path.resolve( + resultDir, + options.values.component_id as string, + ); + + if (withGithubActions) { + await fs.promises.mkdir(`${finalDir}/.github`); + await fs.promises.mkdir(`${finalDir}/.github/workflows`); + await fs.promises.copyFile( + `${__dirname}/templates/.github/workflows/main.yml`, + `${finalDir}/.github/workflows/main.yml`, + ); + + extraAnnotations[GITHUB_ACTIONS_ANNOTATION] = options.values.storePath; + } + // Need to also make a component-info.yaml to store the data about the service. const componentInfo = { apiVersion: 'backstage.io/v1alpha1', @@ -55,6 +74,9 @@ export class CreateReactAppTemplater implements TemplaterBase { metadata: { name: componentName, description, + annotations: { + ...extraAnnotations, + }, }, spec: { type: 'website', @@ -63,11 +85,6 @@ export class CreateReactAppTemplater implements TemplaterBase { }, }; - const finalDir = path.resolve( - resultDir, - options.values.component_id as string, - ); - await fs.promises.writeFile( `${finalDir}/component-info.yaml`, yaml.stringify(componentInfo), diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/templates/.github/workflows/main.yml b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/templates/.github/workflows/main.yml new file mode 100644 index 0000000000..65cae9abbb --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cra/templates/.github/workflows/main.yml @@ -0,0 +1,41 @@ +name: CRA Build + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [12.x] + + steps: + - name: checkout code + uses: actions/checkout@v1 + - name: get yarn cache + id: yarn-cache + run: echo "::set-output name=dir::$(yarn cache dir)" + - uses: actions/cache@v2 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: use node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: yarn install, build, and test + working-directory: . + run: | + yarn install + yarn build + yarn test + env: + CI: true diff --git a/plugins/scaffolder/src/components/JobStatusModal/JobStatusModal.tsx b/plugins/scaffolder/src/components/JobStatusModal/JobStatusModal.tsx index 87b70a9553..0b6c451ff8 100644 --- a/plugins/scaffolder/src/components/JobStatusModal/JobStatusModal.tsx +++ b/plugins/scaffolder/src/components/JobStatusModal/JobStatusModal.tsx @@ -43,10 +43,11 @@ export const JobStatusModal = ({ entity, }: Props) => { const job = useJobPolling(jobId); + const jobStatus = job?.status ?? ''; useEffect(() => { - if (job?.status === 'COMPLETED') onComplete(job); - }, [job, onComplete]); + if (jobStatus === 'COMPLETED') onComplete(job); + }, [jobStatus, onComplete]); // eslint-disable-line react-hooks/exhaustive-deps return ( diff --git a/yarn.lock b/yarn.lock index 0cdce51f95..e89d95bd9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3525,6 +3525,11 @@ resolved "https://registry.npmjs.org/@spotify/eslint-config-base/-/eslint-config-base-7.0.0.tgz#36804ae09ec938f1aa5f9464ea993f3f151cfaa8" integrity sha512-XRTrTRyRRYBxPYINKNHw4B8QWlA3p4I+id/Po2sMdejtXH3LZgDgIjdschUZSdQ6J6dVYDdaVykdizRM9I+G6Q== +"@spotify/eslint-config-base@^8.0.0": + version "8.0.0" + resolved "https://registry.npmjs.org/@spotify/eslint-config-base/-/eslint-config-base-8.0.0.tgz#c3d10d8a05ad9129d579952cb80063e4c4fa216e" + integrity sha512-07Fo+KoTMl4AaZJPD6deFnYmG634wzgeqfFcWdFlIrOLAasvWSH8Lp6ZE9cJBKuffOAy8kuEE1SwFo34+5X8bQ== + "@spotify/eslint-config-oss@^1.0.1": version "1.0.2" resolved "https://registry.npmjs.org/@spotify/eslint-config-oss/-/eslint-config-oss-1.0.2.tgz#b0e56e549c78dcdd79063ce48521f10c3420f701" @@ -3537,12 +3542,22 @@ resolved "https://registry.npmjs.org/@spotify/eslint-config-react/-/eslint-config-react-7.0.1.tgz#2e70de9d7911ea9aeaa55a83a332220a28f6c431" integrity sha512-HNDHvm19EaBXiDgsg52mjMgKWZTeA0hO2Q75ACNwb8UtjIKkANqyyuzyDGo8jiGMbWIm6wJjShlRtT95emNlqQ== +"@spotify/eslint-config-react@^8.0.2": + version "8.0.2" + resolved "https://registry.npmjs.org/@spotify/eslint-config-react/-/eslint-config-react-8.0.2.tgz#91af3c58b22d49a96795336ed66927e722cda430" + integrity sha512-V0gzO/jWmjhODLINAfeunHj+OBdj/cQeVDw+92ZUlkonAg6BZLjX6Vy8jeIUFjfgmVOtI9eKbcApxaurj1jN6g== + "@spotify/eslint-config-typescript@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/@spotify/eslint-config-typescript/-/eslint-config-typescript-7.0.0.tgz#fc5227e3344f74b41ac3a530df24a95ac13254e4" integrity sha512-28I/SAf68NKbWZ5IY0WYMa0D18PxWdC9DP9gRbOTlZufmsS8jEgqf3zBUWmP6XOf1nihpKWcqvbFUG5H7/JYXA== -"@spotify/eslint-config@^7.0.0", "@spotify/eslint-config@^7.0.1": +"@spotify/eslint-config-typescript@^8.0.1": + version "8.0.1" + resolved "https://registry.npmjs.org/@spotify/eslint-config-typescript/-/eslint-config-typescript-8.0.1.tgz#2d3ee56a8a3f945454109086639cde47251d1e62" + integrity sha512-ALkA4WA2ZikX7grkptZ36J1N/iap0IJeViy6/ZcxSkm6yEy2BYslmS2MdoJ5PV/DfZ3Z/21d/+XYFqVEpcbrXg== + +"@spotify/eslint-config@^7.0.0": version "7.0.1" resolved "https://registry.npmjs.org/@spotify/eslint-config/-/eslint-config-7.0.1.tgz#07a21cfd7fce89cfc2c6dd5ea5d747e741201b66" integrity sha512-8GI/TZGUhS4pr7oipT2MjrZFRgXcKzk9YImEusUdD2f5vlCniRFIBQNrvTMkyjfdQqvIVqJPLcdVPXeAgprsMw== @@ -3559,6 +3574,29 @@ eslint-plugin-react "^7.12.4" eslint-plugin-react-hooks "^4.0.0" +"@spotify/eslint-config@^8.1.0": + version "8.1.0" + resolved "https://registry.npmjs.org/@spotify/eslint-config/-/eslint-config-8.1.0.tgz#00801a892a8f51df3f1074f7bc695052df4c9cd6" + integrity sha512-A3THg4Y2eK+hijUO+kt2ZL278XciFo/s/pwZ93c4/cYwFXYf1mcB2tmnmhP/6kK4QxF7rYmO8nYJMwPZ1sOkyQ== + dependencies: + "@spotify/eslint-config-base" "^8.0.0" + "@spotify/eslint-config-react" "^8.0.2" + "@spotify/eslint-config-typescript" "^8.0.1" + "@spotify/eslint-plugin" "^8.1.0" + "@spotify/web-scripts-utils" "^8.0.0" + "@typescript-eslint/eslint-plugin" "^3.4.0" + "@typescript-eslint/parser" "^3.4.0" + eslint-config-prettier "^6.0.0" + eslint-plugin-jest "^23.17.1" + eslint-plugin-jsx-a11y "^6.2.1" + eslint-plugin-react "^7.12.4" + eslint-plugin-react-hooks "^4.0.0" + +"@spotify/eslint-plugin@^8.1.0": + version "8.1.0" + resolved "https://registry.npmjs.org/@spotify/eslint-plugin/-/eslint-plugin-8.1.0.tgz#a9c5f971537c647d20d6f8c608018aec8d1b882a" + integrity sha512-/VBOF0vMRhVQFqdsNQ5NKhZeD8IWimqKZzsp2yrjLKDajXOfCsA8VpCtm/j4T6/8j/mqb7Rz9ePT+thHfGtBxg== + "@spotify/prettier-config@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/@spotify/prettier-config/-/prettier-config-7.0.0.tgz#47750979d1282197295108b6958360660a955c16" @@ -3577,6 +3615,14 @@ glob "^7.1.4" read-pkg-up "^7.0.1" +"@spotify/web-scripts-utils@^8.0.0": + version "8.0.0" + resolved "https://registry.npmjs.org/@spotify/web-scripts-utils/-/web-scripts-utils-8.0.0.tgz#83e49a0050e0ca553769cea4052fe438bc0378a7" + integrity sha512-5ADUaRRW+ZJHYhfSiaJVVq+9hVfAin+WYaJzEd/3oTvd6P1BrVsAdyxBdmXtacTHu+vjlVoye/kxdpUhlIq9Iw== + dependencies: + glob "^7.1.4" + read-pkg-up "^7.0.1" + "@storybook/addon-actions@^6.0.21": version "6.0.21" resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.0.21.tgz#0de1d109d4b1eb99f644bbe84e74c25cfd2b1b6b" @@ -5457,6 +5503,18 @@ regexpp "^3.0.0" tsutils "^3.17.1" +"@typescript-eslint/eslint-plugin@^3.4.0": + version "3.10.1" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz#7e061338a1383f59edc204c605899f93dc2e2c8f" + integrity sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ== + dependencies: + "@typescript-eslint/experimental-utils" "3.10.1" + debug "^4.1.1" + functional-red-black-tree "^1.0.1" + regexpp "^3.0.0" + semver "^7.3.2" + tsutils "^3.17.1" + "@typescript-eslint/experimental-utils@2.24.0", "@typescript-eslint/experimental-utils@^2.5.0": version "2.24.0" resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.24.0.tgz#a5cb2ed89fedf8b59638dc83484eb0c8c35e1143" @@ -5466,6 +5524,17 @@ "@typescript-eslint/typescript-estree" "2.24.0" eslint-scope "^5.0.0" +"@typescript-eslint/experimental-utils@3.10.1": + version "3.10.1" + resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686" + integrity sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/types" "3.10.1" + "@typescript-eslint/typescript-estree" "3.10.1" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + "@typescript-eslint/parser@^2.14.0": version "2.24.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.24.0.tgz#2cf0eae6e6dd44d162486ad949c126b887f11eb8" @@ -5476,6 +5545,22 @@ "@typescript-eslint/typescript-estree" "2.24.0" eslint-visitor-keys "^1.1.0" +"@typescript-eslint/parser@^3.4.0": + version "3.10.1" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.10.1.tgz#1883858e83e8b442627e1ac6f408925211155467" + integrity sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw== + dependencies: + "@types/eslint-visitor-keys" "^1.0.0" + "@typescript-eslint/experimental-utils" "3.10.1" + "@typescript-eslint/types" "3.10.1" + "@typescript-eslint/typescript-estree" "3.10.1" + eslint-visitor-keys "^1.1.0" + +"@typescript-eslint/types@3.10.1": + version "3.10.1" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" + integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== + "@typescript-eslint/typescript-estree@2.24.0": version "2.24.0" resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.24.0.tgz#38bbc8bb479790d2f324797ffbcdb346d897c62a" @@ -5489,6 +5574,27 @@ semver "^6.3.0" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@3.10.1": + version "3.10.1" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853" + integrity sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w== + dependencies: + "@typescript-eslint/types" "3.10.1" + "@typescript-eslint/visitor-keys" "3.10.1" + debug "^4.1.1" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/visitor-keys@3.10.1": + version "3.10.1" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931" + integrity sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ== + dependencies: + eslint-visitor-keys "^1.1.0" + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -10069,6 +10175,13 @@ eslint-plugin-import@^2.20.2, eslint-plugin-import@^2.22.0: resolve "^1.17.0" tsconfig-paths "^3.9.0" +eslint-plugin-jest@^23.17.1: + version "23.20.0" + resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz#e1d69c75f639e99d836642453c4e75ed22da4099" + integrity sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw== + dependencies: + "@typescript-eslint/experimental-utils" "^2.5.0" + eslint-plugin-jest@^23.6.0: version "23.8.2" resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz#6f28b41c67ef635f803ebd9e168f6b73858eb8d4" @@ -10114,9 +10227,9 @@ eslint-plugin-notice@^0.9.10: metric-lcs "^0.1.2" eslint-plugin-react-hooks@^4.0.0: - version "4.0.4" - resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.4.tgz#aed33b4254a41b045818cacb047b81e6df27fa58" - integrity sha512-equAdEIsUETLFNCmmCkiCGq6rkSK5MoJhXFPFYeUebcjKgBmWWcgVOqZyQC8Bv1BwVCnTq9tBxgJFgAJTWoJtA== + version "4.1.1" + resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.1.tgz#b37e1ff622b7800cd673901de32db1103d48411d" + integrity sha512-vFJNwsf4MLYS0lHYfz9LqxQ+GccYsGGeKPHDxgkIaKbAhNuTLnST+q44pt81MzJZyFU5K4XLF6WiCGv3Yb6tCg== eslint-plugin-react@^7.12.4: version "7.19.0"