@catladder/cli 0.0.0-next-78d43d4a → 0.0.0-next-dbb75f51
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/CONTRIBUTING.md +1 -1
- package/README.md +2 -2
- package/dist/apps/cli/src/catci.js +2 -2
- package/dist/apps/cli/src/catci.js.map +1 -1
- package/dist/apps/cli/src/commands/project/commandGitlabCi.js +2 -1
- package/dist/apps/cli/src/commands/project/commandGitlabCi.js.map +1 -1
- package/dist/apps/cli/src/commands/security/commandSecurityAuditCiJob.js +2 -2
- package/dist/apps/cli/src/commands/security/commandSecurityAuditCiJob.js.map +1 -1
- package/dist/apps/cli/src/commands/security/commandSecurityAuditCreate.js +2 -2
- package/dist/apps/cli/src/commands/security/commandSecurityAuditCreate.js.map +1 -1
- package/dist/apps/cli/src/publish/npmPublishJob.js +22 -5
- package/dist/apps/cli/src/publish/npmPublishJob.js.map +1 -1
- package/dist/apps/cli/src/security/topics.json +15 -15
- package/dist/apps/cli/src/utils/gitlabHost.d.ts +14 -0
- package/dist/apps/cli/src/utils/gitlabHost.js +27 -0
- package/dist/apps/cli/src/utils/gitlabHost.js.map +1 -0
- package/dist/bundles/catci/index.js +10 -4
- package/dist/bundles/catenv/index.js +137 -36
- package/dist/bundles/cli/index.js +178 -42
- package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/README.md +2 -2
- package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/_helpers.tpl +0 -10
- package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.ingress.yaml +0 -5
- package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/values.yaml +0 -1
- package/dist/bundles/runner-images/npm-publish/Dockerfile +12 -0
- package/dist/bundles/runner-images/semantic-release/scripts/semanticRelease +4 -3
- package/dist/bundles/skills/catladder-config/SKILL.md +1 -1
- package/dist/bundles/skills/catladder-deploys/references/deploy-types.md +3 -2
- package/dist/packages/pipeline/src/backends/github/createGithubJobs.js +70 -24
- package/dist/packages/pipeline/src/backends/github/createGithubJobs.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js +11 -1
- package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/createGitlabJobs.js +5 -1
- package/dist/packages/pipeline/src/backends/gitlab/createGitlabJobs.js.map +1 -1
- package/dist/packages/pipeline/src/backends/index.d.ts +6 -0
- package/dist/packages/pipeline/src/backends/index.js +9 -2
- package/dist/packages/pipeline/src/backends/index.js.map +1 -1
- package/dist/packages/pipeline/src/context/getEnvironmentVariables.d.ts +1 -1
- package/dist/packages/pipeline/src/customImages/shippedImages.js +1 -0
- package/dist/packages/pipeline/src/customImages/shippedImages.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/base/deploy.js +1 -0
- package/dist/packages/pipeline/src/deploy/base/deploy.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/npmPackage/deployJob.js +6 -1
- package/dist/packages/pipeline/src/deploy/npmPackage/deployJob.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/pages/deployJob.js +16 -5
- package/dist/packages/pipeline/src/deploy/pages/deployJob.js.map +1 -1
- package/dist/packages/pipeline/src/pipeline/generatePipelineFiles.js +10 -0
- package/dist/packages/pipeline/src/pipeline/generatePipelineFiles.js.map +1 -1
- package/dist/packages/pipeline/src/runner/index.d.ts +1 -1
- package/dist/packages/pipeline/src/runner/index.js.map +1 -1
- package/dist/packages/pipeline/src/types/config.d.ts +4 -4
- package/dist/packages/pipeline/src/types/hooks.d.ts +1 -1
- package/dist/packages/pipeline/src/types/jobDefinition.d.ts +1 -1
- package/dist/packages/pipeline/src/types/jobs.d.ts +9 -0
- package/dist/packages/pipeline/src/types/jobs.js.map +1 -1
- package/dist/packages/pipeline/src/utils/writeFiles.d.ts +6 -0
- package/dist/packages/pipeline/src/utils/writeFiles.js +8 -2
- package/dist/packages/pipeline/src/utils/writeFiles.js.map +1 -1
- package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/README.md +2 -2
- package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/_helpers.tpl +0 -10
- package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.ingress.yaml +0 -5
- package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/values.yaml +0 -1
- package/dist/runner-images/npm-publish/Dockerfile +12 -0
- package/dist/runner-images/semantic-release/scripts/semanticRelease +4 -3
- package/dist/skills/catladder-config/SKILL.md +1 -1
- package/dist/skills/catladder-deploys/references/deploy-types.md +3 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/includes/envrc +1 -1
- package/package.json +5 -5
- package/src/catci.ts +2 -3
- package/src/commands/project/commandGitlabCi.ts +2 -1
- package/src/commands/security/commandSecurityAuditCiJob.ts +2 -3
- package/src/commands/security/commandSecurityAuditCreate.ts +2 -3
- package/src/publish/npmPublishJob.ts +32 -6
- package/src/security/topics.json +15 -15
- package/src/utils/gitlabHost.ts +23 -0
|
@@ -2959,6 +2959,7 @@ const child_process_promise_1 = __nccwpck_require__(42242);
|
|
|
2959
2959
|
const lodash_es_1 = __nccwpck_require__(50866);
|
|
2960
2960
|
const open_1 = __importDefault(__nccwpck_require__(81776));
|
|
2961
2961
|
const defineCommand_1 = __nccwpck_require__(40317);
|
|
2962
|
+
const gitlabHost_1 = __nccwpck_require__(83534);
|
|
2962
2963
|
const gitlab_1 = __nccwpck_require__(8680);
|
|
2963
2964
|
const statusEmojiMap = {
|
|
2964
2965
|
failed: "🙀",
|
|
@@ -3033,7 +3034,7 @@ exports.commandCiJobLog = (0, defineCommand_1.defineCommand)({
|
|
|
3033
3034
|
const id = selectedJob.id;
|
|
3034
3035
|
let finished = false;
|
|
3035
3036
|
while (!finished) {
|
|
3036
|
-
const trace = await (0, child_process_promise_1.exec)(`curl -s --header "PRIVATE-TOKEN: ${await (0, gitlab_1.getGitlabToken)(ctx)}" "
|
|
3037
|
+
const trace = await (0, child_process_promise_1.exec)(`curl -s --header "PRIVATE-TOKEN: ${await (0, gitlab_1.getGitlabToken)(ctx)}" "${await (0, gitlabHost_1.getGitlabHostUrl)()}/api/v4/projects/${projectId}/jobs/${id}/trace"`);
|
|
3037
3038
|
const job = await (0, gitlab_1.doGitlabRequest)(ctx, `projects/${projectId}/jobs/${id}`);
|
|
3038
3039
|
if (trace.stdout) {
|
|
3039
3040
|
ctx.log(trace.stdout);
|
|
@@ -4725,7 +4726,7 @@ const defineCommand_1 = __nccwpck_require__(40317);
|
|
|
4725
4726
|
const rest_1 = __nccwpck_require__(37650);
|
|
4726
4727
|
const evaluateSecurityAudit_1 = __nccwpck_require__(79392);
|
|
4727
4728
|
const createSecurityAuditMergeRequest_1 = __nccwpck_require__(91276);
|
|
4728
|
-
const
|
|
4729
|
+
const gitlabHost_1 = __nccwpck_require__(83534);
|
|
4729
4730
|
exports.commandSecurityAuditCiJob = (0, defineCommand_1.defineCommand)({
|
|
4730
4731
|
name: "security audit ci-job",
|
|
4731
4732
|
description: "Evaluates security audit document. Creates MR with template if missing.",
|
|
@@ -4763,7 +4764,7 @@ exports.commandSecurityAuditCiJob = (0, defineCommand_1.defineCommand)({
|
|
|
4763
4764
|
const mainBranch = await ctx.get("mainBranch");
|
|
4764
4765
|
const projectId = await ctx.get("projectId");
|
|
4765
4766
|
const userId = await ctx.get("userId");
|
|
4766
|
-
const api = new rest_1.Gitlab({ host:
|
|
4767
|
+
const api = new rest_1.Gitlab({ host: await (0, gitlabHost_1.getGitlabHostUrl)(), token });
|
|
4767
4768
|
const mr = await (0, createSecurityAuditMergeRequest_1.createSecurityAuditMergeRequest)({
|
|
4768
4769
|
api,
|
|
4769
4770
|
mainBranch,
|
|
@@ -4803,7 +4804,7 @@ exports.commandSecurityAuditCreate = void 0;
|
|
|
4803
4804
|
const defineCommand_1 = __nccwpck_require__(40317);
|
|
4804
4805
|
const rest_1 = __nccwpck_require__(37650);
|
|
4805
4806
|
const createSecurityAuditMergeRequest_1 = __nccwpck_require__(91276);
|
|
4806
|
-
const
|
|
4807
|
+
const gitlabHost_1 = __nccwpck_require__(83534);
|
|
4807
4808
|
exports.commandSecurityAuditCreate = (0, defineCommand_1.defineCommand)({
|
|
4808
4809
|
name: "security audit create",
|
|
4809
4810
|
description: "Creates a MR with the latest security audit template document",
|
|
@@ -4835,7 +4836,7 @@ exports.commandSecurityAuditCreate = (0, defineCommand_1.defineCommand)({
|
|
|
4835
4836
|
const mainBranch = await ctx.get("mainBranch");
|
|
4836
4837
|
const projectId = await ctx.get("projectId");
|
|
4837
4838
|
const userId = await ctx.get("userId");
|
|
4838
|
-
const api = new rest_1.Gitlab({ host:
|
|
4839
|
+
const api = new rest_1.Gitlab({ host: await (0, gitlabHost_1.getGitlabHostUrl)(), token });
|
|
4839
4840
|
const result = await (0, createSecurityAuditMergeRequest_1.createSecurityAuditMergeRequest)({
|
|
4840
4841
|
api,
|
|
4841
4842
|
mainBranch,
|
|
@@ -6722,6 +6723,40 @@ exports.upsertAllVariables = upsertAllVariables;
|
|
|
6722
6723
|
|
|
6723
6724
|
/***/ }),
|
|
6724
6725
|
|
|
6726
|
+
/***/ 83534:
|
|
6727
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
6728
|
+
|
|
6729
|
+
"use strict";
|
|
6730
|
+
|
|
6731
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
6732
|
+
exports.getGitlabHostUrl = void 0;
|
|
6733
|
+
const gitProjectInformation_1 = __nccwpck_require__(83851);
|
|
6734
|
+
/**
|
|
6735
|
+
* the base url of the gitlab instance this project lives on.
|
|
6736
|
+
*
|
|
6737
|
+
* Never hardcode an instance: catladder is used outside panter, and the
|
|
6738
|
+
* host was baked in as https://git.panter.ch in several places, which
|
|
6739
|
+
* silently broke every consumer on another gitlab.
|
|
6740
|
+
*
|
|
6741
|
+
* - in a gitlab CI job, `CI_SERVER_URL` is the authoritative value
|
|
6742
|
+
* (predefined, already includes the scheme)
|
|
6743
|
+
* - locally, derive it from the git remote
|
|
6744
|
+
*
|
|
6745
|
+
* @param remoteName the remote to derive from outside CI (default origin)
|
|
6746
|
+
*/
|
|
6747
|
+
const getGitlabHostUrl = async (remoteName = "origin") => {
|
|
6748
|
+
const fromCi = process.env.CI_SERVER_URL;
|
|
6749
|
+
if (fromCi) {
|
|
6750
|
+
return fromCi.replace(/\/+$/, "");
|
|
6751
|
+
}
|
|
6752
|
+
const { gitRemoteHost } = await (0, gitProjectInformation_1.getGitRemoteHostAndPath)(remoteName);
|
|
6753
|
+
return `https://${gitRemoteHost}`;
|
|
6754
|
+
};
|
|
6755
|
+
exports.getGitlabHostUrl = getGitlabHostUrl;
|
|
6756
|
+
//# sourceMappingURL=gitlabHost.js.map
|
|
6757
|
+
|
|
6758
|
+
/***/ }),
|
|
6759
|
+
|
|
6725
6760
|
/***/ 66697:
|
|
6726
6761
|
/***/ ((__unused_webpack_module, exports) => {
|
|
6727
6762
|
|
|
@@ -8924,6 +8959,11 @@ const makeGithubJob = (context, job, allJobs, uploadProviderIds, images, scripts
|
|
|
8924
8959
|
? runScript
|
|
8925
8960
|
: scripts.add(id, runScript);
|
|
8926
8961
|
const artifactPaths = (_g = (_f = job.artifacts) === null || _f === void 0 ? void 0 : _f.paths) !== null && _g !== void 0 ? _g : [];
|
|
8962
|
+
// github pages: the built site is handed to the official actions
|
|
8963
|
+
// instead of being uploaded as a plain artifact. `deploy-pages`
|
|
8964
|
+
// replaces the whole site, so there is no path_prefix equivalent —
|
|
8965
|
+
// review previews are rejected upstream (see the pages deploy type).
|
|
8966
|
+
const pagesPublishDir = job.pages ? artifactPaths[0] : undefined;
|
|
8927
8967
|
const declaredServices = ((_h = job.services) !== null && _h !== void 0 ? _h : []).map((service) => typeof service === "string" ? { name: service } : service);
|
|
8928
8968
|
// docker runs natively on github runners, so gitlab's docker-in-docker
|
|
8929
8969
|
// services are dropped. The job container stays: the runner mounts the
|
|
@@ -8969,14 +9009,38 @@ const makeGithubJob = (context, job, allJobs, uploadProviderIds, images, scripts
|
|
|
8969
9009
|
*/
|
|
8970
9010
|
const referencesSecrets = Object.values(env).some((value) => typeof value === "string" &&
|
|
8971
9011
|
(value.includes("${{ secrets.") || value.includes("${{ vars.")));
|
|
8972
|
-
const githubEnvironment =
|
|
9012
|
+
const githubEnvironment = pagesPublishDir
|
|
9013
|
+
? // github requires pages deployments to target the `github-pages`
|
|
9014
|
+
// environment, and only the deploy step knows the final url.
|
|
9015
|
+
// `secrets-sync-github` derives its targets from the generated
|
|
9016
|
+
// workflows, so any secret this job references is synced there.
|
|
9017
|
+
{
|
|
9018
|
+
name: "github-pages",
|
|
9019
|
+
url: "${{ steps.deployment.outputs.page_url }}",
|
|
9020
|
+
}
|
|
9021
|
+
: job.environment && isComponent
|
|
9022
|
+
? {
|
|
9023
|
+
name: `${context.env}-${context.name}`,
|
|
9024
|
+
...(createsJobEnv ? { url: "${{ steps.main.outputs.url }}" } : {}),
|
|
9025
|
+
}
|
|
9026
|
+
: referencesSecrets
|
|
9027
|
+
? { name: context.env }
|
|
9028
|
+
: undefined;
|
|
9029
|
+
// declaring `permissions` drops ALL default token grants, so a job
|
|
9030
|
+
// that needs any special grant must also re-declare the ordinary ones:
|
|
9031
|
+
// `contents: read` for the checkout and `packages: read` to pull its
|
|
9032
|
+
// job image from the repo registry.
|
|
9033
|
+
const specialPermissions = {
|
|
9034
|
+
...(pagesPublishDir ? { pages: "write", "id-token": "write" } : {}),
|
|
9035
|
+
...(job.idToken ? { "id-token": "write" } : {}),
|
|
9036
|
+
};
|
|
9037
|
+
const permissions = Object.keys(specialPermissions).length
|
|
8973
9038
|
? {
|
|
8974
|
-
|
|
8975
|
-
...(
|
|
9039
|
+
contents: "read",
|
|
9040
|
+
...(resolved.fromRepoRegistry ? { packages: "read" } : {}),
|
|
9041
|
+
...specialPermissions,
|
|
8976
9042
|
}
|
|
8977
|
-
:
|
|
8978
|
-
? { name: context.env }
|
|
8979
|
-
: undefined;
|
|
9043
|
+
: undefined;
|
|
8980
9044
|
const githubJob = {
|
|
8981
9045
|
name: githubJobName(context, job.name),
|
|
8982
9046
|
"runs-on": "ubuntu-latest",
|
|
@@ -8999,6 +9063,7 @@ const makeGithubJob = (context, job, allJobs, uploadProviderIds, images, scripts
|
|
|
8999
9063
|
: {}),
|
|
9000
9064
|
...(Object.keys(services).length > 0 ? { services } : {}),
|
|
9001
9065
|
...(githubEnvironment ? { environment: githubEnvironment } : {}),
|
|
9066
|
+
...(permissions ? { permissions } : {}),
|
|
9002
9067
|
env,
|
|
9003
9068
|
steps: [
|
|
9004
9069
|
...(skipCheckout
|
|
@@ -9018,25 +9083,41 @@ const makeGithubJob = (context, job, allJobs, uploadProviderIds, images, scripts
|
|
|
9018
9083
|
run,
|
|
9019
9084
|
shell: "bash",
|
|
9020
9085
|
},
|
|
9021
|
-
...(
|
|
9022
|
-
?
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
"include-hidden-files": true,
|
|
9035
|
-
},
|
|
9036
|
-
},
|
|
9037
|
-
]
|
|
9038
|
-
: []
|
|
9086
|
+
...(pagesPublishDir
|
|
9087
|
+
? [
|
|
9088
|
+
{
|
|
9089
|
+
name: "Upload pages artifact",
|
|
9090
|
+
uses: "actions/upload-pages-artifact@v3",
|
|
9091
|
+
with: { path: pagesPublishDir },
|
|
9092
|
+
},
|
|
9093
|
+
{
|
|
9094
|
+
name: "Deploy to github pages",
|
|
9095
|
+
id: "deployment",
|
|
9096
|
+
uses: "actions/deploy-pages@v4",
|
|
9097
|
+
},
|
|
9098
|
+
]
|
|
9039
9099
|
: []),
|
|
9100
|
+
...(pagesPublishDir
|
|
9101
|
+
? []
|
|
9102
|
+
: uploadProviderIds.has(id) || artifactPaths.length > 0
|
|
9103
|
+
? artifactPaths.length > 0
|
|
9104
|
+
? [
|
|
9105
|
+
{
|
|
9106
|
+
name: "Upload artifacts",
|
|
9107
|
+
uses: "actions/upload-artifact@v4",
|
|
9108
|
+
with: {
|
|
9109
|
+
name: id,
|
|
9110
|
+
path: artifactPaths.join("\n"),
|
|
9111
|
+
"if-no-files-found": "warn",
|
|
9112
|
+
// gitlab artifacts include everything; upload-artifact
|
|
9113
|
+
// silently drops hidden files by default — which is
|
|
9114
|
+
// exactly where next.js builds live (.next)
|
|
9115
|
+
"include-hidden-files": true,
|
|
9116
|
+
},
|
|
9117
|
+
},
|
|
9118
|
+
]
|
|
9119
|
+
: []
|
|
9120
|
+
: []),
|
|
9040
9121
|
],
|
|
9041
9122
|
};
|
|
9042
9123
|
return [id, githubJob];
|
|
@@ -9526,8 +9607,10 @@ const createGitlabPipeline_1 = __nccwpck_require__(94411);
|
|
|
9526
9607
|
const gitlabReleaseJobs_1 = __nccwpck_require__(75512);
|
|
9527
9608
|
const getPipelineStages_1 = __nccwpck_require__(29641);
|
|
9528
9609
|
const sortGitLabJobDefProps_1 = __nccwpck_require__(71625);
|
|
9610
|
+
const writeFiles_1 = __nccwpck_require__(7396);
|
|
9529
9611
|
const CATLADDER_GENERATED_FOLDER = ".catladder-generated";
|
|
9530
9612
|
const GITLAB_GENERATED_FOLDER = CATLADDER_GENERATED_FOLDER + "/gitlab";
|
|
9613
|
+
const GITLAB_MAIN_FILE = ".gitlab-ci.yml";
|
|
9531
9614
|
class GitlabBackend {
|
|
9532
9615
|
constructor() {
|
|
9533
9616
|
this.type = "gitlab";
|
|
@@ -9535,12 +9618,20 @@ class GitlabBackend {
|
|
|
9535
9618
|
}
|
|
9536
9619
|
async cleanup() {
|
|
9537
9620
|
await (0, promises_1.rm)(this.generatedFolder, { force: true, recursive: true });
|
|
9621
|
+
// `.gitlab-ci.yml` lives outside the generated folder, so it used to
|
|
9622
|
+
// survive disabling the gitlab backend and kept a stale pipeline
|
|
9623
|
+
// running. Only remove it when it is ours: a project that generates
|
|
9624
|
+
// github only may well hand-maintain a gitlab file of its own.
|
|
9625
|
+
const mainFile = await (0, promises_1.readFile)(GITLAB_MAIN_FILE, "utf-8").catch(() => null);
|
|
9626
|
+
if (mainFile === null || mainFile === void 0 ? void 0 : mainFile.includes(writeFiles_1.GENERATED_FILE_MARKER)) {
|
|
9627
|
+
await (0, promises_1.rm)(GITLAB_MAIN_FILE, { force: true });
|
|
9628
|
+
}
|
|
9538
9629
|
}
|
|
9539
9630
|
async createFiles(config) {
|
|
9540
9631
|
const images = this.createImagesPlan(config);
|
|
9541
9632
|
const includes = await this.createIncludes(config, images);
|
|
9542
9633
|
const mainFile = {
|
|
9543
|
-
path:
|
|
9634
|
+
path: GITLAB_MAIN_FILE,
|
|
9544
9635
|
content: {
|
|
9545
9636
|
include: includes.map((i) => i.path),
|
|
9546
9637
|
},
|
|
@@ -9849,7 +9940,11 @@ const getFullReferencedJobNameFromWorkspace = (referencedJobName, workspaceName,
|
|
|
9849
9940
|
const getJobName = (need) => (0, lodash_es_1.isObject)(need) ? need.job : need;
|
|
9850
9941
|
const makeGitlabJob = (context, job, allJobs, images, baseRules) => {
|
|
9851
9942
|
var _a, _b, _c;
|
|
9852
|
-
const { environment, envMode, requires, provides, name, needs, jobTags, script, variables, runnerVariables, gate, when: jobWhen, allow_failure: jobAllowFailure, cache: jobCache, caches, image: jobImage,
|
|
9943
|
+
const { environment, envMode, requires, provides, name, needs, jobTags, script, variables, runnerVariables, gate, when: jobWhen, allow_failure: jobAllowFailure, cache: jobCache, caches, image: jobImage,
|
|
9944
|
+
// github lowers this to `permissions: id-token: write`; gitlab has
|
|
9945
|
+
// no counterpart, and anything left in `rest` lands in the job yaml
|
|
9946
|
+
// verbatim ("config contains unknown keys: idtoken")
|
|
9947
|
+
idToken: _idToken, ...rest } = job;
|
|
9853
9948
|
// catladder image references resolve to an image built in the repo's
|
|
9854
9949
|
// own registry; the job additionally depends on the image build job
|
|
9855
9950
|
const resolvedImage = images.resolve(jobImage);
|
|
@@ -10518,7 +10613,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
10518
10613
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
10519
10614
|
};
|
|
10520
10615
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
10521
|
-
exports.getEnabledPipelineTypes = exports.getVaultConfig = exports.getPipelineGitRemote = exports.getPipelineOptions = exports.getPipelineBackend = void 0;
|
|
10616
|
+
exports.getEnabledPipelineTypes = exports.getVaultConfig = exports.getPipelineGitRemote = exports.getPipelineOptions = exports.getPipelineBackend = exports.getAllPipelineTypes = void 0;
|
|
10522
10617
|
const github_1 = __nccwpck_require__(48);
|
|
10523
10618
|
const gitlab_1 = __nccwpck_require__(10744);
|
|
10524
10619
|
__exportStar(__nccwpck_require__(33415), exports);
|
|
@@ -10528,6 +10623,13 @@ const BACKENDS = {
|
|
|
10528
10623
|
gitlab: () => new gitlab_1.GitlabBackend(),
|
|
10529
10624
|
github: () => new github_1.GithubBackend(),
|
|
10530
10625
|
};
|
|
10626
|
+
/**
|
|
10627
|
+
* every pipeline type catladder knows how to generate — regardless of
|
|
10628
|
+
* what the config enables. Cleanup uses this to also reach backends that
|
|
10629
|
+
* were switched off (their files would otherwise linger).
|
|
10630
|
+
*/
|
|
10631
|
+
const getAllPipelineTypes = () => Object.keys(BACKENDS);
|
|
10632
|
+
exports.getAllPipelineTypes = getAllPipelineTypes;
|
|
10531
10633
|
const getPipelineBackend = (type) => {
|
|
10532
10634
|
const createBackend = BACKENDS[type];
|
|
10533
10635
|
if (!createBackend) {
|
|
@@ -10570,7 +10672,7 @@ exports.getVaultConfig = getVaultConfig;
|
|
|
10570
10672
|
const getEnabledPipelineTypes = (config) => {
|
|
10571
10673
|
var _a;
|
|
10572
10674
|
if (config.pipelines) {
|
|
10573
|
-
const enabled =
|
|
10675
|
+
const enabled = (0, exports.getAllPipelineTypes)().filter((type) => { var _a; return (_a = config.pipelines) === null || _a === void 0 ? void 0 : _a[type]; });
|
|
10574
10676
|
if (enabled.length === 0) {
|
|
10575
10677
|
throw new Error("`pipelines` is configured, but no pipeline type is enabled");
|
|
10576
10678
|
}
|
|
@@ -13767,6 +13869,7 @@ exports.RUNNER_IMAGE_BUILD_CONTEXT = {
|
|
|
13767
13869
|
"docker-build": "self",
|
|
13768
13870
|
"semantic-release": "self",
|
|
13769
13871
|
changesets: "self",
|
|
13872
|
+
"npm-publish": "self",
|
|
13770
13873
|
"agent-claude": "self",
|
|
13771
13874
|
};
|
|
13772
13875
|
/**
|
|
@@ -13906,6 +14009,7 @@ class DeployJob extends jobs_1.CatladderJob {
|
|
|
13906
14009
|
artifacts: jobDefinition.artifacts,
|
|
13907
14010
|
services: jobDefinition.services,
|
|
13908
14011
|
pages: jobDefinition.pages,
|
|
14012
|
+
idToken: jobDefinition.idToken,
|
|
13909
14013
|
allow_failure: (_e = jobDefinition.allow_failure) !== null && _e !== void 0 ? _e : deployConfig === null || deployConfig === void 0 ? void 0 : deployConfig.allowFailure,
|
|
13910
14014
|
envMode: "stagePerEnv", // makes it easier to run manual tasks er env
|
|
13911
14015
|
needs: [],
|
|
@@ -16163,7 +16267,12 @@ const createNpmPackageDeployJobs = (context) => {
|
|
|
16163
16267
|
];
|
|
16164
16268
|
return (0, base_1.createDeployementJobs)(context, {
|
|
16165
16269
|
deploy: {
|
|
16166
|
-
image:
|
|
16270
|
+
// dedicated image: publishing needs npm >= 11.5.1 for trusted
|
|
16271
|
+
// publishing (OIDC), which jobs-default's node does not carry
|
|
16272
|
+
image: (0, runner_1.getRunnerImage)("npm-publish"),
|
|
16273
|
+
// github: lowered to `id-token: write` so npm can exchange the
|
|
16274
|
+
// workflow's OIDC token for short-lived publish credentials
|
|
16275
|
+
idToken: true,
|
|
16167
16276
|
script: [
|
|
16168
16277
|
// catci derives version + dist-tag from the pipeline trigger,
|
|
16169
16278
|
// sets the version in package.json and runs npm publish
|
|
@@ -16220,9 +16329,14 @@ const createPagesDeployJobs = async (context) => {
|
|
|
16220
16329
|
// should not happen
|
|
16221
16330
|
throw new Error("deploy config is not pages");
|
|
16222
16331
|
}
|
|
16223
|
-
|
|
16224
|
-
|
|
16225
|
-
|
|
16332
|
+
const onGithub = context.pipelineType === "github";
|
|
16333
|
+
if (onGithub && context.environment.envType === "review") {
|
|
16334
|
+
// github pages serves ONE site per repository and deploy-pages
|
|
16335
|
+
// replaces all of it — there is no path_prefix equivalent, so per-PR
|
|
16336
|
+
// previews cannot exist (deploy-pages has a `preview` input, but it
|
|
16337
|
+
// is alpha and not publicly available). Warn instead of throwing, so
|
|
16338
|
+
// the github generation of a multi-backend project still succeeds.
|
|
16339
|
+
console.warn(`component "${context.name}": github pages cannot host per-merge-request previews (one site per repository) — no review deploy job generated`);
|
|
16226
16340
|
return [];
|
|
16227
16341
|
}
|
|
16228
16342
|
// review environments publish under their own path prefix (gitlab
|
|
@@ -16245,8 +16359,14 @@ const createPagesDeployJobs = async (context) => {
|
|
|
16245
16359
|
: []),
|
|
16246
16360
|
...deployConfig.script,
|
|
16247
16361
|
// the gitlab environment url should point at the published site
|
|
16248
|
-
// (the base deploy job reports $ROOT_URL as environment url)
|
|
16249
|
-
|
|
16362
|
+
// (the base deploy job reports $ROOT_URL as environment url).
|
|
16363
|
+
// On github the url is only known after deploy-pages ran, so the
|
|
16364
|
+
// backend takes it from that step's output instead.
|
|
16365
|
+
...(onGithub
|
|
16366
|
+
? []
|
|
16367
|
+
: [
|
|
16368
|
+
`export ROOT_URL="$CI_PAGES_URL${pathPrefix ? `/${pathPrefix}` : ""}"`,
|
|
16369
|
+
]),
|
|
16250
16370
|
],
|
|
16251
16371
|
variables: {},
|
|
16252
16372
|
runnerVariables: {
|
|
@@ -17235,6 +17355,16 @@ async function generatePipelineFiles(context, pipelineType) {
|
|
|
17235
17355
|
await (0, promises_1.rm)(jobImagesPlan_1.GENERATED_IMAGES_FOLDER, { recursive: true, force: true });
|
|
17236
17356
|
// same for the materialized catci bundle (union across backends)
|
|
17237
17357
|
await (0, promises_1.rm)(shippedCatci_1.GENERATED_CATCI_FOLDER, { recursive: true, force: true });
|
|
17358
|
+
// clean up the backends that are NOT enabled (any more): each
|
|
17359
|
+
// backend only ever removed its own files while it was enabled, so
|
|
17360
|
+
// disabling one in `pipelines` used to leave its pipeline files
|
|
17361
|
+
// behind forever — and a stale `.gitlab-ci.yml` keeps running a
|
|
17362
|
+
// stale pipeline. Only safe on a full generation, where the enabled
|
|
17363
|
+
// set is authoritative.
|
|
17364
|
+
const disabledTypes = (0, backends_1.getAllPipelineTypes)().filter((type) => !pipelineTypes.includes(type));
|
|
17365
|
+
for (const type of disabledTypes) {
|
|
17366
|
+
await (0, backends_1.getPipelineBackend)(type).cleanup();
|
|
17367
|
+
}
|
|
17238
17368
|
// agent skills are backend-independent, materialized once per full
|
|
17239
17369
|
// generation
|
|
17240
17370
|
await (0, agentSkills_1.generateAgentSkills)(context);
|
|
@@ -18199,9 +18329,15 @@ exports.removeUndefined = removeUndefined;
|
|
|
18199
18329
|
"use strict";
|
|
18200
18330
|
|
|
18201
18331
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
18202
|
-
exports.FileWriter = exports.yamlStringifyOptions = void 0;
|
|
18332
|
+
exports.FileWriter = exports.yamlStringifyOptions = exports.GENERATED_FILE_MARKER = void 0;
|
|
18203
18333
|
const promises_1 = __nccwpck_require__(91943);
|
|
18204
18334
|
const yaml_1 = __nccwpck_require__(33483);
|
|
18335
|
+
/**
|
|
18336
|
+
* the line that marks a file as catladder-generated. Cleanup code uses
|
|
18337
|
+
* it to tell a generated file apart from a hand-maintained one at the
|
|
18338
|
+
* same path (e.g. a `.gitlab-ci.yml` a project wrote itself).
|
|
18339
|
+
*/
|
|
18340
|
+
exports.GENERATED_FILE_MARKER = "🐱 🔨 This file is generated by catladder";
|
|
18205
18341
|
exports.yamlStringifyOptions = {
|
|
18206
18342
|
// prevents colapsing long command statements into multiple lines
|
|
18207
18343
|
lineWidth: 0,
|
|
@@ -18261,7 +18397,7 @@ class FileWriter {
|
|
|
18261
18397
|
getAutoGeneratedHeader(commentChar) {
|
|
18262
18398
|
return [
|
|
18263
18399
|
"-------------------------------------------------",
|
|
18264
|
-
|
|
18400
|
+
exports.GENERATED_FILE_MARKER,
|
|
18265
18401
|
`🚨 Do not edit this file manually 🚨`,
|
|
18266
18402
|
"-------------------------------------------------",
|
|
18267
18403
|
]
|
|
@@ -330033,7 +330169,7 @@ if (lodash_default_symIterator) {
|
|
|
330033
330169
|
/***/ ((module) => {
|
|
330034
330170
|
|
|
330035
330171
|
"use strict";
|
|
330036
|
-
module.exports = /*#__PURE__*/JSON.parse('[{"description":"No API keys or secrets are stored in repository","responsibles":1,"more":""},{"description":"The app does not provide password login","responsibles":1,"more":""},{"description":"Passwords are not stored","responsibles":1,"more":""},{"description":"No sensitive information (passwords, keys, user data, ...) is logged or traced","responsibles":1,"more":"
|
|
330172
|
+
module.exports = /*#__PURE__*/JSON.parse('[{"description":"No API keys or secrets are stored in repository","responsibles":1,"more":""},{"description":"The app does not provide password login","responsibles":1,"more":""},{"description":"Passwords are not stored","responsibles":1,"more":""},{"description":"No sensitive information (passwords, keys, user data, ...) is logged or traced","responsibles":1,"more":""},{"description":"Passwords are stored hashed with salt and salt is not stored in the repository","responsibles":1,"more":""},{"description":"Input that ends up in DOM is properly sanitized","responsibles":1,"more":""},{"description":"All user inputs have reasonable validations","responsibles":1,"more":""},{"description":"The app is not using cookies","responsibles":1,"more":""},{"description":"The app is using cookies and cookies are properly configured","responsibles":1,"more":""},{"description":"The app uses JWT with a secret and the secret is not stored in the repository","responsibles":1,"more":""},{"description":"Authorization and user roles (RBAC) were reviewed thoroughly","responsibles":2,"more":""},{"description":"CORS headers do not use `*`","responsibles":1,"more":""},{"description":"CSP headers are properly configured (no `unsafe-inline` or `unsafe-eval`)","responsibles":1,"more":""},{"description":"DoS defense mechanism is implemented","responsibles":1,"more":""},{"description":"YAML/XML parsing is not used or used YAML/XML parsers have disabled DTD","responsibles":1,"more":""},{"description":"The app implements CSRF prevention","responsibles":1,"more":""},{"description":"The app has a rate limitter","responsibles":1,"more":""},{"description":"The app has disabled GraphQL introspection and schema registry","responsibles":1,"more":""},{"description":"The app has set GraphQL complexity query limits","responsibles":1,"more":""},{"description":"`sitemap.xml` does not leak any routes with sensitive data","responsibles":1,"more":""},{"description":"Cloud storage is (private) configured to not leak any sensitive data publicly","responsibles":1,"more":""},{"description":"Security Dashboard checks weekly vulnerable dependencies https://dep.panter.swiss/","responsibles":1,"more":""},{"description":"The app has `.well-known/security.txt` https://securitytxt.org/","responsibles":1,"more":""}]');
|
|
330037
330173
|
|
|
330038
330174
|
/***/ }),
|
|
330039
330175
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# The panter chart
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**The default chart catladder deploys kubernetes components with.**
|
|
4
4
|
|
|
5
5
|
Developing helm charts can be complex and they tend to be very verbose.
|
|
6
6
|
Our goal is therefore to provide a common chart that provides all functionalities that you might need
|
|
@@ -21,4 +21,4 @@ This way we avoid having complexity in the projects and make it easier to share
|
|
|
21
21
|
- support for namespace secrets and custom env-vars (using catladder-shell and gitlab-ci)
|
|
22
22
|
- optional prisam1 (_deprecated, prisma2 does not need a separate instance anymore_)
|
|
23
23
|
|
|
24
|
-
See https://
|
|
24
|
+
See https://github.com/panter/catladder for usage information
|
package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/_helpers.tpl
CHANGED
|
@@ -190,13 +190,3 @@ env:
|
|
|
190
190
|
|
|
191
191
|
|
|
192
192
|
|
|
193
|
-
{{- define "visualReviewSnippet" -}}
|
|
194
|
-
<script
|
|
195
|
-
data-project-id='{{.Values.gitlab.projectId}}'
|
|
196
|
-
data-merge-request-id='{{.Values.gitlab.mergeRequestId}}'
|
|
197
|
-
data-mr-url='https://git.panter.ch'
|
|
198
|
-
data-project-path='{{.Values.gitlab.projectPath}}'
|
|
199
|
-
id='review-app-toolbar-script'
|
|
200
|
-
src='https://git.panter.ch/assets/webpack/visual_review_toolbar.js'>
|
|
201
|
-
</script>
|
|
202
|
-
{{- end -}}
|
|
@@ -16,11 +16,6 @@ metadata:
|
|
|
16
16
|
nginx.ingress.kubernetes.io/rewrite-target: /$1
|
|
17
17
|
nginx.ingress.kubernetes.io/configuration-snippet: |
|
|
18
18
|
more_set_headers "x-build-id: {{ .Values.global.BUILD_ID }}";
|
|
19
|
-
{{- if and .Values.gitlab.visualReviewEnabled (and .Values.global.ENV_SHORT (eq .Values.global.ENV_SHORT "review"))}}
|
|
20
|
-
proxy_set_header Accept-Encoding "";
|
|
21
|
-
sub_filter_once on;
|
|
22
|
-
sub_filter "</head>" "{{- include "visualReviewSnippet" . | nindent 8 -}}</head>";
|
|
23
|
-
{{- end }}
|
|
24
19
|
{{- range $key, $value := .Values.ingress.annotations }}
|
|
25
20
|
{{ $key }}: {{ $value | quote }}
|
|
26
21
|
{{- end }}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
FROM node:lts-alpine
|
|
2
|
+
|
|
3
|
+
RUN apk add --no-cache bash git
|
|
4
|
+
|
|
5
|
+
# npm trusted publishing (OIDC) needs npm >= 11.5.1; the npm bundled
|
|
6
|
+
# with the node image is not guaranteed to be new enough, so pin the
|
|
7
|
+
# major explicitly. Without it npm silently falls back to token auth.
|
|
8
|
+
RUN npm install -g npm@11
|
|
9
|
+
|
|
10
|
+
# no publish logic baked in: it lives in catci, which pipeline
|
|
11
|
+
# generation materializes into the repository checkout
|
|
12
|
+
# (.catladder-generated/catci)
|
|
@@ -45,10 +45,11 @@ if [ "$GITHUB_ACTIONS" = "true" ]; then
|
|
|
45
45
|
# is gitlab-specific)
|
|
46
46
|
PUBLISH_PLUGIN=""
|
|
47
47
|
else
|
|
48
|
+
# no gitlabUrl: the plugin derives it from the CI-provided variables
|
|
49
|
+
# of the running instance. It used to be hardcoded to panter's gitlab,
|
|
50
|
+
# which broke the release on every other instance.
|
|
48
51
|
PUBLISH_PLUGIN=',
|
|
49
|
-
|
|
50
|
-
"gitlabUrl": "https://git.panter.ch"
|
|
51
|
-
}]'
|
|
52
|
+
"@semantic-release/gitlab"'
|
|
52
53
|
fi
|
|
53
54
|
|
|
54
55
|
if [ ! -e .releaserc ]; then
|
|
@@ -103,7 +103,7 @@ first.
|
|
|
103
103
|
a dev needs `customJobs` or a transform hook, it almost always means
|
|
104
104
|
catladder is missing a capability that other projects will need too.
|
|
105
105
|
**Open an issue at
|
|
106
|
-
https://
|
|
106
|
+
https://github.com/panter/catladder/issues** describing the use
|
|
107
107
|
case (what you're trying to achieve and why the existing config can't
|
|
108
108
|
express it) so it can be generalized into a supported feature — and,
|
|
109
109
|
where possible, offer to help the dev write that issue. The goal is for
|
|
@@ -54,11 +54,12 @@ resources with `yarn catladder project setup`; detect drift with
|
|
|
54
54
|
- `registry?: string` — registry url, default `https://registry.npmjs.org/`.
|
|
55
55
|
- `distTag?: string` — overrides the derived dist-tag.
|
|
56
56
|
- Version/dist-tag derivation: tagged release (`prod`) → tag version under `latest`; branch/MR → `0.0.0-<branch-slug>-<sha>` under `canary` (branches `next`/`beta` publish under their own dist-tag).
|
|
57
|
-
-
|
|
57
|
+
- Auth: the `NPM_TOKEN` secret (managed like any catladder secret), or — on github — **trusted publishing** with no stored token: register the package's trusted publisher on npmjs.com with the repo and the publishing **workflow filename** (`catladder-release.yml` for tagged releases). npm allows one trusted publisher per package, so canary publishes from the main/review workflows still need `NPM_TOKEN`. A set token always wins over OIDC.
|
|
58
|
+
- Disable staging on the component (`env: { stage: false }`) so tagged releases publish directly.
|
|
58
59
|
|
|
59
60
|
## `pages`
|
|
60
61
|
|
|
61
|
-
- `type: "pages"` — **required**. Publishes a static site on gitlab pages
|
|
62
|
+
- `type: "pages"` — **required**. Publishes a static site on gitlab pages or github pages. On github the repo's Pages source must be set to "GitHub Actions" once; per-merge-request previews are gitlab-only (github serves one site per repository).
|
|
62
63
|
- `script: string[]` — **required**; produces the site.
|
|
63
64
|
- `publishDir?: string` — output directory relative to the repo root, default `"public"`.
|
|
64
65
|
- `requiresInstall?: boolean` — run the package-manager install (yarn/pnpm) first (`requiresYarnInstall` is a deprecated alias).
|