generated from actions/typescript-action
-
Notifications
You must be signed in to change notification settings - Fork 19
/
installer.ts
162 lines (138 loc) · 4.35 KB
/
installer.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
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import {GitHub, getOctokitOptions} from '@actions/github/lib/utils'
import {OctokitOptions} from '@octokit/core/dist-types/types'
import {throttling} from '@octokit/plugin-throttling'
import * as core from '@actions/core'
import * as cache from '@actions/tool-cache'
import * as path from 'path'
import * as semver from 'semver'
import * as fs from 'fs'
let tempDirectory = process.env['RUNNER_TEMPDIRECTORY'] || ''
const EnhancedOctokit = GitHub.plugin(throttling)
const githubToken = core.getInput('github-token')
const failFast = core.getBooleanInput('fail-fast')
let options: OctokitOptions = {
throttle: {
onRateLimit: (retryAfter: Number, opts: OctokitOptions) => {
core.warning(
`Request quota exhausted for request ${opts.method} ${opts.url}`
)
if (!failFast) {
core.warning(`Retrying after ${retryAfter} seconds!`)
}
return !failFast
},
onAbuseLimit: (retryAfter: Number, opts: OctokitOptions) => {
core.warning(`Abuse detected for request ${opts.method} ${opts.url}`)
if (!failFast) {
core.warning(`Retrying after ${retryAfter} seconds!`)
}
return !failFast
}
}
}
if (process.env.NODE_ENV === 'test') {
options = githubToken ? getOctokitOptions(githubToken, options) : options
} else {
options = getOctokitOptions(githubToken, options)
}
const octokit = new EnhancedOctokit(options)
const versionRegex = /\d+\.?\d*\.?\d*/
const toolName = 'kustomize'
const platform = process.platform
const arch = process.arch === 'x64' ? 'amd64' : process.arch
if (!tempDirectory) {
let baseLocation
if (process.platform === 'win32') {
// On windows use the USERPROFILE env variable
baseLocation = process.env['USERPROFILE'] || 'C:\\'
} else {
if (process.platform === 'darwin') {
baseLocation = '/Users'
} else {
baseLocation = '/home'
}
}
tempDirectory = path.join(baseLocation, 'actions', 'temp')
}
export async function getKustomize(targetVersion: string): Promise<void> {
if (!semver.validRange(targetVersion))
throw new Error(`invalid semver requested: ${targetVersion}`)
let kustomizePath = cache.find('kustomize', targetVersion)
if (!kustomizePath) {
const version = await getMaxSatisfyingVersion(targetVersion)
kustomizePath = await acquireVersion(version)
}
return core.addPath(kustomizePath)
}
interface Version {
resolved: string
target: string
url: string
}
async function getMaxSatisfyingVersion(
targetVersion: string
): Promise<Version> {
const version = {target: targetVersion}
const availableVersions: Map<string, string> = new Map()
for await (const response of octokit.paginate.iterator(
octokit.repos.listReleases,
{
owner: 'kubernetes-sigs',
repo: 'kustomize',
per_page: 100
}
)) {
for (const release of response.data) {
const matchingAsset = release.assets.find(
asset =>
asset.name.includes('kustomize') &&
asset.name.includes(platform) &&
asset.name.includes(arch)
)
if (matchingAsset) {
const kustomizeVersion = (
versionRegex.exec(release.tag_name) || []
).shift()
if (kustomizeVersion != null) {
availableVersions.set(
kustomizeVersion,
matchingAsset.browser_download_url
)
}
}
}
}
const resolved = semver.maxSatisfying(
[...availableVersions.keys()],
version.target
)
if (!resolved) {
throw new Error(
`Unable to find Kustomize version '${version.target}' for platform '${platform}' and architecture ${arch}.`
)
}
const url = availableVersions.get(resolved) as string
return {...version, resolved, url}
}
async function acquireVersion(version: Version): Promise<string> {
const toolFilename =
process.platform === 'win32' ? `${toolName}.exe` : toolName
let toolPath: string
try {
toolPath = await cache.downloadTool(version.url)
} catch (err) {
core.debug(err)
throw new Error(`Failed to download version ${version.target}: ${err}`)
}
if (version.url.endsWith('.tar.gz')) {
toolPath = await cache.extractTar(toolPath)
toolPath = path.join(toolPath, toolFilename)
}
switch (process.platform) {
case 'linux':
case 'darwin':
fs.chmodSync(toolPath, 0o755)
break
}
return await cache.cacheFile(toolPath, toolFilename, toolName, version.target)
}