@intentius/sql-yodeler 0.3.0 → 0.5.0
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/README.md +2 -2
- package/dist/apply-steps/index.d.ts +65 -0
- package/dist/apply-steps/index.js +106 -0
- package/dist/apply-steps/index.js.map +1 -0
- package/dist/approval-mode/index.d.ts +78 -0
- package/dist/approval-mode/index.js +105 -0
- package/dist/approval-mode/index.js.map +1 -0
- package/dist/chant/access.d.ts +84 -0
- package/dist/chant/access.js +155 -0
- package/dist/chant/access.js.map +1 -0
- package/dist/chant/drift.d.ts +17 -1
- package/dist/chant/drift.js +55 -2
- package/dist/chant/drift.js.map +1 -1
- package/dist/chant/plan.d.ts +18 -2
- package/dist/chant/plan.js +21 -3
- package/dist/chant/plan.js.map +1 -1
- package/dist/ci/login.d.ts +78 -0
- package/dist/ci/login.js +199 -0
- package/dist/ci/login.js.map +1 -0
- package/dist/ci/render.d.ts +64 -10
- package/dist/ci/render.js +385 -88
- package/dist/ci/render.js.map +1 -1
- package/dist/cleanup/index.d.ts +92 -0
- package/dist/cleanup/index.js +213 -0
- package/dist/cleanup/index.js.map +1 -0
- package/dist/commands/apply.js +178 -20
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/approve.d.ts +13 -0
- package/dist/commands/approve.js +206 -24
- package/dist/commands/approve.js.map +1 -1
- package/dist/commands/ci.js +12 -0
- package/dist/commands/ci.js.map +1 -1
- package/dist/commands/cleanup.d.ts +13 -0
- package/dist/commands/cleanup.js +158 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.js +136 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/drift.js +33 -3
- package/dist/commands/drift.js.map +1 -1
- package/dist/commands/index.js +6 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.js +98 -10
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/lint.js +67 -10
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/new.js +135 -54
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/plan.js +39 -5
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.js +164 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/config/define.d.ts +175 -2
- package/dist/config/define.js +2 -0
- package/dist/config/define.js.map +1 -1
- package/dist/config/load.js +78 -10
- package/dist/config/load.js.map +1 -1
- package/dist/config/settings.d.ts +20 -0
- package/dist/config/settings.js +28 -0
- package/dist/config/settings.js.map +1 -1
- package/dist/credentials.d.ts +119 -0
- package/dist/credentials.js +119 -0
- package/dist/credentials.js.map +1 -0
- package/dist/exit.js +1 -1
- package/dist/exit.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/init/adopt.js +1 -1
- package/dist/init/adopt.js.map +1 -1
- package/dist/init/clickhouse-access.d.ts +64 -0
- package/dist/init/clickhouse-access.js +211 -0
- package/dist/init/clickhouse-access.js.map +1 -0
- package/dist/init/index.d.ts +2 -0
- package/dist/init/index.js +2 -0
- package/dist/init/index.js.map +1 -1
- package/dist/init/live.d.ts +4 -0
- package/dist/init/live.js +16 -0
- package/dist/init/live.js.map +1 -1
- package/dist/init/second.d.ts +70 -0
- package/dist/init/second.js +149 -0
- package/dist/init/second.js.map +1 -0
- package/dist/lint/access.d.ts +18 -0
- package/dist/lint/access.js +34 -0
- package/dist/lint/access.js.map +1 -0
- package/dist/lint/annotations.d.ts +49 -0
- package/dist/lint/annotations.js +82 -0
- package/dist/lint/annotations.js.map +1 -0
- package/dist/lint/check.js +25 -7
- package/dist/lint/check.js.map +1 -1
- package/dist/lint/config.d.ts +7 -1
- package/dist/lint/config.js +11 -5
- package/dist/lint/config.js.map +1 -1
- package/dist/lint/index.d.ts +4 -0
- package/dist/lint/index.js +4 -0
- package/dist/lint/index.js.map +1 -1
- package/dist/lint/naming.d.ts +62 -0
- package/dist/lint/naming.js +138 -0
- package/dist/lint/naming.js.map +1 -0
- package/dist/lint/rules.d.ts +37 -4
- package/dist/lint/rules.js +16 -4
- package/dist/lint/rules.js.map +1 -1
- package/dist/lint/schema-checks.d.ts +63 -0
- package/dist/lint/schema-checks.js +128 -0
- package/dist/lint/schema-checks.js.map +1 -0
- package/dist/lint/statements.d.ts +22 -1
- package/dist/lint/statements.js +40 -1
- package/dist/lint/statements.js.map +1 -1
- package/dist/mcp/tools.d.ts +1 -1
- package/dist/mcp/tools.js +1 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/migrations/checkpoint.js +0 -2
- package/dist/migrations/checkpoint.js.map +1 -1
- package/dist/migrations/checks.d.ts +19 -1
- package/dist/migrations/checks.js +15 -0
- package/dist/migrations/checks.js.map +1 -1
- package/dist/migrations/create.d.ts +13 -4
- package/dist/migrations/create.js +24 -9
- package/dist/migrations/create.js.map +1 -1
- package/dist/migrations/routines.d.ts +5 -15
- package/dist/migrations/routines.js +5 -30
- package/dist/migrations/routines.js.map +1 -1
- package/dist/pr/model.d.ts +4 -1
- package/dist/pr/model.js +13 -5
- package/dist/pr/model.js.map +1 -1
- package/dist/pr/render.d.ts +4 -1
- package/dist/pr/render.js +22 -8
- package/dist/pr/render.js.map +1 -1
- package/dist/pr/tenants.d.ts +37 -0
- package/dist/pr/tenants.js +138 -0
- package/dist/pr/tenants.js.map +1 -0
- package/dist/probe.d.ts +27 -0
- package/dist/probe.js +106 -0
- package/dist/probe.js.map +1 -0
- package/dist/project.d.ts +16 -0
- package/dist/project.js +29 -1
- package/dist/project.js.map +1 -1
- package/dist/replay/clickhouse.d.ts +31 -0
- package/dist/replay/clickhouse.js +103 -6
- package/dist/replay/clickhouse.js.map +1 -1
- package/dist/replay/replay.d.ts +5 -2
- package/dist/replay/replay.js.map +1 -1
- package/dist/report/audit.d.ts +1 -1
- package/dist/report/audit.js +20 -3
- package/dist/report/audit.js.map +1 -1
- package/dist/schemas.d.ts +3 -1
- package/dist/schemas.js +2 -0
- package/dist/schemas.js.map +1 -1
- package/dist/sources/ddl.d.ts +15 -20
- package/dist/sources/ddl.js +34 -328
- package/dist/sources/ddl.js.map +1 -1
- package/dist/sources/index.js +2 -2
- package/dist/sources/index.js.map +1 -1
- package/dist/steps/backfill.d.ts +40 -5
- package/dist/steps/backfill.js +128 -8
- package/dist/steps/backfill.js.map +1 -1
- package/dist/steps/index.d.ts +19 -1
- package/dist/steps/index.js +34 -7
- package/dist/steps/index.js.map +1 -1
- package/dist/steps/kinds.d.ts +42 -4
- package/dist/steps/kinds.js +88 -14
- package/dist/steps/kinds.js.map +1 -1
- package/dist/steps/postgres-migration.d.ts +3 -0
- package/dist/steps/postgres-migration.js +7 -3
- package/dist/steps/postgres-migration.js.map +1 -1
- package/dist/steps/rebuild.d.ts +15 -6
- package/dist/steps/rebuild.js +12 -9
- package/dist/steps/rebuild.js.map +1 -1
- package/dist/tenants/index.d.ts +2 -1
- package/dist/tenants/index.js +3 -4
- package/dist/tenants/index.js.map +1 -1
- package/dist/tenants/wave.d.ts +128 -0
- package/dist/tenants/wave.js +254 -0
- package/dist/tenants/wave.js.map +1 -0
- package/dist/testing/define.d.ts +62 -0
- package/dist/testing/define.js +32 -0
- package/dist/testing/define.js.map +1 -0
- package/dist/testing/files.d.ts +5 -0
- package/dist/testing/files.js +18 -0
- package/dist/testing/files.js.map +1 -0
- package/dist/testing/report.d.ts +14 -0
- package/dist/testing/report.js +83 -0
- package/dist/testing/report.js.map +1 -0
- package/dist/testing/run.d.ts +104 -0
- package/dist/testing/run.js +328 -0
- package/dist/testing/run.js.map +1 -0
- package/dist/versioned/approval.d.ts +6 -0
- package/dist/versioned/approval.js +11 -5
- package/dist/versioned/approval.js.map +1 -1
- package/dist/versioned/checks.d.ts +8 -2
- package/dist/versioned/checks.js +34 -13
- package/dist/versioned/checks.js.map +1 -1
- package/dist/versioned/driver.d.ts +2 -2
- package/dist/versioned/engine.d.ts +10 -0
- package/dist/versioned/engine.js +8 -4
- package/dist/versioned/engine.js.map +1 -1
- package/dist/versioned/explain.d.ts +2 -0
- package/dist/versioned/explain.js +3 -1
- package/dist/versioned/explain.js.map +1 -1
- package/dist/versioned/op.d.ts +4 -0
- package/dist/versioned/op.js +5 -2
- package/dist/versioned/op.js.map +1 -1
- package/dist/versioned/state.js +1 -1
- package/dist/versioned/state.js.map +1 -1
- package/dist/waves/index.d.ts +58 -13
- package/dist/waves/index.js +109 -24
- package/dist/waves/index.js.map +1 -1
- package/dist/waves/record.d.ts +10 -0
- package/dist/waves/record.js.map +1 -1
- package/package.json +8 -7
- package/schemas/apply.schema.json +1 -1
- package/schemas/cleanup.schema.json +40 -0
- package/schemas/init.schema.json +51 -22
- package/schemas/lint-rules.schema.json +4 -0
- package/schemas/new.schema.json +41 -3
- package/schemas/plan.schema.json +39 -0
- package/schemas/report.schema.json +1 -1
- package/schemas/test.schema.json +41 -0
package/dist/ci/login.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cloud login a CI job runs before yodel (#132), when a role it holds
|
|
3
|
+
* has a password minted by a cloud token source: the job's OIDC token,
|
|
4
|
+
* exchanged by the cloud's own command line, which then mints the database
|
|
5
|
+
* token (`aws rds generate-db-auth-token`, `gcloud sql generate-login-token`,
|
|
6
|
+
* `az account get-access-token`). yodel.config.ts `ci.login` says what to
|
|
7
|
+
* log in as ({@link CiLogin}); this renders the steps per forge. Nothing
|
|
8
|
+
* here calls a cloud: the rendered job does, when it runs.
|
|
9
|
+
*
|
|
10
|
+
* The token, per forge:
|
|
11
|
+
* - GitHub: the job requests it for the cloud's audience
|
|
12
|
+
* (ACTIONS_ID_TOKEN_REQUEST_URL, granted by `id-token: write`) and writes
|
|
13
|
+
* it to the token file.
|
|
14
|
+
* - GitLab: the job's `id_tokens` variable (AWS_ID_TOKEN, GCP_ID_TOKEN,
|
|
15
|
+
* AZURE_ID_TOKEN) is written to the token file.
|
|
16
|
+
* - Forgejo gives a job no OIDC token: a login is rendered only when the
|
|
17
|
+
* config's `tokenFile` names a token the runner provides.
|
|
18
|
+
*
|
|
19
|
+
* The login, per cloud, from the token file:
|
|
20
|
+
* - aws: AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_SESSION_NAME,
|
|
21
|
+
* which the aws command line assumes the role with.
|
|
22
|
+
* - gcp: an external_account credential configuration over the token file
|
|
23
|
+
* (the workload identity provider, impersonating the service account),
|
|
24
|
+
* `gcloud auth login --cred-file` with it, and GOOGLE_APPLICATION_CREDENTIALS.
|
|
25
|
+
* - azure: `az login --service-principal --federated-token`, and
|
|
26
|
+
* AZURE_CLIENT_ID, AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE.
|
|
27
|
+
*
|
|
28
|
+
* On GitHub and Forgejo the variables go to $GITHUB_ENV, so every later step
|
|
29
|
+
* has them (the report too); on GitLab they are the job's `variables`, so
|
|
30
|
+
* after_script has them too.
|
|
31
|
+
*/
|
|
32
|
+
export const CLOUDS = ["aws", "gcp", "azure"];
|
|
33
|
+
/** The cloud whose login a token source mints from. */
|
|
34
|
+
export const CLOUD_OF = { "rds-iam": "aws", "cloud-sql-iam": "gcp", entra: "azure" };
|
|
35
|
+
/** The ID token's audience a cloud accepts. GCP's is the workload identity provider's own. */
|
|
36
|
+
export function audience(login) {
|
|
37
|
+
if (login.cloud === "aws")
|
|
38
|
+
return "sts.amazonaws.com";
|
|
39
|
+
if (login.cloud === "gcp")
|
|
40
|
+
return `https://iam.googleapis.com/${login.config.workloadIdentityProvider}`;
|
|
41
|
+
return "api://AzureADTokenExchange";
|
|
42
|
+
}
|
|
43
|
+
/** The GitLab ID token variable per cloud, as #50 named them. */
|
|
44
|
+
export const GITLAB_ID_TOKEN = { aws: "AWS_ID_TOKEN", gcp: "GCP_ID_TOKEN", azure: "AZURE_ID_TOKEN" };
|
|
45
|
+
/** The login config for `env`'s roles minted by `token`: the environment's own, else the project's. */
|
|
46
|
+
export function loginFor(login, env, token) {
|
|
47
|
+
const cloud = CLOUD_OF[token];
|
|
48
|
+
const config = login?.environments?.[env]?.[cloud] ?? login?.[cloud];
|
|
49
|
+
return config ? { cloud, config } : undefined;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The logins of a job holding `held` roles, each cloud once. A job logs in
|
|
53
|
+
* once per cloud, so two environments it holds that name different logins
|
|
54
|
+
* for one cloud are refused.
|
|
55
|
+
*/
|
|
56
|
+
export function jobLogins(login, held, cloudOf) {
|
|
57
|
+
const out = new Map();
|
|
58
|
+
for (const [env, role] of held) {
|
|
59
|
+
const token = cloudOf(env, role);
|
|
60
|
+
if (!token)
|
|
61
|
+
continue;
|
|
62
|
+
const l = loginFor(login, env, token);
|
|
63
|
+
if (!l)
|
|
64
|
+
continue;
|
|
65
|
+
const seen = out.get(l.cloud);
|
|
66
|
+
if (seen && JSON.stringify(seen.login.config) !== JSON.stringify(l.config)) {
|
|
67
|
+
throw new Error(`yodel.config.ts ci.login: a job holds ${seen.env}'s and ${env}'s roles, which log in to ${l.cloud} differently; a job logs in once per cloud, so give them one ${l.cloud} login`);
|
|
68
|
+
}
|
|
69
|
+
if (!seen)
|
|
70
|
+
out.set(l.cloud, { login: l, env });
|
|
71
|
+
}
|
|
72
|
+
return CLOUDS.flatMap((c) => {
|
|
73
|
+
const l = out.get(c)?.login;
|
|
74
|
+
return l ? [l] : [];
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/** Where a job keeps a cloud's token by default. */
|
|
78
|
+
const defaultTokenFile = (forge, cloud) => {
|
|
79
|
+
if (forge === "github")
|
|
80
|
+
return `$RUNNER_TEMP/yodel-${cloud}-token`;
|
|
81
|
+
if (forge === "gitlab")
|
|
82
|
+
return `/tmp/yodel-${cloud}-token`;
|
|
83
|
+
return undefined;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Requests the job's OIDC token for an audience and writes it to a file:
|
|
87
|
+
* `node -e '<this>' <audience> <file>`, so every image with node runs it.
|
|
88
|
+
*/
|
|
89
|
+
const GITHUB_OIDC = 'const [aud, file] = process.argv.slice(1); const url = process.env.ACTIONS_ID_TOKEN_REQUEST_URL, auth = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN; if (!url || !auth) { console.error("no OIDC token for this job: the workflow needs permissions id-token: write"); process.exit(1); } fetch(url + "&audience=" + encodeURIComponent(aud), { headers: { Authorization: "bearer " + auth } }).then(async (r) => { if (!r.ok) throw new Error("the OIDC token request answered " + r.status); require("fs").writeFileSync(file, (await r.json()).value, { mode: 0o600 }); }).catch((e) => { console.error(e.message); process.exit(1); })';
|
|
90
|
+
/** Writes the gcloud credential configuration: `node -e '<this>' <provider> <service account> <token file> <config file>`. */
|
|
91
|
+
const GCP_CREDENTIALS = 'const [provider, sa, token, file] = process.argv.slice(1); require("fs").writeFileSync(file, JSON.stringify({ type: "external_account", audience: "//iam.googleapis.com/" + provider, subject_token_type: "urn:ietf:params:oauth:token-type:jwt", token_url: "https://sts.googleapis.com/v1/token", service_account_impersonation_url: "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/" + sa + ":generateAccessToken", credential_source: { file: token } }, null, 2))';
|
|
92
|
+
const quote = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
|
|
93
|
+
/** A path that may name a variable ($RUNNER_TEMP): double-quoted, so the shell expands it. */
|
|
94
|
+
const path = (s) => `"${s}"`;
|
|
95
|
+
/** The variables a cloud's login sets, from its token file (and gcp's credential configuration). */
|
|
96
|
+
function loginVariables(l, tokenFile) {
|
|
97
|
+
if (l.cloud === "aws")
|
|
98
|
+
return { AWS_ROLE_ARN: l.config.roleArn, AWS_WEB_IDENTITY_TOKEN_FILE: tokenFile, AWS_ROLE_SESSION_NAME: l.config.sessionName ?? "yodel" };
|
|
99
|
+
if (l.cloud === "gcp")
|
|
100
|
+
return { GOOGLE_APPLICATION_CREDENTIALS: `${tokenFile}.json` };
|
|
101
|
+
return { AZURE_CLIENT_ID: l.config.clientId, AZURE_TENANT_ID: l.config.tenantId, AZURE_FEDERATED_TOKEN_FILE: tokenFile };
|
|
102
|
+
}
|
|
103
|
+
const STEP_NAME = { aws: "Log in to AWS (web identity)", gcp: "Log in to Google Cloud (workload identity)", azure: "Log in to Azure (federated token)" };
|
|
104
|
+
/**
|
|
105
|
+
* The login steps of a job on `forge`, for `logins`. On Forgejo a cloud
|
|
106
|
+
* without a `tokenFile` is left out: the runner's own identity mints there.
|
|
107
|
+
*/
|
|
108
|
+
export function loginSteps(forge, logins) {
|
|
109
|
+
const out = { steps: [], variables: {} };
|
|
110
|
+
for (const l of logins) {
|
|
111
|
+
const file = l.config.tokenFile ?? defaultTokenFile(forge, l.cloud);
|
|
112
|
+
if (file === undefined)
|
|
113
|
+
continue;
|
|
114
|
+
const lines = [];
|
|
115
|
+
if (forge === "github")
|
|
116
|
+
lines.push(`node -e ${quote(GITHUB_OIDC)} ${quote(audience(l))} ${path(file)}`);
|
|
117
|
+
if (forge === "gitlab")
|
|
118
|
+
lines.push(`(umask 077 && printf '%s' "$${GITLAB_ID_TOKEN[l.cloud]}" > ${path(file)})`);
|
|
119
|
+
if (l.cloud === "gcp") {
|
|
120
|
+
lines.push(`node -e ${quote(GCP_CREDENTIALS)} ${quote(l.config.workloadIdentityProvider)} ${quote(l.config.serviceAccount)} ${path(file)} ${path(`${file}.json`)}`);
|
|
121
|
+
lines.push(`gcloud auth login --cred-file=${path(`${file}.json`)} --quiet`);
|
|
122
|
+
}
|
|
123
|
+
if (l.cloud === "azure") {
|
|
124
|
+
lines.push(`az login --service-principal --username ${quote(l.config.clientId)} --tenant ${quote(l.config.tenantId)} --federated-token "$(cat ${path(file)})" --allow-no-subscriptions --output none`);
|
|
125
|
+
}
|
|
126
|
+
const vars = loginVariables(l, file);
|
|
127
|
+
if (forge === "gitlab")
|
|
128
|
+
Object.assign(out.variables, vars);
|
|
129
|
+
else
|
|
130
|
+
lines.push(...Object.entries(vars).map(([k, v]) => `echo "${k}=${v}" >> "$GITHUB_ENV"`));
|
|
131
|
+
out.steps.push({ name: STEP_NAME[l.cloud], lines });
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
// ── yodel.config.ts ci.login, checked ───────────────────────────────────────
|
|
136
|
+
const ROLE_ARN = /^arn:aws[a-z-]*:iam::\d{12}:role\/[\w+=,.@/-]+$/;
|
|
137
|
+
const PROVIDER = /^projects\/\d+\/locations\/global\/workloadIdentityPools\/[a-z0-9-]+\/providers\/[a-z0-9-]+$/;
|
|
138
|
+
const SERVICE_ACCOUNT = /^[a-z0-9-]+@[a-z0-9-]+\.iam\.gserviceaccount\.com$/;
|
|
139
|
+
const AZURE_ID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
140
|
+
/** A path, optionally under a variable ($RUNNER_TEMP/...): nothing a shell would read as more than that. */
|
|
141
|
+
const TOKEN_FILE = /^(\$[A-Z_][A-Z0-9_]*)?[\w./-]+$/;
|
|
142
|
+
const SESSION_NAME = /^[\w+=,.@-]{2,64}$/;
|
|
143
|
+
const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
144
|
+
const FIELDS = {
|
|
145
|
+
aws: {
|
|
146
|
+
roleArn: { re: ROLE_ARN, what: "a role ARN, arn:aws:iam::<account>:role/<name>", required: true },
|
|
147
|
+
tokenFile: { re: TOKEN_FILE, what: "a file path", required: false },
|
|
148
|
+
sessionName: { re: SESSION_NAME, what: "2 to 64 of letters, digits and +=,.@_-", required: false },
|
|
149
|
+
},
|
|
150
|
+
gcp: {
|
|
151
|
+
workloadIdentityProvider: { re: PROVIDER, what: "projects/<number>/locations/global/workloadIdentityPools/<pool>/providers/<provider>", required: true },
|
|
152
|
+
serviceAccount: { re: SERVICE_ACCOUNT, what: "<name>@<project>.iam.gserviceaccount.com", required: true },
|
|
153
|
+
tokenFile: { re: TOKEN_FILE, what: "a file path", required: false },
|
|
154
|
+
},
|
|
155
|
+
azure: {
|
|
156
|
+
clientId: { re: AZURE_ID, what: "the application (client) id, a GUID", required: true },
|
|
157
|
+
tenantId: { re: AZURE_ID, what: "the directory (tenant) id, a GUID", required: true },
|
|
158
|
+
tokenFile: { re: TOKEN_FILE, what: "a file path", required: false },
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
function cloudsProblem(value, where, allowEnvironments) {
|
|
162
|
+
for (const [k, v] of Object.entries(value)) {
|
|
163
|
+
if (k === "environments" && allowEnvironments) {
|
|
164
|
+
if (!isRecord(v))
|
|
165
|
+
return `${where}.environments: an object keyed by environment, each { aws?, gcp?, azure? }`;
|
|
166
|
+
for (const [env, logins] of Object.entries(v)) {
|
|
167
|
+
if (!isRecord(logins))
|
|
168
|
+
return `${where}.environments.${env}: expected { aws?, gcp?, azure? }`;
|
|
169
|
+
const problem = cloudsProblem(logins, `${where}.environments.${env}`, false);
|
|
170
|
+
if (problem)
|
|
171
|
+
return problem;
|
|
172
|
+
}
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (!CLOUDS.includes(k))
|
|
176
|
+
return `${where}.${k}: unknown setting (expected ${[...CLOUDS, ...(allowEnvironments ? ["environments"] : [])].join(", ")})`;
|
|
177
|
+
const fields = FIELDS[k];
|
|
178
|
+
if (!isRecord(v))
|
|
179
|
+
return `${where}.${k}: expected { ${Object.keys(fields).join(", ")} }`;
|
|
180
|
+
for (const f of Object.keys(v))
|
|
181
|
+
if (!(f in fields))
|
|
182
|
+
return `${where}.${k}.${f}: unknown setting (expected ${Object.keys(fields).join(", ")})`;
|
|
183
|
+
for (const [f, spec] of Object.entries(fields)) {
|
|
184
|
+
const x = v[f];
|
|
185
|
+
if (x === undefined && !spec.required)
|
|
186
|
+
continue;
|
|
187
|
+
if (typeof x !== "string" || !spec.re.test(x))
|
|
188
|
+
return `${where}.${k}.${f}: ${spec.what}`;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
/** What is wrong with yodel.config.ts `ci.login`, if anything. */
|
|
194
|
+
export function loginProblem(value, where) {
|
|
195
|
+
if (!isRecord(value))
|
|
196
|
+
return `${where}: expected { aws?, gcp?, azure?, environments? }`;
|
|
197
|
+
return cloudsProblem(value, where, true);
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/ci/login.ts"],"names":[],"mappings":"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"}
|
package/dist/ci/render.d.ts
CHANGED
|
@@ -68,6 +68,8 @@
|
|
|
68
68
|
* in that image instead, which carries node, yodel, chant and the lexicons
|
|
69
69
|
* on PATH, and no job runs `npm ci` ({@link Toolchain}).
|
|
70
70
|
*/
|
|
71
|
+
import { type ApprovalMode, type CiLogin } from "../config/define.js";
|
|
72
|
+
import { type CloudToken, type Role } from "../credentials.js";
|
|
71
73
|
import type { Declarable } from "@intentius/chant/declarable";
|
|
72
74
|
export type Forge = "github" | "gitlab" | "forgejo";
|
|
73
75
|
export declare const FORGES: readonly Forge[];
|
|
@@ -107,17 +109,44 @@ export interface Environments {
|
|
|
107
109
|
jobs?: ProjectJobs;
|
|
108
110
|
/** yodel.config.ts `ci.image`: the yodel image every job runs in, by digest. */
|
|
109
111
|
image?: string;
|
|
112
|
+
/** yodel.config.ts `ci.resume`: the scheduled job that resumes a wave whose approval arrived. */
|
|
113
|
+
resume?: {
|
|
114
|
+
schedule: string;
|
|
115
|
+
};
|
|
110
116
|
/** The apply pipeline's waves, in order. */
|
|
111
117
|
waves: readonly Wave[];
|
|
112
118
|
/** chant.config.ts declares the `replay` profile, so the lint job runs the replay check. */
|
|
113
119
|
replay: boolean;
|
|
120
|
+
/** The project has tests/*.test.ts: with the replay profile, the lint job runs yodel test on its server too (#54). */
|
|
121
|
+
tests?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* The environments whose profile is made with credentials() (#50): the
|
|
124
|
+
* variables each role reads, and the cloud token source that mints its
|
|
125
|
+
* password, if any. An environment not here reads the default variables.
|
|
126
|
+
*/
|
|
127
|
+
credentials?: Record<string, EnvCredentials>;
|
|
128
|
+
/** yodel.config.ts `ci.login` (#132): the cloud login a job runs before yodel when a role it holds is cloud-minted. */
|
|
129
|
+
login?: CiLogin;
|
|
130
|
+
}
|
|
131
|
+
/** What a job holding one role of an environment needs: the variables it reads, and the cloud identity its token source mints from. */
|
|
132
|
+
export interface RoleNeeds {
|
|
133
|
+
variables: string[];
|
|
134
|
+
cloud?: CloudToken;
|
|
114
135
|
}
|
|
136
|
+
export type EnvCredentials = Record<Role, RoleNeeds>;
|
|
115
137
|
/** DEV_CLICKHOUSE for dev on ClickHouse: what an environment's variables start with. */
|
|
116
138
|
export declare const variablePrefix: (env: string, dialect: Dialect) => string;
|
|
117
|
-
/** The variables a job reading `env` holds: the URL and the reader. */
|
|
118
|
-
export declare const readerVariables: (env: string, dialect: Dialect) => string[];
|
|
139
|
+
/** The variables a job reading `env` holds: the URL and the reader (the variables credentials() names; none for a token-minted password). */
|
|
140
|
+
export declare const readerVariables: (env: string, dialect: Dialect, creds?: EnvCredentials) => string[];
|
|
119
141
|
/** The variables the apply job for `env` holds: the URL and the writer. */
|
|
120
|
-
export declare const writerVariables: (env: string, dialect: Dialect) => string[];
|
|
142
|
+
export declare const writerVariables: (env: string, dialect: Dialect, creds?: EnvCredentials) => string[];
|
|
143
|
+
/** The GitLab ID token per cloud: its variable and its audience. */
|
|
144
|
+
export declare const ID_TOKENS: Record<CloudToken, {
|
|
145
|
+
variable: string;
|
|
146
|
+
aud: string;
|
|
147
|
+
}>;
|
|
148
|
+
/** The write probe a pull request job runs before its plan: it holds no writer for `envs`. */
|
|
149
|
+
export declare const writeProbe: (envs: readonly string[]) => string;
|
|
121
150
|
/**
|
|
122
151
|
* The approvals: `chant approve` records them on the chant/lifecycle branch,
|
|
123
152
|
* and approvers push it. A CI checkout fetches one ref, so fetch this one too.
|
|
@@ -161,7 +190,17 @@ export declare const REPLAY_SERVICE: Record<Dialect, ReplayService>;
|
|
|
161
190
|
/** Waits up to 90 s for the replay server's port; a shell-free one-liner, so every forge runs it the same. */
|
|
162
191
|
export declare const waitFor: (host: string, port: number) => string;
|
|
163
192
|
export declare const LINT = "yodel lint";
|
|
193
|
+
/**
|
|
194
|
+
* The lint job's `yodel lint`, with its findings where the forge shows them
|
|
195
|
+
* (#129): workflow commands on GitHub and Forgejo, which annotate the
|
|
196
|
+
* migration files in the pull request; on GitLab the code quality report,
|
|
197
|
+
* which the job keeps as its `artifacts:reports:codequality`
|
|
198
|
+
* ({@link CODE_QUALITY_FILE}) and the merge request shows.
|
|
199
|
+
*/
|
|
200
|
+
export declare const lintCommand: (forge: Forge) => string;
|
|
164
201
|
export declare const REPLAY = "yodel lint --replay replay --reset";
|
|
202
|
+
/** yodel test (#54), after the replay check on the same throwaway server, its outcome as JUnit XML. */
|
|
203
|
+
export declare const TEST = "yodel test --env replay --reset --junit yodel-test.xml";
|
|
165
204
|
/** Fails a pull request whose pipelines differ from what yodel ci renders. */
|
|
166
205
|
export declare const CI_CHECK = "yodel ci --check";
|
|
167
206
|
/**
|
|
@@ -200,12 +239,15 @@ export interface Wave {
|
|
|
200
239
|
*/
|
|
201
240
|
requires?: string;
|
|
202
241
|
/**
|
|
203
|
-
* A tenant set's wave (#56): a run per tenant, `<env>/<tenant>`,
|
|
204
|
-
* of
|
|
242
|
+
* A tenant set's wave (#56): a run per tenant, `<env>/<tenant>`, or per
|
|
243
|
+
* slot of a set read at run time, `<env>/@<i>of<n>`, in place of the
|
|
244
|
+
* environment's one, all behind the wave's one gate.
|
|
205
245
|
*/
|
|
206
246
|
targets?: readonly string[];
|
|
207
247
|
/** Split the wave into a deciding job and this many share jobs (yodel.config.ts `waves[].shares`). */
|
|
208
248
|
shares?: number;
|
|
249
|
+
/** Which approvals of the wave's digest count (yodel.config.ts `waves[].approval`, #48); absent, `ledger`. */
|
|
250
|
+
approval?: ApprovalMode;
|
|
209
251
|
}
|
|
210
252
|
/** The waves spec: committed, and read by every wave job (its gate policy at the commit before the push). */
|
|
211
253
|
export declare const WAVES_SPEC = "yodel-waves.json";
|
|
@@ -224,25 +266,35 @@ interface WavesSpec {
|
|
|
224
266
|
}>;
|
|
225
267
|
gate: WaveGate;
|
|
226
268
|
shares?: number;
|
|
269
|
+
approval?: ApprovalMode;
|
|
227
270
|
environment?: {
|
|
228
271
|
name: string;
|
|
229
272
|
};
|
|
230
273
|
variables?: Record<string, string>;
|
|
231
274
|
}>;
|
|
275
|
+
/** The scheduled resume job (yodel.config.ts `ci.resume`); only the pipelines are rendered from it, the spec file leaves it out. */
|
|
276
|
+
resume?: {
|
|
277
|
+
schedule: string;
|
|
278
|
+
};
|
|
232
279
|
}
|
|
233
280
|
/**
|
|
234
281
|
* The waves spec. What the file holds is the same for every forge; each
|
|
235
282
|
* forge's jobs get their own variables on top (`variables`).
|
|
236
283
|
*/
|
|
237
|
-
export declare function wavesSpec(waves: readonly Wave[], variables?: (env: string) => Record<string, string
|
|
284
|
+
export declare function wavesSpec(waves: readonly Wave[], variables?: (env: string) => Record<string, string>, resume?: {
|
|
285
|
+
schedule: string;
|
|
286
|
+
}): WavesSpec;
|
|
238
287
|
/** The waves spec file and the apply pipeline on each forge. */
|
|
239
288
|
export declare function applyPipelines(dir: string, envs: Environments): Promise<RenderedFile[]>;
|
|
240
289
|
/** yodel.config.ts `waves`, checked against the environments; one wave per environment, gate `always`, without it. */
|
|
241
290
|
export declare function readWaves(dir: string, envs: readonly string[]): Promise<Wave[]>;
|
|
242
291
|
/**
|
|
243
|
-
* Each wave of an environment with a tenant set (#56), with
|
|
244
|
-
* tenant
|
|
245
|
-
*
|
|
292
|
+
* Each wave of an environment with a tenant set (#56), with its runs: a
|
|
293
|
+
* run per tenant of a list or a file, or for a set given by a query,
|
|
294
|
+
* `shares` slots (one without) that read the tenants when the wave runs.
|
|
295
|
+
* The query is not run here, so the pipeline stays the same as tenants come
|
|
296
|
+
* and go; a list or a file is in the repository, and changing it is
|
|
297
|
+
* rendering again.
|
|
246
298
|
*/
|
|
247
299
|
export declare function withTenants(dir: string, waves: readonly Wave[]): Promise<Wave[]>;
|
|
248
300
|
/**
|
|
@@ -251,7 +303,7 @@ export declare function withTenants(dir: string, waves: readonly Wave[]): Promis
|
|
|
251
303
|
* writer's only under its environment, which the watch does not declare), and
|
|
252
304
|
* `NAME: $NAME` there would refer to itself.
|
|
253
305
|
*/
|
|
254
|
-
export declare function watchSpec(env: string, dialect: Dialect, forge: Forge): {
|
|
306
|
+
export declare function watchSpec(env: string, dialect: Dialect, forge: Forge, creds?: EnvCredentials): {
|
|
255
307
|
name: string;
|
|
256
308
|
variables?: Record<string, string>;
|
|
257
309
|
permissions?: Record<string, string>;
|
|
@@ -259,6 +311,8 @@ export declare function watchSpec(env: string, dialect: Dialect, forge: Forge):
|
|
|
259
311
|
export declare function watchPipelines(dir: string, envs_: Environments): Promise<RenderedFile[]>;
|
|
260
312
|
/** The dialect and the environments chant.config.ts declares, in order. */
|
|
261
313
|
export declare function environments(dir: string): Promise<Environments>;
|
|
314
|
+
/** The roles of each environment whose profile is made with credentials(). */
|
|
315
|
+
export declare function credentialsIn(profiles: Record<string, unknown>, envs: readonly string[]): Record<string, EnvCredentials>;
|
|
262
316
|
/**
|
|
263
317
|
* The project's own jobs (#65): the module yodel.config.ts `ci.jobs` names,
|
|
264
318
|
* relative to the project, declaring jobs with chant's lexicons. `actions`
|