actions-up 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +3 -3
- package/dist/core/api/check-updates.js +11 -7
- package/dist/core/api/create-github-client.d.ts +8 -0
- package/dist/core/api/create-github-client.js +55 -0
- package/dist/core/api/get-all-releases.d.ts +20 -0
- package/dist/core/api/get-all-releases.js +35 -0
- package/dist/core/api/get-all-tags.d.ts +17 -0
- package/dist/core/api/get-all-tags.js +13 -0
- package/dist/core/api/get-latest-release.d.ts +15 -0
- package/dist/core/api/get-latest-release.js +28 -0
- package/dist/core/api/get-reference-type.d.ts +16 -0
- package/dist/core/api/get-reference-type.js +21 -0
- package/dist/core/api/get-tag-info.d.ts +19 -0
- package/dist/core/api/get-tag-info.js +96 -0
- package/dist/core/api/get-tag-sha.d.ts +19 -0
- package/dist/core/api/get-tag-sha.js +30 -0
- package/dist/core/api/internal-rate-limit-error.d.ts +3 -0
- package/dist/core/api/internal-rate-limit-error.js +8 -0
- package/dist/core/api/make-request.d.ts +13 -0
- package/dist/core/api/make-request.js +31 -0
- package/dist/core/api/resolve-github-token-sync.d.ts +6 -0
- package/dist/core/api/resolve-github-token-sync.js +48 -0
- package/dist/core/api/update-rate-limit-info.d.ts +8 -0
- package/dist/core/api/update-rate-limit-info.js +10 -0
- package/dist/core/interactive/format-version.d.ts +3 -2
- package/dist/core/interactive/format-version.js +33 -2
- package/dist/core/interactive/prompt-update-selection.js +42 -8
- package/dist/core/scan-github-actions.js +1 -1
- package/dist/package.js +1 -1
- package/dist/types/github-client-context.d.ts +32 -0
- package/dist/types/github-client.d.ts +42 -0
- package/dist/types/release-info.d.ts +23 -0
- package/dist/types/tag-info.d.ts +14 -0
- package/package.json +1 -1
- package/readme.md +4 -130
- package/dist/core/api/client.d.ts +0 -98
- package/dist/core/api/client.js +0 -261
package/dist/core/api/client.js
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { execFileSync } from "node:child_process";
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
4
|
-
var GitHubRateLimitError = class extends Error {
|
|
5
|
-
constructor(resetAt) {
|
|
6
|
-
let resetTime = resetAt.toLocaleTimeString();
|
|
7
|
-
super(`GitHub API rate limit exceeded. Resets at ${resetTime}`);
|
|
8
|
-
this.name = "GitHubRateLimitError";
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
var Client = class Client {
|
|
12
|
-
baseUrl = "https://api.github.com";
|
|
13
|
-
token;
|
|
14
|
-
rateLimitReset = /* @__PURE__ */ new Date();
|
|
15
|
-
rateLimitRemaining = 60;
|
|
16
|
-
constructor(token) {
|
|
17
|
-
this.token = token ?? process.env["GITHUB_TOKEN"] ?? resolveGitHubTokenSync();
|
|
18
|
-
this.rateLimitRemaining = this.token ? 5e3 : 60;
|
|
19
|
-
}
|
|
20
|
-
static isRateLimitError(error) {
|
|
21
|
-
if (error && typeof error === "object") {
|
|
22
|
-
let maybeAny = error;
|
|
23
|
-
let message = typeof maybeAny.message === "string" ? maybeAny.message.toLowerCase() : "";
|
|
24
|
-
let status = typeof maybeAny.status === "number" ? maybeAny.status : void 0;
|
|
25
|
-
return message.includes("rate limit") || message.includes("api rate limit") || status === 403;
|
|
26
|
-
}
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
async getTagInfo(owner, repo, tag) {
|
|
30
|
-
try {
|
|
31
|
-
let displayTag = tag.replace(/^refs\/tags\//u, "");
|
|
32
|
-
try {
|
|
33
|
-
let releaseResp = await this.makeRequest(`/repos/${owner}/${repo}/releases/tags/${displayTag}`);
|
|
34
|
-
let releaseData = releaseResp.data;
|
|
35
|
-
let sha = null;
|
|
36
|
-
if (releaseData.target_commitish) try {
|
|
37
|
-
let commitResp = await this.makeRequest(`/repos/${owner}/${repo}/commits/${releaseData.target_commitish}`);
|
|
38
|
-
let commitData = commitResp.data;
|
|
39
|
-
({sha} = commitData);
|
|
40
|
-
} catch {
|
|
41
|
-
sha = releaseData.target_commitish;
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
date: releaseData.published_at ? new Date(releaseData.published_at) : null,
|
|
45
|
-
sha: sha ?? releaseData.target_commitish,
|
|
46
|
-
message: releaseData.body ?? null,
|
|
47
|
-
tag: displayTag
|
|
48
|
-
};
|
|
49
|
-
} catch (releaseError) {
|
|
50
|
-
if (releaseError && typeof releaseError === "object" && "status" in releaseError && releaseError.status === 404) try {
|
|
51
|
-
let referenceResp = await this.makeRequest(`/repos/${owner}/${repo}/git/refs/tags/${displayTag}`);
|
|
52
|
-
let referenceData = referenceResp.data;
|
|
53
|
-
let { sha } = referenceData.object;
|
|
54
|
-
let message = null;
|
|
55
|
-
let date = null;
|
|
56
|
-
if (referenceData.object.type === "tag") try {
|
|
57
|
-
let tagResp = await this.makeRequest(`/repos/${owner}/${repo}/git/tags/${sha}`);
|
|
58
|
-
let tagData = tagResp.data;
|
|
59
|
-
({sha} = tagData.object);
|
|
60
|
-
({message} = tagData);
|
|
61
|
-
date = tagData.tagger.date ? new Date(tagData.tagger.date) : null;
|
|
62
|
-
} catch {}
|
|
63
|
-
else try {
|
|
64
|
-
let commitResp = await this.makeRequest(`/repos/${owner}/${repo}/git/commits/${sha}`);
|
|
65
|
-
let commitData = commitResp.data;
|
|
66
|
-
({message} = commitData);
|
|
67
|
-
date = commitData.author.date ? new Date(commitData.author.date) : null;
|
|
68
|
-
} catch {}
|
|
69
|
-
return {
|
|
70
|
-
tag: displayTag,
|
|
71
|
-
message,
|
|
72
|
-
date,
|
|
73
|
-
sha
|
|
74
|
-
};
|
|
75
|
-
} catch (tagError) {
|
|
76
|
-
if (tagError && typeof tagError === "object" && "status" in tagError && tagError.status === 404) return null;
|
|
77
|
-
throw tagError;
|
|
78
|
-
}
|
|
79
|
-
throw releaseError;
|
|
80
|
-
}
|
|
81
|
-
} catch (error) {
|
|
82
|
-
if (Client.isRateLimitError(error)) throw new GitHubRateLimitError(this.rateLimitReset);
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
async getAllReleases(owner, repo, limit = 10) {
|
|
87
|
-
try {
|
|
88
|
-
let releasesResp = await this.makeRequest(`/repos/${owner}/${repo}/releases?per_page=${limit}`);
|
|
89
|
-
let releases = releasesResp.data;
|
|
90
|
-
let releaseInfos = [];
|
|
91
|
-
await Promise.all(releases.map(async (release) => {
|
|
92
|
-
let sha = null;
|
|
93
|
-
if (release.tag_name) try {
|
|
94
|
-
let tagInfo = await this.getTagInfo(owner, repo, release.tag_name);
|
|
95
|
-
if (tagInfo) ({sha} = tagInfo);
|
|
96
|
-
} catch {
|
|
97
|
-
sha = release.target_commitish;
|
|
98
|
-
}
|
|
99
|
-
releaseInfos.push({
|
|
100
|
-
publishedAt: new Date(release.published_at),
|
|
101
|
-
name: release.name ?? release.tag_name,
|
|
102
|
-
description: release.body ?? null,
|
|
103
|
-
isPrerelease: release.prerelease,
|
|
104
|
-
version: release.tag_name,
|
|
105
|
-
url: release.html_url,
|
|
106
|
-
sha
|
|
107
|
-
});
|
|
108
|
-
}));
|
|
109
|
-
return releaseInfos;
|
|
110
|
-
} catch (error) {
|
|
111
|
-
if (Client.isRateLimitError(error)) throw new GitHubRateLimitError(this.rateLimitReset);
|
|
112
|
-
throw error;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
async getLatestRelease(owner, repo) {
|
|
116
|
-
try {
|
|
117
|
-
let releaseResp = await this.makeRequest(`/repos/${owner}/${repo}/releases/latest`);
|
|
118
|
-
let release = releaseResp.data;
|
|
119
|
-
let sha = null;
|
|
120
|
-
if (release.tag_name) try {
|
|
121
|
-
let tagInfo = await this.getTagInfo(owner, repo, release.tag_name);
|
|
122
|
-
if (tagInfo) ({sha} = tagInfo);
|
|
123
|
-
} catch {
|
|
124
|
-
sha = release.target_commitish;
|
|
125
|
-
}
|
|
126
|
-
return {
|
|
127
|
-
publishedAt: new Date(release.published_at),
|
|
128
|
-
name: release.name ?? release.tag_name,
|
|
129
|
-
description: release.body ?? null,
|
|
130
|
-
isPrerelease: release.prerelease,
|
|
131
|
-
version: release.tag_name,
|
|
132
|
-
url: release.html_url,
|
|
133
|
-
sha
|
|
134
|
-
};
|
|
135
|
-
} catch (error) {
|
|
136
|
-
if (error && typeof error === "object" && "status" in error && error.status === 404) return null;
|
|
137
|
-
if (Client.isRateLimitError(error)) throw new GitHubRateLimitError(this.rateLimitReset);
|
|
138
|
-
throw error;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
async getAllTags(owner, repo, limit = 30) {
|
|
142
|
-
try {
|
|
143
|
-
let tagsResp = await this.makeRequest(`/repos/${owner}/${repo}/tags?per_page=${limit}`);
|
|
144
|
-
let tags = tagsResp.data;
|
|
145
|
-
return tags.map((tag) => ({
|
|
146
|
-
sha: tag.commit.sha,
|
|
147
|
-
tag: tag.name,
|
|
148
|
-
message: null,
|
|
149
|
-
date: null
|
|
150
|
-
}));
|
|
151
|
-
} catch (error) {
|
|
152
|
-
if (Client.isRateLimitError(error)) throw new GitHubRateLimitError(this.rateLimitReset);
|
|
153
|
-
throw error;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
async getRefType(owner, repo, reference) {
|
|
157
|
-
try {
|
|
158
|
-
await this.makeRequest(`/repos/${owner}/${repo}/git/refs/tags/${reference}`);
|
|
159
|
-
return "tag";
|
|
160
|
-
} catch {
|
|
161
|
-
try {
|
|
162
|
-
await this.makeRequest(`/repos/${owner}/${repo}/git/refs/heads/${reference}`);
|
|
163
|
-
return "branch";
|
|
164
|
-
} catch {
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
getRateLimitStatus() {
|
|
170
|
-
return {
|
|
171
|
-
remaining: this.rateLimitRemaining,
|
|
172
|
-
resetAt: this.rateLimitReset
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
shouldWaitForRateLimit(threshold = 100) {
|
|
176
|
-
return this.rateLimitRemaining < threshold;
|
|
177
|
-
}
|
|
178
|
-
async makeRequest(path$1, options = {}) {
|
|
179
|
-
let headers = {
|
|
180
|
-
Accept: "application/vnd.github.v3+json",
|
|
181
|
-
"User-Agent": "actions-up",
|
|
182
|
-
...options.headers
|
|
183
|
-
};
|
|
184
|
-
if (this.token) headers["Authorization"] = `Bearer ${this.token}`;
|
|
185
|
-
let response = await fetch(`${this.baseUrl}${path$1}`, {
|
|
186
|
-
...options,
|
|
187
|
-
headers
|
|
188
|
-
});
|
|
189
|
-
let responseHeaders = {};
|
|
190
|
-
for (let [key, value] of response.headers.entries()) responseHeaders[key] = value;
|
|
191
|
-
this.updateRateLimitInfo(responseHeaders);
|
|
192
|
-
if (!response.ok) {
|
|
193
|
-
let error = /* @__PURE__ */ new Error(`GitHub API error: ${response.status} ${response.statusText}`);
|
|
194
|
-
error.status = response.status;
|
|
195
|
-
if (response.status === 403) {
|
|
196
|
-
let text = await response.text();
|
|
197
|
-
if (text.includes("rate limit") || text.includes("API rate limit")) error.message = "API rate limit exceeded";
|
|
198
|
-
}
|
|
199
|
-
throw error;
|
|
200
|
-
}
|
|
201
|
-
let data = await response.json();
|
|
202
|
-
return {
|
|
203
|
-
headers: responseHeaders,
|
|
204
|
-
data
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
updateRateLimitInfo(headers) {
|
|
208
|
-
let remaining = headers["x-ratelimit-remaining"];
|
|
209
|
-
if (remaining !== void 0) this.rateLimitRemaining = typeof remaining === "string" ? Number.parseInt(remaining, 10) : remaining;
|
|
210
|
-
let reset = headers["x-ratelimit-reset"];
|
|
211
|
-
if (reset !== void 0) {
|
|
212
|
-
let resetTime = typeof reset === "string" ? Number.parseInt(reset, 10) : reset;
|
|
213
|
-
this.rateLimitReset = /* @__PURE__ */ new Date(resetTime * 1e3);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
function resolveGitHubTokenSync() {
|
|
218
|
-
let fromGithubToken = process.env["GITHUB_TOKEN"];
|
|
219
|
-
if (fromGithubToken && fromGithubToken.trim() !== "") return fromGithubToken.trim();
|
|
220
|
-
let fromGhToken = process.env["GH_TOKEN"];
|
|
221
|
-
if (fromGhToken && fromGhToken.trim() !== "") return fromGhToken.trim();
|
|
222
|
-
try {
|
|
223
|
-
let output = execFileSync("gh", ["auth", "token"], {
|
|
224
|
-
stdio: [
|
|
225
|
-
"ignore",
|
|
226
|
-
"pipe",
|
|
227
|
-
"ignore"
|
|
228
|
-
],
|
|
229
|
-
encoding: "utf8",
|
|
230
|
-
timeout: 500
|
|
231
|
-
});
|
|
232
|
-
let token = output.trim();
|
|
233
|
-
if (token) return token;
|
|
234
|
-
} catch {}
|
|
235
|
-
try {
|
|
236
|
-
let gitConfigPath = join(process.cwd(), ".git", "config");
|
|
237
|
-
let content = readFileSync(gitConfigPath, "utf8");
|
|
238
|
-
let directMatch = content.match(/^\s*(?:github\.(?:oauth-token|token)|hub\.oauthtoken)\s*=\s*(?<token>\S[^\n\r]*)$/mu);
|
|
239
|
-
let directToken = directMatch?.groups?.["token"]?.trim();
|
|
240
|
-
if (directToken) return directToken;
|
|
241
|
-
let currentSection = null;
|
|
242
|
-
for (let rawLine of content.split(/\r?\n/u)) {
|
|
243
|
-
let line = rawLine.trim();
|
|
244
|
-
let sectionMatch = line.match(/^\[(?<name>[^\]]+)\]$/u);
|
|
245
|
-
if (sectionMatch?.groups) {
|
|
246
|
-
currentSection = sectionMatch.groups["name"].toLowerCase();
|
|
247
|
-
continue;
|
|
248
|
-
}
|
|
249
|
-
if (currentSection === "github") {
|
|
250
|
-
let tokenMatch = line.match(/^(?:oauth-token|token)\s*=\s*(?<val>\S[^\n\r]*)$/u);
|
|
251
|
-
if (tokenMatch?.groups?.["val"]) return tokenMatch.groups["val"].trim();
|
|
252
|
-
}
|
|
253
|
-
if (currentSection === "hub") {
|
|
254
|
-
let oauthMatch = line.match(/^oauthtoken\s*=\s*(?<val>\S[^\n\r]*)$/u);
|
|
255
|
-
if (oauthMatch?.groups?.["val"]) return oauthMatch.groups["val"].trim();
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
} catch {}
|
|
259
|
-
return void 0;
|
|
260
|
-
}
|
|
261
|
-
export { Client };
|