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.
Files changed (37) hide show
  1. package/dist/cli/index.js +3 -3
  2. package/dist/core/api/check-updates.js +11 -7
  3. package/dist/core/api/create-github-client.d.ts +8 -0
  4. package/dist/core/api/create-github-client.js +55 -0
  5. package/dist/core/api/get-all-releases.d.ts +20 -0
  6. package/dist/core/api/get-all-releases.js +35 -0
  7. package/dist/core/api/get-all-tags.d.ts +17 -0
  8. package/dist/core/api/get-all-tags.js +13 -0
  9. package/dist/core/api/get-latest-release.d.ts +15 -0
  10. package/dist/core/api/get-latest-release.js +28 -0
  11. package/dist/core/api/get-reference-type.d.ts +16 -0
  12. package/dist/core/api/get-reference-type.js +21 -0
  13. package/dist/core/api/get-tag-info.d.ts +19 -0
  14. package/dist/core/api/get-tag-info.js +96 -0
  15. package/dist/core/api/get-tag-sha.d.ts +19 -0
  16. package/dist/core/api/get-tag-sha.js +30 -0
  17. package/dist/core/api/internal-rate-limit-error.d.ts +3 -0
  18. package/dist/core/api/internal-rate-limit-error.js +8 -0
  19. package/dist/core/api/make-request.d.ts +13 -0
  20. package/dist/core/api/make-request.js +31 -0
  21. package/dist/core/api/resolve-github-token-sync.d.ts +6 -0
  22. package/dist/core/api/resolve-github-token-sync.js +48 -0
  23. package/dist/core/api/update-rate-limit-info.d.ts +8 -0
  24. package/dist/core/api/update-rate-limit-info.js +10 -0
  25. package/dist/core/interactive/format-version.d.ts +3 -2
  26. package/dist/core/interactive/format-version.js +33 -2
  27. package/dist/core/interactive/prompt-update-selection.js +42 -8
  28. package/dist/core/scan-github-actions.js +1 -1
  29. package/dist/package.js +1 -1
  30. package/dist/types/github-client-context.d.ts +32 -0
  31. package/dist/types/github-client.d.ts +42 -0
  32. package/dist/types/release-info.d.ts +23 -0
  33. package/dist/types/tag-info.d.ts +14 -0
  34. package/package.json +1 -1
  35. package/readme.md +4 -130
  36. package/dist/core/api/client.d.ts +0 -98
  37. package/dist/core/api/client.js +0 -261
@@ -1,5 +1,36 @@
1
1
  import pc from "picocolors";
2
- function formatVersion(version) {
3
- return version ?? pc.gray("unknown");
2
+ import semver from "semver";
3
+ function formatVersion(latestVersion, currentVersion) {
4
+ if (!latestVersion) return pc.gray("unknown");
5
+ let latest = semver.parse(latestVersion);
6
+ let current = currentVersion ? semver.parse(normalizeVersion(currentVersion)) : null;
7
+ if (!current || !latest) return latestVersion;
8
+ let change = semver.diff(normalizeVersion(currentVersion), latestVersion);
9
+ let unstable = current.major === 0;
10
+ let changeColor = unstable ? pc.yellowBright : pc.gray;
11
+ let parts = [
12
+ latest.major,
13
+ latest.minor,
14
+ latest.patch
15
+ ];
16
+ let colors = parts.map((_, i) => {
17
+ if (change === "major") return pc.redBright;
18
+ if (change === "minor" && i >= 1) return changeColor;
19
+ if (change === "patch" && i === 2) return changeColor;
20
+ return identity;
21
+ });
22
+ let result = colors[0](String(parts[0]));
23
+ if (parts[1] !== void 0) result += colors[0](".") + colors[1](String(parts[1]));
24
+ if (parts[2] !== void 0) result += colors[1](".") + colors[2](String(parts[2]));
25
+ return result;
26
+ }
27
+ function normalizeVersion(version) {
28
+ let cleaned = version.replace(/^v/u, "");
29
+ let parts = cleaned.split(".");
30
+ while (parts.length < 3) parts.push("0");
31
+ return parts.slice(0, 3).join(".");
32
+ }
33
+ function identity(string) {
34
+ return string;
4
35
  }
5
36
  export { formatVersion };
@@ -4,10 +4,11 @@ import { stripAnsi } from "./strip-ansi.js";
4
4
  import { padString } from "./pad-string.js";
5
5
  import "node:worker_threads";
6
6
  import pc from "picocolors";
7
+ import { readFile } from "node:fs/promises";
7
8
  import enquirer from "enquirer";
8
9
  import path from "node:path";
9
10
  const MIN_ACTION_WIDTH = 56;
10
- const MIN_CURRENT_WIDTH = 10;
11
+ const MIN_CURRENT_WIDTH = 16;
11
12
  async function promptUpdateSelection(updates) {
12
13
  if (updates.length === 0) return null;
13
14
  let outdated = updates.filter((update) => update.hasUpdate);
@@ -27,14 +28,33 @@ async function promptUpdateSelection(updates) {
27
28
  });
28
29
  groups.set(file, group);
29
30
  }
31
+ let currentComputedByIndex = await Promise.all(outdated.map(async (update) => {
32
+ let display = formatVersionOrSha(update.currentVersion);
33
+ let effectiveForDiff = update.currentVersion ?? void 0;
34
+ if (!update.currentVersion || !isSha(update.currentVersion)) return {
35
+ effectiveForDiff,
36
+ display
37
+ };
38
+ let versionFromComment = await tryReadInlineVersionComment(update.action.file, update.action.line);
39
+ if (versionFromComment) {
40
+ let shortSha = update.currentVersion.slice(0, 7);
41
+ let version = formatVersionOrSha(versionFromComment);
42
+ display = `${version} ${pc.gray(`(${shortSha})`)}`;
43
+ effectiveForDiff = versionFromComment;
44
+ }
45
+ return {
46
+ effectiveForDiff,
47
+ display
48
+ };
49
+ }));
30
50
  let choices = [];
31
51
  let maxActionLength = stripAnsi("Action").length;
32
52
  let maxCurrentLength = stripAnsi("Current").length;
33
- for (let update of outdated) {
53
+ for (let [index, update] of outdated.entries()) {
34
54
  let actionNameRaw = update.action.name;
35
- let currentRaw = formatVersionOrSha(update.currentVersion);
55
+ let currentRaw = currentComputedByIndex[index].display;
36
56
  maxActionLength = Math.max(maxActionLength, actionNameRaw.length);
37
- maxCurrentLength = Math.max(maxCurrentLength, currentRaw.length);
57
+ maxCurrentLength = Math.max(maxCurrentLength, stripAnsi(currentRaw).length);
38
58
  }
39
59
  let globalActionWidth = Math.max(maxActionLength, MIN_ACTION_WIDTH);
40
60
  let globalCurrentWidth = Math.max(maxCurrentLength, MIN_CURRENT_WIDTH);
@@ -53,10 +73,11 @@ async function promptUpdateSelection(updates) {
53
73
  target: "Target",
54
74
  arrow: "❯"
55
75
  });
56
- for (let { update } of groupOrder) {
76
+ for (let { update, index } of groupOrder) {
57
77
  let hasSha = Boolean(update.latestSha);
58
- let current = formatVersionOrSha(update.currentVersion);
59
- let latest = formatVersion(update.latestVersion);
78
+ let current = currentComputedByIndex[index].display;
79
+ let effectiveCurrentForDiff = currentComputedByIndex[index]?.effectiveForDiff ?? update.currentVersion;
80
+ let latest = formatVersion(update.latestVersion, effectiveCurrentForDiff);
60
81
  let actionName = update.action.name;
61
82
  if (update.latestSha) {
62
83
  let shortSha = update.latestSha.slice(0, 7);
@@ -180,6 +201,19 @@ async function promptUpdateSelection(updates) {
180
201
  throw error;
181
202
  }
182
203
  }
204
+ async function tryReadInlineVersionComment(filePath, lineNumber) {
205
+ try {
206
+ if (!filePath || !lineNumber || lineNumber <= 0) return null;
207
+ let content = await readFile(filePath, "utf8");
208
+ let lines = content.split("\n");
209
+ let index = lineNumber - 1;
210
+ if (index < 0 || index >= lines.length) return null;
211
+ let line = lines[index];
212
+ let match = line.match(/#\s*(?<version>[Vv]?\d+(?:\.\d+){0,2}(?:[+-][\w\-.]+)?)/u);
213
+ if (match?.groups?.["version"]) return match.groups["version"];
214
+ } catch {}
215
+ return null;
216
+ }
183
217
  function formatTableRow(row, actionWidth, currentWidth) {
184
218
  let parts = [
185
219
  padString(row.action, actionWidth),
@@ -198,6 +232,6 @@ function isSha(value) {
198
232
  function formatVersionOrSha(version) {
199
233
  if (!version) return pc.gray("unknown");
200
234
  if (isSha(version)) return version.slice(0, 7);
201
- return version;
235
+ return version.replace(/^v/u, "");
202
236
  }
203
237
  export { promptUpdateSelection };
@@ -2,8 +2,8 @@ import { ACTIONS_DIRECTORY, GITHUB_DIRECTORY, WORKFLOWS_DIRECTORY } from "./cons
2
2
  import { scanWorkflowFile } from "./scan-workflow-file.js";
3
3
  import { scanActionFile } from "./scan-action-file.js";
4
4
  import { isYamlFile } from "./fs/is-yaml-file.js";
5
- import { isAbsolute, join, relative, resolve } from "node:path";
6
5
  import { readFile, readdir, stat } from "node:fs/promises";
6
+ import { isAbsolute, join, relative, resolve } from "node:path";
7
7
  async function scanGitHubActions(rootPath = process.cwd()) {
8
8
  let result = {
9
9
  compositeActions: /* @__PURE__ */ new Map(),
package/dist/package.js CHANGED
@@ -1,2 +1,2 @@
1
- const version = "1.2.0";
1
+ const version = "1.3.0";
2
2
  export { version };
@@ -0,0 +1,32 @@
1
+ import { TagInfo } from './tag-info';
2
+ /**
3
+ * Internal client context shared by all API functions.
4
+ *
5
+ * Stores auth, rate-limit state, base URL and in-memory caches to decrease the
6
+ * number of API requests during a single run.
7
+ */
8
+ export interface GitHubClientContext {
9
+ /** Lightweight caches keyed by owner/repo (+ extra payload). */
10
+ caches: {
11
+ /** Cache of reference type detections (branch/tag/null). */
12
+ refType: Map<string, 'branch' | 'tag' | null>
13
+
14
+ /** Cache of resolved tag metadata (message/date/SHA). */
15
+ tagInfo: Map<string, TagInfo | null>
16
+
17
+ /** Cache of resolved tag commit SHAs. */
18
+ tagSha: Map<string, string | null>
19
+ }
20
+
21
+ /** Remaining requests available per current rate-limit window. */
22
+ rateLimitRemaining: number
23
+
24
+ /** GitHub token, if available. */
25
+ token: undefined | string
26
+
27
+ /** Scheduled time when rate limit resets. */
28
+ rateLimitReset: Date
29
+
30
+ /** GitHub REST API base URL. */
31
+ baseUrl: string
32
+ }
@@ -0,0 +1,42 @@
1
+ import { ReleaseInfo } from './release-info';
2
+ import { TagInfo } from './tag-info';
3
+ /**
4
+ * Public API surface for interacting with GitHub from Actions Up.
5
+ *
6
+ * Methods are thin wrappers around lower-level functions bound to a client
7
+ * context (auth + rate-limit + caches). All methods are async and return
8
+ * normalized, serializable data structures.
9
+ */
10
+ export interface GitHubClient {
11
+ /** Detect whether a reference is a tag or a branch (or unknown). */
12
+ getRefType(
13
+ owner: string,
14
+ repo: string,
15
+ reference: string,
16
+ ): Promise<'branch' | 'tag' | null>
17
+
18
+ /** List releases with minimal enrichment. */
19
+ getAllReleases(
20
+ owner: string,
21
+ repo: string,
22
+ limit?: number,
23
+ ): Promise<ReleaseInfo[]>
24
+
25
+ /** Fetch tag metadata (message/date) and the resolved commit SHA. */
26
+ getTagInfo(owner: string, repo: string, tag: string): Promise<TagInfo | null>
27
+
28
+ /** Resolve commit SHA for a tag without fetching commit data. */
29
+ getTagSha(owner: string, repo: string, tag: string): Promise<string | null>
30
+
31
+ /** List repository tags (name + commit SHA). */
32
+ getAllTags(owner: string, repo: string, limit?: number): Promise<TagInfo[]>
33
+
34
+ /** Fetch the latest release or null when no latest release exists. */
35
+ getLatestRelease(owner: string, repo: string): Promise<ReleaseInfo | null>
36
+
37
+ /** Current rate limit snapshot. */
38
+ getRateLimitStatus(): { remaining: number; resetAt: Date }
39
+
40
+ /** True when remaining requests are below a threshold. */
41
+ shouldWaitForRateLimit(threshold?: number): boolean
42
+ }
@@ -0,0 +1,23 @@
1
+ /** Normalized release information used across the tool. */
2
+ export interface ReleaseInfo {
3
+ /** Release description (body) or null when absent. */
4
+ description: string | null
5
+
6
+ /** True when the release is marked as prerelease. */
7
+ isPrerelease: boolean
8
+
9
+ /** Commit SHA associated with the release tag (may be null). */
10
+ sha: string | null
11
+
12
+ /** Publication date of the release. */
13
+ publishedAt: Date
14
+
15
+ /** Tag name (e.g. V1.2.3). */
16
+ version: string
17
+
18
+ /** Release name or tag name when name is not provided. */
19
+ name: string
20
+
21
+ /** HTML URL of the release page. */
22
+ url: string
23
+ }
@@ -0,0 +1,14 @@
1
+ /** Normalized tag information (message/date) and the resolved commit SHA. */
2
+ export interface TagInfo {
3
+ /** Tag or commit message, null when absent. */
4
+ message: string | null
5
+
6
+ /** Commit SHA the tag ultimately points to (may be null). */
7
+ sha: string | null
8
+
9
+ /** Date associated with the tag (from release, tagger or commit). */
10
+ date: Date | null
11
+
12
+ /** Tag name (e.g. V1.2.3). */
13
+ tag: string
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "actions-up",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Interactive CLI tool to update GitHub Actions to latest versions with SHA pinning",
5
5
  "keywords": [
6
6
  "github-actions",
package/readme.md CHANGED
@@ -23,8 +23,8 @@ Interactively upgrade and pin actions to exact commit SHAs for secure, reproduci
23
23
  - **Batch Updates**: Update multiple actions at once
24
24
  - **Interactive Selection**: Choose which actions to update
25
25
  - **Breaking Changes Detection**: Warns about major version updates
26
- - **Fast & Efficient**: Parallel processing with optimized API calls
27
- - **CI/CD Integration**: Can be used as a GitHub Action for automated PR checks
26
+ - **Fast & Efficient**: Optimized API usage with deduped lookups
27
+ - **CI/CD Integration**: Use in GitHub Actions workflows for automated PR checks
28
28
 
29
29
  ###
30
30
 
@@ -167,15 +167,8 @@ jobs:
167
167
  echo "Running actions-up to check for updates..."
168
168
  actions-up --dry-run > actions-up-raw.txt 2>&1 || true
169
169
 
170
- # Strip ANSI color codes from the output
171
- sed -i 's/\x1b\[[0-9;]*m//g' actions-up-raw.txt
172
-
173
- # Also remove any other control characters
174
- sed -i 's/\x1b\[[0-9;]*[a-zA-Z]//g' actions-up-raw.txt
175
-
176
170
  # Parse the output to detect updates
177
- # Look for patterns like "v3 v4" or "would be updated"
178
- if grep -E "(→|would be updated|Update available)" actions-up-raw.txt > /dev/null 2>&1; then
171
+ if grep -q "→" actions-up-raw.txt; then
179
172
  HAS_UPDATES=true
180
173
  # Count the number of updates (lines with arrows)
181
174
  UPDATE_COUNT=$(grep -c "→" actions-up-raw.txt || echo "0")
@@ -198,67 +191,11 @@ jobs:
198
191
  echo "## GitHub Actions Update Report"
199
192
  echo ""
200
193
 
201
- # Extract summary information
202
- TOTAL_ACTIONS=$(grep -oP 'Found \K[0-9]+(?= actions)' actions-up-raw.txt | head -1 || echo "0")
203
- BREAKING_UPDATES=$(grep -oP '\(([0-9]+) breaking\)' actions-up-raw.txt | grep -oP '[0-9]+' || echo "0")
204
-
205
194
  echo "### Summary"
206
- echo "- **Total actions scanned:** $TOTAL_ACTIONS"
207
195
  echo "- **Updates available:** $UPDATE_COUNT"
208
- if [ "$BREAKING_UPDATES" != "0" ]; then
209
- echo "- **Breaking changes:** $BREAKING_UPDATES"
210
- fi
211
196
  echo ""
212
197
 
213
- echo "### Available Updates"
214
- echo ""
215
-
216
- # Format the updates in a table
217
- echo "| Workflow File | Action | Current | Available | Type | Release Notes |"
218
- echo "|--------------|--------|---------|-----------|------|---------------|"
219
-
220
- # Parse each update line
221
- grep "→" actions-up-raw.txt | while IFS= read -r line; do
222
- # Extract workflow file path (remove leading path)
223
- if echo "$line" | grep -q "\.github/workflows/"; then
224
- PREV_FILE=$(echo "$line" | grep -oP '\.github/workflows/[^:]+' | head -1)
225
- fi
226
-
227
- # Skip file path lines, process only action updates
228
- if echo "$line" | grep -q ": .* → "; then
229
- # Extract action name and versions
230
- ACTION=$(echo "$line" | cut -d: -f1 | xargs)
231
- CURRENT=$(echo "$line" | grep -oP 'v[0-9]+(\.[0-9]+)*' | head -1)
232
- NEW=$(echo "$line" | grep -oP '→ \Kv[0-9]+(\.[0-9]+)*' | head -1)
233
-
234
- # Determine if it's a breaking change
235
- CURRENT_MAJOR=$(echo "$CURRENT" | grep -oP 'v\K[0-9]+' || echo "0")
236
- NEW_MAJOR=$(echo "$NEW" | grep -oP 'v\K[0-9]+' || echo "0")
237
-
238
- if [ "$CURRENT_MAJOR" != "$NEW_MAJOR" ]; then
239
- TYPE="Breaking"
240
- # Generate release URL
241
- # Handle both owner/repo and just repo formats
242
- if echo "$ACTION" | grep -q "/"; then
243
- REPO_PATH="$ACTION"
244
- else
245
- # For actions without owner, assume it's under 'actions' org
246
- REPO_PATH="actions/$ACTION"
247
- fi
248
- RELEASE_URL="https://github.com/${REPO_PATH}/releases/tag/${NEW}"
249
- RELEASE_LINK="[Release](${RELEASE_URL})"
250
- else
251
- TYPE="Minor"
252
- RELEASE_LINK="-"
253
- fi
254
-
255
- # Output table row
256
- WORKFLOW_NAME=$(basename "$PREV_FILE" 2>/dev/null || echo "workflow.yml")
257
- echo "| \`$WORKFLOW_NAME\` | $ACTION | $CURRENT | **$NEW** | $TYPE | $RELEASE_LINK |"
258
- fi
259
- done
260
-
261
- echo ""
198
+ # See the raw output above for details.
262
199
  echo "### How to Update"
263
200
  echo ""
264
201
  echo "You have several options to update these actions:"
@@ -275,42 +212,6 @@ jobs:
275
212
  echo "3. Edit the workflow files and update the version numbers"
276
213
  echo "4. Test the changes in your CI/CD pipeline"
277
214
  echo ""
278
- echo "#### Option 3: Selective Update"
279
- echo '```bash'
280
- echo "# Update only non-breaking changes"
281
- echo "npx actions-up --breaking false"
282
- echo '```'
283
- echo ""
284
-
285
- if [ "$BREAKING_UPDATES" != "0" ]; then
286
- echo "### Breaking Changes Warning"
287
- echo ""
288
- echo "This update includes **$BREAKING_UPDATES breaking change(s)**. Please review the release notes before updating:"
289
- echo ""
290
- grep "→" actions-up-raw.txt | while IFS= read -r line; do
291
- if echo "$line" | grep -q ": .* → "; then
292
- ACTION=$(echo "$line" | cut -d: -f1 | xargs)
293
- CURRENT=$(echo "$line" | grep -oP 'v[0-9]+' | head -1)
294
- NEW=$(echo "$line" | grep -oP '→ \Kv[0-9]+(\.[0-9]+)*' | head -1)
295
- CURRENT_MAJOR=$(echo "$CURRENT" | grep -oP '[0-9]+' || echo "0")
296
- NEW_MAJOR=$(echo "$NEW" | grep -oP '[0-9]+' || echo "0")
297
- if [ "$CURRENT_MAJOR" != "$NEW_MAJOR" ]; then
298
- # Generate release URL
299
- if echo "$ACTION" | grep -q "/"; then
300
- REPO_PATH="$ACTION"
301
- else
302
- REPO_PATH="actions/$ACTION"
303
- fi
304
- RELEASE_URL="https://github.com/${REPO_PATH}/releases/tag/${NEW}"
305
- echo "- **$ACTION**: $CURRENT → $NEW - [View Release Notes](${RELEASE_URL})"
306
- fi
307
- fi
308
- done
309
- echo ""
310
- echo "**Important:** Breaking changes may require modifications to your workflow configuration. Always review the release notes and test thoroughly."
311
- echo ""
312
- fi
313
-
314
215
  echo "---"
315
216
  echo ""
316
217
  echo "<details>"
@@ -440,17 +341,6 @@ jobs:
440
341
 
441
342
  </details>
442
343
 
443
- ### Advanced PR Integration with Comments
444
-
445
- For a more sophisticated integration that comments directly on PRs with detailed update information, check out our [example workflow with PR comments](https://github.com/azat-io/actions-up/blob/main/examples/workflows/check-with-comments.yml).
446
-
447
- This advanced workflow:
448
-
449
- - Comments on PRs with a formatted table of available updates
450
- - Adds labels to PRs with outdated actions
451
- - Includes links to release notes for breaking changes
452
- - Updates existing comments instead of creating duplicates
453
-
454
344
  ### Scheduled Checks
455
345
 
456
346
  You can also set up scheduled checks to stay informed about updates:
@@ -518,22 +408,6 @@ Or in GitHub Actions:
518
408
  run: npx actions-up --dry-run
519
409
  ```
520
410
 
521
- ### Command Line Options
522
-
523
- ```bash
524
- # Update all actions without prompts
525
- npx actions-up --yes
526
-
527
- # Check for updates without making changes
528
- npx actions-up --dry-run
529
-
530
- # Update only non-breaking changes
531
- npx actions-up --breaking false
532
-
533
- # Specify custom workflow directory
534
- npx actions-up --workflows ./custom/workflows
535
- ```
536
-
537
411
  ## Security
538
412
 
539
413
  Actions Up promotes security best practices:
@@ -1,98 +0,0 @@
1
- interface ReleaseInfo {
2
- /** Release description or null if not provided. */
3
- description: string | null;
4
- /** Whether this release is marked as a pre-release. */
5
- isPrerelease: boolean;
6
- /** Git commit SHA for this release. */
7
- sha: string | null;
8
- /** Date when the release was published. */
9
- publishedAt: Date;
10
- /** Version tag name (e.g., 'v1.2.3'). */
11
- version: string;
12
- /** Release name or tag name if name not provided. */
13
- name: string;
14
- /** GitHub URL for this release. */
15
- url: string;
16
- }
17
- /** Processed tag information with normalized types. */
18
- interface TagInfo {
19
- /** Tag or commit message, null if not provided. */
20
- message: string | null;
21
- /** Git commit SHA that this tag points to. */
22
- sha: string | null;
23
- /** Date when the tag was created or committed. */
24
- date: Date | null;
25
- /** Tag name (e.g., 'v1.2.3'). */
26
- tag: string;
27
- }
28
- /** GitHub REST API client with optional authentication. */
29
- export declare class Client {
30
- private readonly baseUrl;
31
- private readonly token;
32
- private rateLimitReset;
33
- private rateLimitRemaining;
34
- /**
35
- * Creates a new GitHub API client.
36
- *
37
- * @param token - Optional GitHub token for authentication.
38
- */
39
- constructor(token?: string);
40
- private static isRateLimitError;
41
- /**
42
- * Get specific tag/version information.
43
- *
44
- * @param owner - The repository owner.
45
- * @param repo - The repository name.
46
- * @param tag - The tag name to fetch.
47
- * @returns Tag information or null if not found.
48
- */
49
- getTagInfo(owner: string, repo: string, tag: string): Promise<TagInfo | null>;
50
- /**
51
- * Get all releases for a repository.
52
- *
53
- * @param owner - The repository owner.
54
- * @param repo - The repository name.
55
- * @param limit - Maximum number of releases to fetch.
56
- * @returns Array of release information.
57
- */
58
- getAllReleases(owner: string, repo: string, limit?: number): Promise<ReleaseInfo[]>;
59
- /**
60
- * Get the latest release for a GitHub repository.
61
- *
62
- * @param owner - The repository owner.
63
- * @param repo - The repository name.
64
- * @returns Latest release information or null if not found.
65
- */
66
- getLatestRelease(owner: string, repo: string): Promise<ReleaseInfo | null>;
67
- getAllTags(owner: string, repo: string, limit?: number): Promise<TagInfo[]>;
68
- getRefType(owner: string, repo: string, reference: string): Promise<'branch' | 'tag' | null>;
69
- getRateLimitStatus(): {
70
- remaining: number;
71
- resetAt: Date;
72
- };
73
- /**
74
- * Check if we should wait before making more requests.
75
- *
76
- * @param threshold - Minimum remaining requests before waiting.
77
- * @returns True if rate limit is below threshold.
78
- */
79
- shouldWaitForRateLimit(threshold?: number): boolean;
80
- private makeRequest;
81
- private updateRateLimitInfo;
82
- }
83
- /**
84
- * Resolve GitHub token from multiple sources with descending priority.
85
- *
86
- * Priority:
87
- *
88
- * 1. Env GITHUB_TOKEN
89
- * 2. Env GH_TOKEN
90
- * 3. Gh auth token
91
- * 4. .git/config keys (github.token, github.oauth-token, hub.oauthtoken).
92
- *
93
- * This is a synchronous best-effort resolver without throwing on failures.
94
- *
95
- * @returns Token string or undefined when not found.
96
- */
97
- export declare function resolveGitHubTokenSync(): undefined | string;
98
- export {};