diff --git a/app/src/lib/api.ts b/app/src/lib/api.ts
index 9876bc0e80..99d89ac121 100644
--- a/app/src/lib/api.ts
+++ b/app/src/lib/api.ts
@@ -341,6 +341,7 @@ export interface IAPIRefCheckRun {
readonly app: IAPIRefCheckRunApp
readonly completed_at: string
readonly started_at: string
+ readonly html_url: string
}
// NB. Only partially mapped
diff --git a/app/src/lib/stores/commit-status-store.ts b/app/src/lib/stores/commit-status-store.ts
index b6b6071ebc..a606da8f0f 100644
--- a/app/src/lib/stores/commit-status-store.ts
+++ b/app/src/lib/stores/commit-status-store.ts
@@ -36,6 +36,7 @@ export interface IRefCheck {
readonly appName: string
readonly checkSuiteId: number | null // API status don't have check suite id's
readonly output: IRefCheckOutput
+ readonly htmlUrl: string | null
}
/**
@@ -484,6 +485,7 @@ export class CommitStatusStore {
mappedCheckRuns.push({
...cr,
+ htmlUrl: matchingJob.html_url,
output: {
type: RefCheckOutputType.Actions,
title: name,
@@ -596,6 +598,7 @@ function apiStatusToRefCheck(apiStatus: IAPIRefStatusItem): IRefCheck {
title: apiStatus.context,
text: '',
},
+ htmlUrl: null,
}
}
@@ -706,6 +709,7 @@ function apiCheckRunToRefCheck(checkRun: IAPIRefCheckRun): IRefCheck {
summary: checkRun.output.summary,
text: checkRun.output.text,
},
+ htmlUrl: checkRun.html_url,
}
}
diff --git a/app/src/ui/branches/ci-check-list-item.tsx b/app/src/ui/branches/ci-check-list-item.tsx
index e0be920113..a42923d7a7 100644
--- a/app/src/ui/branches/ci-check-list-item.tsx
+++ b/app/src/ui/branches/ci-check-list-item.tsx
@@ -10,6 +10,7 @@ import { Octicon } from '../octicons'
import { getClassNameForCheck, getSymbolForCheck } from './ci-status'
import classNames from 'classnames'
import { APICheckConclusion } from '../../lib/api'
+import { Button } from '../lib/button'
interface ICICheckRunListItemProps {
/** The check run to display **/
@@ -23,16 +24,23 @@ interface ICICheckRunListItemProps {
/** Callback for when a check run is clicked */
readonly onCheckRunClick: (checkRun: IRefCheck) => void
+
+ /** Callback to opens check runs on GitHub */
+ readonly onViewOnGitHub: (checkRun: IRefCheck) => void
}
/** The CI check list item. */
export class CICheckRunListItem extends React.PureComponent<
ICICheckRunListItemProps
> {
- public onCheckRunClick = () => {
+ private onCheckRunClick = () => {
this.props.onCheckRunClick(this.props.checkRun)
}
+ private onViewOnGitHub = () => {
+ this.props.onViewOnGitHub(this.props.checkRun)
+ }
+
private renderActionsLogOutput = (output: IRefCheckOutput) => {
if (output.type === RefCheckOutputType.Default) {
return null
@@ -108,6 +116,14 @@ export class CICheckRunListItem extends React.PureComponent<
)
}
+ private renderViewOnGitHub = () => {
+ return (
+
+
+
+ )
+ }
+
private renderLogs = () => {
const {
loadingLogs,
@@ -124,8 +140,11 @@ export class CICheckRunListItem extends React.PureComponent<
return (
- {this.renderActionsLogOutput(output)}
- {this.renderNonActionsLogOutput(output)}
+
+ {this.renderActionsLogOutput(output)}
+ {this.renderNonActionsLogOutput(output)}
+
+ {this.renderViewOnGitHub()}
)
}
diff --git a/app/src/ui/branches/ci-check-run-list.tsx b/app/src/ui/branches/ci-check-run-list.tsx
index b327d85c3a..9e3e395af0 100644
--- a/app/src/ui/branches/ci-check-run-list.tsx
+++ b/app/src/ui/branches/ci-check-run-list.tsx
@@ -11,7 +11,6 @@ import _ from 'lodash'
import { Button } from '../lib/button'
import { CICheckRunListItem } from './ci-check-list-item'
import * as OcticonSymbol from '../octicons/octicons.generated'
-
interface ICICheckRunListProps {
/** The classname for the underlying element. */
readonly className?: string
@@ -120,6 +119,21 @@ export class CICheckRunList extends React.PureComponent<
this.setState({ checkRuns, loadingLogs: false })
}
+ private viewCheckRunsOnGitHub = (checkRun: IRefCheck): void => {
+ // Some checks do not provide htmlURLS like ones for the legacy status
+ // object as they do not have a view in the checks screen. In that case we
+ // will just open the PR and they can navigate from there... a little
+ // dissatisfying tho more of an edgecase anyways.
+ const url =
+ checkRun.htmlUrl ??
+ `${this.props.repository.htmlURL}/pull/${this.props.prNumber}`
+ if (url === null) {
+ // The repository should have a htmlURL.
+ return
+ }
+ this.props.dispatcher.openInBrowser(url)
+ }
+
private onCheckRunClick = (checkRun: IRefCheck): void => {
this.setState({
checkRunLogsShown:
@@ -154,6 +168,7 @@ export class CICheckRunList extends React.PureComponent<
loadingLogs={this.state.loadingLogs}
showLogs={this.state.checkRunLogsShown === c.id.toString()}
onCheckRunClick={this.onCheckRunClick}
+ onViewOnGitHub={this.viewCheckRunsOnGitHub}
/>
)
})
diff --git a/app/styles/ui/_ci-check-list-item.scss b/app/styles/ui/_ci-check-list-item.scss
index 85d3c120aa..30d8adda14 100644
--- a/app/styles/ui/_ci-check-list-item.scss
+++ b/app/styles/ui/_ci-check-list-item.scss
@@ -33,30 +33,39 @@
}
.ci-check-list-item-logs {
- padding: var(--spacing-half);
- font-size: var(--font-size-sm);
+ padding: var(--spacing);
border-bottom: var(--base-border);
box-shadow: inset 0px 0px 3px -1px grey;
- max-height: 200px;
- overflow: auto;
- word-break: break-word;
- pre {
- margin: 0;
- }
+ .ci-check-list-item-logs-output {
+ font-size: var(--font-size-sm);
+ max-height: 200px;
+ overflow: auto;
+ word-break: break-word;
- .ci-check-run-log-step {
- display: flex;
- align-items: center;
- .ci-check-status-symbol {
- padding: var(--spacing-third);
+ pre {
+ margin: 0;
}
- .ci-check-run-log-step-name {
- flex: 1;
+
+ .ci-check-run-log-step {
+ display: flex;
+ align-items: center;
+ .ci-check-status-symbol {
+ padding: var(--spacing-third);
+ }
+ .ci-check-run-log-step-name {
+ flex: 1;
+ }
+ }
+
+ .no-logs-to-display {
+ padding: var(--spacing-half);
}
}
- .no-logs-to-display {
- padding: var(--spacing-half);
+ .view-on-github {
+ .button-component {
+ width: 100%;
+ }
}
}