-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.guard.ts
94 lines (85 loc) · 3.45 KB
/
index.guard.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
import * as core from '@actions/core'
import { Octokit } from '@octokit/rest';
type Release = {
html_url: string
draft: boolean
prerelease: boolean
tag_name: string
}
type ReleasePage = {
pages: number,
releases: Release[],
}
const getRepo = () => {
const actionRepo = (process.env.GITHUB_ACTION_REPOSITORY != ''
? process.env.GITHUB_ACTION_REPOSITORY
: process.env.GITHUB_REPOSITORY) ?? ''
const [ owner, repo ] = actionRepo?.split('/') ?? [ undefined, undefined ]
if (!owner || !repo) {
core.debug('Failed to determine github action repository.')
}
return { actionRepo, owner, repo }
}
const getToken = () => {
const token = core.getInput('token') || process.env.GITHUB_TOKEN
if (!token) {
core.debug('No GitHub token found. Trying to access API publicly.')
}
return token
}
const getReleases = async (): Promise<ReleasePage> => {
const octokit = new Octokit({
auth: getToken(),
})
const { owner, repo } = getRepo()
if (!owner || !repo) {
return { releases: [], pages: 0 }
}
return octokit.rest.repos.listReleases({ owner, repo, per_page: 10 })
.then(( { data, headers } ) => {
const pages = /page=(\d+)>; rel="last"/.exec(headers.link ?? '')
const releases = data
.map((release): Release => ({
draft: release.draft,
html_url: release.html_url,
prerelease: release.prerelease,
tag_name: release.tag_name,
}))
return { releases, pages: pages ? parseInt(pages[1]) : 1 }
})
}
const isProdRelease = (release: Release) => !release.prerelease && !release.draft
const releaseToMarkdownLink = (release: Release) => `* [${release.tag_name}](${release.html_url})`
const guard = async () => {
const { pages, releases} = await getReleases()
.catch((error) => {
core.warning('Failed to fetch releases from GitHub. Turn on debug messaging for more information.')
core.error(error.message ?? error)
return { pages: 0, releases: [] }
})
const { actionRepo } = getRepo()
if (releases.length === 0) {
core.debug(`No releases for this action (${actionRepo}) found on GitHub.`)
return undefined
}
const suggestedVersion = (releases.find(isProdRelease) ?? releases[0]).tag_name
const releaseLinks = releases.map(releaseToMarkdownLink)
if (pages > 1) {
releaseLinks.push(`* [...](${releases[0].html_url.split('/releases/')[0]}/releases?page=2)`)
}
core.summary
.addHeading('🏷️ Only tagged releases of this action can be used in workflows', 3)
.addRaw('Only tagged releases of this action can be used, e.g.\n', true)
.addRaw('```yaml', true)
.addRaw(`- uses: ${actionRepo}@${suggestedVersion}`, true)
.addRaw('```\n', true)
.addRaw('----\nThe following releases are available:', true)
.addRaw(releaseLinks.join('\n'), true)
return suggestedVersion
}
const suggestedVersion = await guard()
let errorMessage = suggestedVersion
? `A tagged release (e.g. ${suggestedVersion}) of this action must be used!`
: 'A tagged release of this action must be used! Could not determine suggested version.'
core.setFailed(errorMessage + core.summary.isEmptyBuffer() ? '' : ' See summary for more details.')
core.summary.isEmptyBuffer() || void core.summary.write({overwrite: true})