Merge branch 'master' into feature/10453-add-custom-options-catalog-table
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
---
|
||||
|
||||
Specify type of `visibilityPermission` property on collators and collator factories.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': minor
|
||||
---
|
||||
|
||||
Override default commit message and author details in GitLab action
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': minor
|
||||
---
|
||||
|
||||
**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`:
|
||||
|
||||
```typescript
|
||||
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,
|
||||
};
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/integration': patch
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
'@backstage/plugin-catalog-backend-module-msgraph': patch
|
||||
---
|
||||
|
||||
Clarify that config locations that emit User and Group kinds now need to declare so in the `catalog.locations.[].rules`
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-bazaar': patch
|
||||
---
|
||||
|
||||
Pass authorization header with Backstage token to backend requests.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-search-backend': patch
|
||||
---
|
||||
|
||||
Check for non-resource permissions when authorizing result-by-result in AuthorizedSearchEngine.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-permission-react': minor
|
||||
---
|
||||
|
||||
**BREAKING**: More restrictive typing for `usePermission` hook and `PermissionedRoute` component. It's no longer possible to pass a `resourceRef` unless the permission is of type `ResourcePermission`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-tasks': patch
|
||||
---
|
||||
|
||||
Refactored the internal `TaskWorker` class to make it easier to test.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-permission-common': minor
|
||||
---
|
||||
|
||||
Add `resourceType` property to `PermissionCondition` type to allow matching them with `ResourcePermission` instances.
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
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:
|
||||
|
||||
```yaml
|
||||
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:
|
||||
|
||||
```diff
|
||||
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:
|
||||
|
||||
```diff
|
||||
catalog:
|
||||
locations:
|
||||
- type: github-org
|
||||
target: https://github.com/my-org-name
|
||||
+ rules:
|
||||
+ - allow: [User, Group]
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Prevent permissions with types other than `ResourcePermission<'catalog-entity'>` from being used with the `useEntityPermission` hook.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
build(deps): bump `eslint-plugin-jest` from 25.3.4 to 26.1.2
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
build(deps): bump `eslint-webpack-plugin` from 2.6.0 to 3.1.1
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
build(deps): bump `@spotify/eslint-config-base` from 12.0.0 to 13.0.0
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
build(deps): bump `@spotify/eslint-config-typescript`
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
'@backstage/plugin-permission-node': minor
|
||||
---
|
||||
|
||||
**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:
|
||||
|
||||
1. The function always creates a _conditional_ policy decision, but this was not reflected in the name.
|
||||
2. Conditional decisions should only ever be returned from `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:
|
||||
|
||||
- The `createPolicyDecision` method has been renamed to `createConditionalDecision`.
|
||||
- Along with conditions, the method now accepts a permission, which must be a `ResourcePermission`. This is expected to be the handled permission in `PermissionPolicy#handle`, whose type must first be narrowed using methods like `isPermission` and `isResourcePermission`:
|
||||
|
||||
```typescript
|
||||
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 `PermissionRule`s, provide a `resourceType`.
|
||||
|
||||
```diff
|
||||
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,
|
||||
}),
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-tasks': minor
|
||||
---
|
||||
|
||||
Adds the ability to manually trigger tasks which are registered
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
'@backstage/plugin-permission-common': minor
|
||||
---
|
||||
|
||||
Refactor api types into more specific, decoupled names.
|
||||
|
||||
- **BREAKING:**
|
||||
- Renamed `AuthorizeDecision` to `EvaluatePermissionResponse`
|
||||
- Renamed `AuthorizeQuery` to `EvaluatePermissionRequest`
|
||||
- Renamed `AuthorizeRequest` to `EvaluatePermissionRequestBatch`
|
||||
- Renamed `AuthorizeResponse` to `EvaluatePermissionResponseBatch`
|
||||
- Renamed `Identified` to `IdentifiedPermissionMessage`
|
||||
- Add `PermissionMessageBatch` helper type
|
||||
- Add `ConditionalPolicyDecision`, `DefinitivePolicyDecision`, and `PolicyDecision` types from `@backstage/plugin-permission-node`
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/plugin-permission-node': minor
|
||||
---
|
||||
|
||||
**BREAKING:**
|
||||
|
||||
- Rename `PolicyAuthorizeQuery` to `PolicyQuery`
|
||||
- Remove `PolicyDecision`, `DefinitivePolicyDecision`, and `ConditionalPolicyDecision`. These types are now exported from `@backstage/plugin-permission-common`
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-home': patch
|
||||
---
|
||||
|
||||
- Adds new `HomePageStackOverflowQuestions` component which renders a list of stack overflow questions on your homepage.
|
||||
|
||||
- Exports `ComponentRenderer` type.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-badges-backend': patch
|
||||
---
|
||||
|
||||
allow overriding `DefaultBadgeBuilder.getMarkdownCode`
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
---
|
||||
|
||||
export kubernetes components
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights-node': patch
|
||||
---
|
||||
|
||||
Adds an optional timeout to fact retriever registrations to stop a task if it runs too long.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Stop logging "Stopped watcher" when shutting down the development backend.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-stack-overflow-backend': minor
|
||||
---
|
||||
|
||||
Add stack overflow backend plugin
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/plugin-permission-backend': patch
|
||||
'@backstage/plugin-permission-react': patch
|
||||
'@backstage/plugin-search-backend': patch
|
||||
'@backstage/test-utils': patch
|
||||
---
|
||||
|
||||
Use updated types from `@backstage/plugin-permission-common`
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-common': patch
|
||||
'@backstage/plugin-jenkins-common': patch
|
||||
---
|
||||
|
||||
Use `createPermission` helper when creating permissions.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-org': patch
|
||||
---
|
||||
|
||||
add aggregated ownership type for kind group in OwnershipCard
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': minor
|
||||
---
|
||||
|
||||
**BREAKING:** Mark CatalogBuilder#addPermissionRules as @alpha.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': minor
|
||||
---
|
||||
|
||||
Add new `draft` option to the `publish:github:pull-request` action.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-graph': patch
|
||||
---
|
||||
|
||||
Added renderNode and renderLabel property to EntityRelationsGraph to support customization using CustomNode and CustomLabel components
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Added the GerritUrlReader that implements "readUrl".
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Add helpful README.md files in the original `packages` and `plugins` folders
|
||||
+60
-1
@@ -137,36 +137,95 @@
|
||||
"@backstage/plugin-todo": "0.2.5",
|
||||
"@backstage/plugin-todo-backend": "0.1.27",
|
||||
"@backstage/plugin-user-settings": "0.4.2",
|
||||
"@backstage/plugin-xcmetrics": "0.2.23"
|
||||
"@backstage/plugin-xcmetrics": "0.2.23",
|
||||
"@backstage/plugin-stack-overflow": "0.0.0",
|
||||
"@backstage/plugin-stack-overflow-backend": "0.0.0"
|
||||
},
|
||||
"changesets": [
|
||||
"afraid-boats-check",
|
||||
"angry-pens-begin",
|
||||
"beige-avocados-matter",
|
||||
"beige-baboons-walk",
|
||||
"big-buses-clap",
|
||||
"big-mayflies-sin",
|
||||
"blue-beers-kiss",
|
||||
"brave-chairs-stare",
|
||||
"calm-walls-heal",
|
||||
"clean-lions-taste",
|
||||
"clever-donuts-teach",
|
||||
"dependabot-05b19b9",
|
||||
"dependabot-2b68456",
|
||||
"dependabot-6754062",
|
||||
"dependabot-84caed8",
|
||||
"dependabot-c1fe92f",
|
||||
"dry-fans-arrive",
|
||||
"eleven-days-brush",
|
||||
"eleven-frogs-promise",
|
||||
"eleven-pens-collect",
|
||||
"empty-pens-invent",
|
||||
"fair-dingos-glow",
|
||||
"fair-lamps-leave",
|
||||
"fast-cheetahs-grow",
|
||||
"few-mayflies-divide",
|
||||
"forty-poets-tie",
|
||||
"four-birds-peel",
|
||||
"fresh-bulldogs-own",
|
||||
"fresh-cobras-admire",
|
||||
"fresh-dodos-rush",
|
||||
"happy-foxes-arrive",
|
||||
"happy-mugs-camp",
|
||||
"hip-poems-breathe",
|
||||
"khaki-pears-march",
|
||||
"large-coins-arrive",
|
||||
"light-drinks-rule",
|
||||
"mean-pumas-search",
|
||||
"mean-rabbits-tell",
|
||||
"mean-tomatoes-shout",
|
||||
"metal-queens-cheat",
|
||||
"mighty-suns-drop",
|
||||
"modern-actors-notice",
|
||||
"modern-pumas-join",
|
||||
"moody-ducks-return",
|
||||
"moody-pigs-rush",
|
||||
"new-lions-run",
|
||||
"nine-grapes-turn",
|
||||
"ninety-fishes-vanish",
|
||||
"olive-geese-chew",
|
||||
"perfect-phones-roll",
|
||||
"pretty-ghosts-scream",
|
||||
"purple-boats-punch",
|
||||
"purple-laws-give",
|
||||
"rare-waves-hammer",
|
||||
"red-snakes-float",
|
||||
"rich-maps-hear",
|
||||
"rotten-planes-watch",
|
||||
"seven-apricots-sell",
|
||||
"shiny-seas-yell",
|
||||
"short-knives-wave",
|
||||
"silent-bobcats-matter",
|
||||
"silly-llamas-relax",
|
||||
"silver-pots-call",
|
||||
"smart-phones-exist",
|
||||
"sour-cameras-deliver",
|
||||
"sour-lobsters-sniff",
|
||||
"stale-carrots-smile",
|
||||
"strange-wasps-whisper",
|
||||
"tasty-emus-hunt",
|
||||
"tasty-goats-shout",
|
||||
"techdocs-coats-obey",
|
||||
"techdocs-head-shoulders-knees-toes",
|
||||
"techdocs-parents-suffer",
|
||||
"thick-comics-fold",
|
||||
"thin-lizards-battle",
|
||||
"tidy-days-warn",
|
||||
"tidy-emus-stare",
|
||||
"twelve-buses-nail",
|
||||
"unlucky-schools-heal",
|
||||
"unlucky-snakes-turn",
|
||||
"warm-mangos-compete",
|
||||
"wicked-beds-return",
|
||||
"wicked-feet-clap",
|
||||
"witty-years-sniff",
|
||||
"yellow-hats-remember"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
---
|
||||
|
||||
`TestDatabases.create` will no longer set up an `afterAll` test handler if no databases are supported.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Removed broken link from Labels section of entity inspector.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-common': patch
|
||||
---
|
||||
|
||||
Add `@alpha` `CatalogEntityPermission` convenience type, available for import from `@backstage/plugin-catalog-common/alpha`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
Handle trailing slashes on GitHub `enterpriseInstanceUrl` settings
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights-backend-module-jsonfc': patch
|
||||
---
|
||||
|
||||
Removes node-cron from tech-insights to utilize backend-tasks
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
'@backstage/plugin-tech-insights-backend': minor
|
||||
---
|
||||
|
||||
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`.
|
||||
|
||||
```diff
|
||||
const builder = buildTechInsightsContext({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
discovery: env.discovery,
|
||||
+ scheduler: env.scheduler,
|
||||
factRetrievers: [ /* ... */ ],
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': minor
|
||||
---
|
||||
|
||||
export `locationSpecToLocationEntity`
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-tech-radar': patch
|
||||
---
|
||||
|
||||
Fix an issue where the Radar is not updated when switching between different radars
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Handle changes to @alpha permission-related types.
|
||||
|
||||
- All exported permission rules and conditions now have a `resourceType`.
|
||||
- `createCatalogConditionalDecision` now expects supplied conditions to have the appropriate `resourceType`.
|
||||
- `createCatalogPermissionRule` now expects `resourceType` as part of the supplied rule object.
|
||||
- Introduce new `CatalogPermissionRule` convenience type.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-permission-node': patch
|
||||
---
|
||||
|
||||
Fix signature of permission rule in test suites
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-permission-common': patch
|
||||
---
|
||||
|
||||
Add `isPermission` helper method.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
The logger returned from `getVoidLogger` is now uses a silenced console transport instead.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Fixed misleading log message during frontend plugin creation.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': minor
|
||||
---
|
||||
|
||||
Expose 'initalFilter' through initialKind prop on Catalog Page.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-gcalendar': minor
|
||||
---
|
||||
|
||||
Fixed issue when not all calendars were fetched for some accounts
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Some documentation layout tweaks:
|
||||
|
||||
- drawer toggle margins
|
||||
- code block margins
|
||||
- sidebar drawer width
|
||||
- inner content width
|
||||
- footer link width
|
||||
- sidebar table of contents scroll
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Update `usePermission` usage.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/integration': minor
|
||||
---
|
||||
|
||||
Gerrit integration: Added an optional configuration to set the Gitiles base url.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'@backstage/cli': minor
|
||||
---
|
||||
|
||||
**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](https://github.com/facebook/jest/releases/tag/v27.0.0).
|
||||
|
||||
We strongly recommend to have completed the [package role migration](https://backstage.io/docs/tutorials/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.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-permission-backend': patch
|
||||
---
|
||||
|
||||
- Add more specific check for policies which return conditional decisions for non-resource permissions.
|
||||
- Refine permission validation in authorize endpoint to differentiate between `BasicPermission` and `ResourcePermission` instances.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-jenkins-backend': patch
|
||||
---
|
||||
|
||||
Fixed possible type error if jenkins response contains null values
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-permission-common': patch
|
||||
---
|
||||
|
||||
- Add more specific `Permission` types.
|
||||
- Add `createPermission` helper to infer the appropriate type for some permission input.
|
||||
- Add `isResourcePermission` helper to refine Permissions to ResourcePermissions.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-stack-overflow': minor
|
||||
---
|
||||
|
||||
Add stack overflow plugin
|
||||
@@ -32,6 +32,7 @@
|
||||
/plugins/explore @backstage/reviewers @backstage/sda-se-reviewers
|
||||
/plugins/explore-react @backstage/reviewers @backstage/sda-se-reviewers
|
||||
/plugins/fossa @backstage/reviewers @backstage/sda-se-reviewers
|
||||
/plugins/gcalendar @backstage/reviewers @szubster @ptychu @kielosz @alexrybch
|
||||
/plugins/git-release-manager @backstage/reviewers @erikengervall
|
||||
/plugins/home @backstage/reviewers @backstage/techdocs-core
|
||||
/plugins/ilert @backstage/reviewers @yacut
|
||||
@@ -44,6 +45,8 @@
|
||||
/plugins/scaffolder-backend-module-yeoman @backstage/reviewers @pawelmitka
|
||||
/plugins/search @backstage/reviewers @backstage/techdocs-core
|
||||
/plugins/search-* @backstage/reviewers @backstage/techdocs-core
|
||||
/plugins/stack-overflow @backstage/reviewers @backstage/techdocs-core
|
||||
/plugins/stack-overflow-backend @backstage/reviewers @backstage/techdocs-core
|
||||
/plugins/sonarqube @backstage/reviewers @backstage/sda-se-reviewers
|
||||
/plugins/techdocs @backstage/reviewers @backstage/techdocs-core
|
||||
/plugins/techdocs-* @backstage/reviewers @backstage/techdocs-core
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
labels: ['dependencies'],
|
||||
extends: ['config:base', ':disableDependencyDashboard', ':gitSignOff'],
|
||||
}
|
||||
@@ -108,6 +108,7 @@ Francesco
|
||||
Gerrit
|
||||
gitbeaker
|
||||
github
|
||||
Gitiles
|
||||
gitlab
|
||||
GitLab
|
||||
Gource
|
||||
@@ -136,6 +137,7 @@ inlinehilite
|
||||
interop
|
||||
JaCoCo
|
||||
JavaScript
|
||||
jenkins
|
||||
Jira
|
||||
jq
|
||||
js
|
||||
@@ -169,6 +171,7 @@ memoized
|
||||
microservice
|
||||
microservices
|
||||
microsite
|
||||
microtasks
|
||||
middleware
|
||||
minikube
|
||||
Minikube
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
name: Automate changeset feedback
|
||||
on:
|
||||
pull_request_target:
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
actions: none
|
||||
checks: none
|
||||
contents: none
|
||||
deployments: none
|
||||
issues: none
|
||||
packages: none
|
||||
pages: none
|
||||
repository-projects: none
|
||||
security-events: none
|
||||
statuses: none
|
||||
|
||||
jobs:
|
||||
feedback:
|
||||
# prevent running towards forks and version packages
|
||||
if: github.repository == 'backstage/backstage' && github.event.pull_request.user.login != 'backstage-service'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
# Fetch the commit that's merged into the base rather than the target ref
|
||||
# This will let us diff only the contents of the PR, without fetching more history
|
||||
ref: 'refs/pull/${{ github.event.pull_request.number }}/merge'
|
||||
|
||||
- name: fetch base
|
||||
run: git fetch --depth 1 origin ${{ github.base_ref }}
|
||||
|
||||
# We avoid using the in-source script since this workflow has elevated permissions that we don't want to expose
|
||||
- name: Generate Feedback
|
||||
id: generate-feedback
|
||||
run: |
|
||||
rm -f generate.js
|
||||
wget -O generate.js https://raw.githubusercontent.com/backstage/backstage/master/scripts/generate-changeset-feedback.js 1>&2
|
||||
node generate.js FETCH_HEAD > feedback.txt
|
||||
|
||||
- name: Post Feedback
|
||||
uses: actions/github-script@v5
|
||||
env:
|
||||
ISSUE_NUMBER: ${{ github.event.pull_request.number }}
|
||||
with:
|
||||
script: |
|
||||
const owner = "backstage";
|
||||
const repo = "backstage";
|
||||
const marker = "<!-- changeset-feedback -->";
|
||||
const feedback = require('fs').readFileSync('feedback.txt', 'utf8');
|
||||
const issue_number = Number(process.env.ISSUE_NUMBER);
|
||||
const body = feedback.trim() ? feedback + marker : undefined
|
||||
|
||||
const existingComments = await github.paginate(github.rest.issues.listComments, {
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
});
|
||||
|
||||
const existingComment = existingComments.find((c) =>
|
||||
c.user.login === "github-actions[bot]" &&
|
||||
c.body.includes(marker)
|
||||
);
|
||||
|
||||
if (existingComment) {
|
||||
if (body) {
|
||||
if (existingComment.body !== body) {
|
||||
console.log(`updating existing comment in #${issue_number}`);
|
||||
await github.rest.issues.updateComment({
|
||||
owner,
|
||||
repo,
|
||||
comment_id: existingComment.id,
|
||||
body,
|
||||
});
|
||||
} else {
|
||||
console.log(`skipped update of identical comment in #${issue_number}`);
|
||||
}
|
||||
} else {
|
||||
console.log(`removing comment from #${issue_number}`);
|
||||
await github.rest.issues.deleteComment({
|
||||
owner,
|
||||
repo,
|
||||
comment_id: existingComment.id,
|
||||
body,
|
||||
});
|
||||
}
|
||||
} else if (body) {
|
||||
console.log(`creating comment for #${issue_number}`);
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
body,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
name: Sync Renovate changeset
|
||||
on:
|
||||
pull_request_target:
|
||||
paths:
|
||||
- '.github/workflows/sync_renovate-changesets.yml'
|
||||
- '**/yarn.lock'
|
||||
|
||||
jobs:
|
||||
generate-changeset:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.actor == 'renovate[bot]' && github.repository == 'backstage/backstage'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 2
|
||||
ref: ${{ github.head_ref }}
|
||||
token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config --global user.email noreply@backstage.io
|
||||
git config --global user.name 'Github changeset workflow'
|
||||
- name: Generate changeset
|
||||
uses: actions/github-script@v5
|
||||
with:
|
||||
script: |
|
||||
const { promises: fs } = require("fs");
|
||||
// Parses package.json files and returns the package names
|
||||
async function getPackagesNames(files) {
|
||||
const names = [];
|
||||
for (const file of files) {
|
||||
const data = JSON.parse(await fs.readFile(file, "utf8"));
|
||||
if (!data.private) {
|
||||
names.push(data.name);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
async function createChangeset(fileName, packageBumps, packages) {
|
||||
let message = "";
|
||||
for (const [pkg, bump] of packageBumps) {
|
||||
message = message + `Updated dependency \`${pkg}\` to \`${bump}\`.\n`;
|
||||
}
|
||||
|
||||
const pkgs = packages.map((pkg) => `'${pkg}': patch`).join("\n");
|
||||
const body = `---\n${pkgs}\n---\n\n${message}\n`;
|
||||
await fs.writeFile(fileName, body);
|
||||
}
|
||||
|
||||
async function getBumps(files) {
|
||||
const bumps = new Map();
|
||||
for (const file of files) {
|
||||
const { stdout: changes } = await exec.getExecOutput("git", [
|
||||
"show",
|
||||
file,
|
||||
]);
|
||||
for (const change of changes.split("\n")) {
|
||||
if (!change.startsWith("+ ")) {
|
||||
continue;
|
||||
}
|
||||
const match = change.match(/"(.*?)"/g);
|
||||
bumps.set(match[0].replace(/"/g, ""), match[1].replace(/"/g, ""));
|
||||
}
|
||||
}
|
||||
return bumps;
|
||||
}
|
||||
|
||||
const branch = await exec.getExecOutput("git branch --show-current");
|
||||
if (!branch.stdout.startsWith("renovate/")) {
|
||||
console.log("Not a renovate branch, skipping");
|
||||
return;
|
||||
}
|
||||
const diffOutput = await exec.getExecOutput("git diff --name-only HEAD~1");
|
||||
const diffFiles = diffOutput.stdout.split("\n");
|
||||
if (diffFiles.find((f) => f.startsWith(".changeset"))) {
|
||||
console.log("Changeset already exists, skipping");
|
||||
return;
|
||||
}
|
||||
const files = diffFiles
|
||||
.filter((file) => file !== "package.json") // skip root package.json
|
||||
.filter((file) => file.includes("package.json"));
|
||||
const packageNames = await getPackagesNames(files);
|
||||
if (!packageNames.length) {
|
||||
console.log("No package.json changes to published packages, skipping");
|
||||
return;
|
||||
}
|
||||
const { stdout: shortHash } = await exec.getExecOutput(
|
||||
"git rev-parse --short HEAD"
|
||||
);
|
||||
const fileName = `.changeset/renovate-${shortHash.trim()}.md`;
|
||||
|
||||
const packageBumps = await getBumps(files);
|
||||
await createChangeset(fileName, packageBumps, packageNames);
|
||||
await exec.exec("git", ["add", fileName]);
|
||||
await exec.exec("git commit -C HEAD --amend --no-edit");
|
||||
await exec.exec("git push --force");
|
||||
@@ -1,11 +1,12 @@
|
||||
name: E2E Test Techdocs
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '.changeset/**'
|
||||
- 'contrib/**'
|
||||
- 'docs/**'
|
||||
- 'microsite/**'
|
||||
paths:
|
||||
- 'yarn.lock'
|
||||
- '.github/workflows/verify_e2e-techdocs.yml'
|
||||
- 'packages/techdocs-cli/**'
|
||||
- 'packages/techdocs-cli-embedded-app/**'
|
||||
- 'plugins/techdocs/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
@@ -5,6 +5,7 @@ name: E2E Test Windows
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'yarn.lock'
|
||||
- '.github/workflows/verify_e2e-windows.yml'
|
||||
- 'packages/cli/**'
|
||||
- 'packages/e2e-test/**'
|
||||
|
||||
+4
-2
@@ -47,7 +47,7 @@ _If you're using Backstage in your organization, please try to add your company
|
||||
| [creditas.com](https://creditas.com/) | [@aureliosaraiva](https://github.com/aureliosaraiva) [@Creditas](https://github.com/creditas) | Centralization of all services, standards, documentation, etc. We started the deployment process. |
|
||||
| [Prisjakt](https://www.prisjakt.nu) / [PriceSpy](https://pricespy.co.uk) | [@kennylindahl](https://github.com/kennylindahl) | Internal developer portal - Documentation, scaffolding, software catalog, TechRadar, Gitlab org data integration |
|
||||
| [Powerspike](https://powerspike.tv/) | [@trelore](https://github.com/trelore) | Developer portal for documentation of core libraries and repositories. |
|
||||
| [2U](https://2u.com) | [Andrew Thal](https://github.com/athal7) | Development team home-base, promoting service discoverability, resource dependencies, and tech radar |
|
||||
| [2U](https://2u.com) | [@danielleEriksen](https://github.com/danielleEriksen), [@sbhatia](https://github.com/sbhatia) | Development team home-base, promoting service discoverability, resource dependencies, and tech radar |
|
||||
| [Taxfix](https://taxfix.de/) | [Sami Ur Rehman](https://github.com/samiurrehman92) | Developer's portal with software catalog at it's core. Hosts API Specs, Tech Docs, Tech Radar and some custom plugins. |
|
||||
| [Busuu](https://busuu.com/) | [Adam Tester](https://github.com/adamtester) | Developer portal with service catalog, API docs, Event docs, service templating, and cost insights. |
|
||||
| [Loadsmart](https://loadsmart.com/) | [Loadsmart](https://github.com/loadsmart) | Improve services visibility and operations for service owners and developers. |
|
||||
@@ -107,4 +107,6 @@ _If you're using Backstage in your organization, please try to add your company
|
||||
| [VIA](https://www.via.com.br) | [@vagnerguedes](https://github.com/vagnerguedes) | Centralized Developer Experience portal - Software catalog and documentation platform, software templates, techdocs, scaffolding, self-service infrastructure |
|
||||
| [Surevine](https://www.surevine.com/) | [@DJDANNY123](https://github.com/djdanny123) | Developer portal for software catalog, discovery and a view of the technologies we are using across the organisation, we are looking to explore how we can enrich our entities in Backstage by integrating a software bill of materials. |
|
||||
| [Bonial International GmbH](https://www.bonial.com/) | [@pjungermann](https://github.com/pjungermann) | Centralized developer portal with software catalog, tech docs, templates, and more. |
|
||||
| [Beez Innovation Labs Pvt. Ltd](https://www.beezlabs.com/) | [Karthikeyan Venkatesan](https://github.com/karthikeyan23) | Developer portal with software catalog, scaffolding, tech docs, templates, and infra. |
|
||||
| [Beez Innovation Labs Pvt. Ltd](https://www.beezlabs.com/) | [Karthikeyan Venkatesan](https://github.com/karthikeyan23) | Developer portal with software catalog, scaffolding, tech docs, templates, and infra. |
|
||||
| [Agorapulse](https://www.agorapulse.com/) | [@jvdrean](https://github.com/jvdrean) | Developer portal with software catalog, documentation, monitoring, runbooks, tech radar and more. |
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# [Backstage](https://backstage.io)
|
||||
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://www.cncf.io/projects)
|
||||
[](https://www.cncf.io/projects)
|
||||
[](https://github.com/backstage/backstage/actions?query=workflow%3A%22Main+Master+Build%22)
|
||||
[](https://discord.gg/EBHEGzX)
|
||||

|
||||
@@ -25,7 +25,7 @@ Out of the box, Backstage includes:
|
||||
- [Backstage TechDocs](https://backstage.io/docs/features/techdocs/techdocs-overview) for making it easy to create, maintain, find, and use technical documentation, using a "docs like code" approach
|
||||
- Plus, a growing ecosystem of [open source plugins](https://github.com/backstage/backstage/tree/master/plugins) that further expand Backstage’s customizability and functionality
|
||||
|
||||
Backstage was created by Spotify but is now hosted by the [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io) as a Sandbox level project. Read the announcement [here](https://backstage.io/blog/2020/09/23/backstage-cncf-sandbox).
|
||||
Backstage was created by Spotify but is now hosted by the [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io) as an Incubation level project. Read the announcement [here](https://backstage.io/blog/2022/03/16/backstage-turns-two#out-of-the-sandbox-and-into-incubation).
|
||||
|
||||
## Project roadmap
|
||||
|
||||
|
||||
+3
-3
@@ -907,9 +907,9 @@ minimatch@^3.0.4:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
version "1.2.6"
|
||||
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||
|
||||
mkdirp@^0.5.4:
|
||||
version "0.5.5"
|
||||
|
||||
@@ -96,7 +96,7 @@ export const MyCustomFieldExtension = plugin.provide(
|
||||
```tsx
|
||||
// packages/app/src/scaffolder/MyCustomExtension/index.ts
|
||||
|
||||
export { MyCustomFieldExtension } from './extension';
|
||||
export { MyCustomFieldExtension } from './extensions';
|
||||
```
|
||||
|
||||
Once all these files are in place, you then need to provide your custom
|
||||
@@ -119,6 +119,8 @@ Should look something like this instead:
|
||||
|
||||
```tsx
|
||||
import { MyCustomFieldExtension } from './scaffolder/MyCustomExtension';
|
||||
import { ScaffolderFieldExtensions } from '@backstage/plugin-scaffolder';
|
||||
|
||||
const routes = (
|
||||
<FlatRoutes>
|
||||
...
|
||||
|
||||
@@ -31,6 +31,8 @@ catalog:
|
||||
locations:
|
||||
- type: github-org
|
||||
target: https://github.com/my-org-name
|
||||
rules:
|
||||
- allow: [User, Group]
|
||||
```
|
||||
|
||||
If Backstage is configured to use GitHub Apps authentication you must grant
|
||||
@@ -53,22 +55,3 @@ The authorization for loading org information comes from a configured
|
||||
[GitHub integration](locations.md#configuration). When using a personal access
|
||||
token, the token needs to have at least the scopes `read:org`, `read:user`, and
|
||||
`user:email` in the given `target`.
|
||||
|
||||
## Addendum
|
||||
|
||||
Some Backstage apps have _replaced_ the catalog processors to override the
|
||||
default catalog processing behavior. These apps will already have a call to
|
||||
`replaceProcessors` in the catalog initialization.
|
||||
|
||||
In the unlikely scenario that this applies to your app, you can import and
|
||||
add the `GithubOrgReaderProcessor` as follows:
|
||||
|
||||
```ts
|
||||
// Typically in packages/backend/src/plugins/catalog.ts
|
||||
import { GithubOrgReaderProcessor } from '@backstage/plugin-catalog-backend';
|
||||
|
||||
builder.replaceProcessors(
|
||||
// ... other processor replacements
|
||||
GithubOrgReaderProcessor.fromConfig(env.config, { logger: env.logger }),
|
||||
);
|
||||
```
|
||||
|
||||
@@ -28,7 +28,7 @@ can list the GitLab providers you want to fetch data from. Each entry is a
|
||||
structure with up to four elements:
|
||||
|
||||
- `host`: The host of the GitLab instance, e.g. `gitlab.company.com`.
|
||||
- `token` (optional): An authentication token as expected by GitLab. If this is
|
||||
- `token` (optional): An authentication token as expected by GitLab. The token need at least `api`, `read_repository` and `write_repository` scopes. If this is
|
||||
not supplied, anonymous access will be used.
|
||||
- `apiBaseUrl` (optional): The URL of the GitLab API. For self-hosted
|
||||
installations, it is commonly at `https://<host>/api/v4`. For gitlab.com, this
|
||||
|
||||
@@ -365,4 +365,6 @@ catalog:
|
||||
locations:
|
||||
- type: ldap-org
|
||||
target: ldaps://ds.example.net
|
||||
rules:
|
||||
- allow: [User, Group]
|
||||
```
|
||||
|
||||
@@ -521,7 +521,9 @@ The built-in configuration brings a couple of benefits and features. The most
|
||||
important one being a baseline transformer and module configuration that enables
|
||||
support for the listed [loaders](#loaders) within tests. It will also
|
||||
automatically detect and use `src/setupTests.ts` if it exists, and provides a
|
||||
coverage configuration that works well with our selected transpilers.
|
||||
coverage configuration that works well with our selected transpilers. The configuration
|
||||
will also detect the appropriate Jest environment for each package role, running
|
||||
`web-libraries` with the `"jsdom"` environment, `node-libraries` with `"node"`, and so on.
|
||||
|
||||
The configuration also takes a project-wide approach, with the expectation most
|
||||
if not all packages within a monorepo will use the same base configuration. This
|
||||
|
||||
@@ -32,7 +32,7 @@ maintain, and find the documentation for all that software in Backstage.
|
||||
One place for everything. Accessible to everyone.
|
||||
|
||||
Backstage was originally built by Spotify and then donated to the CNCF.
|
||||
Backstage is currently in the Sandbox phase. Read the announcement
|
||||
[here](https://backstage.io/blog/2020/09/23/backstage-cncf-sandbox).
|
||||
Backstage is currently in the Incubation phase. Read the announcement
|
||||
[here](https://backstage.io/blog/2022/03/16/backstage-turns-two#out-of-the-sandbox-and-into-incubation).
|
||||
|
||||
<img src="https://backstage.io/img/cncf-white.svg" width="400" />
|
||||
|
||||
@@ -18,3 +18,45 @@ description: Support and Community Details and Links
|
||||
our email newsletter.
|
||||
- Give us a star ⭐️ - If you are using Backstage or think it is an interesting
|
||||
project, we would love a star! ❤️
|
||||
|
||||
## Community Hub
|
||||
|
||||
Check out the Backstage.io [Backstage Community Hub](https://backstage.io/community) for the Community Sessions, recordings, and community resources.
|
||||
|
||||
### Adding a recording to the meetup page
|
||||
|
||||
To add a new recording to the [meetup page](https://backstage.io/on-demand)
|
||||
create a file in
|
||||
[`microsite/data/on-demand`](https://github.com/backstage/backstage/tree/master/microsite/data/on-demand)
|
||||
with your recording's information. Filenames should be in the format `yyyymmdd-xx.yaml`. The page will sort using the filename. Example file content:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: # name of the meetup
|
||||
date: February 23, 2022 # date, format: Month day, year.
|
||||
category: Meetup # Can be Event, Meetup, Webinar
|
||||
description: # description, summary
|
||||
youtubeUrl: # Url to youtube video
|
||||
youtubeImgUrl: # Url to the preview image, for Youtube this is the format: https://i1.ytimg.com/vi/<YOUTUBE_ID>/mqdefault.jpg
|
||||
```
|
||||
|
||||
### Adding an upcoming meetup to the meetup page
|
||||
|
||||
To add an upcoming meetup to the [meetup page](https://backstage.io/on-demand)
|
||||
create a file in
|
||||
[`microsite/data/on-demand`](https://github.com/backstage/backstage/tree/master/microsite/data/on-demand)
|
||||
with your meetup's information. Filenames should be in the format `yyyymmdd-xx.yaml`, the page will sort using the filename. Example file content:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: # name of the meetup
|
||||
date: February 23, 2022 # date, format: Month day, year.
|
||||
category: Upcoming # Should be "Upcoming"
|
||||
description: # description, summary
|
||||
youtubeUrl: # Url to youtube video
|
||||
youtubeImgUrl: # Url to the preview image, for Youtube this is the format: https://i1.ytimg.com/vi/<YOUTUBE_ID>/mqdefault.jpg
|
||||
rsvpUrl: # Link to registration, calendar item, etc
|
||||
eventUrl: # Link to event landing page
|
||||
```
|
||||
|
||||
After the meetup is done, and the recording is ready you can change it to a meetup recording.
|
||||
|
||||
@@ -37,8 +37,8 @@ Out of the box, Backstage includes:
|
||||
|
||||
## Backstage and the CNCF
|
||||
|
||||
Backstage is a CNCF Sandbox project. Read the announcement
|
||||
[here](https://backstage.io/blog/2020/09/23/backstage-cncf-sandbox).
|
||||
Backstage is a CNCF Incubation project after graduating from Sandbox. Read the announcement
|
||||
[here](https://backstage.io/blog/2022/03/16/backstage-turns-two#out-of-the-sandbox-and-into-incubation).
|
||||
|
||||
<img src="https://backstage.io/img/cncf-white.svg" width="400" />
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ class Footer extends React.Component {
|
||||
<a href="https://mailchi.mp/spotify/backstage-community">
|
||||
Subscribe to our newsletter
|
||||
</a>
|
||||
<a href="https://www.cncf.io/sandbox-projects/">CNCF Sandbox</a>
|
||||
<a href="https://www.cncf.io/projects/">CNCF Incubation</a>
|
||||
</div>
|
||||
<div>
|
||||
<h5>More</h5>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Community Sessions
|
||||
date: November 17, 2021
|
||||
category: Meetup
|
||||
description: At this month’s adopters session, get the scoop on Spotify’s plan for paid plugins, a first look at Box’s DevPortal, and answers to big questions, like “How will I know if Backstage will work at a large company like mine?”
|
||||
youtubeUrl: https://youtu.be/apCDT3_DmFk
|
||||
youtubeImgUrl: https://i1.ytimg.com/vi/apCDT3_DmFk/mqdefault.jpg
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Community Sessions
|
||||
date: November 18, 2021
|
||||
category: Meetup
|
||||
description: In the contributors track for this month’s community session, hear about upcoming deprecations, the fruits of Hacktoberfest, the future of both the Kubernetes plugin and the Tech Insights plugin, tips on contributing, and more.
|
||||
youtubeUrl: https://youtu.be/n1OWGwYAOiI
|
||||
youtubeImgUrl: https://i1.ytimg.com/vi/n1OWGwYAOiI/mqdefault.jpg
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Community Sessions
|
||||
date: December 15, 2021
|
||||
category: Meetup
|
||||
description: At our final adopters session of 2021, the community received a grab bag of end-of-year treats, including eye-catching infographics, a presentation from finance startup Brex about their path to adopting Backstage, and tips on branding your Backstage portal. Plus, get your official Backstage Zoom background. But first up, a quick look back at the year that was.
|
||||
youtubeUrl: https://youtu.be/0QMQYSTKAx0
|
||||
youtubeImgUrl: https://i1.ytimg.com/vi/0QMQYSTKAx0/mqdefault.jpg
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Community Sessions
|
||||
date: December 16, 2021
|
||||
category: Meetup
|
||||
description: At our final contributors session of 2021, see how the new Backstage Upgrade Helper works and enjoy smoother upgrades, hear updates from the maintainers, and meet our contributor of the month. As in the adopters session, first we celebrate the year’s milestones and share a few resources you can use to spread the word about Backstage.
|
||||
youtubeUrl: https://youtu.be/nYjI2j-lWEM
|
||||
youtubeImgUrl: https://i1.ytimg.com/vi/nYjI2j-lWEM/mqdefault.jpg
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Community Sessions
|
||||
date: February 16, 2022
|
||||
category: Meetup
|
||||
description: This community session marks one year of Backstage community sessions! In this session, we celebrate one year of the Backstage community, hear from Patrik on stabilizing core APIs, learn more about Homepage Templates, find hidden info about your catalog entities, and Q&A.
|
||||
youtubeUrl: https://youtu.be/evf_LV0KzIk
|
||||
youtubeImgUrl: https://i1.ytimg.com/vi/evf_LV0KzIk/mqdefault.jpg
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Community Sessions
|
||||
date: February 23, 2022
|
||||
category: Meetup
|
||||
description: Community Sessions Anniversary , SWAG opportunity❗, TechDocs add-on framework, URL Reader demo 👨💻, Q&A
|
||||
youtubeUrl: https://youtu.be/Buu_KWdIFwU
|
||||
youtubeImgUrl: https://i1.ytimg.com/vi/Buu_KWdIFwU/mqdefault.jpg
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Contributor Community Sessions
|
||||
date: March 23, 2022
|
||||
category: Upcoming
|
||||
description: Join the maintainers and contributors for the Contributor Community Sessions
|
||||
youtubeUrl: https://youtu.be/evf_LV0KzIk
|
||||
youtubeImgUrl: https://backstage.io/img/b-sessions.png
|
||||
rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com
|
||||
eventUrl: https://github.com/backstage/community/issues
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Adopters Community Sessions
|
||||
date: April 20, 2022
|
||||
category: Upcoming
|
||||
description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc.
|
||||
youtubeUrl: https://youtu.be/mFi_X58igzk
|
||||
youtubeImgUrl: https://backstage.io/img/b-sessions.png
|
||||
rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com
|
||||
eventUrl: https://github.com/backstage/community/issues
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Contributor Community Sessions
|
||||
date: April 27, 2022
|
||||
category: Upcoming
|
||||
description: Join the maintainers and contributors for the Contributor Community Sessions
|
||||
youtubeUrl: https://youtu.be/evf_LV0KzIk
|
||||
youtubeImgUrl: https://backstage.io/img/b-sessions.png
|
||||
rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com
|
||||
eventUrl: https://github.com/backstage/community/issues
|
||||
@@ -19,7 +19,7 @@
|
||||
"@spotify/prettier-config": "^13.0.0",
|
||||
"docusaurus": "^2.0.0-alpha.70",
|
||||
"js-yaml": "^4.1.0",
|
||||
"prettier": "^2.6.0",
|
||||
"prettier": "^2.6.1",
|
||||
"yarn-lock-check": "^1.0.5"
|
||||
},
|
||||
"prettier": "@spotify/prettier-config"
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const React = require('react');
|
||||
const Components = require(`${process.cwd()}/core/Components.js`);
|
||||
const Block = Components.Block;
|
||||
|
||||
const Background = props => {
|
||||
const { config: siteConfig } = props;
|
||||
const { baseUrl } = siteConfig;
|
||||
return (
|
||||
<main className="MainContent">
|
||||
<Block small className="stripe-bottom bg-black-grey">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.Title>Backstage Community</Block.Title>
|
||||
<Block.TextBox>
|
||||
<Block.Paragraph>
|
||||
What's the use of having fun if you can't share it? Exactly. Join
|
||||
the vibrant community around the Backstage project. Be it on
|
||||
GitHub, social media, Discord... You'll find a welcoming
|
||||
environment. To ensure this, we follow the{' '}
|
||||
<a href="https://github.com/cncf/foundation/blob/master/code-of-conduct.md">
|
||||
{' '}
|
||||
CNCF Code of Conduct
|
||||
</a>{' '}
|
||||
in everything we do.
|
||||
</Block.Paragraph>
|
||||
</Block.TextBox>
|
||||
<Block.TextBox>
|
||||
<Block.Paragraph>
|
||||
Main community channels
|
||||
<br />- Chat and get support on our{' '}
|
||||
<a href="https://discord.gg/MUpMjP2">Discord</a>
|
||||
<br />- Get into contributing with the{' '}
|
||||
<a href="https://github.com/backstage/backstage/contribute">
|
||||
Good First Issues
|
||||
</a>
|
||||
<br />- Subscribe to the{' '}
|
||||
<a href="https://mailchi.mp/spotify/backstage-community">
|
||||
Community newsletter
|
||||
</a>
|
||||
<br />- Join the{' '}
|
||||
<a href="https://twitter.com/i/communities/1494019781716062215">
|
||||
Twitter community
|
||||
</a>
|
||||
<br />
|
||||
</Block.Paragraph>
|
||||
</Block.TextBox>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
|
||||
<Block small className="stripe bg-black">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.Title>Community Sessions</Block.Title>
|
||||
<Block.TextBox>
|
||||
<Block.Paragraph>
|
||||
<b>Adopters Community Sessions</b>
|
||||
<br />
|
||||
Backstage Community Sessions is the monthly meetup where we all
|
||||
come together to listen to the latest maintainer updates, learn
|
||||
from each other about adopting, share exciting new demos or
|
||||
discuss any relevant topic like developer effectiveness, developer
|
||||
experience, developer portals, etc.
|
||||
</Block.Paragraph>
|
||||
|
||||
<Block.Paragraph>
|
||||
<b>Contributor Community Sessions</b>
|
||||
<br />
|
||||
Discuss all things contributing, diving deep under the hood of
|
||||
Backstage (Backstage of Backstage? Backerstage?). An open
|
||||
discussion with maintainers and contributors of Backstage.
|
||||
</Block.Paragraph>
|
||||
<Block.LinkButton href="/on-demand">Meetups</Block.LinkButton>
|
||||
</Block.TextBox>
|
||||
<Block.TextBox>
|
||||
<Block.Graphic
|
||||
x={60}
|
||||
y={12}
|
||||
width={30}
|
||||
src={`${baseUrl}img/b-sessions.png`}
|
||||
/>
|
||||
</Block.TextBox>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
|
||||
<Block small className="stripe bg-black-grey">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.TextBox>
|
||||
<Block.Title>Backstage official Newsletter</Block.Title>
|
||||
<Block.Paragraph>
|
||||
The official monthly Backstage newsletter. Containing the latest
|
||||
news from your favorite project.
|
||||
</Block.Paragraph>
|
||||
<Block.LinkButton href="https://mailchi.mp/spotify/backstage-community">
|
||||
Subscribe
|
||||
</Block.LinkButton>
|
||||
</Block.TextBox>
|
||||
<Block.Graphic
|
||||
x={45}
|
||||
y={12}
|
||||
width={30}
|
||||
src={`${baseUrl}img/news-fpo.png`}
|
||||
/>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
|
||||
<Block className="stripe bg-black">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.TextBox>
|
||||
<Block.Title>Spotlight</Block.Title>
|
||||
<Block.Paragraph>
|
||||
A recognition for valuable community work, the{' '}
|
||||
<b>Contributor Spotlight</b>. Nominate contributing members for
|
||||
their efforts! We'll put them in the spotlight ❤️.
|
||||
<br />
|
||||
</Block.Paragraph>
|
||||
<Block.LinkButton href="nominate ">Nominate now</Block.LinkButton>
|
||||
</Block.TextBox>
|
||||
<Block.TextBox>
|
||||
<Block.Title>Open Mic Meetup</Block.Title>
|
||||
<Block.Paragraph>
|
||||
A monthly casual get together of Backstage users sharing their
|
||||
experiences and helping each other. Hosted by{' '}
|
||||
<a href="https://roadie.io/">Roadie.io</a> and{' '}
|
||||
<a href="https://frontside.com/">Frontside Software</a>.
|
||||
<br />
|
||||
</Block.Paragraph>
|
||||
<Block.LinkButton href="https://backstage-openmic.com/">
|
||||
Learn more
|
||||
</Block.LinkButton>
|
||||
</Block.TextBox>
|
||||
<Block.TextBox>
|
||||
<Block.Title>Backstage Weekly</Block.Title>
|
||||
<Block.Paragraph>
|
||||
A weekly newsletter with news, updates and things community from
|
||||
your friends at <a href="https://roadie.io/">Roadie.io</a>.
|
||||
</Block.Paragraph>
|
||||
<Block.LinkButton href="https://roadie.io/backstage-weekly/">
|
||||
Learn more
|
||||
</Block.LinkButton>
|
||||
</Block.TextBox>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
|
||||
<Block small className="bg-black-grey">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.Graphic
|
||||
x={41}
|
||||
y={12}
|
||||
width={40}
|
||||
src={`${baseUrl}img/roadie-newsletter.png`}
|
||||
/>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = Background;
|
||||
@@ -533,7 +533,7 @@ class Index extends React.Component {
|
||||
<a href="https://www.cncf.io">
|
||||
Cloud Native Computing Foundation
|
||||
</a>{' '}
|
||||
sandbox project
|
||||
incubation project
|
||||
<div className="cncf-logo" />
|
||||
</Block.SmallTitle>
|
||||
</Block.Container>
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const React = require('react');
|
||||
const Components = require(`${process.cwd()}/core/Components.js`);
|
||||
const Block = Components.Block;
|
||||
|
||||
const Background = props => {
|
||||
const { config: siteConfig } = props;
|
||||
const { baseUrl } = siteConfig;
|
||||
return (
|
||||
<main className="MainContent">
|
||||
<Block small className="stripe-bottom bg-black-grey">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.TextBox>
|
||||
<Block.Title>Community Sessions</Block.Title>
|
||||
<Block.Paragraph>
|
||||
Please be aware we follow the{' '}
|
||||
<a href="https://github.com/cncf/foundation/blob/master/code-of-conduct.md">
|
||||
{' '}
|
||||
CNCF Code of Conduct
|
||||
</a>
|
||||
.
|
||||
</Block.Paragraph>
|
||||
</Block.TextBox>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
|
||||
<Block className="stripe bg-black">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.Paragraph>
|
||||
<iframe
|
||||
width="1280"
|
||||
height="720"
|
||||
src="https://www.youtube.com/embed/mFi_X58igzk"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
</Block.Paragraph>
|
||||
<Block.TextBox>
|
||||
<iframe
|
||||
src="https://www.youtube.com/live_chat?v=mFi_X58igzk&embed_domain=backstage.io&dark_theme=1"
|
||||
width="400px"
|
||||
height="680px"
|
||||
></iframe>
|
||||
</Block.TextBox>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
|
||||
<Block className="stripe bg-black-grey">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.TextBox>
|
||||
<Block.Title>Don't be a stranger</Block.Title>
|
||||
<Block.Paragraph>
|
||||
Main community channels
|
||||
<br />- Chat and get support on our{' '}
|
||||
<a href="https://discord.gg/MUpMjP2">Discord</a>
|
||||
<br />- Get into contributing with the{' '}
|
||||
<a href="https://github.com/backstage/backstage/contribute">
|
||||
Good First Issues
|
||||
</a>
|
||||
<br />- Subscribe to the{' '}
|
||||
<a href="https://mailchi.mp/spotify/backstage-community">
|
||||
Community newsletter
|
||||
</a>
|
||||
<br />- Join the{' '}
|
||||
<a href="https://twitter.com/i/communities/1494019781716062215">
|
||||
Twitter community
|
||||
</a>
|
||||
<br />
|
||||
</Block.Paragraph>
|
||||
</Block.TextBox>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = Background;
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const React = require('react');
|
||||
const Components = require(`${process.cwd()}/core/Components.js`);
|
||||
const Block = Components.Block;
|
||||
|
||||
const Background = props => {
|
||||
const { config: siteConfig } = props;
|
||||
const { baseUrl } = siteConfig;
|
||||
return (
|
||||
<main className="MainContent">
|
||||
<Block small className="stripe-bottom bg-black-grey">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<Block.Title>Contributor Spotlight nomination</Block.Title>
|
||||
<Block.TextBox>
|
||||
<Block.Paragraph></Block.Paragraph>
|
||||
</Block.TextBox>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
|
||||
<Block className="stripe bg-black">
|
||||
<Block.Container style={{ justifyContent: 'flex-start' }}>
|
||||
<iframe
|
||||
src="https://docs.google.com/forms/d/e/1FAIpQLSdiZ28O7vwHo6NrwirEzGSbuVyBANSv7ItHqRlgVvSz3Z5xqQ/viewform?embedded=true"
|
||||
width="800"
|
||||
height="1262"
|
||||
frameborder="0"
|
||||
marginheight="0"
|
||||
marginwidth="0"
|
||||
>
|
||||
Loading…
|
||||
</iframe>
|
||||
</Block.Container>
|
||||
</Block>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = Background;
|
||||
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const yaml = require('js-yaml');
|
||||
const React = require('react');
|
||||
const Components = require(`${process.cwd()}/core/Components.js`);
|
||||
const {
|
||||
Block: { Container },
|
||||
BulletLine,
|
||||
} = Components;
|
||||
|
||||
const ondemandDirectory = require('path').join(process.cwd(), 'data/on-demand');
|
||||
const ondemandMetadata = fs
|
||||
.readdirSync(ondemandDirectory)
|
||||
.sort()
|
||||
.reverse()
|
||||
.map(file => yaml.load(fs.readFileSync(`./data/on-demand/${file}`, 'utf8')));
|
||||
const truncate = text =>
|
||||
text.length > 170 ? text.substr(0, 170) + '...' : text;
|
||||
|
||||
const addVideoDocsLink = '/docs/overview/support';
|
||||
const defaultIconUrl = 'img/logo-gradient-on-dark.svg';
|
||||
|
||||
const Ondemand = () => (
|
||||
<main className="MainContent">
|
||||
<div className="VideoPageLayout">
|
||||
<div className="VideoPageHeader">
|
||||
<h2>Upcoming live events</h2>
|
||||
<p>Upcoming Backstage events</p>
|
||||
<span>
|
||||
<a className="VideoAddNewButton ButtonFilled" href={addVideoDocsLink}>
|
||||
<b>Add an event or recording</b>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<Container wrapped className="VideoGrid">
|
||||
{ondemandMetadata
|
||||
.filter(video => video.category === 'Upcoming')
|
||||
.map(
|
||||
({
|
||||
title,
|
||||
description,
|
||||
category,
|
||||
date,
|
||||
youtubeUrl,
|
||||
youtubeImgUrl,
|
||||
rsvpUrl,
|
||||
eventUrl,
|
||||
}) => (
|
||||
<div className="VideoCard">
|
||||
<div className="VideoCardHeader">
|
||||
<div className="VideoCardInfo">
|
||||
<h3 className="VideoCardTitle">{title}</h3>
|
||||
<p className="VideoCardDate">on {date}</p>
|
||||
|
||||
<span className="VideoCardChipOutlined">{category}</span>
|
||||
<p>
|
||||
<br />
|
||||
<img src={youtubeImgUrl} alt={title} />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="VideoCardBody">
|
||||
<p>{truncate(description)}</p>
|
||||
</div>
|
||||
<div className="VideoCardFooter">
|
||||
<a className="VideoButtonFilled" href={eventUrl}>
|
||||
Event page
|
||||
</a>
|
||||
<a className="VideoButtonFilled" href={rsvpUrl}>
|
||||
Remind me
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
</Container>
|
||||
<BulletLine style={{ width: '100%' }} />
|
||||
<div className="VideoPageHeader">
|
||||
<h2>Community on demand</h2>
|
||||
</div>
|
||||
<Container wrapped className="VideoGrid">
|
||||
{ondemandMetadata
|
||||
.filter(video => video.category !== 'Upcoming')
|
||||
.map(
|
||||
({
|
||||
title,
|
||||
description,
|
||||
category,
|
||||
date,
|
||||
youtubeUrl,
|
||||
youtubeImgUrl,
|
||||
}) => (
|
||||
<div className="VideoCard">
|
||||
<div className="VideoCardHeader">
|
||||
<div className="VideoCardInfo">
|
||||
<h3 className="VideoCardTitle">{title}</h3>
|
||||
<p className="VideoCardDate">on {date}</p>
|
||||
|
||||
<span className="VideoCardChipOutlined">{category}</span>
|
||||
<p>
|
||||
<br />
|
||||
<img src={youtubeImgUrl} alt={title} />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="VideoCardBody">
|
||||
<p>{truncate(description)}</p>
|
||||
</div>
|
||||
<div className="VideoCardFooter">
|
||||
<a className="VideoButtonFilled" href={youtubeUrl}>
|
||||
Watch on YouTube
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
<div className="VideoCard" id="add-video-card">
|
||||
<div className="VideoCardBody">
|
||||
<p>Do you have a recording of a meetup to include on this page?</p>
|
||||
<p
|
||||
style={{
|
||||
marginTop: '20px',
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<a className="VideoButtonFilled" href={addVideoDocsLink}>
|
||||
<b>Add to the On-demand page</b>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<Container className="VideoCardFooter">
|
||||
<p>
|
||||
Help us create a go-to place for hours of Backstage related
|
||||
content.
|
||||
</p>
|
||||
</Container>
|
||||
</div>
|
||||
</Container>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
|
||||
module.exports = Ondemand;
|
||||
@@ -70,6 +70,10 @@ const siteConfig = {
|
||||
page: 'demos',
|
||||
label: 'Demos',
|
||||
},
|
||||
{
|
||||
page: 'community',
|
||||
label: 'Community',
|
||||
},
|
||||
],
|
||||
|
||||
/* path to images for header/footer */
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
.VideoCard {
|
||||
background-color: #282828;
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.VideoGrid {
|
||||
display: grid;
|
||||
grid-gap: 1rem;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-auto-rows: 1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.VideoGrid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 815px) {
|
||||
.VideoGrid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 485px) {
|
||||
.VideoGrid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.VideoCard img {
|
||||
float: left;
|
||||
margin: 0px 16px 8px 0px;
|
||||
height: 160px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.VideoCardHeader {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
max-height: fit-content;
|
||||
min-height: fit-content;
|
||||
}
|
||||
|
||||
.VideoCardImage {
|
||||
width: 200px;
|
||||
height: 80px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.VideoCardImage img {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.VideoCardTitle {
|
||||
color: white;
|
||||
vertical-align: top;
|
||||
margin: 8px 0 0;
|
||||
}
|
||||
|
||||
.VideoCardInfo {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.VideoAddNewButton {
|
||||
position: absolute;
|
||||
bottom: 16px;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 485px) {
|
||||
.VideoAddNewButton {
|
||||
bottom: -4px;
|
||||
}
|
||||
}
|
||||
|
||||
.VideoButtonFilled {
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
color: #69ddc7;
|
||||
}
|
||||
|
||||
.VideoButtonFilled:hover {
|
||||
border: 1px solid #69ddc7;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.VideoCardChipOutlined {
|
||||
font-size: small;
|
||||
border-radius: 16px;
|
||||
padding: 2px 8px;
|
||||
border: 1px solid #69ddc7;
|
||||
color: #69ddc7;
|
||||
}
|
||||
|
||||
.VideoCardFooter {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
margin-top: auto;
|
||||
min-height: 2em;
|
||||
}
|
||||
|
||||
.VideoCardFooter a {
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
.VideoPageLayout {
|
||||
margin: auto;
|
||||
max-width: 1430px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.VideoPageHeader {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.VideoPageHeader h2 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.VideoCardBody {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.VideoCardDate,
|
||||
.VideoCardDate a {
|
||||
margin-bottom: 0.25em;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.VideoCardDate a:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
#add-video-card {
|
||||
border: 1px solid #69ddc7;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 797 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 252 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 205 KiB |
+7
-7
@@ -4375,9 +4375,9 @@ minimatch@3.0.4, minimatch@^3.0.4, minimatch@~3.0.2:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
version "1.2.6"
|
||||
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||
|
||||
mixin-deep@^1.1.3, mixin-deep@^1.2.0:
|
||||
version "1.3.2"
|
||||
@@ -5209,10 +5209,10 @@ prepend-http@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
||||
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
|
||||
|
||||
prettier@^2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4"
|
||||
integrity sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A==
|
||||
prettier@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz#d472797e0d7461605c1609808e27b80c0f9cfe17"
|
||||
integrity sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A==
|
||||
|
||||
prismjs@^1.22.0:
|
||||
version "1.27.0"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user