@catladder/cli 0.0.0-next-e7541a00 → 0.0.0-next-4e7c6848

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 (45) hide show
  1. package/dist/bundles/catenv/index.js +626 -15
  2. package/dist/bundles/cli/index.js +628 -16
  3. package/dist/cli/src/apps/catenv/catenv.js +1 -2
  4. package/dist/cli/src/apps/catenv/catenv.js.map +1 -1
  5. package/dist/pipeline/src/backends/github/GithubBackend.d.ts +12 -0
  6. package/dist/pipeline/src/backends/github/GithubBackend.js +170 -0
  7. package/dist/pipeline/src/backends/github/GithubBackend.js.map +1 -0
  8. package/dist/pipeline/src/backends/github/ciVariables.d.ts +14 -0
  9. package/dist/pipeline/src/backends/github/ciVariables.js +31 -0
  10. package/dist/pipeline/src/backends/github/ciVariables.js.map +1 -0
  11. package/dist/pipeline/src/backends/github/createGithubJobs.d.ts +17 -0
  12. package/dist/pipeline/src/backends/github/createGithubJobs.js +208 -0
  13. package/dist/pipeline/src/backends/github/createGithubJobs.js.map +1 -0
  14. package/dist/pipeline/src/backends/github/githubReleaseJobs.d.ts +15 -0
  15. package/dist/pipeline/src/backends/github/githubReleaseJobs.js +65 -0
  16. package/dist/pipeline/src/backends/github/githubReleaseJobs.js.map +1 -0
  17. package/dist/pipeline/src/backends/github/index.d.ts +2 -0
  18. package/dist/pipeline/src/backends/github/index.js +26 -0
  19. package/dist/pipeline/src/backends/github/index.js.map +1 -0
  20. package/dist/pipeline/src/backends/github/scriptFunctions.d.ts +6 -0
  21. package/dist/pipeline/src/backends/github/scriptFunctions.js +30 -0
  22. package/dist/pipeline/src/backends/github/scriptFunctions.js.map +1 -0
  23. package/dist/pipeline/src/backends/gitlab/GitlabBackend.d.ts +1 -0
  24. package/dist/pipeline/src/backends/gitlab/GitlabBackend.js +7 -0
  25. package/dist/pipeline/src/backends/gitlab/GitlabBackend.js.map +1 -1
  26. package/dist/pipeline/src/backends/index.d.ts +8 -2
  27. package/dist/pipeline/src/backends/index.js +25 -3
  28. package/dist/pipeline/src/backends/index.js.map +1 -1
  29. package/dist/pipeline/src/backends/types.d.ts +7 -3
  30. package/dist/pipeline/src/bash/ciVariables.js +4 -2
  31. package/dist/pipeline/src/bash/ciVariables.js.map +1 -1
  32. package/dist/pipeline/src/constants.js +1 -1
  33. package/dist/pipeline/src/context/getReviewSlug.js +3 -1
  34. package/dist/pipeline/src/context/getReviewSlug.js.map +1 -1
  35. package/dist/pipeline/src/pipeline/generatePipelineFiles.d.ts +6 -1
  36. package/dist/pipeline/src/pipeline/generatePipelineFiles.js +14 -7
  37. package/dist/pipeline/src/pipeline/generatePipelineFiles.js.map +1 -1
  38. package/dist/pipeline/src/types/config.d.ts +20 -0
  39. package/dist/pipeline/src/types/github-types.d.ts +47 -0
  40. package/dist/pipeline/src/types/github-types.js +9 -0
  41. package/dist/pipeline/src/types/github-types.js.map +1 -0
  42. package/dist/pipeline/src/types/pipeline.d.ts +4 -3
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +1 -1
  45. package/src/apps/catenv/catenv.ts +1 -1
@@ -5845,6 +5845,578 @@ exports.getShell = getShell;
5845
5845
 
5846
5846
  /***/ }),
5847
5847
 
5848
+ /***/ 54038:
5849
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
5850
+
5851
+ "use strict";
5852
+
5853
+
5854
+ Object.defineProperty(exports, "__esModule", ({
5855
+ value: true
5856
+ }));
5857
+ exports.GithubBackend = void 0;
5858
+ const promises_1 = __nccwpck_require__(91943);
5859
+ const path_1 = __nccwpck_require__(16928);
5860
+ const createAllJobs_1 = __nccwpck_require__(83671);
5861
+ const config_1 = __nccwpck_require__(96925);
5862
+ const ciVariables_1 = __nccwpck_require__(25474);
5863
+ const createGithubJobs_1 = __nccwpck_require__(14016);
5864
+ const githubReleaseJobs_1 = __nccwpck_require__(55611);
5865
+ const WORKFLOWS_FOLDER = ".github/workflows";
5866
+ /**
5867
+ * generated workflow files are prefixed so that cleanup never touches
5868
+ * user-maintained workflows in the same folder
5869
+ */
5870
+ const GENERATED_FILE_PREFIX = "catladder-";
5871
+ const TRIGGER_WORKFLOWS = {
5872
+ mr: {
5873
+ name: "catladder review",
5874
+ on: {
5875
+ pull_request: {
5876
+ types: ["opened", "synchronize", "reopened"]
5877
+ }
5878
+ },
5879
+ concurrency: {
5880
+ group: "catladder-review-${{ github.event.number }}",
5881
+ "cancel-in-progress": true
5882
+ }
5883
+ },
5884
+ mainBranch: {
5885
+ name: "catladder main",
5886
+ // TODO: make the default branch configurable
5887
+ on: {
5888
+ push: {
5889
+ branches: ["main"]
5890
+ }
5891
+ }
5892
+ },
5893
+ taggedRelease: {
5894
+ name: "catladder release",
5895
+ on: {
5896
+ push: {
5897
+ tags: ["v*"]
5898
+ }
5899
+ }
5900
+ }
5901
+ };
5902
+ class GithubBackend {
5903
+ constructor() {
5904
+ this.type = "github";
5905
+ }
5906
+ async cleanup() {
5907
+ const entries = await (0, promises_1.readdir)(WORKFLOWS_FOLDER).catch(() => []);
5908
+ await Promise.all(entries.filter(file => file.startsWith(GENERATED_FILE_PREFIX)).map(file => (0, promises_1.unlink)((0, path_1.join)(WORKFLOWS_FOLDER, file))));
5909
+ }
5910
+ async createFiles(config) {
5911
+ const workflows = await this.createWorkflows(config);
5912
+ return Object.entries(workflows).map(([fileName, workflow]) => ({
5913
+ path: (0, path_1.join)(WORKFLOWS_FOLDER, fileName),
5914
+ content: workflow
5915
+ }));
5916
+ }
5917
+ /**
5918
+ * all workflows keyed by file name, mainly for testing purposes
5919
+ */
5920
+ async createWorkflows(config) {
5921
+ const workflows = {};
5922
+ const reviewStopJobs = {};
5923
+ const manualJobs = {};
5924
+ for (const trigger of config_1.ALL_PIPELINE_TRIGGERS) {
5925
+ const allJobs = await (0, createAllJobs_1.createAllJobs)({
5926
+ config,
5927
+ trigger,
5928
+ pipelineType: this.type
5929
+ });
5930
+ const uploadProviderIds = (0, createGithubJobs_1.getUploadProviderIds)(allJobs);
5931
+ const jobs = {};
5932
+ // NOTE: agent jobs are gitlab-only and skipped on github
5933
+ [...allJobs.workspaces, ...allJobs.components].forEach(({
5934
+ context,
5935
+ jobs: contextJobs
5936
+ }) => contextJobs.forEach(job => {
5937
+ const [id, githubJob] = (0, createGithubJobs_1.makeGithubJob)(context, job, allJobs, uploadProviderIds);
5938
+ if (isReviewStopJob(context, job)) {
5939
+ reviewStopJobs[id] = githubJob;
5940
+ } else if (isManualTaskJob(job)) {
5941
+ manualJobs[id] = githubJob;
5942
+ } else {
5943
+ jobs[id] = githubJob;
5944
+ }
5945
+ }));
5946
+ if (trigger === "mainBranch") {
5947
+ const releaseJobs = (0, githubReleaseJobs_1.getGithubReleaseJobs)(config, Object.keys(jobs));
5948
+ Object.assign(jobs, releaseJobs.main);
5949
+ Object.assign(manualJobs, releaseJobs.manual);
5950
+ }
5951
+ if (Object.keys(jobs).length > 0) {
5952
+ workflows[`${GENERATED_FILE_PREFIX}${workflowFileName(trigger)}`] = {
5953
+ ...TRIGGER_WORKFLOWS[trigger],
5954
+ env: ciVariables_1.GITHUB_INJECTED_WORKFLOW_ENV,
5955
+ jobs
5956
+ };
5957
+ }
5958
+ }
5959
+ if (Object.keys(reviewStopJobs).length > 0) {
5960
+ workflows[`${GENERATED_FILE_PREFIX}review-stop.yml`] = {
5961
+ name: "catladder review stop",
5962
+ on: {
5963
+ pull_request: {
5964
+ types: ["closed"]
5965
+ }
5966
+ },
5967
+ env: ciVariables_1.GITHUB_INJECTED_WORKFLOW_ENV,
5968
+ jobs: reviewStopJobs
5969
+ };
5970
+ }
5971
+ if (Object.keys(manualJobs).length > 0) {
5972
+ workflows[`${GENERATED_FILE_PREFIX}manual.yml`] = {
5973
+ name: "catladder manual tasks",
5974
+ on: {
5975
+ workflow_dispatch: {
5976
+ inputs: {
5977
+ job: {
5978
+ description: "the task to run",
5979
+ required: true,
5980
+ type: "choice",
5981
+ options: Object.keys(manualJobs)
5982
+ }
5983
+ }
5984
+ }
5985
+ },
5986
+ env: ciVariables_1.GITHUB_INJECTED_WORKFLOW_ENV,
5987
+ jobs: Object.fromEntries(Object.entries(manualJobs).map(([id, job]) => [id, {
5988
+ ...job,
5989
+ if: `\${{ inputs.job == '${id}' }}`
5990
+ }]))
5991
+ };
5992
+ }
5993
+ return workflows;
5994
+ }
5995
+ }
5996
+ exports.GithubBackend = GithubBackend;
5997
+ const workflowFileName = trigger => {
5998
+ switch (trigger) {
5999
+ case "mr":
6000
+ return "review.yml";
6001
+ case "mainBranch":
6002
+ return "main.yml";
6003
+ case "taggedRelease":
6004
+ return "release.yml";
6005
+ }
6006
+ throw new Error(`${trigger} is not supported`);
6007
+ };
6008
+ /**
6009
+ * stop jobs of review environments run in their own workflow when the
6010
+ * pull request is closed (the counterpart of gitlab's on_stop wiring)
6011
+ */
6012
+ const isReviewStopJob = (context, job) => {
6013
+ var _a;
6014
+ return ((_a = job.environment) === null || _a === void 0 ? void 0 : _a.action) === "stop" && context.type === "component" && context.environment.envType === "review";
6015
+ };
6016
+ /**
6017
+ * stop/rollback jobs of non-review environments have no automatic
6018
+ * trigger; they are collected in a workflow_dispatch workflow
6019
+ * (gitlab runs them as manual jobs inside the pipeline)
6020
+ */
6021
+ const isManualTaskJob = job => job.stage === "stop" || job.stage === "rollback";
6022
+
6023
+ /***/ }),
6024
+
6025
+ /***/ 25474:
6026
+ /***/ ((__unused_webpack_module, exports) => {
6027
+
6028
+ "use strict";
6029
+
6030
+
6031
+ Object.defineProperty(exports, "__esModule", ({
6032
+ value: true
6033
+ }));
6034
+ exports.GITHUB_INJECTED_WORKFLOW_ENV = exports.GITHUB_CI_VARIABLES = void 0;
6035
+ /**
6036
+ * how the github backend names the predefined CI variables.
6037
+ *
6038
+ * GITHUB_* variables are provided by github actions natively; the CL_*
6039
+ * variables are injected by the {@link GithubBackend} itself (workflow or
6040
+ * job level), because github has no direct counterpart.
6041
+ */
6042
+ exports.GITHUB_CI_VARIABLES = {
6043
+ commitSha: "GITHUB_SHA",
6044
+ jobToken: "CL_JOB_TOKEN",
6045
+ jobImage: "CL_JOB_IMAGE",
6046
+ registry: "CL_REGISTRY",
6047
+ registryImage: "CL_REGISTRY_IMAGE"
6048
+ };
6049
+ /**
6050
+ * the workflow-level env the backend injects to provide the CL_*
6051
+ * variables referenced by {@link GITHUB_CI_VARIABLES}
6052
+ */
6053
+ exports.GITHUB_INJECTED_WORKFLOW_ENV = {
6054
+ CL_JOB_TOKEN: "${{ github.token }}",
6055
+ CL_REGISTRY: "ghcr.io",
6056
+ CL_REGISTRY_IMAGE: "ghcr.io/${{ github.repository }}",
6057
+ // empty outside of pull request events
6058
+ CL_PR_NUMBER: "${{ github.event.number }}"
6059
+ };
6060
+
6061
+ /***/ }),
6062
+
6063
+ /***/ 14016:
6064
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
6065
+
6066
+ "use strict";
6067
+
6068
+
6069
+ Object.defineProperty(exports, "__esModule", ({
6070
+ value: true
6071
+ }));
6072
+ exports.getUploadProviderIds = exports.makeGithubJob = exports.resolveGithubNeeds = exports.githubJobId = void 0;
6073
+ const lodash_es_1 = __nccwpck_require__(64284);
6074
+ const getInjectVarsScript_1 = __nccwpck_require__(90436);
6075
+ const createJobCache_1 = __nccwpck_require__(65644);
6076
+ const getEnvironmentVariables_1 = __nccwpck_require__(85855);
6077
+ const utils_1 = __nccwpck_require__(20595);
6078
+ const gitlab_1 = __nccwpck_require__(13468);
6079
+ const scriptFunctions_1 = __nccwpck_require__(75759);
6080
+ /**
6081
+ * runner variables that only make sense on gitlab runners and must not
6082
+ * leak into github jobs (docker-in-docker daemon config, kubernetes
6083
+ * executor resource requests, gitlab clone strategy)
6084
+ */
6085
+ const GITLAB_ONLY_RUNNER_VARIABLES = new Set(["DOCKER_HOST", "DOCKER_TLS_CERTDIR", "DOCKER_DRIVER", "KUBERNETES_CPU_REQUEST", "KUBERNETES_MEMORY_REQUEST", "KUBERNETES_CPU_LIMIT", "KUBERNETES_MEMORY_LIMIT", "GIT_STRATEGY"]);
6086
+ /**
6087
+ * github runs docker natively on its runners, gitlab needs a
6088
+ * docker-in-docker service for it
6089
+ */
6090
+ const isDindService = image => /(^|\/)docker:.*dind/.test(image);
6091
+ const slug = value => {
6092
+ const slugged = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
6093
+ // job ids must start with a letter or _
6094
+ return /^[a-z_]/.test(slugged) ? slugged : `job-${slugged}`;
6095
+ };
6096
+ const githubJobId = (context, jobName) => slug(`${context.type === "workspace" ? "ws-" : ""}${context.name}-${jobName}-${context.env}`);
6097
+ exports.githubJobId = githubJobId;
6098
+ const githubJobName = (context, jobName) => `${context.name} ${jobName} | ${context.env}`;
6099
+ const resolveNeed = (context, need, allJobs) => {
6100
+ var _a;
6101
+ const env = context.env;
6102
+ const findComponentJob = (componentName, jobName) => {
6103
+ const provider = allJobs.components.find(c => c.context.name === componentName && c.context.env === env);
6104
+ const job = provider === null || provider === void 0 ? void 0 : provider.jobs.find(j => j.name === jobName);
6105
+ if (!provider || !job) {
6106
+ throw new Error(`unknown job referenced: '${jobName}' from '${env}:${componentName}'`);
6107
+ }
6108
+ return (0, exports.githubJobId)(provider.context, jobName);
6109
+ };
6110
+ const findWorkspaceJob = (workspaceName, jobName) => {
6111
+ const provider = allJobs.workspaces.find(w => w.context.name === workspaceName && w.context.env === env);
6112
+ const job = provider === null || provider === void 0 ? void 0 : provider.jobs.find(j => j.name === jobName);
6113
+ if (!provider || !job) {
6114
+ throw new Error(`unknown job referenced: '${jobName}' from workspace '${env}:${workspaceName}'`);
6115
+ }
6116
+ return (0, exports.githubJobId)(provider.context, jobName);
6117
+ };
6118
+ if ((0, lodash_es_1.isObject)(need)) {
6119
+ if ("workspaceName" in need && need.workspaceName) {
6120
+ return {
6121
+ id: findWorkspaceJob(need.workspaceName, need.job),
6122
+ artifacts: need.artifacts
6123
+ };
6124
+ }
6125
+ return {
6126
+ id: findComponentJob((_a = "componentName" in need ? need.componentName : undefined) !== null && _a !== void 0 ? _a : context.name, need.job),
6127
+ artifacts: need.artifacts
6128
+ };
6129
+ }
6130
+ return {
6131
+ id: context.type === "workspace" ? findWorkspaceJob(context.name, need) : findComponentJob(context.name, need),
6132
+ // plain string needs download artifacts by default (gitlab semantics)
6133
+ artifacts: true
6134
+ };
6135
+ };
6136
+ const resolveGithubNeeds = (context, job, allJobs) => {
6137
+ var _a;
6138
+ const resolved = ((_a = job.needs) !== null && _a !== void 0 ? _a : []).map(need => resolveNeed(context, need, allJobs));
6139
+ // deduplicate by provider id, explicit entries win (they come last)
6140
+ return [...new Map(resolved.map(n => [n.id, n])).values()].sort((a, b) => a.id.localeCompare(b.id));
6141
+ };
6142
+ exports.resolveGithubNeeds = resolveGithubNeeds;
6143
+ const createCacheSteps = (context, job) => {
6144
+ var _a, _b;
6145
+ if (!((_a = job.caches) === null || _a === void 0 ? void 0 : _a.length)) {
6146
+ return [];
6147
+ }
6148
+ const lowered = (_b = (0, createJobCache_1.createJobCacheFromCacheConfigs)(context, job.caches)) !== null && _b !== void 0 ? _b : [];
6149
+ return (0, utils_1.ensureArray)(lowered).map(cache => {
6150
+ var _a, _b, _c, _d, _e, _f;
6151
+ const paths = (0, utils_1.ensureArray)((_a = cache.paths) !== null && _a !== void 0 ? _a : []);
6152
+ const key = cache.key;
6153
+ const {
6154
+ cacheKey,
6155
+ restoreKeyPrefix,
6156
+ label
6157
+ } = typeof key === "string" || key === undefined ? {
6158
+ // unique key per run so the cache is re-saved, restored via prefix
6159
+ cacheKey: `${key !== null && key !== void 0 ? key : "cache"}-\${{ github.run_id }}`,
6160
+ restoreKeyPrefix: `${key !== null && key !== void 0 ? key : "cache"}-`,
6161
+ label: key !== null && key !== void 0 ? key : "cache"
6162
+ } : {
6163
+ cacheKey: `${(_b = key.prefix) !== null && _b !== void 0 ? _b : "files"}-\${{ hashFiles(${((_c = key.files) !== null && _c !== void 0 ? _c : []).map(f => `'${f}'`).join(", ")}) }}`,
6164
+ restoreKeyPrefix: `${(_d = key.prefix) !== null && _d !== void 0 ? _d : "files"}-`,
6165
+ label: (_e = key.prefix) !== null && _e !== void 0 ? _e : ((_f = key.files) !== null && _f !== void 0 ? _f : []).join(",")
6166
+ };
6167
+ return {
6168
+ name: `Cache ${label}`,
6169
+ // pull-only caches are restored but never saved
6170
+ uses: cache.policy === "pull" ? "actions/cache/restore@v4" : "actions/cache@v4",
6171
+ with: {
6172
+ path: paths.join("\n"),
6173
+ key: cacheKey,
6174
+ "restore-keys": restoreKeyPrefix
6175
+ }
6176
+ };
6177
+ });
6178
+ };
6179
+ const getSecretsEnv = context => {
6180
+ var _a, _b;
6181
+ const keys = [...context.environment.secretEnvVarKeys, ...((_a = context.environment.jobOnlyVars.build.secretEnvVarKeys) !== null && _a !== void 0 ? _a : []), ...((_b = context.environment.jobOnlyVars.deploy.secretEnvVarKeys) !== null && _b !== void 0 ? _b : [])];
6182
+ return Object.fromEntries(keys.map(({
6183
+ key
6184
+ }) => {
6185
+ const name = (0, getEnvironmentVariables_1.getSecretVarName)(context.env, context.name, key);
6186
+ return [name, `\${{ secrets.${name} }}`];
6187
+ }));
6188
+ };
6189
+ const makeGithubJob = (context, job, allJobs, uploadProviderIds) => {
6190
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
6191
+ const id = (0, exports.githubJobId)(context, job.name);
6192
+ const isComponent = context.type === "component";
6193
+ const createsJobEnv = !!job.environment && isComponent && (!job.environment.action || job.environment.action === "start");
6194
+ const skipCheckout = ((_a = job.runnerVariables) === null || _a === void 0 ? void 0 : _a.GIT_STRATEGY) === "none";
6195
+ const needs = (0, exports.resolveGithubNeeds)(context, job, allJobs);
6196
+ const image = typeof job.image === "string" ? job.image : Array.isArray(job.image) ? job.image[0] : (_b = job.image) === null || _b === void 0 ? void 0 : _b.name;
6197
+ const runScript = [...(0, scriptFunctions_1.getGithubScriptFunctionDefinitions)(), ...(0, gitlab_1.collapseableSection)("injectvars", "Injecting variables")((0, getInjectVarsScript_1.getInjectVarsScript)((_c = job.variables) !== null && _c !== void 0 ? _c : {})), ...((_e = (_d = job.script) === null || _d === void 0 ? void 0 : _d.filter(utils_1.notNil)) !== null && _e !== void 0 ? _e : []), ...(createsJobEnv ? [`echo "url=$ROOT_URL" >> "$GITHUB_OUTPUT"`] : [])].join("\n");
6198
+ const artifactPaths = (_g = (_f = job.artifacts) === null || _f === void 0 ? void 0 : _f.paths) !== null && _g !== void 0 ? _g : [];
6199
+ const services = Object.fromEntries(((_h = job.services) !== null && _h !== void 0 ? _h : []).map(service => typeof service === "string" ? {
6200
+ name: service
6201
+ } : service).filter(service => !isDindService(service.name)).map(service => [slug("alias" in service && service.alias ? service.alias : service.name), {
6202
+ image: service.name,
6203
+ ...("variables" in service && service.variables ? {
6204
+ env: service.variables
6205
+ } : {})
6206
+ }]));
6207
+ const env = {
6208
+ ...Object.fromEntries(Object.entries((_j = job.runnerVariables) !== null && _j !== void 0 ? _j : {}).filter(([key]) => !GITLAB_ONLY_RUNNER_VARIABLES.has(key))),
6209
+ ...(isComponent ? getSecretsEnv(context) : {}),
6210
+ CL_JOB_IMAGE: image !== null && image !== void 0 ? image : "runner"
6211
+ };
6212
+ const githubJob = {
6213
+ name: githubJobName(context, job.name),
6214
+ "runs-on": "ubuntu-latest",
6215
+ ...(needs.length > 0 ? {
6216
+ needs: needs.map(n => n.id)
6217
+ } : {}),
6218
+ ...(image ? {
6219
+ container: {
6220
+ image
6221
+ }
6222
+ } : {}),
6223
+ ...(Object.keys(services).length > 0 ? {
6224
+ services
6225
+ } : {}),
6226
+ ...(job.environment && isComponent ? {
6227
+ environment: {
6228
+ name: context.environment.envType === "review" ? `review-pr\${{ github.event.number }}-${context.name}` : `${context.env}-${context.name}`,
6229
+ ...(createsJobEnv ? {
6230
+ url: "${{ steps.main.outputs.url }}"
6231
+ } : {})
6232
+ }
6233
+ } : {}),
6234
+ env,
6235
+ steps: [...(skipCheckout ? [] : [{
6236
+ name: "Checkout",
6237
+ uses: "actions/checkout@v4"
6238
+ }]), ...createCacheSteps(context, job), ...needs.filter(n => n.artifacts).map(n => ({
6239
+ name: `Download artifacts from ${n.id}`,
6240
+ uses: "actions/download-artifact@v4",
6241
+ with: {
6242
+ name: n.id
6243
+ }
6244
+ })), {
6245
+ name: job.name,
6246
+ id: "main",
6247
+ run: runScript,
6248
+ shell: "bash"
6249
+ }, ...(uploadProviderIds.has(id) || artifactPaths.length > 0 ? artifactPaths.length > 0 ? [{
6250
+ name: "Upload artifacts",
6251
+ uses: "actions/upload-artifact@v4",
6252
+ with: {
6253
+ name: id,
6254
+ path: artifactPaths.join("\n"),
6255
+ "if-no-files-found": "warn"
6256
+ }
6257
+ }] : [] : [])]
6258
+ };
6259
+ return [id, githubJob];
6260
+ };
6261
+ exports.makeGithubJob = makeGithubJob;
6262
+ /**
6263
+ * the ids of all jobs whose artifacts are consumed by other jobs
6264
+ * (they need an upload step)
6265
+ */
6266
+ const getUploadProviderIds = allJobs => {
6267
+ const ids = new Set();
6268
+ [...allJobs.workspaces, ...allJobs.components].forEach(({
6269
+ context,
6270
+ jobs
6271
+ }) => jobs.forEach(job => (0, exports.resolveGithubNeeds)(context, job, allJobs).filter(n => n.artifacts).forEach(n => ids.add(n.id))));
6272
+ return ids;
6273
+ };
6274
+ exports.getUploadProviderIds = getUploadProviderIds;
6275
+
6276
+ /***/ }),
6277
+
6278
+ /***/ 55611:
6279
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
6280
+
6281
+ "use strict";
6282
+
6283
+
6284
+ Object.defineProperty(exports, "__esModule", ({
6285
+ value: true
6286
+ }));
6287
+ exports.getGithubReleaseJobs = void 0;
6288
+ const runner_1 = __nccwpck_require__(92348);
6289
+ const createReleaseJob = needs => ({
6290
+ name: "create release",
6291
+ "runs-on": "ubuntu-latest",
6292
+ container: {
6293
+ image: (0, runner_1.getRunnerImage)("semantic-release")
6294
+ },
6295
+ // semantic-release pushes the version tag and release commit
6296
+ permissions: {
6297
+ contents: "write"
6298
+ },
6299
+ ...(needs && needs.length > 0 ? {
6300
+ needs
6301
+ } : {}),
6302
+ env: {
6303
+ GITHUB_TOKEN: "${{ github.token }}"
6304
+ },
6305
+ steps: [{
6306
+ name: "Checkout",
6307
+ uses: "actions/checkout@v4",
6308
+ // semantic-release needs the full history to determine the version
6309
+ with: {
6310
+ "fetch-depth": 0
6311
+ }
6312
+ }, {
6313
+ name: "create release",
6314
+ run: "semanticRelease",
6315
+ shell: "bash"
6316
+ }]
6317
+ });
6318
+ /**
6319
+ * the release jobs for the github backend (the counterpart of the
6320
+ * gitlab release jobs):
6321
+ * - releases.when === "auto": the release job runs in the main-branch
6322
+ * workflow after all other jobs; a force variant goes to the manual
6323
+ * tasks workflow
6324
+ * - otherwise (manual, the default): the release job goes to the
6325
+ * manual tasks workflow
6326
+ */
6327
+ const getGithubReleaseJobs = (config, mainWorkflowJobIds) => {
6328
+ var _a;
6329
+ if (((_a = config.releases) === null || _a === void 0 ? void 0 : _a.when) === "auto") {
6330
+ return {
6331
+ main: {
6332
+ "create-release": createReleaseJob(mainWorkflowJobIds)
6333
+ },
6334
+ manual: {
6335
+ "force-create-release": createReleaseJob()
6336
+ }
6337
+ };
6338
+ }
6339
+ return {
6340
+ main: {},
6341
+ manual: {
6342
+ "create-release": createReleaseJob()
6343
+ }
6344
+ };
6345
+ };
6346
+ exports.getGithubReleaseJobs = getGithubReleaseJobs;
6347
+
6348
+ /***/ }),
6349
+
6350
+ /***/ 99635:
6351
+ /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
6352
+
6353
+ "use strict";
6354
+
6355
+
6356
+ var __createBinding = this && this.__createBinding || (Object.create ? function (o, m, k, k2) {
6357
+ if (k2 === undefined) k2 = k;
6358
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6359
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6360
+ desc = {
6361
+ enumerable: true,
6362
+ get: function () {
6363
+ return m[k];
6364
+ }
6365
+ };
6366
+ }
6367
+ Object.defineProperty(o, k2, desc);
6368
+ } : function (o, m, k, k2) {
6369
+ if (k2 === undefined) k2 = k;
6370
+ o[k2] = m[k];
6371
+ });
6372
+ var __exportStar = this && this.__exportStar || function (m, exports) {
6373
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
6374
+ };
6375
+ Object.defineProperty(exports, "__esModule", ({
6376
+ value: true
6377
+ }));
6378
+ __exportStar(__nccwpck_require__(54038), exports);
6379
+ __exportStar(__nccwpck_require__(25474), exports);
6380
+
6381
+ /***/ }),
6382
+
6383
+ /***/ 75759:
6384
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
6385
+
6386
+ "use strict";
6387
+
6388
+
6389
+ Object.defineProperty(exports, "__esModule", ({
6390
+ value: true
6391
+ }));
6392
+ exports.getGithubScriptFunctionDefinitions = void 0;
6393
+ const globalScriptFunctions_1 = __nccwpck_require__(53891);
6394
+ /**
6395
+ * github variants of the global script functions where the gitlab
6396
+ * implementation uses gitlab-specific mechanics (e.g. collapsible log
6397
+ * sections use gitlab's `section_start` escape codes, github uses
6398
+ * `::group::` workflow commands). All other functions are plain bash
6399
+ * and shared as-is.
6400
+ */
6401
+ const GITHUB_FUNCTION_OVERRIDES = {
6402
+ collapseable_section_start: `local section_title="\${1}"
6403
+ local section_description="\${2:-$section_title}"
6404
+ echo "::group::\${section_description}"`,
6405
+ collapseable_section_end: `echo "::endgroup::"`
6406
+ };
6407
+ /**
6408
+ * the bash function definitions to prepend to every job script.
6409
+ * github has no pipeline-wide before_script like gitlab, so each job
6410
+ * carries its own definitions.
6411
+ */
6412
+ const getGithubScriptFunctionDefinitions = () => [...globalScriptFunctions_1.globalScriptFunctions.values()].map(fn => {
6413
+ const override = GITHUB_FUNCTION_OVERRIDES[fn.name];
6414
+ return override ? `function ${fn.name} () {\n${override.trim()}\n}` : fn.toBashFunction();
6415
+ });
6416
+ exports.getGithubScriptFunctionDefinitions = getGithubScriptFunctionDefinitions;
6417
+
6418
+ /***/ }),
6419
+
5848
6420
  /***/ 22278:
5849
6421
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
5850
6422
 
@@ -5855,6 +6427,7 @@ Object.defineProperty(exports, "__esModule", ({
5855
6427
  value: true
5856
6428
  }));
5857
6429
  exports.GitlabBackend = void 0;
6430
+ const promises_1 = __nccwpck_require__(91943);
5858
6431
  const rules_1 = __nccwpck_require__(44565);
5859
6432
  const config_1 = __nccwpck_require__(96925);
5860
6433
  const createAllJobs_1 = __nccwpck_require__(83671);
@@ -5870,6 +6443,12 @@ class GitlabBackend {
5870
6443
  this.type = "gitlab";
5871
6444
  this.generatedFolder = GITLAB_GENERATED_FOLDER;
5872
6445
  }
6446
+ async cleanup() {
6447
+ await (0, promises_1.rm)(this.generatedFolder, {
6448
+ force: true,
6449
+ recursive: true
6450
+ });
6451
+ }
5873
6452
  async createFiles(config) {
5874
6453
  const includes = await this.createIncludes(config);
5875
6454
  const mainFile = {
@@ -6584,12 +7163,15 @@ var __exportStar = this && this.__exportStar || function (m, exports) {
6584
7163
  Object.defineProperty(exports, "__esModule", ({
6585
7164
  value: true
6586
7165
  }));
6587
- exports.getPipelineBackend = void 0;
7166
+ exports.getEnabledPipelineTypes = exports.getPipelineBackend = void 0;
7167
+ const github_1 = __nccwpck_require__(99635);
6588
7168
  const gitlab_1 = __nccwpck_require__(8475);
6589
7169
  __exportStar(__nccwpck_require__(92474), exports);
6590
7170
  __exportStar(__nccwpck_require__(8475), exports);
7171
+ __exportStar(__nccwpck_require__(99635), exports);
6591
7172
  const BACKENDS = {
6592
- gitlab: () => new gitlab_1.GitlabBackend()
7173
+ gitlab: () => new gitlab_1.GitlabBackend(),
7174
+ github: () => new github_1.GithubBackend()
6593
7175
  };
6594
7176
  const getPipelineBackend = type => {
6595
7177
  const createBackend = BACKENDS[type];
@@ -6599,6 +7181,25 @@ const getPipelineBackend = type => {
6599
7181
  return createBackend();
6600
7182
  };
6601
7183
  exports.getPipelineBackend = getPipelineBackend;
7184
+ /**
7185
+ * the pipeline types enabled for this config. Multiple types can be
7186
+ * enabled at once (parallel generation, e.g. during a CI migration).
7187
+ */
7188
+ const getEnabledPipelineTypes = config => {
7189
+ var _a;
7190
+ if (config.pipelines) {
7191
+ const enabled = Object.keys(BACKENDS).filter(type => {
7192
+ var _a;
7193
+ return (_a = config.pipelines) === null || _a === void 0 ? void 0 : _a[type];
7194
+ });
7195
+ if (enabled.length === 0) {
7196
+ throw new Error("`pipelines` is configured, but no pipeline type is enabled");
7197
+ }
7198
+ return enabled;
7199
+ }
7200
+ return [(_a = config.pipelineType) !== null && _a !== void 0 ? _a : "gitlab"];
7201
+ };
7202
+ exports.getEnabledPipelineTypes = getEnabledPipelineTypes;
6602
7203
 
6603
7204
  /***/ }),
6604
7205
 
@@ -6922,10 +7523,12 @@ Object.defineProperty(exports, "__esModule", ({
6922
7523
  value: true
6923
7524
  }));
6924
7525
  exports.getCiVariable = void 0;
6925
- const ciVariables_1 = __nccwpck_require__(78506);
7526
+ const ciVariables_1 = __nccwpck_require__(25474);
7527
+ const ciVariables_2 = __nccwpck_require__(78506);
6926
7528
  const BashExpression_1 = __nccwpck_require__(25354);
6927
7529
  const CI_VARIABLES_PER_PIPELINE_TYPE = {
6928
- gitlab: ciVariables_1.GITLAB_CI_VARIABLES
7530
+ gitlab: ciVariables_2.GITLAB_CI_VARIABLES,
7531
+ github: ciVariables_1.GITHUB_CI_VARIABLES
6929
7532
  };
6930
7533
  /**
6931
7534
  * resolves a platform-neutral CI variable to a bash expression for the
@@ -8544,7 +9147,7 @@ Object.defineProperty(exports, "__esModule", ({
8544
9147
  value: true
8545
9148
  }));
8546
9149
  exports.DOCKER_REGISTRY = exports.PIPELINE_IMAGE_TAG = void 0;
8547
- exports.PIPELINE_IMAGE_TAG = "next-e7541a00" || 0;
9150
+ exports.PIPELINE_IMAGE_TAG = "next-4e7c6848" || 0;
8548
9151
  exports.DOCKER_REGISTRY = "git.panter.ch:5001/catladder/catladder" || 0;
8549
9152
 
8550
9153
  /***/ }),
@@ -9111,7 +9714,9 @@ const bashExpressionPerPipelineType_1 = __nccwpck_require__(61945);
9111
9714
  const getEnvType_1 = __nccwpck_require__(28254);
9112
9715
  const REVIEW_SLUG = {
9113
9716
  default: "unknown-review-slug",
9114
- gitlab: new BashExpression_1.BashExpression(`$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })`)
9717
+ gitlab: new BashExpression_1.BashExpression(`$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })`),
9718
+ // CL_PR_NUMBER is injected by the github backend at the workflow level
9719
+ github: new BashExpression_1.BashExpression(`$([ -n "$CL_PR_NUMBER" ] && echo "pr$CL_PR_NUMBER" || echo "unknown")`)
9115
9720
  };
9116
9721
  const getReviewSlug = (envConfig, env, pipelineType) => {
9117
9722
  const envType = (0, getEnvType_1.getEnvType)(env, envConfig);
@@ -12287,14 +12892,22 @@ const promises_1 = __nccwpck_require__(91943);
12287
12892
  const path_1 = __nccwpck_require__(16928);
12288
12893
  const backends_1 = __nccwpck_require__(93243);
12289
12894
  const gitlab_1 = __nccwpck_require__(8475);
12895
+ /**
12896
+ * generates the pipeline files of all pipeline types enabled in the
12897
+ * config (see `pipelines`). Pass an explicit `pipelineType` to generate
12898
+ * only that one.
12899
+ */
12290
12900
  async function generatePipelineFiles(context, pipelineType) {
12291
- const backend = (0, backends_1.getPipelineBackend)(pipelineType);
12901
+ const pipelineTypes = pipelineType ? [pipelineType] : (0, backends_1.getEnabledPipelineTypes)(context.config);
12902
+ for (const type of pipelineTypes) {
12903
+ await generatePipelineFilesForBackend(context, (0, backends_1.getPipelineBackend)(type));
12904
+ }
12905
+ }
12906
+ exports.generatePipelineFiles = generatePipelineFiles;
12907
+ async function generatePipelineFilesForBackend(context, backend) {
12292
12908
  const files = await backend.createFiles(context.config);
12293
- // first clean up the folder
12294
- await (0, promises_1.rm)(backend.generatedFolder, {
12295
- force: true,
12296
- recursive: true
12297
- });
12909
+ // first clean up previously generated files
12910
+ await backend.cleanup();
12298
12911
  // write files
12299
12912
  await Promise.all(files.map(async ({
12300
12913
  path,
@@ -12306,7 +12919,6 @@ async function generatePipelineFiles(context, pipelineType) {
12306
12919
  await context.fileWriter.writeYamlfile(path, content);
12307
12920
  }));
12308
12921
  }
12309
- exports.generatePipelineFiles = generatePipelineFiles;
12310
12922
  /**
12311
12923
  *
12312
12924
  * for testing purposes
@@ -155912,7 +156524,7 @@ function differenceInCalendarMonths(dateLeft, dateRight) {
155912
156524
  "use strict";
155913
156525
 
155914
156526
  exports.differenceInCalendarQuarters = differenceInCalendarQuarters;
155915
- var _index = __nccwpck_require__(14016);
156527
+ var _index = __nccwpck_require__(91635);
155916
156528
  var _index2 = __nccwpck_require__(65073);
155917
156529
 
155918
156530
  /**
@@ -160324,7 +160936,7 @@ function getOverlappingDaysInIntervals(intervalLeft, intervalRight) {
160324
160936
 
160325
160937
  /***/ }),
160326
160938
 
160327
- /***/ 14016:
160939
+ /***/ 91635:
160328
160940
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
160329
160941
 
160330
160942
  "use strict";
@@ -161892,7 +162504,7 @@ Object.keys(_index92).forEach(function (key) {
161892
162504
  },
161893
162505
  });
161894
162506
  });
161895
- var _index93 = __nccwpck_require__(14016);
162507
+ var _index93 = __nccwpck_require__(91635);
161896
162508
  Object.keys(_index93).forEach(function (key) {
161897
162509
  if (key === "default" || key === "__esModule") return;
161898
162510
  if (key in exports && exports[key] === _index93[key]) return;