@catladder/cli 0.0.0-fix-changeset-hint-package-manager-20002c27 → 0.0.0-fix-github-gating-release-push-fbb576dc
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/apps/cli/src/apps/cli/commands/project/doctor/checkGithub.js +31 -9
- package/dist/apps/cli/src/apps/cli/commands/project/doctor/checkGithub.js.map +1 -1
- package/dist/apps/cli/src/apps/cli/commands/project/githubMergeGating.d.ts +70 -0
- package/dist/apps/cli/src/apps/cli/commands/project/githubMergeGating.js +71 -0
- package/dist/apps/cli/src/apps/cli/commands/project/githubMergeGating.js.map +1 -0
- package/dist/apps/cli/src/apps/cli/commands/project/setup/setupGithub.d.ts +9 -7
- package/dist/apps/cli/src/apps/cli/commands/project/setup/setupGithub.js +77 -31
- package/dist/apps/cli/src/apps/cli/commands/project/setup/setupGithub.js.map +1 -1
- package/dist/apps/cli/src/release/changesetsReleaseJob.js +19 -1
- package/dist/apps/cli/src/release/changesetsReleaseJob.js.map +1 -1
- package/dist/apps/cli/src/utils/github.d.ts +1 -1
- package/dist/apps/cli/src/utils/github.js.map +1 -1
- package/dist/bundles/catci/index.js +1 -1
- package/dist/bundles/catenv/index.js +200 -8
- package/dist/bundles/cli/index.js +386 -48
- package/dist/bundles/skills/catladder-deploys/references/deploy-types.md +1 -0
- package/dist/bundles/skills/catladder-migrate-ci-backend/SKILL.md +11 -7
- package/dist/packages/pipeline/src/deploy/cloudRun/index.js +6 -1
- package/dist/packages/pipeline/src/deploy/cloudRun/index.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/cloudRun/utils/getServiceName.d.ts +68 -0
- package/dist/packages/pipeline/src/deploy/cloudRun/utils/getServiceName.js +184 -3
- package/dist/packages/pipeline/src/deploy/cloudRun/utils/getServiceName.js.map +1 -1
- package/dist/packages/pipeline/src/store/index.d.ts +8 -0
- package/dist/packages/pipeline/src/store/index.js +9 -3
- package/dist/packages/pipeline/src/store/index.js.map +1 -1
- package/dist/skills/catladder-deploys/references/deploy-types.md +1 -0
- package/dist/skills/catladder-migrate-ci-backend/SKILL.md +11 -7
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/apps/cli/commands/project/__tests__/githubMergeGating.test.ts +112 -0
- package/src/apps/cli/commands/project/doctor/checkGithub.ts +44 -8
- package/src/apps/cli/commands/project/githubMergeGating.ts +90 -0
- package/src/apps/cli/commands/project/setup/setupGithub.ts +105 -26
- package/src/release/changesetsReleaseJob.ts +19 -1
- package/src/utils/github.ts +1 -1
|
@@ -9632,9 +9632,14 @@ exports.GCLOUD_RUN_DEPLOY_TYPE = {
|
|
|
9632
9632
|
// generation time. For review envs the service name part still
|
|
9633
9633
|
// contains a runtime expression (the review slug), so the host stays
|
|
9634
9634
|
// a bash expression there; the suffix is always a literal.
|
|
9635
|
+
//
|
|
9636
|
+
// The service name has to come from getRawServiceNameForEnvContext,
|
|
9637
|
+
// not from fullName: it is shortened when the label would otherwise
|
|
9638
|
+
// exceed what cloud run serves deterministically, and the url must
|
|
9639
|
+
// name the service that is actually deployed.
|
|
9635
9640
|
const HOSTNAME_INTERNAL = deployConfigRaw && envType !== "local"
|
|
9636
9641
|
? (0, bash_1.joinBashExpressions)([
|
|
9637
|
-
|
|
9642
|
+
(0, getServiceName_1.getRawServiceNameForEnvContext)(ctx),
|
|
9638
9643
|
`${(0, store_1.getGcloudProjectNumber)(fullConfig, deployConfigRaw.projectId)}.${deployConfigRaw.region}.run.app`,
|
|
9639
9644
|
], "-").toLowerCase()
|
|
9640
9645
|
: undefined;
|
|
@@ -9896,16 +9901,197 @@ exports.getCloudRunServiceOrJobArgsArg = getCloudRunServiceOrJobArgsArg;
|
|
|
9896
9901
|
/***/ }),
|
|
9897
9902
|
|
|
9898
9903
|
/***/ 33102:
|
|
9899
|
-
/***/ ((__unused_webpack_module, exports) => {
|
|
9904
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
9900
9905
|
|
|
9901
9906
|
"use strict";
|
|
9902
9907
|
|
|
9903
9908
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
9904
|
-
exports.getServiceNameForEnvContext = exports.getServiceName = void 0;
|
|
9905
|
-
const
|
|
9909
|
+
exports.getRawServiceNameForEnvContext = exports.getServiceNameForEnvContext = exports.getServiceName = exports.resolveCloudRunComponentPart = exports.REVIEW_SLUG_LENGTH_BUDGET = exports.CLOUD_RUN_DNS_SEGMENT_LIMIT = void 0;
|
|
9910
|
+
const bash_1 = __nccwpck_require__(94143);
|
|
9911
|
+
const store_1 = __nccwpck_require__(2789);
|
|
9912
|
+
/**
|
|
9913
|
+
* cloud run only serves its deterministic url
|
|
9914
|
+
* `https://<service>-<projectNumber>.<region>.run.app` while that first dns
|
|
9915
|
+
* label stays within the 63 characters a dns label allows — the label holds
|
|
9916
|
+
* the service name, the project number and any traffic tag together.
|
|
9917
|
+
*
|
|
9918
|
+
* Beyond it cloud run silently switches to a legacy url built from a random
|
|
9919
|
+
* identifier that nothing can recompute. The url catladder generates would
|
|
9920
|
+
* then be a hostname that can never resolve, and everything consuming
|
|
9921
|
+
* ROOT_URL/ROOT_URL_INTERNAL (cloud tasks targets, service-to-service
|
|
9922
|
+
* calls) fails with a dns error instead of a helpful one — which is why the
|
|
9923
|
+
* component part is shortened to stay under the limit rather than left to
|
|
9924
|
+
* overflow.
|
|
9925
|
+
*
|
|
9926
|
+
* https://cloud.google.com/run/docs/triggering/https-request
|
|
9927
|
+
*/
|
|
9928
|
+
exports.CLOUD_RUN_DNS_SEGMENT_LIMIT = 63;
|
|
9929
|
+
/**
|
|
9930
|
+
* review environments resolve their slug at runtime (`mr<iid>` on gitlab,
|
|
9931
|
+
* `pr<number>` on github), so its exact length is unknown while generating.
|
|
9932
|
+
* Budget for a six digit number so that service names — and with them the
|
|
9933
|
+
* urls of already deployed services — do not start changing years later
|
|
9934
|
+
* just because a project's merge request numbers grew a digit.
|
|
9935
|
+
*/
|
|
9936
|
+
exports.REVIEW_SLUG_LENGTH_BUDGET = "mr123456".length;
|
|
9937
|
+
/**
|
|
9938
|
+
* a service name shortened past this point is no longer recognizable. When
|
|
9939
|
+
* even this does not fit, the fixed parts (customer name, app name, env,
|
|
9940
|
+
* project number) are what needs to shrink — only the user can do that.
|
|
9941
|
+
*/
|
|
9942
|
+
const MIN_COMPONENT_PART_LENGTH = 6;
|
|
9943
|
+
const quote = (name) => `"${name}"`;
|
|
9944
|
+
/**
|
|
9945
|
+
* a trailing dash would end up in the hostname as `...-foo-.run.app`
|
|
9946
|
+
*/
|
|
9947
|
+
const shortenTo = (name, maxLength) => name.slice(0, maxLength).replace(/-+$/, "");
|
|
9948
|
+
/**
|
|
9949
|
+
* the component-name part of a cloud run service name, shortened just
|
|
9950
|
+
* enough to keep the deterministic url resolvable.
|
|
9951
|
+
*
|
|
9952
|
+
* Only the component part is shortened: the env and review slug parts have
|
|
9953
|
+
* to stay intact (they are what makes the name unique per environment), the
|
|
9954
|
+
* project number is fixed, and customerName/appName are shared by every
|
|
9955
|
+
* service of the project.
|
|
9956
|
+
*/
|
|
9957
|
+
const resolveCloudRunComponentPart = ({ customerName, appName, env, isReviewEnv, componentName, projectNumber, otherComponentNames, }) => {
|
|
9958
|
+
const fixedParts = [
|
|
9959
|
+
customerName,
|
|
9960
|
+
appName,
|
|
9961
|
+
env,
|
|
9962
|
+
...(isReviewEnv ? ["_".repeat(exports.REVIEW_SLUG_LENGTH_BUDGET)] : []),
|
|
9963
|
+
projectNumber,
|
|
9964
|
+
];
|
|
9965
|
+
// + 1 for the dash that joins the component part to the rest
|
|
9966
|
+
const fixedLength = fixedParts.join("-").length + 1;
|
|
9967
|
+
const available = exports.CLOUD_RUN_DNS_SEGMENT_LIMIT - fixedLength;
|
|
9968
|
+
if (componentName.length <= available) {
|
|
9969
|
+
return {
|
|
9970
|
+
value: componentName,
|
|
9971
|
+
dropped: 0,
|
|
9972
|
+
dnsSegmentLength: fixedLength + componentName.length,
|
|
9973
|
+
};
|
|
9974
|
+
}
|
|
9975
|
+
if (available < MIN_COMPONENT_PART_LENGTH) {
|
|
9976
|
+
throw new Error(`Cannot build a resolvable cloud run url for component ${quote(componentName)} in env ${quote(env)}.\n` +
|
|
9977
|
+
`Everything but the component name already takes ${fixedLength} of the ${exports.CLOUD_RUN_DNS_SEGMENT_LIMIT} characters ` +
|
|
9978
|
+
`a dns label allows (${fixedParts.join("-")}-<component>), leaving only ${available} for the component name.\n` +
|
|
9979
|
+
`Shorten appName (${quote(appName)}) or customerName (${quote(customerName)}) by at least ` +
|
|
9980
|
+
`${MIN_COMPONENT_PART_LENGTH - available} character(s).` +
|
|
9981
|
+
(isReviewEnv
|
|
9982
|
+
? `\nReview environments also carry a runtime slug, for which ${exports.REVIEW_SLUG_LENGTH_BUDGET} characters are reserved.`
|
|
9983
|
+
: ""));
|
|
9984
|
+
}
|
|
9985
|
+
const value = shortenTo(componentName, available);
|
|
9986
|
+
const colliding = otherComponentNames.filter((other) => shortenTo(other, available) === value);
|
|
9987
|
+
if (colliding.length > 0) {
|
|
9988
|
+
throw new Error(`Cloud run service names collide in env ${quote(env)}: ${quote(componentName)} and ` +
|
|
9989
|
+
`${colliding.map(quote).join(", ")} all shorten to ${quote(value)}, so they would deploy over each other.\n` +
|
|
9990
|
+
`The deterministic cloud run url allows ${exports.CLOUD_RUN_DNS_SEGMENT_LIMIT} characters, which leaves ${available} ` +
|
|
9991
|
+
`for the component name here — rename the components so their first ${available} characters differ.`);
|
|
9992
|
+
}
|
|
9993
|
+
return {
|
|
9994
|
+
value,
|
|
9995
|
+
dropped: componentName.length - value.length,
|
|
9996
|
+
dnsSegmentLength: fixedLength + value.length,
|
|
9997
|
+
};
|
|
9998
|
+
};
|
|
9999
|
+
exports.resolveCloudRunComponentPart = resolveCloudRunComponentPart;
|
|
10000
|
+
/**
|
|
10001
|
+
* one note per shortened service name instead of one per generated job:
|
|
10002
|
+
* service names are resolved again for every job that references them
|
|
10003
|
+
*/
|
|
10004
|
+
const reportedTruncations = new Set();
|
|
10005
|
+
const reportTruncation = (env, componentName, { value, dnsSegmentLength }) => {
|
|
10006
|
+
const key = `${env}/${componentName}`;
|
|
10007
|
+
if (reportedTruncations.has(key)) {
|
|
10008
|
+
return;
|
|
10009
|
+
}
|
|
10010
|
+
reportedTruncations.add(key);
|
|
10011
|
+
console.warn(`ℹ️ component "${componentName}" deploys to cloud run as "...-${value}" in env "${env}": ` +
|
|
10012
|
+
`the full name would push the url past the ${exports.CLOUD_RUN_DNS_SEGMENT_LIMIT} characters cloud run ` +
|
|
10013
|
+
`serves deterministically, so the component part is shortened ` +
|
|
10014
|
+
`(${dnsSegmentLength} of ${exports.CLOUD_RUN_DNS_SEGMENT_LIMIT} characters used).`);
|
|
10015
|
+
};
|
|
10016
|
+
/**
|
|
10017
|
+
* the cloud run service name before lowercasing, so that callers keep
|
|
10018
|
+
* lowercasing the whole expression exactly like they did before.
|
|
10019
|
+
*
|
|
10020
|
+
* Returns `fullName` unchanged unless the component part had to be
|
|
10021
|
+
* shortened — every project whose url already fits generates byte-identical
|
|
10022
|
+
* output.
|
|
10023
|
+
*
|
|
10024
|
+
* Note that the composition below has to match the one `fullName` is built
|
|
10025
|
+
* from in getEnvironmentContext; the tests pin that they agree.
|
|
10026
|
+
*/
|
|
10027
|
+
const getRawServiceName = ({ fullName, environmentSlugPrefix, componentName, env, isReviewEnv, deployConfig, config, }) => {
|
|
10028
|
+
const projectNumber = deployConfig
|
|
10029
|
+
? (0, store_1.readGcloudProjectNumber)(config, deployConfig.projectId)
|
|
10030
|
+
: null;
|
|
10031
|
+
if (!projectNumber) {
|
|
10032
|
+
// without the project number there is no deterministic url to keep
|
|
10033
|
+
// resolvable — generating the url itself fails with a store error that
|
|
10034
|
+
// says how to fix it, so don't second-guess the name here
|
|
10035
|
+
return fullName;
|
|
10036
|
+
}
|
|
10037
|
+
const componentPart = (0, exports.resolveCloudRunComponentPart)({
|
|
10038
|
+
customerName: config.customerName,
|
|
10039
|
+
appName: config.appName,
|
|
10040
|
+
env,
|
|
10041
|
+
isReviewEnv,
|
|
10042
|
+
componentName,
|
|
10043
|
+
projectNumber,
|
|
10044
|
+
otherComponentNames: Object.keys(config.components).filter((name) => name !== componentName),
|
|
10045
|
+
});
|
|
10046
|
+
if (componentPart.dropped === 0) {
|
|
10047
|
+
return fullName;
|
|
10048
|
+
}
|
|
10049
|
+
reportTruncation(env, componentName, componentPart);
|
|
10050
|
+
return (0, bash_1.joinBashExpressions)([
|
|
10051
|
+
config.customerName,
|
|
10052
|
+
config.appName,
|
|
10053
|
+
environmentSlugPrefix,
|
|
10054
|
+
componentPart.value,
|
|
10055
|
+
], "-");
|
|
10056
|
+
};
|
|
10057
|
+
const fromComponentContext = (context) => {
|
|
10058
|
+
var _a;
|
|
10059
|
+
const deployConfig = (_a = context.deploy) === null || _a === void 0 ? void 0 : _a.config;
|
|
10060
|
+
return {
|
|
10061
|
+
fullName: context.environment.fullName,
|
|
10062
|
+
environmentSlugPrefix: context.environment.slugPrefix,
|
|
10063
|
+
componentName: context.name,
|
|
10064
|
+
env: context.env,
|
|
10065
|
+
isReviewEnv: context.environment.envType === "review",
|
|
10066
|
+
deployConfig: deployConfig && deployConfig.type === "google-cloudrun"
|
|
10067
|
+
? deployConfig
|
|
10068
|
+
: null,
|
|
10069
|
+
config: context.fullConfig,
|
|
10070
|
+
};
|
|
10071
|
+
};
|
|
10072
|
+
const fromEnvironmentContext = (context) => ({
|
|
10073
|
+
fullName: context.fullName,
|
|
10074
|
+
environmentSlugPrefix: context.environmentSlugPrefix,
|
|
10075
|
+
componentName: context.componentName,
|
|
10076
|
+
env: context.env,
|
|
10077
|
+
isReviewEnv: context.envType === "review",
|
|
10078
|
+
deployConfig: context.deployConfigRaw || null,
|
|
10079
|
+
config: context.fullConfig,
|
|
10080
|
+
});
|
|
10081
|
+
/**
|
|
10082
|
+
* the cloud run service name as it is passed to `gcloud run` — lowercased,
|
|
10083
|
+
* and shortened when the deterministic url would otherwise not fit.
|
|
10084
|
+
*/
|
|
10085
|
+
const getServiceName = (context) => getRawServiceName(fromComponentContext(context)).toLowerCase();
|
|
9906
10086
|
exports.getServiceName = getServiceName;
|
|
9907
|
-
const getServiceNameForEnvContext = (context) => context.
|
|
10087
|
+
const getServiceNameForEnvContext = (context) => getRawServiceName(fromEnvironmentContext(context)).toLowerCase();
|
|
9908
10088
|
exports.getServiceNameForEnvContext = getServiceNameForEnvContext;
|
|
10089
|
+
/**
|
|
10090
|
+
* the service name part of the deterministic url, still to be lowercased
|
|
10091
|
+
* together with the rest of the hostname by the caller.
|
|
10092
|
+
*/
|
|
10093
|
+
const getRawServiceNameForEnvContext = (context) => getRawServiceName(fromEnvironmentContext(context));
|
|
10094
|
+
exports.getRawServiceNameForEnvContext = getRawServiceNameForEnvContext;
|
|
9909
10095
|
//# sourceMappingURL=getServiceName.js.map
|
|
9910
10096
|
|
|
9911
10097
|
/***/ }),
|
|
@@ -12322,7 +12508,7 @@ exports.getRunnerImage = getRunnerImage;
|
|
|
12322
12508
|
"use strict";
|
|
12323
12509
|
|
|
12324
12510
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
12325
|
-
exports.getGcloudProjectNumber = exports.readCatladderStore = exports.getCatladderStorePath = exports.catladderStoreSchema = exports.CATLADDER_STORE_FILE = exports.CATLADDER_STORE_FILE_NAME = exports.CATLADDER_STORE_DIR = void 0;
|
|
12511
|
+
exports.getGcloudProjectNumber = exports.readGcloudProjectNumber = exports.readCatladderStore = exports.getCatladderStorePath = exports.catladderStoreSchema = exports.CATLADDER_STORE_FILE = exports.CATLADDER_STORE_FILE_NAME = exports.CATLADDER_STORE_DIR = void 0;
|
|
12326
12512
|
const fs_1 = __nccwpck_require__(79896);
|
|
12327
12513
|
const path_1 = __nccwpck_require__(16928);
|
|
12328
12514
|
const yaml_1 = __nccwpck_require__(99292);
|
|
@@ -12374,6 +12560,13 @@ const readCatladderStore = (directory = process.cwd()) => {
|
|
|
12374
12560
|
}
|
|
12375
12561
|
};
|
|
12376
12562
|
exports.readCatladderStore = readCatladderStore;
|
|
12563
|
+
/**
|
|
12564
|
+
* gcloud project number from the store, or null when it has not been
|
|
12565
|
+
* fetched yet. Use this where a missing number is not itself the problem —
|
|
12566
|
+
* `getGcloudProjectNumber` is the one that reports it.
|
|
12567
|
+
*/
|
|
12568
|
+
const readGcloudProjectNumber = (config, projectId) => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = config.store) === null || _a === void 0 ? void 0 : _a.gcloudProjects) === null || _b === void 0 ? void 0 : _b[projectId]) === null || _c === void 0 ? void 0 : _c.projectNumber) !== null && _d !== void 0 ? _d : null; };
|
|
12569
|
+
exports.readGcloudProjectNumber = readGcloudProjectNumber;
|
|
12377
12570
|
/**
|
|
12378
12571
|
* gcloud project number from the store — needed to compute deterministic
|
|
12379
12572
|
* cloud run urls (`<service>-<projectNumber>.<region>.run.app`) at
|
|
@@ -12383,8 +12576,7 @@ exports.readCatladderStore = readCatladderStore;
|
|
|
12383
12576
|
* catenv fail until `catladder project setup` has stored it.
|
|
12384
12577
|
*/
|
|
12385
12578
|
const getGcloudProjectNumber = (config, projectId) => {
|
|
12386
|
-
|
|
12387
|
-
const projectNumber = (_c = (_b = (_a = config.store) === null || _a === void 0 ? void 0 : _a.gcloudProjects) === null || _b === void 0 ? void 0 : _b[projectId]) === null || _c === void 0 ? void 0 : _c.projectNumber;
|
|
12579
|
+
const projectNumber = (0, exports.readGcloudProjectNumber)(config, projectId);
|
|
12388
12580
|
if (!projectNumber) {
|
|
12389
12581
|
throw new Error(`Missing gcloud project number for project "${projectId}" in ${exports.CATLADDER_STORE_FILE}.\n` +
|
|
12390
12582
|
`Run "catladder project setup" to fetch and store it.`);
|