From 9fb2d6072a2dc04288548cb97d71784912dde76e Mon Sep 17 00:00:00 2001 From: Bilawal Hameed Date: Wed, 15 Jul 2020 12:02:12 +0200 Subject: [PATCH 01/14] docs(techdocs-cli): add docs on deploying / bumping up version --- packages/techdocs-cli/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/techdocs-cli/README.md b/packages/techdocs-cli/README.md index 960574db37..497101df78 100644 --- a/packages/techdocs-cli/README.md +++ b/packages/techdocs-cli/README.md @@ -45,3 +45,18 @@ npx techdocs serve You should have a `localhost:3000` serving TechDocs in Backstage, as well as `localhost:8000` serving Mkdocs (which won't open up and be exposed to the user). Happy hacking! + +## Deploying a new version + +Deploying the Node packages to NPM happens automatically on merge to `master` through GitHub Actions. The deployment happens through Lerna which determines which packages throughout the Backstage project have changed. In our case, the package is called `techdocs-cli` in the repository but `@techdocs/cli` in the NPM registry. + +> Note: Once a package is published under a version, any subsequent changes will not override that version. You will need to bump up the version across the entire Backstage repository, which can be done through Lerna (see the command below). + +In order to bump up all packages, go to the root of the Backstage repository. To see the current version see the `lerna.json` under the `version` key. To then update all the versions (locally on your machine), run the following: + +```bash +git checkout -b bump-up-version +yarn lerna version --no-push --allow-branch --yes +``` + +Upon being merged to master, Lerna will then automatically publish these packages as configured by the Backstage core team. From 79d8d2ddcd8cedc53d75c4ef4a185b0edd17d43f Mon Sep 17 00:00:00 2001 From: Nikita Nek Dudnik Date: Wed, 15 Jul 2020 11:27:20 +0200 Subject: [PATCH 02/14] feat: connect UI and API --- packages/app/package.json | 1 + packages/app/src/apis.ts | 6 +- plugins/github-actions/package.json | 2 + .../src/api/GithubActionsApi.ts | 44 ++- .../src/api/GithubActionsClient.ts | 177 +++++----- .../BuildDetailsPage/BuildDetailsPage.tsx | 55 ++- .../BuildInfoCard/BuildInfoCard.tsx | 20 +- .../BuildListPage/BuildListPage.tsx | 2 +- .../BuildListTable/BuildListTable.tsx | 23 +- .../components/BuildListTable/useBuilds.ts | 323 +++--------------- plugins/github-actions/src/plugin.ts | 2 +- 11 files changed, 213 insertions(+), 442 deletions(-) diff --git a/packages/app/package.json b/packages/app/package.json index ed256e6c2d..f0e534da04 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -23,6 +23,7 @@ "@backstage/theme": "^0.1.1-alpha.13", "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", + "@octokit/rest": "^18.0.0", "history": "^5.0.0", "prop-types": "^15.7.2", "react": "^16.12.0", diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index 011c549619..6d8e1bd3c3 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -58,6 +58,7 @@ import { import { scaffolderApiRef, ScaffolderApi } from '@backstage/plugin-scaffolder'; import { rollbarApiRef, RollbarClient } from '@backstage/plugin-rollbar'; +import { Octokit } from '@octokit/rest'; import { GithubActionsClient, githubActionsApiRef, @@ -82,7 +83,10 @@ export const apis = (config: ConfigApi) => { circleCIApiRef, new CircleCIApi(`${backendUrl}/proxy/circleci/api`), ); - builder.add(githubActionsApiRef, new GithubActionsClient()); + + const octokit = new Octokit(); + const client = new GithubActionsClient({ api: octokit }); + builder.add(githubActionsApiRef, client); builder.add(featureFlagsApiRef, new FeatureFlags()); builder.add(lighthouseApiRef, new LighthouseRestApi('http://localhost:3003')); diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 8ac474169f..676e27614c 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -28,6 +28,8 @@ "@material-ui/core": "^4.9.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", + "@octokit/rest": "^18.0.0", + "@octokit/types": "^5.0.1", "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "6.0.0-beta.0", diff --git a/plugins/github-actions/src/api/GithubActionsApi.ts b/plugins/github-actions/src/api/GithubActionsApi.ts index dd75f34bf7..e6d5ff9ea6 100644 --- a/plugins/github-actions/src/api/GithubActionsApi.ts +++ b/plugins/github-actions/src/api/GithubActionsApi.ts @@ -15,7 +15,11 @@ */ import { createApiRef } from '@backstage/core'; -import { Build, BuildDetails } from './types'; +import { + ActionsListWorkflowRunsForRepoResponseData, + ActionsGetWorkflowResponseData, + ActionsGetWorkflowRunResponseData, +} from '@octokit/types'; export const githubActionsApiRef = createApiRef({ id: 'plugin.githubactions.service', @@ -23,14 +27,42 @@ export const githubActionsApiRef = createApiRef({ }); export type GithubActionsApi = { - listBuilds: ({ + listWorkflowRuns: ({ owner, repo, - token, + pageSize, + page, }: { owner: string; repo: string; - token: string; - }) => Promise; - getBuild: (buildUri: string, token: Promise) => Promise; + pageSize?: number; + page?: number; + }) => Promise; + getWorkflow: ({ + owner, + repo, + id, + }: { + owner: string; + repo: string; + id: number; + }) => Promise; + getWorkflowRun: ({ + owner, + repo, + id, + }: { + owner: string; + repo: string; + id: number; + }) => Promise; + reRunWorkflow: ({ + owner, + repo, + runId, + }: { + owner: string; + repo: string; + runId: number; + }) => void; }; diff --git a/plugins/github-actions/src/api/GithubActionsClient.ts b/plugins/github-actions/src/api/GithubActionsClient.ts index 58d7280c1f..a22164e9c5 100644 --- a/plugins/github-actions/src/api/GithubActionsClient.ts +++ b/plugins/github-actions/src/api/GithubActionsClient.ts @@ -15,117 +15,94 @@ */ import { GithubActionsApi } from './GithubActionsApi'; -import { Build, BuildDetails, BuildStatus, WorkflowRun } from './types'; +import { Octokit } from '@octokit/rest'; +import { + ActionsListWorkflowRunsForRepoResponseData, + ActionsGetWorkflowResponseData, + ActionsGetWorkflowRunResponseData, +} from '@octokit/types'; -const statusToBuildStatus: { [status: string]: BuildStatus } = { - success: BuildStatus.Success, - failure: BuildStatus.Failure, - pending: BuildStatus.Pending, - running: BuildStatus.Running, - in_progress: BuildStatus.Running, - completed: BuildStatus.Success, -}; +// const statusToBuildStatus: { [status: string]: BuildStatus } = { +// success: BuildStatus.Success, +// failure: BuildStatus.Failure, +// pending: BuildStatus.Pending, +// running: BuildStatus.Running, +// in_progress: BuildStatus.Running, +// completed: BuildStatus.Success, +// }; -const conclusionToStatus = (conslusion: string): BuildStatus => - statusToBuildStatus[conslusion] ?? BuildStatus.Null; +// const conclusionToStatus = (conslusion: string): BuildStatus => +// statusToBuildStatus[conslusion] ?? BuildStatus.Null; export class GithubActionsClient implements GithubActionsApi { - async listBuilds({ + private api: Octokit; + constructor({ api }: { api: Octokit }) { + this.api = api; + } + reRunWorkflow({ owner, repo, - token, + runId, }: { owner: string; repo: string; - token: string; - }): Promise { - const url = `https://api.github.com/repos/${owner}/${repo}/actions/runs`; - - const response = await fetch(url, { - headers: new Headers({ - Authorization: `Bearer ${token}`, - }), + runId: number; + }) { + this.api.actions.reRunWorkflow({ + owner, + repo, + run_id: runId, }); - - if (!response.ok) { - return [ - { - commitId: 'Error', - message: 'Response status is not OK', - branch: 'Error', - status: BuildStatus.Failure, - uri: 'Error', - }, - ]; - } - - const data = await response.json(); - - const newData: WorkflowRun[] = data.workflow_runs; - - const endData: Build[] = []; - - newData.forEach((element, index) => { - const transData: Build = { - commitId: '', - message: '', - branch: '', - status: BuildStatus.Null, - uri: '', - }; - transData.commitId = String(element.head_commit.id); - transData.branch = element.head_branch; - transData.status = conclusionToStatus(element.conclusion); - transData.message = element.head_commit.message; - transData.uri = element.url; - endData[index] = transData; - }); - - return endData; } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - async getBuild( - buildUri: string, - token: Promise, - ): Promise { - const response = await fetch(buildUri, { - headers: new Headers({ - Authorization: `Bearer ${await token}`, - }), + async listWorkflowRuns({ + owner, + repo, + pageSize = 100, + page = 0, + }: { + owner: string; + repo: string; + pageSize?: number; + page?: number; + }): Promise { + const workflowRuns = await this.api.actions.listWorkflowRunsForRepo({ + owner, + repo, + per_page: pageSize, + page, }); - const buildBlank: Build = { - commitId: '', - message: '', - branch: '', - status: BuildStatus.Null, - uri: '', - }; - - const dataBlank: BuildDetails = { - build: buildBlank, - author: '', - logUrl: '', - overviewUrl: '', - }; - - if (!response.ok) { - return dataBlank; - } - - const data = await response.json(); - - const newData: WorkflowRun = data; - - dataBlank.author = newData.head_commit.author.name; - dataBlank.build.branch = newData.head_branch; - dataBlank.build.commitId = newData.head_commit.id; - dataBlank.build.message = newData.head_commit.message; - dataBlank.build.status = conclusionToStatus(newData.status); - dataBlank.build.uri = newData.url; - dataBlank.logUrl = newData.logs_url; - dataBlank.overviewUrl = newData.html_url; - - return dataBlank; + return workflowRuns.data; + } + async getWorkflow({ + owner, + repo, + id, + }: { + owner: string; + repo: string; + id: number; + }): Promise { + const workflow = await this.api.actions.getWorkflow({ + owner, + repo, + workflow_id: id, + }); + return workflow.data; + } + async getWorkflowRun({ + owner, + repo, + id, + }: { + owner: string; + repo: string; + id: number; + }): Promise { + const run = await this.api.actions.getWorkflowRun({ + owner, + repo, + run_id: id, + }); + return run.data; } } diff --git a/plugins/github-actions/src/components/BuildDetailsPage/BuildDetailsPage.tsx b/plugins/github-actions/src/components/BuildDetailsPage/BuildDetailsPage.tsx index 707c670f40..fd77f93c86 100644 --- a/plugins/github-actions/src/components/BuildDetailsPage/BuildDetailsPage.tsx +++ b/plugins/github-actions/src/components/BuildDetailsPage/BuildDetailsPage.tsx @@ -16,7 +16,6 @@ import { Button, - ButtonGroup, LinearProgress, makeStyles, Paper, @@ -29,10 +28,9 @@ import { Typography, } from '@material-ui/core'; import React from 'react'; -import { useLocation } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import { useAsync } from 'react-use'; -import { BuildStatusIndicator } from '../BuildStatusIndicator'; -import { Link, useApi, githubAuthApiRef } from '@backstage/core'; +import { Link, useApi } from '@backstage/core'; import { githubActionsApiRef } from '../../api'; const useStyles = makeStyles(theme => ({ @@ -49,15 +47,23 @@ const useStyles = makeStyles(theme => ({ })); export const BuildDetailsPage = () => { + const repo = 'try-ssr'; + const owner = 'CircleCITest3'; const api = useApi(githubActionsApiRef); - const githubApi = useApi(githubAuthApiRef); - const token = githubApi.getAccessToken('repo'); const classes = useStyles(); - const location = useLocation(); + const { id } = useParams(); const status = useAsync( () => - api.getBuild(decodeURIComponent(location.search.split('uri=')[1]), token), + api + .getWorkflowRun({ + owner, + repo, + id: parseInt(id, 10), + }) + .then(data => { + return data; + }), [location.search], ); @@ -90,55 +96,42 @@ export const BuildDetailsPage = () => { Branch - {details?.build.branch} + {details?.head_branch} Message - {details?.build.message} + {details?.head_commit.message} Commit ID - {details?.build.commitId} + {details?.head_commit.id} Status - - - + {details?.status} Author - {details?.author} + {`${details?.head_commit.author.name} (${details?.head_commit.author.email})`} Links - - {details?.overviewUrl && ( - - )} - {details?.logUrl && ( - - )} - + {details?.html_url && ( + + )} diff --git a/plugins/github-actions/src/components/BuildInfoCard/BuildInfoCard.tsx b/plugins/github-actions/src/components/BuildInfoCard/BuildInfoCard.tsx index cbbc1da339..f26b153435 100644 --- a/plugins/github-actions/src/components/BuildInfoCard/BuildInfoCard.tsx +++ b/plugins/github-actions/src/components/BuildInfoCard/BuildInfoCard.tsx @@ -27,8 +27,8 @@ import { import React from 'react'; import { useAsync } from 'react-use'; import { BuildStatusIndicator } from '../BuildStatusIndicator'; -import { githubActionsApiRef } from '../../api'; -import { Link, useApi, githubAuthApiRef } from '@backstage/core'; +import { githubActionsApiRef, BuildStatus } from '../../api'; +import { Link, useApi } from '@backstage/core'; const useStyles = makeStyles(theme => ({ root: { @@ -41,11 +41,9 @@ const useStyles = makeStyles(theme => ({ const BuildInfoCardContent = () => { const api = useApi(githubActionsApiRef); - const githubApi = useApi(githubAuthApiRef); const status = useAsync(async () => { - const token = await githubApi.getAccessToken('repo'); - return api.listBuilds({ owner: 'spotify', repo: 'backstage', token }); + return api.listWorkflowRuns({ owner: 'spotify', repo: 'backstage' }); }); if (status.loading) { @@ -58,8 +56,8 @@ const BuildInfoCardContent = () => { ); } - const [build] = - status.value?.filter(({ branch }) => branch === 'master') ?? []; + // const [build] = + // status.value?.filter(({ branch }) => branch === 'master') ?? []; return ( @@ -69,8 +67,8 @@ const BuildInfoCardContent = () => { Message - - {build?.message} + + build message @@ -78,14 +76,14 @@ const BuildInfoCardContent = () => { Commit ID - {build?.commitId} + build commit id Status - + diff --git a/plugins/github-actions/src/components/BuildListPage/BuildListPage.tsx b/plugins/github-actions/src/components/BuildListPage/BuildListPage.tsx index 9f6807d8bd..172b3611bf 100644 --- a/plugins/github-actions/src/components/BuildListPage/BuildListPage.tsx +++ b/plugins/github-actions/src/components/BuildListPage/BuildListPage.tsx @@ -47,7 +47,7 @@ export const BuildListPage = () => { - + diff --git a/plugins/github-actions/src/components/BuildListTable/BuildListTable.tsx b/plugins/github-actions/src/components/BuildListTable/BuildListTable.tsx index dc593afdbc..b5fd4636f5 100644 --- a/plugins/github-actions/src/components/BuildListTable/BuildListTable.tsx +++ b/plugins/github-actions/src/components/BuildListTable/BuildListTable.tsx @@ -74,7 +74,7 @@ const generatedColumns: TableColumn[] = [ field: 'buildName', highlight: true, render: (row: Partial) => ( - + {row.buildName} ), @@ -161,16 +161,23 @@ const BuildListTableView: FC = ({ ); }; -const noop = () => {}; - -export const BuildListTable = () => { - const [tableProps] = useBuilds(); +export const BuildListTable = ({ + repo, + owner, +}: { + repo: string; + owner: string; +}) => { + const [tableProps, { retry, setPage, setPageSize }] = useBuilds({ + repo, + owner, + }); return ( ); }; diff --git a/plugins/github-actions/src/components/BuildListTable/useBuilds.ts b/plugins/github-actions/src/components/BuildListTable/useBuilds.ts index 2ac5ef98d6..6d21df2df9 100644 --- a/plugins/github-actions/src/components/BuildListTable/useBuilds.ts +++ b/plugins/github-actions/src/components/BuildListTable/useBuilds.ts @@ -13,300 +13,57 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useCallback, useState } from 'react'; +import { useState } from 'react'; import { useAsyncRetry } from 'react-use'; import { Build } from './BuildListTable'; +import { githubActionsApiRef } from '../../api/GithubActionsApi'; +import { useApi } from '@backstage/core'; +import { ActionsListWorkflowRunsForRepoResponseData } from '@octokit/types'; -// TODO(shmidt-i): use real APIs -const useEntityGHSettings = () => ({ repo: 'test', owner: 'shmidt-i-test' }); -const buildsMock = { - total_count: 1, - workflow_runs: [ - { - id: 30433642, - node_id: 'MDEyOldvcmtmbG93IFJ1bjI2OTI4OQ==', - head_branch: 'master', - head_sha: 'acb5820ced9479c074f688cc328bf03f341a511d', - run_number: 562, - event: 'push', - status: 'queued', - conclusion: null, - workflow_id: 159038, - url: - 'https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642', - html_url: 'https://github.com/octo-org/octo-repo/actions/runs/30433642', - pull_requests: [], - created_at: '2020-01-22T19:33:08Z', - updated_at: '2020-01-22T19:33:08Z', - jobs_url: - 'https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/jobs', - logs_url: - 'https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/logs', - check_suite_url: - 'https://api.github.com/repos/octo-org/octo-repo/check-suites/414944374', - artifacts_url: - 'https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/artifacts', - cancel_url: - 'https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/cancel', - rerun_url: - 'https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/rerun', - workflow_url: - 'https://api.github.com/repos/octo-org/octo-repo/actions/workflows/159038', - head_commit: { - id: 'acb5820ced9479c074f688cc328bf03f341a511d', - tree_id: 'd23f6eedb1e1b9610bbc754ddb5197bfe7271223', - message: 'Create linter.yml', - timestamp: '2020-01-22T19:33:05Z', - author: { - name: 'Octo Cat', - email: 'octocat@github.com', - }, - committer: { - name: 'GitHub', - email: 'noreply@github.com', - }, - }, - repository: { - id: 1296269, - node_id: 'MDEwOlJlcG9zaXRvcnkxMjk2MjY5', - name: 'Hello-World', - full_name: 'octocat/Hello-World', - owner: { - login: 'octocat', - id: 1, - node_id: 'MDQ6VXNlcjE=', - avatar_url: 'https://github.com/images/error/octocat_happy.gif', - gravatar_id: '', - url: 'https://api.github.com/users/octocat', - html_url: 'https://github.com/octocat', - followers_url: 'https://api.github.com/users/octocat/followers', - following_url: - 'https://api.github.com/users/octocat/following{/other_user}', - gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}', - starred_url: - 'https://api.github.com/users/octocat/starred{/owner}{/repo}', - subscriptions_url: - 'https://api.github.com/users/octocat/subscriptions', - organizations_url: 'https://api.github.com/users/octocat/orgs', - repos_url: 'https://api.github.com/users/octocat/repos', - events_url: 'https://api.github.com/users/octocat/events{/privacy}', - received_events_url: - 'https://api.github.com/users/octocat/received_events', - type: 'User', - site_admin: false, - }, - private: false, - html_url: 'https://github.com/octocat/Hello-World', - description: 'This your first repo!', - fork: false, - url: 'https://api.github.com/repos/octocat/Hello-World', - archive_url: - 'http://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}', - assignees_url: - 'http://api.github.com/repos/octocat/Hello-World/assignees{/user}', - blobs_url: - 'http://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}', - branches_url: - 'http://api.github.com/repos/octocat/Hello-World/branches{/branch}', - collaborators_url: - 'http://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}', - comments_url: - 'http://api.github.com/repos/octocat/Hello-World/comments{/number}', - commits_url: - 'http://api.github.com/repos/octocat/Hello-World/commits{/sha}', - compare_url: - 'http://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}', - contents_url: - 'http://api.github.com/repos/octocat/Hello-World/contents/{+path}', - contributors_url: - 'http://api.github.com/repos/octocat/Hello-World/contributors', - deployments_url: - 'http://api.github.com/repos/octocat/Hello-World/deployments', - downloads_url: - 'http://api.github.com/repos/octocat/Hello-World/downloads', - events_url: 'http://api.github.com/repos/octocat/Hello-World/events', - forks_url: 'http://api.github.com/repos/octocat/Hello-World/forks', - git_commits_url: - 'http://api.github.com/repos/octocat/Hello-World/git/commits{/sha}', - git_refs_url: - 'http://api.github.com/repos/octocat/Hello-World/git/refs{/sha}', - git_tags_url: - 'http://api.github.com/repos/octocat/Hello-World/git/tags{/sha}', - git_url: 'git:github.com/octocat/Hello-World.git', - issue_comment_url: - 'http://api.github.com/repos/octocat/Hello-World/issues/comments{/number}', - issue_events_url: - 'http://api.github.com/repos/octocat/Hello-World/issues/events{/number}', - issues_url: - 'http://api.github.com/repos/octocat/Hello-World/issues{/number}', - keys_url: - 'http://api.github.com/repos/octocat/Hello-World/keys{/key_id}', - labels_url: - 'http://api.github.com/repos/octocat/Hello-World/labels{/name}', - languages_url: - 'http://api.github.com/repos/octocat/Hello-World/languages', - merges_url: 'http://api.github.com/repos/octocat/Hello-World/merges', - milestones_url: - 'http://api.github.com/repos/octocat/Hello-World/milestones{/number}', - notifications_url: - 'http://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}', - pulls_url: - 'http://api.github.com/repos/octocat/Hello-World/pulls{/number}', - releases_url: - 'http://api.github.com/repos/octocat/Hello-World/releases{/id}', - ssh_url: 'git@github.com:octocat/Hello-World.git', - stargazers_url: - 'http://api.github.com/repos/octocat/Hello-World/stargazers', - statuses_url: - 'http://api.github.com/repos/octocat/Hello-World/statuses/{sha}', - subscribers_url: - 'http://api.github.com/repos/octocat/Hello-World/subscribers', - subscription_url: - 'http://api.github.com/repos/octocat/Hello-World/subscription', - tags_url: 'http://api.github.com/repos/octocat/Hello-World/tags', - teams_url: 'http://api.github.com/repos/octocat/Hello-World/teams', - trees_url: - 'http://api.github.com/repos/octocat/Hello-World/git/trees{/sha}', - }, - head_repository: { - id: 217723378, - node_id: 'MDEwOlJlcG9zaXRvcnkyMTc3MjMzNzg=', - name: 'octo-repo', - full_name: 'octo-org/octo-repo', - private: true, - owner: { - login: 'octocat', - id: 1, - node_id: 'MDQ6VXNlcjE=', - avatar_url: 'https://github.com/images/error/octocat_happy.gif', - gravatar_id: '', - url: 'https://api.github.com/users/octocat', - html_url: 'https://github.com/octocat', - followers_url: 'https://api.github.com/users/octocat/followers', - following_url: - 'https://api.github.com/users/octocat/following{/other_user}', - gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}', - starred_url: - 'https://api.github.com/users/octocat/starred{/owner}{/repo}', - subscriptions_url: - 'https://api.github.com/users/octocat/subscriptions', - organizations_url: 'https://api.github.com/users/octocat/orgs', - repos_url: 'https://api.github.com/users/octocat/repos', - events_url: 'https://api.github.com/users/octocat/events{/privacy}', - received_events_url: - 'https://api.github.com/users/octocat/received_events', - type: 'User', - site_admin: false, - }, - html_url: 'https://github.com/octo-org/octo-repo', - description: null, - fork: false, - url: 'https://api.github.com/repos/octo-org/octo-repo', - forks_url: 'https://api.github.com/repos/octo-org/octo-repo/forks', - keys_url: - 'https://api.github.com/repos/octo-org/octo-repo/keys{/key_id}', - collaborators_url: - 'https://api.github.com/repos/octo-org/octo-repo/collaborators{/collaborator}', - teams_url: 'https://api.github.com/repos/octo-org/octo-repo/teams', - hooks_url: 'https://api.github.com/repos/octo-org/octo-repo/hooks', - issue_events_url: - 'https://api.github.com/repos/octo-org/octo-repo/issues/events{/number}', - events_url: 'https://api.github.com/repos/octo-org/octo-repo/events', - assignees_url: - 'https://api.github.com/repos/octo-org/octo-repo/assignees{/user}', - branches_url: - 'https://api.github.com/repos/octo-org/octo-repo/branches{/branch}', - tags_url: 'https://api.github.com/repos/octo-org/octo-repo/tags', - blobs_url: - 'https://api.github.com/repos/octo-org/octo-repo/git/blobs{/sha}', - git_tags_url: - 'https://api.github.com/repos/octo-org/octo-repo/git/tags{/sha}', - git_refs_url: - 'https://api.github.com/repos/octo-org/octo-repo/git/refs{/sha}', - trees_url: - 'https://api.github.com/repos/octo-org/octo-repo/git/trees{/sha}', - statuses_url: - 'https://api.github.com/repos/octo-org/octo-repo/statuses/{sha}', - languages_url: - 'https://api.github.com/repos/octo-org/octo-repo/languages', - stargazers_url: - 'https://api.github.com/repos/octo-org/octo-repo/stargazers', - contributors_url: - 'https://api.github.com/repos/octo-org/octo-repo/contributors', - subscribers_url: - 'https://api.github.com/repos/octo-org/octo-repo/subscribers', - subscription_url: - 'https://api.github.com/repos/octo-org/octo-repo/subscription', - commits_url: - 'https://api.github.com/repos/octo-org/octo-repo/commits{/sha}', - git_commits_url: - 'https://api.github.com/repos/octo-org/octo-repo/git/commits{/sha}', - comments_url: - 'https://api.github.com/repos/octo-org/octo-repo/comments{/number}', - issue_comment_url: - 'https://api.github.com/repos/octo-org/octo-repo/issues/comments{/number}', - contents_url: - 'https://api.github.com/repos/octo-org/octo-repo/contents/{+path}', - compare_url: - 'https://api.github.com/repos/octo-org/octo-repo/compare/{base}...{head}', - merges_url: 'https://api.github.com/repos/octo-org/octo-repo/merges', - archive_url: - 'https://api.github.com/repos/octo-org/octo-repo/{archive_format}{/ref}', - downloads_url: - 'https://api.github.com/repos/octo-org/octo-repo/downloads', - issues_url: - 'https://api.github.com/repos/octo-org/octo-repo/issues{/number}', - pulls_url: - 'https://api.github.com/repos/octo-org/octo-repo/pulls{/number}', - milestones_url: - 'https://api.github.com/repos/octo-org/octo-repo/milestones{/number}', - notifications_url: - 'https://api.github.com/repos/octo-org/octo-repo/notifications{?since,all,participating}', - labels_url: - 'https://api.github.com/repos/octo-org/octo-repo/labels{/name}', - releases_url: - 'https://api.github.com/repos/octo-org/octo-repo/releases{/id}', - deployments_url: - 'https://api.github.com/repos/octo-org/octo-repo/deployments', - }, - }, - ], -}; - -export function useBuilds() { - const { repo, owner } = useEntityGHSettings(); +export function useBuilds({ repo, owner }: { repo: string; owner: string }) { + const api = useApi(githubActionsApiRef); const [total, setTotal] = useState(0); const [page, setPage] = useState(0); const [pageSize, setPageSize] = useState(5); - const getBuilds = useCallback(async () => buildsMock, []); const restartBuild = async () => {}; - const { loading, value: builds, retry } = useAsyncRetry( + const { loading, value: builds, retry } = useAsyncRetry( () => - getBuilds().then((allBuilds): Build[] => { - setTotal(allBuilds.total_count); - // Transformation here - return allBuilds.workflow_runs.map(run => ({ - buildName: run.head_commit.message, - id: `${run.id}`, - onRestartClick: () => {}, - source: { - branchName: run.head_branch, - commit: { - hash: run.head_commit.id, - url: run.head_repository.branches_url.replace( - '{/branch}', - run.head_branch, - ), - }, + api + // GitHub API pagination count starts from 1 + .listWorkflowRuns({ owner, repo, pageSize, page: page + 1 }) + .then( + (allBuilds: ActionsListWorkflowRunsForRepoResponseData): Build[] => { + setTotal(allBuilds.total_count); + // Transformation here + return allBuilds.workflow_runs.map(run => ({ + buildName: run.head_commit.message, + id: `${run.id}`, + onRestartClick: () => { + api.reRunWorkflow({ + owner, + repo, + runId: run.id, + }); + }, + source: { + branchName: run.head_branch, + commit: { + hash: run.head_commit.id, + url: run.head_repository.branches_url.replace( + '{/branch}', + run.head_branch, + ), + }, + }, + status: run.status, + buildUrl: run.url, + })); }, - status: run.status, - buildUrl: run.url, - })); - }), - [page, pageSize, getBuilds], + ), + [page, pageSize], ); const projectName = `${owner}/${repo}`; @@ -320,7 +77,7 @@ export function useBuilds() { total, }, { - getBuilds, + builds, setPage, setPageSize, restartBuild, diff --git a/plugins/github-actions/src/plugin.ts b/plugins/github-actions/src/plugin.ts index 8897fe53db..b728296cbc 100644 --- a/plugins/github-actions/src/plugin.ts +++ b/plugins/github-actions/src/plugin.ts @@ -24,7 +24,7 @@ export const rootRouteRef = createRouteRef({ title: 'GitHub Actions', }); export const buildRouteRef = createRouteRef({ - path: '/github-actions/builds', + path: '/github-actions/build/:id', title: 'GitHub Actions Build', }); From eda7f30da27090907c11dfdacdec75229795ba1a Mon Sep 17 00:00:00 2001 From: Nikita Dudnik Date: Thu, 16 Jul 2020 11:03:58 +0200 Subject: [PATCH 03/14] Update packages/app/src/apis.ts Shorten the code Co-authored-by: Ivan Shmidt --- packages/app/src/apis.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index 6d8e1bd3c3..b72a5f1c6d 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -85,8 +85,7 @@ export const apis = (config: ConfigApi) => { ); const octokit = new Octokit(); - const client = new GithubActionsClient({ api: octokit }); - builder.add(githubActionsApiRef, client); + builder.add(githubActionsApiRef, new GithubActionsClient({ api: octokit })); builder.add(featureFlagsApiRef, new FeatureFlags()); builder.add(lighthouseApiRef, new LighthouseRestApi('http://localhost:3003')); From 0bfadd867693ebc9f21dd14f6695c44aa5640b03 Mon Sep 17 00:00:00 2001 From: Nikita Nek Dudnik Date: Thu, 16 Jul 2020 11:11:19 +0200 Subject: [PATCH 04/14] fix: code review --- packages/app/src/apis.ts | 3 ++- .../github-actions/src/api/GithubActionsClient.ts | 12 ------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index b72a5f1c6d..ca0e2298cf 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -84,8 +84,9 @@ export const apis = (config: ConfigApi) => { new CircleCIApi(`${backendUrl}/proxy/circleci/api`), ); - const octokit = new Octokit(); + const octokit = new Octokit({ auth: process.env.GITHUB_ACCESS_TOKEN }); builder.add(githubActionsApiRef, new GithubActionsClient({ api: octokit })); + builder.add(featureFlagsApiRef, new FeatureFlags()); builder.add(lighthouseApiRef, new LighthouseRestApi('http://localhost:3003')); diff --git a/plugins/github-actions/src/api/GithubActionsClient.ts b/plugins/github-actions/src/api/GithubActionsClient.ts index a22164e9c5..c2efa44539 100644 --- a/plugins/github-actions/src/api/GithubActionsClient.ts +++ b/plugins/github-actions/src/api/GithubActionsClient.ts @@ -22,18 +22,6 @@ import { ActionsGetWorkflowRunResponseData, } from '@octokit/types'; -// const statusToBuildStatus: { [status: string]: BuildStatus } = { -// success: BuildStatus.Success, -// failure: BuildStatus.Failure, -// pending: BuildStatus.Pending, -// running: BuildStatus.Running, -// in_progress: BuildStatus.Running, -// completed: BuildStatus.Success, -// }; - -// const conclusionToStatus = (conslusion: string): BuildStatus => -// statusToBuildStatus[conslusion] ?? BuildStatus.Null; - export class GithubActionsClient implements GithubActionsApi { private api: Octokit; constructor({ api }: { api: Octokit }) { From e782b5cd48772fbd8bac044f686748cd5d17a77c Mon Sep 17 00:00:00 2001 From: Nikita Nek Dudnik Date: Thu, 16 Jul 2020 16:24:09 +0200 Subject: [PATCH 05/14] fix: use gitgub token from UI --- packages/app/src/apis.ts | 4 +-- .../src/api/GithubActionsApi.ts | 8 +++++ .../src/api/GithubActionsClient.ts | 22 +++++++++----- .../BuildDetailsPage/BuildDetailsPage.tsx | 29 ++++++++++--------- .../BuildInfoCard/BuildInfoCard.tsx | 6 ++-- .../components/BuildListTable/useBuilds.ts | 18 +++++++----- 6 files changed, 53 insertions(+), 34 deletions(-) diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index ca0e2298cf..cac3d6e171 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -58,7 +58,6 @@ import { import { scaffolderApiRef, ScaffolderApi } from '@backstage/plugin-scaffolder'; import { rollbarApiRef, RollbarClient } from '@backstage/plugin-rollbar'; -import { Octokit } from '@octokit/rest'; import { GithubActionsClient, githubActionsApiRef, @@ -84,8 +83,7 @@ export const apis = (config: ConfigApi) => { new CircleCIApi(`${backendUrl}/proxy/circleci/api`), ); - const octokit = new Octokit({ auth: process.env.GITHUB_ACCESS_TOKEN }); - builder.add(githubActionsApiRef, new GithubActionsClient({ api: octokit })); + builder.add(githubActionsApiRef, new GithubActionsClient()); builder.add(featureFlagsApiRef, new FeatureFlags()); diff --git a/plugins/github-actions/src/api/GithubActionsApi.ts b/plugins/github-actions/src/api/GithubActionsApi.ts index e6d5ff9ea6..eedf9686f3 100644 --- a/plugins/github-actions/src/api/GithubActionsApi.ts +++ b/plugins/github-actions/src/api/GithubActionsApi.ts @@ -28,39 +28,47 @@ export const githubActionsApiRef = createApiRef({ export type GithubActionsApi = { listWorkflowRuns: ({ + token, owner, repo, pageSize, page, }: { + token: string; owner: string; repo: string; pageSize?: number; page?: number; }) => Promise; getWorkflow: ({ + token, owner, repo, id, }: { + token: string; owner: string; repo: string; id: number; }) => Promise; getWorkflowRun: ({ + token, owner, repo, id, }: { + token: string; owner: string; repo: string; id: number; }) => Promise; reRunWorkflow: ({ + token, owner, repo, runId, }: { + token: string; owner: string; repo: string; runId: number; diff --git a/plugins/github-actions/src/api/GithubActionsClient.ts b/plugins/github-actions/src/api/GithubActionsClient.ts index c2efa44539..1606c268f4 100644 --- a/plugins/github-actions/src/api/GithubActionsClient.ts +++ b/plugins/github-actions/src/api/GithubActionsClient.ts @@ -23,37 +23,39 @@ import { } from '@octokit/types'; export class GithubActionsClient implements GithubActionsApi { - private api: Octokit; - constructor({ api }: { api: Octokit }) { - this.api = api; - } reRunWorkflow({ + token, owner, repo, runId, }: { + token: string; owner: string; repo: string; runId: number; }) { - this.api.actions.reRunWorkflow({ + new Octokit({ auth: token }).actions.reRunWorkflow({ owner, repo, run_id: runId, }); } async listWorkflowRuns({ + token, owner, repo, pageSize = 100, page = 0, }: { + token: string; owner: string; repo: string; pageSize?: number; page?: number; }): Promise { - const workflowRuns = await this.api.actions.listWorkflowRunsForRepo({ + const workflowRuns = await new Octokit({ + auth: token, + }).actions.listWorkflowRunsForRepo({ owner, repo, per_page: pageSize, @@ -62,15 +64,17 @@ export class GithubActionsClient implements GithubActionsApi { return workflowRuns.data; } async getWorkflow({ + token, owner, repo, id, }: { + token: string; owner: string; repo: string; id: number; }): Promise { - const workflow = await this.api.actions.getWorkflow({ + const workflow = await new Octokit({ auth: token }).actions.getWorkflow({ owner, repo, workflow_id: id, @@ -78,15 +82,17 @@ export class GithubActionsClient implements GithubActionsApi { return workflow.data; } async getWorkflowRun({ + token, owner, repo, id, }: { + token: string; owner: string; repo: string; id: number; }): Promise { - const run = await this.api.actions.getWorkflowRun({ + const run = await new Octokit({ auth: token }).actions.getWorkflowRun({ owner, repo, run_id: id, diff --git a/plugins/github-actions/src/components/BuildDetailsPage/BuildDetailsPage.tsx b/plugins/github-actions/src/components/BuildDetailsPage/BuildDetailsPage.tsx index fd77f93c86..55c568106c 100644 --- a/plugins/github-actions/src/components/BuildDetailsPage/BuildDetailsPage.tsx +++ b/plugins/github-actions/src/components/BuildDetailsPage/BuildDetailsPage.tsx @@ -30,7 +30,7 @@ import { import React from 'react'; import { useParams } from 'react-router-dom'; import { useAsync } from 'react-use'; -import { Link, useApi } from '@backstage/core'; +import { Link, useApi, githubAuthApiRef } from '@backstage/core'; import { githubActionsApiRef } from '../../api'; const useStyles = makeStyles(theme => ({ @@ -50,22 +50,23 @@ export const BuildDetailsPage = () => { const repo = 'try-ssr'; const owner = 'CircleCITest3'; const api = useApi(githubActionsApiRef); + const auth = useApi(githubAuthApiRef); const classes = useStyles(); const { id } = useParams(); - const status = useAsync( - () => - api - .getWorkflowRun({ - owner, - repo, - id: parseInt(id, 10), - }) - .then(data => { - return data; - }), - [location.search], - ); + const status = useAsync(async () => { + const token = await auth.getAccessToken(['repo', 'user']); + return api + .getWorkflowRun({ + token, + owner, + repo, + id: parseInt(id, 10), + }) + .then(data => { + return data; + }); + }, [location.search]); if (status.loading) { return ; diff --git a/plugins/github-actions/src/components/BuildInfoCard/BuildInfoCard.tsx b/plugins/github-actions/src/components/BuildInfoCard/BuildInfoCard.tsx index f26b153435..acc1b496ec 100644 --- a/plugins/github-actions/src/components/BuildInfoCard/BuildInfoCard.tsx +++ b/plugins/github-actions/src/components/BuildInfoCard/BuildInfoCard.tsx @@ -28,7 +28,7 @@ import React from 'react'; import { useAsync } from 'react-use'; import { BuildStatusIndicator } from '../BuildStatusIndicator'; import { githubActionsApiRef, BuildStatus } from '../../api'; -import { Link, useApi } from '@backstage/core'; +import { Link, useApi, githubAuthApiRef } from '@backstage/core'; const useStyles = makeStyles(theme => ({ root: { @@ -41,9 +41,11 @@ const useStyles = makeStyles(theme => ({ const BuildInfoCardContent = () => { const api = useApi(githubActionsApiRef); + const auth = useApi(githubAuthApiRef); const status = useAsync(async () => { - return api.listWorkflowRuns({ owner: 'spotify', repo: 'backstage' }); + const token = await auth.getAccessToken(['repo', 'user']); + return api.listWorkflowRuns({ token, owner: 'spotify', repo: 'backstage' }); }); if (status.loading) { diff --git a/plugins/github-actions/src/components/BuildListTable/useBuilds.ts b/plugins/github-actions/src/components/BuildListTable/useBuilds.ts index 6d21df2df9..7b93e178d6 100644 --- a/plugins/github-actions/src/components/BuildListTable/useBuilds.ts +++ b/plugins/github-actions/src/components/BuildListTable/useBuilds.ts @@ -17,11 +17,12 @@ import { useState } from 'react'; import { useAsyncRetry } from 'react-use'; import { Build } from './BuildListTable'; import { githubActionsApiRef } from '../../api/GithubActionsApi'; -import { useApi } from '@backstage/core'; +import { useApi, githubAuthApiRef } from '@backstage/core'; import { ActionsListWorkflowRunsForRepoResponseData } from '@octokit/types'; export function useBuilds({ repo, owner }: { repo: string; owner: string }) { const api = useApi(githubActionsApiRef); + const auth = useApi(githubAuthApiRef); const [total, setTotal] = useState(0); const [page, setPage] = useState(0); @@ -29,11 +30,13 @@ export function useBuilds({ repo, owner }: { repo: string; owner: string }) { const restartBuild = async () => {}; - const { loading, value: builds, retry } = useAsyncRetry( - () => + const { loading, value: builds, retry } = useAsyncRetry(async () => { + const token = await auth.getAccessToken(['repo', 'user']); + + return ( api // GitHub API pagination count starts from 1 - .listWorkflowRuns({ owner, repo, pageSize, page: page + 1 }) + .listWorkflowRuns({ token, owner, repo, pageSize, page: page + 1 }) .then( (allBuilds: ActionsListWorkflowRunsForRepoResponseData): Build[] => { setTotal(allBuilds.total_count); @@ -43,6 +46,7 @@ export function useBuilds({ repo, owner }: { repo: string; owner: string }) { id: `${run.id}`, onRestartClick: () => { api.reRunWorkflow({ + token, owner, repo, runId: run.id, @@ -62,9 +66,9 @@ export function useBuilds({ repo, owner }: { repo: string; owner: string }) { buildUrl: run.url, })); }, - ), - [page, pageSize], - ); + ) + ); + }, [page, pageSize]); const projectName = `${owner}/${repo}`; return [ From 2ac6422640474a138a1a6c91dea5f242411a8fb1 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 17 Jul 2020 10:57:07 +0200 Subject: [PATCH 06/14] cli: pin esbuild to 0.6.3 --- packages/cli/package.json | 1 + yarn.lock | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 55462d1ebf..454df97a36 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -53,6 +53,7 @@ "css-loader": "^3.5.3", "dashify": "^2.0.0", "diff": "^4.0.2", + "esbuild": "0.6.3", "eslint": "^7.1.0", "eslint-formatter-friendly": "^7.0.0", "eslint-plugin-import": "^2.20.2", diff --git a/yarn.lock b/yarn.lock index 3b883964f8..6c0ff99388 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8077,10 +8077,10 @@ es6-shim@^0.35.5: resolved "https://registry.npmjs.org/es6-shim/-/es6-shim-0.35.5.tgz#46f59dc0a84a1c5029e8ff1166ca0a902077a9ab" integrity sha512-E9kK/bjtCQRpN1K28Xh4BlmP8egvZBGJJ+9GtnzOwt7mdqtrjHFuVGr7QJfdjBIKqrlU5duPf3pCBoDrkjVYFg== -esbuild@^0.5.3: - version "0.5.3" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.5.3.tgz#18f5bdb618220c6f14bcb1cf5af528d02d4734c9" - integrity sha512-RVzTK62svYjnh+agJRh+NWfZX74iKwFNUX52cF7Mo4QPS6bKxP1o+8GacPUMND2QnodVp2D3nKJs8gLspSfZzA== +esbuild@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.6.3.tgz#a957e22f2503c745793514388110f9b55b3a6f83" + integrity sha512-4lHgz/EvGLRQnDYzzrvW+eilaPHim5pCLz4mP0k0QIalD/n8Ji2NwQwoIa1uX+yKkbn9R/FAZvaEbodjx55rDg== escape-goat@^2.0.0: version "2.1.1" @@ -16480,12 +16480,11 @@ rollup-plugin-dts@^1.4.6: "@babel/code-frame" "^7.8.3" rollup-plugin-esbuild@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-2.1.0.tgz#8e12337c63a5b1144e0c5e8adf2f1568ad4d7d69" - integrity sha512-XYqmwk4X0SPEExgilARbre/PplhLtE3q6wiZtfgIbwxJOVGXWec1Bkcux7TFTHGX3TQozzqEASTsRJCt7py/5Q== + version "2.3.0" + resolved "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-2.3.0.tgz#7c107d4508af80d30966a148b306cb7d5b36b258" + integrity sha512-lNbWDRaClwXauaIybuaiOBRWgxcp3GkZu0UUix9yH/OHFgVohKmzlU0NtNbvfbxAcfEooyuBRAv6YCaJl1Mbpw== dependencies: "@rollup/pluginutils" "^3.1.0" - esbuild "^0.5.3" rollup-plugin-image-files@^1.4.2: version "1.4.2" From a2955532cc669e2c366a1671602bd588f6dee980 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 16 Jul 2020 12:31:10 +0200 Subject: [PATCH 07/14] auth-backend: tweak error messages --- plugins/auth-backend/src/lib/OAuthProvider.test.ts | 4 ++-- plugins/auth-backend/src/lib/OAuthProvider.ts | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/plugins/auth-backend/src/lib/OAuthProvider.test.ts b/plugins/auth-backend/src/lib/OAuthProvider.test.ts index f67a91dfcd..3d631bd4ac 100644 --- a/plugins/auth-backend/src/lib/OAuthProvider.test.ts +++ b/plugins/auth-backend/src/lib/OAuthProvider.test.ts @@ -51,7 +51,7 @@ describe('OAuthProvider Utils', () => { } as unknown) as express.Request; expect(() => { verifyNonce(mockRequest, 'providera'); - }).toThrowError('Missing nonce'); + }).toThrowError('Auth response is missing cookie nonce'); }); it('should throw error if state nonce missing', () => { @@ -63,7 +63,7 @@ describe('OAuthProvider Utils', () => { } as unknown) as express.Request; expect(() => { verifyNonce(mockRequest, 'providera'); - }).toThrowError('Missing nonce'); + }).toThrowError('Auth response is missing state nonce'); }); it('should throw error if nonce mismatch', () => { diff --git a/plugins/auth-backend/src/lib/OAuthProvider.ts b/plugins/auth-backend/src/lib/OAuthProvider.ts index 5434b6a4ba..c4996c31a2 100644 --- a/plugins/auth-backend/src/lib/OAuthProvider.ts +++ b/plugins/auth-backend/src/lib/OAuthProvider.ts @@ -43,10 +43,12 @@ export const verifyNonce = (req: express.Request, providerId: string) => { const cookieNonce = req.cookies[`${providerId}-nonce`]; const stateNonce = req.query.state; - if (!cookieNonce || !stateNonce) { - throw new Error('Missing nonce'); + if (!cookieNonce) { + throw new Error('Auth response is missing cookie nonce'); + } + if (!stateNonce) { + throw new Error('Auth response is missing state nonce'); } - if (cookieNonce !== stateNonce) { throw new Error('Invalid nonce'); } @@ -151,9 +153,8 @@ export class OAuthProvider implements AuthProviderRouteHandlers { } if (!this.options.disableRefresh) { - // throw error if missing refresh token if (!refreshToken) { - throw new Error('Missing refresh token'); + throw new InputError('Missing refresh token'); } // set new refresh token From fc06371c6b0d0716ad85019d07c7a2fb524eac65 Mon Sep 17 00:00:00 2001 From: Ivan Shmidt Date: Fri, 17 Jul 2020 11:05:26 +0200 Subject: [PATCH 08/14] feat(scaffolder): add color bg to template cards, use correct header colors --- packages/core/src/layout/Page/PageThemeProvider.ts | 2 +- .../src/components/ScaffolderPage/ScaffolderPage.tsx | 2 +- .../src/components/TemplateCard/TemplateCard.tsx | 12 +++++++----- .../src/components/TemplatePage/TemplatePage.tsx | 3 ++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/core/src/layout/Page/PageThemeProvider.ts b/packages/core/src/layout/Page/PageThemeProvider.ts index 3df2a61aa8..36430021bb 100644 --- a/packages/core/src/layout/Page/PageThemeProvider.ts +++ b/packages/core/src/layout/Page/PageThemeProvider.ts @@ -26,7 +26,7 @@ export type PageTheme = { export const gradients: Record = { darkGrey: { - colors: ['#181818', '#404040'], + colors: ['#171717', '#383838'], waveColor: '#757575', opacity: ['1.0', '0.0'], }, diff --git a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx index a0957a6544..14823dd396 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx @@ -64,7 +64,7 @@ export const ScaffolderPage: React.FC<{}> = () => { }, [error, errorApi]); return ( - +
({ header: { color: theme.palette.common.white, padding: theme.spacing(2, 2, 6), - backgroundImage: - 'linear-gradient(-137deg, rgb(25, 230, 140) 0%, rgb(29, 127, 110) 100%)', + backgroundImage: (props: { gradientStart: string; gradientStop: string }) => + `linear-gradient(-137deg, ${props.gradientStart} 0%, ${props.gradientStop} 100%)`, }, content: { padding: theme.spacing(2), @@ -55,7 +55,9 @@ export const TemplateCard = ({ type, name, }: TemplateCardProps) => { - const classes = useStyles(); + const theme = pageTheme[type] ?? pageTheme['other']; + const [gradientStart, gradientStop] = theme.gradient.colors; + const classes = useStyles({ gradientStart, gradientStop }); const href = generatePath(templateRoute.path, { templateName: name }); return ( @@ -72,7 +74,7 @@ export const TemplateCard = ({ {description}
-
diff --git a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx index 5c949e55d9..05cc249e41 100644 --- a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx +++ b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx @@ -22,6 +22,7 @@ import { Lifecycle, Page, useApi, + pageTheme, } from '@backstage/core'; import { catalogApiRef } from '@backstage/plugin-catalog'; import { LinearProgress } from '@material-ui/core'; @@ -135,7 +136,7 @@ export const TemplatePage = () => { } return ( - +
Date: Fri, 17 Jul 2020 11:14:06 +0200 Subject: [PATCH 09/14] fix linting --- plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx index 466c10336a..7d38c6f223 100644 --- a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx @@ -55,7 +55,7 @@ export const TemplateCard = ({ type, name, }: TemplateCardProps) => { - const theme = pageTheme[type] ?? pageTheme['other']; + const theme = pageTheme[type] ?? pageTheme.other; const [gradientStart, gradientStop] = theme.gradient.colors; const classes = useStyles({ gradientStart, gradientStop }); const href = generatePath(templateRoute.path, { templateName: name }); From cbb36ea3b97f82e27977e4a981bb7c46d9719732 Mon Sep 17 00:00:00 2001 From: Jesko Steinberg Date: Fri, 17 Jul 2020 12:56:41 +0200 Subject: [PATCH 10/14] fix(build-imgae): get package name from env --- packages/cli/src/commands/backend/buildImage.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/backend/buildImage.ts b/packages/cli/src/commands/backend/buildImage.ts index a847f1ef54..e163af2875 100644 --- a/packages/cli/src/commands/backend/buildImage.ts +++ b/packages/cli/src/commands/backend/buildImage.ts @@ -20,7 +20,8 @@ import { paths } from '../../lib/paths'; import { run } from '../../lib/run'; export default async (imageTag: string) => { - const tempDistWorkspace = await createDistWorkspace(['example-backend'], { + const packageName: string = process.env.npm_package_name!; + const tempDistWorkspace = await createDistWorkspace([packageName], { files: [ 'package.json', 'yarn.lock', @@ -28,7 +29,6 @@ export default async (imageTag: string) => { { src: paths.resolveTarget('Dockerfile'), dest: 'Dockerfile' }, ], }); - console.log(`Dist workspace ready at ${tempDistWorkspace}`); await run('docker', ['build', '.', '-t', imageTag], { From ffbe547f7f003783da58059dd1c1a4750a758291 Mon Sep 17 00:00:00 2001 From: Jesko Steinberg Date: Fri, 17 Jul 2020 15:02:46 +0200 Subject: [PATCH 11/14] fix: get package name from package.json --- packages/cli/src/commands/backend/buildImage.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/backend/buildImage.ts b/packages/cli/src/commands/backend/buildImage.ts index e163af2875..258ef102d7 100644 --- a/packages/cli/src/commands/backend/buildImage.ts +++ b/packages/cli/src/commands/backend/buildImage.ts @@ -19,9 +19,12 @@ import { createDistWorkspace } from '../../lib/packager'; import { paths } from '../../lib/paths'; import { run } from '../../lib/run'; +const PKG_PATH = 'package.json'; + export default async (imageTag: string) => { - const packageName: string = process.env.npm_package_name!; - const tempDistWorkspace = await createDistWorkspace([packageName], { + const pkgPath = paths.resolveTarget(PKG_PATH); + const pkg = await fs.readJson(pkgPath); + const tempDistWorkspace = await createDistWorkspace([pkg.name], { files: [ 'package.json', 'yarn.lock', From 13a1d2552720151dd0479cff2b0862636e79eddb Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Fri, 17 Jul 2020 15:10:21 +0200 Subject: [PATCH 12/14] docs: add SDA SE to adopters (#1678) --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index ec35bc7659..b568fde271 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -5,4 +5,5 @@ | [DFDS](https://www.dfds.com) | [@carlsendk](https://github.com/carlsendk) | V2 self-service platform. | | [Roadie](https://roadie.io) | [@dtuite](https://github.com/dtuite) | Hosted, managed Backstage with easy set-up | | [Roku](https://www.roku.com) | [@timurista](https://github.com/timurista) | Initial work on Cloud engineering service platform. | +| [SDA SE](https://sda.se) | [@Fox32](https://github.com/Fox32) | Central place for developing and sharing services in our insurance ecosystem. | | [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. | From 183179669fa997c02089a36ffdb03f658ab8205a Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Fri, 17 Jul 2020 17:42:40 +0200 Subject: [PATCH 13/14] docs: Add link to Figma library (#1674) --- docs/dls/figma.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/dls/figma.md b/docs/dls/figma.md index e69de29bb2..8fe6ea8d0f 100644 --- a/docs/dls/figma.md +++ b/docs/dls/figma.md @@ -0,0 +1 @@ +We have a [Figma component library](https://www.figma.com/@backstage) that you can use to build your own plugins for Backstage. From 5e36d0cf2806f8489a7986f930662212cba1f834 Mon Sep 17 00:00:00 2001 From: Paul Pacheco Date: Fri, 17 Jul 2020 13:07:49 -0500 Subject: [PATCH 14/14] Add AA to adopters (#1684) --- ADOPTERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index b568fde271..7c05cdd5d7 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -7,3 +7,4 @@ | [Roku](https://www.roku.com) | [@timurista](https://github.com/timurista) | Initial work on Cloud engineering service platform. | | [SDA SE](https://sda.se) | [@Fox32](https://github.com/Fox32) | Central place for developing and sharing services in our insurance ecosystem. | | [H-E-B](https://www.heb.com) | [@german-j-rodriguez](https://github.com/german-j-rodriguez) | Initial work on Engineering Portal service platform. | +| [American Airlines](https://www.aa.com) | [@paulpach](https://github.com/paulpach) | Central place for developers to develop and maintain applications |