This commit is contained in:
Tim Hansen
2020-09-14 14:09:57 -06:00
60 changed files with 647 additions and 395 deletions
+8
View File
@@ -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
-13
View File
@@ -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
@@ -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'
+45 -1
View File
@@ -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
+21 -17
View File
@@ -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:
@@ -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.
+8 -4
View File
@@ -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.
+12 -11
View File
@@ -8,16 +8,21 @@ sidebar_label: Overview
<!-- Intro, backstory, etc.: -->
Wait, what is TechDocs? TechDocs is Spotifys homegrown docs-like-code solution
built directly into Backstage. Today, it is now one of the core products in
Spotifys developer experience offering with 2,400+ documentation sites and
1,000+ engineers using it daily.
TechDocs is Spotifys 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 Spotifys 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 @@ Spotifys 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)
+6
View File
@@ -0,0 +1,6 @@
---
id: architecture
title: Architecture
---
![TechDocs Big Picture](../../assets/techdocs/techdocs_big_picture.png)
+3 -3
View File
@@ -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)
@@ -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 ~/<repository-path>/
cd /path/to/docs-repository/
npx @techdocs/cli serve
```
+5 -32
View File
@@ -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. Its based on the
developer portal weve 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.
@@ -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)
@@ -39,7 +39,7 @@ You can customize Backstage Software Templates to fit your organizations 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 youve 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)
+1 -1
View File
@@ -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"
}
}
+3 -1
View File
@@ -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"
]
+3 -2
View File
@@ -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 */
+55 -3
View File
@@ -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%,
+4 -4
View File
@@ -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"
+3 -1
View File
@@ -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:
+6 -14
View File
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+1 -4
View File
@@ -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
+1 -3
View File
@@ -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",
@@ -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
@@ -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
-3
View File
@@ -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",
@@ -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 (
<Content>
<Grid container spacing={3}>
{entity.metadata?.annotations?.[GITHUB_ACTIONS_ANNOTATION] && (
<Grid item sm={12}>
<LatestWorkflowsForBranchCard entity={entity} branch="master" />
</Grid>
)}
</Grid>
</Content>
);
};
@@ -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 (
<Content>
<Grid container spacing={3}>
<Grid item sm={4}>
<AboutCard entity={entity} />
</Grid>
{entity.metadata?.annotations?.[
'backstage.io/jenkins-github-folder'
] && (
<Grid item sm={4}>
<JenkinsLastBuildWidget entity={entity} branch="master" />
</Grid>
)}
{entity.metadata?.annotations?.[
'backstage.io/jenkins-github-folder'
] && (
<Grid item sm={8}>
<JenkinsBuildsWidget entity={entity} />
</Grid>
)}
{entity.metadata?.annotations?.[GITHUB_ACTIONS_ANNOTATION] && (
<Grid item sm={3}>
<LatestWorkflowRunCard entity={entity} branch="master" />
</Grid>
)}
</Grid>
</Content>
);
};
@@ -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})
</Typography>
</AccordionSummary>
<AccordionDetails className={classes.expansionPanelDetails}>
<AccordionDetails className={classes.accordionDetails}>
{messages.length === 0 ? (
'Nothing here...'
) : (
+2 -2
View File
@@ -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"
@@ -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
@@ -19,6 +19,7 @@ import {
ActionsListWorkflowRunsForRepoResponseData,
ActionsGetWorkflowResponseData,
ActionsGetWorkflowRunResponseData,
EndpointInterface,
} from '@octokit/types';
export const githubActionsApiRef = createApiRef<GithubActionsApi>({
@@ -75,4 +76,15 @@ export type GithubActionsApi = {
repo: string;
runId: number;
}) => Promise<any>;
downloadJobLogsForWorkflowRun: ({
token,
owner,
repo,
runId,
}: {
token: string;
owner: string;
repo: string;
runId: number;
}) => Promise<EndpointInterface>;
};
@@ -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<EndpointInterface> {
const workflow = await new Octokit({
auth: token,
}).actions.downloadJobLogsForWorkflowRun({
owner,
repo,
job_id: runId,
});
return workflow.data;
}
}
+1
View File
@@ -29,6 +29,7 @@ export type Job = {
conclusion: string;
started_at: string;
completed_at: string;
id: string;
name: string;
steps: Step[];
};
@@ -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>(theme => ({
root: {
@@ -57,7 +57,7 @@ const useStyles = makeStyles<Theme>(theme => ({
table: {
padding: theme.spacing(1),
},
expansionPanelDetails: {
accordionDetails: {
padding: 0,
},
button: {
@@ -71,7 +71,7 @@ const useStyles = makeStyles<Theme>(theme => ({
},
}));
const JobsList = ({ jobs }: { jobs?: Jobs }) => {
const JobsList = ({ jobs, entity }: { jobs?: Jobs; entity: Entity }) => {
const classes = useStyles();
return (
<Box>
@@ -83,6 +83,7 @@ const JobsList = ({ jobs }: { jobs?: Jobs }) => {
className={
job.status !== 'success' ? classes.failed : classes.success
}
entity={entity}
/>
))}
</Box>
@@ -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 (
<Accordion TransitionProps={{ unmountOnExit: true }} className={className}>
@@ -127,7 +136,7 @@ const JobListItem = ({ job, className }: { job: Job; className: string }) => {
{job.name} ({getElapsedTime(job.started_at, job.completed_at)})
</Typography>
</AccordionSummary>
<AccordionDetails className={classes.expansionPanelDetails}>
<AccordionDetails className={classes.accordionDetails}>
<TableContainer>
<Table>
{job.steps.map((step: Step) => (
@@ -136,6 +145,11 @@ const JobListItem = ({ job, className }: { job: Job; className: string }) => {
</Table>
</TableContainer>
</AccordionDetails>
{job.status === 'queued' || job.status === 'in_progress' ? (
<WorkflowRunLogs runId={job.id} inProgress entity={entity} />
) : (
<WorkflowRunLogs runId={job.id} inProgress={false} entity={entity} />
)}
</Accordion>
);
};
@@ -218,7 +232,7 @@ export const WorkflowRunDetails = ({ entity }: { entity: Entity }) => {
{jobs.loading ? (
<CircularProgress />
) : (
<JobsList jobs={jobs.value} />
<JobsList jobs={jobs.value} entity={entity} />
)}
</TableCell>
</TableRow>
@@ -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<Theme>(() => ({
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 (
<Suspense fallback={<LinearProgress />}>
<div className={className}>
<LazyLog
text={jobLogs ?? 'No Values Found'}
extraLines={1}
caseInsensitive
enableSearch
formatPart={line => {
if (
line.toLocaleLowerCase().includes('error') ||
line.toLocaleLowerCase().includes('failed') ||
line.toLocaleLowerCase().includes('failure')
) {
return (
<LinePart style={{ color: 'red' }} part={{ text: line }} />
);
}
return line;
}}
/>
</div>
</Suspense>
);
};
/**
* 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 (
<Accordion TransitionProps={{ unmountOnExit: true }} disabled={inProgress}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls={`panel-${name}-content`}
id={`panel-${name}-header`}
IconButtonProps={{
className: classes.button,
}}
>
<Typography variant="button">
{jobLogs.loading ? <CircularProgress /> : 'Job Log'}
</Typography>
<Tooltip title="Open Log" TransitionComponent={Zoom} arrow>
<DescriptionIcon
onClick={event => {
event.stopPropagation();
handleOpen();
}}
style={{ marginLeft: 'auto' }}
/>
</Tooltip>
<Modal
className={classes.modal}
onClick={event => event.stopPropagation()}
open={open}
onClose={handleClose}
>
<Fade in={open}>
<DisplayLog
jobLogs={jobLogs.value || undefined}
className={classes.modalLog}
/>
</Fade>
</Modal>
</AccordionSummary>
{jobLogs.value && (
<DisplayLog
jobLogs={jobLogs.value || undefined}
className={classes.normalLog}
/>
)}
</Accordion>
);
};
@@ -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';
@@ -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;
};
+1 -2
View File
@@ -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",
-2
View File
@@ -1,2 +0,0 @@
#!/usr/bin/env bash
echo "use this script to load your service with some mock data if needed!"
@@ -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<{
>
<Typography variant="button">{name}</Typography>
</AccordionSummary>
<AccordionDetails className={classes.expansionPanelDetails}>
<AccordionDetails className={classes.accordionDetails}>
Nothing here...
</AccordionDetails>
</Accordion>
+1 -1
View File
@@ -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",
+1 -2
View File
@@ -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",
@@ -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
@@ -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
@@ -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) => {
<Accordion
TransitionProps={{ unmountOnExit: true }}
className={cn(
classes.expansionPanel,
classes.accordion,
classes[status.toLowerCase() as keyof ReturnType<typeof useStyles>] ??
classes.neutral,
)}
@@ -123,7 +123,7 @@ export const JobStage = ({ endedAt, startedAt, name, log, status }: Props) => {
{startedAt && !endedAt && <CircularProgress size="1em" />}
</Typography>
</AccordionSummary>
<AccordionDetails className={classes.expansionPanelDetails}>
<AccordionDetails className={classes.accordionDetails}>
{log.length === 0 ? (
<Box px={4}>No logs available for this step</Box>
) : (
@@ -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 (
-3
View File
@@ -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
+1 -2
View File
@@ -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",
@@ -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
+24 -9
View File
@@ -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<string> => {
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<number> => {
const repositoryLocation = await checkoutGithubRepository(repositoryUrl);
const repositoryLocation = await checkoutGithubRepository(
repositoryUrl,
logger,
);
const repository = await Repository.open(repositoryLocation);
const commit = await repository.getReferenceCommit('HEAD');
@@ -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
@@ -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),
@@ -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);
+1 -1
View File
@@ -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==