Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/.yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ npmMinimalAgeGate: 0
plugins:
- checksum: ae08ece83681cc6d217ebb53d9e00a06ea215383f34af0681a05da5720e018a6b0d98012112f9368e9fe2328b19919baba37ada25f46c4614b894765a9338db9
path: .yarn/plugins/@yarnpkg/plugin-backstage.cjs
spec: "https://versions.backstage.io/v1/releases/1.53.2/yarn-plugin"
spec: "https://versions.backstage.io/v1/releases/1.54.6/yarn-plugin"

yarnPath: .yarn/releases/yarn-4.15.0.cjs
74 changes: 73 additions & 1 deletion src/app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,79 @@ app:
packages: all

extensions:
# Configure the catalog index page to be the root page, this is normally mounted on /catalog
# Home
#
# Visit tracking records which pages users navigate to and is disabled by default.
# Enable it to populate the Most Visited and Recently Visited widgets on the Home page.
# Visit data is stored via UserSettings storage if available, otherwise browser localStorage.
# - api:home/visits: true
# - app-root-element:home/visit-listener: true
- home-page-widget:home/toolkit:
config:
tools:
- url: https://backstage.io/docs
label: Docs
icon: docs
- url: https://github.com/backstage/backstage
label: GitHub
icon: github
- url: https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md
label: Contributing
icon: docs
- url: https://backstage.io/plugins
label: Plugins Directory
icon: kind:component
- url: https://github.com/backstage/backstage/issues/new/choose
label: Submit New Issue
icon: github
- home-page-widget:home/world-clock:
config:
clockConfigs:
- label: NYC
timeZone: America/New_York
- label: UTC
timeZone: UTC
- page:home:
config:
path: /
defaultConfig:
- component: HomePageSearchBar
column: 0
row: 0
width: 12
height: 2
deletable: false
- component: GettingStarted
column: 0
row: 1
width: 4
height: 11
- component: HomePageStarredEntities
column: 4
row: 2
width: 4
height: 4
- component: HomePageToolkit
column: 4
row: 6
width: 4
height: 3
- component: HomePageWorldClock
column: 8
row: 6
width: 4
height: 3
- component: HomePageMostVisited
column: 4
row: 9
width: 4
height: 4
- component: HomePageRecentlyVisited
column: 8
row: 9
width: 4
height: 4
# Catalog
- page:catalog:
config:
pagination:
Expand Down
2 changes: 1 addition & 1 deletion src/backstage.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "1.53.2"
"version": "1.54.6"
}
3 changes: 1 addition & 2 deletions src/examples/template/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ spec:
title: Name
type: string
description: Unique name of the component
ui:field: EntityNamePicker
ui:autofocus: true
ui:options:
rows: 5
- title: Choose a location
required:
- repoUrl
Expand Down
2 changes: 2 additions & 0 deletions src/packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
"@backstage/plugin-catalog-graph": "backstage:^",
"@backstage/plugin-catalog-import": "backstage:^",
"@backstage/plugin-catalog-unprocessed-entities": "backstage:^",
"@backstage/plugin-home": "backstage:^",
"@backstage/plugin-home-react": "backstage:^",
"@backstage/plugin-notifications": "backstage:^",
"@backstage/plugin-org": "backstage:^",
"@backstage/plugin-scaffolder": "backstage:^",
Expand Down
3 changes: 3 additions & 0 deletions src/packages/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import serverlessOpsCatalogModule from '@internal/backstage-plugin-catalog-modul
import serverlessOpsApiDocsModule from '@internal/backstage-plugin-api-docs-module-serverlessops';
import appModuleNav from '@internal/backstage-plugin-app-module-nav';

import { homeModule } from './modules/home';

const signInPage = SignInPageBlueprint.make({
params: {
loader: async () => props => {
Expand Down Expand Up @@ -54,6 +56,7 @@ const signInPage = SignInPageBlueprint.make({
export default createApp({
features: [
catalogPlugin,
homeModule,
githubActionsPlugin,
githubDeploymentsPlugin,
githubIssuesPlugin,
Expand Down
52 changes: 52 additions & 0 deletions src/packages/app/src/modules/home/homeModule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { createFrontendModule } from '@backstage/frontend-plugin-api';
import { HomePageWidgetBlueprint } from '@backstage/plugin-home-react/alpha';
import { MarkdownContent } from '@backstage/core-components';

const content = `
## Welcome to Backstage! 👋

Backstage is your developer portal — a single place to manage all your
software, services, and documentation.

### Quick Start

- **Explore the catalog** — Browse all your organization's software in
the [Software Catalog](/catalog)
- **Create something new** — Use a [Software Template](/create) to
scaffold a new project in minutes
- **Read the docs** — Find technical documentation for any service
right from its catalog page

### Helpful Links

- [Backstage Documentation](https://backstage.io/docs)
- [Customizing Your Homepage](https://backstage.io/docs/getting-started/homepage)
- [Adding Plugins](https://backstage.io/docs/plugins)
- [Contributing](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md)

### How to Edit This Card

This widget is defined in \`packages/app/src/modules/home/homeModule.tsx\`.
Comment thread
tmclaugh marked this conversation as resolved.
You can update the markdown content there to welcome your team with
your own links and getting started tips.

To remove this card entirely, delete the getting started widget and
remove it from the home module's extensions array in this file.
`;

const gettingStartedWidget = HomePageWidgetBlueprint.make({
name: 'getting-started',
params: {
name: 'GettingStarted',
title: 'Getting Started',
description: 'Tips and links to help you get started with Backstage',
components: async () => ({
Content: () => <MarkdownContent content={content} />,
}),
},
});

export const homeModule = createFrontendModule({
pluginId: 'home',
extensions: [gettingStartedWidget],
});
1 change: 1 addition & 0 deletions src/packages/app/src/modules/home/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { homeModule } from './homeModule';
1 change: 1 addition & 0 deletions src/packages/app/src/modules/nav/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const SidebarContent: ExtensionDefinition<any> = NavContentBlueprint.make
</SidebarGroup>
<SidebarDivider />
<SidebarGroup label="Menu" icon={<MenuIcon />}>
{nav.take('page:home')}
{nav.take('page:catalog')}
{nav.take('page:scaffolder')}
<SidebarDivider />
Expand Down
49 changes: 22 additions & 27 deletions src/packages/backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,53 @@
# yarn tsc
# yarn build:backend
#
# Host build steps (yarn install, yarn build:backend) must use the same
# Node version as the FROM image below. Mismatched versions break native modules.
#
# Once the commands have been run, you can build the image using `yarn build-image`

FROM node:24-trixie-slim

# Set Python interpreter for `node-gyp` to use
ENV PYTHON=/usr/bin/python3

# Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend.
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install -y --no-install-recommends python3 g++ build-essential && \
rm -rf /var/lib/apt/lists/*

# Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image,
# in which case you should also move better-sqlite3 to "devDependencies" in package.json.
# Additionally, we install dependencies for `techdocs.generator.runIn: local`.
# https://backstage.io/docs/features/techdocs/getting-started#disabling-docker-in-docker-situation-optional
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install -y --no-install-recommends libsqlite3-dev && \
rm -rf /var/lib/apt/lists/*
apt-get install -y --no-install-recommends libsqlite3-dev python3 python3-pip python3-venv build-essential && \
yarn config set python /usr/bin/python3
Comment thread
tmclaugh marked this conversation as resolved.

# Set up a virtual environment for mkdocs-techdocs-core.
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

RUN pip3 install mkdocs-techdocs-core==1.1.7
Comment thread
tmclaugh marked this conversation as resolved.

# From here on we use the least-privileged `node` user to run the backend.
WORKDIR /app
RUN chown node:node /app
USER node

# This should create the app dir as `node`.
# If it is instead created as `root` then the `tar` command below will fail: `can't create directory 'packages/': Permission denied`.
# If this occurs, then ensure BuildKit is enabled (`DOCKER_BUILDKIT=1`) so the app dir is correctly created as `node`.
WORKDIR /app
# This switches many Node.js dependencies to production mode.
ENV NODE_ENV=production

# Copy files needed by Yarn
COPY --chown=node:node .yarn ./.yarn
COPY --chown=node:node .yarnrc.yml ./
COPY --chown=node:node backstage.json ./

# This switches many Node.js dependencies to production mode.
ENV NODE_ENV=production

# This disables node snapshot for Node 20 to work with the Scaffolder
ENV NODE_OPTIONS="--no-node-snapshot"

# Copy repo skeleton first, to avoid unnecessary docker cache invalidation.
# The skeleton contains the package.json of each package in the monorepo,
# and along with yarn.lock and the root package.json, that's enough to run yarn install.
COPY --chown=node:node yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./
RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz

RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \
yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)"

# This will include the examples, if you don't need these simply remove this line
COPY --chown=node:node examples ./examples
# FIXME: Added this to get around a build failure.
RUN mkdir -p /home/node/.yarn/berry/index
RUN --mount=type=cache,target=/home/node/.yarn/berry/cache,sharing=locked,uid=1000,gid=1000 \
yarn workspaces focus --all --production

# Then copy the rest of the backend bundle, along with any other files we might want.
COPY --chown=node:node packages/backend/dist/bundle.tar.gz app-config*.yaml ./
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/app-module-nav/src/nav/SidebarOverride.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export const SidebarContentOverrideComponent = ({ navItems }: { navItems: any })
</SidebarGroup>
<SidebarDivider />
<SidebarGroup label="Menu" icon={<MenuIcon />}>
{nav.take('page:home')}
<SidebarDivider />
{nav.take('page:catalog')}
{nav.take('page:catalog-graph')}
{nav.take('page:scaffolder')}
Expand Down
Loading
Loading