diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000000..bbe2ee8e93 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,8 @@ +comment: false # Ref: https://docs.codecov.io/docs/pull-request-comments + +coverage: + status: + project: + default: + threshold: 0% # Ref: https://docs.codecov.io/docs/codecovyml-reference#coveragestatus + target: auto diff --git a/.github/workflows/e2e-win.yml b/.github/workflows/e2e-win.yml index b4ea1e350f..5bab1b1299 100644 --- a/.github/workflows/e2e-win.yml +++ b/.github/workflows/e2e-win.yml @@ -27,25 +27,12 @@ jobs: steps: - uses: actions/checkout@v2 - # Beginning of yarn setup, keep in sync between all workflows, see ci.yml - name: use node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ # Needed for auth - - name: find location of global yarn cache - id: yarn-cache - run: echo "::set-output name=dir::$(yarn cache dir)" - - name: cache global yarn cache - uses: actions/cache@v2 - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - name: yarn install run: yarn install --frozen-lockfile - # End of yarn setup - run: yarn tsc - name: yarn build diff --git a/.github/workflows/techdocs-project-board.yml b/.github/workflows/techdocs-project-board.yml new file mode 100644 index 0000000000..b389cf6bf5 --- /dev/null +++ b/.github/workflows/techdocs-project-board.yml @@ -0,0 +1,53 @@ +name: Automatically add new TechDocs Issues and PRs to the GitHub project board +# Development of TechDocs in Backstage is managed by this Kanban board - https://github.com/spotify/backstage/projects/5 +# New issues with TechDocs in their title or docs-like-code label will be added to the board. + +on: + issues: + types: [opened, reopened, labeled, edited] + pull_request: + types: [opened, reopened, labeled, edited] + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + assign_issue_or_pr_to_project: + runs-on: ubuntu-latest + name: Triage + steps: + - name: Assign new issue to Incoming based on its title. + uses: srggrs/assign-one-project-github-action@1.2.0 + if: | + contains(github.event.issue.title, 'TechDocs') || + contains(github.event.issue.title, 'techdocs') || + contains(github.event.issue.title, 'Techdocs') + with: + project: 'https://github.com/spotify/backstage/projects/5' + column_name: 'Incoming' + + - name: Assign new issue to Incoming based on its label. + uses: srggrs/assign-one-project-github-action@1.2.0 + if: | + contains(github.event.issue.labels.*.name, 'docs-like-code') + with: + project: 'https://github.com/spotify/backstage/projects/5' + column_name: 'Incoming' + + - name: Assign new PR to Incoming based on its title. + uses: srggrs/assign-one-project-github-action@1.2.0 + if: | + contains(github.event.pull_request.title, 'TechDocs') || + contains(github.event.pull_request.title, 'techdocs') || + contains(github.event.pull_request.title, 'Techdocs') + with: + project: 'https://github.com/spotify/backstage/projects/5' + column_name: 'Incoming' + + - name: Assign new PR to Incoming based on its label. + uses: srggrs/assign-one-project-github-action@1.2.0 + if: | + contains(github.event.pull_request.labels.*.name, 'docs-like-code') + with: + project: 'https://github.com/spotify/backstage/projects/5' + column_name: 'Incoming' diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f9235172b..294c57815e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,13 +6,40 @@ If you encounter issues while upgrading to a newer version, don't hesitate to re ## Next Release +### @backstage/core + +- Introduced initial version of an inverted app/plugin relationship, where plugins export components for apps to use, instead registering themselves directly into the app. This enables more fine-grained control of plugin features, and also composition of plugins such as catalog pages with additional cards and tabs. This breaks the use of `RouteRef`s, and there will be more changes related to this in the future, but this change lays the initial foundation. See `packages/app` and followup PRs for how to update plugins for this change. [#2076](https://github.com/spotify/backstage/pull/2076) +- Switch to an automatic dependency injection mechanism for all Utility APIs, allowing plugins to ship default implementations of their APIs. See [https://backstage.io/docs/api/utility-apis](https://backstage.io/docs/api/utility-apis). [#2285](https://github.com/spotify/backstage/pull/2285) + > Collect changes for the next release below +### @backstage/cli + +- Change `backstage-cli backend:build-image` to forward all args to `docker image build`, instead of just tag. Also add `--build` flag for building all dependent packages before packaging the workspace for the docker build. [#2299](https://github.com/spotify/backstage/pull/2299) + +### @backstage/create-app + +- Change root `tsc` output dir to `dist-types`, in order to allow for standalone plugin repos. [#2278](https://github.com/spotify/backstage/pull/2278) + +## v0.1.1-alpha.21 + +- Added many more frontend plugins to the template along with the sidebar. [#1942](https://github.com/spotify/backstage/pull/1942), [#2084](https://github.com/spotify/backstage/pull/2084) + +### @backstage/core + - Material-UI: Bumped to 4.11.0, which is the version that create-app will resolve to, because we wanted to get the renaming of ExpansionPanel to Accordion into place. This gets rid of a lot of console deprecation warnings in newly scaffolded apps. +### @backstage/cli + +- Set `NODE_ENV` to `test` when running test. [#2214](https://github.com/spotify/backstage/pull/2214) + +- Fix for backend plugins names requiring to be prefixed with `@backstage` to build. [#2224](https://github.com/spotify/backstage/pull/2224) + +### @backstage/backend-common + - The backend plugin [service builder](https://github.com/spotify/backstage/blob/master/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts) no longer adds `express.json()` automatically to all routes. While convenient @@ -22,14 +49,31 @@ If you encounter issues while upgrading to a newer version, don't hesitate to re still had to cater to that manually. We therefore decided to let plugins add `express.json()` themselves if they happen to deal with JSON data. +### @backstage/catalog-backend + +- Add rules configuration for catalog location and entity kinds. The default rules should cover most use-cases, but you may need to allow specific entity kinds when using things like Template or Group entities. [#2118](https://github.com/spotify/backstage/pull/2118) + ## v0.1.1-alpha.20 -- Includes https://github.com/spotify/backstage/pull/2097 to resolve issues with create-plugin command. +### @backstage/cli + +- Use config files according to `NODE_ENV` when serving and building frontend packages. [#2077](https://github.com/spotify/backstage/pull/2077) + +- Pin `rollup-plugin-dts` to avoid a later broken version. [#2097](https://github.com/spotify/backstage/pull/2097) ## v0.1.1-alpha.19 +### @backstage/backend-common + +- Allow listen host and port to be configured separately, in order to support PORT environment variables. [#1950](https://github.com/spotify/backstage/pull/1950) + +### @backstage/core + +- Added new `DiscoveryApi` for discovering backend endpoint in the frontend, and use in most plugins. See [packages/app/src/apis.ts](https://github.com/spotify/backstage/blob/master/packages/app/src/apis.ts) for how to register in your app. [#2074](https://github.com/spotify/backstage/pull/2074) + ### @backstage/create-app +- Added catalog and scaffolder frontend plugins to the template along with the sidebar. [#1942](https://github.com/spotify/backstage/pull/1942), [#2084](https://github.com/spotify/backstage/pull/2084) - Many plugins have been added to the catalog and will for now be required to be added to separate apps as well. This will be solved as [#1536](https://github.com/spotify/backstage/issues/1536) gets sorted out, but for now you may need to install some plugins just to get pages to work. ### @backstage/catalog-backend diff --git a/app-config.yaml b/app-config.yaml index 2d7f31e72d..5b704f9b8e 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -76,23 +76,27 @@ catalog: privateToken: $secret: env: AZURE_PRIVATE_TOKEN - exampleEntityLocations: - github: - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/artist-lookup-component.yaml - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/playback-order-component.yaml - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/podcast-api-component.yaml - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/queue-proxy-component.yaml - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/searcher-component.yaml - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/playback-lib-component.yaml - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/www-artist-component.yaml - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/shuffle-api-component.yaml - - https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml - - https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/template.yaml - - https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml - - https://github.com/spotify/cookiecutter-golang/blob/master/template.yaml - - https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/docs-template/template.yaml - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/hello-world-api.yaml - - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/streetlights-api.yaml + + locations: + # Backstage example components + - type: github + target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/all-components.yaml + + # Example component for github-actions + - type: github + target: https://github.com/spotify/backstage/blob/master/plugins/github-actions/examples/sample.yaml + + # Example component for techdocs + - type: github + target: https://github.com/spotify/backstage/blob/master/plugins/techdocs-backend/examples/documented-component/documented-component.yaml + + # Backstage example APIs + - type: github + target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/all-apis.yaml + + # Backstage example templates + - type: github + target: https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/all-templates.yaml auth: providers: diff --git a/docs/features/software-templates/adding-templates.md b/docs/features/software-templates/adding-templates.md index 4f7af7c015..1472986c2a 100644 --- a/docs/features/software-templates/adding-templates.md +++ b/docs/features/software-templates/adding-templates.md @@ -105,13 +105,6 @@ curl \ This should then have added the catalog, and also should now be listed under the create page at http://localhost:3000/create. -Alternatively, if you want to get setup with some mock templates that are -already provided, run the following to load those templates: - -``` -yarn lerna run mock-data -``` - The `type` field which is chosen in the request to add the `template.yaml` to the Service Catalog here, will be come the `PreparerKey` which will be used to select the `Preparer` when creating a job. diff --git a/docs/features/techdocs/FAQ.md b/docs/features/techdocs/FAQ.md index 8c716313bb..cae0288889 100644 --- a/docs/features/techdocs/FAQ.md +++ b/docs/features/techdocs/FAQ.md @@ -6,14 +6,11 @@ sidebar_label: FAQ This page answers frequently asked questions about [TechDocs](README.md). -_Got a question that you think others might be interested in knowing the answer -to? Edit this file -[here](https://github.com/spotify/backstage/edit/master/docs/features/techdocs/FAQ.md)._ - ## Technology - [What static site generator is TechDocs using?](#what-static-site-generator-is-techdocs-using) - [What is the mkdocs-techdocs-core plugin?](#what-is-the-mkdocs-techdocs-core-plugin) +- [Does TechDocs support file formats other than Markdown (e.g. rst, asciidoc)?](#does-techdocs-support-file-formats-other-than-markdown-eg-rst-asciidoc-) #### What static site generator is TechDocs using? @@ -30,3 +27,10 @@ package is a MkDocs Plugin that works like a wrapper around multiple MkDocs plugins (e.g. [MkDocs Monorepo Plugin](https://github.com/spotify/mkdocs-monorepo-plugin)) as well as a selection of Python Markdown extensions that TechDocs supports. + +#### Does TechDocs support file formats other than Markdown (e.g. rst, asciidoc) ? + +Not right now. We are currently using MkDocs to generate the documentation from +source. So, they have to be in Markdown format. However, in future we want to +support other alternatives to MkDocs. That will make it possible to use other +file formats. diff --git a/docs/features/techdocs/README.md b/docs/features/techdocs/README.md index a7af6cc503..03f3d452f4 100644 --- a/docs/features/techdocs/README.md +++ b/docs/features/techdocs/README.md @@ -8,16 +8,21 @@ sidebar_label: Overview -Wait, what is TechDocs? TechDocs is Spotify’s homegrown docs-like-code solution -built directly into Backstage. Today, it is now one of the core products in -Spotify’s developer experience offering with 2,400+ documentation sites and -1,000+ engineers using it daily. +TechDocs is Spotify’s homegrown docs-like-code solution built directly into +Backstage. This means engineers write their documentation in Markdown files +which live together with their code. + +Today, it is one of the core products in Spotify’s developer experience offering +with 2,400+ documentation sites and 1,000+ engineers using it daily. Read more +about TechDocs and the philosophy in its +[announcement blog post](https://backstage.io/blog/2020/09/08/announcing-tech-docs). +🎉 ## Features -- A centralized place to discover documentation. +- A centralized place to discover and read documentation. -- A clear end-to-end docs-like-code solution. (_Coming soon in V.1_) +- A clear end-to-end docs-like-code solution. - A tightly coupled feedback loop with the developer workflow. (_Coming soon in V.3_) @@ -44,7 +49,7 @@ Spotify’s developer experience offering with 2,400+ documentation sites and #### TechDocs V.0 - As a user I can navigate to a manually curated docs explore page. -- As a user I can navigte to and read mock documentation that is manually +- As a user I can navigate to and read mock documentation that is manually uploaded by the TechDocs core team. #### TechDocs V.1 @@ -101,7 +106,3 @@ more to come... https://github.com/spotify/backstage/blob/master/packages/techdocs-container [techdocs/cli]: https://github.com/spotify/backstage/blob/master/packages/techdocs-cli - -## TechDocs Big Picture - -![TechDocs Big Picture](../..//assets/techdocs/techdocs_big_picture.png) diff --git a/docs/features/techdocs/architecture.md b/docs/features/techdocs/architecture.md new file mode 100644 index 0000000000..4e063a8559 --- /dev/null +++ b/docs/features/techdocs/architecture.md @@ -0,0 +1,6 @@ +--- +id: architecture +title: Architecture +--- + +![TechDocs Big Picture](../../assets/techdocs/techdocs_big_picture.png) diff --git a/docs/features/techdocs/concepts.md b/docs/features/techdocs/concepts.md index 2fa84cebd6..8f5558c0f8 100644 --- a/docs/features/techdocs/concepts.md +++ b/docs/features/techdocs/concepts.md @@ -8,9 +8,9 @@ solution in Backstage. ### TechDocs Core Plugin -The TechDocs Core Plugin is a MkDocs plugin created as a wrapper around multiple -MkDocs plugins and Python Markdown extensions to standardize the configuration -of MkDocs used for TechDocs. +The TechDocs Core Plugin is an [MkDocs](https://www.mkdocs.org/) plugin created +as a wrapper around multiple MkDocs plugins and Python Markdown extensions to +standardize the configuration of MkDocs used for TechDocs. [TechDocs Core](https://github.com/spotify/backstage/blob/master/packages/techdocs-container/techdocs-core/README.md) diff --git a/docs/features/techdocs/creating-and-publishing.md b/docs/features/techdocs/creating-and-publishing.md index 0dfa40f819..89df2fb18e 100644 --- a/docs/features/techdocs/creating-and-publishing.md +++ b/docs/features/techdocs/creating-and-publishing.md @@ -11,7 +11,7 @@ This section will guide you through: - [Manually add documentation setup to already existing repository](#manually-add-documentation-setup-to-already-existing-repository) - [Writing and previewing your documentation](#writing-and-previewing-your-documentation) -## Prerequisities +## Prerequisites - A working Backstage instance with TechDocs installed (see [TechDocs getting started](getting-started.md)) @@ -81,12 +81,12 @@ updated documentation next time you run Backstage! ## Writing and previewing your documentation Using the `techdocs-cli` you can preview your docs inside a local Backstage -instance and get automatic recompilation on changes. This is useful for when you -want to write your documentation. +instance and get live reload on changes. This is useful when you want to preview +your documentation while writing. To do this you can run: ```bash -cd ~// +cd /path/to/docs-repository/ npx @techdocs/cli serve ``` diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md index 33edfecbe8..174894b020 100644 --- a/docs/features/techdocs/getting-started.md +++ b/docs/features/techdocs/getting-started.md @@ -6,35 +6,8 @@ title: Getting Started TechDocs functions as a plugin to Backstage, so you will need to use Backstage to use TechDocs. -## What is Backstage? - -Backstage is an open platform for building developer portals. It’s based on the -developer portal we’ve been using internally at Spotify for over four years. -[Read more here](https://github.com/spotify/backstage). - -## Prerequisities - -In order to use Backstage and TechDocs, you need to have the following -installed: - -- [Node.js](https://nodejs.org) Active LTS (long term support), currently v12 -- [Yarn](https://yarnpkg.com/getting-started/install) - -## Creating a new Backstage app - -> If you have already created a Backstage application, jump to -> [Installing TechDocs](#installing-techdocs), otherwise complete this step. - -To create a new Backstage application for TechDocs, run the following command: - -```bash -npx @backstage/create-app -``` - -You will then be prompted to enter a name for your application. Once that's -done, a new Backstage application will be created in a new folder. For example, -if you choose the name `hello-world`, a new `hello-world` folder is created -containing your new Backstage application. +If you haven't setup Backstage already, start +[here](../../getting-started/index.md). ## Installing TechDocs @@ -74,7 +47,7 @@ export { plugin as TechDocs } from '@backstage/plugin-techdocs'; ### Setting the configuration TechDocs allows for configuration of the docs storage URL through your -`app-config` file. We provide two different values to be configured, +`app-config.yaml` file. We provide two different values to be configured, `requestUrl` and `storageUrl`. The `requestUrl` is what the reader will request its data from, and `storageUrl` is where the backend can find the stored documentation. @@ -87,13 +60,13 @@ techdocs: requestUrl: http://localhost:7000/techdocs/docs ``` -If you want `techdocs-backend` to manage building and publishing you want +If you want `techdocs-backend` to manage building and publishing, you want `requestUrl` to point to the default value (or wherever `techdocs-backend` is hosted). `storageUrl` should be where your publisher publishes your docs. Using the default `LocalPublish` that is the default value. If you have a setup where you are not using `techdocs-backend` for managing -building and publishing of your documentation you want to change the +building and publishing of your documentation, you want to change the `requestUrl` to point to your storage. In this case `storageUrl` is not required. diff --git a/docs/getting-started/running-backstage-locally.md b/docs/getting-started/running-backstage-locally.md index 04be6499c6..08d2ab385b 100644 --- a/docs/getting-started/running-backstage-locally.md +++ b/docs/getting-started/running-backstage-locally.md @@ -4,8 +4,8 @@ title: Running Backstage Locally --- First make sure you are using NodeJS with an Active LTS Release, currently v12. -This is made easy with a version manager such as nvm which allows for version -switching. +This is made easy with a version manager such as +[nvm](https://github.com/nvm-sh/nvm) which allows for version switching. ```bash # Checking your version @@ -48,18 +48,27 @@ yarn start That starts up a backend instance on port 7000. -In the other window, we will first populate the catalog with some nice mock data -to look at, and then launch the frontend. These commands are run from the -project root, not inside the backend directory. +In the other window, we will then launch the frontend. This command is run from +the project root, not inside the backend directory. ```bash -yarn lerna run mock-data yarn start ``` That starts up the frontend on port 3000, and should automatically open a browser window showing it. +## Authentication + +When Backstage starts, you can choose to enter as a Guest user and start +exploring. + +But you can also set up any of the available authentication methods. The easiest +option will be GitHub. To setup GitHub authentication in Backstage, see +[these instructions](https://github.com/spotify/backstage/tree/master/plugins/auth-backend#github). + +--- + Congratulations! That should be it. Let us know how it went [on discord](https://discord.gg/EBHEGzX), file issues for any [feature](https://github.com/spotify/backstage/issues/new?labels=help+wanted&template=feature_template.md) @@ -80,5 +89,3 @@ instance of Backstage with your own plugins. - [Create a Backstage Plugin](../plugins/create-a-plugin.md) - [Structure of a Plugin](../plugins/structure-of-a-plugin.md) - [Utility APIs](../api/utility-apis.md) - -[Back to Docs](../README.md) diff --git a/microsite/blog/2020-08-05-announcing-backstage-software-templates.md b/microsite/blog/2020-08-05-announcing-backstage-software-templates.md index 51c1da2885..81d495e1c3 100644 --- a/microsite/blog/2020-08-05-announcing-backstage-software-templates.md +++ b/microsite/blog/2020-08-05-announcing-backstage-software-templates.md @@ -39,7 +39,7 @@ You can customize Backstage Software Templates to fit your organization’s stan ## Getting started -The sample Software Templates are available under `/create`. If you're setting up Backstage for the first time, follow [Getting Started with Backstage](https://backstage.io/docs/getting-started/) and go to `http://localhost:3000/create`. If you’ve already been running Backstage locally, run the command `yarn lerna run mock-data` to load the new sample templates into the Service Catalog first. +The sample Software Templates are available under `/create`. If you're setting up Backstage for the first time, follow [Getting Started with Backstage](https://backstage.io/docs/getting-started/) and go to `http://localhost:3000/create`. ![available-templates](assets/2020-08-05/templates.png) diff --git a/microsite/package.json b/microsite/package.json index 25598c18b4..734f1e4d49 100644 --- a/microsite/package.json +++ b/microsite/package.json @@ -13,7 +13,7 @@ "rename-version": "docusaurus-rename-version" }, "devDependencies": { - "docusaurus": "^2.0.0-alpha.61", + "docusaurus": "^2.0.0-alpha.64", "js-yaml": "^3.14.0" } } diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 7b4c852f4d..f7aa0630ef 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -42,6 +42,7 @@ "features/software-catalog/installation", "features/software-catalog/system-model", "features/software-catalog/descriptor-format", + "features/software-catalog/well-known-annotations", "features/software-catalog/extending-the-model", "features/software-catalog/external-integrations", "features/software-catalog/software-catalog-api" @@ -62,11 +63,12 @@ }, { "type": "subcategory", - "label": "Docs-like-code", + "label": "TechDocs", "ids": [ "features/techdocs/techdocs-overview", "features/techdocs/getting-started", "features/techdocs/concepts", + "features/techdocs/architecture", "features/techdocs/creating-and-publishing", "features/techdocs/faqs" ] diff --git a/microsite/siteConfig.js b/microsite/siteConfig.js index f0762dbf09..d7a3bd67d0 100644 --- a/microsite/siteConfig.js +++ b/microsite/siteConfig.js @@ -67,8 +67,9 @@ const siteConfig = { primaryColor: '#36BAA2', secondaryColor: '#121212', textColor: '#FFFFFF', - navigatorTitleTextColor: '#9e9e9e', - navigatorItemTextColor: '#616161', + navigatorTitleTextColor: '#e4e4e4', + navigatorItemTextColor: '#9e9e9e', + navGroupSubcategoryTitleColor: '#9e9e9e', }, /* Colors for syntax highlighting */ diff --git a/microsite/static/css/custom.css b/microsite/static/css/custom.css index 5e078582cc..111065a5d5 100644 --- a/microsite/static/css/custom.css +++ b/microsite/static/css/custom.css @@ -113,6 +113,10 @@ td { color: $navigatorTitleTextColor; } +.toc .toggleNav .navGroup .navGroupSubcategoryTitle { + color: $navGroupSubcategoryTitleColor; +} + .toc .toggleNav ul li a, .onPageNav a { color: $navigatorItemTextColor; @@ -203,6 +207,54 @@ td { border-radius: 0.25rem; } +/* + * Fix for viewing Table of Contents bar on documentation + * and blog pages on smaller screens. + */ +@media only screen and (max-width: 1023px) { + /* Nav bar hides the docs toc bar */ + .docMainWrapper { + margin-top: 4rem; + } + + /* Toc bar does not have to be fixed */ + .docsNavContainer { + position: unset; + width: 95vw; + z-index: 100; + margin-left: -2vw; + } + + /* Toc bar does not have to be fixed when slider is active */ + .docsSliderActive .toc .navBreadcrumb, + .tocActive .navBreadcrumb { + position: unset; + } + + /* Fix unexpected width increase when toc is toggled */ + .docsSliderActive .toc .navBreadcrumb, + .tocActive .navBreadcrumb { + width: inherit; + } + + /* This pseudo-element stops toc toggle button to be clicked */ + header.postHeader::before { + height: 2em !important; + margin-top: -2em !important; + } + + /* This pseudo-element stops toc toggle button to be clicked */ + #__docusaurus.postHeaderTitle::before { + height: 1em; + margin-top: -1em; + } + + /* Useless button causing trouble */ + .tocToggler { + display: none; + } +} + /* content */ .postContainer blockquote { color: $textColor; @@ -288,17 +340,17 @@ code { background: linear-gradient(70.44deg, #121212 75%, #5d817b 100%); } .bg-teal-top-right { - background: + background: /* linear-gradient( 178.64deg, rgba(255, 255, 255, 0) 57.61%, rgba(255, 255, 255, 0.17) 127.71% - ), */ + ), */ /* linear-gradient( 144.35deg, rgba(98, 197, 179, 0) 56.68%, rgba(98, 197, 179, 0.59) 109.25% - ), */ + ), */ /* linear-gradient( 192.29deg, rgba(155, 240, 225, 0) 54.17%, diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 422959d3fd..84b5d50d60 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -2228,10 +2228,10 @@ dir-glob@2.0.0: arrify "^1.0.1" path-type "^3.0.0" -docusaurus@^2.0.0-alpha.61: - version "2.0.0-alpha.63" - resolved "https://registry.npmjs.org/docusaurus/-/docusaurus-2.0.0-alpha.63.tgz#40402d47b18c42b62e93beb78ce06e000cb88312" - integrity sha512-R19pAqcTemJMt7Qykd7ogB2i6R86vbE4/vA/l5/Uuh7xg7ixSKOVZ5M7d9uSoX5jCALOwEyp5iJdleznXUVwAw== +docusaurus@^2.0.0-alpha.64: + version "2.0.0-alpha.64" + resolved "https://registry.yarnpkg.com/docusaurus/-/docusaurus-2.0.0-alpha.64.tgz#7833960e9d338403894a27b79058aa4076a676d3" + integrity sha512-ARCx0GwAvc5qx7AHvRVZidZuoDTfaaGXzgmkU23NahU6jzO/aK2Q1bH8IKNEQ5C2JuDerQ/hHDh80N20ijk82g== dependencies: "@babel/core" "^7.9.0" "@babel/plugin-proposal-class-properties" "^7.8.3" diff --git a/mkdocs.yml b/mkdocs.yml index 10cd7df9b2..a74ef5737f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -30,6 +30,7 @@ nav: - Overview: 'features/software-catalog/index.md' - System model: 'features/software-catalog/system-model.md' - YAML File Format: 'features/software-catalog/descriptor-format.md' + - Well-known Annotations: 'features/software-catalog/well-known-annotations.md' - Configuration: 'features/software-catalog/configuration.md' - Extending the model: 'features/software-catalog/extending-the-model.md' - External integrations: 'features/software-catalog/external-integrations.md' @@ -43,10 +44,11 @@ nav: - Create your own Templater: 'features/software-templates/extending/create-your-own-templater.md' - Create your own Publisher: 'features/software-templates/extending/create-your-own-publisher.md' - Create your own Preparer: 'features/software-templates/extending/create-your-own-preparer.md' - - Docs-like-code: + - TechDocs: - Overview: 'features/techdocs/README.md' - Getting Started: 'features/techdocs/getting-started.md' - Concepts: 'features/techdocs/concepts.md' + - TechDocs Architecture: 'features/techdocs/architecture.md' - Creating and Publishing Documentation: 'features/techdocs/creating-and-publishing.md' - FAQ: 'features/techdocs/FAQ.md' - Plugins: diff --git a/packages/backend/README.md b/packages/backend/README.md index 860520f4b5..c45a0d28d9 100644 --- a/packages/backend/README.md +++ b/packages/backend/README.md @@ -43,21 +43,13 @@ The backend starts up on port 7000 per default. ## Populating The Catalog -If you want to use the catalog functionality, you need to add so called locations -to the backend. These are places where the backend can find some entity descriptor -data to consume and serve. +If you want to use the catalog functionality, you need to add so called +locations to the backend. These are places where the backend can find some +entity descriptor data to consume and serve. For more information, see +[Software Catalog Overview - Adding Components to the Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview#adding-components-to-the-catalog). -To get started, you can issue the following after starting the backend, from inside -the `plugins/catalog-backend` directory: - -```bash -yarn mock-data -``` - -You should then start seeing data on `localhost:7000/catalog/entities`. - -The catalog currently runs in-memory only, so feel free to try it out, but it will -need to be re-populated on next startup. +For convenience we already include some statically configured example locations +in `app-config.yaml` under `catalog.locations`. For local development you can override these in your own `app-config.local.yaml`. ## Authentication diff --git a/packages/catalog-model/examples/all-apis.yaml b/packages/catalog-model/examples/all-apis.yaml new file mode 100644 index 0000000000..33b000d1ae --- /dev/null +++ b/packages/catalog-model/examples/all-apis.yaml @@ -0,0 +1,10 @@ +apiVersion: backstage.io/v1alpha1 +kind: Location +metadata: + name: example-apis + description: A collection of all Backstage example APIs +spec: + type: github + targets: + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/hello-world-api.yaml + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/streetlights-api.yaml diff --git a/packages/catalog-model/examples/all-components.yaml b/packages/catalog-model/examples/all-components.yaml new file mode 100644 index 0000000000..cad4eee044 --- /dev/null +++ b/packages/catalog-model/examples/all-components.yaml @@ -0,0 +1,16 @@ +apiVersion: backstage.io/v1alpha1 +kind: Location +metadata: + name: example-components + description: A collection of all Backstage example components +spec: + type: github + targets: + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/artist-lookup-component.yaml + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/playback-order-component.yaml + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/podcast-api-component.yaml + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/queue-proxy-component.yaml + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/searcher-component.yaml + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/playback-lib-component.yaml + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/www-artist-component.yaml + - https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/shuffle-api-component.yaml diff --git a/packages/create-app/templates/default-app/app-config.yaml.hbs b/packages/create-app/templates/default-app/app-config.yaml.hbs index bdd933e810..7b86b4f50e 100644 --- a/packages/create-app/templates/default-app/app-config.yaml.hbs +++ b/packages/create-app/templates/default-app/app-config.yaml.hbs @@ -51,25 +51,12 @@ catalog: locations: # Backstage example components - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/artist-lookup-component.yaml + target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/all-components.yaml + + # Backstage example APIs - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/playback-order-component.yaml - - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/podcast-api-component.yaml - - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/queue-proxy-component.yaml - - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/searcher-component.yaml - - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/playback-lib-component.yaml - - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/www-artist-component.yaml - - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/shuffle-api-component.yaml - - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/hello-world-api.yaml - - type: github - target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/streetlights-api.yaml + target: https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/all-apis.yaml + # Backstage example templates - type: github target: https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml diff --git a/packages/create-app/templates/default-app/packages/backend/README.md b/packages/create-app/templates/default-app/packages/backend/README.md index f94904a930..5583bff625 100644 --- a/packages/create-app/templates/default-app/packages/backend/README.md +++ b/packages/create-app/templates/default-app/packages/backend/README.md @@ -3,8 +3,8 @@ This package is an EXAMPLE of a Backstage backend. The main purpose of this package is to provide a test bed for Backstage plugins -that have a backend part. Feel free to experiment locally or within your fork -by adding dependencies and routes to this backend, to try things out. +that have a backend part. Feel free to experiment locally or within your fork by +adding dependencies and routes to this backend, to try things out. Our goal is to eventually amend the create-app flow of the CLI, such that a production ready version of a backend skeleton is made alongside the frontend @@ -33,34 +33,32 @@ LOG_LEVEL=debug \ yarn start ``` -Substitute `x` for actual values, or leave them as -dummy values just to try out the backend without using the auth or sentry features. +Substitute `x` for actual values, or leave them as dummy values just to try out +the backend without using the auth or sentry features. The backend starts up on port 7000 per default. ## Populating The Catalog -If you want to use the catalog functionality, you need to add so called locations -to the backend. These are places where the backend can find some entity descriptor -data to consume and serve. +If you want to use the catalog functionality, you need to add so called +locations to the backend. These are places where the backend can find some +entity descriptor data to consume and serve. For more information, see +[Software Catalog Overview - Adding Components to the Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview#adding-components-to-the-catalog). -To get started, you can issue the following after starting the backend, from inside -the `plugins/catalog-backend` directory: - -```bash -yarn mock-data -``` - -You should then start seeing data on `localhost:7000/catalog/entities`. - -The catalog currently runs in-memory only, so feel free to try it out, but it will -need to be re-populated on next startup. +To get started quickly, this template already includes some statically configured example locations +in `app-config.yaml` under `catalog.locations`. You can remove and replace these locations as you +like, and also override them for local development in `app-config.local.yaml`. ## Authentication -We chose [Passport](http://www.passportjs.org/) as authentication platform due to its comprehensive set of supported authentication [strategies](http://www.passportjs.org/packages/). +We chose [Passport](http://www.passportjs.org/) as authentication platform due +to its comprehensive set of supported authentication +[strategies](http://www.passportjs.org/packages/). -Read more about the [auth-backend](https://github.com/spotify/backstage/blob/master/plugins/auth-backend/README.md) and [how to add a new provider](https://github.com/spotify/backstage/blob/master/docs/auth/add-auth-provider.md) +Read more about the +[auth-backend](https://github.com/spotify/backstage/blob/master/plugins/auth-backend/README.md) +and +[how to add a new provider](https://github.com/spotify/backstage/blob/master/docs/auth/add-auth-provider.md) ## Documentation diff --git a/plugins/catalog-backend/README.md b/plugins/catalog-backend/README.md index 7c52dfad72..1b4a653f4a 100644 --- a/plugins/catalog-backend/README.md +++ b/plugins/catalog-backend/README.md @@ -21,12 +21,9 @@ To evaluate the catalog and have a greater amount of functionality available, in # in one terminal window, run this from from the very root of the Backstage project cd packages/backend yarn start - -# open another terminal window, and run the following from the very root of the Backstage project -yarn lerna run mock-data ``` -This will launch the full example backend and populate its catalog with some mock entities. +This will launch the full example backend, populated some example entities. ## Links diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index c1b20ed7bb..d1711cf3d5 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -17,9 +17,7 @@ "test": "backstage-cli test", "prepack": "backstage-cli prepack", "postpack": "backstage-cli postpack", - "clean": "backstage-cli clean", - "mock-data": "./scripts/mock-data.sh", - "mock-data:local": "./scripts/mock-data-local.sh" + "clean": "backstage-cli clean" }, "dependencies": { "@backstage/backend-common": "^0.1.1-alpha.21", diff --git a/plugins/catalog-backend/scripts/mock-data-local.sh b/plugins/catalog-backend/scripts/mock-data-local.sh deleted file mode 100755 index 3bea819319..0000000000 --- a/plugins/catalog-backend/scripts/mock-data-local.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -for FILE in \ - ../../packages/catalog-model/examples/*.yaml \ -; do \ - curl \ - --location \ - --request POST 'localhost:7000/catalog/locations' \ - --header 'Content-Type: application/json' \ - --data-raw "{\"type\": \"file\", \"target\": \"../catalog-model/${FILE}\"}" - echo -done diff --git a/plugins/catalog-backend/scripts/mock-data.sh b/plugins/catalog-backend/scripts/mock-data.sh deleted file mode 100755 index 92ec647281..0000000000 --- a/plugins/catalog-backend/scripts/mock-data.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -for URL in \ - 'artist-lookup-component.yaml' \ - 'playback-order-component.yaml' \ - 'podcast-api-component.yaml' \ - 'queue-proxy-component.yaml' \ - 'searcher-component.yaml' \ - 'playback-lib-component.yaml' \ - 'www-artist-component.yaml' \ - 'shuffle-api-component.yaml' \ - 'petstore-api.yaml' \ - 'streetlights-api.yaml' \ -; do \ - curl \ - --location \ - --request POST 'localhost:7000/catalog/locations' \ - --header 'Content-Type: application/json' \ - --data-raw "{\"type\": \"github\", \"target\": \"https://github.com/spotify/backstage/blob/master/packages/catalog-model/examples/${URL}\"}" - echo -done diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index dca8b6adee..e1b52795d3 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -23,10 +23,7 @@ "dependencies": { "@backstage/catalog-model": "^0.1.1-alpha.21", "@backstage/core": "^0.1.1-alpha.21", - "@backstage/plugin-github-actions": "^0.1.1-alpha.21", - "@backstage/plugin-jenkins": "^0.1.1-alpha.21", "@backstage/plugin-scaffolder": "^0.1.1-alpha.21", - "@backstage/plugin-sentry": "^0.1.1-alpha.21", "@backstage/plugin-techdocs": "^0.1.1-alpha.21", "@backstage/theme": "^0.1.1-alpha.21", "@material-ui/core": "^4.11.0", diff --git a/plugins/catalog/src/components/EntityPageCi/EntityPageCi.tsx b/plugins/catalog/src/components/EntityPageCi/EntityPageCi.tsx deleted file mode 100644 index 0974e6bb83..0000000000 --- a/plugins/catalog/src/components/EntityPageCi/EntityPageCi.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -// TODO(shmidt-i): move to the app -import { Entity } from '@backstage/catalog-model'; -import { Content } from '@backstage/core'; -import { - LatestWorkflowsForBranchCard, - GITHUB_ACTIONS_ANNOTATION, -} from '@backstage/plugin-github-actions'; -import { Grid } from '@material-ui/core'; -import React, { FC } from 'react'; - -export const EntityPageCi: FC<{ entity: Entity }> = ({ entity }) => { - return ( - - - {entity.metadata?.annotations?.[GITHUB_ACTIONS_ANNOTATION] && ( - - - - )} - - - ); -}; diff --git a/plugins/catalog/src/components/EntityPageOverview/EntityPageOverview.tsx b/plugins/catalog/src/components/EntityPageOverview/EntityPageOverview.tsx deleted file mode 100644 index c43e83edaa..0000000000 --- a/plugins/catalog/src/components/EntityPageOverview/EntityPageOverview.tsx +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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. - */ - -// TODO(shmidt-i): move to the app -import { Entity } from '@backstage/catalog-model'; -import { Content } from '@backstage/core'; -import { - LatestWorkflowRunCard, - GITHUB_ACTIONS_ANNOTATION, -} from '@backstage/plugin-github-actions'; -import { - JenkinsBuildsWidget, - JenkinsLastBuildWidget, -} from '@backstage/plugin-jenkins'; -import { Grid } from '@material-ui/core'; -import React, { FC } from 'react'; -import { AboutCard } from '../AboutCard'; - -export const EntityPageOverview: FC<{ entity: Entity }> = ({ entity }) => { - return ( - - - - - - {entity.metadata?.annotations?.[ - 'backstage.io/jenkins-github-folder' - ] && ( - - - - )} - {entity.metadata?.annotations?.[ - 'backstage.io/jenkins-github-folder' - ] && ( - - - - )} - {entity.metadata?.annotations?.[GITHUB_ACTIONS_ANNOTATION] && ( - - - - )} - - - ); -}; diff --git a/plugins/circleci/src/components/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx b/plugins/circleci/src/components/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx index 2a059f7e02..65e4537ad7 100644 --- a/plugins/circleci/src/components/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx +++ b/plugins/circleci/src/components/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx @@ -30,7 +30,7 @@ import React, { FC, Suspense, useEffect, useState } from 'react'; const LazyLog = React.lazy(() => import('react-lazylog/build/LazyLog')); moment.relativeTimeThreshold('ss', 0); const useStyles = makeStyles({ - expansionPanelDetails: { + accordionDetails: { padding: 0, }, button: { @@ -80,7 +80,7 @@ export const ActionOutput: FC<{ {name} ({timeElapsed}) - + {messages.length === 0 ? ( 'Nothing here...' ) : ( diff --git a/plugins/github-actions/scripts/sample.yaml b/plugins/github-actions/examples/sample.yaml similarity index 100% rename from plugins/github-actions/scripts/sample.yaml rename to plugins/github-actions/examples/sample.yaml diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index e55a195f6e..49862dea80 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -18,8 +18,7 @@ "diff": "backstage-cli plugin:diff", "prepack": "backstage-cli prepack", "postpack": "backstage-cli postpack", - "clean": "backstage-cli clean", - "mock-data": "./scripts/mock-data.sh" + "clean": "backstage-cli clean" }, "dependencies": { "@backstage/catalog-model": "^0.1.1-alpha.21", @@ -35,6 +34,7 @@ "moment": "^2.27.0", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-lazylog": "^4.5.3", "react-router": "6.0.0-beta.0", "react-router-dom": "6.0.0-beta.0", "react-use": "^15.3.3" diff --git a/plugins/github-actions/scripts/mock-data.sh b/plugins/github-actions/scripts/mock-data.sh deleted file mode 100755 index 2653a415dd..0000000000 --- a/plugins/github-actions/scripts/mock-data.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - - curl \ - --location \ - --request POST 'localhost:7000/catalog/locations' \ - --header 'Content-Type: application/json' \ - --data-raw "{\"type\": \"file\", \"target\": \"$(pwd)/scripts/sample.yaml\"}" - echo diff --git a/plugins/github-actions/src/api/GithubActionsApi.ts b/plugins/github-actions/src/api/GithubActionsApi.ts index 9a95f21860..bf79e74351 100644 --- a/plugins/github-actions/src/api/GithubActionsApi.ts +++ b/plugins/github-actions/src/api/GithubActionsApi.ts @@ -19,6 +19,7 @@ import { ActionsListWorkflowRunsForRepoResponseData, ActionsGetWorkflowResponseData, ActionsGetWorkflowRunResponseData, + EndpointInterface, } from '@octokit/types'; export const githubActionsApiRef = createApiRef({ @@ -75,4 +76,15 @@ export type GithubActionsApi = { repo: string; runId: number; }) => Promise; + downloadJobLogsForWorkflowRun: ({ + token, + owner, + repo, + runId, + }: { + token: string; + owner: string; + repo: string; + runId: number; + }) => Promise; }; diff --git a/plugins/github-actions/src/api/GithubActionsClient.ts b/plugins/github-actions/src/api/GithubActionsClient.ts index 72f65075e6..94fb774537 100644 --- a/plugins/github-actions/src/api/GithubActionsClient.ts +++ b/plugins/github-actions/src/api/GithubActionsClient.ts @@ -20,6 +20,7 @@ import { ActionsListWorkflowRunsForRepoResponseData, ActionsGetWorkflowResponseData, ActionsGetWorkflowRunResponseData, + EndpointInterface, } from '@octokit/types'; export class GithubActionsClient implements GithubActionsApi { @@ -102,4 +103,24 @@ export class GithubActionsClient implements GithubActionsApi { }); return run.data; } + async downloadJobLogsForWorkflowRun({ + token, + owner, + repo, + runId, + }: { + token: string; + owner: string; + repo: string; + runId: number; + }): Promise { + const workflow = await new Octokit({ + auth: token, + }).actions.downloadJobLogsForWorkflowRun({ + owner, + repo, + job_id: runId, + }); + return workflow.data; + } } diff --git a/plugins/github-actions/src/api/types.ts b/plugins/github-actions/src/api/types.ts index cd74a20cda..ccc9198e58 100644 --- a/plugins/github-actions/src/api/types.ts +++ b/plugins/github-actions/src/api/types.ts @@ -29,6 +29,7 @@ export type Job = { conclusion: string; started_at: string; completed_at: string; + id: string; name: string; steps: Step[]; }; diff --git a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index a8ceb717da..fd2cc69376 100644 --- a/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/github-actions/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import { Entity } from '@backstage/catalog-model'; import { Link } from '@backstage/core'; import { @@ -45,6 +44,7 @@ import { useProjectName } from '../useProjectName'; import { WorkflowRunStatus } from '../WorkflowRunStatus'; import { useWorkflowRunJobs } from './useWorkflowRunJobs'; import { useWorkflowRunsDetails } from './useWorkflowRunsDetails'; +import { WorkflowRunLogs } from '../WorkflowRunLogs'; const useStyles = makeStyles(theme => ({ root: { @@ -57,7 +57,7 @@ const useStyles = makeStyles(theme => ({ table: { padding: theme.spacing(1), }, - expansionPanelDetails: { + accordionDetails: { padding: 0, }, button: { @@ -71,7 +71,7 @@ const useStyles = makeStyles(theme => ({ }, })); -const JobsList = ({ jobs }: { jobs?: Jobs }) => { +const JobsList = ({ jobs, entity }: { jobs?: Jobs; entity: Entity }) => { const classes = useStyles(); return ( @@ -83,6 +83,7 @@ const JobsList = ({ jobs }: { jobs?: Jobs }) => { className={ job.status !== 'success' ? classes.failed : classes.success } + entity={entity} /> ))} @@ -111,7 +112,15 @@ const StepView = ({ step }: { step: Step }) => { ); }; -const JobListItem = ({ job, className }: { job: Job; className: string }) => { +const JobListItem = ({ + job, + className, + entity, +}: { + job: Job; + className: string; + entity: Entity; +}) => { const classes = useStyles(); return ( @@ -127,7 +136,7 @@ const JobListItem = ({ job, className }: { job: Job; className: string }) => { {job.name} ({getElapsedTime(job.started_at, job.completed_at)}) - + {job.steps.map((step: Step) => ( @@ -136,6 +145,11 @@ const JobListItem = ({ job, className }: { job: Job; className: string }) => {
+ {job.status === 'queued' || job.status === 'in_progress' ? ( + + ) : ( + + )}
); }; @@ -218,7 +232,7 @@ export const WorkflowRunDetails = ({ entity }: { entity: Entity }) => { {jobs.loading ? ( ) : ( - + )} diff --git a/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx b/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx new file mode 100644 index 0000000000..390f35d516 --- /dev/null +++ b/plugins/github-actions/src/components/WorkflowRunLogs/WorkflowRunLogs.tsx @@ -0,0 +1,169 @@ +/* + * 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 { + Accordion, + AccordionSummary, + CircularProgress, + Fade, + LinearProgress, + makeStyles, + Modal, + Theme, + Tooltip, + Typography, + Zoom, +} from '@material-ui/core'; + +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 useStyles = makeStyles(() => ({ + button: { + order: -1, + marginRight: 0, + marginLeft: '-20px', + }, + modal: { + display: 'flex', + alignItems: 'center', + width: '85%', + height: '85%', + justifyContent: 'center', + margin: 'auto', + }, + normalLog: { + height: '75vh', + width: '100%', + }, + modalLog: { + height: '100%', + width: '100%', + }, +})); + +const DisplayLog = ({ + jobLogs, + className, +}: { + jobLogs: any; + className: string; +}) => { + return ( + }> +
+ { + if ( + line.toLocaleLowerCase().includes('error') || + line.toLocaleLowerCase().includes('failed') || + line.toLocaleLowerCase().includes('failure') + ) { + return ( + + ); + } + return line; + }} + /> +
+
+ ); +}; + +/** + * A component for Run Logs visualization. + */ +export const WorkflowRunLogs = ({ + entity, + runId, + inProgress, +}: { + entity: Entity; + runId: string; + inProgress: boolean; +}) => { + const classes = useStyles(); + const projectName = useProjectName(entity); + + const [owner, repo] = projectName.value ? projectName.value.split('/') : []; + const jobLogs = useDownloadWorkflowRunLogs(repo, owner, runId); + const [open, setOpen] = React.useState(false); + + const handleOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + return ( + + } + aria-controls={`panel-${name}-content`} + id={`panel-${name}-header`} + IconButtonProps={{ + className: classes.button, + }} + > + + {jobLogs.loading ? : 'Job Log'} + + + { + event.stopPropagation(); + handleOpen(); + }} + style={{ marginLeft: 'auto' }} + /> + + event.stopPropagation()} + open={open} + onClose={handleClose} + > + + + + + + {jobLogs.value && ( + + )} + + ); +}; diff --git a/plugins/github-actions/src/components/WorkflowRunLogs/index.ts b/plugins/github-actions/src/components/WorkflowRunLogs/index.ts new file mode 100644 index 0000000000..0fcffd4dec --- /dev/null +++ b/plugins/github-actions/src/components/WorkflowRunLogs/index.ts @@ -0,0 +1,16 @@ +/* + * 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. + */ +export { WorkflowRunLogs } from './WorkflowRunLogs'; diff --git a/plugins/github-actions/src/components/WorkflowRunLogs/useDownloadWorkflowRunLogs.ts b/plugins/github-actions/src/components/WorkflowRunLogs/useDownloadWorkflowRunLogs.ts new file mode 100644 index 0000000000..734f617b1f --- /dev/null +++ b/plugins/github-actions/src/components/WorkflowRunLogs/useDownloadWorkflowRunLogs.ts @@ -0,0 +1,40 @@ +/* + * 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 { useApi, githubAuthApiRef } from '@backstage/core'; +import { useAsync } from 'react-use'; +import { githubActionsApiRef } from '../../api'; + +export const useDownloadWorkflowRunLogs = ( + repo: string, + owner: string, + id: string, +) => { + const api = useApi(githubActionsApiRef); + const auth = useApi(githubAuthApiRef); + const details = useAsync(async () => { + const token = await auth.getAccessToken(['repo']); + return repo && owner + ? api.downloadJobLogsForWorkflowRun({ + token, + owner, + repo, + runId: parseInt(id, 10), + }) + : Promise.reject('No repo/owner provided'); + }, [repo, owner, id]); + return details; +}; diff --git a/plugins/graphql/package.json b/plugins/graphql/package.json index 1612398ea9..706592c430 100644 --- a/plugins/graphql/package.json +++ b/plugins/graphql/package.json @@ -16,8 +16,7 @@ "test": "backstage-cli test", "prepack": "backstage-cli prepack", "postpack": "backstage-cli postpack", - "clean": "backstage-cli clean", - "mock-data": "./scripts/mock-data.sh" + "clean": "backstage-cli clean" }, "dependencies": { "@backstage/backend-common": "^0.1.1-alpha.21", diff --git a/plugins/graphql/scripts/mock-data.sh b/plugins/graphql/scripts/mock-data.sh deleted file mode 100755 index ff30921715..0000000000 --- a/plugins/graphql/scripts/mock-data.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -echo "use this script to load your service with some mock data if needed!" diff --git a/plugins/jenkins/src/pages/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx b/plugins/jenkins/src/pages/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx index a9b73f6f0b..0dcaeb8948 100644 --- a/plugins/jenkins/src/pages/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx +++ b/plugins/jenkins/src/pages/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx @@ -25,7 +25,7 @@ import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import React, { FC, useEffect } from 'react'; const useStyles = makeStyles({ - expansionPanelDetails: { + accordionDetails: { padding: 0, }, button: { @@ -57,7 +57,7 @@ export const ActionOutput: FC<{ > {name} - + Nothing here... diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index 9c9d609c04..38a47bc0fc 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -4,7 +4,7 @@ "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", - "private": true, + "private": false, "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 2fe27f4eb7..2283dd5d05 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -17,8 +17,7 @@ "test": "backstage-cli test", "prepack": "backstage-cli prepack", "postpack": "backstage-cli postpack", - "clean": "backstage-cli clean", - "mock-data": "./scripts/mock-data.sh" + "clean": "backstage-cli clean" }, "dependencies": { "@backstage/backend-common": "^0.1.1-alpha.21", diff --git a/plugins/scaffolder-backend/sample-templates/all-templates.yaml b/plugins/scaffolder-backend/sample-templates/all-templates.yaml new file mode 100644 index 0000000000..1eb619a072 --- /dev/null +++ b/plugins/scaffolder-backend/sample-templates/all-templates.yaml @@ -0,0 +1,13 @@ +apiVersion: backstage.io/v1alpha1 +kind: Location +metadata: + name: example-templates + description: A collection of all Backstage example templates +spec: + type: github + targets: + - https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml + - https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/springboot-grpc-template/template.yaml + - https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml + - https://github.com/spotify/cookiecutter-golang/blob/master/template.yaml + - https://github.com/spotify/backstage/blob/master/plugins/scaffolder-backend/sample-templates/docs-template/template.yaml diff --git a/plugins/scaffolder-backend/scripts/mock-data.sh b/plugins/scaffolder-backend/scripts/mock-data.sh deleted file mode 100755 index 9a9b0b186b..0000000000 --- a/plugins/scaffolder-backend/scripts/mock-data.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -for URL in \ - 'react-ssr-template' \ - 'springboot-grpc-template' \ - 'create-react-app' \ - 'docs-template' \ -; do \ - curl \ - --location \ - --request POST 'localhost:7000/catalog/locations' \ - --header 'Content-Type: application/json' \ - --data-raw "{\"type\": \"file\", \"target\": \"$(pwd)/sample-templates/${URL}/template.yaml\"}" - echo -done - -curl \ - --location \ - --request POST 'localhost:7000/catalog/locations' \ - --header 'Content-Type: application/json' \ - --data-raw "{\"type\": \"github\", \"target\": \"https://github.com/spotify/cookiecutter-golang/blob/master/template.yaml\"}" -echo diff --git a/plugins/scaffolder/src/components/JobStage/JobStage.tsx b/plugins/scaffolder/src/components/JobStage/JobStage.tsx index c7de6dff61..0baba0c9b9 100644 --- a/plugins/scaffolder/src/components/JobStage/JobStage.tsx +++ b/plugins/scaffolder/src/components/JobStage/JobStage.tsx @@ -35,7 +35,7 @@ const LazyLog = React.lazy(() => import('react-lazylog/build/LazyLog')); moment.relativeTimeThreshold('ss', 0); const useStyles = makeStyles(theme => ({ - expansionPanelDetails: { + accordionDetails: { padding: 0, }, button: { @@ -45,7 +45,7 @@ const useStyles = makeStyles(theme => ({ cardContent: { backgroundColor: theme.palette.background.default, }, - expansionPanel: { + accordion: { position: 'relative', '&:after': { pointerEvents: 'none', @@ -103,7 +103,7 @@ export const JobStage = ({ endedAt, startedAt, name, log, status }: Props) => { ] ?? classes.neutral, )} @@ -123,7 +123,7 @@ export const JobStage = ({ endedAt, startedAt, name, log, status }: Props) => { {startedAt && !endedAt && } - + {log.length === 0 ? ( No logs available for this step ) : ( diff --git a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx index d98b1a11e9..470fef1148 100644 --- a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx @@ -23,8 +23,8 @@ const useStyles = makeStyles(theme => ({ header: { color: theme.palette.common.white, padding: theme.spacing(2, 2, 6), - backgroundImage: (props: { gradientStart: string; gradientStop: string }) => - `linear-gradient(-137deg, ${props.gradientStart} 0%, ${props.gradientStop} 100%)`, + backgroundImage: (props: { backgroundImage: string }) => + props.backgroundImage, }, content: { padding: theme.spacing(2), @@ -56,8 +56,7 @@ export const TemplateCard = ({ name, }: TemplateCardProps) => { const theme = pageTheme[type] ?? pageTheme.other; - const [gradientStart, gradientStop] = theme.colors; - const classes = useStyles({ gradientStart, gradientStop }); + const classes = useStyles({ backgroundImage: theme.backgroundImage }); const href = generatePath(templateRoute.path, { templateName: name }); return ( diff --git a/plugins/techdocs-backend/README.md b/plugins/techdocs-backend/README.md index 6a54971788..2185c3b3e4 100644 --- a/plugins/techdocs-backend/README.md +++ b/plugins/techdocs-backend/README.md @@ -14,9 +14,6 @@ To evaluate TechDocs and have a greater amount of functionality available, inste # in one terminal window, run this from from the very root of the Backstage project cd packages/backend yarn start - -# open another terminal window, and run the following from the very root of the Backstage project -yarn lerna run mock-data ``` ## What techdocs-backend does diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index edafe31657..47b2ebc8aa 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -17,8 +17,7 @@ "test": "backstage-cli test", "prepack": "backstage-cli prepack", "postpack": "backstage-cli postpack", - "clean": "backstage-cli clean", - "mock-data": "./scripts/mock-data.sh" + "clean": "backstage-cli clean" }, "dependencies": { "@backstage/backend-common": "^0.1.1-alpha.21", diff --git a/plugins/techdocs-backend/scripts/mock-data.sh b/plugins/techdocs-backend/scripts/mock-data.sh deleted file mode 100755 index 0630490694..0000000000 --- a/plugins/techdocs-backend/scripts/mock-data.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -for URL in \ - 'documented-component/documented-component.yaml' \ -; do \ - curl \ - --location \ - --request POST 'localhost:7000/catalog/locations' \ - --header 'Content-Type: application/json' \ - --data-raw "{\"type\": \"file\", \"target\": \"$(pwd)/examples/${URL}\"}" - echo -done diff --git a/plugins/techdocs-backend/src/helpers.ts b/plugins/techdocs-backend/src/helpers.ts index 25d7f593c2..14f4d490ba 100644 --- a/plugins/techdocs-backend/src/helpers.ts +++ b/plugins/techdocs-backend/src/helpers.ts @@ -24,6 +24,7 @@ import defaultBranch from 'default-branch'; import { Entity } from '@backstage/catalog-model'; import { InputError } from '@backstage/backend-common'; import { RemoteProtocol } from './techdocs/stages/prepare/types'; +import { Logger } from 'winston'; export type ParsedLocationAnnotation = { type: RemoteProtocol; @@ -110,6 +111,7 @@ export const getGitHubRepositoryTempFolder = async ( export const checkoutGithubRepository = async ( repoUrl: string, + logger: Logger, ): Promise => { const parsedGitLocation = parseGitUrl(repoUrl); const repositoryTmpPath = await getGitHubRepositoryTempFolder(repoUrl); @@ -119,14 +121,23 @@ export const checkoutGithubRepository = async ( const token = process.env.GITHUB_PRIVATE_TOKEN || ''; if (fs.existsSync(repositoryTmpPath)) { - const repository = await Repository.open(repositoryTmpPath); - const currentBranchName = (await repository.getCurrentBranch()).shorthand(); - await repository.fetch('origin'); - await repository.mergeBranches( - currentBranchName, - `origin/${currentBranchName}`, - ); - return repositoryTmpPath; + try { + const repository = await Repository.open(repositoryTmpPath); + const currentBranchName = ( + await repository.getCurrentBranch() + ).shorthand(); + await repository.fetch('origin'); + await repository.mergeBranches( + currentBranchName, + `origin/${currentBranchName}`, + ); + return repositoryTmpPath; + } catch (e) { + logger.info( + `Found error "${e.message}" in cached repository "${repoUrl}" when getting latest changes. Removing cached repository.`, + ); + fs.removeSync(repositoryTmpPath); + } } if (user && token) { @@ -143,8 +154,12 @@ export const checkoutGithubRepository = async ( export const getLastCommitTimestamp = async ( repositoryUrl: string, + logger: Logger, ): Promise => { - const repositoryLocation = await checkoutGithubRepository(repositoryUrl); + const repositoryLocation = await checkoutGithubRepository( + repositoryUrl, + logger, + ); const repository = await Repository.open(repositoryLocation); const commit = await repository.getReferenceCommit('HEAD'); diff --git a/plugins/techdocs-backend/src/service/helpers.ts b/plugins/techdocs-backend/src/service/helpers.ts index 0fc4f41b3d..60c76e6384 100644 --- a/plugins/techdocs-backend/src/service/helpers.ts +++ b/plugins/techdocs-backend/src/service/helpers.ts @@ -110,7 +110,7 @@ export class DocsBuilder { // Should probably be broken out and handled per type later. Doing this for now since we only support github age checks if (type === 'github') { - const lastCommit = await getLastCommitTimestamp(target); + const lastCommit = await getLastCommitTimestamp(target, this.logger); const storageTimeStamp = buildMetadataStorage.getTimestamp(); // Check if documentation source is newer than what we have diff --git a/plugins/techdocs-backend/src/techdocs/stages/prepare/dir.ts b/plugins/techdocs-backend/src/techdocs/stages/prepare/dir.ts index a9eda943c6..5fd4abb4bd 100644 --- a/plugins/techdocs-backend/src/techdocs/stages/prepare/dir.ts +++ b/plugins/techdocs-backend/src/techdocs/stages/prepare/dir.ts @@ -43,7 +43,10 @@ export class DirectoryPreparer implements PreparerBase { switch (type) { case 'github': { const parsedGitLocation = parseGitUrl(target); - const repoLocation = await checkoutGithubRepository(target); + const repoLocation = await checkoutGithubRepository( + target, + this.logger, + ); return path.dirname( path.join(repoLocation, parsedGitLocation.filepath), diff --git a/plugins/techdocs-backend/src/techdocs/stages/prepare/github.ts b/plugins/techdocs-backend/src/techdocs/stages/prepare/github.ts index 7b9fc7fbe2..03b0adcb88 100644 --- a/plugins/techdocs-backend/src/techdocs/stages/prepare/github.ts +++ b/plugins/techdocs-backend/src/techdocs/stages/prepare/github.ts @@ -43,7 +43,7 @@ export class GithubPreparer implements PreparerBase { } try { - const repoPath = await checkoutGithubRepository(target); + const repoPath = await checkoutGithubRepository(target, this.logger); const parsedGitLocation = parseGitUrl(target); return path.join(repoPath, parsedGitLocation.filepath); diff --git a/yarn.lock b/yarn.lock index 11bb8a3fd8..38f5d6c799 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17550,7 +17550,7 @@ react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-i resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-lazylog@^4.5.2: +react-lazylog@^4.5.2, react-lazylog@^4.5.3: version "4.5.3" resolved "https://registry.npmjs.org/react-lazylog/-/react-lazylog-4.5.3.tgz#289e24995b5599e75943556ac63f5e2c04d0001e" integrity sha512-lyov32A/4BqihgXgtNXTHCajXSXkYHPlIEmV8RbYjHIMxCFSnmtdg4kDCI3vATz7dURtiFTvrw5yonHnrS+NNg==