@intentius/chant-lexicon-gitlab 0.124.31 → 0.124.33
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/codegen/docs-cli.js +2 -0
- package/dist/codegen/docs.js +157 -0
- package/dist/codegen/fetch.js +93 -0
- package/dist/codegen/generate-cli.js +30 -0
- package/dist/codegen/generate-lexicon.js +36 -0
- package/dist/codegen/generate-typescript.js +105 -0
- package/dist/codegen/generate.js +125 -0
- package/dist/codegen/naming.js +48 -0
- package/dist/codegen/package.js +41 -0
- package/dist/codegen/parse.js +539 -0
- package/dist/codegen/patches.js +84 -0
- package/dist/codegen/typecheck.js +4 -0
- package/dist/components/ci-jobs.js +16 -0
- package/dist/components/generate-op-pipeline.d.ts.map +1 -1
- package/dist/components/generate-op-pipeline.js +294 -0
- package/dist/components/generate-op-waves-pipeline.js +125 -0
- package/dist/components/generate-pipeline.d.ts.map +1 -1
- package/dist/components/generate-pipeline.js +376 -0
- package/dist/composites/catalog.js +418 -0
- package/dist/composites/docker-build.js +38 -0
- package/dist/composites/index.js +5 -0
- package/dist/composites/mr-plan-report.js +42 -0
- package/dist/composites/node-pipeline.js +67 -0
- package/dist/composites/python-pipeline.js +45 -0
- package/dist/composites/review-app.js +32 -0
- package/dist/coverage.js +35 -0
- package/dist/generated/index.js +25 -0
- package/dist/generated/runtime.js +4 -0
- package/dist/graph-edges.js +202 -0
- package/dist/import/generator.js +196 -0
- package/dist/import/parser.js +111 -0
- package/dist/index.js +26 -0
- package/dist/integrity.json +3 -3
- package/dist/intrinsics.js +33 -0
- package/dist/lint/audit-catalog.js +53 -0
- package/dist/lint/audit-lineage.js +64 -0
- package/dist/lint/post-synth/index.js +84 -0
- package/dist/lint/post-synth/wgl010.js +34 -0
- package/dist/lint/post-synth/wgl011.js +48 -0
- package/dist/lint/post-synth/wgl012.d.ts.map +1 -1
- package/dist/lint/post-synth/wgl012.js +68 -0
- package/dist/lint/post-synth/wgl013.js +57 -0
- package/dist/lint/post-synth/wgl014.js +43 -0
- package/dist/lint/post-synth/wgl015.js +70 -0
- package/dist/lint/post-synth/wgl016.js +70 -0
- package/dist/lint/post-synth/wgl017.js +38 -0
- package/dist/lint/post-synth/wgl018.js +34 -0
- package/dist/lint/post-synth/wgl019.js +43 -0
- package/dist/lint/post-synth/wgl020.js +47 -0
- package/dist/lint/post-synth/wgl021.js +52 -0
- package/dist/lint/post-synth/wgl022.js +38 -0
- package/dist/lint/post-synth/wgl023.js +44 -0
- package/dist/lint/post-synth/wgl024.js +41 -0
- package/dist/lint/post-synth/wgl025.js +42 -0
- package/dist/lint/post-synth/wgl026.js +58 -0
- package/dist/lint/post-synth/wgl027.js +49 -0
- package/dist/lint/post-synth/wgl028.js +58 -0
- package/dist/lint/post-synth/wgl029.js +55 -0
- package/dist/lint/post-synth/wgl030.js +43 -0
- package/dist/lint/post-synth/wgl031.js +33 -0
- package/dist/lint/post-synth/wgl032.js +64 -0
- package/dist/lint/post-synth/wgl033.js +32 -0
- package/dist/lint/post-synth/wgl034.js +37 -0
- package/dist/lint/post-synth/wgl035.js +40 -0
- package/dist/lint/post-synth/wgl036.js +38 -0
- package/dist/lint/post-synth/wgl037.js +41 -0
- package/dist/lint/post-synth/wgl038.js +43 -0
- package/dist/lint/post-synth/wgl039.js +34 -0
- package/dist/lint/post-synth/wgl040.js +35 -0
- package/dist/lint/post-synth/wgl041.js +53 -0
- package/dist/lint/post-synth/wgl042.js +41 -0
- package/dist/lint/post-synth/wgl043.js +39 -0
- package/dist/lint/post-synth/wgl044.js +35 -0
- package/dist/lint/post-synth/wgl045.js +54 -0
- package/dist/lint/post-synth/wgl046.js +40 -0
- package/dist/lint/post-synth/wgl047.js +34 -0
- package/dist/lint/post-synth/wgl048.js +32 -0
- package/dist/lint/post-synth/wgl049.js +53 -0
- package/dist/lint/post-synth/wgl050.js +42 -0
- package/dist/lint/post-synth/yaml-helpers.js +432 -0
- package/dist/lint/rules/artifact-no-expiry.js +53 -0
- package/dist/lint/rules/data/known-include-sources.js +44 -0
- package/dist/lint/rules/data/untrusted-variables.js +30 -0
- package/dist/lint/rules/deprecated-only-except.js +46 -0
- package/dist/lint/rules/import-source.js +61 -0
- package/dist/lint/rules/index.js +7 -0
- package/dist/lint/rules/missing-script.js +67 -0
- package/dist/lint/rules/missing-stage.js +60 -0
- package/dist/lsp/completions.d.ts.map +1 -1
- package/dist/lsp/completions.js +18 -0
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/lsp/hover.js +33 -0
- package/dist/manifest.json +1 -1
- package/dist/mcp/context-tools.js +262 -0
- package/dist/migrate/from-github/actions/index.js +17 -0
- package/dist/migrate/from-github/actions/registry.js +61 -0
- package/dist/migrate/from-github/actions/tier-1.js +298 -0
- package/dist/migrate/from-github/actions/tier-2.js +241 -0
- package/dist/migrate/from-github/actions/tier-3.js +96 -0
- package/dist/migrate/from-github/composites/patterns.js +151 -0
- package/dist/migrate/from-github/composites/rewriter.js +22 -0
- package/dist/migrate/from-github/diagnostics.js +53 -0
- package/dist/migrate/from-github/emit-yaml.js +121 -0
- package/dist/migrate/from-github/expressions.js +275 -0
- package/dist/migrate/from-github/index.js +96 -0
- package/dist/migrate/from-github/provenance.js +35 -0
- package/dist/migrate/from-github/rules.js +74 -0
- package/dist/migrate/from-github/security.js +189 -0
- package/dist/migrate/from-github/stages.js +156 -0
- package/dist/migrate/from-github/transformer.js +633 -0
- package/dist/op/activities/gitlab.js +38 -0
- package/dist/op/activities/index.js +10 -0
- package/dist/op/builders.js +26 -0
- package/dist/package-cli.js +21 -0
- package/dist/plugin.js +536 -0
- package/dist/rules/wgl012.ts +2 -2
- package/dist/serializer.js +197 -0
- package/dist/testdata/create-fixture.js +40 -0
- package/dist/testdata/load-fixtures.js +20 -0
- package/dist/validate-cli.js +16 -0
- package/dist/validate.js +29 -0
- package/dist/variables.js +30 -0
- package/package.json +8 -8
- package/src/codegen/fetch.ts +2 -2
- package/src/codegen/package.ts +2 -2
- package/src/components/__fixtures__/pr-loop-build.gitlab.golden.yml +3 -3
- package/src/components/__fixtures__/pr-loop-record.gitlab.golden.yml +46 -0
- package/src/components/__fixtures__/pr-loop-waves.gitlab.golden.yml +101 -0
- package/src/components/__fixtures__/pr-loop.gitlab.golden.yml +3 -3
- package/src/components/generate-op-pipeline.test.ts +10 -0
- package/src/components/generate-op-pipeline.ts +8 -1
- package/src/components/generate-pipeline.ts +71 -30
- package/src/components/generate-pr-pipeline.test.ts +61 -18
- package/src/components/generate-pr-waves-pipeline.test.ts +88 -0
- package/src/lint/post-synth/wgl012.ts +2 -2
- package/src/lsp/completions.ts +2 -1
- package/src/lsp/hover.ts +2 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action mapping registry — public surface.
|
|
3
|
+
*
|
|
4
|
+
* Tier 1 mappings auto-register into the default registry on import of
|
|
5
|
+
* this module. Tier 2 and Tier 3 are added in #88.
|
|
6
|
+
*/
|
|
7
|
+
export { createRegistry, getDefaultRegistry, lookupAction, setDefaultRegistry } from "./registry.js";
|
|
8
|
+
import { registerTier1 } from "./tier-1.js";
|
|
9
|
+
import { registerTier2 } from "./tier-2.js";
|
|
10
|
+
import { registerTier3 } from "./tier-3.js";
|
|
11
|
+
import { getDefaultRegistry } from "./registry.js";
|
|
12
|
+
// Auto-register Tiers 1/2/3 into the default registry the first time
|
|
13
|
+
// this module is imported.
|
|
14
|
+
registerTier1(getDefaultRegistry());
|
|
15
|
+
registerTier2(getDefaultRegistry());
|
|
16
|
+
registerTier3(getDefaultRegistry());
|
|
17
|
+
export { registerTier1, registerTier2, registerTier3 };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ActionMapping registry for GitHub Actions → GitLab CI translation.
|
|
3
|
+
*
|
|
4
|
+
* Each marketplace action gets a typed mapping that returns the GitLab-side
|
|
5
|
+
* effects (script lines, image substitution, services, cache, artifacts,
|
|
6
|
+
* job-level variables) plus provenance records.
|
|
7
|
+
*
|
|
8
|
+
* v1 ships a built-in registry covering 33 actions (Tier 1/2/3, see
|
|
9
|
+
* `tier-1.ts`/`tier-2.ts`/`tier-3.ts`). Users can inject their own
|
|
10
|
+
* mappings via `MigrateOptions.registry`.
|
|
11
|
+
*/
|
|
12
|
+
class DefaultRegistry {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.byName = new Map();
|
|
15
|
+
}
|
|
16
|
+
register(mapping) {
|
|
17
|
+
const arr = this.byName.get(mapping.actionName) ?? [];
|
|
18
|
+
arr.push(mapping);
|
|
19
|
+
this.byName.set(mapping.actionName, arr);
|
|
20
|
+
}
|
|
21
|
+
lookup(actionRef) {
|
|
22
|
+
// actionRef is e.g. "actions/checkout@v4" or "docker/build-push-action@v5"
|
|
23
|
+
const [name, version] = actionRef.split("@");
|
|
24
|
+
const candidates = this.byName.get(name);
|
|
25
|
+
if (!candidates || candidates.length === 0)
|
|
26
|
+
return undefined;
|
|
27
|
+
if (!version)
|
|
28
|
+
return candidates[0];
|
|
29
|
+
// Find a mapping whose majorVersions includes this version (best effort)
|
|
30
|
+
const major = version.replace(/^v/, "").split(".")[0];
|
|
31
|
+
for (const c of candidates) {
|
|
32
|
+
if (!c.majorVersions || c.majorVersions.length === 0)
|
|
33
|
+
return c;
|
|
34
|
+
if (c.majorVersions.includes(`v${major}`) || c.majorVersions.includes(major)) {
|
|
35
|
+
return c;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// No version match — fall back to first registered
|
|
39
|
+
return candidates[0];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
let defaultRegistryInstance;
|
|
43
|
+
export function getDefaultRegistry() {
|
|
44
|
+
if (!defaultRegistryInstance) {
|
|
45
|
+
defaultRegistryInstance = new DefaultRegistry();
|
|
46
|
+
}
|
|
47
|
+
return defaultRegistryInstance;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Test-only: replace the default registry. Used by `lookupAction` callers
|
|
51
|
+
* that pass `opts.registry` to inject a stub. Reset to undefined to restore.
|
|
52
|
+
*/
|
|
53
|
+
export function setDefaultRegistry(registry) {
|
|
54
|
+
defaultRegistryInstance = registry;
|
|
55
|
+
}
|
|
56
|
+
export function createRegistry() {
|
|
57
|
+
return new DefaultRegistry();
|
|
58
|
+
}
|
|
59
|
+
export function lookupAction(actionRef, registry) {
|
|
60
|
+
return (registry ?? getDefaultRegistry()).lookup(actionRef);
|
|
61
|
+
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tier 1 marketplace action mappings — the 14 most-used GitHub Actions
|
|
3
|
+
* marketplace actions, per the upstream skill's `references/marketplace-actions.md`.
|
|
4
|
+
*
|
|
5
|
+
* Each mapping returns:
|
|
6
|
+
* - scriptLines: appended to job.script
|
|
7
|
+
* - image: job-level image override (last write wins)
|
|
8
|
+
* - services: docker:dind etc.
|
|
9
|
+
* - cache / artifacts: native GitLab keywords
|
|
10
|
+
* - provenance: per-step records
|
|
11
|
+
*/
|
|
12
|
+
import { getDefaultRegistry } from "./registry.js";
|
|
13
|
+
const prov = (ctx, actionName, tier, note, category = "action-map") => ({
|
|
14
|
+
gitlabPath: `jobs.${ctx.logicalId}.script`,
|
|
15
|
+
gitlabLogicalId: ctx.logicalId,
|
|
16
|
+
sourceKey: `jobs.${ctx.jobName}.steps[${ctx.stepIndex}].uses`,
|
|
17
|
+
sourceFile: ctx.sourceFile,
|
|
18
|
+
category,
|
|
19
|
+
rule: `ACT-${actionName.replace(/[\/-]/g, "-")}`,
|
|
20
|
+
note,
|
|
21
|
+
actionRef: actionName,
|
|
22
|
+
mappingTier: tier,
|
|
23
|
+
});
|
|
24
|
+
function withVal(o, key) {
|
|
25
|
+
if (!o)
|
|
26
|
+
return undefined;
|
|
27
|
+
return o[key];
|
|
28
|
+
}
|
|
29
|
+
function getWith(step) {
|
|
30
|
+
return step.with ?? {};
|
|
31
|
+
}
|
|
32
|
+
// actions/checkout: GitLab clones automatically. Emit no script lines.
|
|
33
|
+
const actionsCheckout = {
|
|
34
|
+
actionName: "actions/checkout",
|
|
35
|
+
tier: 1,
|
|
36
|
+
translate(step, ctx) {
|
|
37
|
+
const w = getWith(step);
|
|
38
|
+
const variables = {};
|
|
39
|
+
if (w["fetch-depth"] !== undefined) {
|
|
40
|
+
variables.GIT_DEPTH = w["fetch-depth"];
|
|
41
|
+
}
|
|
42
|
+
if (w.submodules === true || w.submodules === "true" || w.submodules === "recursive") {
|
|
43
|
+
variables.GIT_SUBMODULE_STRATEGY = w.submodules === "recursive" ? "recursive" : "normal";
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
scriptLines: [],
|
|
47
|
+
variables: Object.keys(variables).length > 0 ? variables : undefined,
|
|
48
|
+
provenance: [prov(ctx, "actions/checkout", 1, "Removed — GitLab clones the repository automatically", "skipped")],
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
// actions/setup-node: image: node:<version>
|
|
53
|
+
const actionsSetupNode = {
|
|
54
|
+
actionName: "actions/setup-node",
|
|
55
|
+
tier: 1,
|
|
56
|
+
translate(step, ctx) {
|
|
57
|
+
const w = getWith(step);
|
|
58
|
+
const version = w["node-version"] ?? "22";
|
|
59
|
+
const cache = w.cache;
|
|
60
|
+
const cacheKey = cache === "npm"
|
|
61
|
+
? { key: { files: ["package-lock.json"] }, paths: [".npm/"] }
|
|
62
|
+
: cache === "yarn"
|
|
63
|
+
? { key: { files: ["yarn.lock"] }, paths: [".yarn/cache/"] }
|
|
64
|
+
: cache === "pnpm"
|
|
65
|
+
? { key: { files: ["pnpm-lock.yaml"] }, paths: [".pnpm-store/"] }
|
|
66
|
+
: undefined;
|
|
67
|
+
return {
|
|
68
|
+
scriptLines: [],
|
|
69
|
+
image: `node:${version}`,
|
|
70
|
+
cache: cacheKey,
|
|
71
|
+
provenance: [prov(ctx, "actions/setup-node", 1, `setup-node → image: node:${version}`)],
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
const actionsSetupPython = {
|
|
76
|
+
actionName: "actions/setup-python",
|
|
77
|
+
tier: 1,
|
|
78
|
+
translate(step, ctx) {
|
|
79
|
+
const w = getWith(step);
|
|
80
|
+
const version = w["python-version"] ?? "3.12";
|
|
81
|
+
const cache = w.cache;
|
|
82
|
+
const cacheKey = cache === "pip"
|
|
83
|
+
? { paths: [".cache/pip/"] }
|
|
84
|
+
: cache === "poetry"
|
|
85
|
+
? { paths: [".cache/pypoetry/"] }
|
|
86
|
+
: undefined;
|
|
87
|
+
return {
|
|
88
|
+
scriptLines: [],
|
|
89
|
+
image: `python:${version}`,
|
|
90
|
+
cache: cacheKey,
|
|
91
|
+
provenance: [prov(ctx, "actions/setup-python", 1, `setup-python → image: python:${version}`)],
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
const actionsSetupJava = {
|
|
96
|
+
actionName: "actions/setup-java",
|
|
97
|
+
tier: 1,
|
|
98
|
+
translate(step, ctx) {
|
|
99
|
+
const w = getWith(step);
|
|
100
|
+
const version = w["java-version"] ?? "17";
|
|
101
|
+
const cache = w.cache;
|
|
102
|
+
const cacheKey = cache === "maven"
|
|
103
|
+
? { paths: [".m2/repository/"] }
|
|
104
|
+
: cache === "gradle"
|
|
105
|
+
? { paths: [".gradle/"] }
|
|
106
|
+
: undefined;
|
|
107
|
+
return {
|
|
108
|
+
scriptLines: [],
|
|
109
|
+
image: `eclipse-temurin:${version}`,
|
|
110
|
+
cache: cacheKey,
|
|
111
|
+
provenance: [prov(ctx, "actions/setup-java", 1, `setup-java → image: eclipse-temurin:${version}`)],
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
const actionsSetupGo = {
|
|
116
|
+
actionName: "actions/setup-go",
|
|
117
|
+
tier: 1,
|
|
118
|
+
translate(step, ctx) {
|
|
119
|
+
const w = getWith(step);
|
|
120
|
+
const version = w["go-version"] ?? "1.22";
|
|
121
|
+
return {
|
|
122
|
+
scriptLines: [],
|
|
123
|
+
image: `golang:${version}`,
|
|
124
|
+
cache: w.cache === true || w.cache === "true"
|
|
125
|
+
? { paths: [".cache/go-build/", "go/pkg/mod/"] }
|
|
126
|
+
: undefined,
|
|
127
|
+
provenance: [prov(ctx, "actions/setup-go", 1, `setup-go → image: golang:${version}`)],
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
const actionsSetupRuby = {
|
|
132
|
+
actionName: "actions/setup-ruby",
|
|
133
|
+
tier: 1,
|
|
134
|
+
translate(step, ctx) {
|
|
135
|
+
const w = getWith(step);
|
|
136
|
+
const version = w["ruby-version"] ?? "3.3";
|
|
137
|
+
return {
|
|
138
|
+
scriptLines: [],
|
|
139
|
+
image: `ruby:${version}`,
|
|
140
|
+
cache: w["bundler-cache"] === true || w["bundler-cache"] === "true"
|
|
141
|
+
? { paths: ["vendor/bundle/"] }
|
|
142
|
+
: undefined,
|
|
143
|
+
provenance: [prov(ctx, "actions/setup-ruby", 1, `setup-ruby → image: ruby:${version}`)],
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
const actionsCache = {
|
|
148
|
+
actionName: "actions/cache",
|
|
149
|
+
tier: 1,
|
|
150
|
+
translate(step, ctx) {
|
|
151
|
+
const w = getWith(step);
|
|
152
|
+
const paths = w.path?.split("\n").map((p) => p.trim()).filter(Boolean) ?? [];
|
|
153
|
+
const key = w.key;
|
|
154
|
+
const cache = {};
|
|
155
|
+
if (paths.length > 0)
|
|
156
|
+
cache.paths = paths;
|
|
157
|
+
if (key)
|
|
158
|
+
cache.key = key;
|
|
159
|
+
return {
|
|
160
|
+
scriptLines: [],
|
|
161
|
+
cache: Object.keys(cache).length > 0 ? cache : undefined,
|
|
162
|
+
provenance: [prov(ctx, "actions/cache", 1, "actions/cache → native cache: keyword")],
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
const actionsUploadArtifact = {
|
|
167
|
+
actionName: "actions/upload-artifact",
|
|
168
|
+
tier: 1,
|
|
169
|
+
translate(step, ctx) {
|
|
170
|
+
const w = getWith(step);
|
|
171
|
+
const paths = w.path?.split("\n").map((p) => p.trim()).filter(Boolean) ?? [];
|
|
172
|
+
const name = w.name;
|
|
173
|
+
const retention = w["retention-days"];
|
|
174
|
+
const artifacts = {};
|
|
175
|
+
if (paths.length > 0)
|
|
176
|
+
artifacts.paths = paths;
|
|
177
|
+
if (name)
|
|
178
|
+
artifacts.name = name;
|
|
179
|
+
if (retention !== undefined)
|
|
180
|
+
artifacts.expire_in = `${retention} days`;
|
|
181
|
+
return {
|
|
182
|
+
scriptLines: [],
|
|
183
|
+
artifacts: Object.keys(artifacts).length > 0 ? artifacts : undefined,
|
|
184
|
+
provenance: [prov(ctx, "actions/upload-artifact", 1, "upload-artifact → native artifacts: keyword")],
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
const actionsDownloadArtifact = {
|
|
189
|
+
actionName: "actions/download-artifact",
|
|
190
|
+
tier: 1,
|
|
191
|
+
translate(_step, ctx) {
|
|
192
|
+
return {
|
|
193
|
+
scriptLines: [],
|
|
194
|
+
provenance: [prov(ctx, "actions/download-artifact", 1, "download-artifact removed — GitLab auto-passes artifacts via stages or needs:artifacts:")],
|
|
195
|
+
};
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
const dockerLoginAction = {
|
|
199
|
+
actionName: "docker/login-action",
|
|
200
|
+
tier: 1,
|
|
201
|
+
translate(step, ctx) {
|
|
202
|
+
const w = getWith(step);
|
|
203
|
+
const registry = w.registry ?? "";
|
|
204
|
+
const userVar = withVal(w, "username") ?? "$CI_REGISTRY_USER";
|
|
205
|
+
const passVar = withVal(w, "password") ?? "$CI_REGISTRY_PASSWORD";
|
|
206
|
+
return {
|
|
207
|
+
scriptLines: [`docker login -u ${userVar} -p ${passVar} ${registry}`.trim()],
|
|
208
|
+
provenance: [prov(ctx, "docker/login-action", 1, "docker/login-action → inline docker login")],
|
|
209
|
+
};
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
const dockerBuildPushAction = {
|
|
213
|
+
actionName: "docker/build-push-action",
|
|
214
|
+
tier: 1,
|
|
215
|
+
translate(step, ctx) {
|
|
216
|
+
const w = getWith(step);
|
|
217
|
+
const context = w.context ?? ".";
|
|
218
|
+
const file = w.file ?? "Dockerfile";
|
|
219
|
+
const push = w.push === true || w.push === "true";
|
|
220
|
+
const tags = w.tags?.split(/[\n,]/).map((t) => t.trim()).filter(Boolean) ?? [];
|
|
221
|
+
const lines = [];
|
|
222
|
+
const tagFlags = tags.map((t) => `-t ${t}`).join(" ");
|
|
223
|
+
lines.push(`docker build -f ${file} ${tagFlags} ${context}`.trim());
|
|
224
|
+
if (push) {
|
|
225
|
+
for (const t of tags)
|
|
226
|
+
lines.push(`docker push ${t}`);
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
scriptLines: lines,
|
|
230
|
+
image: "docker:latest",
|
|
231
|
+
services: [{ name: "docker:dind", alias: "docker", variables: { DOCKER_TLS_CERTDIR: "/certs" } }],
|
|
232
|
+
provenance: [prov(ctx, "docker/build-push-action", 1, "docker/build-push-action → inline docker build/push + docker:dind service")],
|
|
233
|
+
};
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
const dockerSetupBuildxAction = {
|
|
237
|
+
actionName: "docker/setup-buildx-action",
|
|
238
|
+
tier: 1,
|
|
239
|
+
translate(_step, ctx) {
|
|
240
|
+
return {
|
|
241
|
+
scriptLines: ["docker buildx create --use"],
|
|
242
|
+
image: "docker:latest",
|
|
243
|
+
services: [{ name: "docker:dind", alias: "docker", variables: { DOCKER_TLS_CERTDIR: "/certs" } }],
|
|
244
|
+
provenance: [prov(ctx, "docker/setup-buildx-action", 1, "docker/setup-buildx-action → docker buildx create --use + docker:dind")],
|
|
245
|
+
};
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
const dockerSetupQemuAction = {
|
|
249
|
+
actionName: "docker/setup-qemu-action",
|
|
250
|
+
tier: 1,
|
|
251
|
+
translate(step, ctx) {
|
|
252
|
+
const w = getWith(step);
|
|
253
|
+
const platforms = w.platforms ?? "linux/amd64,linux/arm64";
|
|
254
|
+
return {
|
|
255
|
+
scriptLines: [`docker run --rm --privileged tonistiigi/binfmt --install ${platforms}`],
|
|
256
|
+
provenance: [prov(ctx, "docker/setup-qemu-action", 1, "docker/setup-qemu-action → tonistiigi/binfmt")],
|
|
257
|
+
};
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
const actionsGithubScript = {
|
|
261
|
+
actionName: "actions/github-script",
|
|
262
|
+
tier: 1,
|
|
263
|
+
translate(_step, ctx) {
|
|
264
|
+
return {
|
|
265
|
+
scriptLines: [
|
|
266
|
+
"# TODO(migration): actions/github-script has no direct GitLab equivalent.",
|
|
267
|
+
"# Replace with glab CLI or curl against the GitLab API.",
|
|
268
|
+
],
|
|
269
|
+
provenance: [prov(ctx, "actions/github-script", 1, "actions/github-script: use glab CLI or REST API", "needs-review")],
|
|
270
|
+
};
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
const TIER_1_MAPPINGS = [
|
|
274
|
+
actionsCheckout,
|
|
275
|
+
actionsSetupNode,
|
|
276
|
+
actionsSetupPython,
|
|
277
|
+
actionsSetupJava,
|
|
278
|
+
actionsSetupGo,
|
|
279
|
+
actionsSetupRuby,
|
|
280
|
+
actionsCache,
|
|
281
|
+
actionsUploadArtifact,
|
|
282
|
+
actionsDownloadArtifact,
|
|
283
|
+
dockerLoginAction,
|
|
284
|
+
dockerBuildPushAction,
|
|
285
|
+
dockerSetupBuildxAction,
|
|
286
|
+
dockerSetupQemuAction,
|
|
287
|
+
actionsGithubScript,
|
|
288
|
+
];
|
|
289
|
+
/**
|
|
290
|
+
* Register all Tier 1 mappings into the given registry (or default).
|
|
291
|
+
* Idempotent — call before `lookupAction` is first invoked.
|
|
292
|
+
*/
|
|
293
|
+
export function registerTier1(registry = getDefaultRegistry()) {
|
|
294
|
+
for (const m of TIER_1_MAPPINGS) {
|
|
295
|
+
registry.register(m);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
export { TIER_1_MAPPINGS };
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tier 2 marketplace action mappings — 14 common actions from the
|
|
3
|
+
* upstream skill's `references/marketplace-actions.md`.
|
|
4
|
+
*/
|
|
5
|
+
import { getDefaultRegistry } from "./registry.js";
|
|
6
|
+
const prov = (ctx, actionName, note, category = "action-map") => ({
|
|
7
|
+
gitlabPath: `jobs.${ctx.logicalId}.script`,
|
|
8
|
+
gitlabLogicalId: ctx.logicalId,
|
|
9
|
+
sourceKey: `jobs.${ctx.jobName}.steps[${ctx.stepIndex}].uses`,
|
|
10
|
+
sourceFile: ctx.sourceFile,
|
|
11
|
+
category,
|
|
12
|
+
rule: `ACT-${actionName.replace(/[\/-]/g, "-")}`,
|
|
13
|
+
note,
|
|
14
|
+
actionRef: actionName,
|
|
15
|
+
mappingTier: 2,
|
|
16
|
+
});
|
|
17
|
+
const getWith = (s) => s.with ?? {};
|
|
18
|
+
const actionsSetupDotnet = {
|
|
19
|
+
actionName: "actions/setup-dotnet",
|
|
20
|
+
tier: 2,
|
|
21
|
+
translate(step, ctx) {
|
|
22
|
+
const w = getWith(step);
|
|
23
|
+
const version = w["dotnet-version"] ?? "8.0";
|
|
24
|
+
return {
|
|
25
|
+
scriptLines: [],
|
|
26
|
+
image: `mcr.microsoft.com/dotnet/sdk:${version}`,
|
|
27
|
+
cache: { paths: [".nuget/packages/"] },
|
|
28
|
+
provenance: [prov(ctx, "actions/setup-dotnet", `setup-dotnet → image: mcr.microsoft.com/dotnet/sdk:${version}`)],
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
const shivammathurSetupPhp = {
|
|
33
|
+
actionName: "shivammathur/setup-php",
|
|
34
|
+
tier: 2,
|
|
35
|
+
translate(step, ctx) {
|
|
36
|
+
const w = getWith(step);
|
|
37
|
+
const version = w["php-version"] ?? "8.3";
|
|
38
|
+
const extensions = w.extensions ?? "";
|
|
39
|
+
const lines = ["apt-get update"];
|
|
40
|
+
if (extensions)
|
|
41
|
+
lines.push(`docker-php-ext-install ${extensions.split(",").map((s) => s.trim()).join(" ")}`);
|
|
42
|
+
return {
|
|
43
|
+
scriptLines: [],
|
|
44
|
+
image: `php:${version}`,
|
|
45
|
+
beforeScript: lines,
|
|
46
|
+
provenance: [prov(ctx, "shivammathur/setup-php", `setup-php → image: php:${version} + before_script extensions`)],
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
const awsConfigureCredentials = {
|
|
51
|
+
actionName: "aws-actions/configure-aws-credentials",
|
|
52
|
+
tier: 2,
|
|
53
|
+
translate(step, ctx) {
|
|
54
|
+
const w = getWith(step);
|
|
55
|
+
const region = w["aws-region"] ?? "us-east-1";
|
|
56
|
+
return {
|
|
57
|
+
scriptLines: [],
|
|
58
|
+
variables: {
|
|
59
|
+
AWS_DEFAULT_REGION: region,
|
|
60
|
+
},
|
|
61
|
+
provenance: [prov(ctx, "aws-actions/configure-aws-credentials", "Configure AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY as masked CI/CD variables, or use GitLab OIDC to AWS", "needs-review")],
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
const googleAuthAction = {
|
|
66
|
+
actionName: "google-github-actions/auth",
|
|
67
|
+
tier: 2,
|
|
68
|
+
translate(_step, ctx) {
|
|
69
|
+
return {
|
|
70
|
+
scriptLines: [
|
|
71
|
+
"echo $GCP_SA_KEY | base64 -d > /tmp/gcp-key.json",
|
|
72
|
+
"gcloud auth activate-service-account --key-file=/tmp/gcp-key.json",
|
|
73
|
+
],
|
|
74
|
+
variables: { GOOGLE_APPLICATION_CREDENTIALS: "/tmp/gcp-key.json" },
|
|
75
|
+
provenance: [prov(ctx, "google-github-actions/auth", "Set GCP_SA_KEY as masked CI/CD variable (base64-encoded), or use GitLab OIDC to GCP", "needs-review")],
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const azureLogin = {
|
|
80
|
+
actionName: "azure/login",
|
|
81
|
+
tier: 2,
|
|
82
|
+
translate(_step, ctx) {
|
|
83
|
+
return {
|
|
84
|
+
scriptLines: ["az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_CLIENT_SECRET --tenant $AZURE_TENANT_ID"],
|
|
85
|
+
provenance: [prov(ctx, "azure/login", "Set AZURE_CLIENT_ID/SECRET/TENANT_ID as masked CI/CD variables, or use GitLab OIDC to Azure", "needs-review")],
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
const hashicorpSetupTerraform = {
|
|
90
|
+
actionName: "hashicorp/setup-terraform",
|
|
91
|
+
tier: 2,
|
|
92
|
+
translate(step, ctx) {
|
|
93
|
+
const w = getWith(step);
|
|
94
|
+
const version = w.terraform_version ?? "1.6";
|
|
95
|
+
return {
|
|
96
|
+
scriptLines: [],
|
|
97
|
+
image: `hashicorp/terraform:${version}`,
|
|
98
|
+
provenance: [prov(ctx, "hashicorp/setup-terraform", `setup-terraform → image: hashicorp/terraform:${version} (or use GitLab Terraform template)`)],
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
const codecovAction = {
|
|
103
|
+
actionName: "codecov/codecov-action",
|
|
104
|
+
tier: 2,
|
|
105
|
+
translate(step, ctx) {
|
|
106
|
+
const w = getWith(step);
|
|
107
|
+
const file = w.files ?? w.file ?? "coverage.xml";
|
|
108
|
+
return {
|
|
109
|
+
scriptLines: [
|
|
110
|
+
"pip install codecov-cli",
|
|
111
|
+
`codecovcli upload-process --file ${file} --token $CODECOV_TOKEN`,
|
|
112
|
+
],
|
|
113
|
+
provenance: [prov(ctx, "codecov/codecov-action", "codecov-action → codecov-cli; set CODECOV_TOKEN as masked variable")],
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
const softpropsGhRelease = {
|
|
118
|
+
actionName: "softprops/action-gh-release",
|
|
119
|
+
tier: 2,
|
|
120
|
+
translate(_step, ctx) {
|
|
121
|
+
return {
|
|
122
|
+
scriptLines: ["glab release create $CI_COMMIT_TAG"],
|
|
123
|
+
provenance: [prov(ctx, "softprops/action-gh-release", "softprops/action-gh-release → glab release create (for GitLab) or curl GitHub API", "needs-review")],
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
const peterEvansCreatePr = {
|
|
128
|
+
actionName: "peter-evans/create-pull-request",
|
|
129
|
+
tier: 2,
|
|
130
|
+
translate(step, ctx) {
|
|
131
|
+
const w = getWith(step);
|
|
132
|
+
const title = w.title ?? "Automated update";
|
|
133
|
+
return {
|
|
134
|
+
scriptLines: [
|
|
135
|
+
"git config user.email \"ci@example.com\"",
|
|
136
|
+
"git config user.name \"CI Bot\"",
|
|
137
|
+
"git add .",
|
|
138
|
+
`git commit -m "${title}"`,
|
|
139
|
+
`glab mr create --title "${title}"`,
|
|
140
|
+
],
|
|
141
|
+
provenance: [prov(ctx, "peter-evans/create-pull-request", "create-pull-request → glab mr create", "needs-review")],
|
|
142
|
+
};
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
const jamesIvesPagesDeploy = {
|
|
146
|
+
actionName: "JamesIves/github-pages-deploy-action",
|
|
147
|
+
tier: 2,
|
|
148
|
+
translate(step, ctx) {
|
|
149
|
+
const w = getWith(step);
|
|
150
|
+
const folder = w.folder ?? "build";
|
|
151
|
+
return {
|
|
152
|
+
scriptLines: [
|
|
153
|
+
"mkdir -p public",
|
|
154
|
+
`cp -r ${folder}/* public/`,
|
|
155
|
+
],
|
|
156
|
+
artifacts: { paths: ["public"] },
|
|
157
|
+
provenance: [prov(ctx, "JamesIves/github-pages-deploy-action", "pages-deploy → GitLab Pages requires job name 'pages' and artifacts in public/. May need a separate `pages:` job.", "needs-review")],
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
const pnpmActionSetup = {
|
|
162
|
+
actionName: "pnpm/action-setup",
|
|
163
|
+
tier: 2,
|
|
164
|
+
translate(step, ctx) {
|
|
165
|
+
const w = getWith(step);
|
|
166
|
+
const version = w.version ?? "9";
|
|
167
|
+
return {
|
|
168
|
+
scriptLines: [`npm install -g pnpm@${version}`],
|
|
169
|
+
cache: { paths: [".pnpm-store/"] },
|
|
170
|
+
provenance: [prov(ctx, "pnpm/action-setup", `pnpm/action-setup → npm install -g pnpm@${version}`)],
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
const ovenSetupBun = {
|
|
175
|
+
actionName: "oven-sh/setup-bun",
|
|
176
|
+
tier: 2,
|
|
177
|
+
translate(step, ctx) {
|
|
178
|
+
const w = getWith(step);
|
|
179
|
+
const version = w["bun-version"] ?? "latest";
|
|
180
|
+
return {
|
|
181
|
+
scriptLines: [],
|
|
182
|
+
image: `oven/bun:${version}`,
|
|
183
|
+
cache: { paths: [".bun/install/cache/"] },
|
|
184
|
+
provenance: [prov(ctx, "oven-sh/setup-bun", `setup-bun → image: oven/bun:${version}`)],
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
const gradleBuildAction = {
|
|
189
|
+
actionName: "gradle/gradle-build-action",
|
|
190
|
+
tier: 2,
|
|
191
|
+
translate(step, ctx) {
|
|
192
|
+
const w = getWith(step);
|
|
193
|
+
const version = w["gradle-version"] ?? "8";
|
|
194
|
+
return {
|
|
195
|
+
scriptLines: [],
|
|
196
|
+
image: `gradle:${version}`,
|
|
197
|
+
cache: { paths: [".gradle/"] },
|
|
198
|
+
provenance: [prov(ctx, "gradle/gradle-build-action", `gradle-build-action → image: gradle:${version}`)],
|
|
199
|
+
};
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
const cypressAction = {
|
|
203
|
+
actionName: "cypress-io/github-action",
|
|
204
|
+
tier: 2,
|
|
205
|
+
translate(step, ctx) {
|
|
206
|
+
const w = getWith(step);
|
|
207
|
+
const browser = w.browser ?? "chrome";
|
|
208
|
+
const start = w.start;
|
|
209
|
+
const lines = ["npm install"];
|
|
210
|
+
if (start)
|
|
211
|
+
lines.push(`${start} &`);
|
|
212
|
+
lines.push(`npx cypress run --browser ${browser}`);
|
|
213
|
+
return {
|
|
214
|
+
scriptLines: lines,
|
|
215
|
+
image: "cypress/browsers:latest",
|
|
216
|
+
provenance: [prov(ctx, "cypress-io/github-action", `cypress-io → cypress/browsers image + npx cypress run`)],
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
const TIER_2_MAPPINGS = [
|
|
221
|
+
actionsSetupDotnet,
|
|
222
|
+
shivammathurSetupPhp,
|
|
223
|
+
awsConfigureCredentials,
|
|
224
|
+
googleAuthAction,
|
|
225
|
+
azureLogin,
|
|
226
|
+
hashicorpSetupTerraform,
|
|
227
|
+
codecovAction,
|
|
228
|
+
softpropsGhRelease,
|
|
229
|
+
peterEvansCreatePr,
|
|
230
|
+
jamesIvesPagesDeploy,
|
|
231
|
+
pnpmActionSetup,
|
|
232
|
+
ovenSetupBun,
|
|
233
|
+
gradleBuildAction,
|
|
234
|
+
cypressAction,
|
|
235
|
+
];
|
|
236
|
+
export function registerTier2(registry = getDefaultRegistry()) {
|
|
237
|
+
for (const m of TIER_2_MAPPINGS) {
|
|
238
|
+
registry.register(m);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
export { TIER_2_MAPPINGS };
|