actionspack 0.0.0 → 0.1.1
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/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +86 -0
- package/dist/commands-CPJczWTq.mjs +1329 -0
- package/dist/index.d.mts +108 -0
- package/dist/index.mjs +2 -0
- package/package.json +62 -8
- package/index.js +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright © 2026-PRESENT Kevin Deng (https://github.com/sxzz)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# actionspack
|
|
2
|
+
|
|
3
|
+
[![Open on npmx][npmx-version-src]][npmx-href]
|
|
4
|
+
[![npm downloads][npmx-downloads-src]][npmx-href]
|
|
5
|
+
[![Unit Test][unit-test-src]][unit-test-href]
|
|
6
|
+
|
|
7
|
+
`actionspack` is a lockfile-first GitHub Actions workflow packer. It lets you
|
|
8
|
+
author workflows in `.github/workflows/src/`, lock every remote workflow/action
|
|
9
|
+
dependency in `.github/workflow.lock.yml`, and generate pinned workflows in
|
|
10
|
+
`.github/workflows/`.
|
|
11
|
+
|
|
12
|
+
It currently supports inlining composite actions and safely transformable
|
|
13
|
+
reusable workflows. JavaScript and Docker actions are pinned as external
|
|
14
|
+
dependencies instead of being bundled.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm i actionspack
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
Put authored workflows under `.github/workflows/src/`:
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
# .github/workflows/src/ci.yml
|
|
28
|
+
name: CI
|
|
29
|
+
|
|
30
|
+
on:
|
|
31
|
+
push:
|
|
32
|
+
|
|
33
|
+
jobs:
|
|
34
|
+
test:
|
|
35
|
+
uses: owner/repo/.github/workflows/test.yml@main
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then run:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx actionspack
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`actionspack` defaults to `actionspack pack`. It writes:
|
|
45
|
+
|
|
46
|
+
- `.github/workflow.lock.yml`
|
|
47
|
+
- `.github/workflows/ci.yml`
|
|
48
|
+
|
|
49
|
+
Generated workflows are safe to commit. Existing lockfile SHAs are reused until
|
|
50
|
+
you explicitly run `actionspack update`.
|
|
51
|
+
|
|
52
|
+
## Commands
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
actionspack pack
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Scan source workflows, resolve missing dependencies, update the lockfile, and
|
|
59
|
+
write generated workflows.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
actionspack scan
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Update the lockfile graph shape only. This adds newly discovered dependencies
|
|
66
|
+
and removes unreachable ones without refreshing existing SHAs.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
actionspack update [package]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Refresh all locked dependencies, or only the selected package. By default this
|
|
73
|
+
also packs workflows. Use `--lockfile-only` to update only
|
|
74
|
+
`.github/workflow.lock.yml`.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
actionspack verify
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Check that generated workflows are current and contain no unsupported unpinned
|
|
81
|
+
remote references.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
actionspack tree
|
|
85
|
+
actionspack why <package>
|
|
86
|
+
actionspack diff
|
|
87
|
+
actionspack diff --json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Inspect the lockfile dependency tree, explain why a package is present, or
|
|
91
|
+
compare the current lockfile with `HEAD`.
|
|
92
|
+
|
|
93
|
+
## Configuration
|
|
94
|
+
|
|
95
|
+
`actionspack.yml` is optional. Without it, `actionspack` discovers
|
|
96
|
+
`.github/workflows/src/*.yml` and `.github/workflows/src/*.yaml`, then writes
|
|
97
|
+
matching generated workflows to `.github/workflows/*.yml`.
|
|
98
|
+
|
|
99
|
+
Use explicit entries when you need custom paths:
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
$schema: ./actionspack.schema.json
|
|
103
|
+
|
|
104
|
+
entries:
|
|
105
|
+
- source: .github/workflows/src/ci.yml
|
|
106
|
+
output: .github/workflows/ci.yml
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Use `external` to pin a workflow or action without bundling it:
|
|
110
|
+
|
|
111
|
+
```yaml
|
|
112
|
+
external:
|
|
113
|
+
- actions/checkout
|
|
114
|
+
- owner/repo/path
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The same configuration can be supplied through CLI flags:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
actionspack pack \
|
|
121
|
+
--entry .github/workflows/src/ci.yml:.github/workflows/ci.yml \
|
|
122
|
+
--external actions/checkout
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Packing Rules
|
|
126
|
+
|
|
127
|
+
Composite actions are recursively inlined when `runs.using` is `composite`.
|
|
128
|
+
Inputs are substituted from caller `with` values or action defaults. Missing
|
|
129
|
+
required inputs fail closed.
|
|
130
|
+
|
|
131
|
+
Reusable workflows are inlined only when they use `workflow_call` and can be
|
|
132
|
+
transformed into local jobs deterministically. Unsupported cases, unresolved
|
|
133
|
+
refs, unsafe reusable workflows, and leftover remote `uses` fail closed.
|
|
134
|
+
|
|
135
|
+
JavaScript actions, Docker actions, and `docker://` references are not bundled
|
|
136
|
+
yet. They are pinned to locked SHAs as external dependencies.
|
|
137
|
+
|
|
138
|
+
## API
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { diff, pack, scan, tree, update, verify, why } from 'actionspack'
|
|
142
|
+
|
|
143
|
+
await pack()
|
|
144
|
+
await update({ packageName: 'owner/repo', lockfileOnly: true })
|
|
145
|
+
await verify()
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Sponsors
|
|
149
|
+
|
|
150
|
+
<p align="center">
|
|
151
|
+
<a href="https://cdn.jsdelivr.net/gh/sxzz/sponsors/sponsors.svg">
|
|
152
|
+
<img src='https://cdn.jsdelivr.net/gh/sxzz/sponsors/sponsors.svg'/>
|
|
153
|
+
</a>
|
|
154
|
+
</p>
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
[MIT](./LICENSE) License © 2026-PRESENT [Kevin Deng](https://github.com/sxzz)
|
|
159
|
+
|
|
160
|
+
<!-- Badges -->
|
|
161
|
+
|
|
162
|
+
[npmx-version-src]: https://npmx.dev/api/registry/badge/version/actionspack
|
|
163
|
+
[npmx-downloads-src]: https://npmx.dev/api/registry/badge/downloads-month/actionspack
|
|
164
|
+
[npmx-href]: https://npmx.dev/actionspack
|
|
165
|
+
[unit-test-src]: https://github.com/sxzz/actionspack/actions/workflows/unit-test.yml/badge.svg
|
|
166
|
+
[unit-test-href]: https://github.com/sxzz/actionspack/actions/workflows/unit-test.yml
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { a as why, f as scan, i as update, l as verify, r as tree, s as pack, t as diff } from "./commands-CPJczWTq.mjs";
|
|
3
|
+
import { styleText } from "node:util";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { cac } from "cac";
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/cli.ts
|
|
8
|
+
const cli = cac("actionspack");
|
|
9
|
+
async function main() {
|
|
10
|
+
cli.command("", "Pack workflows").option("--entry <source:output>", "Use an explicit source/output workflow mapping").option("--external <selector>", "Pin a workflow or action without bundling it").action(async (flags) => {
|
|
11
|
+
await pack({
|
|
12
|
+
...normalizeConfigFlags(flags),
|
|
13
|
+
stderr: process.stderr,
|
|
14
|
+
stdout: process.stdout
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
cli.command("pack", "Pack workflows").option("--entry <source:output>", "Use an explicit source/output workflow mapping").option("--external <selector>", "Pin a workflow or action without bundling it").action(async (flags) => {
|
|
18
|
+
await pack({
|
|
19
|
+
...normalizeConfigFlags(flags),
|
|
20
|
+
stderr: process.stderr,
|
|
21
|
+
stdout: process.stdout
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
cli.command("scan", "Update the lockfile graph without generating workflows").option("--entry <source:output>", "Use an explicit source/output workflow mapping").option("--external <selector>", "Pin a workflow or action without bundling it").action(async (flags) => {
|
|
25
|
+
await scan({
|
|
26
|
+
...normalizeConfigFlags(flags),
|
|
27
|
+
stderr: process.stderr,
|
|
28
|
+
stdout: process.stdout
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
cli.command("update [packageName]", "Refresh locked dependency versions").option("--entry <source:output>", "Use an explicit source/output workflow mapping").option("--external <selector>", "Pin a workflow or action without bundling it").option("--lockfile-only", "Write only .github/workflow.lock.yml").action(async (packageName, flags) => {
|
|
32
|
+
const { lockfileOnly, ...rest } = flags;
|
|
33
|
+
await update({
|
|
34
|
+
...normalizeConfigFlags(rest),
|
|
35
|
+
packageName,
|
|
36
|
+
lockfileOnly,
|
|
37
|
+
stderr: process.stderr,
|
|
38
|
+
stdout: process.stdout
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
cli.command("tree", "Show the dependency tree from the lockfile").action(async () => {
|
|
42
|
+
await tree({ stdout: process.stdout });
|
|
43
|
+
});
|
|
44
|
+
cli.command("why <packageName>", "Explain why a dependency exists").action(async (packageName) => {
|
|
45
|
+
await why(packageName, { stdout: process.stdout });
|
|
46
|
+
});
|
|
47
|
+
cli.command("diff", "Show lockfile changes compared with HEAD").option("--json", "Print JSON output").action(async (flags) => {
|
|
48
|
+
await diff({
|
|
49
|
+
json: flags.json,
|
|
50
|
+
stdout: process.stdout
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
cli.command("verify", "Verify lockfile and packed workflows").action(async () => {
|
|
54
|
+
await verify();
|
|
55
|
+
});
|
|
56
|
+
cli.help();
|
|
57
|
+
cli.parse(process.argv, { run: false });
|
|
58
|
+
await cli.runMatchedCommand();
|
|
59
|
+
}
|
|
60
|
+
function normalizeConfigFlags(flags) {
|
|
61
|
+
return {
|
|
62
|
+
...flags.entry ? { entries: normalizeEntries(flags.entry) } : {},
|
|
63
|
+
...flags.external ? { external: normalizeStringList(flags.external) } : {}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function normalizeEntries(value) {
|
|
67
|
+
return normalizeStringList(value).map((item) => {
|
|
68
|
+
const [source, ...outputParts] = item.split(":");
|
|
69
|
+
const output = outputParts.join(":");
|
|
70
|
+
if (!source || !output) throw new Error(`Invalid --entry value: ${item}`);
|
|
71
|
+
return {
|
|
72
|
+
source,
|
|
73
|
+
output
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function normalizeStringList(value) {
|
|
78
|
+
return Array.isArray(value) ? value : [value];
|
|
79
|
+
}
|
|
80
|
+
main().catch((error) => {
|
|
81
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
82
|
+
process.stderr.write(`${styleText("red", `actionspack: ${message}`)}\n`);
|
|
83
|
+
process.exitCode = 1;
|
|
84
|
+
});
|
|
85
|
+
//#endregion
|
|
86
|
+
export {};
|