GitHub Actions is GitHub’s integrated continuous integration / continuous delivery (CI/CD) and automation solution. It allows you to define workflows (build, test, deploy, automation tasks) that run on GitHub-hosted runners or on your own infrastructure. Using GitHub Actions, developers can streamline their development pipelines closer to their code, leveraging first-party support and tight GitHub integration.
The Backstage GitHub Actions plugin lets you embed GitHub Actions workflow status, details, and job-level insights directly into your Backstage Component pages. Rather than jumping between Backstage and GitHub to check build health, teams can view recent runs, drill into jobs, see logs, and (if permissions allow) retry workflows — all within your developer portal.
Originally developed in the core Backstage monorepo and later migrated to the community plugins workspace, this plugin is actively maintained under the @backstage-community/plugin-github-actions package.
Typical use cases include:
- Surface CI health next to your services in the catalog
- Enable engineers and SREs to quickly see whether a service’s most recent build succeeded or failed
- Provide contextual links into GitHub logs or job steps
- Optionally offer retry controls (for workflows) from within Backstage
Installation Instructions
These instructions apply to self-hosted Backstage only.
If you are using Roadie, or you are using a GitHub app with self-hosted Backstage, OAuth
is already configured for use with the GitHub APIs. You can simply install the plugin and it
should work automatically. Your GitHub App requires action:read
permission.
If your Backstage instance is using a Personal Access Token to authenticate against GitHub, you will need to follow our instructions to create a GitHub OAuth app for Backstage.
Install the plugin into your Backstage instance.
yarn --cwd packages/app add @backstage-community/plugin-github-actions
In your backend code (e.g. packages/backend/index.ts
), enable the GitHub auth provider if not already.
backend.add(
import('@backstage/plugin-auth-backend-module-github-provider')
);
Make sure auth is configured if using OAuth to connect to GitHub.
# app-config.yaml
auth:
providers:
github:
development:
clientId: ${AUTH_GITHUB_CLIENT_ID}
clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}
production:
clientId: ${AUTH_GITHUB_CLIENT_ID}
clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}
integrations:
github:
- host: github.com
apiBaseUrl: https://api.github.com
- host: your-ghe.example.com
apiBaseUrl: https://ghe.example.com/api/v3
Add the tab to your entity pages.
import {
EntityGithubActionsContent,
isGithubActionsAvailable,
EntityRecentGithubActionsRunsCard,
} from '@backstage-community/plugin-github-actions';
const serviceEntityPage = (
<EntityLayout>
{/* other tabs … */}
<EntityLayout.Route
path="/github-actions"
title="GitHub Actions"
if={isGithubActionsAvailable}
>
<EntityGithubActionsContent />
</EntityLayout.Route>
</EntityLayout>
);
Optionally add the recent runs card to the overview page
// packages/app/src/components/catalog/EntityPage.tsx
import { EntityRecentGithubActionsRunsCard } from '@backstage/plugin-github-actions';
const overviewContent = (
<Grid container spacing={3} alignItems="stretch">
{/* other cards … */}
<EntitySwitch>
<EntitySwitch.Case if={isGithubActionsAvailable}>
<Grid item sm={6}>
<EntityRecentGithubActionsRunsCard limit={4} variant="gridItem" />
</Grid>
</EntitySwitch.Case>
</EntitySwitch>
</Grid>
);
Annotate a component with the github.com/project-slug
key and value so that Backstage
knows which builds correspond to your component.
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: sample-service
description: Component with GitHub actions enabled.
annotations:
github.com/project-slug: 'RoadieHQ/sample-service'
spec:
type: service
lifecycle: production
owner: engineering-team
Things to Know
- The plugin issues GitHub API calls from the browser using OAuth, so each user must grant access.
- The plugin supports self-hosted GitHub (GitHub Enterprise) via integrations.github config.
- There is a built-in limit: one OAuth client/token pair can manage up to ~100 GitHub App installations. Beyond that, you may hit throttling or permission issues.
- You can choose an alternative “card view” UI instead of table view by passing view=‘cards’ to
. - Retry controls (i.e. “rerun workflow”) might only appear if your OAuth app and the repository permissions allow it.
- The plugin currently does not support authenticating on behalf of users via a GitHub App (i.e. without a separate OAuth flow).
- Some users have reported seeing “No Workflow Data” even after correct setup; often this stems from mis-annotation (wrong repo slug), insufficient permissions, or caching/debugging issues.
- There is an open enhancement request to use GitHub App–based authentication under the hood (to reduce double login).
- Future versions may add optional configuration for hiding retry buttons or improving time columns.
Authentication & Permission Model
Because requests are made from the browser on behalf of the user, each user must grant the GitHub OAuth app access to their account. This means users may see an OAuth consent prompt when they first navigate to any GitHub Actions view.
To allow retrying workflows and deeper detail access, your OAuth app (or installed GitHub App) must have actions:read
(and possibly actions:write
) permissions in the relevant repositories.
Self-hosted GitHub / GitHub Enterprise
You can use this plugin with GitHub Enterprise or self-hosted GitHub by specifying the host and apiBaseUrl entries under integrations.github
in app-config.yaml. The plugin will then use those endpoints for API calls.
Annotation & Repo Mapping
The plugin relies on the github.com/project-slug
annotation in your catalog component to map Backstage entities to GitHub repositories. If that annotation is missing or incorrect, you’ll get “No Workflow Data.” Always double-check the slug matches org/repo exactly.
Multiple CI Systems / Fallback
You can combine this with other CI or deployment plugins (e.g. Jenkins, CircleCI) using patterns like EntitySwitch
or conditional rendering (e.g. isGithubActionsAvailable
) so components display the right tab based on what’s enabled.
Changelog
This changelog is produced from commits made to the GitHub Actions plugin since a year ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.
Features
- Add filtering based on annotation presence for the new front end system components. Cards hide when the required annotation is missing. #2020 (merged 10 months ago)
Performance
- Add conditional branch fetching in useWorkflowRuns. Skip loading large branch lists on views that do not need them. #3821 (merged 4 months ago)
Bug fixes
- Use the repository default branch for latest builds when no branch is set. It no longer assumes master. #4636 (merged 2 months ago)
- Fix workflow status alignment in run details. It no longer forces center alignment. #4652 (merged 2 months ago)
- Start branch list pagination at page 1 to avoid duplicates in the WorkflowRunsCard filter. #3657 (merged 5 months ago)
- Remove the special empty state shown on auth errors in workflow runs. Show the same empty state for all missing data cases. #2279 (merged 9 months ago)
- Truncate the displayed commit message at the first newline. Show the full message on hover. #2012 (merged 10 months ago)
Documentation
- Fix plugin setup guide to avoid an unnecessary import. #2631 (merged 8 months ago)
- Add a missing backend dependency step to the docs. #1760 (merged 11 months ago)
Chore
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.