diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000..c69a5cb18f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,31 @@
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+charset = utf-8
+indent_style = space
+
+[*.html]
+indent_style = space
+indent_size = 2
+
+[*.{ts,json,js,tsx,jsx}]
+indent_style = space
+indent_size = 2
+
+[*.md]
+indent_size = 2
+indent_style = space
+
+[Dockerfile]
+indent_style = space
+indent_size = 2
+
+[*.{yml,yaml}]
+indent_size = 2
+indent_style = space
diff --git a/.eslintrc.js b/.eslintrc.js
index a7cf9c3694..c227c17938 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,21 +1,4 @@
-const copyrightTemplate = `/*
- * 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 path = require('path')
const base = require('@spotify-backstage/cli/config/eslint');
module.exports = {
@@ -25,8 +8,7 @@ module.exports = {
'notice/notice': [
'error',
{
- template: copyrightTemplate,
- onNonMatchingHeader: 'replace',
+ templateFile: path.resolve(__dirname, "scripts/copyright.js"),
},
],
},
diff --git a/.github/ISSUE_TEMPLATE/bug_template.md b/.github/ISSUE_TEMPLATE/bug_template.md
new file mode 100644
index 0000000000..8c1733a6a6
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_template.md
@@ -0,0 +1,35 @@
+---
+name: 'Bug Report'
+about: 'Create Bug Report'
+---
+
+
+
+## Expected Behavior
+
+
+## Current Behavior
+
+
+## Possible Solution
+
+
+
+## Steps to Reproduce (for bugs)
+
+
+1.
+2.
+3.
+4.
+
+## Context
+
+
+
+
+## Your Environment
+
+* NodeJS Version (v12):
+* Operating System and Version (e.g. Ubuntu 14.04):
+* Browser Information:
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_template.md b/.github/ISSUE_TEMPLATE/feature_template.md
new file mode 100644
index 0000000000..17b543c27a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_template.md
@@ -0,0 +1,18 @@
+---
+name: 'Feature Request'
+about: 'Suggest new features and changes'
+---
+
+
+
+## Feature Suggestion
+
+
+
+## Possible Implementation
+
+
+## Context
+
+
+
\ No newline at end of file
diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml
new file mode 100644
index 0000000000..31bf396f5f
--- /dev/null
+++ b/.github/workflows/cli.yml
@@ -0,0 +1,49 @@
+name: CLI Test
+
+on:
+ pull_request:
+ paths: ['.github/workflows/cli.yml', 'packages/cli/**']
+ types: [opened, reopened, edited, synchronize]
+
+jobs:
+ build:
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ node-version: [12.x]
+
+ name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v2
+ - name: find location of yarn cache
+ id: yarn-cache
+ run: echo "::set-output name=dir::$(yarn cache dir)"
+ - uses: actions/cache@v1
+ 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 }}
+ - run: yarn install
+ - run: yarn build
+ # This creates a new plugin and pollutes the workspace, so it should be run last.
+ - name: verify app serve and plugin creation
+ shell: bash
+ run: |
+ if [ "$RUNNER_OS" == "Linux" ]; then
+ sudo sysctl fs.inotify.max_user_watches=524288
+ fi
+ node scripts/cli-e2e-test.js
+ - name: yarn lint, test after plugin creation
+ working-directory: plugins/test-plugin
+ run: |
+ yarn lint
+ yarn test
+ env:
+ CI: true
diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index 5db1f65aa3..5c8e5c43b9 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -13,9 +13,8 @@ jobs:
node-version: [12.x]
steps:
- - name: checkout code
- uses: actions/checkout@v2
- - name: get yarn cache
+ - uses: actions/checkout@v2
+ - name: find location of yarn cache
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
@@ -31,12 +30,8 @@ jobs:
- name: yarn install, build, and test
run: |
yarn install
+ yarn lint
yarn build
yarn test
env:
CI: true
- # This creates a new plugin and pollutes the workspace, so it should be run last.
- - name: verify app serve and plugin creation
- run: |
- sudo sysctl fs.inotify.max_user_watches=524288
- node scripts/cli-e2e-test.js
diff --git a/README.md b/README.md
index fd3bcb72d7..629bfdc376 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,23 @@
+
+
# [Backstage](https://backstage.io)
[](https://opensource.org/licenses/Apache-2.0)

[](https://discord.gg/EBHEGzX)
+
+
## What is Backstage?
Backstage is an open platform for building developer portals.
The philosophy behind Backstage is simple: Don't expose your engineers to the full complexity of your infrastructure tooling. Engineers should be shipping code — not figuring out a whole new toolset every time they want to implement the basics. Backstage allows you add "stuff" (tooling, services, features, etc.) by adding a plugin, instead of building a new tool. This saves you work and avoids the need of your team to learn how to use and support yet another tool.
-
-
For more information go to [backstage.io](https://backstage.io)
## What problem does Backstage solve?
-As companies grow, their infrastructure systems get messier. Backstage unifies all your infrastructure tooling, services, and documentation with a single, consistent UI.
+As companies grow, their infrastructure systems get messier. Backstage unifies all your infrastructure tooling, services, and documentation with a single, consistent UI.
This blog post provides more examples of how Backstage is used inside Spotify:
@@ -25,11 +27,11 @@ https://labs.spotify.com/2020/03/17/what-the-heck-is-backstage-anyway/
We created Backstage about 4 years ago. While our internal version of Backstage has had the benefit of time to mature and evolve, the first iteration of our open source version is still nascent. We are envisioning three phases of the project and we have already begun work on various aspects of these phases:
-- **Phase 1:** Extensible frontend platform (now) - You will be able to easily create a single consistent UI layer for your internal infrastructure and tools. A set of reusable UX patterns and components help ensure a consistent experience between tools.
+- 🐣 **Phase 1:** Extensible frontend platform (now) - You will be able to easily create a single consistent UI layer for your internal infrastructure and tools. A set of reusable UX patterns and components help ensure a consistent experience between tools.
-- **Phase 2:** Manage your stuff (next 2-3 months) - Manage anything from microservices to software components to infrastructure and your service catalog. Regardless of whether you want to create a new library, view service deployment status in Kubernetes, or check the test coverage for a website -- Backstage will provide all of those tools - and many more - in a single developer portal.
+- 🐢 **Phase 2:** Manage your stuff (next 2-3 months) - Manage anything from microservices to software components to infrastructure and your service catalog. Regardless of whether you want to create a new library, view service deployment status in Kubernetes, or check the test coverage for a website -- Backstage will provide all of those tools - and many more - in a single developer portal.
-- **Phase 3:** Ecosystem (later) - Everyone's infrastructure stack is different. By fostering a vibrant community of contributors we hope to provide an ecosystem of Open Source plugins/integrations that allows you to pick the tools that match your stack.
+- 🐇 **Phase 3:** Ecosystem (later) - Everyone's infrastructure stack is different. By fostering a vibrant community of contributors we hope to provide an ecosystem of Open Source plugins/integrations that allows you to pick the tools that match your stack.
Check out our [Milestones](https://github.com/spotify/backstage/milestones) and how they relate to the 3 Phases outlined above.
diff --git a/docs/headline.png b/docs/headline.png
new file mode 100644
index 0000000000..b0f9cb8b5c
Binary files /dev/null and b/docs/headline.png differ
diff --git a/headline.png b/headline.png
deleted file mode 100644
index 063f5be00b..0000000000
Binary files a/headline.png and /dev/null differ
diff --git a/packages/cli/.eslintrc.js b/packages/cli/.eslintrc.js
index 182a6df30a..f3f858836d 100644
--- a/packages/cli/.eslintrc.js
+++ b/packages/cli/.eslintrc.js
@@ -1,4 +1,5 @@
module.exports = {
+ ignorePatterns: ['templates/**'],
rules: {
'no-console': 0,
},
diff --git a/packages/cli/src/commands/plugin/assets.d.ts b/packages/cli/src/commands/plugin/assets.d.ts
index 34ba07f75c..54523e926b 100644
--- a/packages/cli/src/commands/plugin/assets.d.ts
+++ b/packages/cli/src/commands/plugin/assets.d.ts
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
///
///
///
diff --git a/packages/cli/src/commands/plugin/build.ts b/packages/cli/src/commands/plugin/build.ts
index ff95bb994a..4c2113eb2a 100644
--- a/packages/cli/src/commands/plugin/build.ts
+++ b/packages/cli/src/commands/plugin/build.ts
@@ -16,10 +16,27 @@
import { Command } from 'commander';
import fs from 'fs-extra';
-import recursive from 'recursive-readdir';
import path from 'path';
+import recursive from 'recursive-readdir';
import { run } from '../../helpers/run';
+const copyStaticAssets = async () => {
+ const pluginRoot = fs.realpathSync(process.cwd());
+ const source = path.resolve(pluginRoot, 'src');
+ const destination = path.resolve(pluginRoot, 'dist', 'cjs');
+ const assetFiles = await recursive(source, [
+ '**/*.tsx',
+ '**/*.ts',
+ '**/*.js',
+ ]);
+ assetFiles.forEach(file => {
+ const fileToBeCopied = file.replace(source, destination);
+ const dirForFileToBeCopied = path.dirname(fileToBeCopied);
+ fs.ensureDirSync(dirForFileToBeCopied);
+ fs.copyFileSync(file, file.replace(source, destination).toString());
+ });
+};
+
export default async (cmd: Command) => {
const args = [
'--outDir',
@@ -37,20 +54,3 @@ export default async (cmd: Command) => {
await copyStaticAssets();
await run('tsc', args);
};
-
-const copyStaticAssets = async () => {
- const pluginRoot = fs.realpathSync(process.cwd());
- const source = path.resolve(pluginRoot, 'src');
- const destination = path.resolve(pluginRoot, 'dist', 'cjs');
- const assetFiles = await recursive(source, [
- '**/*.tsx',
- '**/*.ts',
- '**/*.js',
- ]);
- assetFiles.forEach(file => {
- const fileToBeCopied = file.replace(source, destination);
- const dirForFileToBeCopied = path.dirname(fileToBeCopied);
- fs.ensureDirSync(dirForFileToBeCopied);
- fs.copyFileSync(file, file.replace(source, destination).toString());
- });
-};
diff --git a/packages/cli/templates/default-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs b/packages/cli/templates/default-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs
index 2bb43d5cce..4801dea6dd 100644
--- a/packages/cli/templates/default-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs
+++ b/packages/cli/templates/default-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs
@@ -1,3 +1,4 @@
+/* eslint-disable react/prop-types */
/*
* Copyright 2020 Spotify AB
*
diff --git a/packages/cli/templates/default-plugin/src/plugin.test.ts.hbs b/packages/cli/templates/default-plugin/src/plugin.test.ts.hbs
index 0139d97727..4e94ca5d50 100644
--- a/packages/cli/templates/default-plugin/src/plugin.test.ts.hbs
+++ b/packages/cli/templates/default-plugin/src/plugin.test.ts.hbs
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
import plugin from './plugin';
describe('{{ id }}', () => {
diff --git a/packages/cli/templates/default-plugin/src/plugin.ts.hbs b/packages/cli/templates/default-plugin/src/plugin.ts.hbs
index 830de5f553..ccac096007 100644
--- a/packages/cli/templates/default-plugin/src/plugin.ts.hbs
+++ b/packages/cli/templates/default-plugin/src/plugin.ts.hbs
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
import { createPlugin } from '@spotify-backstage/core';
import ExampleComponent from './components/ExampleComponent';
diff --git a/packages/core/src/testUtils/logCollector.js b/packages/core/src/testUtils/logCollector.js
index 57b30c8f5c..c3ffa525b3 100644
--- a/packages/core/src/testUtils/logCollector.js
+++ b/packages/core/src/testUtils/logCollector.js
@@ -15,6 +15,7 @@
*/
/* eslint-disable no-console */
+/* eslint-disable no-param-reassign */
// If the callback function is async this one will be too.
export function withLogCollector(logsToCollect, callback) {
diff --git a/scripts/copyright.js b/scripts/copyright.js
new file mode 100644
index 0000000000..4376d55847
--- /dev/null
+++ b/scripts/copyright.js
@@ -0,0 +1,15 @@
+/*
+ * Copyright <%= YEAR %> 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.
+ */
diff --git a/yarn.lock b/yarn.lock
index dda14de215..a6914db055 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10772,12 +10772,12 @@ load-json-file@^5.3.0:
type-fest "^0.3.0"
loader-fs-cache@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz#54cedf6b727e1779fd8f01205f05f6e88706f086"
- integrity sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw==
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz#f08657646d607078be2f0a032f8bd69dd6f277d9"
+ integrity sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==
dependencies:
find-cache-dir "^0.1.1"
- mkdirp "0.5.1"
+ mkdirp "^0.5.1"
loader-runner@^2.4.0:
version "2.4.0"
@@ -11435,16 +11435,16 @@ minimist-options@^3.0.1:
arrify "^1.0.1"
is-plain-obj "^1.1.0"
-minimist@0.0.8:
- version "0.0.8"
- resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
- integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
-
minimist@1.2.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
+minimist@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
+ integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+
minimist@~0.0.1:
version "0.0.10"
resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
@@ -11537,12 +11537,12 @@ mkdirp@*:
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea"
integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==
-mkdirp@0.5.1, mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
- version "0.5.1"
- resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
- integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
+mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
+ version "0.5.3"
+ resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz#5a514b7179259287952881e94410ec5465659f8c"
+ integrity sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==
dependencies:
- minimist "0.0.8"
+ minimist "^1.2.5"
modify-values@^1.0.0:
version "1.0.1"