docs/releases/v1.1.0-changelog.md
bdd2773202: Refactored the internal TaskWorker class to make it easier to test.
a83babdd63: Fixed the initialDelay parameter of tasks to properly make task workers
always wait before the first invocations on startup, not just the very first
time that the task is ever created. This behavior is more in line with
expectations. Callers to not need to update their code.
Also clarified in the doc comment for the field that this wait applies only on an individual worker level. That is, if you have a cluster of workers then each individual machine may postpone its first task invocation by the given amount of time to leave room for the service to settle, but other workers may still continue to invoke the task on the regular cadence in the meantime.
Updated dependencies
1f7d4763ab: BREAKING: Bump the version range of jest from ^26.0.1 to ^27.5.1. You can find the complete list of breaking changes here.
We strongly recommend to have completed the package role migration before upgrading to this version, as the package roles are used to automatically determine the testing environment for each package. If you instead want to set an explicit test environment for each package, you can do so for example in the "jest" section in package.json. The default test environment for all packages is now node, which is also the new Jest default.
Note that one of the breaking changes of Jest 27 is that the jsdom environment no longer includes setImmediate and clearImmediate, which means you might need to update some of your frontend packages. Another notable change is that jest.useFakeTimers now defaults to the 'modern' implementation, which also mocks microtasks.
e80ecad93c: Bump the rushstack api generator libraries to their latest versions
c54ce828bd: build(deps): bump eslint-plugin-jest from 25.3.4 to 26.1.2
f151dfee5a: build(deps): bump eslint-webpack-plugin from 2.6.0 to 3.1.1
7e7ba704be: build(deps): bump @spotify/eslint-config-base from 12.0.0 to 13.0.0
ecd72391fb: build(deps): bump @spotify/eslint-config-typescript
6a341b2d87: build(deps): bump @spotify/eslint-config-react from 12.0.0 to 13.0.0
3c26b2edb5: build(deps): bump npm-packlist from 3.0.0 to 5.0.0
ed3551b7be: Introduced a new experimental test configuration with a number of changes. It switches the coverage provider from v8 to the default Babel provider, along with always enabling source maps in the Sucrase transform. It also adds a custom module loader that caches both file transforms and VM script objects across all projects in a test run, which provides a big performance boost when running tests from the project root, increasing speed and reducing memory usage.
This new configuration is not enabled by default. It is enabled by setting the environment variable BACKSTAGE_NEXT_TESTS to a non-empty value.
6ad0c45648: Added an experimental package fix command which applies automated fixes to the target package. The initial fix that is available is to add missing monorepo dependencies to the target package.
5b3079694e: Stop logging "Stopped watcher" when shutting down the development backend.
f512554910: Updated the plugin template to install version 14 of @testing-library/user-event.
To apply this change to your own project, update the devDependencies section in your package.json files:
"devDependencies": {
... omitted dev dependencies ...
- "@testing-library/user-event": "^13.1.8",
+ "@testing-library/user-event": "^14.0.0",
... omitted dev dependencies ...
}
df7862cfa6: Fixed a bug were the react-hot-loader transform was being applied to backend development builds.
230ad0826f: Bump to using @types/node v16
c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values.
948a56f401: Added a new experimental repo list-deprecations command, which scans the entire project for usage of deprecated APIs.
4782f9e925: Fixed misleading log message during frontend plugin creation.
0383cd0228: The versions:* commands no longer warns about duplicate plugin libraries, such as @backstage/plugin-catalog-common.
Updated dependencies
ignoreSchemaErrors to schema.process.ajv from 7.0.3 to 8.10.0@types/node v161691c6c5c2: Clarify that config locations that emit User and Group kinds now need to declare so in the catalog.locations.[].rules
3ef123bbf0: Support external ID when assuming roles in S3 integration
In order to assume a role created by a 3rd party as external ID is needed. This change adds an optional field to the s3 integration configuration and consumes that in the AwsS3UrlReader.
d26e1b0146: Exported replaceGitLabUrlType from package
733187987b: Removed an undocumented, broken behavior where README.md files would be copied to index.md if it did not exist, leading to broken links in the TechDocs UI.
WARNING: If you notice 404s in TechDocs after updating, check to make sure that all markdown files referenced in your mkdocs.ymls' nav sections exist. The following flag may be passed to the generate command to temporarily revert to the broken behavior.
techdocs-cli generate --legacyCopyReadmeMdToIndexMd
@types/node v16token in their sign-in result. Returning an id is no longer supported.c5aeaf339d: DEPRECATION: The AuthProviderFactoryOptions type has been deprecated, as the options are now instead inlined in the AuthProviderFactory type. This will make it possible to more easily introduce new options in the future without a possibly breaking change.
794f7542b6: Updated openid-client from 4.1.2 to 5.1.3
c5aeaf339d: DEPRECATION: The getEntityClaims helper has been deprecated, with getDefaultOwnershipEntityRefs being added to replace it.
de231e5b06: Declare oauth2 clientSecret with visibility secret
c5aeaf339d: DEPRECATION: All create<Provider>Provider and <provider>*SignInResolver have been deprecated. Instead, a single providers object is exported which contains all built-in auth providers.
If you have a setup that currently looks for example like this:
import {
createRouter,
defaultAuthProviderFactories,
createGoogleProvider,
googleEmailSignInResolver,
} from '@backstage/plugin-auth-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({
...env,
providerFactories: {
...defaultAuthProviderFactories,
google: createGoogleProvider({
signIn: {
resolver: googleEmailSignInResolver,
},
}),
},
});
}
You would migrate it to something like this:
import {
createRouter,
providers,
defaultAuthProviderFactories,
} from '@backstage/plugin-auth-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({
...env,
providerFactories: {
...defaultAuthProviderFactories,
google: providers.google.create({
signIn: {
resolver:
providers.google.resolvers.emailMatchingUserEntityAnnotation(),
},
}),
},
});
}
2cc1d1b235: Applied the fix from version 0.12.3 of this package, which is part of the v1.0.1 release of Backstage.
c5aeaf339d: DEPRECATION The AuthResolverContext has received a number of changes, which is the context used by auth handlers and sign-in resolvers.
The following fields deprecated: logger, tokenIssuer, catalogIdentityClient. If you need to access the logger, you can do so through a closure instead. The tokenIssuer has been replaced with an issueToken method, which is available directory on the context. The catalogIdentityClient has been replaced by the signInWithCatalogUser method, as well as the lower level findCatalogUser method and getDefaultOwnershipEntityRefs helper.
It should be possible to migrate most sign-in resolvers to more or less only use signInWithCatalogUser, for example an email lookup resolver like this one:
async ({ profile }, ctx) => {
if (!profile.email) {
throw new Error('Profile contained no email');
}
const entity = await ctx.catalogIdentityClient.findUser({
annotations: {
'acme.org/email': profile.email,
},
});
const claims = getEntityClaims(entity);
const token = await ctx.tokenIssuer.issueToken({ claims });
return { id: entity.metadata.name, entity, token };
};
can be migrated to the following:
async ({ profile }, ctx) => {
if (!profile.email) {
throw new Error('Profile contained no email');
}
return ctx.signInWithCatalogUser({
annotations: {
'acme.org/email': profile.email,
},
});
};
While a direct entity name lookup using a user ID might look like this:
async ({ result: { fullProfile } }, ctx) => {
return ctx.signInWithCatalogUser({
entityRef: {
name: fullProfile.userId,
},
});
};
If you want more control over the way that users are looked up, ownership is assigned, or tokens are issued, you can use a combination of the findCatalogUser, getDefaultOwnershipEntityRefs, and issueToken instead.
f4cdf4cac1: Defensively encode URL parameters when fetching ELB keys
6ee04078e1: DEPRECATION: The tokenIssuer option for OAuthAdapter is no longer needed and has been deprecated.
a45bce06e3: Handle trailing slashes on GitHub enterpriseInstanceUrl settings
45f7a261c7: Bumped passport-microsoft to resolve CVE-2021-41580
c5aeaf339d: Added exports of the following types: AuthProviderConfig, StateEncoder, TokenParams, AwsAlbResult.
Updated dependencies
id and entity fields from BackstageSignInResult.@testing-library/user-event from 13.5.0 to 14.0.08012ac46a0: BREAKING (alpha api): Replace createCatalogPolicyDecision export with createCatalogConditionalDecision, which accepts a permission parameter of type ResourcePermission<'catalog-entity'> along with conditions. The permission passed is expected to be the handled permission in PermissionPolicy#handle, whose type must first be narrowed using methods like isPermission and isResourcePermission:
class TestPermissionPolicy implements PermissionPolicy {
async handle(
request: PolicyQuery<Permission>,
_user?: BackstageIdentityResponse,
): Promise<PolicyDecision> {
if (
// Narrow type of `request.permission` to `ResourcePermission<'catalog-entity'>
isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)
) {
return createCatalogConditionalDecision(
request.permission,
catalogConditions.isEntityOwner(
_user?.identity.ownershipEntityRefs ?? [],
),
);
}
return {
result: AuthorizeResult.ALLOW,
};
8012ac46a0: BREAKING: Mark CatalogBuilder#addPermissionRules as @alpha.
fb02d2d94d: export locationSpecToLocationEntity
bf82edf4c9: Added /validate-entity endpoint
ada4446733: Specify type of visibilityPermission property on collators and collator factories.
1691c6c5c2: Clarify that config locations that emit User and Group kinds now need to declare so in the catalog.locations.[].rules
8592cacfd3: Fixed an issue where sometimes entities would have stale relations "stuck" and not getting removed as expected, after the other end of the relation had stopped referring to them.
23646e51a5: Use new PermissionEvaluator#authorizeConditional method when retrieving permission conditions.
9fe24b0fc8: Adjust the error messages when entities fail validation, to clearly state what entity that failed it
48405ed232: Added spec.profile.displayName to search index for Group kinds
95408dbe99: Enable internal batching of very large deletions, to not run into SQL binding limits
8012ac46a0: Handle changes to @alpha permission-related types.
resourceType.createCatalogConditionalDecision now expects supplied conditions to have the appropriate resourceType.createCatalogPermissionRule now expects resourceType as part of the supplied rule object.CatalogPermissionRule convenience type.ffec894ed0: add gitlab to AnnotateScmSlugEntityProcessor
Updated dependencies
README.md in the cicd-statistics-module-gitlab plugin folder on how to set it up.@testing-library/user-event from 13.5.0 to 14.0.0@types/node v163d45427666: BREAKING Custom cluster suppliers need to cache their getClusters result
To allow custom KubernetesClustersSupplier instances to refresh the list of clusters
the getClusters method is now called whenever the list of clusters is needed.
Existing KubernetesClustersSupplier implementations will need to ensure that getClusters
can be called frequently and should return a cached result from getClusters instead.
For example, here's a simple example of a custom supplier in packages/backend/src/plugins/kubernetes.ts:
-import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';
+import {
+ ClusterDetails,
+ KubernetesBuilder,
+ KubernetesClustersSupplier,
+} from '@backstage/plugin-kubernetes-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
+import { Duration } from 'luxon';
+
+export class CustomClustersSupplier implements KubernetesClustersSupplier {
+ constructor(private clusterDetails: ClusterDetails[] = []) {}
+
+ static create(refreshInterval: Duration) {
+ const clusterSupplier = new CustomClustersSupplier();
+ // setup refresh, e.g. using a copy of https://github.com/backstage/backstage/blob/master/plugins/search-backend-node/src/runPeriodically.ts
+ runPeriodically(
+ () => clusterSupplier.refreshClusters(),
+ refreshInterval.toMillis(),
+ );
+ return clusterSupplier;
+ }
+
+ async refreshClusters(): Promise<void> {
+ this.clusterDetails = []; // fetch from somewhere
+ }
+
+ async getClusters(): Promise<ClusterDetails[]> {
+ return this.clusterDetails;
+ }
+}
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
- const { router } = await KubernetesBuilder.createBuilder({
+ const builder = await KubernetesBuilder.createBuilder({
logger: env.logger,
config: env.config,
- }).build();
+ });
+ builder.setClusterSupplier(
+ CustomClustersSupplier.create(Duration.fromObject({ minutes: 60 })),
+ );
+ const { router } = await builder.build();
backstage.io/kubernetes-namespace to allow namespaced Kubernetes resources fetches8012ac46a0: Add resourceType property to PermissionCondition type to allow matching them with ResourcePermission instances.
c98d271466: Refactor api types into more specific, decoupled names.
AuthorizeDecision to EvaluatePermissionResponseAuthorizeQuery to EvaluatePermissionRequestAuthorizeRequest to EvaluatePermissionRequestBatchAuthorizeResponse to EvaluatePermissionResponseBatchIdentified to IdentifiedPermissionMessagePermissionMessageBatch helper typeConditionalPolicyDecision, DefinitivePolicyDecision, and PolicyDecision types from @backstage/plugin-permission-node90754d4fa9: Removed strict validation from PermissionCriteria schemas to support backward-compatible changes.
2b07063d77: Added PermissionEvaluator, which will replace the existing PermissionAuthorizer interface. This new interface provides stronger type safety and validation by splitting PermissionAuthorizer.authorize() into two methods:
authorize(): Used when the caller requires a definitive decision.authorizeConditional(): Used when the caller can optimize the evaluation of any conditional decisions. For example, a plugin backend may want to use conditions in a database query instead of evaluating each resource in memory.8012ac46a0: Add isPermission helper method.
95284162d6: - Add more specific Permission types.
createPermission helper to infer the appropriate type for some permission input.isResourcePermission helper to refine Permissions to ResourcePermissions.8012ac46a0: BREAKING: Stronger typing in PermissionPolicy 🎉.
Previously, it was entirely the responsibility of the PermissionPolicy author to only return CONDITIONAL decisions for permissions that are associated with a resource, and to return the correct kind of PermissionCondition instances inside the decision. Now, the policy authoring helpers provided in this package now ensure that the decision and permission match.
For policy authors: rename and adjust api of createConditionExports. Previously, the function returned a factory for creating conditional decisions named createPolicyDecision, which had a couple of drawbacks:
PermissionPolicy#handle for resource permissions, but there was nothing in the API that encoded this constraint.This change addresses the drawbacks above by making the following changes for policy authors:
createPolicyDecision method has been renamed to createConditionalDecision.ResourcePermission. This is expected to be the handled permission in PermissionPolicy#handle, whose type must first be narrowed using methods like isPermission and isResourcePermission:class TestPermissionPolicy implements PermissionPolicy {
async handle(
request: PolicyQuery<Permission>,
_user?: BackstageIdentityResponse,
): Promise<PolicyDecision> {
if (
// Narrow type of `request.permission` to `ResourcePermission<'catalog-entity'>
isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)
) {
return createCatalogConditionalDecision(
request.permission,
catalogConditions.isEntityOwner(
_user?.identity.ownershipEntityRefs ?? [],
),
);
}
return {
result: AuthorizeResult.ALLOW,
};
BREAKING: when creating PermissionRules, provide a resourceType.
export const isEntityOwner = createCatalogPermissionRule({
name: 'IS_ENTITY_OWNER',
description: 'Allow entities owned by the current user',
+ resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
apply: (resource: Entity, claims: string[]) => {
if (!resource.relations) {
return false;
}
return resource.relations
.filter(relation => relation.type === RELATION_OWNED_BY)
.some(relation => claims.includes(relation.targetRef));
},
toQuery: (claims: string[]) => ({
key: 'relations.ownedBy',
values: claims,
}),
});
c98d271466: BREAKING:
PolicyAuthorizeQuery to PolicyQueryPolicyDecision, DefinitivePolicyDecision, and ConditionalPolicyDecision. These types are now exported from @backstage/plugin-permission-common322b69e46a: BREAKING: ServerPermissionClient now implements PermissionEvaluator, which moves out the capabilities for evaluating conditional decisions from authorize() to authorizeConditional() method.
PermissionCriteria schemas to support backward-compatible changes.usePermission hook and PermissionedRoute component. It's no longer possible to pass a resourceRef unless the permission is of type ResourcePermission.@backstage/plugin-permission-commonIdentityPermissionApi#authorize typing more strict, using AuthorizePermissionRequest and AuthorizePermissionResponse.contextMenu prop of the scaffolder page./edit path instead. There is a redirect in place from /preview.@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16NextScaffolderRouter which will eventually replace the exiting routerusePermission usage.draft option to the publish:github:pull-request action.isbinaryfile from 4.0.8 to 5.0.0@gitbeaker/core from 34.6.0 to 35.6.0520e21aaea: The following exports has now been fully deleted from this package and can be import from @backstage/plugin-search-react instead.
SearchApi interface.
searchApiRef
SearchContextProvider
useSearch
SearchContext has now been fully deleted from this package and is no longer exported publicly. Use SearchContextProvider when access to the context is needed.
7c7919777e: build(deps-dev): bump @testing-library/react-hooks from 7.0.2 to 8.0.0
24254fd433: build(deps): bump @testing-library/user-event from 13.5.0 to 14.0.0
5c062f275e: Support customizing the content of the SidebarSearchModal
38e01f2f70: Switch to SearchDocument type in DefaultResultListItem props
230ad0826f: Bump to using @types/node v16
ab230a433f: The following exports has been moved to @backstage/plugin-search-react and will be removed in the next release. import from @backstage/plugin-search-react instead.
SearchApi interface.searchApiRefSearchContextSearchContextProvideruseSearchUpdated dependencies
authorization property is no longer returned on search results when queried. Note: this will only result in a breaking change if you have custom code in your frontend that relies on the authorization.resourceRef property on documents.PermissionEvaluator instead of PermissionAuthorizer, which is now deprecated.IndexableResultSet type as return type of query method in SearchEngine implementation.@backstage/plugin-permission-common0a63e99a26: BREAKING: IndexBuilder.addCollator() now requires a schedule parameter (replacing defaultRefreshIntervalSeconds) which is expected to be a TaskRunner that is configured with the desired search indexing schedule for the given collator.
Scheduler.addToSchedule() now takes a new parameter object (ScheduleTaskParameters) with two new options id and scheduledRunner in addition to the migrated task argument.
NOTE: The search backend plugin now creates a dedicated database for coordinating indexing tasks.
To make this change to an existing app, make the following changes to packages/backend/src/plugins/search.ts:
+import { Duration } from 'luxon';
/* ... */
+ const schedule = env.scheduler.createScheduledTaskRunner({
+ frequency: Duration.fromObject({ minutes: 10 }),
+ timeout: Duration.fromObject({ minutes: 15 }),
+ initialDelay: Duration.fromObject({ seconds: 3 }),
+ });
indexBuilder.addCollator({
- defaultRefreshIntervalSeconds: 600,
+ schedule,
factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {
discovery: env.discovery,
tokenManager: env.tokenManager,
}),
});
indexBuilder.addCollator({
- defaultRefreshIntervalSeconds: 600,
+ schedule,
factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
discovery: env.discovery,
tokenManager: env.tokenManager,
}),
});
const { scheduler } = await indexBuilder.build();
- setTimeout(() => scheduler.start(), 3000);
+ scheduler.start();
/* ... */
NOTE: For scenarios where the lunr search engine is used in a multi-node configuration, a non-distributed TaskRunner like the following should be implemented to ensure consistency across nodes (alternatively, you can configure
the search plugin to use a non-distributed DB such as SQLite):
+import { TaskInvocationDefinition, TaskRunner } from '@backstage/backend-tasks';
/* ... */
+ const schedule: TaskRunner = {
+ run: async (task: TaskInvocationDefinition) => {
+ const startRefresh = async () => {
+ while (!task.signal?.aborted) {
+ try {
+ await task.fn(task.signal);
+ } catch {
+ // ignore intentionally
+ }
+
+ await new Promise(resolve => setTimeout(resolve, 600 * 1000));
+ }
+ };
+ startRefresh();
+ },
+ };
indexBuilder.addCollator({
- defaultRefreshIntervalSeconds: 600,
+ schedule,
factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {
discovery: env.discovery,
tokenManager: env.tokenManager,
}),
});
/* ... */
IndexableResultSet type as return type of query method in SearchEngine implementation.@types/node v167c7919777e: build(deps-dev): bump @testing-library/react-hooks from 7.0.2 to 8.0.0
076b091113: api-report clean up - the package now exports following additional types:
SearchContextProviderProps
SearchContextValue
SearchContextProviderForStorybookProps
SearchApiProviderForStorybookProps
e1de8526aa: Versioned search context managed through version-bridge
Updated dependencies
@testing-library/user-event from 13.5.0 to 14.0.0@types/node v1624254fd433: build(deps): bump @testing-library/user-event from 13.5.0 to 14.0.0
230ad0826f: Bump to using @types/node v16
2fe58c7285: Improved the Tech-Insights documentation:
lifecycle examples used ttl when it should be timeToLiveUpdated dependencies
231fee736b: This backend now uses the @backstage/backend-tasks package facilities for scheduling fact retrievers.
BREAKING: The buildTechInsightsContext function now takes an additional field in its options argument: scheduler. This is an instance of PluginTaskScheduler, which can be found in your backend initialization code's env.
const builder = buildTechInsightsContext({
logger: env.logger,
config: env.config,
database: env.database,
discovery: env.discovery,
+ scheduler: env.scheduler,
factRetrievers: [ /* ... */ ],
});
21de525ce9: Updated README.md with better install instructions
c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values.
2fe58c7285: Improved the Tech-Insights documentation:
lifecycle examples used ttl when it should be timeToLiveUpdated dependencies
ace749b785: TechDocs supports a new, experimental method of customization: addons!
To customize the standalone TechDocs reader page experience, update your /packages/app/src/App.tsx in the following way:
import { TechDocsIndexPage, TechDocsReaderPage } from '@backstage/plugin-techdocs';
+ import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
+ import { SomeAddon } from '@backstage/plugin-some-plugin';
// ...
<Route path="/docs" element={<TechDocsIndexPage />} />
<Route
path="/docs/:namespace/:kind/:name/*"
element={<TechDocsReaderPage />}
>
+ <TechDocsAddons>
+ <SomeAddon />
+ </TechDocsAddons>
</Route>
// ...
To customize the TechDocs reader experience on the Catalog entity page, update your packages/app/src/components/catalog/EntityPage.tsx in the following way:
import { EntityTechdocsContent } from '@backstage/plugin-techdocs';
+ import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
+ import { SomeAddon } from '@backstage/plugin-some-plugin';
// ...
<EntityLayoutWrapper>
<EntityLayout.Route path="/" title="Overview">
{overviewContent}
</EntityLayout.Route>
<EntityLayout.Route path="/docs" title="Docs">
- <EntityTechDocsContent />
+ <EntityTechdocsContent>
+ <TechDocsAddons>
+ <SomeAddon />
+ </TechDocsAddons>
+ </EntityTechdocsContent>
</EntityLayout.Route>
</EntityLayoutWrapper>
// ...
If you do not wish to customize your TechDocs reader experience in this way at this time, no changes are necessary!
ab230a433f: imports from @backstage/plugin-search-react instead of @backstage/plugin-search
7c7919777e: build(deps-dev): bump @testing-library/react-hooks from 7.0.2 to 8.0.0
24254fd433: build(deps): bump @testing-library/user-event from 13.5.0 to 14.0.0
230ad0826f: Bump to using @types/node v16
f0fb9153b7: Fix broken query selectors on techdocs
9975ff9852: Applied the fix from version 1.0.1 of this package, which is part of the v1.0.2 release of Backstage.
3ba256c389: Fixed a bug preventing custom TechDocs reader page implementations from rendering without being double-wrapped in the <TechDocsReaderPage /> component.
fe53fe97d7: Fix permalink scrolling for anchors where the id starts with a number.
0152c0de22: Some documentation layout tweaks:
3ba256c389: Fixed a bug that caused addons in the Subheader location to break the default TechDocs reader page layout.
Updated dependencies
733187987b: Removed an undocumented, broken behavior where README.md files would be copied to index.md if it did not exist, leading to broken links in the TechDocs UI.
WARNING: If you notice 404s in TechDocs after updating, check to make sure that all markdown files referenced in your mkdocs.ymls' nav sections exist. The following configuration may be used to temporarily revert to the broken behavior.
techdocs:
generator:
mkdocs:
legacyCopyReadmeMdToIndexMd: true
visibilityPermission property on collators and collator factories.HEAD request, rather than a GET request.README.md files would be copied to index.md if it did not exist, leading to broken links in the TechDocs UI.v1.0.2.ff1cc8bced: This package will house frontend utilities related to TechDocs to be shared across other frontend Backstage packages.
In this release, it introduces a framework that can be used create TechDocs addons.
Note: this package is not necessarily stable yet. After iteration on this package, its stability will be signaled by a major-version bump.
@testing-library/react-hooks from 7.0.2 to 8.0.0@types/node v1619f6c6c32a: The backend will no longer fail to start up when configured secrets do not match the configuration schema.
b7436743cb: Added the GerritUrlReader that implements "readUrl".
3ef123bbf0: Support external ID when assuming roles in S3 integration
In order to assume a role created by a 3rd party as external ID is needed. This change adds an optional field to the s3 integration configuration and consumes that in the AwsS3UrlReader.
bae9359032: The logger returned from getVoidLogger is now uses a silenced console transport instead.
3ff0e79654: Tweaked the UrlReader multiplexer so that it uses the more helpful NotAllowedError messaging for all methods.
12608f8ba8: Add @types/webpack-env to dependencies.
f9f512559b: Updated the visibility of database connection fields in config to be secret
Updated dependencies
TestDatabases.create will no longer set up an afterAll test handler if no databases are supported.e0a51384ac: build(deps): bump ajv from 7.0.3 to 8.10.0
c12f8374d1: Added a connection between www-artist and artist-lookup components
<details> <summary>Screenshots</summary> </details>@types/node v16@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16IdentityProviders type.<Sidebar /> now accepts additional props sidebarOptions and submenuOptions to allow further customization@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v161691c6c5c2: Made User and Group entity kinds not permitted by the default
catalog.rules config.
The effect of this is that after creating a new Backstage repository, its
catalog no longer permits regular users to register User or Group entities
using the Backstage interface. Additionally, if you have config locations that
result in User or Group entities, you need to add those kinds to its own
specific rules:
catalog:
locations:
# This applies for example to url type locations
- type: url
target: https://example.com/org.yaml
rules:
- allow: [User, Group]
# But also note that this applies to ALL org location types!
- type: github-org
target: https://github.com/my-org-name
rules:
- allow: [User, Group]
This rule change does NOT affect entity providers, only things that are emitted by entity processors.
We recommend that this change is applied to your own Backstage repository, since it makes it impossible for regular end users to affect your org data through e.g. YAML files. To do so, remove the two kinds from the default rules in your config:
catalog:
rules:
- - allow: [Component, System, API, Group, User, Resource, Location]
+ - allow: [Component, System, API, Resource, Location]
And for any location that in any way results in org data being ingested, add the corresponding rule to it:
catalog:
locations:
- type: github-org
target: https://github.com/my-org-name
+ rules:
+ - allow: [User, Group]
0e911394d2: Remove the knex package that is installed in the packages/backend as it's provided by the @backstage/* packages for you automatically. You can make the following change in your packages/backend/package.json if you wish to apply this change.
"lint": "backstage-cli package lint",
"test": "backstage-cli package test",
"clean": "backstage-cli package clean",
- "migrate:create": "knex migrate:make -x ts"
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
- "knex": "^0.21.6",
"pg": "^8.3.0",
520e21aaea: imports useSearch hook from new @backstage/plugin-search-react package.
To upgrade existing Apps:
packages/app/src/components/search/SearchPage.tsx
import {
...
SearchType,
- useSearch,
} from '@backstage/plugin-search';
+import { useSearch } from '@backstage/plugin-search-react';
@backstage/plugin-search-react as a dependency to the app.43759dd789: Removed @octokit/rest and @gitbeaker/node from backend dependencies as these are unused in the default app.
To apply these changes to your existing app, remove the following lines from the dependencies section of packages/backend/package.json
"@backstage/plugin-techdocs-backend": "^1.0.0",
- "@gitbeaker/node": "^34.6.0",
- "@octokit/rest": "^18.5.3",
e838a7060a: Add type resolutions for @types/react and types/react-dom.
The reason for this is the usage of "@types/react": "*" as a dependency which is very common practice in react packages. This recently resolves to react 18 which introduces several breaking changes in both internal and external packages.
To apply these changes to your existing installation, add a resolutions block to your package.json
"resolutions": {
"@types/react": "^17",
"@types/react-dom": "^17"
},
If your existing app depends on react 16, use this resolution block instead.
"resolutions": {
"@types/react": "^16",
"@types/react-dom": "^16"
},
0a63e99a26: BREAKING: IndexBuilder.addCollator() now requires a schedule parameter (replacing defaultRefreshIntervalSeconds) which is expected to be a TaskRunner that is configured with the desired search indexing schedule for the given collator.
Scheduler.addToSchedule() now takes a new parameter object (ScheduleTaskParameters) with two new options id and scheduledRunner in addition to the migrated task argument.
NOTE: The search backend plugin now creates a dedicated database for coordinating indexing tasks.
To make this change to an existing app, make the following changes to packages/backend/src/plugins/search.ts:
+import { Duration } from 'luxon';
/* ... */
+ const schedule = env.scheduler.createScheduledTaskRunner({
+ frequency: Duration.fromObject({ minutes: 10 }),
+ timeout: Duration.fromObject({ minutes: 15 }),
+ initialDelay: Duration.fromObject({ seconds: 3 }),
+ });
indexBuilder.addCollator({
- defaultRefreshIntervalSeconds: 600,
+ schedule,
factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {
discovery: env.discovery,
tokenManager: env.tokenManager,
}),
});
indexBuilder.addCollator({
- defaultRefreshIntervalSeconds: 600,
+ schedule,
factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
discovery: env.discovery,
tokenManager: env.tokenManager,
}),
});
const { scheduler } = await indexBuilder.build();
- setTimeout(() => scheduler.start(), 3000);
+ scheduler.start();
/* ... */
NOTE: For scenarios where the lunr search engine is used in a multi-node configuration, a non-distributed TaskRunner like the following should be implemented to ensure consistency across nodes (alternatively, you can configure
the search plugin to use a non-distributed DB such as SQLite):
+import { TaskInvocationDefinition, TaskRunner } from '@backstage/backend-tasks';
/* ... */
+ const schedule: TaskRunner = {
+ run: async (task: TaskInvocationDefinition) => {
+ const startRefresh = async () => {
+ while (!task.signal?.aborted) {
+ try {
+ await task.fn(task.signal);
+ } catch {
+ // ignore intentionally
+ }
+
+ await new Promise(resolve => setTimeout(resolve, 600 * 1000));
+ }
+ };
+ startRefresh();
+ },
+ };
indexBuilder.addCollator({
- defaultRefreshIntervalSeconds: 600,
+ schedule,
factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {
discovery: env.discovery,
tokenManager: env.tokenManager,
}),
});
/* ... */
c07d9f9e1c: Add helpful README.md files in the original packages and plugins folders
230ad0826f: Bump to using @types/node v16
1882dbda2b: Accept PermissionEvaluator instead of the deprecated PermissionAuthorizer.
Apply the following to packages/backend/src/types.ts:
- import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
+ import { PermissionEvaluator } from '@backstage/plugin-permission-common';
export type PluginEnvironment = {
...
discovery: PluginEndpointDiscovery;
tokenManager: TokenManager;
scheduler: PluginTaskScheduler;
- permissions: PermissionAuthorizer;
+ permissions: PermissionEvaluator;
};
e80cca164d: Tweaked .eslintrc.js files in the template to avoid having them apply during development. This change does not affect create apps.
@testing-library/user-event from 13.5.0 to 14.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@backstage/plugin-permission-common@types/node v16@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@asyncapi/react-component@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16DefaultBadgeBuilder.getMarkdownCode@testing-library/user-event from 13.5.0 to 14.0.0@types/node v165969c4b65c: Add a new provider AwsS3EntityProvider as replacement for AwsS3DiscoveryProcessor.
In order to migrate from the AwsS3DiscoveryProcessor you need to apply
the following changes:
Before:
# app-config.yaml
catalog:
locations:
- type: s3-discovery
target: https://sample-bucket.s3.us-east-2.amazonaws.com/prefix/
/* packages/backend/src/plugins/catalog.ts */
import { AwsS3DiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-aws';
const builder = await CatalogBuilder.create(env);
/** ... other processors ... */
builder.addProcessor(new AwsS3DiscoveryProcessor(env.reader));
After:
# app-config.yaml
catalog:
providers:
awsS3:
yourProviderId: # identifies your dataset / provider independent of config changes
bucketName: sample-bucket
prefix: prefix/ # optional
region: us-east-2 # optional, uses the default region otherwise
/* packages/backend/src/plugins/catalog.ts */
import { AwsS3EntityProvider } from '@backstage/plugin-catalog-backend-module-aws';
const builder = await CatalogBuilder.create(env);
/** ... other processors and/or providers ... */
builder.addEntityProvider(
...AwsS3EntityProvider.fromConfig(env.config, {
logger: env.logger,
schedule: env.scheduler.createScheduledTaskRunner({
frequency: Duration.fromObject({ minutes: 30 }),
timeout: Duration.fromObject({ minutes: 3 }),
}),
}),
);
For simple setups, you can omit the provider ID at the config
which has the same effect as using default for it.
# app-config.yaml
catalog:
providers:
awsS3:
# uses "default" as provider ID
bucketName: sample-bucket
prefix: prefix/ # optional
region: us-east-2 # optional, uses the default region otherwise
776a91ea3a: Corrected title and URL to setup documentation in README
Updated dependencies
catalog.locations.[].rulesgroupSelect which allow the client to fetch defined fields from the ms-graph api.createPermission helper when creating permissions.@alpha CatalogEntityPermission convenience type, available for import from @backstage/plugin-catalog-common/alpha.@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.00ffd88a90e: Prevent permissions with types other than ResourcePermission<'catalog-entity'> from being used with the useEntityPermission hook.
7c7919777e: build(deps-dev): bump @testing-library/react-hooks from 7.0.2 to 8.0.0
24254fd433: build(deps): bump @testing-library/user-event from 13.5.0 to 14.0.0
4af82967f4: Decouple tags picker from backend entities
EntityTagPicker fetches all the tags independently and it doesn't require all the entities to be available client side.
4be0d1e777: Changed catalog filter components to only pay attention to query parameters relevant to the component.
5d5fdbe541: Columns in CatalogTable now change depending on the entity kind, ensuring only relevant columns are displayed.
863e7bcb7b: Updated the "unregister location" behavior in UnregisterEntityDialog. Removed unnecessary entity deletion requests that were sent after successfully deleting a location.
37b04b5a5e: Removed broken link from Labels section of entity inspector.
a496cee4d1: Add support for string refs to the EntityRefLinks component
d34900af81: Added a new NextScaffolderRouter which will eventually replace the exiting router
99063c39ae: Minor API report cleanup
4431873583: Update usePermission usage.
Updated dependencies
@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16ab230a433f: Export template logos TemplateBackstageLogo and TemplateBackstageLogoIcon from package.
24254fd433: build(deps): bump @testing-library/user-event from 13.5.0 to 14.0.0
ac323de4ad: - Adds new HomePageStackOverflowQuestions component which renders a list of stack overflow questions on your homepage.
ComponentRenderer type.230ad0826f: Bump to using @types/node v16
9b58775849: Updated the dependency on @backstage/config to ^1.0.0.
99063c39ae: Minor API report cleanup
Updated dependencies
@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16PermissionEvaluator instead of PermissionAuthorizer, which is now deprecated.resourceRef required in JenkinsApi to match usage.createPermission helper when creating permissions.@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@types/jest-when from 2.7.2 to 3.5.0cronstrue from 1.125.0 to 2.2.0@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v1624254fd433: build(deps): bump @testing-library/user-event from 13.5.0 to 14.0.0
cb592bfce7: Provides the ability to hide the relations toggle on the OwnershipCard as well as setting a default relation type.
To hide the toggle simply include the hideRelationsToggle prop like this:
<EntityOwnershipCard
variant="gridItem"
entityFilterKind={customEntityFilterKind}
hideRelationsToggle
/>
To set the default relation type, add the relationsType prop with a value of direct or aggregated, the default if not provided is direct. Here is an example:
<EntityOwnershipCard
variant="gridItem"
entityFilterKind={customEntityFilterKind}
relationsType="aggregated"
/>
d014fe2cb4: Introduced a new MyGroupsSidebarItem SidebarItem that links to one or more groups based on the logged in user's membership.
To use MyGroupsSidebarItem you'll need to add it to your Root.tsx like this:
// app/src/components/Root/Root.tsx
+ import { MyGroupsSidebarItem } from '@backstage/plugin-org';
+ import GroupIcon from '@material-ui/icons/People';
<SidebarPage>
<Sidebar>
//...
<SidebarGroup label="Menu" icon={<MenuIcon />}>
//...
<SidebarItem icon={HomeIcon} to="catalog" text="Home" />
+ <MyGroupsSidebarItem
+ singularTitle="My Squad"
+ pluralTitle="My Squads"
+ icon={GroupIcon}
+ />
//...
</SidebarGroup>
</ Sidebar>
</SidebarPage>
111995470d: add aggregated ownership type for kind group in OwnershipCard
230ad0826f: Bump to using @types/node v16
0bada4fc4d: Added the metadata.description to the bottom of each member on the MembersListCard
99063c39ae: Minor API report cleanup
Updated dependencies
@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@backstage/plugin-permission-commonBasicPermission and ResourcePermission instances.@testing-library/react-hooks from 7.0.2 to 8.0.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@types/node v16IndexableResultSet type as return type of query method in SearchEngine implementation.IndexableResultSet type as return type of query method in SearchEngine implementation.SearchDocument type. This type contains the subset of IndexableDocument properties relevant to the frontend, and is intended to be used for documents returned to the frontend from the search API.
SearchResultSet is now a wrapper for documents of type SearchDocument, and is intended to be used in the frontend. This isn't a breaking change, since IndexableDocuments are valid SearchDocuments, so the old and new types are compatible.IndexableResultSet type, which wraps IndexableDocument instances in the same way as SearchResultSet.@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16ajv from 7.0.3 to 8.10.0@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16@testing-library/user-event from 13.5.0 to 14.0.0@types/node v1624254fd433: build(deps): bump @testing-library/user-event from 13.5.0 to 14.0.0
cf647f6a72: Wired up the OneLogin provider to be visible in the Settings UI when configured correctly.
Previously it wasn't visible at all.
af508a895e: Dynamically layout User Settings theme toggle container
230ad0826f: Bump to using @types/node v16
016c574b51: Added the ability to render extra setting tabs
Updated dependencies
@testing-library/user-event from 13.5.0 to 14.0.0@types/node v16