Merge branch 'master' of github.com:backstage/backstage into update-docs

This commit is contained in:
Adam Harvey
2020-12-29 11:48:31 -05:00
99 changed files with 1387 additions and 875 deletions
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/core-api': patch
'@backstage/core': patch
---
Add `FlatRoutes` component to replace the top-level `Routes` component from `react-router` within apps, removing the need for manually appending `/*` to paths or sorting routes.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-register-component': patch
---
Register component plugin is deprecated in favor of @backstage/plugin-catalog-import
-9
View File
@@ -1,9 +0,0 @@
---
'@backstage/plugin-catalog': patch
---
Add `CatalogIndexPage` and `CatalogEntityPage`, two new extensions that replace the existing `Router` component.
Add `EntityLayout` to replace `EntityPageLayout`, using children instead of an element property, and allowing for collection of all `RouteRef` mount points used within tabs.
Add `EntitySwitch` to be used to select components based on entity data, along with accompanying `isKind`, `isNamespace`, and `isComponentType` filters.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-api-docs': patch
---
Link register API to catalog-import plugin
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/backend-common': patch
'@backstage/techdocs-common': patch
'@backstage/plugin-scaffolder-backend': patch
---
Moving the Git actions to isomorphic-git instead of the node binding version of nodegit
-20
View File
@@ -1,20 +0,0 @@
---
'@backstage/techdocs-common': patch
'@backstage/plugin-techdocs-backend': patch
---
Using @backstage/integration package for GitHub/GitLab/Azure tokens and request options.
Most probably you do not have to make any changes in the app because of this change.
However, if you are using the `DirectoryPreparer` or `CommonGitPreparer` exported by
`@backstage/techdocs-common` package, you now need to add pass in a `config` (from `@backstage/config`)
instance as argument.
```
<!-- Before -->
const directoryPreparer = new DirectoryPreparer(logger);
const commonGitPreparer = new CommonGitPreparer(logger);
<!-- Now -->
const directoryPreparer = new DirectoryPreparer(config, logger);
const commonGitPreparer = new CommonGitPreparer(config, logger);
```
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/dev-utils': patch
---
Add new `addPage` method for use with extensions, as well as an `EntityGridItem` to easily create different test cases for entity overview cards.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-cost-insights': patch
---
Fix links in sample instructions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Tweaked development log formatter to include extra fields at the end of each log line
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-techdocs': patch
'@backstage/plugin-techdocs-backend': patch
---
Added configuration schema for the commonly used properties of techdocs and techdocs-backend plugins
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-fossa': patch
---
Bump dependency versions of @backstage/core, cli and test-utils
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog': patch
---
Add new `EntityProvider` component, which can be used to provide an entity for the `useEntity` hook.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-api': patch
---
Deprecate `RouteRef` path parameter and member, and remove deprecated `routeRef.createSubRouteRef`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-api': patch
---
Delay auth loginPopup close to avoid race condition with callers of authFlowHelpers.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-auth-backend': patch
---
fix bug in token expiration date
+1
View File
@@ -134,6 +134,7 @@ neuro
newrelic
nginx
Niklas
nodegit
nohoist
nonces
npm
+1 -1
View File
@@ -81,7 +81,7 @@ jobs:
- uses: Klemensas/action-autotag@1.2.3
if: matrix.node-version == '12.x'
with:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
GITHUB_TOKEN: '${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}'
package_root: 'packages/core'
tag_prefix: 'v'
+33 -21
View File
@@ -6,19 +6,19 @@ Therefore we want to create strong community of contributors -- all working toge
Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. ❤️
Backstage is released under the Apache2.0 License, and original creations contributed to this repo are accepted under the same license.
Backstage is released under the Apache 2.0 License, and original creations contributed to this repo are accepted under the same license.
# Types of Contributions
## Types of Contributions
## Report bugs
### Report bugs
No one likes bugs. Report bugs as an issue [here](https://github.com/backstage/backstage/issues/new?template=bug_template.md).
## Fix bugs or build new features
### Fix bugs or build new features
Look through the GitHub issues for [bugs](https://github.com/backstage/backstage/labels/bugs), [good first issues](https://github.com/backstage/backstage/labels/good%20first%20issue) or [help wanted](https://github.com/backstage/backstage/labels/help%20wanted).
## Build a plugin
### Build a plugin
The value of Backstage grows with every new plugin that gets added. Wouldn't it be fantastic if there was a plugin for every infrastructure project out there? We think so. And we would love your help.
@@ -26,27 +26,27 @@ A great reference example of a plugin can be found on [our blog](https://backsta
What kind of plugins should/could be created? Some inspiration from the 120+ plugins that we have developed inside Spotify can be found [here](https://backstage.io/demos), but we will keep a running list of suggestions labeled with [[plugin]](https://github.com/backstage/backstage/labels/plugin).
## Suggesting a plugin
### Suggesting a plugin
If you start developing a plugin that you aim to release as open source, we suggest that you create a [new Issue](https://github.com/backstage/backstage/issues/new?labels=plugin&template=plugin_template.md&title=%5BPlugin%5D+THE+PLUGIN+NAME). This helps the community know what plugins are in development.
You can also use this process if you have an idea for a good plugin but you hope that someone else will pick up the work.
## Adding Non-code Contributions
### Adding Non-code Contributions
Since there is such a large landscape of possible development, build, and deployment environments, we welcome community contributions in these areas in the [`/contrib`](https://github.com/backstage/backstage/tree/master/contrib) folder of the project. This is an excellent place to put things that help out the community at large, but which may not fit within the scope of the core product to support natively. Here, you will find Helm charts, alternative Docker images, and much more.
## Write Documentation
### Write Documentation
The current documentation is very limited. Help us make the `/docs` folder come alive.
## Contribute to Storybook
### Contribute to Storybook
We think the best way to ensure different plugins provide a consistent experience is through a solid set of reusable UI/UX components. Backstage uses [Storybook](http://backstage.io/storybook).
Either help us [create new components](https://github.com/backstage/backstage/labels/help%20wanted) or improve stories for the existing ones (look for files with `*.stories.tsx`).
## Submit Feedback
### Submit Feedback
The best way to send feedback is to file [an issue](https://github.com/backstage/backstage/issues).
@@ -58,47 +58,59 @@ If you are proposing a feature:
- Remember that this is a volunteer-driven project, and that contributions
are welcome :)
## Add your company to ADOPTERS
### Add your company to ADOPTERS
Have you started using Backstage? Adding your company to [ADOPTERS](ADOPTERS.md) really helps the project.
# Get Started!
## Get Started!
So...feel ready to jump in? Let's do this. 👏🏻💯
Start by reading our [Getting Started](https://backstage.io/docs/getting-started/) page. If you need help, just jump into our [Discord chatroom](https://discord.gg/MUpMjP2).
# Coding Guidelines
## Coding Guidelines
All code is formatted with `prettier` using the configuration in the repo. If possible we recommend configuring your editor to format automatically, but you can also use the `yarn prettier --write <file>` command to format files.
A consistent coding style is included via [EditorConfig](https://editorconfig.org/) with the file [`.editorconfig`](.editorconfig) at the root of the repo. Depending on your editor of choice, it will either support it out of the box or you can [download a plugin](https://editorconfig.org/#download) for the config to be applied.
If you're contributing to the backend or CLI tooling, be mindful of cross-platform support. [This](https://shapeshed.com/writing-cross-platform-node/) blog post is a good guide of what to keep in mind when writing cross-platform NodeJS.
Also be sure to skim through our [ADRs](https://github.com/backstage/backstage/tree/master/docs/architecture-decisions) to see if they cover what you're working on. In particular [ADR006: Avoid React.FC and React.SFC](https://github.com/backstage/backstage/blob/master/docs/architecture-decisions/adr006-avoid-react-fc.md) is one to look out for.
If there are any updates in `markdown` file please make sure to run `yarn run lint:docs`. Though it is checked on `lint-staged`. It is required to install [vale](https://docs.errata.ai/vale/install) separately and make sure it is accessed by global command.
# Creating Changesets
## Creating Changesets
We use [changesets](https://github.com/atlassian/changesets) to help us prepare releases. It helps us make sure that every package affected by a change gets a proper version number and an entry in its `CHANGELOG.md`. To make the process of generating releases easy. it helps when contributors include changesets with their pull requests.
We use [changesets](https://github.com/atlassian/changesets) to help us prepare releases. They help us make sure that every package affected by a change gets a proper version number and an entry in its `CHANGELOG.md`. To make the process of generating releases easy, it helps when contributors include changesets with their pull requests.
## To create a changeset
### When to use a changeset?
Any time a patch, minor, or major change aligning to [Semantic Versioning](https://semver.org) is made to any published package in `packages/` or `plugins/`, a changeset should be used. It helps to align your change to the [Backstage stability index](https://backstage.io/docs/overview/stability-index) for the package you are changing, for example, when to provide additional clarity on deprecation or impacting changes which will then be included into CHANGELOGs.
In general, changesets are not needed for the documentation, build utilities, contributed samples in `contrib/`, or the [example `packages/app`](packages/app).
### How to create a changeset
1. Run `yarn changeset`
2. Select which packages you want to include a changeset for
3. Select impact of change that you're introducing (minor, major or patch)
3. Select impact of change that you're introducing (patch, minor, or major)
4. Add generated changeset to Git
5. Push the commit with your changeset to the branch associated with your PR
6. Accept our gratitude for making the release process easier on the maintainer
6. Accept our gratitude for making the release process easier on the maintainers
For more information, checkout [adding a changeset](https://github.com/atlassian/changesets/blob/master/docs/adding-a-changeset.md) documentation in changesets repository.
For more information, checkout [adding a changeset](https://github.com/atlassian/changesets/blob/master/docs/adding-a-changeset.md) documentation in the changesets repository.
# Code of Conduct
## Merging to Master
For those contributors who have earned write access to the repository, when a pull request is approved, in general we prefer the author of the PR to perform the merge themselves. This allows them to own accountability for the change and they likely know best how or when to address pending fixes or additional follow-ups. In this way, we all help contribute to the project's successful outcomes.
## Code of Conduct
This project adheres to the [Spotify FOSS Code of Conduct][code-of-conduct]. By participating, you are expected to honor this code.
[code-of-conduct]: https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md
# Security Issues?
## Security Issues?
See [SECURITY](SECURITY.md).
+10 -14
View File
@@ -17,22 +17,18 @@ const Background = props => {
<Block small className="stripe-bottom bg-black-grey">
<Block.Container style={{ justifyContent: 'flex-start' }}>
<Block.TextBox>
<Block.Title>See us in action.</Block.Title>
<Block.Title>See us in action</Block.Title>
<Block.Paragraph>
To illustrate the potential of Backstage, were showing you{' '}
<a href="https://labs.spotify.com/2020/04/21/how-we-use-backstage-at-spotify/">
how we use it here at Spotify
To explore the UI and basic features of Backstage firsthand, go
to: <a href="https://demo.backstage.io">demo.backstage.io</a>.
</Block.Paragraph>
<Block.Paragraph>
Watch the videos below to get an introduction to Backstage and to
see how we use different plugins to customize{' '}
<a href="https://engineering.atspotify.com/2020/04/21/how-we-use-backstage-at-spotify/">
our internal version of Backstage at Spotify
</a>
. The videos below feature the custom plugins and templates that
we built for our internal version of Backstage. You can use
Backstage to build the developer portal you want integrating the
tools that you use in your own infrastructure ecosystem. (Or get
started by building an open source plugin for Backstage that
everyone can use, like our{' '}
<a href="https://backstage.io/blog/2020/04/06/lighthouse-plugin">
Lighthouse Plugin
</a>
.)
.
</Block.Paragraph>
</Block.TextBox>
<Block.Graphics>
+1
View File
@@ -45,6 +45,7 @@
"fs-extra": "^9.0.1",
"git-url-parse": "^11.4.3",
"helmet": "^4.0.0",
"isomorphic-git": "^1.8.0",
"knex": "^0.21.6",
"lodash": "^4.17.15",
"logform": "^2.1.1",
+1
View File
@@ -24,3 +24,4 @@ export * from './reading';
export * from './service';
export * from './paths';
export * from './hot';
export * from './scm';
@@ -17,19 +17,23 @@ import * as winston from 'winston';
import { TransformableInfo } from 'logform';
const coloredTemplate = (info: TransformableInfo) => {
const { timestamp, level, message, plugin, service } = info;
const { timestamp, level, message, plugin, service, ...fields } = info;
const colorizer = winston.format.colorize();
const prefix = plugin || service;
const timestampColor = colorizer.colorize('timestamp', timestamp);
const prefixColor = colorizer.colorize('prefix', prefix);
return `${timestampColor} ${prefixColor} ${level} ${message}`;
const extraFields = Object.entries(fields)
.map(([key, value]) => `${colorizer.colorize('field', `${key}`)}=${value}`)
.join(' ');
return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`;
};
export const coloredFormat = winston.format.combine(
winston.format.timestamp(),
winston.format.colorize({
colors: { timestamp: 'dim', prefix: 'blue' },
colors: { timestamp: 'dim', prefix: 'blue', field: 'cyan' },
}),
winston.format.printf(coloredTemplate),
);
+321
View File
@@ -0,0 +1,321 @@
/*
* 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.
*/
jest.mock('isomorphic-git');
jest.mock('isomorphic-git/http/node');
jest.mock('fs-extra');
import * as isomorphic from 'isomorphic-git';
import { Git } from './git';
import http from 'isomorphic-git/http/node';
import fs from 'fs-extra';
describe('Git', () => {
beforeEach(() => {
jest.resetAllMocks();
});
describe('add', () => {
it('should call isomorphic-git add with the correct arguments', async () => {
const git = Git.fromAuth({});
const dir = 'mockdirectory';
const filepath = 'mockfile/path';
await git.add({ dir, filepath });
expect(isomorphic.add).toHaveBeenCalledWith({
fs,
dir,
filepath,
});
});
});
describe('addRemote', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const git = Git.fromAuth({});
const dir = 'mockdirectory';
const remote = 'origin';
const url = 'git@github.com/something/sads';
await git.addRemote({ dir, remote, url });
expect(isomorphic.addRemote).toHaveBeenCalledWith({
fs,
dir,
remote,
url,
});
});
});
describe('commit', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const git = Git.fromAuth({});
const dir = 'mockdirectory';
const message = 'Inital Commit';
const author = {
name: 'author',
email: 'test@backstage.io',
};
const committer = {
name: 'comitter',
email: 'test@backstage.io',
};
await git.commit({ dir, message, author, committer });
expect(isomorphic.commit).toHaveBeenCalledWith({
fs,
dir,
message,
author,
committer,
});
});
});
describe('clone', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const url = 'http://github.com/some/repo';
const dir = '/some/mock/dir';
const auth = {
username: 'blob',
password: 'hunter2',
};
const git = Git.fromAuth(auth);
await git.clone({ url, dir });
expect(isomorphic.clone).toHaveBeenCalledWith({
fs,
http,
url,
dir,
singleBranch: true,
depth: 1,
onProgress: expect.any(Function),
headers: {
'user-agent': 'git/@isomorphic-git',
},
onAuth: expect.any(Function),
});
});
it('should pass a function that returns the authorization as the onAuth handler', async () => {
const url = 'http://github.com/some/repo';
const dir = '/some/mock/dir';
const auth = {
username: 'blob',
password: 'hunter2',
};
const git = Git.fromAuth(auth);
await git.clone({ url, dir });
const { onAuth } = ((isomorphic.clone as unknown) as jest.Mock<
typeof isomorphic['clone']
>).mock.calls[0][0]!;
expect(onAuth()).toEqual(auth);
});
});
describe('currentBranch', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const dir = '/some/mock/dir';
const fullName = true;
const git = Git.fromAuth({});
await git.currentBranch({ dir, fullName });
expect(isomorphic.currentBranch).toHaveBeenCalledWith({
fs,
dir,
fullname: true,
});
await git.currentBranch({ dir });
expect(isomorphic.currentBranch).toHaveBeenCalledWith({
fs,
dir,
fullname: false,
});
});
});
describe('fetch', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const remote = 'http://github.com/some/repo';
const dir = '/some/mock/dir';
const auth = {
username: 'blob',
password: 'hunter2',
};
const git = Git.fromAuth(auth);
await git.fetch({ remote, dir });
expect(isomorphic.fetch).toHaveBeenCalledWith({
fs,
http,
remote,
dir,
onProgress: expect.any(Function),
headers: {
'user-agent': 'git/@isomorphic-git',
},
onAuth: expect.any(Function),
});
});
it('should pass a function that returns the authorization as the onAuth handler', async () => {
const remote = 'http://github.com/some/repo';
const dir = '/some/mock/dir';
const auth = {
username: 'blob',
password: 'hunter2',
};
const git = Git.fromAuth(auth);
await git.fetch({ remote, dir });
const { onAuth } = ((isomorphic.fetch as unknown) as jest.Mock<
typeof isomorphic['fetch']
>).mock.calls[0][0]!;
expect(onAuth()).toEqual(auth);
});
});
describe('init', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const dir = '/some/mock/dir';
const git = Git.fromAuth({});
await git.init({ dir });
expect(isomorphic.init).toHaveBeenCalledWith({
fs,
dir,
});
});
});
describe('merge', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const dir = '/some/mock/dir';
const author = {
name: 'author',
email: 'test@backstage.io',
};
const committer = {
name: 'comitter',
email: 'test@backstage.io',
};
const theirs = 'master';
const ours = 'production';
const git = Git.fromAuth({});
await git.merge({ dir, theirs, ours, author, committer });
expect(isomorphic.merge).toHaveBeenCalledWith({
fs,
dir,
ours,
theirs,
author,
committer,
});
});
});
describe('push', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const remote = 'origin';
const dir = '/some/mock/dir';
const auth = {
username: 'blob',
password: 'hunter2',
};
const git = Git.fromAuth(auth);
await git.push({ dir, remote });
expect(isomorphic.push).toHaveBeenCalledWith({
fs,
http,
remote,
dir,
onProgress: expect.any(Function),
headers: {
'user-agent': 'git/@isomorphic-git',
},
onAuth: expect.any(Function),
});
});
it('should pass a function that returns the authorization as the onAuth handler', async () => {
const remote = 'origin';
const dir = '/some/mock/dir';
const auth = {
username: 'blob',
password: 'hunter2',
};
const git = Git.fromAuth(auth);
await git.push({ remote, dir });
const { onAuth } = ((isomorphic.push as unknown) as jest.Mock<
typeof isomorphic['push']
>).mock.calls[0][0]!;
expect(onAuth()).toEqual(auth);
});
});
describe('readCommit', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const dir = '/some/mock/dir';
const sha = 'as43bd7';
const git = Git.fromAuth({});
await git.readCommit({ dir, sha });
expect(isomorphic.readCommit).toHaveBeenCalledWith({
fs,
dir,
oid: sha,
});
});
});
describe('resolveRef', () => {
it('should call isomorphic-git with the correct arguments', async () => {
const dir = '/some/mock/dir';
const ref = 'as43bd7';
const git = Git.fromAuth({});
await git.resolveRef({ dir, ref });
expect(isomorphic.resolveRef).toHaveBeenCalledWith({
fs,
dir,
ref,
});
});
});
});
+251
View File
@@ -0,0 +1,251 @@
/*
* 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 git, {
ProgressCallback,
MergeResult,
ReadCommitResult,
} from 'isomorphic-git';
import http from 'isomorphic-git/http/node';
import fs from 'fs-extra';
import { Logger } from 'winston';
/*
provider username password
GitHub token 'x-oauth-basic'
GitHub App token 'x-access-token'
BitBucket 'x-token-auth' token
GitLab 'oauth2' token
From : https://isomorphic-git.org/docs/en/onAuth
Azure 'notempty' token
*/
export class Git {
private constructor(
private readonly config: {
username?: string;
password?: string;
logger?: Logger;
},
) {}
async add({
dir,
filepath,
}: {
dir: string;
filepath: string;
}): Promise<void> {
this.config.logger?.info(`Adding file {dir=${dir},filepath=${filepath}}`);
return git.add({ fs, dir, filepath });
}
async addRemote({
dir,
url,
remote,
}: {
dir: string;
remote: string;
url: string;
}): Promise<void> {
this.config.logger?.info(
`Creating new remote {dir=${dir},remote=${remote},url=${url}}`,
);
return git.addRemote({ fs, dir, remote, url });
}
async commit({
dir,
message,
author,
committer,
}: {
dir: string;
message: string;
author: { name: string; email: string };
committer: { name: string; email: string };
}): Promise<string> {
this.config.logger?.info(
`Committing file to repo {dir=${dir},message=${message}}`,
);
return git.commit({ fs, dir, message, author, committer });
}
async clone({ url, dir }: { url: string; dir: string }): Promise<void> {
this.config.logger?.info(`Cloning repo {dir=${dir},url=${url}}`);
return git.clone({
fs,
http,
url,
dir,
singleBranch: true,
depth: 1,
onProgress: this.onProgressHandler(),
headers: {
'user-agent': 'git/@isomorphic-git',
},
onAuth: this.onAuth,
});
}
// https://isomorphic-git.org/docs/en/currentBranch
async currentBranch({
dir,
fullName,
}: {
dir: string;
fullName?: boolean;
}): Promise<string | undefined> {
const fullname = fullName ?? false;
return git.currentBranch({ fs, dir, fullname }) as Promise<
string | undefined
>;
}
// https://isomorphic-git.org/docs/en/fetch
async fetch({
dir,
remote,
}: {
dir: string;
remote?: string;
}): Promise<void> {
const remoteValue = remote ?? 'origin';
this.config.logger?.info(
`Fetching remote=${remoteValue} for repository {dir=${dir}}`,
);
await git.fetch({
fs,
http,
dir,
remote: remoteValue,
onProgress: this.onProgressHandler(),
headers: {
'user-agent': 'git/@isomorphic-git',
},
onAuth: this.onAuth,
});
}
async init({ dir }: { dir: string }): Promise<void> {
this.config.logger?.info(`Init git repository {dir=${dir}}`);
return git.init({
fs,
dir,
});
}
// https://isomorphic-git.org/docs/en/merge
async merge({
dir,
theirs,
ours,
author,
committer,
}: {
dir: string;
theirs: string;
ours?: string;
author: { name: string; email: string };
committer: { name: string; email: string };
}): Promise<MergeResult> {
this.config.logger?.info(
`Merging branch '${theirs}' into '${ours}' for repository {dir=${dir}}`,
);
// If ours is undefined, current branch is used.
return git.merge({
fs,
dir,
ours,
theirs,
author,
committer,
});
}
async push({ dir, remote }: { dir: string; remote: string }) {
this.config.logger?.info(
`Pushing directory to remote {dir=${dir},remote=${remote}}`,
);
return git.push({
fs,
dir,
http,
onProgress: this.onProgressHandler(),
headers: {
'user-agent': 'git/@isomorphic-git',
},
remote: remote,
onAuth: this.onAuth,
});
}
// https://isomorphic-git.org/docs/en/readCommit
async readCommit({
dir,
sha,
}: {
dir: string;
sha: string;
}): Promise<ReadCommitResult> {
return git.readCommit({ fs, dir, oid: sha });
}
// https://isomorphic-git.org/docs/en/resolveRef
async resolveRef({
dir,
ref,
}: {
dir: string;
ref: string;
}): Promise<string> {
return git.resolveRef({ fs, dir, ref });
}
private onAuth = () => ({
username: this.config.username,
password: this.config.password,
});
private onProgressHandler = (): ProgressCallback => {
let currentPhase = '';
return event => {
if (currentPhase !== event.phase) {
currentPhase = event.phase;
this.config.logger?.info(event.phase);
}
const total = event.total
? `${Math.round((event.loaded / event.total) * 100)}%`
: event.loaded;
this.config.logger?.debug(`status={${event.phase},total={${total}}}`);
};
};
static fromAuth = ({
username,
password,
logger,
}: {
username?: string;
password?: string;
logger?: Logger;
}) => new Git({ username, password, logger });
}
+17
View File
@@ -0,0 +1,17 @@
/*
* 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 { Git } from './git';
+6
View File
@@ -1,5 +1,11 @@
# @backstage/cli
## 0.4.4
### Patch Changes
- d45efbc9b: Fix typo in .app.listen.port config schema
## 0.4.3
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli",
"description": "CLI for developing Backstage plugins and apps",
"version": "0.4.3",
"version": "0.4.4",
"private": false,
"publishConfig": {
"access": "public"
@@ -113,8 +113,8 @@
"devDependencies": {
"@backstage/backend-common": "^0.4.1",
"@backstage/config": "^0.1.2",
"@backstage/core": "^0.4.2",
"@backstage/dev-utils": "^0.1.6",
"@backstage/core": "^0.4.3",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@backstage/theme": "^0.2.2",
"@types/diff": "^4.0.2",
@@ -182,7 +182,7 @@
"visibility": "frontend",
"description": "The host that the frontend should be bound to. Only used for local development."
},
"post": {
"port": {
"type": "number",
"visibility": "frontend",
"description": "The port that the frontend should be bound to. Only used for local development."
+8
View File
@@ -1,5 +1,13 @@
# @backstage/core-api
## 0.2.8
### Patch Changes
- a08c32ced: Add `FlatRoutes` component to replace the top-level `Routes` component from `react-router` within apps, removing the need for manually appending `/*` to paths or sorting routes.
- 86c3c652a: Deprecate `RouteRef` path parameter and member, and remove deprecated `routeRef.createSubRouteRef`.
- 27f2af935: Delay auth loginPopup close to avoid race condition with callers of authFlowHelpers.
## 0.2.7
### Patch Changes
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core-api",
"description": "Internal Core API used by Backstage plugins and apps",
"version": "0.2.7",
"version": "0.2.8",
"private": false,
"publishConfig": {
"access": "public",
@@ -43,7 +43,7 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/cli": "^0.4.4",
"@backstage/test-utils-core": "^0.1.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+10
View File
@@ -1,5 +1,15 @@
# @backstage/core
## 0.4.3
### Patch Changes
- a08c32ced: Add `FlatRoutes` component to replace the top-level `Routes` component from `react-router` within apps, removing the need for manually appending `/*` to paths or sorting routes.
- Updated dependencies [a08c32ced]
- Updated dependencies [86c3c652a]
- Updated dependencies [27f2af935]
- @backstage/core-api@0.2.8
## 0.4.2
### Patch Changes
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core",
"description": "Core API used by Backstage plugins and apps",
"version": "0.4.2",
"version": "0.4.3",
"private": false,
"publishConfig": {
"access": "public",
@@ -30,7 +30,7 @@
},
"dependencies": {
"@backstage/config": "^0.1.2",
"@backstage/core-api": "^0.2.7",
"@backstage/core-api": "^0.2.8",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -65,7 +65,7 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/cli": "^0.4.4",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+22
View File
@@ -1,5 +1,27 @@
# @backstage/create-app
## 0.3.1
### Patch Changes
- 4e0e3b1bf: Add missing `yarn clean` for app.
For users with existing Backstage installations, add the following under the `scripts` section in `packages/app/package.json`, after the "lint" entry:
```json
"clean": "backstage-cli clean",
```
This will add the missing `yarn clean` for the generated frontend.
- 352a6581f: Added `"start-backend"` script to root `package.json`.
To apply this change to an existing app, add the following script to the root `package.json`:
```json
"start-backend": "yarn workspace backend start"
```
## 0.3.0
### Minor Changes
@@ -24,6 +24,8 @@ const isLocal = require('fs').existsSync(path.resolve(__dirname, '../src'));
if (!isLocal || process.env.BACKSTAGE_E2E_CLI_TEST) {
require('..');
} else {
// Only used for development, so should be a devDependency
// eslint-disable-next-line import/no-extraneous-dependencies
require('ts-node').register({
transpileOnly: true,
project: path.resolve(__dirname, '../../../tsconfig.json'),
+14 -9
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/create-app",
"description": "Create app package for Backstage",
"version": "0.3.0",
"version": "0.3.1",
"private": false,
"publishConfig": {
"access": "public"
@@ -39,27 +39,27 @@
"devDependencies": {
"@backstage/backend-common": "^0.4.1",
"@backstage/catalog-model": "^0.6.0",
"@backstage/cli": "^0.4.3",
"@backstage/cli": "^0.4.4",
"@backstage/config": "^0.1.2",
"@backstage/core": "^0.4.2",
"@backstage/plugin-api-docs": "^0.4.1",
"@backstage/core": "^0.4.3",
"@backstage/plugin-api-docs": "^0.4.2",
"@backstage/plugin-app-backend": "^0.3.3",
"@backstage/plugin-auth-backend": "^0.2.7",
"@backstage/plugin-catalog": "^0.2.8",
"@backstage/plugin-auth-backend": "^0.2.8",
"@backstage/plugin-catalog": "^0.2.9",
"@backstage/plugin-catalog-backend": "^0.5.1",
"@backstage/plugin-circleci": "^0.2.5",
"@backstage/plugin-explore": "^0.2.2",
"@backstage/plugin-github-actions": "^0.2.6",
"@backstage/plugin-lighthouse": "^0.2.6",
"@backstage/plugin-proxy-backend": "^0.2.3",
"@backstage/plugin-register-component": "^0.2.5",
"@backstage/plugin-register-component": "^0.2.6",
"@backstage/plugin-rollbar-backend": "^0.1.5",
"@backstage/plugin-scaffolder": "^0.3.5",
"@backstage/plugin-search": "^0.2.4",
"@backstage/plugin-scaffolder-backend": "^0.3.6",
"@backstage/plugin-tech-radar": "^0.3.1",
"@backstage/plugin-techdocs": "^0.5.1",
"@backstage/plugin-techdocs-backend": "^0.5.0",
"@backstage/plugin-techdocs": "^0.5.2",
"@backstage/plugin-techdocs-backend": "^0.5.1",
"@backstage/plugin-user-settings": "^0.2.3",
"@backstage/test-utils": "^0.1.6",
"@backstage/theme": "^0.2.2",
@@ -70,6 +70,11 @@
"@types/recursive-readdir": "^2.2.0",
"ts-node": "^8.6.2"
},
"nodemonConfig": {
"watch": "./src",
"exec": "bin/backstage-create-app",
"ext": "ts"
},
"files": [
"bin",
"dist",
@@ -7,6 +7,7 @@
},
"scripts": {
"start": "yarn workspace app start",
"start-backend": "yarn workspace backend start",
"build": "lerna run build",
"build-image": "yarn workspace backend build-image",
"tsc": "tsc",
@@ -46,6 +46,7 @@
"build": "backstage-cli app:build",
"test": "backstage-cli test",
"lint": "backstage-cli lint",
"clean": "backstage-cli clean",
"test:e2e": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:dev",
"test:e2e:ci": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:run",
"cy:dev": "cypress open",
+11
View File
@@ -1,5 +1,16 @@
# @backstage/dev-utils
## 0.1.7
### Patch Changes
- 696b8ce74: Add new `addPage` method for use with extensions, as well as an `EntityGridItem` to easily create different test cases for entity overview cards.
- Updated dependencies [a08c32ced]
- Updated dependencies [7e0b8cac5]
- Updated dependencies [87c0c53c2]
- @backstage/core@0.4.3
- @backstage/plugin-catalog@0.2.9
## 0.1.6
### Patch Changes
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/dev-utils",
"description": "Utilities for developing Backstage plugins.",
"version": "0.1.6",
"version": "0.1.7",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,9 +29,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.4.0",
"@backstage/core": "^0.4.3",
"@backstage/catalog-model": "^0.6.0",
"@backstage/plugin-catalog": "^0.2.8",
"@backstage/plugin-catalog": "^0.2.9",
"@backstage/test-utils": "^0.1.5",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
@@ -47,7 +47,7 @@
"react-router-dom": "6.0.0-beta.0"
},
"devDependencies": {
"@backstage/cli": "^0.4.1",
"@backstage/cli": "^0.4.4",
"@types/jest": "^26.0.7",
"@types/node": "^12.0.0"
},
+20
View File
@@ -1,5 +1,25 @@
# @backstage/techdocs-common
## 0.3.1
### Patch Changes
- 8804e8981: Using @backstage/integration package for GitHub/GitLab/Azure tokens and request options.
Most probably you do not have to make any changes in the app because of this change.
However, if you are using the `DirectoryPreparer` or `CommonGitPreparer` exported by
`@backstage/techdocs-common` package, you now need to add pass in a `config` (from `@backstage/config`)
instance as argument.
```
<!-- Before -->
const directoryPreparer = new DirectoryPreparer(logger);
const commonGitPreparer = new CommonGitPreparer(logger);
<!-- Now -->
const directoryPreparer = new DirectoryPreparer(config, logger);
const commonGitPreparer = new CommonGitPreparer(config, logger);
```
## 0.3.0
### Minor Changes
+2 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/techdocs-common",
"description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli",
"version": "0.3.0",
"version": "0.3.1",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -51,18 +51,16 @@
"js-yaml": "^3.14.0",
"mime-types": "^2.1.27",
"mock-fs": "^4.13.0",
"nodegit": "^0.27.0",
"recursive-readdir": "^2.2.2",
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/cli": "^0.4.4",
"@types/fs-extra": "^9.0.5",
"@types/git-url-parse": "^9.0.0",
"@types/js-yaml": "^3.12.5",
"@types/mime-types": "^2.1.0",
"@types/mock-fs": "^4.13.0",
"@types/nodegit": "^0.26.12",
"@types/recursive-readdir": "^2.2.0"
},
"jest": {
+59 -35
View File
@@ -17,9 +17,8 @@
import os from 'os';
import path from 'path';
import parseGitUrl from 'git-url-parse';
import NodeGit, { Clone, Repository } from 'nodegit';
import fs from 'fs-extra';
import { InputError, UrlReader } from '@backstage/backend-common';
import { InputError, UrlReader, Git } from '@backstage/backend-common';
import { Entity } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import { getDefaultBranch } from './default-branch';
@@ -27,10 +26,6 @@ import { getGitRepoType, getTokenForGitRepo } from './git-auth';
import { RemoteProtocol } from './stages/prepare/types';
import { Logger } from 'winston';
// Enables core.longpaths on windows to prevent crashing when checking out repos with long foldernames and/or deep nesting
// @ts-ignore
NodeGit.Libgit2.opts(28, 1);
export type ParsedLocationAnnotation = {
type: RemoteProtocol;
target: string;
@@ -128,17 +123,61 @@ export const checkoutGitRepository = async (
const repositoryTmpPath = await getGitRepositoryTempFolder(repoUrl, config);
const token = await getTokenForGitRepo(repoUrl, config);
// Initialize a git client
let git = Git.fromAuth({ logger });
// Docs about why username and password are set to these specific values.
// https://isomorphic-git.org/docs/en/onAuth#oauth2-tokens
if (token) {
const type = getGitRepoType(repoUrl);
switch (type) {
case 'github':
git = Git.fromAuth({
username: token,
password: 'x-oauth-basic',
logger,
});
parsedGitLocation.token = `${token}:x-oauth-basic`;
break;
case 'gitlab':
git = Git.fromAuth({
username: 'oauth2',
password: token,
logger,
});
parsedGitLocation.token = `dummyUsername:${token}`;
parsedGitLocation.git_suffix = true;
break;
case 'azure/api':
git = Git.fromAuth({
username: 'notempty',
password: token,
logger: logger,
});
break;
default:
parsedGitLocation.token = `:${token}`;
}
}
// Pull from repository if it has already been cloned.
if (fs.existsSync(repositoryTmpPath)) {
try {
const repository = await Repository.open(repositoryTmpPath);
const currentBranchName = (
await repository.getCurrentBranch()
).shorthand();
await repository.fetch('origin');
await repository.mergeBranches(
currentBranchName,
`origin/${currentBranchName}`,
);
const currentBranchName = await git.currentBranch({
dir: repositoryTmpPath,
});
await git.fetch({ dir: repositoryTmpPath, remote: 'origin' });
await git.merge({
dir: repositoryTmpPath,
theirs: `origin/${currentBranchName}`,
ours: currentBranchName || undefined,
author: { name: 'Backstage TechDocs', email: 'techdocs@backstage.io' },
committer: {
name: 'Backstage TechDocs',
email: 'techdocs@backstage.io',
},
});
return repositoryTmpPath;
} catch (e) {
logger.info(
@@ -148,26 +187,10 @@ export const checkoutGitRepository = async (
}
}
if (token) {
const type = getGitRepoType(repoUrl);
switch (type) {
case 'gitlab':
// Personal Access Token
parsedGitLocation.token = `dummyUsername:${token}`;
parsedGitLocation.git_suffix = true;
break;
case 'github':
parsedGitLocation.token = `${token}:x-oauth-basic`;
break;
default:
parsedGitLocation.token = `:${token}`;
}
}
const repositoryCheckoutUrl = parsedGitLocation.toString('https');
fs.mkdirSync(repositoryTmpPath, { recursive: true });
await Clone.clone(repositoryCheckoutUrl, repositoryTmpPath);
await git.clone({ url: repositoryCheckoutUrl, dir: repositoryTmpPath });
return repositoryTmpPath;
};
@@ -183,10 +206,11 @@ export const getLastCommitTimestamp = async (
logger,
);
const repository = await Repository.open(repositoryLocation);
const commit = await repository.getReferenceCommit('HEAD');
const git = Git.fromAuth({ logger });
const sha = await git.resolveRef({ dir: repositoryLocation, ref: 'HEAD' });
const commit = await git.readCommit({ dir: repositoryLocation, sha });
return commit.date().getTime();
return commit.commit.committer.timestamp;
};
export const getDocFilesFromRepository = async (
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-api-docs
## 0.4.2
### Patch Changes
- 9161531b2: Link register API to catalog-import plugin
- Updated dependencies [a08c32ced]
- Updated dependencies [7e0b8cac5]
- Updated dependencies [87c0c53c2]
- @backstage/core@0.4.3
- @backstage/plugin-catalog@0.2.9
## 0.4.1
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-api-docs",
"version": "0.4.1",
"version": "0.4.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -30,8 +30,8 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.9",
"@backstage/theme": "^0.2.2",
"@kyma-project/asyncapi-react": "^0.14.2",
"@material-icons/font": "^1.0.2",
@@ -49,8 +49,8 @@
"swagger-ui-react": "^3.37.2"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+6
View File
@@ -1,5 +1,11 @@
# @backstage/plugin-auth-backend
## 0.2.8
### Patch Changes
- cc046682e: fix bug in token expiration date
## 0.2.7
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-auth-backend",
"version": "0.2.7",
"version": "0.2.8",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -64,7 +64,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.4.2",
"@backstage/cli": "^0.4.4",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/express-session": "^1.17.2",
+3 -3
View File
@@ -31,7 +31,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/plugin-catalog-backend": "^0.5.0",
"@backstage/integration": "^0.1.4",
@@ -50,8 +50,8 @@
"yaml": "^1.10.0"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+16
View File
@@ -1,5 +1,21 @@
# @backstage/plugin-catalog
## 0.2.9
### Patch Changes
- 7e0b8cac5: Add `CatalogIndexPage` and `CatalogEntityPage`, two new extensions that replace the existing `Router` component.
Add `EntityLayout` to replace `EntityPageLayout`, using children instead of an element property, and allowing for collection of all `RouteRef` mount points used within tabs.
Add `EntitySwitch` to be used to select components based on entity data, along with accompanying `isKind`, `isNamespace`, and `isComponentType` filters.
- 87c0c53c2: Add new `EntityProvider` component, which can be used to provide an entity for the `useEntity` hook.
- Updated dependencies [a08c32ced]
- Updated dependencies [359f9d2d8]
- @backstage/core@0.4.3
- @backstage/plugin-techdocs@0.5.2
## 0.2.8
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog",
"version": "0.2.8",
"version": "0.2.9",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,9 +32,9 @@
"dependencies": {
"@backstage/catalog-client": "^0.3.4",
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-scaffolder": "^0.3.5",
"@backstage/plugin-techdocs": "^0.5.1",
"@backstage/plugin-techdocs": "^0.5.2",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -52,8 +52,8 @@
"swr": "^0.3.0"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@microsoft/microsoft-graph-types": "^1.25.0",
"@testing-library/jest-dom": "^5.10.1",
+3 -3
View File
@@ -32,7 +32,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
@@ -50,8 +50,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -31,7 +31,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
@@ -49,8 +49,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+8
View File
@@ -1,5 +1,13 @@
# @backstage/plugin-cost-insights
## 0.5.4
### Patch Changes
- 3fca9adb9: Fix links in sample instructions
- Updated dependencies [a08c32ced]
- @backstage/core@0.4.3
## 0.5.3
### Patch Changes
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-cost-insights",
"version": "0.5.3",
"version": "0.5.4",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,7 +31,7 @@
},
"dependencies": {
"@backstage/config": "^0.1.2",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/test-utils": "^0.1.5",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
@@ -56,8 +56,8 @@
"yup": "^0.29.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -30,7 +30,7 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -42,8 +42,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+9
View File
@@ -0,0 +1,9 @@
# @backstage/plugin-fossa
## 0.1.1
### Patch Changes
- 7afdfef98: Bump dependency versions of @backstage/core, cli and test-utils
- Updated dependencies [a08c32ced]
- @backstage/core@0.4.3
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-fossa",
"version": "0.1.0",
"version": "0.1.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,7 +32,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -43,8 +43,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -30,7 +30,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -41,8 +41,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -33,7 +33,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/core-api": "^0.2.7",
"@backstage/plugin-catalog": "^0.2.8",
"@backstage/theme": "^0.2.2",
@@ -51,8 +51,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -31,7 +31,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -42,8 +42,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -31,7 +31,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -43,8 +43,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -32,7 +32,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
@@ -46,8 +46,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -33,7 +33,7 @@
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/config": "^0.1.2",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-kubernetes-backend": "^0.2.3",
"@backstage/theme": "^0.2.2",
"@kubernetes/client-node": "^0.12.1",
@@ -46,8 +46,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -33,7 +33,7 @@
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/config": "^0.1.2",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/core-api": "^0.2.6",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/theme": "^0.2.2",
@@ -47,8 +47,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -31,7 +31,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -41,8 +41,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -21,7 +21,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
@@ -33,8 +33,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -31,7 +31,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -44,8 +44,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+11
View File
@@ -1,5 +1,16 @@
# @backstage/plugin-register-component
## 0.2.6
### Patch Changes
- 1517876fd: Register component plugin is deprecated in favor of @backstage/plugin-catalog-import
- Updated dependencies [a08c32ced]
- Updated dependencies [7e0b8cac5]
- Updated dependencies [87c0c53c2]
- @backstage/core@0.4.3
- @backstage/plugin-catalog@0.2.9
## 0.2.5
### Patch Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-register-component",
"version": "0.2.5",
"version": "0.2.6",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -31,8 +31,8 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.9",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -45,8 +45,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -32,7 +32,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
@@ -47,8 +47,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -4
View File
@@ -42,6 +42,7 @@
"command-exists-promise": "^2.0.2",
"compression": "^1.7.4",
"cors": "^2.8.5",
"cross-fetch": "^3.0.6",
"dockerode": "^3.2.1",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
@@ -49,20 +50,18 @@
"git-url-parse": "^11.4.3",
"globby": "^11.0.0",
"helmet": "^4.0.0",
"isomorphic-git": "^1.8.0",
"jsonschema": "^1.2.6",
"morgan": "^1.10.0",
"nodegit": "0.27.0",
"uuid": "^8.2.0",
"winston": "^3.2.1",
"yaml": "^1.10.0",
"cross-fetch": "^3.0.6"
"yaml": "^1.10.0"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@octokit/types": "^5.4.1",
"@types/fs-extra": "^9.0.1",
"@types/git-url-parse": "^9.0.0",
"@types/nodegit": "0.26.11",
"@types/supertest": "^2.0.8",
"supertest": "^4.0.2",
"yaml": "^1.10.0"
@@ -14,11 +14,6 @@
* limitations under the License.
*/
const mocks = {
Clone: { clone: jest.fn() },
CheckoutOptions: jest.fn(() => {}),
};
jest.doMock('nodegit', () => mocks);
jest.doMock('fs-extra', () => ({
promises: {
mkdtemp: jest.fn(dir => `${dir}-static`),
@@ -30,10 +25,16 @@ import {
TemplateEntityV1alpha1,
LOCATION_ANNOTATION,
} from '@backstage/catalog-model';
import { getVoidLogger } from '@backstage/backend-common';
import { getVoidLogger, Git } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
describe('AzurePreparer', () => {
const mockGitClient = {
clone: jest.fn(),
};
jest.spyOn(Git, 'fromAuth').mockReturnValue(mockGitClient as any);
let mockEntity: TemplateEntityV1alpha1;
beforeEach(() => {
jest.clearAllMocks();
@@ -77,18 +78,7 @@ describe('AzurePreparer', () => {
};
});
it('calls the clone command with the correct arguments for a repository', async () => {
const preparer = new AzurePreparer(new ConfigReader({}));
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://dev.azure.com/backstage-org/backstage-project/_git/template-repo',
expect.any(String),
{},
);
});
it('calls the clone command with the correct arguments if an access token is provided for a repository', async () => {
it('initializes git client with the correct arguments if an access token is provided for a repository', async () => {
const preparer = new AzurePreparer(
new ConfigReader({
scaffolder: {
@@ -100,36 +90,44 @@ describe('AzurePreparer', () => {
},
}),
);
const logger = getVoidLogger();
await preparer.prepare(mockEntity, { logger });
expect(Git.fromAuth).toHaveBeenCalledWith({
username: 'notempty',
password: 'fake-token',
logger,
});
});
it('calls the clone command with the correct arguments for a repository', async () => {
const preparer = new AzurePreparer(new ConfigReader({}));
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://dev.azure.com/backstage-org/backstage-project/_git/template-repo',
expect.any(String),
{
fetchOpts: {
callbacks: {
credentials: expect.anything(),
},
},
},
);
expect(mockGitClient.clone).toHaveBeenCalledWith({
url:
'https://dev.azure.com/backstage-org/backstage-project/_git/template-repo',
dir: expect.any(String),
});
});
it('calls the clone command with the correct arguments for a repository when no path is provided', async () => {
const preparer = new AzurePreparer(new ConfigReader({}));
delete mockEntity.spec.path;
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://dev.azure.com/backstage-org/backstage-project/_git/template-repo',
expect.any(String),
{},
);
expect(mockGitClient.clone).toHaveBeenCalledWith({
url:
'https://dev.azure.com/backstage-org/backstage-project/_git/template-repo',
dir: expect.any(String),
});
});
it('return the temp directory with the path to the folder if it is specified', async () => {
const preparer = new AzurePreparer(new ConfigReader({}));
mockEntity.spec.path = './template/test/1/2/3';
const response = await preparer.prepare(mockEntity, {
logger: getVoidLogger(),
});
@@ -142,6 +140,7 @@ describe('AzurePreparer', () => {
it('return the working directory with the path to the folder if it is specified', async () => {
const preparer = new AzurePreparer(new ConfigReader({}));
mockEntity.spec.path = './template/test/1/2/3';
const response = await preparer.prepare(mockEntity, {
logger: getVoidLogger(),
workingDirectory: '/workDir',
@@ -18,10 +18,9 @@ import fs from 'fs-extra';
import path from 'path';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { parseLocationAnnotation } from '../helpers';
import { InputError } from '@backstage/backend-common';
import { InputError, Git } from '@backstage/backend-common';
import { PreparerBase, PreparerOptions } from './types';
import GitUriParser from 'git-url-parse';
import { Clone, Cred } from 'nodegit';
import { Config } from '@backstage/config';
export class AzurePreparer implements PreparerBase {
@@ -38,6 +37,7 @@ export class AzurePreparer implements PreparerBase {
): Promise<string> {
const { protocol, location } = parseLocationAnnotation(template);
const workingDirectory = opts?.workingDirectory ?? os.tmpdir();
const { logger } = opts;
if (!['azure/api', 'url'].includes(protocol)) {
throw new InputError(
@@ -57,19 +57,20 @@ export class AzurePreparer implements PreparerBase {
template.spec.path ?? '.',
);
const options = this.privateToken
? {
fetchOpts: {
callbacks: {
credentials: () =>
// Username can anything but the empty string according to: https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page#use-a-pat
Cred.userpassPlaintextNew('notempty', this.privateToken),
},
},
}
: {};
// Username can be anything but the empty string according to:
// https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page#use-a-pat
const git = this.privateToken
? Git.fromAuth({
password: this.privateToken,
username: 'notempty',
logger,
})
: Git.fromAuth({ logger });
await Clone.clone(repositoryCheckoutUrl, tempDir, options);
await git.clone({
url: repositoryCheckoutUrl,
dir: tempDir,
});
return path.resolve(tempDir, templateDirectory);
}
@@ -14,11 +14,6 @@
* limitations under the License.
*/
const mocks = {
Clone: { clone: jest.fn() },
CheckoutOptions: jest.fn(() => {}),
};
jest.doMock('nodegit', () => mocks);
jest.doMock('fs-extra', () => ({
promises: {
mkdtemp: jest.fn(dir => `${dir}-static`),
@@ -30,10 +25,16 @@ import {
TemplateEntityV1alpha1,
LOCATION_ANNOTATION,
} from '@backstage/catalog-model';
import { getVoidLogger } from '@backstage/backend-common';
import { getVoidLogger, Git } from '@backstage/backend-common';
describe('GitHubPreparer', () => {
let mockEntity: TemplateEntityV1alpha1;
const mockGitClient = {
clone: jest.fn(),
};
jest.spyOn(Git, 'fromAuth').mockReturnValue(mockGitClient as any);
beforeEach(() => {
jest.clearAllMocks();
mockEntity = {
@@ -77,28 +78,24 @@ describe('GitHubPreparer', () => {
});
it('calls the clone command with the correct arguments for a repository', async () => {
const preparer = new GithubPreparer();
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://github.com/benjdlambert/backstage-graphql-template',
expect.any(String),
{
checkoutBranch: 'master',
},
);
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://github.com/benjdlambert/backstage-graphql-template',
dir: expect.any(String),
});
});
it('calls the clone command with the correct arguments for a repository when no path is provided', async () => {
const preparer = new GithubPreparer();
delete mockEntity.spec.path;
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://github.com/benjdlambert/backstage-graphql-template',
expect.any(String),
{
checkoutBranch: 'master',
},
);
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://github.com/benjdlambert/backstage-graphql-template',
dir: expect.any(String),
});
});
it('return the temp directory with the path to the folder if it is specified', async () => {
@@ -128,19 +125,14 @@ describe('GitHubPreparer', () => {
it('calls the clone command with the token when provided', async () => {
const preparer = new GithubPreparer({ token: 'abc' });
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://github.com/benjdlambert/backstage-graphql-template',
expect.any(String),
{
checkoutBranch: 'master',
fetchOpts: {
callbacks: {
credentials: expect.any(Function),
},
},
},
);
const logger = getVoidLogger();
await preparer.prepare(mockEntity, { logger });
expect(Git.fromAuth).toHaveBeenCalledWith({
logger,
username: 'abc',
password: 'x-oauth-basic',
});
});
});
@@ -18,10 +18,9 @@ import fs from 'fs-extra';
import path from 'path';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { parseLocationAnnotation } from '../helpers';
import { InputError } from '@backstage/backend-common';
import { InputError, Git } from '@backstage/backend-common';
import { PreparerBase, PreparerOptions } from './types';
import GitUriParser from 'git-url-parse';
import { Clone, CloneOptions, Cred } from 'nodegit';
export class GithubPreparer implements PreparerBase {
token?: string;
@@ -36,7 +35,7 @@ export class GithubPreparer implements PreparerBase {
): Promise<string> {
const { protocol, location } = parseLocationAnnotation(template);
const workingDirectory = opts?.workingDirectory ?? os.tmpdir();
const { token } = this;
const { logger } = opts;
if (!['github', 'url'].includes(protocol)) {
throw new InputError(
@@ -56,25 +55,21 @@ export class GithubPreparer implements PreparerBase {
template.spec.path ?? '.',
);
let cloneOptions: CloneOptions = {
checkoutBranch: parsedGitLocation.ref,
};
const checkoutLocation = path.resolve(tempDir, templateDirectory);
if (token) {
cloneOptions = {
...cloneOptions,
fetchOpts: {
callbacks: {
credentials() {
return Cred.userpassPlaintextNew(token, 'x-oauth-basic');
},
},
},
};
}
const git = this.token
? Git.fromAuth({
username: this.token,
password: 'x-oauth-basic',
logger,
})
: Git.fromAuth({ logger });
await Clone.clone(repositoryCheckoutUrl, tempDir, cloneOptions);
await git.clone({
url: repositoryCheckoutUrl,
dir: tempDir,
});
return path.resolve(tempDir, templateDirectory);
return checkoutLocation;
}
}
@@ -13,11 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const mocks = {
Clone: { clone: jest.fn() },
CheckoutOptions: jest.fn(() => {}),
};
jest.doMock('nodegit', () => mocks);
jest.doMock('fs-extra', () => ({
promises: {
mkdtemp: jest.fn(dir => `${dir}-static`),
@@ -30,7 +25,7 @@ import {
LOCATION_ANNOTATION,
} from '@backstage/catalog-model';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { getVoidLogger, Git } from '@backstage/backend-common';
const mockEntityWithProtocol = (protocol: string): TemplateEntityV1alpha1 => ({
apiVersion: 'backstage.io/v1alpha1',
@@ -72,6 +67,12 @@ const mockEntityWithProtocol = (protocol: string): TemplateEntityV1alpha1 => ({
describe('GitLabPreparer', () => {
let mockEntity: TemplateEntityV1alpha1;
const mockGitClient = {
clone: jest.fn(),
};
jest.spyOn(Git, 'fromAuth').mockReturnValue(mockGitClient as any);
beforeEach(() => {
jest.clearAllMocks();
});
@@ -80,13 +81,13 @@ describe('GitLabPreparer', () => {
it(`calls the clone command with the correct arguments for a repository using the ${protocol} protocol`, async () => {
const preparer = new GitlabPreparer(new ConfigReader({}));
mockEntity = mockEntityWithProtocol(protocol);
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://gitlab.com/benjdlambert/backstage-graphql-template',
expect.any(String),
{},
);
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://gitlab.com/benjdlambert/backstage-graphql-template',
dir: expect.any(String),
});
});
it(`calls the clone command with the correct arguments if an access token is provided in integrations for a repository using the ${protocol} protocol`, async () => {
@@ -103,19 +104,15 @@ describe('GitLabPreparer', () => {
}),
);
mockEntity = mockEntityWithProtocol(protocol);
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://gitlab.com/benjdlambert/backstage-graphql-template',
expect.any(String),
{
fetchOpts: {
callbacks: {
credentials: expect.anything(),
},
},
},
);
const logger = getVoidLogger();
await preparer.prepare(mockEntity, { logger });
expect(Git.fromAuth).toHaveBeenCalledWith({
logger,
username: 'oauth2',
password: 'fake-token',
});
});
it(`calls the clone command with the correct arguments if an access token is provided in scaffolder for a repository using the ${protocol} protocol`, async () => {
@@ -127,32 +124,28 @@ describe('GitLabPreparer', () => {
}),
);
mockEntity = mockEntityWithProtocol(protocol);
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://gitlab.com/benjdlambert/backstage-graphql-template',
expect.any(String),
{
fetchOpts: {
callbacks: {
credentials: expect.anything(),
},
},
},
);
const logger = getVoidLogger();
await preparer.prepare(mockEntity, { logger });
expect(Git.fromAuth).toHaveBeenCalledWith({
logger,
username: 'oauth2',
password: 'fake-token',
});
});
it(`calls the clone command with the correct arguments for a repository when no path is provided using the ${protocol} protocol`, async () => {
const preparer = new GitlabPreparer(new ConfigReader({}));
mockEntity = mockEntityWithProtocol(protocol);
delete mockEntity.spec.path;
await preparer.prepare(mockEntity, { logger: getVoidLogger() });
expect(mocks.Clone.clone).toHaveBeenNthCalledWith(
1,
'https://gitlab.com/benjdlambert/backstage-graphql-template',
expect.any(String),
{},
);
expect(mockGitClient.clone).toHaveBeenCalledWith({
url: 'https://gitlab.com/benjdlambert/backstage-graphql-template',
dir: expect.any(String),
});
});
it(`return the temp directory with the path to the folder if it is specified using the ${protocol} protocol`, async () => {
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { InputError } from '@backstage/backend-common';
import { InputError, Git } from '@backstage/backend-common';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import {
@@ -22,7 +22,6 @@ import {
} from '@backstage/integration';
import fs from 'fs-extra';
import GitUriParser from 'git-url-parse';
import { Clone, Cred } from 'nodegit';
import os from 'os';
import path from 'path';
import { parseLocationAnnotation } from '../helpers';
@@ -46,6 +45,7 @@ export class GitlabPreparer implements PreparerBase {
opts: PreparerOptions,
): Promise<string> {
const { protocol, location } = parseLocationAnnotation(template);
const { logger } = opts;
const workingDirectory = opts?.workingDirectory ?? os.tmpdir();
if (!['gitlab', 'gitlab/api', 'url'].includes(protocol)) {
@@ -67,17 +67,18 @@ export class GitlabPreparer implements PreparerBase {
);
const token = this.getToken(parsedGitLocation.resource);
const options = token
? {
fetchOpts: {
callbacks: {
credentials: () => Cred.userpassPlaintextNew('oauth2', token),
},
},
}
: {};
const git = token
? Git.fromAuth({
password: token,
username: 'oauth2',
logger,
})
: Git.fromAuth({ logger });
await Clone.clone(repositoryCheckoutUrl, tempDir, options);
await git.clone({
url: repositoryCheckoutUrl,
dir: tempDir,
});
return path.resolve(tempDir, templateDirectory);
}
@@ -13,17 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
jest.mock('nodegit');
jest.mock('azure-devops-node-api/GitApi');
jest.mock('azure-devops-node-api/interfaces/GitInterfaces');
jest.mock('./helpers', () => ({
pushToRemoteUserPass: jest.fn(),
}));
jest.mock('./helpers');
import { AzurePublisher } from './azure';
import { GitApi } from 'azure-devops-node-api/GitApi';
import { pushToRemoteUserPass } from './helpers';
import * as helpers from './helpers';
import { getVoidLogger } from '@backstage/backend-common';
const { mockGitApi } = require('azure-devops-node-api/GitApi') as {
mockGitApi: {
@@ -33,6 +28,7 @@ const { mockGitApi } = require('azure-devops-node-api/GitApi') as {
describe('Azure Publisher', () => {
const publisher = new AzurePublisher(new GitApi('', []), 'fake-token');
const logger = getVoidLogger();
beforeEach(() => {
jest.clearAllMocks();
@@ -50,6 +46,7 @@ describe('Azure Publisher', () => {
owner: 'bob',
},
directory: '/tmp/test',
logger,
});
expect(result).toEqual({
@@ -63,12 +60,12 @@ describe('Azure Publisher', () => {
},
'project',
);
expect(pushToRemoteUserPass).toHaveBeenCalledWith(
'/tmp/test',
'https://dev.azure.com/organization/project/_git/repo',
'notempty',
'fake-token',
);
expect(helpers.initRepoAndPush).toHaveBeenCalledWith({
dir: '/tmp/test',
remoteUrl: 'https://dev.azure.com/organization/project/_git/repo',
auth: { username: 'notempty', password: 'fake-token' },
logger,
});
});
});
});
@@ -17,9 +17,9 @@
import { PublisherBase, PublisherOptions, PublisherResult } from './types';
import { GitApi } from 'azure-devops-node-api/GitApi';
import { GitRepositoryCreateOptions } from 'azure-devops-node-api/interfaces/GitInterfaces';
import { pushToRemoteUserPass } from './helpers';
import { JsonValue } from '@backstage/config';
import { RequiredTemplateValues } from '../templater';
import { initRepoAndPush } from './helpers';
export class AzurePublisher implements PublisherBase {
private readonly client: GitApi;
@@ -33,11 +33,21 @@ export class AzurePublisher implements PublisherBase {
async publish({
values,
directory,
logger,
}: PublisherOptions): Promise<PublisherResult> {
const remoteUrl = await this.createRemote(values);
await pushToRemoteUserPass(directory, remoteUrl, 'notempty', this.token);
const catalogInfoUrl = `${remoteUrl}?path=%2Fcatalog-info.yaml`;
await initRepoAndPush({
dir: directory,
remoteUrl,
auth: {
username: 'notempty',
password: this.token,
},
logger,
});
return { remoteUrl, catalogInfoUrl };
}
@@ -15,10 +15,7 @@
*/
jest.mock('@octokit/rest');
jest.mock('nodegit');
jest.mock('./helpers', () => ({
pushToRemoteUserPass: jest.fn(),
}));
jest.mock('./helpers');
import { Octokit } from '@octokit/rest';
import {
@@ -27,7 +24,8 @@ import {
UsersGetByUsernameResponseData,
} from '@octokit/types';
import { GithubPublisher } from './github';
import { pushToRemoteUserPass } from './helpers';
import { initRepoAndPush } from './helpers';
import { getVoidLogger } from '@backstage/backend-common';
const { mockGithubClient } = require('@octokit/rest') as {
mockGithubClient: {
@@ -38,6 +36,7 @@ const { mockGithubClient } = require('@octokit/rest') as {
};
describe('GitHub Publisher', () => {
const logger = getVoidLogger();
beforeEach(() => {
jest.clearAllMocks();
});
@@ -69,6 +68,7 @@ describe('GitHub Publisher', () => {
access: 'blam/team',
},
directory: '/tmp/test',
logger,
});
expect(result).toEqual({
@@ -91,12 +91,12 @@ describe('GitHub Publisher', () => {
repo: 'test',
permission: 'admin',
});
expect(pushToRemoteUserPass).toHaveBeenCalledWith(
'/tmp/test',
'https://github.com/backstage/backstage.git',
'abc',
'x-oauth-basic',
);
expect(initRepoAndPush).toHaveBeenCalledWith({
dir: '/tmp/test',
remoteUrl: 'https://github.com/backstage/backstage.git',
auth: { username: 'abc', password: 'x-oauth-basic' },
logger,
});
});
it('should use octokit to create a repo in the authed user if the organisation property is not set', async () => {
@@ -118,6 +118,7 @@ describe('GitHub Publisher', () => {
access: 'blam',
},
directory: '/tmp/test',
logger,
});
expect(result).toEqual({
@@ -132,12 +133,13 @@ describe('GitHub Publisher', () => {
private: false,
});
expect(mockGithubClient.repos.addCollaborator).not.toHaveBeenCalled();
expect(pushToRemoteUserPass).toHaveBeenCalledWith(
'/tmp/test',
'https://github.com/backstage/backstage.git',
'abc',
'x-oauth-basic',
);
expect(initRepoAndPush).toHaveBeenCalledWith({
dir: '/tmp/test',
remoteUrl: 'https://github.com/backstage/backstage.git',
auth: { username: 'abc', password: 'x-oauth-basic' },
logger,
});
});
});
@@ -161,6 +163,7 @@ describe('GitHub Publisher', () => {
description: 'description',
},
directory: '/tmp/test',
logger,
});
expect(result).toEqual({
@@ -181,12 +184,12 @@ describe('GitHub Publisher', () => {
username: 'bob',
permission: 'admin',
});
expect(pushToRemoteUserPass).toHaveBeenCalledWith(
'/tmp/test',
'https://github.com/backstage/backstage.git',
'abc',
'x-oauth-basic',
);
expect(initRepoAndPush).toHaveBeenCalledWith({
dir: '/tmp/test',
remoteUrl: 'https://github.com/backstage/backstage.git',
auth: { username: 'abc', password: 'x-oauth-basic' },
logger,
});
});
});
@@ -216,6 +219,7 @@ describe('GitHub Publisher', () => {
owner: 'bob',
},
directory: '/tmp/test',
logger,
});
expect(result).toEqual({
@@ -229,12 +233,12 @@ describe('GitHub Publisher', () => {
private: true,
visibility: 'internal',
});
expect(pushToRemoteUserPass).toHaveBeenCalledWith(
'/tmp/test',
'https://github.com/backstage/backstage.git',
'abc',
'x-oauth-basic',
);
expect(initRepoAndPush).toHaveBeenCalledWith({
dir: '/tmp/test',
remoteUrl: 'https://github.com/backstage/backstage.git',
auth: { username: 'abc', password: 'x-oauth-basic' },
logger,
});
});
});
@@ -263,6 +267,7 @@ describe('GitHub Publisher', () => {
owner: 'bob',
},
directory: '/tmp/test',
logger,
});
expect(result).toEqual({
@@ -276,12 +281,12 @@ describe('GitHub Publisher', () => {
name: 'test',
private: true,
});
expect(pushToRemoteUserPass).toHaveBeenCalledWith(
'/tmp/test',
'https://github.com/backstage/backstage.git',
'abc',
'x-oauth-basic',
);
expect(initRepoAndPush).toHaveBeenCalledWith({
dir: '/tmp/test',
remoteUrl: 'https://github.com/backstage/backstage.git',
auth: { username: 'abc', password: 'x-oauth-basic' },
logger,
});
});
});
});
@@ -16,7 +16,7 @@
import { PublisherBase, PublisherOptions, PublisherResult } from './types';
import { Octokit } from '@octokit/rest';
import { pushToRemoteUserPass } from './helpers';
import { initRepoAndPush } from './helpers';
import { JsonValue } from '@backstage/config';
import { RequiredTemplateValues } from '../templater';
@@ -46,14 +46,20 @@ export class GithubPublisher implements PublisherBase {
async publish({
values,
directory,
logger,
}: PublisherOptions): Promise<PublisherResult> {
const remoteUrl = await this.createRemote(values);
await pushToRemoteUserPass(
directory,
await initRepoAndPush({
dir: directory,
remoteUrl,
this.token,
'x-oauth-basic',
);
auth: {
username: this.token,
password: 'x-oauth-basic',
},
logger,
});
const catalogInfoUrl = remoteUrl.replace(
/\.git$/,
'/blob/master/catalog-info.yaml',
@@ -14,16 +14,14 @@
* limitations under the License.
*/
jest.mock('nodegit');
jest.mock('@gitbeaker/node');
jest.mock('./helpers', () => ({
pushToRemoteUserPass: jest.fn(),
}));
jest.mock('./helpers');
import { GitlabPublisher } from './gitlab';
import { Gitlab as GitlabAPI } from '@gitbeaker/core';
import { Gitlab } from '@gitbeaker/node';
import { pushToRemoteUserPass } from './helpers';
import { initRepoAndPush } from './helpers';
import { getVoidLogger } from '@backstage/backend-common';
const { mockGitlabClient } = require('@gitbeaker/node') as {
mockGitlabClient: {
@@ -34,6 +32,7 @@ const { mockGitlabClient } = require('@gitbeaker/node') as {
};
describe('GitLab Publisher', () => {
const logger = getVoidLogger();
const publisher = new GitlabPublisher(new Gitlab({}), 'fake-token');
beforeEach(() => {
@@ -56,6 +55,7 @@ describe('GitLab Publisher', () => {
owner: 'bob',
},
directory: '/tmp/test',
logger,
});
expect(result).toEqual({ remoteUrl: 'mockclone' });
@@ -63,12 +63,12 @@ describe('GitLab Publisher', () => {
namespace_id: 42,
name: 'test',
});
expect(pushToRemoteUserPass).toHaveBeenCalledWith(
'/tmp/test',
'mockclone',
'oauth2',
'fake-token',
);
expect(initRepoAndPush).toHaveBeenCalledWith({
dir: '/tmp/test',
remoteUrl: 'mockclone',
auth: { username: 'oauth2', password: 'fake-token' },
logger,
});
});
it('should use gitbeaker to create a repo in the authed user if the namespace property is not set', async () => {
@@ -86,6 +86,7 @@ describe('GitLab Publisher', () => {
owner: 'bob',
},
directory: '/tmp/test',
logger,
});
expect(result).toEqual({ remoteUrl: 'mockclone' });
@@ -94,12 +95,12 @@ describe('GitLab Publisher', () => {
namespace_id: 21,
name: 'test',
});
expect(pushToRemoteUserPass).toHaveBeenCalledWith(
'/tmp/test',
'mockclone',
'oauth2',
'fake-token',
);
expect(initRepoAndPush).toHaveBeenCalledWith({
dir: '/tmp/test',
remoteUrl: 'mockclone',
auth: { username: 'oauth2', password: 'fake-token' },
logger,
});
});
});
});
@@ -16,8 +16,8 @@
import { PublisherBase, PublisherOptions, PublisherResult } from './types';
import { Gitlab } from '@gitbeaker/core';
import { pushToRemoteUserPass } from './helpers';
import { JsonValue } from '@backstage/config';
import { initRepoAndPush } from './helpers';
import { RequiredTemplateValues } from '../templater';
export class GitlabPublisher implements PublisherBase {
@@ -32,9 +32,19 @@ export class GitlabPublisher implements PublisherBase {
async publish({
values,
directory,
logger,
}: PublisherOptions): Promise<PublisherResult> {
const remoteUrl = await this.createRemote(values);
await pushToRemoteUserPass(directory, remoteUrl, 'oauth2', this.token);
await initRepoAndPush({
dir: directory,
remoteUrl,
auth: {
username: 'oauth2',
password: this.token,
},
logger,
});
return { remoteUrl };
}
@@ -1,112 +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.
*/
jest.mock('nodegit');
import * as NodeGit from 'nodegit';
import { pushToRemoteCred } from './helpers';
const {
Repository,
mockRepo,
mockIndex,
Signature,
Remote,
mockRemote,
Cred,
} = require('nodegit') as {
Repository: jest.Mocked<{ init: any }>;
Signature: jest.Mocked<{ now: any }>;
Cred: jest.Mocked<{ userpassPlaintextNew: any }>;
Remote: jest.Mocked<{ create: any }>;
mockIndex: jest.Mocked<NodeGit.Index>;
mockRepo: jest.Mocked<NodeGit.Repository>;
mockRemote: jest.Mocked<NodeGit.Remote>;
};
describe('pushToRemoteCred', () => {
beforeEach(() => {
jest.clearAllMocks();
});
const directory = '/tmp/test/dir';
const remote = 'mockclone';
const credentialsProvider = () =>
NodeGit.Cred.userpassPlaintextNew('username', 'password');
it('should call init on the repo with the directory', async () => {
await pushToRemoteCred(directory, remote, credentialsProvider);
expect(Repository.init).toHaveBeenCalledWith(directory, 0);
});
it('should call refresh index on the index and write the new files', async () => {
await pushToRemoteCred(directory, remote, credentialsProvider);
expect(mockRepo.refreshIndex).toHaveBeenCalled();
});
it('should call add all files and write', async () => {
await pushToRemoteCred(directory, remote, credentialsProvider);
expect(mockIndex.addAll).toHaveBeenCalled();
expect(mockIndex.write).toHaveBeenCalled();
expect(mockIndex.writeTree).toHaveBeenCalled();
});
it('should create a commit with on head with the right name and committer', async () => {
const mockSignature = { mockSignature: 'bloblly' };
Signature.now.mockReturnValue(mockSignature);
await pushToRemoteCred(directory, remote, credentialsProvider);
expect(Signature.now).toHaveBeenCalledTimes(2);
expect(Signature.now).toHaveBeenCalledWith(
'Scaffolder',
'scaffolder@backstage.io',
);
expect(mockRepo.createCommit).toHaveBeenCalledWith(
'HEAD',
mockSignature,
mockSignature,
'initial commit',
'mockoid',
[],
);
});
it('creates a remote with the repo and remote', async () => {
await pushToRemoteCred(directory, remote, credentialsProvider);
expect(Remote.create).toHaveBeenCalledWith(mockRepo, 'origin', 'mockclone');
});
it('should push to the remote repo', async () => {
await pushToRemoteCred(directory, remote, credentialsProvider);
const [remotes, { callbacks }] = mockRemote.push.mock
.calls[0] as NodeGit.PushOptions[];
expect(remotes).toEqual(['refs/heads/master:refs/heads/master']);
callbacks?.credentials?.();
expect(Cred.userpassPlaintextNew).toHaveBeenCalledWith(
'username',
'password',
);
});
});
@@ -13,43 +13,57 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Repository, Remote, Signature, Cred } from 'nodegit';
export async function pushToRemoteCred(
directory: string,
remote: string,
credentialsProvider: () => Cred,
): Promise<void> {
const repo = await Repository.init(directory, 0);
const index = await repo.refreshIndex();
await index.addAll();
await index.write();
const oid = await index.writeTree();
await repo.createCommit(
'HEAD',
Signature.now('Scaffolder', 'scaffolder@backstage.io'),
Signature.now('Scaffolder', 'scaffolder@backstage.io'),
'initial commit',
oid,
[],
);
import globby from 'globby';
import { Logger } from 'winston';
import { Git } from '@backstage/backend-common';
const remoteRepo = await Remote.create(repo, 'origin', remote);
export async function initRepoAndPush({
dir,
remoteUrl,
auth,
logger,
}: {
dir: string;
remoteUrl: string;
auth: { username: string; password: string };
logger: Logger;
}): Promise<void> {
const git = Git.fromAuth({
username: auth.username,
password: auth.password,
logger,
});
await remoteRepo.push(['refs/heads/master:refs/heads/master'], {
callbacks: {
credentials: credentialsProvider,
},
await git.init({
dir,
});
const paths = await globby(['./**', './**/.*'], {
cwd: dir,
gitignore: true,
dot: true,
});
for (const filepath of paths) {
await git.add({ dir, filepath });
}
await git.commit({
dir,
message: 'Initial commit',
author: { name: 'Scaffolder', email: 'scaffolder@backstage.io' },
committer: { name: 'Scaffolder', email: 'scaffolder@backstage.io' },
});
await git.addRemote({
dir,
url: remoteUrl,
remote: 'origin',
});
await git.push({
dir,
remote: 'origin',
});
}
export async function pushToRemoteUserPass(
directory: string,
remote: string,
username: string,
password: string,
): Promise<void> {
return pushToRemoteCred(directory, remote, () =>
Cred.userpassPlaintextNew(username, password),
);
}
@@ -17,6 +17,7 @@ import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { RequiredTemplateValues } from '../templater';
import { JsonValue } from '@backstage/config';
import { RemoteProtocol } from '../types';
import { Logger } from 'winston';
/**
* Publisher is in charge of taking a folder created by
@@ -34,6 +35,7 @@ export type PublisherBase = {
export type PublisherOptions = {
values: RequiredTemplateValues & Record<string, JsonValue>;
logger: Logger;
directory: string;
};
@@ -159,6 +159,7 @@ export async function createRouter(
const result = await publisher.publish({
values: ctx.values,
directory: ctx.resultDir,
logger: ctx.logger,
});
return result;
},
+3 -3
View File
@@ -31,7 +31,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.8",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
@@ -50,8 +50,8 @@
"swr": "^0.3.0"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/plugin-catalog": "^0.2.7",
"@backstage/catalog-model": "^0.6.0",
"@backstage/theme": "^0.2.2",
@@ -43,8 +43,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -32,7 +32,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -45,8 +45,8 @@
"timeago.js": "^4.0.2"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -33,7 +33,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -46,8 +46,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -30,7 +30,7 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/test-utils": "^0.1.5",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
@@ -44,8 +44,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+24
View File
@@ -1,5 +1,29 @@
# @backstage/plugin-techdocs-backend
## 0.5.1
### Patch Changes
- 8804e8981: Using @backstage/integration package for GitHub/GitLab/Azure tokens and request options.
Most probably you do not have to make any changes in the app because of this change.
However, if you are using the `DirectoryPreparer` or `CommonGitPreparer` exported by
`@backstage/techdocs-common` package, you now need to add pass in a `config` (from `@backstage/config`)
instance as argument.
```
<!-- Before -->
const directoryPreparer = new DirectoryPreparer(logger);
const commonGitPreparer = new CommonGitPreparer(logger);
<!-- Now -->
const directoryPreparer = new DirectoryPreparer(config, logger);
const commonGitPreparer = new CommonGitPreparer(config, logger);
```
- 359f9d2d8: Added configuration schema for the commonly used properties of techdocs and techdocs-backend plugins
- Updated dependencies [8804e8981]
- @backstage/techdocs-common@0.3.1
## 0.5.0
### Minor Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-techdocs-backend",
"version": "0.5.0",
"version": "0.5.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -33,7 +33,7 @@
"@backstage/backend-common": "^0.4.1",
"@backstage/catalog-model": "^0.6.0",
"@backstage/config": "^0.1.2",
"@backstage/techdocs-common": "^0.3.0",
"@backstage/techdocs-common": "^0.3.1",
"@types/dockerode": "^3.2.1",
"@types/express": "^4.17.6",
"cross-fetch": "^3.0.6",
@@ -44,7 +44,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/cli": "^0.4.4",
"supertest": "^4.0.2"
},
"files": [
+16
View File
@@ -1,5 +1,21 @@
# @backstage/plugin-techdocs
## 0.5.2
### Patch Changes
- 359f9d2d8: Added configuration schema for the commonly used properties of techdocs and techdocs-backend plugins
- Updated dependencies [a08c32ced]
- Updated dependencies [7e0b8cac5]
- Updated dependencies [8804e8981]
- Updated dependencies [87c0c53c2]
- Updated dependencies [86c3c652a]
- Updated dependencies [27f2af935]
- @backstage/core-api@0.2.8
- @backstage/core@0.4.3
- @backstage/plugin-catalog@0.2.9
- @backstage/techdocs-common@0.3.1
## 0.5.1
### Patch Changes
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-techdocs",
"version": "0.5.1",
"version": "0.5.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -32,12 +32,12 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.6.0",
"@backstage/core": "^0.4.2",
"@backstage/core-api": "^0.2.7",
"@backstage/plugin-catalog": "^0.2.8",
"@backstage/core": "^0.4.3",
"@backstage/core-api": "^0.2.8",
"@backstage/plugin-catalog": "^0.2.9",
"@backstage/test-utils": "^0.1.6",
"@backstage/theme": "^0.2.2",
"@backstage/techdocs-common": "^0.3.0",
"@backstage/techdocs-common": "^0.3.1",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -50,8 +50,8 @@
"sanitize-html": "^1.27.0"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -30,7 +30,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -41,8 +41,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+3 -3
View File
@@ -30,7 +30,7 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.4.2",
"@backstage/core": "^0.4.3",
"@backstage/theme": "^0.2.2",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
@@ -41,8 +41,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.4.3",
"@backstage/dev-utils": "^0.1.6",
"@backstage/cli": "^0.4.4",
"@backstage/dev-utils": "^0.1.7",
"@backstage/test-utils": "^0.1.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
Regular → Executable
View File
View File
+58 -199
View File
@@ -1666,10 +1666,10 @@
yup "^0.29.3"
"@backstage/core@^0.3.0":
version "0.4.1"
version "0.4.2"
dependencies:
"@backstage/config" "^0.1.2"
"@backstage/core-api" "^0.2.6"
"@backstage/core-api" "^0.2.7"
"@backstage/theme" "^0.2.2"
"@material-ui/core" "^4.11.0"
"@material-ui/icons" "^4.9.1"
@@ -3921,9 +3921,9 @@
universal-user-agent "^6.0.0"
"@octokit/openapi-types@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-2.0.0.tgz#6d8f8ad9db3b75a39115f5def2654df8bed39f28"
integrity sha512-J4bfM7lf8oZvEAdpS71oTvC1ofKxfEZgU5vKVwzZKi4QPiL82udjpseJwxPid9Pu2FNmyRQOX4iEj6W1iOSnPw==
version "2.0.1"
resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-2.0.1.tgz#7453d8281ce66b8ed1607f7ac7d751c3baffd2cc"
integrity sha512-9AuC04PUnZrjoLiw3uPtwGh9FE4Q3rTqs51oNlQ0rkwgE8ftYsOC+lsrQyvCvWm85smBbSc0FNRKKumvGyb44Q==
"@octokit/plugin-enterprise-rest@^6.0.1":
version "6.0.1"
@@ -4348,11 +4348,6 @@
resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
"@sindresorhus/is@^2.0.0":
version "2.1.1"
resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz#ceff6a28a5b4867c2dd4a1ba513de278ccbe8bb1"
integrity sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==
"@sindresorhus/is@^3.1.1":
version "3.1.2"
resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.2.tgz#548650de521b344e3781fbdb0ece4aa6f729afb8"
@@ -5110,7 +5105,7 @@
dependencies:
defer-to-connect "^1.0.1"
"@szmarczak/http-timer@^4.0.0", "@szmarczak/http-timer@^4.0.5":
"@szmarczak/http-timer@^4.0.5":
version "4.0.5"
resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152"
integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==
@@ -5822,7 +5817,7 @@
resolved "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72"
integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==
"@types/keyv@*", "@types/keyv@^3.1.1":
"@types/keyv@*":
version "3.1.1"
resolved "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7"
integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==
@@ -5977,20 +5972,6 @@
resolved "https://registry.npmjs.org/@types/node/-/node-13.13.15.tgz#fe1cc3aa465a3ea6858b793fd380b66c39919766"
integrity sha512-kwbcs0jySLxzLsa2nWUAGOd/s21WU1jebrEdtzhsj1D4Yps1EOuyI1Qcu+FD56dL7NRNIJtDDjcqIG22NwkgLw==
"@types/nodegit@0.26.11":
version "0.26.11"
resolved "https://registry.npmjs.org/@types/nodegit/-/nodegit-0.26.11.tgz#0cbc5e929f23e5ffc536920e3a887e0b3f46d1a4"
integrity sha512-BGrY9F8lBtfU+Ne1Pjb9k/PUsfSCUAqPXgKkTkM6mc5213H5VAoM12zG/sz/cr3jI3AXcngNbAYWlqSrXsWJug==
dependencies:
"@types/node" "*"
"@types/nodegit@^0.26.12":
version "0.26.12"
resolved "https://registry.npmjs.org/@types/nodegit/-/nodegit-0.26.12.tgz#93afb4cb85d3a48d392c3232699c9c07d8251a36"
integrity sha512-4YpeTImFZNJ1cve4lEueHFVS8rAs8XpZqlmx+Bm9bMc+XMiCrcwaUf6peN7pod7Rl3esVlGP1zdBB7Z12eMVAA==
dependencies:
"@types/node" "*"
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
@@ -7643,6 +7624,11 @@ async-limiter@~1.0.0:
resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
async-lock@^1.1.0:
version "1.2.4"
resolved "https://registry.npmjs.org/async-lock/-/async-lock-1.2.4.tgz#80d0d612383045dd0c30eb5aad08510c1397cb91"
integrity sha512-UBQJC2pbeyGutIfYmErGc9RaJYnpZ1FHaxuKwb0ahvGiiCkPUf3p67Io+YLPmmv3RHY+mF6JEtNW8FlHsraAaA==
async-retry@^1.2.1:
version "1.3.1"
resolved "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz#139f31f8ddce50c0870b0ba558a6079684aaed55"
@@ -8280,14 +8266,6 @@ bindings@^1.5.0:
dependencies:
file-uri-to-path "1.0.0"
bl@^1.0.0:
version "1.2.2"
resolved "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==
dependencies:
readable-stream "^2.3.5"
safe-buffer "^5.1.1"
bl@^4.0.3:
version "4.0.3"
resolved "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489"
@@ -8546,19 +8524,6 @@ btoa@^1.2.1:
resolved "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
buffer-alloc@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
dependencies:
buffer-alloc-unsafe "^1.1.0"
buffer-fill "^1.0.0"
buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@@ -8569,11 +8534,6 @@ buffer-equal-constant-time@1.0.1:
resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
buffer-fill@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
buffer-from@1.x, buffer-from@^1.0.0:
version "1.1.1"
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@@ -8742,14 +8702,6 @@ cache-base@^1.0.1:
union-value "^1.0.0"
unset-value "^1.0.0"
cacheable-lookup@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz#87be64a18b925234875e10a9bb1ebca4adce6b38"
integrity sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==
dependencies:
"@types/keyv" "^3.1.1"
keyv "^4.0.0"
cacheable-lookup@^5.0.3:
version "5.0.3"
resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3"
@@ -9057,7 +9009,7 @@ chokidar@^3.2.2, chokidar@^3.3.0, chokidar@^3.3.1, chokidar@^3.4.1, chokidar@^3.
optionalDependencies:
fsevents "~2.1.2"
chownr@^1.0.1, chownr@^1.1.1, chownr@^1.1.2:
chownr@^1.1.1, chownr@^1.1.2:
version "1.1.4"
resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
@@ -9121,6 +9073,11 @@ clean-css@^4.2.3:
dependencies:
source-map "~0.6.0"
clean-git-ref@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz#dcc0ca093b90e527e67adb5a5e55b1af6816dcd9"
integrity sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==
clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
@@ -10716,13 +10673,6 @@ decompress-response@^4.2.0:
dependencies:
mimic-response "^2.0.0"
decompress-response@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz#7849396e80e3d1eba8cb2f75ef4930f76461cb0f"
integrity sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==
dependencies:
mimic-response "^2.0.0"
decompress-response@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
@@ -10981,6 +10931,11 @@ diff-sequences@^26.6.2:
resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1"
integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==
diff3@0.0.3:
version "0.0.3"
resolved "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz#d4e5c3a4cdf4e5fe1211ab42e693fcb4321580fc"
integrity sha1-1OXDpM305f4SEatC5pP8tDIVgPw=
diff@^4.0.1, diff@^4.0.2:
version "4.0.2"
resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
@@ -12866,7 +12821,7 @@ fs-extra@^0.30.0:
path-is-absolute "^1.0.0"
rimraf "^2.2.8"
fs-extra@^7.0.0, fs-extra@^7.0.1:
fs-extra@^7.0.1:
version "7.0.1"
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
@@ -13438,27 +13393,6 @@ google-p12-pem@^3.0.3:
dependencies:
node-forge "^0.10.0"
got@^10.7.0:
version "10.7.0"
resolved "https://registry.npmjs.org/got/-/got-10.7.0.tgz#62889dbcd6cca32cd6a154cc2d0c6895121d091f"
integrity sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==
dependencies:
"@sindresorhus/is" "^2.0.0"
"@szmarczak/http-timer" "^4.0.0"
"@types/cacheable-request" "^6.0.1"
cacheable-lookup "^2.0.0"
cacheable-request "^7.0.1"
decompress-response "^5.0.0"
duplexer3 "^0.1.4"
get-stream "^5.0.0"
lowercase-keys "^2.0.0"
mimic-response "^2.1.0"
p-cancelable "^2.0.0"
p-event "^4.0.0"
responselike "^2.0.0"
to-readable-stream "^2.0.0"
type-fest "^0.10.0"
got@^11.5.2:
version "11.6.0"
resolved "https://registry.npmjs.org/got/-/got-11.6.0.tgz#4978c78f3cbc3a45ee95381f8bb6efd1db1f4638"
@@ -15201,6 +15135,23 @@ isomorphic-form-data@~2.0.0:
dependencies:
form-data "^2.3.2"
isomorphic-git@^1.8.0:
version "1.8.0"
resolved "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.8.0.tgz#50440650a64706a321cbea1af955c1cf1110b238"
integrity sha512-TWJvQh+++eFrEG0IFS/jLhMwsBoCOX1/Dsw9q8no59Mp1K0jEjSHXFWv2P04PwkxcIpePkXVBI5YFcFT2nkuQg==
dependencies:
async-lock "^1.1.0"
clean-git-ref "^2.0.1"
crc-32 "^1.2.0"
diff3 "0.0.3"
ignore "^5.1.4"
minimisted "^2.0.0"
pako "^1.0.10"
pify "^4.0.1"
readable-stream "^3.4.0"
sha.js "^2.4.9"
simple-get "^3.0.2"
isomorphic-ws@^4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc"
@@ -15944,7 +15895,7 @@ json3@^3.3.2:
resolved "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
json5@2.x, json5@^2.1.0, json5@^2.1.1, json5@^2.1.2:
json5@2.x, json5@^2.1.1, json5@^2.1.2:
version "2.1.3"
resolved "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
@@ -17456,7 +17407,7 @@ mimic-response@^1.0.0, mimic-response@^1.0.1:
resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
mimic-response@^2.0.0, mimic-response@^2.1.0:
mimic-response@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
@@ -17526,6 +17477,13 @@ minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minimisted@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz#d059fb905beecf0774bc3b308468699709805cb1"
integrity sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==
dependencies:
minimist "^1.2.5"
minipass-collect@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617"
@@ -17969,23 +17927,6 @@ node-gyp@3.x:
tar "^2.0.0"
which "1"
node-gyp@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz#972654af4e5dd0cd2a19081b4b46fe0442ba6f45"
integrity sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==
dependencies:
glob "^7.0.3"
graceful-fs "^4.1.2"
mkdirp "^0.5.0"
nopt "2 || 3"
npmlog "0 || 1 || 2 || 3 || 4"
osenv "0"
request "^2.87.0"
rimraf "2"
semver "~5.3.0"
tar "^4.4.8"
which "1"
node-gyp@^5.0.2:
version "5.1.0"
resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.0.tgz#8e31260a7af4a2e2f994b0673d4e0b3866156332"
@@ -18075,22 +18016,6 @@ node-pre-gyp@^0.11.0:
semver "^5.3.0"
tar "^4"
node-pre-gyp@^0.13.0:
version "0.13.0"
resolved "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz#df9ab7b68dd6498137717838e4f92a33fc9daa42"
integrity sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==
dependencies:
detect-libc "^1.0.2"
mkdirp "^0.5.1"
needle "^2.2.1"
nopt "^4.0.1"
npm-packlist "^1.1.6"
npmlog "^4.0.2"
rc "^1.2.7"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^4"
node-releases@^1.1.52, node-releases@^1.1.58:
version "1.1.60"
resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084"
@@ -18119,21 +18044,6 @@ node-request-interceptor@^0.5.1:
debug "^4.1.1"
headers-utils "^1.2.0"
nodegit@0.27.0, nodegit@^0.27.0:
version "0.27.0"
resolved "https://registry.npmjs.org/nodegit/-/nodegit-0.27.0.tgz#4e8cc236f60e1c97324a5acff99056fe116a6ebe"
integrity sha512-E9K4gPjWiA0b3Tx5lfWCzG7Cvodi2idl3V5UD2fZrOrHikIfrN7Fc2kWLtMUqqomyoToYJLeIC8IV7xb1CYRLA==
dependencies:
fs-extra "^7.0.0"
got "^10.7.0"
json5 "^2.1.0"
lodash "^4.17.14"
nan "^2.14.0"
node-gyp "^4.0.0"
node-pre-gyp "^0.13.0"
ramda "^0.25.0"
tar-fs "^1.16.3"
nodemon@^2.0.2:
version "2.0.6"
resolved "https://registry.npmjs.org/nodemon/-/nodemon-2.0.6.tgz#1abe1937b463aaf62f0d52e2b7eaadf28cc2240d"
@@ -18718,7 +18628,7 @@ p-each-series@^2.1.0:
resolved "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48"
integrity sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==
p-event@^4.0.0, p-event@^4.1.0:
p-event@^4.1.0:
version "4.2.0"
resolved "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5"
integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==
@@ -18908,7 +18818,7 @@ packet-reader@1.0.0:
resolved "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74"
integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==
pako@~1.0.5:
pako@^1.0.10, pako@~1.0.5:
version "1.0.11"
resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
@@ -20253,14 +20163,6 @@ public-encrypt@^4.0.0:
randombytes "^2.0.1"
safe-buffer "^5.1.2"
pump@^1.0.0:
version "1.0.3"
resolved "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954"
integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
pump@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
@@ -20406,11 +20308,6 @@ ramda@^0.21.0:
resolved "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35"
integrity sha1-oAGr7bP/YQd9T/HVd9RN536NCjU=
ramda@^0.25.0:
version "0.25.0"
resolved "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9"
integrity sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==
ramda@^0.26, ramda@~0.26.1:
version "0.26.1"
resolved "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06"
@@ -21169,7 +21066,7 @@ read@1, read@~1.0.1:
dependencies:
mute-stream "~0.0.4"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@@ -21856,9 +21753,9 @@ rollup-plugin-dts@1.4.13:
"@babel/code-frame" "^7.10.4"
rollup-plugin-esbuild@2.6.x:
version "2.6.0"
resolved "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-2.6.0.tgz#80336399b113a179ccb2af5bdf7c03f061f37146"
integrity sha512-wtyDAX8kNABrBfwkrrG2xLRKRGSWUyMBURS067IRvRMpgJlLRo14WcFl95uGc4iYWfdAx436/z1LMzYqdlY4ig==
version "2.6.1"
resolved "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-2.6.1.tgz#5785532940d49adf1bff5b38e9bd9089262d4e7a"
integrity sha512-hskMEQQ4Vxlyoeg1OWlFTwWHIhpNaw6q+diOT7p9pdkk34m9Mbk3aymS/JbTqLXy/AbJi22iuXrucknKpeczfg==
dependencies:
"@rollup/pluginutils" "^4.1.0"
joycon "^2.2.5"
@@ -22243,7 +22140,7 @@ setprototypeof@1.2.0:
resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8:
sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8, sha.js@^2.4.9:
version "2.4.11"
resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
@@ -22354,7 +22251,7 @@ simple-concat@^1.0.0:
resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
simple-get@^3.0.3:
simple-get@^3.0.2, simple-get@^3.0.3:
version "3.1.0"
resolved "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3"
integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==
@@ -23465,16 +23362,6 @@ tapable@^1.0.0, tapable@^1.1.3:
resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
tar-fs@^1.16.3:
version "1.16.3"
resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509"
integrity sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==
dependencies:
chownr "^1.0.1"
mkdirp "^0.5.1"
pump "^1.0.0"
tar-stream "^1.1.2"
tar-fs@~2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2"
@@ -23485,19 +23372,6 @@ tar-fs@~2.0.1:
pump "^3.0.0"
tar-stream "^2.0.0"
tar-stream@^1.1.2:
version "1.6.2"
resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==
dependencies:
bl "^1.0.0"
buffer-alloc "^1.2.0"
end-of-stream "^1.0.0"
fs-constants "^1.0.0"
readable-stream "^2.3.0"
to-buffer "^1.1.1"
xtend "^4.0.0"
tar-stream@^2.0.0, tar-stream@^2.1.4:
version "2.1.4"
resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.4.tgz#c4fb1a11eb0da29b893a5b25476397ba2d053bfa"
@@ -23837,11 +23711,6 @@ to-arraybuffer@^1.0.0:
resolved "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
to-buffer@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80"
integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -23859,11 +23728,6 @@ to-readable-stream@^1.0.0:
resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
to-readable-stream@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz#82880316121bea662cdc226adb30addb50cb06e8"
integrity sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==
to-regex-range@^2.1.0:
version "2.1.1"
resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"
@@ -24164,11 +24028,6 @@ type-detect@4.0.8:
resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
type-fest@^0.10.0:
version "0.10.0"
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz#7f06b2b9fbfc581068d1341ffabd0349ceafc642"
integrity sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==
type-fest@^0.11.0:
version "0.11.0"
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1"