diff --git a/plugins/github-deployments/README.md b/plugins/github-deployments/README.md index c2c56b02e5..8658eb5985 100644 --- a/plugins/github-deployments/README.md +++ b/plugins/github-deployments/README.md @@ -6,7 +6,16 @@ The GitHub Deployments Plugin displays recent deployments from GitHub. ## Getting Started -1. Install the GitHub Deployments Plugin +1. Provide OAuth credentials: + +- Create an [OAuth App](https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/) and set env variables for ID and Secret. + +```bash +export AUTH_GITHUB_CLIENT_ID={{YOUR_CLIENT_ID}} +export AUTH_CLIENT_SECRET={{YOUR_CLIENT_SECRET}} +``` + +2. Install the GitHub Deployments Plugin. ```bash # packages/app @@ -14,24 +23,16 @@ The GitHub Deployments Plugin displays recent deployments from GitHub. yarn add @backstage/plugin-github-deployments ``` -2. Add proxy and auth token for GitHub +3. If you use GitHub enterprise then set the host in `app-config.yaml`. ```yaml # app-config.yaml - -proxy: - ... - '/github/api': - target: https://api.github.com - changeOrigin: true - secure: true - headers: - Authorization: - # Content: 'token OAUTH-TOKEN' - $env: GITHUB_OAUTH_TOKEN +integrations: + github: + - host: { { YOUR_GITHUB_HOST_URL } } ``` -3. Add the plugin to the app +4. Add the plugin to the app ```typescript // packages/app/src/plugins.ts @@ -39,25 +40,25 @@ proxy: export { plugin as GithubDeployments } from '@backstage/plugin-github-deployments'; ``` -4. Add the ... to the EntityPage: +5. Add the `EntityGithubDeploymentsCard` to the EntityPage: ```typescript // packages/app/src/components/catalog/EntityPage.tsx import { EntityGithubDeploymentsCard } from '@backstage/plugin-github-deployments'; -const OverviewContent = ({ entity }: { entity: Entity }) => ( +const OverviewContent = () => ( // ... - + // ... ); ``` -5. Add the `github.com/project-slug` annotation to your `catalog-info.yaml` file: +6. Add the `github.com/project-slug` annotation to your `catalog-info.yaml` file: ```yaml apiVersion: backstage.io/v1alpha1 diff --git a/plugins/github-deployments/src/api/index.ts b/plugins/github-deployments/src/api/index.ts index 4198776b57..3942d43f37 100644 --- a/plugins/github-deployments/src/api/index.ts +++ b/plugins/github-deployments/src/api/index.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { createApiRef, DiscoveryApi } from '@backstage/core'; +import { ConfigApi, createApiRef, OAuthApi } from '@backstage/core'; import { graphql } from '@octokit/graphql'; export type GithubDeployment = { @@ -40,8 +40,8 @@ export const githubDeploymentsApiRef = createApiRef({ }); export type Options = { - discoveryApi: DiscoveryApi; - proxyPath?: string; + configApi: ConfigApi; + githubAuthApi: OAuthApi; }; const deploymentsQuery = ` @@ -63,14 +63,19 @@ query lastDeployments($owner: String!, $repo: String!, $last: Int) { `; export class GithubDeploymentsApiClient implements GithubDeploymentsApi { - private readonly discoveryApi: DiscoveryApi; + private readonly configApi: ConfigApi; + private readonly githubAuthApi: OAuthApi; constructor(options: Options) { - this.discoveryApi = options.discoveryApi; + this.configApi = options.configApi; + this.githubAuthApi = options.githubAuthApi; } - private async getProxyUrl() { - return await this.discoveryApi.getBaseUrl('proxy'); + private getBaseUrl() { + const providerConfigs = + this.configApi.getOptionalConfigArray('integrations.github') ?? []; + const targetProviderConfig = providerConfigs[0]; + return targetProviderConfig?.getOptionalString('apiBaseUrl'); } async listDeployments(options: { @@ -78,12 +83,17 @@ export class GithubDeploymentsApiClient implements GithubDeploymentsApi { repo: string; last: number; }): Promise { - const proxyUrl = await this.getProxyUrl(); - const graphQlWithBaseURL = graphql.defaults({ - baseUrl: `${proxyUrl}/github/api`, + const token = await this.githubAuthApi.getAccessToken(['repo']); + const baseUrl = this.getBaseUrl() || 'https://api.github.com'; + + const graphQLWithAuth = graphql.defaults({ + baseUrl, + headers: { + authorization: `token ${token}`, + }, }); - const response: any = await graphQlWithBaseURL(deploymentsQuery, options); + const response: any = await graphQLWithAuth(deploymentsQuery, options); return response.repository?.deployments?.nodes?.reverse() || []; } } diff --git a/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx b/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx index e933592355..73fbbf1dad 100644 --- a/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx +++ b/plugins/github-deployments/src/components/GithubDeploymentsCard.test.tsx @@ -21,6 +21,8 @@ import { UrlPatternDiscovery, configApiRef, ConfigReader, + ConfigApi, + OAuthApi, } from '@backstage/core'; import { render } from '@testing-library/react'; @@ -39,13 +41,20 @@ jest.mock('@backstage/plugin-catalog-react', () => ({ }, })); -const discoveryApi = UrlPatternDiscovery.compile('http://exampleapi.com'); const errorApiMock = { post: jest.fn(), error$: jest.fn() }; +const configApi: ConfigApi = new ConfigReader({}); +const githubAuthApi: OAuthApi = { + getAccessToken: async _ => 'access_token', +}; + const apis = ApiRegistry.from([ - [configApiRef, new ConfigReader({})], + [configApiRef, configApi], [errorApiRef, errorApiMock], - [githubDeploymentsApiRef, new GithubDeploymentsApiClient({ discoveryApi })], + [ + githubDeploymentsApiRef, + new GithubDeploymentsApiClient({ configApi, githubAuthApi }), + ], ]); describe('github-deployments', () => { diff --git a/plugins/github-deployments/src/plugin.ts b/plugins/github-deployments/src/plugin.ts index 2985688785..438f2f70d2 100644 --- a/plugins/github-deployments/src/plugin.ts +++ b/plugins/github-deployments/src/plugin.ts @@ -14,10 +14,11 @@ * limitations under the License. */ import { + configApiRef, createApiFactory, createComponentExtension, createPlugin, - discoveryApiRef, + githubAuthApiRef, } from '@backstage/core'; import { githubDeploymentsApiRef, GithubDeploymentsApiClient } from './api'; @@ -26,9 +27,9 @@ export const githubDeploymentsPlugin = createPlugin({ apis: [ createApiFactory({ api: githubDeploymentsApiRef, - deps: { discoveryApi: discoveryApiRef }, - factory: ({ discoveryApi }) => - new GithubDeploymentsApiClient({ discoveryApi }), + deps: { configApi: configApiRef, githubAuthApi: githubAuthApiRef }, + factory: ({ configApi, githubAuthApi }) => + new GithubDeploymentsApiClient({ configApi, githubAuthApi }), }), ], });