-
Notifications
You must be signed in to change notification settings - Fork 5
add basic READMEs #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,11 @@ | ||
# [Backstage](https://backstage.io) | ||
# coder/backstage-plugins | ||
|
||
We believe [Backstage.io](https://backstage.io) can be extended to help developers where they spend the majority of their time: within their IDE. This repository contains a collection of plugins that onboard developers faster and reduce context-switching by giving them one-click access into reproducible development environments: | ||
|
||
- [backstage-plugin-coder](./plugins/backstage-plugin-coder/README.md): A plugin for integrating Coder workspaces into Backstage. | ||
- [backstage-plugin-devcontainers](./plugins/backstage-plugin-devcontainers/README.md): A plugin for integrating DevContainers into Backstage (no Coder deployment necessary). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will there be a frontend one? right now there is only how are READMEs typically handled when there is this "split"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at some community examples I think we'll just stick one at plugin root so folks don't have to cobble together information from two different sources (so what you have is fine). |
||
|
||
bpmct marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Please use [GitHub issues](https://github.com/coder/backstage-plugins/issues) to report any issues or feature requests. | ||
|
||
## Contributing | ||
|
||
|
@@ -24,7 +31,7 @@ Backstage app. | |
## Releasing | ||
|
||
To draft a release for a plugin push a tag named `$name/v$version` without the | ||
bpmct marked this conversation as resolved.
Show resolved
Hide resolved
|
||
`backstage-plugin-` prefix. For example: | ||
`backstage-plugin-` prefix. For example: | ||
|
||
```sh | ||
git tag -a coder/v0.0.0 -m "coder v0.0.0" | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,100 +1,132 @@ | ||||||
# coder-backstage | ||||||
|
||||||
A basic plugin that adds the "Open in Coder" button to catalog items in backstage based on | ||||||
the catalog spec. | ||||||
|
||||||
| Catalog item without Coder | Catalog item with Coder | | ||||||
| ---------------------------------------------------------------- | ---------------------------------------------------------- | | ||||||
|  |  | | ||||||
|
||||||
This is a very basic MVP, but demonstrates the power of a Coder+Backstage integration. It allows Backstage users to quickly develop a service inside a CDE. | ||||||
|
||||||
## How it works | ||||||
|
||||||
All backstage catalog items are git repos with a [catalog-info.yaml](https://github.com/bcdr-demos/python-project/blob/main/catalog-info.yaml) file. To add Coder compatibility to a given template, we need to add a `coder` section to the catalog-info.yaml file. | ||||||
|
||||||
Here's an example: | ||||||
|
||||||
```yaml | ||||||
apiVersion: backstage.io/v1alpha1 | ||||||
kind: Component | ||||||
metadata: | ||||||
name: python-project | ||||||
spec: | ||||||
type: other | ||||||
lifecycle: unknown | ||||||
owner: pm | ||||||
coder: | ||||||
template: 'devcontainers' | ||||||
createMode: 'auto' | ||||||
params: | ||||||
repo: 'custom' | ||||||
repo_url: 'https://github.com/bcdr-demos/python-project' | ||||||
region: 'us-pittsburgh' | ||||||
``` | ||||||
|
||||||
## Adding the component | ||||||
|
||||||
Since the Backstage UI is "DIY," you'll need to modify `EntityPage.tsx` in your Backstage deployment to import the components from this plugin. | ||||||
# Coder Backstage Plugin | ||||||
|
||||||
Create and manage [Coder workspaces](https://coder.com/docs/v2/latest) from Backstage. | ||||||
|
||||||
## Screenshots | ||||||
|
||||||
 | ||||||
|
||||||
 | ||||||
|
||||||
## Features | ||||||
|
||||||
- Users link their Coder accounts with Backstage via tokens | ||||||
- Associate Coder workspaces with catalog items in Backstage | ||||||
- Workspace list component for viewing and managing workspaces | ||||||
- Full Coder API access for custom plugins & integrations | ||||||
bpmct marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
## Setup | ||||||
|
||||||
This assumes you already have a [Coder](https://github.com/coder/coder) deployment running. | ||||||
Replace `https://coder.example.com` with your Coder deployment access URL. This also assumes | ||||||
you have a template that has a parameter for a git repository URL (e.g. `git_repo_url`) that auto-clones | ||||||
the repository or uses [envbuilder](https://coder.com/docs/v2/latest/templates/devcontainers) to build | ||||||
the devcontainer. | ||||||
|
||||||
1. If you have a standalone app (you didn't clone this repo), then do | ||||||
|
||||||
```bash | ||||||
yarn --cwd packages/app add @coder/backstage-plugin-coder | ||||||
``` | ||||||
|
||||||
1. Add the proxy key to your `app-config.yaml`: | ||||||
|
||||||
```yaml | ||||||
proxy: | ||||||
endpoints: | ||||||
'/coder': | ||||||
# Replace with your Coder deployment access URL and a trailing / | ||||||
target: 'https://coder.example.com/' | ||||||
changeOrigin: true | ||||||
allowedMethods: ['GET'] | ||||||
allowedHeaders: ['Authorization', 'Coder-Session-Token'] | ||||||
headers: | ||||||
X-Custom-Source: backstage | ||||||
``` | ||||||
|
||||||
1. Add the `CoderProvider` to the application: | ||||||
bpmct marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
```tsx | ||||||
// In packages/app/src/App.tsx | ||||||
import { | ||||||
type CoderAppConfig, | ||||||
CoderProvider, | ||||||
} from '@coder/backstage-plugin-coder'; | ||||||
|
||||||
const appConfig: CoderAppConfig = { | ||||||
deployment: { | ||||||
accessUrl: 'https://coder.example.com', | ||||||
}, | ||||||
|
||||||
// Set the default template (and parameters) for | ||||||
// catalog items. This can be overridden in the | ||||||
// catalog-info.yaml for specific items. | ||||||
workspaces: { | ||||||
templateName: 'devcontainers', | ||||||
mode: 'manual', | ||||||
// This parameter is used to filter Coder workspaces | ||||||
// by a repo URL parameter. | ||||||
repoUrlParamKeys: ['custom_repo', 'repo_url'], | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Think it might be help to make it more clear that this is specifically for specifying multiple parameters for the repo URL, if a company somehow has multiple teams using different key names There's a section in the API Reference that mentions the general order of operations that the logic uses to process these parameter names. Might be worth linking to it once the API docs are good to go There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure how a single template would be supported, but multiple parameters for repo, unless I'm missing something. I think we leave it in the API reference for now. |
||||||
params: { | ||||||
repo: 'custom', | ||||||
region: 'eu-helsinki', | ||||||
}, | ||||||
}, | ||||||
}; | ||||||
|
||||||
// ... | ||||||
|
||||||
export default app.createRoot( | ||||||
<CoderProvider appConfig={appConfig}> | ||||||
<AlertDisplay /> | ||||||
<OAuthRequestDialog /> | ||||||
<AppRouter> | ||||||
<Root>{routes}</Root> | ||||||
</AppRouter> | ||||||
</CoderProvider>, | ||||||
); | ||||||
``` | ||||||
|
||||||
1. Add the `WorkspacesList` card to the entity page in your app: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Do you also think that it's worth shouting out that the individual pieces will be available as imports, too, for people who want more customization options, or can that stay more of a footnote in the API docs? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that would be excellent. Will we have an example of that in the API docs? Left a comment for now. |
||||||
|
||||||
```tsx | ||||||
// In packages/app/src/components/catalog/EntityPage.tsx | ||||||
import { CoderWorkspacesCard } from '@coder/backstage-plugin-coder'; | ||||||
|
||||||
// ... | ||||||
|
||||||
<Grid item md={6} xs={12}> | ||||||
<CoderWorkspacesCard readEntityData /> | ||||||
</Grid>; | ||||||
``` | ||||||
|
||||||
There are several ways to use the integration: | ||||||
|
||||||
### Example Card | ||||||
|
||||||
The easiest way to consume this integration is by importing the `ExampleContributingCard` component | ||||||
See [the plugin documentation](./docs) for full configuration options and API reference. | ||||||
|
||||||
### API Access | ||||||
|
||||||
The plugin provides a `CoderApi` instance for accessing the Coder API. This can be used in custom plugins and integrations. Here is an example component that lists all templates: | ||||||
|
||||||
```tsx | ||||||
// EntityPage.tsx | ||||||
import { ExampleContributingCard } from '@internal/plugin-coder'; | ||||||
|
||||||
// ... | ||||||
const overviewContent = ( | ||||||
<Grid container spacing={3} alignItems="stretch"> | ||||||
{/* ... */} | ||||||
<Grid item md={6} xs={12}> | ||||||
<ExampleContributingCard coderAccessUrl="https://coder.example.com" /> | ||||||
</Grid> | ||||||
{/* ... */} | ||||||
</Grid> | ||||||
); | ||||||
``` | ||||||
import { useCoder } from '@coder/backstage-plugin-coder'; | ||||||
|
||||||
### Button | ||||||
|
||||||
You can also just import the `OpenInCoderButton` component and use it in your own component. | ||||||
|
||||||
### URL | ||||||
|
||||||
For the most control, you can use the `useOpenInCoderLink` to get the Coder URL for a given catalog item. | ||||||
|
||||||
```ts | ||||||
// MyCustomComponent.tsx | ||||||
import { useOpenInCoderLink } from '@internal/plugin-coder'; | ||||||
|
||||||
export const MyCustomComponent = () => { | ||||||
const coderLink = useOpenInCoderLink(catalogItem); | ||||||
// some basic component that has error handling if coderLink is null | ||||||
if (coderLink) return <a href={coderLink}>Open in Coder</a>; | ||||||
return <p>Not configured for Coder</p>; | ||||||
}; | ||||||
// TODO. I believe Michael said this is possible today? | ||||||
// This can be a very basic component that requires auth | ||||||
// and lists all templates in a basic unstyled list | ||||||
// with a refresh button | ||||||
Comment on lines
+116
to
+119
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this depends on your definition of "possible today". With the current proxy settings, it is possible to hit any arbitrary endpoint, though there's zero type-safety/type-hints or good ergonomics around it. There's also not a great way to bring the Coder session token from the other UI components into any arbitrary fetch call Again, though, these changes are perfectly doable in time for launch – they're just not ready quite yet There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha. Commented out fo rnow |
||||||
``` | ||||||
|
||||||
## Taking this further | ||||||
See to the [Coder REST API Reference](https://coder.com/docs/v2/latest/api) for more details | ||||||
|
||||||
This is only the beginning. We can extend this integration further: | ||||||
## Roadmap | ||||||
|
||||||
- [ ] Display Coder-compatible templates in the catalog | ||||||
- [ ] Developing a neutral Backstage plugin to detect `devcontainer.json` in repos and add a more advanced "contributing" card that links to VS Code Remote, Codespaces, and Coder | ||||||
- [ ] Allow developers to see their existing Coder workspaces and relate workspaces more directly to catalog items | ||||||
- [ ] Allow developers to create new workspaces from the catalog item page or a dedicated sidebar page | ||||||
- [ ] Build an IDE extension to allow people to see catalog items and start a new project, and open their CDE, without leaving their editor! | ||||||
This plugin is in active development. The following features are planned: | ||||||
|
||||||
More ideas welcome! | ||||||
- [ ] Add support for only rendering component if `catalog-info.yaml` indicates the item is compatible with Coder | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this would be too hard – my gut feeling is that we would basically export a custom hook (something like I think that'll be the best option for giving devs the most control, since there's so much freedom as far as where the component can be placed, and blindly hiding an element could cause layout jank in our user's webpages. Though on top of this, we could also add a property to the component that says whether to render at all |
||||||
- [ ] OAuth support (vs. token auth) for linking Coder accounts | ||||||
- [ ] "Open in Coder" button/card component for catalog items | ||||||
- [ ] Example creating workspaces with Backstage Scaffolder | ||||||
- [ ] Example dedicated "Coder" page in Backstage | ||||||
bpmct marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
## Contributing | ||||||
|
||||||
Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/coder](http://localhost:3000/coder). | ||||||
|
||||||
You can also serve the plugin in isolation by running `yarn start` in the plugin directory. | ||||||
This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads. | ||||||
It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. | ||||||
This plugin is part of the Backstage community. We welcome contributions! |
Uh oh!
There was an error while loading. Please reload this page.