From 79d8d2ddcd8cedc53d75c4ef4a185b0edd17d43f Mon Sep 17 00:00:00 2001 From: Nikita Nek Dudnik Date: Wed, 15 Jul 2020 11:27:20 +0200 Subject: [PATCH] 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', });