-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathindex.tsx
137 lines (121 loc) · 4.59 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { Log, Viewer } from '@microsoft/sarif-web-component'
import { AppInsights } from "applicationinsights-js"
import { CommonServiceIds, getClient, IProjectPageService } from 'azure-devops-extension-api'
import { BuildRestClient, BuildServiceIds, IBuildPageDataService } from 'azure-devops-extension-api/Build'
import * as SDK from 'azure-devops-extension-sdk'
import * as JSZip from 'jszip'
import { observable, runInAction } from 'mobx'
import { observer } from 'mobx-react'
import * as React from 'react'
import * as ReactDOM from 'react-dom'
const isProduction = self !== top
const perfLoadStart = performance.now() // For telemetry.
@observer class Tab extends React.Component {
@observable.ref logs = undefined as Log[]
@observable pipelineId = undefined as string
@observable user = undefined as string
constructor(props) {
super(props)
SDK.init({
applyTheme: true,
loaded: true,
})
;(async () => {
await SDK.ready()
console.info('Version', SDK.getExtensionContext().version)
const user = SDK.getUser()
const organization = SDK.getHost().name
if (isProduction) {
AppInsights.setAuthenticatedUserContext(user.name /* typically email */, organization)
}
const projectService = await SDK.getService<IProjectPageService>(CommonServiceIds.ProjectPageService)
const project = await projectService.getProject()
const buildPageDataService = await SDK.getService<IBuildPageDataService>(BuildServiceIds.BuildPageDataService)
const buildPageData = await buildPageDataService.getBuildPageData()
if (!buildPageData) {
SDK.notifyLoadSucceeded()
AppInsights.trackException(new Error('buildPageData undefined'))
return
}
const { build, definition } = buildPageData
const buildClient = getClient(BuildRestClient)
const artifacts = await buildClient.getArtifacts(project.id, build.id)
const files = await (async () => {
if (!artifacts.some(a => a.name === 'CodeAnalysisLogs')) return []
const arrayBuffer = await buildClient.getArtifactContentZip(project.id, build.id, 'CodeAnalysisLogs')
const zip = await JSZip.loadAsync(arrayBuffer)
return Object.values(zip.files)
.filter(entry => !entry.dir && entry.name.endsWith('.sarif'))
.map(entry => ({
name: entry.name.replace('CodeAnalysisLogs/', ''),
contentsPromise: entry.async('string')
}))
})()
const logTexts = await Promise.all(files.map(async file => {
let contents = await file.contentsPromise
if (contents.match(/^\uFEFF/)) {
AppInsights.trackEvent('BOM trimmed')
contents = contents.replace(/^\uFEFF/, ''); // Trim BOM to avoid 'Unexpected token in JSON at position 0'.
}
return contents
}))
const logs = logTexts.map(log => {
if (log === '') {
AppInsights.trackEvent('Empty log')
return undefined
}
try {
return JSON.parse(log) as Log
} catch(e) {
AppInsights.trackException(e, null, { logSnippet: JSON.stringify(log.slice(0, 100)) })
return undefined
}
}).filter(log => log)
const toolNames = logs.map(log => {
return log.runs
.filter(run => run.tool.driver) // Guard against old versions.
.map(run => run.tool.driver.name)
})
const toolNamesSet = new Set([].concat(...toolNames))
// Show file names when the tool names are homogeneous.
if (files.length > 1 && toolNamesSet.size === 1) {
logs.forEach((log, i) =>
log.runs.forEach(run => {
run.properties = run.properties || {}
run.properties['logFileName'] = files[i].name
})
)
}
runInAction(() => {
this.logs = logs
this.pipelineId = `${organization}.${definition.id}`
this.user = user.name
})
SDK.notifyLoadSucceeded()
if (isProduction) {
const customDimensions = {
logLength: logs.length + '',
toolNames: [...toolNamesSet.values()].join(' '),
version: SDK.getExtensionContext().version,
}
AppInsights.trackPageView(project.name, document.referrer, customDimensions, undefined, performance.now() - perfLoadStart)
}
})()
}
render() {
const {logs, user} = this
return !logs || logs.length
? <Viewer logs={logs} filterState={{
Baseline: { value: ['new', 'updated', 'absent'] },
Level: { value: ['error', 'warning'] },
}} user={user} />
: <div className="full">No SARIF artifacts found.</div>
}
}
if (isProduction) {
AppInsights.downloadAndSetup({ instrumentationKey: '' })
addEventListener('unhandledrejection', e => AppInsights.trackException(e.reason))
}
ReactDOM.render(<Tab />, document.getElementById("app"))