@tailor-platform/sdk 1.75.0 → 1.76.1
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/CHANGELOG.md +34 -0
- package/dist/{application-DYshsH-K.mjs → application-BUfYmf0O.mjs} +274 -10
- package/dist/application-BUfYmf0O.mjs.map +1 -0
- package/dist/application-DbvD5UUz.mjs +3 -0
- package/dist/cli/index.mjs +218 -66
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.mjs +2 -2
- package/dist/cli/query/index.d.mts +4 -0
- package/dist/completion/zsh-worker.zsh +2 -2
- package/dist/configure/index.mjs +1 -1
- package/dist/configure/services/tailordb/schema.d.mts +31 -21
- package/dist/resource_pb-BRv7AMXK.mjs +49 -0
- package/dist/resource_pb-BRv7AMXK.mjs.map +1 -0
- package/dist/{runtime-CJ5usBOu.mjs → runtime-_vUgjiqT.mjs} +27 -252
- package/dist/runtime-_vUgjiqT.mjs.map +1 -0
- package/dist/{schema-Dl_y0m9e.mjs → schema-DrVyN-LP.mjs} +60 -36
- package/dist/schema-DrVyN-LP.mjs.map +1 -0
- package/dist/{service_pb-D-PXRoMg.mjs → service_pb-B2FF59sP.mjs} +1 -1
- package/dist/{service_pb-4unFyubn.mjs → service_pb-B5w9rjPY.mjs} +3 -46
- package/dist/service_pb-B5w9rjPY.mjs.map +1 -0
- package/docs/cli/auth.md +3 -3
- package/docs/cli/setup.md +8 -8
- package/docs/services/tailordb.md +20 -0
- package/package.json +10 -10
- package/dist/application-BJKNlv8c.mjs +0 -3
- package/dist/application-DYshsH-K.mjs.map +0 -1
- package/dist/runtime-CJ5usBOu.mjs.map +0 -1
- package/dist/schema-Dl_y0m9e.mjs.map +0 -1
- package/dist/service_pb-4unFyubn.mjs.map +0 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { B as FunctionExecution_Type, Ct as PATScope, T as CustomDomainStatus, gt as AuthInvokerSchema } from "../service_pb-4unFyubn.mjs";
|
|
3
2
|
import { t as assertDefined } from "../assert-DBxo8jPo.mjs";
|
|
4
3
|
import { n as logger, r as styles } from "../logger-BEiZZ3qT.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import { A as
|
|
4
|
+
import { A as hasAnyUserTokenEntry, B as readPlatformConfig, Ct as toPageDirection, D as loadConfig, F as loadMachineUserName, G as defaultPlatformBaseUrl, H as saveUserTokens, K as fetchAll, L as loadStoredUserTokens, M as loadAccessToken, O as deleteUserTokens, P as loadConsoleBaseUrl, R as loadWorkspaceId, St as resolveMachineUserInputSource, T as hashContent$1, U as writePlatformConfig, V as resolveUserTokenKey, W as closeConnectionPool, X as fetchPlatformMachineUserToken, Y as fetchPaged, Z as fetchUserInfo, _ as platformBundleDefinePlugin, a as resolveInlineSourcemap, b as resolveBundleLogLevel, c as ResolverSchema, ct as configArg, et as getOrNull, it as isDefaultPlatform, j as hasUserTokenEntry, k as fetchLatestToken, lt as confirmationArgs, mt as multiConfigArg, nt as initOAuth2Client, pt as isVerbose, q as fetchAllTolerant, rt as initOperatorClient, s as WorkflowJobSchema, st as commonArgs, t as defineApplication, u as INVOKER_EXPR, ut as deploymentArgs, v as composeFunctionTreeshakeOptions, vt as pagedLogArgs, w as getDistDir, wt as workspaceArgs, y as createLogLevelTreeshakeOptions, yt as paginationArgs, z as platformConfigFromProfile } from "../application-BUfYmf0O.mjs";
|
|
5
|
+
import { $t as compareSnapshotWithRemote, A as listCommand$12, An as apiCommand, C as listCommand$13, Cn as hasChanges, Dn as PluginManager, Dt as listCommand$6, E as waitCommand, En as sdkNameLabelKey, F as generateCommand$1, G as removeCommand$1, Gt as deploy, H as extractOwnedNamespaces, Ht as formatKeyValueTable, I as generateMigrationScript, It as getCommand$6, K as updateCommand$3, Kt as ensureConfigId, L as writeDbTypesFile, Mn as assertWritable, N as truncateCommand, Nn as defineAppCommand, O as resumeCommand, On as generateUserTypes, Pt as startCommand, Q as getCommand$5, Qt as parseMigrationLabelNumber, R as getConfiguredEditorCommand, Rt as executionsCommand, Sn as formatMigrationDiff, T as healthCommand, Tn as resourceTrn, Tt as triggerCommand, U as logBetaWarning, Ut as getCommand$1, V as showCommand, Vt as functionExecutionStatusToString, X as listCommand$11, Xt as MIGRATION_LABEL_KEY, Y as treeCommand, Zt as handleOptionalToRequiredError, _n as loadDiff, b as createCommand$4, bn as parseMigrationNumberArg, c as listCommand$14, cn as compareLocalTypesWithSnapshot, ct as createCommand$3, dn as getLatestMigrationNumber, en as generateAllTypeManifestsFromSnapshot, et as updateCommand$2, f as restoreCommand, ft as getCommand$3, g as getCommand$7, gn as isValidMigrationNumber, gt as listCommand$8, ht as tokenCommand, i as updateCommand$4, in as INITIAL_SCHEMA_NUMBER, it as getCommand$4, jt as jobsCommand, kn as prompt, m as listCommand$15, mn as getMigrationFiles, nt as listCommand$10, o as removeCommand, ot as deleteCommand$4, pn as getMigrationFilePath, qt as executeScript, r as queryCommand, sn as assertValidMigrationFiles, t as isNativeTypeScriptRuntime, tn as protoGqlPermission, u as inviteCommand, un as createSnapshotFromLocalTypes, ut as listCommand$9, v as deleteCommand$5, vn as reconstructSnapshotFromMigrations, vt as generate, wn as getNamespacesWithMigrations, wt as webhookCommand, xt as getCommand$2, yn as formatMigrationNumber, yt as listCommand$7, z as openInConfiguredEditor } from "../runtime-_vUgjiqT.mjs";
|
|
7
6
|
import { n as ExecutorSchema } from "../service-BCRJ-3NV.mjs";
|
|
8
7
|
import { t as multiline } from "../multiline-sfHpTZZK.mjs";
|
|
9
8
|
import { r as isPluginGeneratedType } from "../seed-fm0LeYP2.mjs";
|
|
10
9
|
import { t as readPackageJson } from "../package-json-8b0O9TlX.mjs";
|
|
11
10
|
import { i as userAgent } from "../secret-file-VSVGy1V0.mjs";
|
|
12
11
|
import { n as isCLIError } from "../errors-Dtf2WPaW.mjs";
|
|
12
|
+
import { B as FunctionExecution_Type, Ct as PATScope, T as CustomDomainStatus, gt as AuthInvokerSchema } from "../service_pb-B5w9rjPY.mjs";
|
|
13
13
|
import { a as JSON_FOOTER_MARKER, i as CRASH_LOG_EXTENSION, o as parseCrashReportConfig, r as sendCrashReport, t as initCrashReporting } from "../crashreport-ayWANEZ6.mjs";
|
|
14
14
|
import { arg, defineCommand, runCommand, runMain } from "politty";
|
|
15
15
|
import { withCompletionCommand } from "politty/completion";
|
|
@@ -1440,6 +1440,7 @@ When a \`.js\` file is provided, detection and bundling are skipped and the file
|
|
|
1440
1440
|
const authNamespace = resolveAuthNamespace(config.auth);
|
|
1441
1441
|
const machineUserName = await resolveMachineUserName({
|
|
1442
1442
|
cliMachineUser: args["machine-user"],
|
|
1443
|
+
cliMachineUserSource: resolveMachineUserInputSource(args["machine-user"]),
|
|
1443
1444
|
profile: args.profile,
|
|
1444
1445
|
authConfig: config.auth
|
|
1445
1446
|
});
|
|
@@ -1556,9 +1557,10 @@ function resolveAuthNamespace(authConfig) {
|
|
|
1556
1557
|
* @returns Resolved machine user name
|
|
1557
1558
|
*/
|
|
1558
1559
|
async function resolveMachineUserName(options) {
|
|
1559
|
-
const { cliMachineUser, profile, authConfig } = options;
|
|
1560
|
+
const { cliMachineUser, cliMachineUserSource, profile, authConfig } = options;
|
|
1560
1561
|
const resolved = await loadMachineUserName({
|
|
1561
1562
|
machineUser: cliMachineUser,
|
|
1563
|
+
machineUserSource: cliMachineUserSource,
|
|
1562
1564
|
profile
|
|
1563
1565
|
});
|
|
1564
1566
|
if (resolved) return resolved;
|
|
@@ -1737,8 +1739,47 @@ const redirectUri = `http://localhost:${redirectPort}/callback`;
|
|
|
1737
1739
|
function randomState() {
|
|
1738
1740
|
return crypto.randomBytes(32).toString("base64url");
|
|
1739
1741
|
}
|
|
1740
|
-
function
|
|
1741
|
-
if (args.profile
|
|
1742
|
+
function getProfileUserMismatch(args, authenticatedUser) {
|
|
1743
|
+
if (!args.profile || !args.profileUser || authenticatedUser === args.profileUser) return;
|
|
1744
|
+
return {
|
|
1745
|
+
profile: args.profile,
|
|
1746
|
+
oldUser: args.profileUser,
|
|
1747
|
+
authenticatedUser,
|
|
1748
|
+
loginMode: args.loginMode ?? "user"
|
|
1749
|
+
};
|
|
1750
|
+
}
|
|
1751
|
+
function quoteCommandArg(value, platform = process.platform) {
|
|
1752
|
+
if (platform === "win32") {
|
|
1753
|
+
if (/^[A-Za-z0-9_./:@+=,-]+$/.test(value)) return value;
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1756
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
1757
|
+
}
|
|
1758
|
+
function profileUpdateCommand(mismatch) {
|
|
1759
|
+
const profileArg = quoteCommandArg(mismatch.profile);
|
|
1760
|
+
const userArg = quoteCommandArg(mismatch.authenticatedUser);
|
|
1761
|
+
if (profileArg && userArg) return `tailor-sdk profile update --user ${userArg} -- ${profileArg}`;
|
|
1762
|
+
return [
|
|
1763
|
+
"tailor-sdk profile update --user <authenticated-user> -- <profile>",
|
|
1764
|
+
`profile = ${JSON.stringify(mismatch.profile)}`,
|
|
1765
|
+
`authenticated user = ${JSON.stringify(mismatch.authenticatedUser)}`
|
|
1766
|
+
].join("\n");
|
|
1767
|
+
}
|
|
1768
|
+
function retryInstruction(mismatch) {
|
|
1769
|
+
if (mismatch.loginMode === "machine-user") return "Then retry the original machine-user login command.";
|
|
1770
|
+
const profileArg = quoteCommandArg(mismatch.profile);
|
|
1771
|
+
if (!profileArg) return "Then retry the browser login with the same profile value.";
|
|
1772
|
+
return `Then run:\n tailor-sdk login --profile ${profileArg}`;
|
|
1773
|
+
}
|
|
1774
|
+
function profileUserMismatchError(mismatch) {
|
|
1775
|
+
const updateCommand = profileUpdateCommand(mismatch);
|
|
1776
|
+
const nextStep = retryInstruction(mismatch);
|
|
1777
|
+
return new Error(multiline`
|
|
1778
|
+
Profile "${mismatch.profile}" is configured for "${mismatch.oldUser}", but login authenticated "${mismatch.authenticatedUser}".
|
|
1779
|
+
The authenticated user has been saved. To use it with this profile, run:
|
|
1780
|
+
${updateCommand}
|
|
1781
|
+
${nextStep}
|
|
1782
|
+
`);
|
|
1742
1783
|
}
|
|
1743
1784
|
function shouldUpdateCurrentUser(profile, platformConfig) {
|
|
1744
1785
|
if (!profile) return true;
|
|
@@ -1758,12 +1799,16 @@ const startAuthServer = async (args = {}) => {
|
|
|
1758
1799
|
codeVerifier
|
|
1759
1800
|
});
|
|
1760
1801
|
const userInfo = await fetchUserInfo(tokens.accessToken, args.platformConfig);
|
|
1761
|
-
assertProfileLoginUser(args, userInfo.email);
|
|
1762
1802
|
const pfConfig = await readPlatformConfig();
|
|
1763
1803
|
await saveUserTokens(pfConfig, userInfo.email, {
|
|
1764
1804
|
accessToken: tokens.accessToken,
|
|
1765
1805
|
refreshToken: tokens.refreshToken ?? void 0
|
|
1766
1806
|
}, new Date(assertDefined(tokens.expiresAt, "token response missing expiresAt")).toISOString(), args.platformConfig);
|
|
1807
|
+
const mismatch = getProfileUserMismatch(args, userInfo.email);
|
|
1808
|
+
if (mismatch) {
|
|
1809
|
+
writePlatformConfig(pfConfig);
|
|
1810
|
+
throw profileUserMismatchError(mismatch);
|
|
1811
|
+
}
|
|
1767
1812
|
if (args.updateCurrentUser ?? true) pfConfig.current_user = userInfo.email;
|
|
1768
1813
|
writePlatformConfig(pfConfig);
|
|
1769
1814
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
@@ -1806,11 +1851,15 @@ const startAuthServer = async (args = {}) => {
|
|
|
1806
1851
|
});
|
|
1807
1852
|
};
|
|
1808
1853
|
async function loginAsMachineUser(args) {
|
|
1809
|
-
assertProfileLoginUser(args, args.clientId);
|
|
1810
1854
|
const clientSecret = args.clientSecret ?? await prompt.password({ message: "Client secret" });
|
|
1811
1855
|
const tokens = await fetchPlatformMachineUserToken(args.clientId, clientSecret, args.platformConfig);
|
|
1812
1856
|
const pfConfig = await readPlatformConfig();
|
|
1813
1857
|
await saveUserTokens(pfConfig, args.clientId, { accessToken: tokens.accessToken }, new Date(assertDefined(tokens.expiresAt, "token response missing expiresAt")).toISOString(), args.platformConfig);
|
|
1858
|
+
const mismatch = getProfileUserMismatch(args, args.clientId);
|
|
1859
|
+
if (mismatch) {
|
|
1860
|
+
writePlatformConfig(pfConfig);
|
|
1861
|
+
throw profileUserMismatchError(mismatch);
|
|
1862
|
+
}
|
|
1814
1863
|
if (args.updateCurrentUser ?? true) pfConfig.current_user = args.clientId;
|
|
1815
1864
|
writePlatformConfig(pfConfig);
|
|
1816
1865
|
}
|
|
@@ -1843,31 +1892,36 @@ const loginCommand = defineAppCommand({
|
|
|
1843
1892
|
})
|
|
1844
1893
|
}).strict().describe("Machine User Login")]),
|
|
1845
1894
|
run: async (args) => {
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1895
|
+
try {
|
|
1896
|
+
let platformConfig;
|
|
1897
|
+
let profileUser;
|
|
1898
|
+
if ("profile" in args && args.profile) {
|
|
1899
|
+
const profileEntry = (await readPlatformConfig()).profiles[args.profile];
|
|
1900
|
+
if (!profileEntry) throw new Error(`Profile "${args.profile}" not found`);
|
|
1901
|
+
platformConfig = platformConfigFromProfile(profileEntry);
|
|
1902
|
+
profileUser = profileEntry.user;
|
|
1903
|
+
}
|
|
1904
|
+
const updateCurrentUser = shouldUpdateCurrentUser(args.profile, platformConfig);
|
|
1905
|
+
if ("machine-user" in args) await loginAsMachineUser({
|
|
1906
|
+
clientId: args.clientId,
|
|
1907
|
+
clientSecret: args.clientSecret,
|
|
1908
|
+
profile: args.profile,
|
|
1909
|
+
profileUser,
|
|
1910
|
+
platformConfig,
|
|
1911
|
+
updateCurrentUser,
|
|
1912
|
+
loginMode: "machine-user"
|
|
1913
|
+
});
|
|
1914
|
+
else await startAuthServer({
|
|
1915
|
+
profile: args.profile,
|
|
1916
|
+
profileUser,
|
|
1917
|
+
platformConfig,
|
|
1918
|
+
updateCurrentUser,
|
|
1919
|
+
loginMode: "user"
|
|
1920
|
+
});
|
|
1921
|
+
logger.success("Successfully logged in to Tailor Platform.");
|
|
1922
|
+
} finally {
|
|
1923
|
+
await closeConnectionPool();
|
|
1853
1924
|
}
|
|
1854
|
-
const updateCurrentUser = shouldUpdateCurrentUser(args.profile, platformConfig);
|
|
1855
|
-
if ("machine-user" in args) await loginAsMachineUser({
|
|
1856
|
-
clientId: args.clientId,
|
|
1857
|
-
clientSecret: args.clientSecret,
|
|
1858
|
-
profile: args.profile,
|
|
1859
|
-
profileUser,
|
|
1860
|
-
platformConfig,
|
|
1861
|
-
updateCurrentUser
|
|
1862
|
-
});
|
|
1863
|
-
else await startAuthServer({
|
|
1864
|
-
profile: args.profile,
|
|
1865
|
-
profileUser,
|
|
1866
|
-
platformConfig,
|
|
1867
|
-
updateCurrentUser
|
|
1868
|
-
});
|
|
1869
|
-
logger.success("Successfully logged in to Tailor Platform.");
|
|
1870
|
-
await closeConnectionPool();
|
|
1871
1925
|
}
|
|
1872
1926
|
});
|
|
1873
1927
|
|
|
@@ -2822,7 +2876,7 @@ function findTarget(lock, kind, workspaceName) {
|
|
|
2822
2876
|
|
|
2823
2877
|
//#endregion
|
|
2824
2878
|
//#region src/cli/commands/setup/action.yml
|
|
2825
|
-
var action_default = "# __HEADER__\nname: __WORKSPACE_NAME__\ndescription: >-\n Deploy __WORKSPACE_NAME__ to Tailor Platform.\n Checkout and dependency installation are expected to be handled by the caller.\n\ninputs:\n workspace-id:\n description: Tailor Platform workspace id\n required: true\n name:\n description: Workspace name (used in Slack notifications)\n required: true\n working-directory:\n description: App directory relative to the repository root\n required: false\n default: \".\"\n platform-client-id:\n description: Machine-user client id\n required: true\n platform-client-secret:\n description: Machine-user client secret\n required: true\n slack-token:\n description: Slack bot token\n required: false\n slack-channel-id:\n description: Slack channel id\n required: false\n user-mapping:\n description: JSON string mapping GitHub usernames to Slack user IDs\n required: false\n package-manager:\n description: Package manager used for dependency installation (pnpm, npm, yarn, bun)\n required: false\n default: pnpm\n\noutputs:\n app-url:\n description: Deployed application URL\n value: ${{ steps.tailor-apply.outputs.app-url }}\n\nruns:\n using: composite\n steps:\n # __STATIC_WEBSITE_BUILD_START__\n - id: build-site\n shell: bash\n run: |\n # Replace with your static website build command.\n # Example: pnpm --filter <package-name> run build:static\n # Note: this run: command is user-editable. Custom build commands are preserved across\n # reruns and are not treated as drift by setup check. Other edits to this file are flagged\n # as drift and will be overwritten if you re-run setup action with --force.\n true\n # __STATIC_WEBSITE_BUILD_END__\n - id: tailor-apply\n uses: tailor-platform/actions/deploy@e74173d4bdd931d036ad359cf5f7729fc6aa7067 # v1.5.1\n with:\n workspace-id: ${{ inputs.workspace-id }}\n working-directory: ${{ inputs.working-directory }}\n package-manager: ${{ inputs.package-manager }}\n platform-client-id: ${{ inputs.platform-client-id }}\n platform-client-secret: ${{ inputs.platform-client-secret }}\n - id: tailor-notify\n if: failure() && inputs.slack-token != '' && inputs.slack-channel-id != ''\n uses: tailor-platform/actions/notify@e74173d4bdd931d036ad359cf5f7729fc6aa7067 # v1.5.1\n with:\n provider: slack\n status: failure\n workspace-name: ${{ inputs.name }}\n slack-token: ${{ inputs.slack-token }}\n slack-channel-id: ${{ inputs.slack-channel-id }}\n user-mapping: ${{ inputs.user-mapping }}\n";
|
|
2879
|
+
var action_default = "# __HEADER__\nname: __WORKSPACE_NAME__\ndescription: >-\n Deploy __WORKSPACE_NAME__ to Tailor Platform.\n Checkout and dependency installation are expected to be handled by the caller.\n\ninputs:\n workspace-id:\n description: Tailor Platform workspace id\n required: true\n name:\n description: Workspace name (used in Slack notifications)\n required: true\n working-directory:\n description: App directory relative to the repository root\n required: false\n default: \".\"\n config:\n description: SDK config path, or comma-separated config paths for multi-config deploys\n required: false\n default: \"tailor.config.ts\"\n deploy:\n description: Whether to run the Tailor deploy step after build steps\n required: false\n default: \"true\"\n build-site:\n description: Whether to run the static website build slot when present\n required: false\n default: \"true\"\n platform-client-id:\n description: Machine-user client id\n required: true\n platform-client-secret:\n description: Machine-user client secret\n required: true\n slack-token:\n description: Slack bot token\n required: false\n slack-channel-id:\n description: Slack channel id\n required: false\n user-mapping:\n description: JSON string mapping GitHub usernames to Slack user IDs\n required: false\n package-manager:\n description: Package manager used for dependency installation (pnpm, npm, yarn, bun)\n required: false\n default: pnpm\n\noutputs:\n app-url:\n description: Deployed application URL\n value: ${{ steps.tailor-apply.outputs.app-url }}\n\nruns:\n using: composite\n steps:\n # __STATIC_WEBSITE_BUILD_START__\n - id: build-site\n if: inputs.build-site == 'true'\n shell: bash\n run: |\n # Replace with your static website build command.\n # Example: pnpm --filter <package-name> run build:static\n # Note: this run: command is user-editable. Custom build commands are preserved across\n # reruns and are not treated as drift by setup check. Other edits to this file are flagged\n # as drift and will be overwritten if you re-run setup action with --force.\n true\n # __STATIC_WEBSITE_BUILD_END__\n - id: tailor-apply\n if: inputs.deploy == 'true'\n uses: tailor-platform/actions/deploy@e74173d4bdd931d036ad359cf5f7729fc6aa7067 # v1.5.1\n env:\n TAILOR_PLATFORM_SDK_CONFIG_PATH: ${{ inputs.config }}\n with:\n workspace-id: ${{ inputs.workspace-id }}\n working-directory: ${{ inputs.working-directory }}\n package-manager: ${{ inputs.package-manager }}\n platform-client-id: ${{ inputs.platform-client-id }}\n platform-client-secret: ${{ inputs.platform-client-secret }}\n - id: tailor-notify\n if: failure() && inputs.slack-token != '' && inputs.slack-channel-id != ''\n uses: tailor-platform/actions/notify@e74173d4bdd931d036ad359cf5f7729fc6aa7067 # v1.5.1\n with:\n provider: slack\n status: failure\n workspace-name: ${{ inputs.name }}\n slack-token: ${{ inputs.slack-token }}\n slack-channel-id: ${{ inputs.slack-channel-id }}\n user-mapping: ${{ inputs.user-mapping }}\n";
|
|
2826
2880
|
|
|
2827
2881
|
//#endregion
|
|
2828
2882
|
//#region src/cli/commands/setup/branch.workflow.yml
|
|
@@ -3019,7 +3073,7 @@ const ACTIONS_SHA = "e74173d4bdd931d036ad359cf5f7729fc6aa7067";
|
|
|
3019
3073
|
* @returns Rendered YAML and the list of managed job/step ids
|
|
3020
3074
|
*/
|
|
3021
3075
|
function renderCoordinateWorkflow(params) {
|
|
3022
|
-
const { coordinatorName, kind,
|
|
3076
|
+
const { coordinatorName, kind, actionGroups, environment, packageManager } = params;
|
|
3023
3077
|
const isTag = kind === "tag";
|
|
3024
3078
|
const branch = params.branch;
|
|
3025
3079
|
const tagPattern = params.tagPattern ?? "v*";
|
|
@@ -3054,29 +3108,60 @@ function renderCoordinateWorkflow(params) {
|
|
|
3054
3108
|
` with:`,
|
|
3055
3109
|
` package-manager: ${packageManager}`
|
|
3056
3110
|
].join("\n");
|
|
3057
|
-
const
|
|
3111
|
+
const configPath = (app) => app.dir === "." ? "tailor.config.ts" : `${app.dir}/tailor.config.ts`;
|
|
3112
|
+
const groupConfigPath = (group) => group.apps.map(configPath).join(",");
|
|
3113
|
+
const firstApp = (group) => {
|
|
3114
|
+
const [app] = group.apps;
|
|
3115
|
+
if (!app) throw new Error("Coordinate action groups must contain at least one app.");
|
|
3116
|
+
return app;
|
|
3117
|
+
};
|
|
3118
|
+
const singleAppPlanStep = (group, app) => {
|
|
3058
3119
|
const wd = app.dir !== "." ? app.dir : void 0;
|
|
3059
3120
|
const wdLine = wd ? `\n working-directory: ${wd}` : "";
|
|
3060
3121
|
return [
|
|
3061
|
-
`- id: tailor-
|
|
3062
|
-
` uses: tailor-platform/actions/generate-check@${ACTIONS_SHA} # v1.5.1`,
|
|
3063
|
-
` with:`,
|
|
3064
|
-
` package-manager: ${packageManager}${wdLine}`,
|
|
3065
|
-
`- id: tailor-plan-${app.name}`,
|
|
3122
|
+
`- id: tailor-plan-${group.id}`,
|
|
3066
3123
|
` if: github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork`,
|
|
3067
3124
|
` uses: tailor-platform/actions/plan@${ACTIONS_SHA} # v1.5.1`,
|
|
3068
3125
|
` with:`,
|
|
3069
3126
|
` workspace-id: \${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}`,
|
|
3070
3127
|
` package-manager: ${packageManager}${wdLine}`,
|
|
3071
|
-
` label: ${coordinatorName}/${
|
|
3128
|
+
` label: ${coordinatorName}/${group.id}`,
|
|
3072
3129
|
` platform-client-id: \${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}`,
|
|
3073
3130
|
` platform-client-secret: \${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}`,
|
|
3074
3131
|
` github-token: \${{ secrets.GITHUB_TOKEN }}`
|
|
3075
3132
|
];
|
|
3133
|
+
};
|
|
3134
|
+
const multiConfigPlanStep = (group) => [
|
|
3135
|
+
`- id: tailor-plan-${group.id}`,
|
|
3136
|
+
` if: github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork`,
|
|
3137
|
+
` uses: tailor-platform/actions/plan@${ACTIONS_SHA} # v1.5.1`,
|
|
3138
|
+
` env:`,
|
|
3139
|
+
` TAILOR_PLATFORM_SDK_CONFIG_PATH: ${groupConfigPath(group)}`,
|
|
3140
|
+
` with:`,
|
|
3141
|
+
` workspace-id: \${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}`,
|
|
3142
|
+
` package-manager: ${packageManager}`,
|
|
3143
|
+
` label: ${coordinatorName}/${group.id}`,
|
|
3144
|
+
` platform-client-id: \${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}`,
|
|
3145
|
+
` platform-client-secret: \${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}`,
|
|
3146
|
+
` github-token: \${{ secrets.GITHUB_TOKEN }}`
|
|
3147
|
+
];
|
|
3148
|
+
const perAppPlanSteps = actionGroups.flatMap((group) => {
|
|
3149
|
+
const generateCheckSteps = group.apps.flatMap((app) => {
|
|
3150
|
+
const wd = app.dir !== "." ? app.dir : void 0;
|
|
3151
|
+
const wdLine = wd ? `\n working-directory: ${wd}` : "";
|
|
3152
|
+
return [
|
|
3153
|
+
`- id: tailor-generate-check-${app.name}`,
|
|
3154
|
+
` uses: tailor-platform/actions/generate-check@${ACTIONS_SHA} # v1.5.1`,
|
|
3155
|
+
` with:`,
|
|
3156
|
+
` package-manager: ${packageManager}${wdLine}`
|
|
3157
|
+
];
|
|
3158
|
+
});
|
|
3159
|
+
const planStep = group.apps.length === 1 ? singleAppPlanStep(group, firstApp(group)) : multiConfigPlanStep(group);
|
|
3160
|
+
return [...generateCheckSteps, ...planStep];
|
|
3076
3161
|
}).join("\n");
|
|
3077
3162
|
out = line(out, "PER_APP_PLAN_STEPS", `${driftCheckStep}\n${perAppPlanSteps}`);
|
|
3078
|
-
const
|
|
3079
|
-
`- id: tailor-deploy-${
|
|
3163
|
+
const singleAppDeployStep = (group, app) => [
|
|
3164
|
+
`- id: tailor-deploy-${group.id}`,
|
|
3080
3165
|
` uses: ./.github/actions/tailor-${app.name}`,
|
|
3081
3166
|
` with:`,
|
|
3082
3167
|
` workspace-id: \${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}`,
|
|
@@ -3088,7 +3173,39 @@ function renderCoordinateWorkflow(params) {
|
|
|
3088
3173
|
` slack-token: \${{ secrets.TAILOR_SLACK_BOT_TOKEN }}`,
|
|
3089
3174
|
` slack-channel-id: \${{ vars.TAILOR_SLACK_CHANNEL_ID }}`,
|
|
3090
3175
|
` # editable: api-url:`
|
|
3091
|
-
]
|
|
3176
|
+
];
|
|
3177
|
+
const buildSiteStep = (app) => [
|
|
3178
|
+
`- id: tailor-build-site-${app.name}`,
|
|
3179
|
+
` uses: ./.github/actions/tailor-${app.name}`,
|
|
3180
|
+
` with:`,
|
|
3181
|
+
` workspace-id: \${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}`,
|
|
3182
|
+
` name: ${app.name}`,
|
|
3183
|
+
` working-directory: ${app.dir}`,
|
|
3184
|
+
` deploy: "false"`,
|
|
3185
|
+
` package-manager: ${packageManager}`,
|
|
3186
|
+
` platform-client-id: \${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}`,
|
|
3187
|
+
` platform-client-secret: \${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}`,
|
|
3188
|
+
` slack-token: \${{ secrets.TAILOR_SLACK_BOT_TOKEN }}`,
|
|
3189
|
+
` slack-channel-id: \${{ vars.TAILOR_SLACK_CHANNEL_ID }}`
|
|
3190
|
+
];
|
|
3191
|
+
const multiConfigDeployStep = (group) => [
|
|
3192
|
+
...group.apps.filter((app) => app.hasStaticWebsites).flatMap(buildSiteStep),
|
|
3193
|
+
`- id: tailor-deploy-${group.id}`,
|
|
3194
|
+
` uses: ./.github/actions/tailor-${firstApp(group).name}`,
|
|
3195
|
+
` with:`,
|
|
3196
|
+
` workspace-id: \${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}`,
|
|
3197
|
+
` name: ${coordinatorName}/${group.id}`,
|
|
3198
|
+
` working-directory: .`,
|
|
3199
|
+
` config: ${groupConfigPath(group)}`,
|
|
3200
|
+
` build-site: "false"`,
|
|
3201
|
+
` package-manager: ${packageManager}`,
|
|
3202
|
+
` platform-client-id: \${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}`,
|
|
3203
|
+
` platform-client-secret: \${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}`,
|
|
3204
|
+
` slack-token: \${{ secrets.TAILOR_SLACK_BOT_TOKEN }}`,
|
|
3205
|
+
` slack-channel-id: \${{ vars.TAILOR_SLACK_CHANNEL_ID }}`,
|
|
3206
|
+
` # editable: api-url:`
|
|
3207
|
+
];
|
|
3208
|
+
const deploySteps = actionGroups.flatMap((group) => group.apps.length === 1 ? singleAppDeployStep(group, firstApp(group)) : multiConfigDeployStep(group)).join("\n");
|
|
3092
3209
|
out = line(out, "PER_APP_DEPLOY_STEPS", deploySteps);
|
|
3093
3210
|
out = out.replaceAll("__WORKSPACE_NAME__", () => coordinatorName);
|
|
3094
3211
|
out = out.replaceAll("__ENVIRONMENT__", () => environment);
|
|
@@ -3097,9 +3214,15 @@ function renderCoordinateWorkflow(params) {
|
|
|
3097
3214
|
const generatedIds = [];
|
|
3098
3215
|
if (isTag && branch !== void 0) generatedIds.push("tailor-tag-guard", "tailor-tag-guard/tailor-checkout", "tailor-tag-guard/tailor-tag-guard");
|
|
3099
3216
|
generatedIds.push("tailor-plan", "tailor-plan/tailor-checkout", "tailor-plan/tailor-setup", "tailor-plan/tailor-drift-check");
|
|
3100
|
-
for (const
|
|
3217
|
+
for (const group of actionGroups) {
|
|
3218
|
+
for (const app of group.apps) generatedIds.push(`tailor-plan/tailor-generate-check-${app.name}`);
|
|
3219
|
+
generatedIds.push(`tailor-plan/tailor-plan-${group.id}`);
|
|
3220
|
+
}
|
|
3101
3221
|
generatedIds.push("tailor-deploy", "tailor-deploy/tailor-checkout", "tailor-deploy/tailor-setup");
|
|
3102
|
-
for (const
|
|
3222
|
+
for (const group of actionGroups) {
|
|
3223
|
+
for (const app of group.apps) if (group.apps.length > 1 && app.hasStaticWebsites) generatedIds.push(`tailor-deploy/tailor-build-site-${app.name}`);
|
|
3224
|
+
generatedIds.push(`tailor-deploy/tailor-deploy-${group.id}`);
|
|
3225
|
+
}
|
|
3103
3226
|
return {
|
|
3104
3227
|
content: out,
|
|
3105
3228
|
generatedIds
|
|
@@ -3137,6 +3260,25 @@ function renderTailorSetupAction(params) {
|
|
|
3137
3260
|
|
|
3138
3261
|
//#endregion
|
|
3139
3262
|
//#region src/cli/commands/setup/generate.ts
|
|
3263
|
+
function actionName(input) {
|
|
3264
|
+
return input.startsWith("tailor-") ? input.slice(7) : input;
|
|
3265
|
+
}
|
|
3266
|
+
function splitActionGroup(input) {
|
|
3267
|
+
const names = input.split(",").map((entry) => actionName(entry.trim()));
|
|
3268
|
+
if (names.some((name) => name.length === 0)) throw new Error("--action must contain one or more non-empty action names.");
|
|
3269
|
+
return names;
|
|
3270
|
+
}
|
|
3271
|
+
function uniqueGroupId(names, usedIds) {
|
|
3272
|
+
const base = names.join("-");
|
|
3273
|
+
let id = base;
|
|
3274
|
+
let suffix = 2;
|
|
3275
|
+
while (usedIds.has(id)) {
|
|
3276
|
+
id = `${base}-${suffix}`;
|
|
3277
|
+
suffix += 1;
|
|
3278
|
+
}
|
|
3279
|
+
usedIds.add(id);
|
|
3280
|
+
return id;
|
|
3281
|
+
}
|
|
3140
3282
|
async function defaultLoadConfigName(configPath) {
|
|
3141
3283
|
const { config } = await loadConfig(configPath);
|
|
3142
3284
|
return config.name;
|
|
@@ -3327,7 +3469,7 @@ async function resolve$1(options) {
|
|
|
3327
3469
|
configPath
|
|
3328
3470
|
};
|
|
3329
3471
|
}
|
|
3330
|
-
const BUILD_SITE_RUN_RE = /([ \t]*- id: build-site\n[ \t]+shell: bash\n[ \t]+run: \|)([\s\S]*?)(\n[ \t]*- |\n*$)/;
|
|
3472
|
+
const BUILD_SITE_RUN_RE = /([ \t]*- id: build-site\n(?:[ \t]+if: [^\n]+\n)?[ \t]+shell: bash\n[ \t]+run: \|)([\s\S]*?)(\n[ \t]*- |\n*$)/;
|
|
3331
3473
|
/**
|
|
3332
3474
|
* Strip the mutable run: body of the build-site step before hashing.
|
|
3333
3475
|
* When hasStaticWebsites is true the step is present; users are expected to
|
|
@@ -3469,7 +3611,7 @@ async function setupTarget(options) {
|
|
|
3469
3611
|
kind: resolved.kind,
|
|
3470
3612
|
workspaceName: resolved.workspaceName,
|
|
3471
3613
|
file: resolved.file,
|
|
3472
|
-
templateVersion:
|
|
3614
|
+
templateVersion: 7,
|
|
3473
3615
|
inputs: resolved.inputs,
|
|
3474
3616
|
generatedIds: resolved.render.generatedIds,
|
|
3475
3617
|
ejectedIds: existing?.ejectedIds ?? [],
|
|
@@ -3527,23 +3669,33 @@ async function setupCoordinate(options) {
|
|
|
3527
3669
|
const packageManager = detectPackageManager(outputDir);
|
|
3528
3670
|
const lock = readLock(outputDir);
|
|
3529
3671
|
if (!lock) throw new Error(".github/tailor-sdk.lock not found. Run `tailor-sdk setup action --name <name>` for each app before running setup coordinate.");
|
|
3672
|
+
const actionTargets = new Map(lock.targets.filter((t) => t.kind === "action").map((target) => [target.workspaceName, target]));
|
|
3530
3673
|
const seenNames = /* @__PURE__ */ new Set();
|
|
3531
|
-
const
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3674
|
+
const usedGroupIds = /* @__PURE__ */ new Set();
|
|
3675
|
+
const actionGroups = actions.map((actionGroup) => {
|
|
3676
|
+
const names = splitActionGroup(actionGroup);
|
|
3677
|
+
const apps = names.map((name) => {
|
|
3678
|
+
if (seenNames.has(name)) throw new Error(`Duplicate --action "${name}". Each composite action can only appear once in a coordinator.`);
|
|
3679
|
+
seenNames.add(name);
|
|
3680
|
+
const entry = actionTargets.get(name);
|
|
3681
|
+
if (!entry) throw new Error(`Action target "${name}" not found in .github/tailor-sdk.lock. Run \`tailor-sdk setup action --name ${name}\` first.`);
|
|
3682
|
+
if (names.length > 1 && entry.templateVersion < 7) throw new Error(`Action target "${name}" was generated with an older setup template. Run \`tailor-sdk setup action --name ${name} --force\` before grouping it in setup coordinate.`);
|
|
3683
|
+
validateDir(entry.inputs.dir);
|
|
3684
|
+
return {
|
|
3685
|
+
name,
|
|
3686
|
+
dir: entry.inputs.dir,
|
|
3687
|
+
hasStaticWebsites: entry.inputs.hasStaticWebsites
|
|
3688
|
+
};
|
|
3689
|
+
});
|
|
3538
3690
|
return {
|
|
3539
|
-
|
|
3540
|
-
|
|
3691
|
+
id: uniqueGroupId(names, usedGroupIds),
|
|
3692
|
+
apps
|
|
3541
3693
|
};
|
|
3542
3694
|
});
|
|
3543
3695
|
const render = renderCoordinateWorkflow({
|
|
3544
3696
|
coordinatorName,
|
|
3545
3697
|
kind: coordinateKind,
|
|
3546
|
-
|
|
3698
|
+
actionGroups,
|
|
3547
3699
|
branch: branch ?? void 0,
|
|
3548
3700
|
tagPattern: coordinateKind === "tag" ? tagPattern : void 0,
|
|
3549
3701
|
environment,
|
|
@@ -3579,7 +3731,7 @@ async function setupCoordinate(options) {
|
|
|
3579
3731
|
kind: "coordinate",
|
|
3580
3732
|
workspaceName: coordinatorName,
|
|
3581
3733
|
file,
|
|
3582
|
-
templateVersion:
|
|
3734
|
+
templateVersion: 7,
|
|
3583
3735
|
inputs: {
|
|
3584
3736
|
branch,
|
|
3585
3737
|
branchAutoDetected: coordinateKind === "branch" ? branchAutoDetected : branch !== null ? false : void 0,
|
|
@@ -3587,7 +3739,7 @@ async function setupCoordinate(options) {
|
|
|
3587
3739
|
environment,
|
|
3588
3740
|
dir: ".",
|
|
3589
3741
|
packageManager,
|
|
3590
|
-
actionDirs: apps.map((a) => a.dir)
|
|
3742
|
+
actionDirs: actionGroups.flatMap((group) => group.apps.map((a) => a.dir))
|
|
3591
3743
|
},
|
|
3592
3744
|
generatedIds: render.generatedIds,
|
|
3593
3745
|
ejectedIds: existing?.ejectedIds ?? [],
|
|
@@ -3611,8 +3763,8 @@ async function setupCoordinate(options) {
|
|
|
3611
3763
|
logger.log(` gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID --env ${environment}`);
|
|
3612
3764
|
logger.log(` gh secret set TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET --env ${environment}`);
|
|
3613
3765
|
logger.newline();
|
|
3614
|
-
logger.log(`2. Provision
|
|
3615
|
-
logger.log(" tailor-sdk workspace create #
|
|
3766
|
+
logger.log(`2. Provision the target workspace and set TAILOR_PLATFORM_WORKSPACE_ID on the "${environment}" environment:`);
|
|
3767
|
+
logger.log(" tailor-sdk workspace create # if it does not exist yet; copy the id");
|
|
3616
3768
|
logger.log(` gh variable set TAILOR_PLATFORM_WORKSPACE_ID --env ${environment}`);
|
|
3617
3769
|
logger.newline();
|
|
3618
3770
|
logger.log("3. Commit the generated files:");
|
|
@@ -3767,7 +3919,7 @@ async function checkGitHub(options) {
|
|
|
3767
3919
|
currentHash,
|
|
3768
3920
|
configExists,
|
|
3769
3921
|
defaultBranch,
|
|
3770
|
-
templateVersion:
|
|
3922
|
+
templateVersion: 7,
|
|
3771
3923
|
erdNamespaces,
|
|
3772
3924
|
hasMigrations,
|
|
3773
3925
|
hasSeeds,
|
|
@@ -3805,7 +3957,7 @@ function resolveMatch(outputDir, targets, input) {
|
|
|
3805
3957
|
}
|
|
3806
3958
|
function warnCoordinatorReferences(allTargets, deletedKeys, match) {
|
|
3807
3959
|
if (match.target.kind !== "action") return;
|
|
3808
|
-
for (const coordinator of allTargets) if (coordinator.kind === "coordinate" && coordinator.inputs.actionDirs?.includes(match.target.inputs.dir) && !deletedKeys.has(targetKey(coordinator))) logger.warn(`Coordinator "${coordinator.workspaceName}" still references this action's directory (${match.target.inputs.dir}).
|
|
3960
|
+
for (const coordinator of allTargets) if (coordinator.kind === "coordinate" && coordinator.inputs.actionDirs?.includes(match.target.inputs.dir) && !deletedKeys.has(targetKey(coordinator))) logger.warn(`Coordinator "${coordinator.workspaceName}" still references this action's directory (${match.target.inputs.dir}). Remove \`${match.target.workspaceName}\` from the relevant \`--action\` value and re-run \`tailor-sdk setup coordinate\` to update it.`);
|
|
3809
3961
|
}
|
|
3810
3962
|
/**
|
|
3811
3963
|
* Delete managed workflow/action files and their `.github/tailor-sdk.lock` entries.
|
|
@@ -3873,7 +4025,7 @@ const coordinateCommand = defineAppCommand({
|
|
|
3873
4025
|
alias: "n",
|
|
3874
4026
|
description: "Coordinator name (used in the generated workflow file name and job names)"
|
|
3875
4027
|
}),
|
|
3876
|
-
action: arg(z.array(z.string().min(1)).min(1), { description: "Composite action to include
|
|
4028
|
+
action: arg(z.array(z.string().min(1)).min(1), { description: "Composite action to include. Repeat for separate deploy steps, or use commas to deploy actions as one multi-config group. tailor- prefix optional." }),
|
|
3877
4029
|
branch: arg(z.string().min(1).optional(), { description: "Branch target: deploy trigger branch (defaults to the detected default branch)" }),
|
|
3878
4030
|
tag: arg(z.boolean().default(false), { description: "Generate a tag target coordinator" }),
|
|
3879
4031
|
environment: arg(z.string().min(1).optional(), { description: "GitHub Environment for the plan/deploy jobs" }),
|
|
@@ -6070,7 +6222,7 @@ async function fetchRemoteTypes(client, workspaceId, namespace) {
|
|
|
6070
6222
|
async function assertMigrationsReproduceLocalTypes(loaded, target) {
|
|
6071
6223
|
const { config, plugins } = loaded;
|
|
6072
6224
|
const pluginManager = plugins.length > 0 ? new PluginManager(plugins) : void 0;
|
|
6073
|
-
const { defineApplication, generatePluginFilesIfNeeded } = await import("../application-
|
|
6225
|
+
const { defineApplication, generatePluginFilesIfNeeded } = await import("../application-DbvD5UUz.mjs");
|
|
6074
6226
|
const application = defineApplication({
|
|
6075
6227
|
config,
|
|
6076
6228
|
pluginManager
|