Merge branch 'master' of github.com:backstage/backstage into RoadieHQ-5identity-api-client-interface

This commit is contained in:
Brian Fletcher
2022-09-01 10:51:52 +01:00
245 changed files with 65219 additions and 190669 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs-node': patch
---
Fix Techdocs S3 and GCS publisher to include bucketRootPath in requests
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-node': patch
---
Adds experimental `catalogServiceRef` for obtaining a `CatalogClient` in the new backend system.
+14
View File
@@ -0,0 +1,14 @@
---
'@backstage/backend-common': patch
'@backstage/integration': patch
'@backstage/plugin-adr': patch
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-catalog-import': patch
'@backstage/plugin-scaffolder': patch
'@backstage/plugin-scaffolder-backend': patch
'@backstage/plugin-techdocs': patch
'@backstage/plugin-techdocs-module-addons-contrib': patch
'@backstage/plugin-techdocs-node': patch
---
Bump `git-url-parse` version to `^13.0.0`
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/backend-common': patch
'@backstage/cli': patch
---
Remove use of deprecated trimLeft/trimRight
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Added support for handling broken symlinks within the scaffolder backend. This is intended for templates that may hold a symlink that is invalid at build time but valid within the destination repo.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Tweaked workspace packaging to not rewrite existing `package.json` files.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': minor
---
Added `repositoryId` output when create a repository in Azure
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-app-api': patch
---
Updated `ServiceRegistry` to not initialize factories more than once.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/cli': patch
---
Fixed a misconfiguration where all modules where treated as ESM by the React Refresh plugin for Webpack.
+108
View File
@@ -0,0 +1,108 @@
---
'@backstage/backend-common': patch
'@backstage/backend-test-utils': patch
'@backstage/catalog-client': patch
'@backstage/cli': patch
'@backstage/config-loader': patch
'@backstage/core-app-api': patch
'@backstage/core-components': patch
'@backstage/core-plugin-api': patch
'@backstage/integration-react': patch
'@backstage/integration': patch
'@backstage/release-manifests': patch
'@backstage/test-utils': patch
'@backstage/plugin-adr-backend': patch
'@backstage/plugin-adr': patch
'@backstage/plugin-airbrake-backend': patch
'@backstage/plugin-airbrake': patch
'@backstage/plugin-allure': patch
'@backstage/plugin-analytics-module-ga': patch
'@backstage/plugin-apache-airflow': patch
'@backstage/plugin-api-docs': patch
'@backstage/plugin-apollo-explorer': patch
'@backstage/plugin-app-backend': patch
'@backstage/plugin-auth-backend': patch
'@backstage/plugin-auth-node': patch
'@backstage/plugin-azure-devops-backend': patch
'@backstage/plugin-azure-devops': patch
'@backstage/plugin-badges': patch
'@backstage/plugin-bitbucket-cloud-common': patch
'@backstage/plugin-bitrise': patch
'@backstage/plugin-catalog-backend-module-azure': patch
'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch
'@backstage/plugin-catalog-backend-module-bitbucket-server': patch
'@backstage/plugin-catalog-backend-module-bitbucket': patch
'@backstage/plugin-catalog-backend-module-gerrit': patch
'@backstage/plugin-catalog-backend-module-github': patch
'@backstage/plugin-catalog-backend-module-gitlab': patch
'@backstage/plugin-catalog-backend-module-msgraph': patch
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-catalog-graphql': patch
'@backstage/plugin-catalog-import': patch
'@backstage/plugin-circleci': patch
'@backstage/plugin-cloudbuild': patch
'@backstage/plugin-code-climate': patch
'@backstage/plugin-code-coverage-backend': patch
'@backstage/plugin-code-coverage': patch
'@backstage/plugin-codescene': patch
'@backstage/plugin-config-schema': patch
'@backstage/plugin-cost-insights': patch
'@backstage/plugin-dynatrace': patch
'@backstage/plugin-explore-react': patch
'@backstage/plugin-explore': patch
'@backstage/plugin-firehydrant': patch
'@backstage/plugin-fossa': patch
'@backstage/plugin-gcalendar': patch
'@backstage/plugin-gcp-projects': patch
'@backstage/plugin-git-release-manager': patch
'@backstage/plugin-github-actions': patch
'@backstage/plugin-github-deployments': patch
'@backstage/plugin-github-issues': patch
'@backstage/plugin-github-pull-requests-board': patch
'@backstage/plugin-gitops-profiles': patch
'@backstage/plugin-gocd': patch
'@backstage/plugin-graphiql': patch
'@backstage/plugin-graphql-backend': patch
'@backstage/plugin-home': patch
'@backstage/plugin-ilert': patch
'@backstage/plugin-jenkins-backend': patch
'@backstage/plugin-jenkins': patch
'@backstage/plugin-kafka': patch
'@backstage/plugin-kubernetes': patch
'@backstage/plugin-lighthouse': patch
'@backstage/plugin-newrelic': patch
'@backstage/plugin-org': patch
'@backstage/plugin-pagerduty': patch
'@backstage/plugin-periskop-backend': patch
'@backstage/plugin-periskop': patch
'@backstage/plugin-permission-backend': patch
'@backstage/plugin-permission-common': patch
'@backstage/plugin-permission-node': patch
'@backstage/plugin-proxy-backend': patch
'@backstage/plugin-rollbar-backend': patch
'@backstage/plugin-rollbar': patch
'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
'@backstage/plugin-scaffolder-backend': patch
'@backstage/plugin-scaffolder': patch
'@backstage/plugin-search': patch
'@backstage/plugin-sentry': patch
'@backstage/plugin-shortcuts': patch
'@backstage/plugin-sonarqube-backend': patch
'@backstage/plugin-sonarqube': patch
'@backstage/plugin-splunk-on-call': patch
'@backstage/plugin-stack-overflow': patch
'@backstage/plugin-tech-insights': patch
'@backstage/plugin-tech-radar': patch
'@backstage/plugin-techdocs-addons-test-utils': patch
'@backstage/plugin-techdocs-backend': patch
'@backstage/plugin-techdocs-module-addons-contrib': patch
'@backstage/plugin-techdocs': patch
'@backstage/plugin-todo-backend': patch
'@backstage/plugin-todo': patch
'@backstage/plugin-user-settings': patch
'@backstage/plugin-vault-backend': patch
'@backstage/plugin-vault': patch
'@backstage/plugin-xcmetrics': patch
---
Updated dependency `msw` to `^0.46.0`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-search-backend-module-elasticsearch': patch
---
Updated dependency `aws-os-connection` to `^0.2.0`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': patch
---
fix uiSchema generation when using complex dependencies
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Limit the length of error messages that get written to the database and logs - to prevent performance issues
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Added alpha `scaffolderPlugin` to be used with experimental backend system.
+28
View File
@@ -0,0 +1,28 @@
---
'@backstage/core-app-api': patch
---
If you'd like to send analytics events to multiple implementations, you may now
do so using the `MultipleAnalyticsApi` implementation provided by this package.
```tsx
import { MultipleAnalyticsApi } from '@backstage/core-app-api';
import {
analyticsApiRef,
configApiRef,
storageApiRef,
identityApiRef,
} from '@internal/backstage/core-plugin-api';
import { CustomAnalyticsApi } from '@internal/analytics';
import { VendorAnalyticsApi } from '@vendor/analytics';
createApiFactory({
api: analyticsApiRef,
deps: { configApi: configApiRef, identityApi: identityApiRef, storageApi: storageApiRef },
factory: ({ configApi, identityApi, storageApi }) =>
MultipleAnalyticsApi.fromApis([
VendorAnalyticsApi.fromConfig(configApi, { identityApi }),
CustomAnalyticsApi.fromConfig(configApi, { identityApi, storageApi }),
]),
}),
```
+2
View File
@@ -1,4 +1,6 @@
.git
.yarn/cache
.yarn/install-state.gz
docs
cypress
microsite
+6 -4
View File
@@ -190,12 +190,14 @@ jobs:
run: git diff --quiet origin/master HEAD -- yarn.lock
continue-on-error: true
- name: lock
run: yarn lock:check
- name: lint
- name: lint changed packages
if: ${{ steps.yarn-lock.outcome == 'success' }}
run: yarn backstage-cli repo lint --since origin/master
- name: lint all packages
if: ${{ steps.yarn-lock.outcome == 'failure' }}
run: yarn backstage-cli repo lint
- name: test changed packages
if: ${{ steps.yarn-lock.outcome == 'success' }}
run: yarn lerna -- run test --since origin/master -- --coverage --runInBand
+1 -1
View File
@@ -56,7 +56,7 @@ jobs:
${{ runner.os }}-yarn-
- name: yarn install
if: steps.cache-modules.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile
run: yarn install --immutable
# End of yarn setup
- name: create-app
+3 -3
View File
@@ -29,12 +29,12 @@ jobs:
# dependencies and the microsite. We leave it to the main master workflow to produce the
# cache, as that results in a smaller bundle.
- name: top-level yarn install
run: yarn install --frozen-lockfile
run: yarn install --immutable
- name: microsite yarn install
run: yarn install --frozen-lockfile
run: yarn install --immutable
working-directory: microsite
- name: storybook yarn install
run: yarn install --frozen-lockfile
run: yarn install --immutable
working-directory: storybook
- name: build API reference
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
fetch-depth: 0
token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}
- name: Install Dependencies
run: yarn --frozen-lockfile
run: yarn --immutable
- name: Create Release Pull Request
uses: backstage/changesets-action@v2
with:
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
- uses: actions/setup-python@v3
- name: install dependencies
run: yarn install --frozen-lockfile
run: yarn install --immutable
- name: generate types
run: yarn tsc
+1 -1
View File
@@ -48,7 +48,7 @@ jobs:
- name: setup chrome
uses: browser-actions/setup-chrome@latest
- name: yarn install
run: yarn install --frozen-lockfile
run: yarn install --immutable
- run: yarn tsc
- run: yarn backstage-cli repo build
+1 -5
View File
@@ -29,17 +29,13 @@ jobs:
# Skip caching of microsite dependencies, it keeps the global cache size
# smaller, which make Windows builds a lot faster for the rest of the project.
- name: yarn install
run: yarn install --frozen-lockfile
run: yarn install --immutable
working-directory: microsite
- name: prettier
run: yarn prettier:check
working-directory: microsite
- name: lock
run: yarn lock:check
working-directory: microsite
- name: build microsite
run: yarn build
working-directory: microsite
+1 -1
View File
@@ -39,7 +39,7 @@ jobs:
with:
cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }}
- name: storybook yarn install
run: yarn install --frozen-lockfile
run: yarn install --immutable
working-directory: storybook
- run: yarn build-storybook
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
# Windows file operation slowness means there's no point caching this
- name: yarn install
run: yarn install --frozen-lockfile
run: yarn install --immutable
- name: lint
run: yarn backstage-cli repo lint
+9
View File
@@ -61,6 +61,15 @@ typings/
# Optional npm cache directory
.npm
# Yarn 3 files
.pnp.*
**/.yarn/*
!**/.yarn/patches
!**/.yarn/plugins
!**/.yarn/releases
!**/.yarn/sdks
!**/.yarn/versions
# Node version directives
.nvmrc
+1 -1
View File
@@ -10,7 +10,7 @@ services:
- echo "yarn --cwd ${TUGBOAT_ROOT} start-backend --config ${TUGBOAT_ROOT}/app-config.yaml --config ${TUGBOAT_ROOT}/.tugboat/tugboat.app-config.production.yaml" >> /etc/service/node/run
- chmod +x /etc/service/node/run
build:
- yarn install --frozen-lockfile
- yarn install --immutable
- yarn workspace example-app build
start:
# wget the endpoint. Will retry every 2 seconds. 30 retries = 1m for service to come up. Plenty.
File diff suppressed because one or more lines are too long
-147529
View File
File diff suppressed because one or more lines are too long
+783
View File
File diff suppressed because one or more lines are too long
-9
View File
@@ -1,9 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
registry "https://registry.npmjs.org/"
disable-self-update-check true
lastUpdateCheck 1580389148099
yarn-path ".yarn/releases/yarn-1.22.19.js"
network-timeout 300000
+13
View File
@@ -0,0 +1,13 @@
enableGlobalCache: true
httpTimeout: 300000
nodeLinker: node-modules
npmRegistryServer: 'https://registry.npmjs.org/'
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: '@yarnpkg/plugin-workspace-tools'
yarnPath: .yarn/releases/yarn-3.2.3.cjs
+9 -9
View File
@@ -40,14 +40,14 @@
lodash.once "^4.1.1"
"@types/node@*":
version "18.7.6"
resolved "https://registry.npmjs.org/@types/node/-/node-18.7.6.tgz#31743bc5772b6ac223845e18c3fc26f042713c83"
integrity sha512-EdxgKRXgYsNITy5mjjXjVE/CS8YENSdhiagGrLqjG0pvA2owgJ6i4l7wy/PFZGC0B1/H20lWKN7ONVDNYDZm7A==
version "18.7.14"
resolved "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz#0fe081752a3333392d00586d815485a17c2cf3c9"
integrity sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA==
"@types/node@^14.14.31":
version "14.18.24"
resolved "https://registry.npmjs.org/@types/node/-/node-14.18.24.tgz#406b220dc748947e1959d8a38a75979e87166704"
integrity sha512-aJdn8XErcSrfr7k8ZDDfU6/2OgjZcB2Fu9d+ESK8D7Oa5mtsv8Fa8GpcwTA0v60kuZBaalKPzuzun4Ov1YWO/w==
version "14.18.26"
resolved "https://registry.npmjs.org/@types/node/-/node-14.18.26.tgz#239e19f8b4ea1a9eb710528061c1d733dc561996"
integrity sha512-0b+utRBSYj8L7XAp0d+DX7lI4cSmowNaaTkk6/1SKzbKkG+doLuPusB9EOvzLJ8ahJSk03bTLIL6cWaEd4dBKA==
"@types/sinonjs__fake-timers@8.1.1":
version "8.1.1"
@@ -304,9 +304,9 @@ cross-spawn@^7.0.0:
which "^2.0.1"
cypress@^10.0.0:
version "10.6.0"
resolved "https://registry.npmjs.org/cypress/-/cypress-10.6.0.tgz#13f46867febf2c3715874ed5dce9c2e946b175fe"
integrity sha512-6sOpHjostp8gcLO34p6r/Ci342lBs8S5z9/eb3ZCQ22w2cIhMWGUoGKkosabPBfKcvRS9BE4UxybBtlIs8gTQA==
version "10.7.0"
resolved "https://registry.npmjs.org/cypress/-/cypress-10.7.0.tgz#2d37f8b9751c6de33ee48639cb7e67a2ce593231"
integrity sha512-gTFvjrUoBnqPPOu9Vl5SBHuFlzx/Wxg/ZXIz2H4lzoOLFelKeF7mbwYUOzgzgF0oieU2WhJAestQdkgwJMMTvQ==
dependencies:
"@cypress/request" "^2.88.10"
"@cypress/xvfb" "^1.2.4"
+1 -1
View File
@@ -212,7 +212,7 @@ future.
common for companies to have their own npm registry, and this file makes sure
that this folder always uses the public registry.
- [`.yarnrc`](https://github.com/backstage/backstage/tree/master/.yarnrc) -
- [`.yarnrc.yml`](https://github.com/backstage/backstage/tree/master/.yarnrc.yml) -
Enforces "our" version of Yarn.
- [`app-config.yaml`](https://github.com/backstage/backstage/tree/master/app-config.yaml) -
+76
View File
@@ -0,0 +1,76 @@
---
id: yarn-migration
title: Migration to Yarn 3
description: Guide for how to migrate a Backstage project to use Yarn 3
---
> NOTE: We do not yet recommend all projects to migrate to Yarn 3. Only do so if you have specific reasons for it.
While Backstage projects created with `@backstage/create-app` use [Yarn 1](https://classic.yarnpkg.com/) by default, it
is possible to switch them to instead use [Yarn 3](https://yarnpkg.com/). Tools like `yarn backstage-cli versions:bump` will
still work, as they recognize both lockfile formats.
## Migration
In addition to this guide, also be sure to check out the [Yarn migration guide](https://yarnpkg.com/getting-started/migration) as well.
### Ignore File Updates
First off, be sure to have the updated ignore entries in your app. These are included in all newly created projects, but might be missing in yours:
Add the following to `.gitignore`:
```gitignore
# Yarn 3 files
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
```
And this to `.dockerignore`:
```gitignore
.yarn/cache
.yarn/install-state.gz
```
### Installation
Let's move on to the actual installation. We'd recommend making separate Git commits of most of these steps, in case you need to go back and debug anything. To install Yarn 3, run the following command in the project root:
```bash
yarn set version stable
```
We'll need the Yarn workspace tools plugin later on, so let's install that too:
```bash
yarn plugin import @yarnpkg/plugin-workspace-tools
```
Now we're ready to re-install all dependencies. This will update your `yarn.lock` and switch the project to use `node-modules` as the Yarn node linker.
In case you had a `.yarnrc` you can delete it now, but be sure to migrate over any options to `.yarnrc.yml`. See the [Yarn configuration docs](https://yarnpkg.com/configuration/manifest) for a full list of options. For example, `registry` is now `npmRegistryServer`, and `network-timeout` is `httpTimeout`.
### Migrate Usage
At this point you'll be all set up with Yarn 3! What remains is to migrate any usage of Yarn according to their [migration guide](https://yarnpkg.com/getting-started/migration). For example, any `yarn install --frozen-lockfile` commands should be replaced with `yarn install --immutable`.
You'll also need to update any `Dockerfile`s to add instructions to copy in your Yarn 3 installation into the image:
```Dockerfile
COPY .yarn ./.yarn
COPY .yarnrc.yml ./
```
The `--production` flag to `yarn install` has been removed in Yarn 3, instead you need to use `yarn workspaces focus --all --production` to avoid installing development dependencies in your production deployment. A tradeoff of this is that `yarn workspaces focus` does not support the `--immutable` flag.
```Dockerfile
RUN yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)"
```
If you have any internal CLI tools in your project that are exposed through `"bin"` entries in `package.json`, then you'll need to add these packages as dependencies in your project root `package.json`. This is to make sure Yarn picks up the executables and makes them available through `yarn <executable>`.
-5
View File
@@ -1,5 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
registry "https://registry.npmjs.org/"
network-timeout 300000
+2 -4
View File
@@ -12,15 +12,13 @@
"write-translations": "docusaurus-write-translations",
"version": "docusaurus-version",
"rename-version": "docusaurus-rename-version",
"verify:sidebars": "node ./scripts/verify-sidebars",
"lock:check": "yarn-lock-check"
"verify:sidebars": "node ./scripts/verify-sidebars"
},
"devDependencies": {
"@spotify/prettier-config": "^14.0.0",
"docusaurus": "^2.0.0-alpha.70",
"js-yaml": "^4.1.0",
"prettier": "^2.6.2",
"yarn-lock-check": "^1.0.5"
"prettier": "^2.6.2"
},
"prettier": "@spotify/prettier-config"
}
+2 -1
View File
@@ -331,7 +331,8 @@
"tutorials/configuring-plugin-databases",
"tutorials/switching-sqlite-postgres",
"tutorials/using-backstage-proxy-within-plugin",
"tutorials/backend-to-backend-auth"
"tutorials/backend-to-backend-auth",
"tutorials/yarn-migration"
],
"Architecture Decision Records (ADRs)": [
"architecture-decisions/adrs-overview",
+9553 -6675
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -187,6 +187,7 @@ nav:
- Adding Custom Plugin to Existing Monorepo App: 'tutorials/quickstart-app-plugin.md'
- Switching Backstage from SQLite to PostgreSQL: 'tutorials/switching-sqlite-postgres.md'
- Using the Backstage Proxy from Within a Plugin: 'tutorials/using-backstage-proxy-within-plugin.md'
- Migration to Yarn 3: 'tutorials/yarn-migration.md'
- Architecture Decision Records (ADRs):
- Overview: 'architecture-decisions/index.md'
- ADR001 - Architecture Decision Record (ADR) log: 'architecture-decisions/adr001-add-adr-log.md'
+13 -9
View File
@@ -26,17 +26,16 @@
"backstage-create": "backstage-cli create --scope backstage --no-private",
"create-plugin": "yarn backstage-create --select plugin",
"remove-plugin": "backstage-cli remove-plugin",
"release": "node scripts/prepare-release.js && changeset version && yarn diff --yes && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' '.changeset/*.json' && yarn install",
"release": "node scripts/prepare-release.js && changeset version && yarn diff --yes && yarn prettier --write '{packages,plugins}/*/{package.json,CHANGELOG.md}' '.changeset/*.json' && yarn install --no-immutable",
"prettier:check": "prettier --check .",
"lerna": "lerna",
"storybook": "yarn --cwd storybook start",
"storybook": "yarn ./storybook run start",
"snyk:test": "npx snyk test --yarn-workspaces --strict-out-of-sync=false",
"snyk:test:package": "yarn snyk:test --include",
"build-storybook": "yarn --cwd storybook build-storybook",
"build-storybook": "yarn ./storybook run build-storybook",
"techdocs-cli": "node scripts/techdocs-cli.js",
"techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js",
"prepare": "husky install",
"lock:check": "yarn-lock-check"
"prepare": "husky install"
},
"workspaces": {
"packages": [
@@ -57,14 +56,19 @@
"@microsoft/tsdoc": "^0.14.1"
},
"devDependencies": {
"@backstage/cli": "workspace:*",
"@backstage/codemods": "workspace:*",
"@backstage/create-app": "workspace:*",
"@changesets/cli": "^2.14.0",
"@octokit/rest": "^19.0.3",
"@spotify/prettier-config": "^14.0.0",
"@techdocs/cli": "workspace:*",
"@types/node": "^16.11.26",
"@types/webpack": "^5.28.0",
"command-exists": "^1.2.9",
"cross-env": "^7.0.0",
"concurrently": "^7.0.0",
"cross-env": "^7.0.0",
"e2e-test": "workspace:*",
"eslint-plugin-notice": "^0.9.10",
"fs-extra": "10.1.0",
"husky": "^8.0.0",
@@ -75,8 +79,7 @@
"semver": "^7.3.2",
"shx": "^0.3.2",
"ts-node": "^10.4.0",
"typescript": "~4.7.0",
"yarn-lock-check": "^1.0.5"
"typescript": "~4.7.0"
},
"prettier": "@spotify/prettier-config",
"lint-staged": {
@@ -90,5 +93,6 @@
"*.md": [
"node ./scripts/check-docs-quality"
]
}
},
"packageManager": "yarn@3.2.3"
}
+1 -2
View File
@@ -2,7 +2,6 @@
"name": "@backstage/app-defaults",
"description": "Provides the default wiring of a Backstage App",
"version": "1.0.6-next.1",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -33,8 +32,8 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/core-components": "^0.11.1-next.1",
"@backstage/core-app-api": "^1.1.0-next.1",
"@backstage/core-components": "^0.11.1-next.1",
"@backstage/core-plugin-api": "^1.0.6-next.1",
"@backstage/plugin-permission-react": "^0.4.5-next.1",
"@backstage/theme": "^0.2.16",
+2 -2
View File
@@ -16,9 +16,9 @@
"@backstage/core-plugin-api": "^1.0.6-next.1",
"@backstage/integration-react": "^1.1.4-next.0",
"@backstage/plugin-airbrake": "^0.3.9-next.1",
"@backstage/plugin-apache-airflow": "^0.2.2-next.1",
"@backstage/plugin-api-docs": "^0.8.9-next.1",
"@backstage/plugin-azure-devops": "^0.2.0-next.1",
"@backstage/plugin-apache-airflow": "^0.2.2-next.1",
"@backstage/plugin-badges": "^0.2.33-next.1",
"@backstage/plugin-catalog-common": "^1.0.6-next.0",
"@backstage/plugin-catalog-graph": "^0.2.21-next.1",
@@ -61,6 +61,7 @@
"@backstage/plugin-todo": "^0.2.11-next.1",
"@backstage/plugin-user-settings": "^0.4.8-next.1",
"@backstage/theme": "^0.2.16",
"@internal/plugin-catalog-customized": "0.0.2-next.0",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
@@ -69,7 +70,6 @@
"@roadiehq/backstage-plugin-github-insights": "^2.0.0",
"@roadiehq/backstage-plugin-github-pull-requests": "^2.0.0",
"@roadiehq/backstage-plugin-travis-ci": "^2.0.0",
"@internal/plugin-catalog-customized": "0.0.2-next.0",
"history": "^5.0.0",
"prop-types": "^15.7.2",
"react": "^17.0.2",
+1 -2
View File
@@ -4,7 +4,6 @@
"version": "0.2.1-next.0",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
@@ -34,8 +33,8 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/backend-plugin-api": "^0.1.2-next.0",
"@backstage/backend-common": "^0.15.1-next.1",
"@backstage/backend-plugin-api": "^0.1.2-next.0",
"@backstage/backend-tasks": "^0.3.5-next.0",
"@backstage/plugin-permission-node": "^0.6.5-next.1",
"express": "^4.17.1",
@@ -17,6 +17,7 @@
import {
createServiceRef,
createServiceFactory,
ServiceRef,
} from '@backstage/backend-plugin-api';
import { ServiceRegistry } from './ServiceRegistry';
@@ -170,4 +171,53 @@ describe('ServiceRegistry', () => {
expect(await factoryB('catalog')).toBe(await factoryB('catalog'));
expect(await factoryA('catalog')).not.toBe(await factoryB('catalog'));
});
it('should only call each default factory loader once', async () => {
const factoryLoader = jest.fn(async (service: ServiceRef<void>) =>
createServiceFactory({
service,
deps: {},
factory: async () => async () => {},
}),
);
const ref = createServiceRef<void>({
id: '1',
defaultFactory: factoryLoader,
});
const registry = new ServiceRegistry([]);
const factory = registry.get(ref)!;
await Promise.all([
expect(factory('catalog')).resolves.toBeUndefined(),
expect(factory('catalog')).resolves.toBeUndefined(),
]);
expect(factoryLoader).toHaveBeenCalledTimes(1);
});
it('should not call factory functions more than once', async () => {
const innerFactory = jest.fn(async (pluginId: string) => {
return { x: 1, pluginId };
});
const factory = jest.fn(async () => innerFactory);
const myFactory = createServiceFactory({
service: ref1,
deps: {},
factory,
});
const registry = new ServiceRegistry([myFactory]);
await Promise.all([
registry.get(ref1)!('catalog')!,
registry.get(ref1)!('catalog')!,
registry.get(ref1)!('catalog')!,
registry.get(ref1)!('scaffolder')!,
registry.get(ref1)!('scaffolder')!,
]);
expect(factory).toHaveBeenCalledTimes(1);
expect(innerFactory).toHaveBeenCalledTimes(2);
expect(innerFactory).toHaveBeenCalledWith('catalog');
expect(innerFactory).toHaveBeenCalledWith('scaffolder');
});
});
@@ -21,8 +21,14 @@ import {
export class ServiceRegistry {
readonly #providedFactories: Map<string, ServiceFactory>;
readonly #loadedDefaultFactories: Map<Function, ServiceFactory>;
readonly #implementations: Map<ServiceFactory, Map<string, unknown>>;
readonly #loadedDefaultFactories: Map<Function, Promise<ServiceFactory>>;
readonly #implementations: Map<
ServiceFactory,
{
factoryFunc: Promise<FactoryFunc<unknown>>;
byPlugin: Map<string, Promise<unknown>>;
}
>;
constructor(factories: ServiceFactory<any>[]) {
this.#providedFactories = new Map(factories.map(f => [f.service.id, f]));
@@ -41,35 +47,38 @@ export class ServiceRegistry {
if (!factory) {
let loadedFactory = this.#loadedDefaultFactories.get(defaultFactory!);
if (!loadedFactory) {
loadedFactory = (await defaultFactory!(ref)) as ServiceFactory;
loadedFactory = defaultFactory!(ref) as Promise<ServiceFactory>;
this.#loadedDefaultFactories.set(defaultFactory!, loadedFactory);
}
factory = loadedFactory;
// NOTE: This await is safe as long as #providedFactories is not mutated.
factory = await loadedFactory;
}
let implementations = this.#implementations.get(factory);
if (implementations) {
if (implementations.has(pluginId)) {
return implementations.get(pluginId) as T;
}
} else {
implementations = new Map();
this.#implementations.set(factory, implementations);
let implementation = this.#implementations.get(factory);
if (!implementation) {
const factoryDeps = Object.fromEntries(
Object.entries(factory.deps).map(([name, serviceRef]) => [
name,
this.get(serviceRef)!, // TODO: throw
]),
);
implementation = {
factoryFunc: factory.factory(factoryDeps),
byPlugin: new Map(),
};
this.#implementations.set(factory, implementation);
}
const factoryDeps = Object.fromEntries(
Object.entries(factory.deps).map(([name, serviceRef]) => [
name,
this.get(serviceRef)!, // TODO: throw
]),
);
let result = implementation.byPlugin.get(pluginId) as Promise<any>;
if (!result) {
result = implementation.factoryFunc.then(func => func(pluginId));
const factoryFunc = await factory.factory(factoryDeps);
const implementation = await factoryFunc(pluginId);
implementation.byPlugin.set(pluginId, result);
}
implementations.set(pluginId, implementation);
return implementation as T;
return result;
};
}
}
+3 -4
View File
@@ -4,7 +4,6 @@
"version": "0.15.1-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
@@ -59,7 +58,7 @@
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"fs-extra": "10.1.0",
"git-url-parse": "^12.0.0",
"git-url-parse": "^13.0.0",
"helmet": "^6.0.0",
"isomorphic-git": "^1.8.0",
"jose": "^4.6.0",
@@ -106,13 +105,13 @@
"@types/stoppable": "^1.1.0",
"@types/supertest": "^2.0.8",
"@types/tar": "^6.1.1",
"@types/yauzl": "^2.10.0",
"@types/webpack-env": "^1.15.2",
"@types/yauzl": "^2.10.0",
"aws-sdk-mock": "^5.2.1",
"better-sqlite3": "^7.5.0",
"http-errors": "^2.0.0",
"mock-fs": "^5.1.0",
"msw": "^0.45.0",
"msw": "^0.46.0",
"mysql2": "^2.2.5",
"recursive-readdir": "^2.2.2",
"supertest": "^6.1.3"
@@ -34,7 +34,7 @@ export function requestLoggingHandler(logger?: Logger): RequestHandler {
return morgan('combined', {
stream: {
write(message: String) {
actualLogger.info(message.trimRight());
actualLogger.info(message.trimEnd());
},
},
});
-1
View File
@@ -4,7 +4,6 @@
"version": "0.1.1-next.0",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
+2 -3
View File
@@ -4,7 +4,6 @@
"version": "0.1.2-next.0",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
@@ -34,10 +33,10 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/config": "^1.0.1",
"@backstage/backend-common": "^0.15.1-next.1",
"@backstage/plugin-permission-common": "^0.6.4-next.0",
"@backstage/backend-tasks": "^0.3.5-next.0",
"@backstage/config": "^1.0.1",
"@backstage/plugin-permission-common": "^0.6.4-next.0",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"winston": "^3.2.1",
-1
View File
@@ -4,7 +4,6 @@
"version": "0.3.5-next.0",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
+2 -3
View File
@@ -4,7 +4,6 @@
"version": "0.1.28-next.1",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
@@ -35,14 +34,14 @@
"start": "backstage-cli package start"
},
"dependencies": {
"@backstage/backend-common": "^0.15.1-next.1",
"@backstage/backend-app-api": "^0.2.1-next.0",
"@backstage/backend-common": "^0.15.1-next.1",
"@backstage/backend-plugin-api": "^0.1.2-next.0",
"@backstage/cli": "^0.19.0-next.1",
"@backstage/config": "^1.0.1",
"better-sqlite3": "^7.5.0",
"knex": "^2.0.0",
"msw": "^0.45.0",
"msw": "^0.46.0",
"mysql2": "^2.2.5",
"pg": "^8.3.0",
"testcontainers": "^8.1.2",
+6 -1
View File
@@ -25,13 +25,18 @@ WORKDIR /app
# This switches many Node.js dependencies to production mode.
ENV NODE_ENV production
# Copy over Yarn 3 configuration, release, and plugins
COPY .yarn ./.yarn
COPY .yarnrc.yml ./
# Copy repo skeleton first, to avoid unnecessary docker cache invalidation.
# The skeleton contains the package.json of each package in the monorepo,
# and along with yarn.lock and the root package.json, that's enough to run yarn install.
COPY --chown=node:node yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./
RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz
RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)"
# Note that this install is not immutable, which is one of the reasons we don't recommend Yarn 3 yet
RUN yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)"
# Then copy the rest of the backend bundle, along with any other files we might want.
COPY --chown=node:node packages/backend/dist/bundle.tar.gz app-config*.yaml ./
+7 -7
View File
@@ -41,8 +41,8 @@
"@backstage/plugin-code-coverage-backend": "^0.2.2-next.0",
"@backstage/plugin-graphql-backend": "^0.1.26-next.1",
"@backstage/plugin-jenkins-backend": "^0.1.26-next.1",
"@backstage/plugin-kubernetes-backend": "^0.7.2-next.1",
"@backstage/plugin-kafka-backend": "^0.2.29-next.0",
"@backstage/plugin-kubernetes-backend": "^0.7.2-next.1",
"@backstage/plugin-permission-backend": "^0.5.11-next.0",
"@backstage/plugin-permission-common": "^0.6.4-next.0",
"@backstage/plugin-permission-node": "^0.6.5-next.1",
@@ -51,24 +51,24 @@
"@backstage/plugin-scaffolder-backend": "^1.6.0-next.1",
"@backstage/plugin-scaffolder-backend-module-rails": "^0.4.4-next.0",
"@backstage/plugin-search-backend": "^1.0.2-next.0",
"@backstage/plugin-search-common": "^1.0.1-next.0",
"@backstage/plugin-search-backend-node": "^1.0.2-next.1",
"@backstage/plugin-search-backend-module-elasticsearch": "^1.0.2-next.0",
"@backstage/plugin-search-backend-module-pg": "^0.4.0-next.1",
"@backstage/plugin-techdocs-backend": "^1.2.2-next.0",
"@backstage/plugin-search-backend-node": "^1.0.2-next.1",
"@backstage/plugin-search-common": "^1.0.1-next.0",
"@backstage/plugin-tech-insights-backend": "^0.5.2-next.1",
"@backstage/plugin-tech-insights-node": "^0.3.4-next.0",
"@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.20-next.0",
"@backstage/plugin-tech-insights-node": "^0.3.4-next.0",
"@backstage/plugin-techdocs-backend": "^1.2.2-next.0",
"@backstage/plugin-todo-backend": "^0.1.33-next.0",
"@gitbeaker/node": "^35.1.0",
"@octokit/rest": "^19.0.3",
"better-sqlite3": "^7.5.0",
"azure-devops-node-api": "^11.0.1",
"better-sqlite3": "^7.5.0",
"dockerode": "^3.3.1",
"example-app": "link:../app",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"express-prom-bundle": "^6.3.6",
"express-promise-router": "^4.1.0",
"luxon": "^3.0.0",
"pg": "^8.3.0",
"pg-connection-string": "^2.3.0",
+1 -2
View File
@@ -5,7 +5,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
@@ -40,7 +39,7 @@
"devDependencies": {
"@backstage/cli": "^0.19.0-next.1",
"@types/jest": "^26.0.7",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist"
-1
View File
@@ -5,7 +5,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
-1
View File
@@ -2,7 +2,6 @@
"name": "@backstage/cli-common",
"description": "Common functionality used by cli, backend, and create-app",
"version": "0.1.9",
"private": false,
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
+3 -3
View File
@@ -2,7 +2,6 @@
"name": "@backstage/cli",
"description": "CLI for developing Backstage plugins and apps",
"version": "0.19.0-next.1",
"private": false,
"publishConfig": {
"access": "public"
},
@@ -155,9 +154,10 @@
"@types/yarnpkg__lockfile": "^1.1.4",
"del": "^6.0.0",
"mock-fs": "^5.1.0",
"msw": "^0.45.0",
"msw": "^0.46.0",
"nodemon": "^2.0.2",
"ts-node": "^10.0.0"
"ts-node": "^10.0.0",
"type-fest": "^2.0.0"
},
"peerDependencies": {
"@microsoft/api-extractor": "^7.21.2"
+1 -1
View File
@@ -101,7 +101,7 @@ export async function command(opts: OptionValues): Promise<void> {
if (resultText) {
console.log();
console.log(chalk.red(`Lint failed in ${relativeDir}:`));
console.log(resultText.trimLeft());
console.log(resultText.trimStart());
failed = true;
}
@@ -190,7 +190,6 @@ export const transforms = (options: TransformOptions): Transforms => {
if (isDev) {
plugins.push(
new ReactRefreshPlugin({
esModule: true,
overlay: { sockProtocol: 'ws' },
}),
);
@@ -67,18 +67,21 @@ export async function copyPackageDist(packageDir: string, targetDir: string) {
delete pkg.optionalDependencies;
}
// Write the modified package.json so that the file listing is correct
await fs.writeJson(pkgPath, pkg, { encoding: 'utf8', spaces: 2 });
// Lists all dist files, respecting .npmignore, files field in package.json, etc.
const filePaths = await npmPackList({ path: packageDir });
const filePaths = await npmPackList({
path: packageDir,
// This makes sure we use the update package.json when listing files
packageJsonCache: new Map([[resolvePath(packageDir, 'package.json'), pkg]]),
});
await fs.ensureDir(targetDir);
for (const filePath of filePaths.sort()) {
await fs.copy(
resolvePath(packageDir, filePath),
resolvePath(targetDir, filePath),
);
const target = resolvePath(targetDir, filePath);
if (filePath === 'package.json') {
await fs.writeJson(target, pkg, { encoding: 'utf8', spaces: 2 });
} else {
await fs.copy(resolvePath(packageDir, filePath), target);
}
}
if (publishConfig.alphaTypes) {
@@ -87,7 +90,4 @@ export async function copyPackageDist(packageDir: string, targetDir: string) {
if (publishConfig.betaTypes) {
await writeReleaseStageEntrypoint(pkg, 'beta', targetDir);
}
// Restore package.json
await fs.writeFile(pkgPath, pkgContent, 'utf8');
}
@@ -41,7 +41,7 @@
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
"@types/supertest": "{{versionQuery '@types/supertest' '2.0.8'}}",
"supertest": "{{versionQuery 'supertest' '4.0.2'}}",
"msw": "{{versionQuery 'msw' '0.45.0'}}"
"msw": "{{versionQuery 'msw' '0.46.0'}}"
},
"files": [
"dist"
@@ -49,7 +49,7 @@
"@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '14.0.0'}}",
"@types/jest": "{{versionQuery '@types/jest' '26.0.7'}}",
"@types/node": "{{versionQuery '@types/node' '16.11.26'}}",
"msw": "{{versionQuery 'msw' '0.45.0'}}",
"msw": "{{versionQuery 'msw' '0.46.0'}}",
"cross-fetch": "{{versionQuery 'cross-fetch' '3.1.5'}}"
},
"files": [
-1
View File
@@ -2,7 +2,6 @@
"name": "@backstage/codemods",
"description": "A collection of codemods for Backstage projects",
"version": "0.1.38",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js"
+1 -2
View File
@@ -2,7 +2,6 @@
"name": "@backstage/config-loader",
"description": "Config loading functionality used by Backstage backend, and CLI",
"version": "1.1.4-next.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
@@ -57,7 +56,7 @@
"@types/node": "^16.11.26",
"@types/yup": "^0.29.13",
"mock-fs": "^5.1.0",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist"
-1
View File
@@ -2,7 +2,6 @@
"name": "@backstage/config",
"description": "Config API used by Backstage core, backend, and CLI",
"version": "1.0.1",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
+6
View File
@@ -409,6 +409,12 @@ export class MicrosoftAuth {
static create(options: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T;
}
// @public
export class MultipleAnalyticsApi implements AnalyticsApi {
captureEvent(event: AnalyticsEvent): void;
static fromApis(actualApis: AnalyticsApi[]): MultipleAnalyticsApi;
}
// @public
export class NoOpAnalyticsApi implements AnalyticsApi {
// (undocumented)
+3 -4
View File
@@ -2,7 +2,6 @@
"name": "@backstage/core-app-api",
"description": "Core app API used by Backstage apps",
"version": "1.1.0-next.1",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -59,11 +58,11 @@
"@types/node": "^16.11.26",
"@types/zen-observable": "^0.8.0",
"cross-fetch": "^3.1.5",
"msw": "^0.45.0",
"msw": "^0.46.0",
"react-router-beta": "npm:react-router@6.0.0-beta.0",
"react-router-dom-beta": "npm:react-router-dom@6.0.0-beta.0",
"react-router-stable": "npm:react-router@^6.3.0",
"react-router-dom-stable": "npm:react-router-dom@^6.3.0"
"react-router-dom-stable": "npm:react-router-dom@^6.3.0",
"react-router-stable": "npm:react-router@^6.3.0"
},
"files": [
"dist",
@@ -0,0 +1,64 @@
/*
* Copyright 2022 The Backstage Authors
*
* 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 { MultipleAnalyticsApi } from './MultipleAnalyticsApi';
describe('MultipleAnalyticsApi', () => {
const analyticsApiOne = { captureEvent: jest.fn() };
const analyticsApiTwo = { captureEvent: jest.fn() };
const multipleApis = MultipleAnalyticsApi.fromApis([
analyticsApiOne,
analyticsApiTwo,
]);
const event = {
action: 'navivate',
subject: '/path',
context: {
extension: 'App',
pluginId: 'plugin',
routeRef: 'unknown',
},
};
beforeEach(() => {
jest.clearAllMocks();
});
it('forwards events to all apis', () => {
// When an event is captured
multipleApis.captureEvent(event);
// Then both underlying APIs should have received the event
expect(analyticsApiOne.captureEvent).toHaveBeenCalledTimes(1);
expect(analyticsApiOne.captureEvent).toHaveBeenCalledWith(event);
expect(analyticsApiTwo.captureEvent).toHaveBeenCalledTimes(1);
expect(analyticsApiTwo.captureEvent).toHaveBeenCalledWith(event);
});
it('forwards events to all apis even if one throws an error', () => {
// Given one underlying API that throws on capture
analyticsApiOne.captureEvent.mockImplementation(() => {
throw new Error('!!!');
});
// When an event is captured
multipleApis.captureEvent(event);
// Then the other underlying API should have still received the event
expect(analyticsApiTwo.captureEvent).toHaveBeenCalledTimes(1);
expect(analyticsApiTwo.captureEvent).toHaveBeenCalledWith(event);
});
});
@@ -0,0 +1,70 @@
/*
* Copyright 2022 The Backstage Authors
*
* 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 { AnalyticsApi, AnalyticsEvent } from '@backstage/core-plugin-api';
/**
* An implementation of the AnalyticsApi that can be used to forward analytics
* events to multiple concrete implementations.
*
* @public
*
* @example
*
* ```jsx
* createApiFactory({
* api: analyticsApiRef,
* deps: { configApi: configApiRef, identityApi: identityApiRef, storageApi: storageApiRef },
* factory: ({ configApi, identityApi, storageApi }) =>
* MultipleAnalyticsApi.fromApis([
* VendorAnalyticsApi.fromConfig(configApi, { identityApi }),
* CustomAnalyticsApi.fromConfig(configApi, { identityApi, storageApi }),
* ]),
* });
* ```
*/
export class MultipleAnalyticsApi implements AnalyticsApi {
private constructor(private readonly actualApis: AnalyticsApi[]) {}
/**
* Create an AnalyticsApi implementation from an array of concrete
* implementations.
*
* @example
*
* ```jsx
* MultipleAnalyticsApi.fromApis([
* SomeAnalyticsApi.fromConfig(configApi),
* new CustomAnalyticsApi(),
* ]);
* ```
*/
static fromApis(actualApis: AnalyticsApi[]) {
return new MultipleAnalyticsApi(actualApis);
}
/**
* Forward the event to all configured analytics API implementations.
*/
captureEvent(event: AnalyticsEvent): void {
this.actualApis.forEach(analyticsApi => {
try {
analyticsApi.captureEvent(event);
} catch {
/* ignored */
}
});
}
}
@@ -14,4 +14,5 @@
* limitations under the License.
*/
export { MultipleAnalyticsApi } from './MultipleAnalyticsApi';
export { NoOpAnalyticsApi } from './NoOpAnalyticsApi';
+4 -5
View File
@@ -2,7 +2,6 @@
"name": "@backstage/core-components",
"description": "Core components used by Backstage plugins and apps",
"version": "0.11.1-next.1",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -42,6 +41,7 @@
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
"@react-hookz/web": "^15.0.0",
"@types/react-sparklines": "^1.7.0",
"@types/react-text-truncate": "^0.14.0",
"ansi-regex": "^6.0.1",
@@ -64,7 +64,6 @@
"react-syntax-highlighter": "^15.4.5",
"react-text-truncate": "^0.19.0",
"react-use": "^17.3.2",
"@react-hookz/web": "^15.0.0",
"react-virtualized-auto-sizer": "^1.0.6",
"react-window": "^1.8.6",
"remark-gfm": "^3.0.1",
@@ -79,18 +78,18 @@
"react-router-dom": "6.0.0-beta.0 || ^6.3.0"
},
"devDependencies": {
"@backstage/core-app-api": "^1.1.0-next.1",
"@backstage/cli": "^0.19.0-next.1",
"@backstage/core-app-api": "^1.1.0-next.1",
"@backstage/test-utils": "^1.2.0-next.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/react-hooks": "^8.0.0",
"@testing-library/user-event": "^14.0.0",
"@types/ansi-regex": "^5.0.0",
"@types/classnames": "^2.2.9",
"@types/d3-selection": "^3.0.1",
"@types/d3-shape": "^3.0.1",
"@types/d3-zoom": "^3.0.1",
"@types/ansi-regex": "^5.0.0",
"@types/dagre": "^0.7.44",
"@types/google-protobuf": "^3.7.2",
"@types/jest": "^26.0.7",
@@ -101,7 +100,7 @@
"@types/react-window": "^1.8.5",
"@types/zen-observable": "^0.8.0",
"cross-fetch": "^3.1.5",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist"
+1 -2
View File
@@ -2,7 +2,6 @@
"name": "@backstage/core-plugin-api",
"description": "Core API used by Backstage plugins",
"version": "1.0.6-next.1",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -59,7 +58,7 @@
"@types/prop-types": "^15.7.3",
"@types/zen-observable": "^0.8.0",
"cross-fetch": "^3.1.5",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist",
-1
View File
@@ -2,7 +2,6 @@
"name": "@backstage/create-app",
"description": "A CLI that helps you create your own Backstage app",
"version": "0.4.31-next.1",
"private": false,
"publishConfig": {
"access": "public"
},
@@ -1,4 +1,6 @@
.git
.yarn/cache
.yarn/install-state.gz
node_modules
packages/*/src
packages/*/node_modules
@@ -15,6 +15,15 @@ coverage
# Dependencies
node_modules/
# Yarn 3 files
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Node version directives
.nvmrc
+1 -2
View File
@@ -2,7 +2,6 @@
"name": "@backstage/dev-utils",
"description": "Utilities for developing Backstage plugins.",
"version": "1.0.6-next.1",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -34,10 +33,10 @@
},
"dependencies": {
"@backstage/app-defaults": "^1.0.6-next.1",
"@backstage/catalog-model": "^1.1.0",
"@backstage/core-app-api": "^1.1.0-next.1",
"@backstage/core-components": "^0.11.1-next.1",
"@backstage/core-plugin-api": "^1.0.6-next.1",
"@backstage/catalog-model": "^1.1.0",
"@backstage/integration-react": "^1.1.4-next.0",
"@backstage/plugin-catalog-react": "^1.1.4-next.1",
"@backstage/test-utils": "^1.2.0-next.1",
+1 -3
View File
@@ -25,9 +25,7 @@
"build": "backstage-cli package build",
"clean": "backstage-cli package clean"
},
"bin": {
"e2e-test": "bin/e2e-test"
},
"bin": "bin/e2e-test",
"devDependencies": {
"@backstage/cli-common": "^0.1.9-next.0",
"@backstage/errors": "^1.1.0-next.0",
+27 -8
View File
@@ -50,6 +50,9 @@ export async function run() {
print('Building dist workspace');
const workspaceDir = await buildDistWorkspace('workspace', rootDir);
// Otherwise yarn will refuse to install with CI=true
process.env.YARN_ENABLE_IMMUTABLE_INSTALLS = 'false';
print('Creating a Backstage App');
const appDir = await createApp('test-app', workspaceDir, rootDir);
@@ -172,7 +175,7 @@ async function buildDistWorkspace(workspaceName: string, rootDir: string) {
await pinYarnVersion(workspaceDir);
print('Installing workspace dependencies');
await runPlain(['yarn', 'install', '--production', '--frozen-lockfile'], {
await runPlain(['yarn', 'workspaces', 'focus', '--all', '--production'], {
cwd: workspaceDir,
});
@@ -183,20 +186,33 @@ async function buildDistWorkspace(workspaceName: string, rootDir: string) {
* Pin the yarn version in a directory to the one we're using in the Backstage repo
*/
async function pinYarnVersion(dir: string) {
const yarnRc = await fs.readFile(paths.resolveOwnRoot('.yarnrc'), 'utf8');
const yarnRc = await fs.readFile(paths.resolveOwnRoot('.yarnrc.yml'), 'utf8');
const yarnRcLines = yarnRc.split('\n');
const yarnPathLine = yarnRcLines.find(line => line.startsWith('yarn-path'));
const yarnPathLine = yarnRcLines.find(line => line.startsWith('yarnPath:'));
if (!yarnPathLine) {
throw new Error(`Unable to find 'yarn-path' in ${yarnRc}`);
throw new Error(`Unable to find 'yarnPath' in ${yarnRc}`);
}
const match = yarnPathLine.match(/"(.*)"/);
const match = yarnPathLine.match(/^yarnPath: (.*)$/);
if (!match) {
throw new Error(`Invalid 'yarn-path' in ${yarnRc}`);
throw new Error(`Invalid 'yarnPath' in ${yarnRc}`);
}
const [, localYarnPath] = match;
const yarnPath = paths.resolveOwnRoot(localYarnPath);
const yarnPluginPath = paths.resolveOwnRoot(
localYarnPath,
'../../plugins/@yarnpkg/plugin-workspace-tools.cjs',
);
await fs.writeFile(resolvePath(dir, '.yarnrc'), `yarn-path "${yarnPath}"\n`);
await fs.writeFile(
resolvePath(dir, '.yarnrc.yml'),
`yarnPath: ${yarnPath}
nodeLinker: node-modules
enableGlobalCache: true
plugins:
- path: ${yarnPluginPath}
spec: '@yarnpkg/plugin-workspace-tools'
`,
);
}
/**
@@ -342,7 +358,10 @@ async function createPlugin(
const pluginDir = resolvePath(appDir, 'plugins', canonicalName);
for (const cmd of [['tsc'], ['lint'], ['test', '--no-watch']]) {
print(`Running 'yarn tsc' in root for newly created plugin`);
await runPlain(['yarn', 'tsc'], { cwd: appDir });
for (const cmd of [['lint'], ['test', '--no-watch']]) {
print(`Running 'yarn ${cmd.join(' ')}' in newly created plugin`);
await runPlain(['yarn', ...cmd], { cwd: pluginDir });
}
+1 -1
View File
@@ -31,7 +31,7 @@ export function spawnPiped(cmd: string[], options?: SpawnOptions) {
return (data: Buffer) => {
const prefixedMsg = data
.toString('utf8')
.trimRight()
.trimEnd()
.replace(/^/gm, prefix);
stream.write(`${prefixedMsg}\n`, 'utf8');
};
-1
View File
@@ -5,7 +5,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
+2 -3
View File
@@ -5,7 +5,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -46,8 +45,8 @@
"@testing-library/user-event": "^14.0.0",
"@types/jest": "^26.0.7",
"@types/node": "^16.11.26",
"msw": "^0.45.0",
"cross-fetch": "^3.1.5"
"cross-fetch": "^3.1.5",
"msw": "^0.46.0"
},
"files": [
"dist"
+6 -7
View File
@@ -5,7 +5,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
@@ -35,12 +34,12 @@
"dependencies": {
"@backstage/config": "^1.0.1",
"@backstage/errors": "^1.1.0",
"cross-fetch": "^3.1.5",
"git-url-parse": "^12.0.0",
"@octokit/rest": "^19.0.3",
"@octokit/auth-app": "^4.0.0",
"luxon": "^3.0.0",
"lodash": "^4.17.21"
"@octokit/rest": "^19.0.3",
"cross-fetch": "^3.1.5",
"git-url-parse": "^13.0.0",
"lodash": "^4.17.21",
"luxon": "^3.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.19.0-next.1",
@@ -48,7 +47,7 @@
"@backstage/test-utils": "^1.2.0-next.1",
"@types/jest": "^26.0.7",
"@types/luxon": "^3.0.0",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist",
+2 -3
View File
@@ -2,7 +2,6 @@
"name": "@backstage/release-manifests",
"description": "Helper library for receiving release manifests",
"version": "0.0.6-next.0",
"private": false,
"main": "src/index.ts",
"types": "src/index.ts",
"publishConfig": {
@@ -37,9 +36,9 @@
},
"devDependencies": {
"@backstage/test-utils": "^1.2.0-next.1",
"msw": "^0.45.0",
"@types/jest": "^26.0.7",
"@types/node": "^16.0.0"
"@types/node": "^16.0.0",
"msw": "^0.46.0"
},
"files": [
"dist"
@@ -28,7 +28,7 @@ const executeCommand = (
stdout: string;
stderr: string;
}> => {
return new Promise(resolve => {
return new Promise((resolve, reject) => {
const stdout: Buffer[] = [];
const stderr: Buffer[] = [];
@@ -43,6 +43,7 @@ const executeCommand = (
stderr.push(Buffer.from(data));
});
proc.on('error', reject);
proc.on('exit', code => {
resolve({
exit: code ?? 0,
@@ -59,6 +60,7 @@ jest.setTimeout(timeout * 2);
describe('end-to-end', () => {
const cwd = path.resolve(__dirname, '../src/example-docs');
const entryPoint = path.resolve(__dirname, '../bin/techdocs-cli');
afterEach(async () => {
// On Windows the pid of a spawned process may be wrong
@@ -72,33 +74,24 @@ describe('end-to-end', () => {
}
});
beforeAll(() => {
execSync('yarn workspace @techdocs/cli link', { stdio: 'ignore' });
});
afterAll(() => {
execSync('yarn workspace @techdocs/cli unlink', { stdio: 'ignore' });
});
it('shows help text', async () => {
const proc = await executeCommand('techdocs-cli', ['--help']);
const proc = await executeCommand(entryPoint, ['--help']);
expect(proc.stdout).toContain('Usage: techdocs-cli [options]');
expect(proc.exit).toEqual(0);
});
it('can generate', async () => {
const proc = await executeCommand(
'techdocs-cli',
['generate', '--no-docker'],
{ cwd, timeout },
);
const proc = await executeCommand(entryPoint, ['generate', '--no-docker'], {
cwd,
timeout,
});
expect(proc.stdout).toContain('Successfully generated docs');
expect(proc.exit).toEqual(0);
});
it('can serve in mkdocs', async () => {
const proc = await executeCommand(
'techdocs-cli',
entryPoint,
['serve:mkdocs', '--no-docker'],
{ cwd, timeout },
);
@@ -108,11 +101,10 @@ describe('end-to-end', () => {
it('can serve in backstage', async () => {
jest.setTimeout(30000);
const proc = await executeCommand(
'techdocs-cli',
['serve', '--no-docker'],
{ cwd, timeout },
);
const proc = await executeCommand(entryPoint, ['serve', '--no-docker'], {
cwd,
timeout,
});
expect(proc.stdout).toContain('Starting mkdocs server');
expect(proc.stdout).toContain('Serving docs in Backstage at');
expect(proc.exit).toEqual(0);
-1
View File
@@ -2,7 +2,6 @@
"name": "@techdocs/cli",
"description": "Utility CLI for managing TechDocs sites in Backstage.",
"version": "1.2.1-next.0",
"private": false,
"publishConfig": {
"access": "public"
},
+1 -2
View File
@@ -2,7 +2,6 @@
"name": "@backstage/test-utils",
"description": "Utilities to test Backstage plugins and apps.",
"version": "1.2.0-next.1",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -58,7 +57,7 @@
"@backstage/cli": "^0.19.0-next.1",
"@types/jest": "^26.0.7",
"@types/node": "^16.11.26",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist"
-1
View File
@@ -2,7 +2,6 @@
"name": "@backstage/theme",
"description": "material-ui theme for use with Backstage.",
"version": "0.2.16",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
-2
View File
@@ -5,7 +5,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
@@ -32,7 +31,6 @@
"postpack": "backstage-cli package postpack",
"clean": "backstage-cli package clean"
},
"dependencies": {},
"devDependencies": {
"@backstage/cli": "^0.19.0-next.1",
"@types/zen-observable": "^0.8.0",
-1
View File
@@ -2,7 +2,6 @@
"name": "@backstage/version-bridge",
"description": "Utilities used by @backstage packages to support multiple concurrent versions",
"version": "1.0.1",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
+3 -4
View File
@@ -4,7 +4,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
@@ -39,16 +38,16 @@
"@backstage/plugin-search-common": "^1.0.1-next.0",
"luxon": "^3.0.0",
"marked": "^4.0.14",
"winston": "^3.2.1",
"node-fetch": "^2.6.5",
"winston": "^3.2.1",
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.19.0-next.1",
"@types/marked": "^4.0.0",
"@types/supertest": "^2.0.8",
"supertest": "^6.1.3",
"msw": "^0.45.0"
"msw": "^0.46.0",
"supertest": "^6.1.3"
},
"files": [
"dist"
-1
View File
@@ -5,7 +5,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
+2 -2
View File
@@ -34,7 +34,7 @@
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
"git-url-parse": "^12.0.0",
"git-url-parse": "^13.0.0",
"octokit": "^2.0.0",
"react-markdown": "^8.0.0",
"react-use": "^17.2.4",
@@ -56,7 +56,7 @@
"@types/jest": "*",
"@types/node": "*",
"cross-fetch": "^3.1.5",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist"
+2 -2
View File
@@ -25,8 +25,8 @@
"@backstage/backend-common": "^0.15.1-next.1",
"@backstage/config": "^1.0.1",
"@types/express": "*",
"express-promise-router": "^4.1.0",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"http-proxy-middleware": "^2.0.0",
"winston": "^3.2.1",
"yn": "^4.0.0"
@@ -35,7 +35,7 @@
"@backstage/cli": "^0.19.0-next.1",
"@types/http-proxy-middleware": "^0.19.3",
"@types/supertest": "^2.0.8",
"msw": "^0.45.0",
"msw": "^0.46.0",
"supertest": "^6.1.6"
},
"files": [
+1 -1
View File
@@ -52,7 +52,7 @@
"@types/node": "^16.11.26",
"@types/object-hash": "^2.2.1",
"cross-fetch": "^3.1.5",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist"
+1 -2
View File
@@ -5,7 +5,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -50,7 +49,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^16.11.26",
"cross-fetch": "^3.1.5",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist"
+1 -2
View File
@@ -4,7 +4,6 @@
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
@@ -48,7 +47,7 @@
"@types/jest": "^26.0.7",
"@types/node": "^16.11.26",
"cross-fetch": "^3.1.5",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist",
+1 -1
View File
@@ -45,7 +45,7 @@
"@testing-library/user-event": "^14.0.0",
"@types/jest": "^26.0.7",
"@types/node": "^16.11.26",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist",
+1 -1
View File
@@ -68,7 +68,7 @@
"@types/node": "^16.11.26",
"@types/swagger-ui-react": "^4.1.1",
"cross-fetch": "^3.1.5",
"msw": "^0.45.0"
"msw": "^0.46.0"
},
"files": [
"dist"
+3 -3
View File
@@ -22,6 +22,7 @@
"postpack": "backstage-cli package postpack"
},
"dependencies": {
"@apollo/explorer": "^1.1.1",
"@backstage/core-components": "^0.11.1-next.1",
"@backstage/core-plugin-api": "^1.0.6-next.1",
"@backstage/theme": "^0.2.16",
@@ -29,7 +30,6 @@
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^4.0.0-alpha.57",
"react-use": "^17.2.4",
"@apollo/explorer": "^1.1.1",
"use-deep-compare-effect": "^1.8.1"
},
"peerDependencies": {
@@ -45,8 +45,8 @@
"@testing-library/user-event": "^14.0.0",
"@types/jest": "*",
"@types/node": "*",
"msw": "^0.45.0",
"cross-fetch": "^3.1.5"
"cross-fetch": "^3.1.5",
"msw": "^0.46.0"
},
"files": [
"dist"

Some files were not shown because too many files have changed in this diff Show More