-
Notifications
You must be signed in to change notification settings - Fork 21
/
build.ts
102 lines (89 loc) · 2.96 KB
/
build.ts
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
// -*- mode: javascript; js-indent-level: 2 -*-
import * as core from '@actions/core'
import * as exec from '@actions/exec'
import * as fs from 'fs'
import * as os from 'os'
import * as path from 'path'
import * as process from 'process'
import * as tools from './tools'
interface ImageInfo {
// eslint-disable-next-line @typescript-eslint/naming-convention
'build-request-id'?: string
// eslint-disable-next-line @typescript-eslint/naming-convention
'build-request-timestamp'?: string
// eslint-disable-next-line @typescript-eslint/naming-convention
build_url?: string
}
function expandHome(p: string): string {
if (p === '~' || p.startsWith('~/')) {
p = os.homedir() + p.slice(1)
}
return p
}
interface SnapcraftBuilderOptions {
projectRoot: string
includeBuildInfo: boolean
snapcraftChannel: string
snapcraftArgs: string
uaToken: string
}
export class SnapcraftBuilder {
projectRoot: string
includeBuildInfo: boolean
snapcraftChannel: string
snapcraftArgs: string
uaToken: string
constructor(options: SnapcraftBuilderOptions) {
this.projectRoot = expandHome(options.projectRoot)
this.includeBuildInfo = options.includeBuildInfo
this.snapcraftChannel = options.snapcraftChannel
this.snapcraftArgs = options.snapcraftArgs
this.uaToken = options.uaToken
}
async build(): Promise<void> {
core.startGroup('Installing Snapcraft plus dependencies')
await tools.ensureSnapd()
await tools.ensureLXD()
await tools.ensureSnapcraft(this.snapcraftChannel)
core.endGroup()
const imageInfo: ImageInfo = {
// eslint-disable-next-line @typescript-eslint/naming-convention
build_url: `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`
}
// Copy and update environment to pass to snapcraft
const env: {[key: string]: string} = {}
Object.assign(env, process.env)
env['SNAPCRAFT_BUILD_ENVIRONMENT'] = 'lxd'
env['SNAPCRAFT_IMAGE_INFO'] = JSON.stringify(imageInfo)
if (this.includeBuildInfo) {
env['SNAPCRAFT_BUILD_INFO'] = '1'
}
let snapcraft = 'snapcraft'
if (this.snapcraftArgs) {
snapcraft = `${snapcraft} ${this.snapcraftArgs}`
}
if (this.uaToken) {
snapcraft = `${snapcraft} --ua-token ${this.uaToken}`
}
await exec.exec('sg', ['lxd', '-c', snapcraft], {
cwd: this.projectRoot,
env
})
}
// This wrapper is for the benefit of the tests, due to the crazy
// typing of fs.promises.readdir()
async _readdir(dir: string): Promise<string[]> {
return await fs.promises.readdir(dir)
}
async outputSnap(): Promise<string> {
const files = await this._readdir(this.projectRoot)
const snaps = files.filter(name => name.endsWith('.snap'))
if (snaps.length === 0) {
throw new Error('No snap files produced by build')
}
if (snaps.length > 1) {
core.warning(`Multiple snaps found in ${this.projectRoot}`)
}
return path.join(this.projectRoot, snaps[0])
}
}