actions-up 1.12.0 → 1.13.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/build-json-report.d.ts +257 -0
  2. package/dist/cli/build-json-report.js +64 -0
  3. package/dist/cli/index.d.ts +3 -1
  4. package/dist/cli/index.js +132 -73
  5. package/dist/cli/resolve-scan-directories.d.ts +6 -2
  6. package/dist/cli/validate-cli-options.d.ts +20 -0
  7. package/dist/cli/validate-cli-options.js +4 -0
  8. package/dist/core/api/check-updates.js +68 -55
  9. package/dist/core/api/get-all-releases.d.ts +2 -1
  10. package/dist/core/api/get-compatible-update.d.ts +15 -5
  11. package/dist/core/api/get-latest-release.d.ts +3 -3
  12. package/dist/core/ast/utils/extract-uses-from-steps.d.ts +12 -4
  13. package/dist/core/constants.d.ts +3 -1
  14. package/dist/core/fs/find-yaml-files-recursive.js +1 -1
  15. package/dist/core/interactive/prompt-update-selection.d.ts +3 -1
  16. package/dist/core/interactive/prompt-update-selection.js +9 -9
  17. package/dist/core/parsing/parse-action-reference.d.ts +16 -12
  18. package/dist/core/scan-github-actions.d.ts +4 -1
  19. package/dist/core/scan-github-actions.js +67 -67
  20. package/dist/core/versions/get-update-level.d.ts +3 -1
  21. package/dist/package.js +1 -1
  22. package/dist/types/action-update.d.ts +30 -10
  23. package/dist/types/composite-action-runs.d.ts +12 -4
  24. package/dist/types/composite-action-step.d.ts +24 -8
  25. package/dist/types/composite-action-structure.d.ts +21 -7
  26. package/dist/types/github-action.d.ts +27 -9
  27. package/dist/types/github-client-context.d.ts +24 -8
  28. package/dist/types/github-client.d.ts +24 -8
  29. package/dist/types/release-info.d.ts +24 -8
  30. package/dist/types/scan-result.d.ts +12 -4
  31. package/dist/types/tag-info.d.ts +15 -5
  32. package/dist/types/update-mode.d.ts +3 -1
  33. package/dist/types/workflow-job.d.ts +27 -9
  34. package/dist/types/workflow-step.d.ts +21 -7
  35. package/dist/types/workflow-structure.d.ts +15 -5
  36. package/package.json +3 -8
  37. package/readme.md +94 -71
@@ -1,14 +1,24 @@
1
- /** Normalized tag information (message/date) and the resolved commit SHA. */
1
+ /**
2
+ * Normalized tag information (message/date) and the resolved commit SHA.
3
+ */
2
4
  export interface TagInfo {
3
- /** Tag or commit message, null when absent. */
5
+ /**
6
+ * Tag or commit message, null when absent.
7
+ */
4
8
  message: string | null
5
9
 
6
- /** Commit SHA the tag ultimately points to (may be null). */
10
+ /**
11
+ * Commit SHA the tag ultimately points to (may be null).
12
+ */
7
13
  sha: string | null
8
14
 
9
- /** Date associated with the tag (from release, tagger or commit). */
15
+ /**
16
+ * Date associated with the tag (from release, tagger or commit).
17
+ */
10
18
  date: Date | null
11
19
 
12
- /** Tag name (e.g. V1.2.3). */
20
+ /**
21
+ * Tag name (e.g. V1.2.3).
22
+ */
13
23
  tag: string
14
24
  }
@@ -1,2 +1,4 @@
1
- /** Allowed update modes for filtering actions. */
1
+ /**
2
+ * Allowed update modes for filtering actions.
3
+ */
2
4
  export type UpdateMode = 'major' | 'minor' | 'patch'
@@ -1,27 +1,45 @@
1
1
  import { WorkflowStep } from './workflow-step';
2
- /** Represents a job in a GitHub Actions workflow. */
2
+ /**
3
+ * Represents a job in a GitHub Actions workflow.
4
+ */
3
5
  export interface WorkflowJob {
4
- /** Secrets passed to the reusable workflow ('inherit' or specific secrets). */
6
+ /**
7
+ * Secrets passed to the reusable workflow ('inherit' or specific secrets).
8
+ */
5
9
  secrets?: Record<string, unknown> | 'inherit'
6
10
 
7
- /** Input parameters passed to the reusable workflow. */
11
+ /**
12
+ * Input parameters passed to the reusable workflow.
13
+ */
8
14
  with?: Record<string, unknown>
9
15
 
10
- /** Runner environment(s) to execute this job on (e.g., 'ubuntu-latest'). */
16
+ /**
17
+ * Runner environment(s) to execute this job on (e.g., 'ubuntu-latest').
18
+ */
11
19
  'runs-on'?: string[] | string
12
20
 
13
- /** Job IDs that must complete successfully before this job runs. */
21
+ /**
22
+ * Job IDs that must complete successfully before this job runs.
23
+ */
14
24
  needs?: string[] | string
15
25
 
16
- /** Array of steps to execute in this job. */
26
+ /**
27
+ * Array of steps to execute in this job.
28
+ */
17
29
  steps?: WorkflowStep[]
18
30
 
19
- /** Allow additional properties for job configuration. */
31
+ /**
32
+ * Allow additional properties for job configuration.
33
+ */
20
34
  [key: string]: unknown
21
35
 
22
- /** Reusable workflow reference (mutually exclusive with 'steps'). */
36
+ /**
37
+ * Reusable workflow reference (mutually exclusive with 'steps').
38
+ */
23
39
  uses?: string
24
40
 
25
- /** Conditional expression to determine if the job should run. */
41
+ /**
42
+ * Conditional expression to determine if the job should run.
43
+ */
26
44
  if?: string
27
45
  }
@@ -1,20 +1,34 @@
1
- /** Represents a single step in a GitHub Actions workflow job. */
1
+ /**
2
+ * Represents a single step in a GitHub Actions workflow job.
3
+ */
2
4
  export interface WorkflowStep {
3
- /** Input parameters to pass to the action. */
5
+ /**
6
+ * Input parameters to pass to the action.
7
+ */
4
8
  with?: Record<string, unknown>
5
9
 
6
- /** Environment variables to set for this step. */
10
+ /**
11
+ * Environment variables to set for this step.
12
+ */
7
13
  env?: Record<string, unknown>
8
14
 
9
- /** Allow additional properties for step configuration. */
15
+ /**
16
+ * Allow additional properties for step configuration.
17
+ */
10
18
  [key: string]: unknown
11
19
 
12
- /** Action to use for this step (e.g., 'actions/checkout@v4'). */
20
+ /**
21
+ * Action to use for this step (e.g., 'actions/checkout@v4').
22
+ */
13
23
  uses?: string
14
24
 
15
- /** Display name for this step. */
25
+ /**
26
+ * Display name for this step.
27
+ */
16
28
  name?: string
17
29
 
18
- /** Shell command to run for this step. */
30
+ /**
31
+ * Shell command to run for this step.
32
+ */
19
33
  run?: string
20
34
  }
@@ -1,15 +1,25 @@
1
1
  import { WorkflowJob } from './workflow-job';
2
- /** Represents the root structure of a GitHub Actions workflow file. */
2
+ /**
3
+ * Represents the root structure of a GitHub Actions workflow file.
4
+ */
3
5
  export interface WorkflowStructure {
4
- /** Map of job IDs to job configurations. */
6
+ /**
7
+ * Map of job IDs to job configurations.
8
+ */
5
9
  jobs?: Record<string, WorkflowJob>
6
10
 
7
- /** Allow additional properties for workflow configuration. */
11
+ /**
12
+ * Allow additional properties for workflow configuration.
13
+ */
8
14
  [key: string]: unknown
9
15
 
10
- /** Display name for the workflow. */
16
+ /**
17
+ * Display name for the workflow.
18
+ */
11
19
  name?: string
12
20
 
13
- /** Events that trigger the workflow (push, pull_request, etc.). */
21
+ /**
22
+ * Events that trigger the workflow (push, pull_request, etc.).
23
+ */
14
24
  on?: unknown
15
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "actions-up",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "Interactive CLI tool to update GitHub Actions to latest versions with SHA pinning",
5
5
  "keywords": [
6
6
  "github-actions",
@@ -36,19 +36,14 @@
36
36
  "./dist"
37
37
  ],
38
38
  "dependencies": {
39
- "cac": "^6.7.14",
39
+ "cac": "^7.0.0",
40
40
  "enquirer": "^2.4.1",
41
41
  "nanospinner": "^1.2.2",
42
42
  "picocolors": "^1.1.1",
43
43
  "semver": "^7.7.4",
44
- "yaml": "^2.8.2"
44
+ "yaml": "^2.8.3"
45
45
  },
46
46
  "engines": {
47
47
  "node": "^18.0.0 || >=20.0.0"
48
- },
49
- "pnpm": {
50
- "overrides": {
51
- "vite": "npm:rolldown-vite@latest"
52
- }
53
48
  }
54
49
  }
package/readme.md CHANGED
@@ -12,15 +12,21 @@
12
12
  [![Code Coverage](https://img.shields.io/codecov/c/github/azat-io/actions-up.svg?color=fff&labelColor=4493f8)](https://codecov.io/gh/azat-io/actions-up)
13
13
  [![GitHub License](https://img.shields.io/badge/license-MIT-232428.svg?color=fff&labelColor=4493f8)](https://github.com/azat-io/actions-up/blob/main/license.md)
14
14
 
15
- Actions Up scans your workflows and composite actions to discover every referenced GitHub Action, then checks for newer releases.
15
+ Actions Up scans your workflows and composite actions to discover every
16
+ referenced GitHub Action, then checks for newer releases.
16
17
 
17
- Interactively upgrade and pin actions to exact commit SHAs for secure, reproducible CI and low-friction maintenance.
18
+ Interactively upgrade and pin actions to exact commit SHAs for secure,
19
+ reproducible CI and low-friction maintenance.
18
20
 
19
21
  ## Features
20
22
 
21
- - **Auto-discovery**: Scans all workflows (`.github/workflows/*.yml`) and composite actions (`.github/actions/*/action.yml` and root `action.yml`/`action.yaml`)
22
- - **Reusable Workflows**: Detects and updates reusable workflow calls at the job level
23
- - **SHA pinning**: Updates actions to use commit SHA instead of tags for better security
23
+ - **Auto-discovery**: Scans all workflows (`.github/workflows/*.yml`) and
24
+ composite actions (`.github/actions/*/action.yml` and root
25
+ `action.yml`/`action.yaml`)
26
+ - **Reusable Workflows**: Detects and updates reusable workflow calls at the job
27
+ level
28
+ - **SHA pinning**: Updates actions to use commit SHA instead of tags for better
29
+ security
24
30
  - **Batch Updates**: Update multiple actions at once
25
31
  - **Interactive Selection**: Choose which actions to update
26
32
  - **Breaking Changes Detection**: Warns about major version updates
@@ -49,7 +55,9 @@ Interactively upgrade and pin actions to exact commit SHAs for secure, reproduci
49
55
 
50
56
  ## Why
51
57
 
52
- Keeping GitHub Actions updated is critical and time-consuming. Actions Up scans all workflows, highlights available updates, and can pin actions to SHAs for reproducibility.
58
+ Keeping GitHub Actions updated is critical and time-consuming. Actions Up scans
59
+ all workflows, highlights available updates, and can pin actions to SHAs for
60
+ reproducibility.
53
61
 
54
62
  | Without Actions Up | With Actions Up |
55
63
  | :----------------------------- | :------------------------------- |
@@ -59,7 +67,10 @@ Keeping GitHub Actions updated is critical and time-consuming. Actions Up scans
59
67
 
60
68
  ### Security Motivation
61
69
 
62
- GitHub Actions run arbitrary code in your CI. If a job has secrets available, any action used in that job can read the environment and exfiltrate those secrets. A compromised action or a mutable version tag is a direct path to leakage.
70
+ GitHub Actions run arbitrary code in your CI. If a job has secrets available,
71
+ any action used in that job can read the environment and exfiltrate those
72
+ secrets. A compromised action or a mutable version tag is a direct path to
73
+ leakage.
63
74
 
64
75
  Actions Up reduces risk by:
65
76
 
@@ -67,7 +78,9 @@ Actions Up reduces risk by:
67
78
  - Making outdated actions visible and showing exactly what runs in CI
68
79
  - Warning about major updates so you can review changes before applying them
69
80
 
70
- Note: secrets are available on `push`, `workflow_dispatch`, `schedule`, and `pull_request_target` triggers (and on fork PRs if explicitly enabled). Always scope workflow permissions to the minimum required.
81
+ Note: secrets are available on `push`, `workflow_dispatch`, `schedule`, and
82
+ `pull_request_target` triggers (and on fork PRs if explicitly enabled). Always
83
+ scope workflow permissions to the minimum required.
71
84
 
72
85
  ## Installation
73
86
 
@@ -107,7 +120,8 @@ npx actions-up
107
120
 
108
121
  This will:
109
122
 
110
- 1. Scan all `.github/workflows/*.yml` and `.github/actions/*/action.yml` files, plus root `action.yml`/`action.yaml`
123
+ 1. Scan all `.github/workflows/*.yml` and `.github/actions/*/action.yml` files,
124
+ plus root `action.yml`/`action.yaml`
111
125
  2. Check for available updates
112
126
  3. Show an interactive list to select updates
113
127
  4. Apply selected updates with SHA pinning
@@ -130,11 +144,23 @@ Check for updates without making any changes:
130
144
  npx actions-up --dry-run
131
145
  ```
132
146
 
147
+ ### JSON Mode
148
+
149
+ Output a machine-readable JSON report instead of the interactive UI:
150
+
151
+ ```bash
152
+ npx actions-up --json
153
+ ```
154
+
155
+ `--json` is report-only: it never writes files, skips the interactive prompt,
156
+ and cannot be combined with `--yes`.
157
+
133
158
  ### Custom Directory
134
159
 
135
160
  By default, Actions Up scans `.github`.
136
161
 
137
- Use `--dir` to choose another directory, and pass it multiple times to scan several directories:
162
+ Use `--dir` to choose another directory, and pass it multiple times to scan
163
+ several directories:
138
164
 
139
165
  ```bash
140
166
  npx actions-up --dir .gitea
@@ -143,18 +169,23 @@ npx actions-up --dir .github --dir ./other/.github
143
169
 
144
170
  ### Recursive Scanning
145
171
 
146
- Use `--recursive` (`-r`) to scan YAML workflow/composite-action files recursively in the selected directories:
172
+ Use `--recursive` (`-r`) to scan YAML workflow/composite-action files
173
+ recursively in the selected directories:
147
174
 
148
175
  ```bash
149
176
  npx actions-up -r
150
177
  npx actions-up --dir ./gh-repo-defaults -r
151
178
  ```
152
179
 
153
- When `--recursive` is used without `--dir`, Actions Up scans from the current directory (`.`).
180
+ When `--recursive` is used without `--dir`, Actions Up scans from the current
181
+ directory (`.`).
154
182
 
155
183
  ### Branch References
156
184
 
157
- By default, actions pinned to branch refs (e.g., `@main`, `@release/v1`) are skipped to avoid changing intentionally floating references. Skipped entries are listed in the output. To include them in update checks, pass `--include-branches`.
185
+ By default, actions pinned to branch refs (e.g., `@main`, `@release/v1`) are
186
+ skipped to avoid changing intentionally floating references. Skipped entries are
187
+ listed in the output. To include them in update checks, pass
188
+ `--include-branches`.
158
189
 
159
190
  ### Update Mode
160
191
 
@@ -165,15 +196,17 @@ npx actions-up --mode minor
165
196
  npx actions-up --mode patch
166
197
  ```
167
198
 
168
- In `minor` and `patch` modes, Actions Up tries to find the newest compatible
169
- tag first (for example, from `@v4` in `minor` mode it will choose the latest
199
+ In `minor` and `patch` modes, Actions Up tries to find the newest compatible tag
200
+ first (for example, from `@v4` in `minor` mode it will choose the latest
170
201
  `v4.x.y`). If no compatible version exists, that action is skipped.
171
202
 
172
203
  ## GitHub Actions Integration
173
204
 
174
205
  ### Automated PR Checks
175
206
 
176
- You can integrate Actions Up into your CI/CD pipeline to automatically check for outdated actions on every pull request. This helps maintain security and ensures your team stays aware of available updates.
207
+ You can integrate Actions Up into your CI/CD pipeline to automatically check for
208
+ outdated actions on every pull request. This helps maintain security and ensures
209
+ your team stays aware of available updates.
177
210
 
178
211
  <details>
179
212
  <summary>Create <code>.github/workflows/check-actions-updates.yml</code>.</summary>
@@ -213,69 +246,53 @@ jobs:
213
246
  echo "## GitHub Actions Update Check" >> $GITHUB_STEP_SUMMARY
214
247
  echo "" >> $GITHUB_STEP_SUMMARY
215
248
 
216
- # Initialize variables
217
- HAS_UPDATES=false
218
- UPDATE_COUNT=0
219
-
220
- # Run actions-up and capture output
249
+ # Run actions-up and capture machine-readable output
221
250
  echo "Running actions-up to check for updates..."
222
- actions-up --dry-run > actions-up-raw.txt 2>&1
251
+ actions-up --json > actions-up-report.json
223
252
 
224
- # Parse the output to detect updates
225
- if grep -q "→" actions-up-raw.txt; then
226
- HAS_UPDATES=true
227
- # Count the number of updates (lines with arrows)
228
- UPDATE_COUNT=$(grep -c "→" actions-up-raw.txt || echo "0")
229
- fi
253
+ UPDATE_COUNT=$(node -pe "JSON.parse(require('node:fs').readFileSync('actions-up-report.json', 'utf8')).summary.totalUpdates")
230
254
 
231
255
  # Create formatted output
232
- if [ "$HAS_UPDATES" = true ]; then
256
+ if [ "$UPDATE_COUNT" -gt 0 ]; then
233
257
  echo "Found $UPDATE_COUNT GitHub Actions with available updates" >> $GITHUB_STEP_SUMMARY
234
258
  echo "" >> $GITHUB_STEP_SUMMARY
235
259
  echo "<details>" >> $GITHUB_STEP_SUMMARY
236
- echo "<summary>Click to see details</summary>" >> $GITHUB_STEP_SUMMARY
260
+ echo "<summary>Click to see JSON report</summary>" >> $GITHUB_STEP_SUMMARY
237
261
  echo "" >> $GITHUB_STEP_SUMMARY
238
- echo '```' >> $GITHUB_STEP_SUMMARY
239
- cat actions-up-raw.txt >> $GITHUB_STEP_SUMMARY
262
+ echo '```json' >> $GITHUB_STEP_SUMMARY
263
+ cat actions-up-report.json >> $GITHUB_STEP_SUMMARY
240
264
  echo '```' >> $GITHUB_STEP_SUMMARY
241
265
  echo "</details>" >> $GITHUB_STEP_SUMMARY
242
266
 
243
267
  # Create detailed markdown report with better formatting
244
- {
245
- echo "## GitHub Actions Update Report"
246
- echo ""
268
+ node --input-type=module <<'EOF'
269
+ import { readFileSync, writeFileSync } from 'node:fs'
270
+
271
+ let report = JSON.parse(readFileSync('actions-up-report.json', 'utf8'))
272
+ let lines = [
273
+ '## GitHub Actions Update Report',
274
+ '',
275
+ '### Summary',
276
+ `- **Updates available:** ${report.summary.totalUpdates}`,
277
+ '',
278
+ '### Updates',
279
+ '',
280
+ ]
281
+
282
+ for (let update of report.updates) {
283
+ let file = update.action.file ?? 'unknown'
284
+ let currentVersion = update.currentVersion ?? 'unknown'
285
+ let latestVersion = update.latestVersion ?? 'unknown'
286
+ lines.push(
287
+ `- \`${update.action.name}\` in \`${file}\`: \`${currentVersion}\` → \`${latestVersion}\``,
288
+ )
289
+ }
247
290
 
248
- echo "### Summary"
249
- echo "- **Updates available:** $UPDATE_COUNT"
250
- echo ""
291
+ lines.push('')
292
+ lines.push('Run `npx actions-up` locally to review and apply updates.')
251
293
 
252
- # See the raw output above for details.
253
- echo "### How to Update"
254
- echo ""
255
- echo "Choose from several ways to update these actions:"
256
- echo ""
257
- echo "#### Option 1: Automatic Update (Recommended)"
258
- echo '```bash'
259
- echo "# Run this command locally in your repository"
260
- echo "npx actions-up"
261
- echo '```'
262
- echo ""
263
- echo "#### Option 2: Manual Update"
264
- echo "1. Review each update in the table above"
265
- echo "2. For breaking changes, click the Release Notes link to review changes"
266
- echo "3. Edit the workflows and update the version numbers"
267
- echo "4. Test the changes in your CI/CD pipeline"
268
- echo ""
269
- echo "---"
270
- echo ""
271
- echo "<details>"
272
- echo "<summary>Raw actions-up output</summary>"
273
- echo ""
274
- echo '```'
275
- cat actions-up-raw.txt
276
- echo '```'
277
- echo "</details>"
278
- } > actions-up-report.md
294
+ writeFileSync('actions-up-report.md', lines.join('\n'))
295
+ EOF
279
296
 
280
297
  echo "has-updates=true" >> $GITHUB_OUTPUT
281
298
  echo "update-count=$UPDATE_COUNT" >> $GITHUB_OUTPUT
@@ -295,7 +312,9 @@ jobs:
295
312
  fi
296
313
 
297
314
  - name: Comment PR with updates
298
- if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
315
+ if:
316
+ github.event_name == 'pull_request' &&
317
+ github.event.pull_request.head.repo.full_name == github.repository
299
318
  uses: actions/github-script@v7
300
319
  with:
301
320
  script: |
@@ -433,7 +452,8 @@ jobs:
433
452
 
434
453
  ### GitHub Token
435
454
 
436
- Use `GITHUB_TOKEN` (or a PAT) to raise API rate limits from 60 to 5000 requests/hour.
455
+ Use `GITHUB_TOKEN` (or a PAT) to raise API rate limits from 60 to 5000
456
+ requests/hour.
437
457
 
438
458
  ```bash
439
459
  GITHUB_TOKEN=your_token_here npx actions-up
@@ -445,7 +465,7 @@ Or in GitHub Actions:
445
465
  - name: Check for updates
446
466
  env:
447
467
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
448
- run: npx actions-up --dry-run
468
+ run: npx actions-up --json
449
469
  ```
450
470
 
451
471
  ### Skipping Updates
@@ -479,14 +499,17 @@ Ignore comments (file/block/next-line/inline):
479
499
 
480
500
  Interactive CLI for developers who want control over GitHub Actions updates.
481
501
 
482
- - **vs. Dependabot/Renovate:** Dependabot and Renovate update via pull requests; Actions Up is an interactive CLI with explicit SHA pinning.
483
- - **vs. pinact:** pinact is a CLI to pin and update Actions and reusable workflows; Actions Up adds interactive selection and major update warnings.
502
+ - **vs. Dependabot/Renovate:** Dependabot and Renovate update via pull requests;
503
+ Actions Up is an interactive CLI with explicit SHA pinning.
504
+ - **vs. pinact:** pinact is a CLI to pin and update Actions and reusable
505
+ workflows; Actions Up adds interactive selection and major update warnings.
484
506
  - **Zero-config:** `npx actions-up` runs immediately.
485
507
  - **Breaking change warnings:** Major updates are flagged before applying.
486
508
 
487
509
  ## Contributing
488
510
 
489
- See [Contributing Guide](https://github.com/azat-io/actions-up/blob/main/contributing.md).
511
+ See
512
+ [Contributing Guide](https://github.com/azat-io/actions-up/blob/main/contributing.md).
490
513
 
491
514
  ## License
492
515