From 300a891f71f369662bc58e35271fb43e9db07260 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Wed, 15 Apr 2020 14:58:20 +0200 Subject: [PATCH] Create new app in temp dir --- .github/workflows/cli.yml | 14 ++++++--- packages/cli/bin/backstage-cli | 6 +++- .../cli/src/commands/build-cache/index.ts | 2 +- .../cli/src/commands/plugin/rollup.config.ts | 1 + .../templates/default-app/package.json.hbs | 3 ++ .../default-app/packages/app/package.json.hbs | 4 ++- scripts/cli-e2e-test.js | 23 ++++++++++---- scripts/createTestApp.js | 4 +-- scripts/createTestPlugin.js | 4 +-- scripts/generateTempDir.js | 30 +++++++++++++++++++ 10 files changed, 74 insertions(+), 17 deletions(-) create mode 100644 scripts/generateTempDir.js diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index 44a18f10da..6b32834ebd 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -41,18 +41,24 @@ jobs: - name: yarn install run: yarn install --frozen-lockfile - run: yarn build - # This creates a new app and plugin which pollutes the workspace, so it should be run last. + # generate temp directory + - name: generate tempdir + id: generate_tempdir + run: echo ::set-output name=tempdir::$(node scripts/generateTempDir.js) + # This creates a new app and plugin which pollutes the workspace, so it should be run last. - name: verify app and plugin creation on Windows + working-directory: ${{ steps.generate_tempdir.outputs.tempdir }} if: runner.os == 'Windows' - run: node scripts/cli-e2e-test.js + run: node ${{ github.workspace }}/scripts/cli-e2e-test.js - name: verify app and plugin creation on Linux + working-directory: ${{ steps.generate_tempdir.outputs.tempdir }} if: runner.os == 'Linux' run: | sudo sysctl fs.inotify.max_user_watches=524288 - node scripts/cli-e2e-test.js + node ${{ github.workspace }}/scripts/cli-e2e-test.js # This should lint and test both an app and a plugin - name: yarn lint, test after creation - working-directory: test-app + working-directory: ${{ steps.generate_tempdir.outputs.tempdir }}/test-app run: | yarn lint yarn test diff --git a/packages/cli/bin/backstage-cli b/packages/cli/bin/backstage-cli index a8ba74f28a..1cdf8c81af 100755 --- a/packages/cli/bin/backstage-cli +++ b/packages/cli/bin/backstage-cli @@ -19,7 +19,11 @@ const path = require('path'); // Figure out whether we're running inside the backstage repo or as an installed dependency const isLocal = require('fs').existsSync(path.resolve(__dirname, '../src')); -if (!isLocal) { + +// This is used for e2e-tests where we create a new app in a tmp folder +const isTemp = path.resolve(__dirname).includes(require('os').tmpdir()); + +if (!isLocal || isTemp || process.env.E2E) { // src-relative imports are a pain to get to work with plain tsc compilation, as the // transpiled code will maintain the imports as they are in the source. Which means an // import for `helpers/paths` will start like that in the output, which won't work in NodeJS. diff --git a/packages/cli/src/commands/build-cache/index.ts b/packages/cli/src/commands/build-cache/index.ts index a8a1a27e9d..368fac2593 100644 --- a/packages/cli/src/commands/build-cache/index.ts +++ b/packages/cli/src/commands/build-cache/index.ts @@ -30,7 +30,7 @@ export async function withCache( buildFunc: () => Promise, ): Promise { const key = await Cache.readInputKey(options.inputs); - if (!key) { + if (!key || process.env.E2E) { print('input directory is dirty, skipping cache'); await fs.remove(options.output); await buildFunc(); diff --git a/packages/cli/src/commands/plugin/rollup.config.ts b/packages/cli/src/commands/plugin/rollup.config.ts index fe2675e0e0..c991fa3efb 100644 --- a/packages/cli/src/commands/plugin/rollup.config.ts +++ b/packages/cli/src/commands/plugin/rollup.config.ts @@ -46,6 +46,7 @@ export default { json(), typescript({ include: `${paths.resolveTarget('src')}/**/*.{js,jsx,ts,tsx}`, + clean: true, }), ], } as RollupWatchOptions; diff --git a/packages/cli/templates/default-app/package.json.hbs b/packages/cli/templates/default-app/package.json.hbs index 7b5fab5221..5161e85fe0 100644 --- a/packages/cli/templates/default-app/package.json.hbs +++ b/packages/cli/templates/default-app/package.json.hbs @@ -25,5 +25,8 @@ "@backstage/cli": "^{{version}}", "lerna": "^3.20.2", "prettier": "^1.19.1" + }, + "resolutions": { + "@backstage/cli": "file:/home/runner/work/backstage/backstage/packages/cli" } } diff --git a/packages/cli/templates/default-app/packages/app/package.json.hbs b/packages/cli/templates/default-app/packages/app/package.json.hbs index a5b2b07b96..940091380a 100644 --- a/packages/cli/templates/default-app/packages/app/package.json.hbs +++ b/packages/cli/templates/default-app/packages/app/package.json.hbs @@ -5,6 +5,7 @@ "dependencies": { "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "4.0.0-alpha.45", "@backstage/cli": "^{{version}}", "@backstage/core": "^{{version}}", "@backstage/theme": "^{{version}}", @@ -17,7 +18,8 @@ "plugin-welcome": "0.0.0", "react": "^16.12.0", "react-dom": "^16.12.0", - "react-router-dom": "^5.1.2" + "react-router-dom": "^5.1.2", + "react-use": "^13.24.0" }, "scripts": { "start": "backstage-cli app:serve", diff --git a/scripts/cli-e2e-test.js b/scripts/cli-e2e-test.js index e852f73ed0..814d2d6f60 100644 --- a/scripts/cli-e2e-test.js +++ b/scripts/cli-e2e-test.js @@ -27,27 +27,38 @@ const { const createTestApp = require('./createTestApp'); const createTestPlugin = require('./createTestPlugin'); +const generateTempDir = require('./generateTempDir.js'); Browser.localhost('localhost', 3000); async function main() { - process.env.CI = 'true'; + process.env.E2E = 'true'; - const projectDir = resolvePath(__dirname, '..'); - process.chdir(projectDir); + const rootDir = process.env.CI + ? resolvePath(process.env.GITHUB_WORKSPACE) + : resolvePath(__dirname, '..'); - await createTestApp(); + const tempDir = process.env.CI + ? resolvePath(__dirname) + : await generateTempDir(); - const appDir = resolvePath(projectDir, 'test-app'); + process.chdir(tempDir); + await waitForExit(spawnPiped(['yarn', 'init --yes'])); + + const createAppCmd = `${rootDir}/packages/cli/bin/backstage-cli create-app`; + await createTestApp(createAppCmd); + + const appDir = resolvePath(tempDir, 'test-app'); process.chdir(appDir); + await createTestPlugin(); + print('Starting the app'); const startApp = spawnPiped(['yarn', 'start']); try { const browser = new Browser(); - await createTestPlugin(); await waitForPageWithText(browser, '/', 'Welcome to Backstage'); await waitForPageWithText( browser, diff --git a/scripts/createTestApp.js b/scripts/createTestApp.js index 89fa023436..80f7bf3b18 100644 --- a/scripts/createTestApp.js +++ b/scripts/createTestApp.js @@ -16,9 +16,9 @@ const { spawnPiped, waitFor, waitForExit, print } = require('./helpers'); -async function createTestApp() { +async function createTestApp(cmd) { print('Creating a Backstage App'); - const createApp = spawnPiped(['yarn', 'create-app']); + const createApp = spawnPiped(['node', cmd]); try { let stdout = ''; diff --git a/scripts/createTestPlugin.js b/scripts/createTestPlugin.js index c204067ae3..59e8d6dd77 100644 --- a/scripts/createTestPlugin.js +++ b/scripts/createTestPlugin.js @@ -29,8 +29,8 @@ async function createTestPlugin() { await waitFor(() => stdout.includes('Enter an ID for the plugin')); createPlugin.stdin.write('test-plugin\n'); - await waitFor(() => stdout.includes('Enter the owner(s) of the plugin')); - createPlugin.stdin.write('@someuser\n'); + // await waitFor(() => stdout.includes('Enter the owner(s) of the plugin')); + // createPlugin.stdin.write('@someuser\n'); print('Waiting for plugin create script to be done'); await waitForExit(createPlugin); diff --git a/scripts/generateTempDir.js b/scripts/generateTempDir.js new file mode 100644 index 0000000000..e455a29320 --- /dev/null +++ b/scripts/generateTempDir.js @@ -0,0 +1,30 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const { handleError } = require('./helpers'); + +async function generateTempDir() { + const tempDir = await require('fs-extra').mkdtemp( + require('path').join(require('os').tmpdir(), 'backstage-e2e-'), + ); + process.stdout.write(tempDir); + return tempDir; +} + +module.exports = generateTempDir; + +process.on('unhandledRejection', handleError); +generateTempDir().catch(handleError);