@tailor-platform/sdk 2.0.0 → 2.1.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/CHANGELOG.md +51 -0
- package/README.md +2 -2
- package/dist/application-Af1zIqSI.mjs +3 -0
- package/dist/{application-CM6hKnSK.mjs → application-D77KJFKD.mjs} +121 -23
- package/dist/application-D77KJFKD.mjs.map +1 -0
- package/dist/cli/lib.mjs +2 -2
- package/dist/cli/main.mjs +33 -20
- package/dist/cli/main.mjs.map +1 -1
- package/dist/completion/zsh-worker.zsh +1 -1
- package/dist/configure/config/types.d.mts +12 -1
- package/dist/configure/index.d.mts +1 -1
- package/dist/configure/services/index.d.mts +1 -1
- package/dist/configure/services/resolver/index.d.mts +1 -1
- package/dist/configure/services/resolver/resolver.d.mts +1 -1
- package/dist/{globals-TfAVItuK.mjs → globals-B2nlxBrz.mjs} +2 -10
- package/dist/globals-B2nlxBrz.mjs.map +1 -0
- package/dist/{register-ts-hook-LYV7zH-e.mjs → register-ts-hook-BU18uU44.mjs} +3 -3
- package/dist/{register-ts-hook-LYV7zH-e.mjs.map → register-ts-hook-BU18uU44.mjs.map} +1 -1
- package/dist/runtime/globals.d.mts +0 -7
- package/dist/runtime/workflow.d.mts +2 -7
- package/dist/utils/test/index.d.mts +3 -0
- package/dist/utils/test/index.mjs +24 -12
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/mocks/file.d.mts +1 -1
- package/dist/vitest/setup.mjs +1 -1
- package/dist/workflow-Bamae_Yc.mjs.map +1 -1
- package/docs/configuration.md +3 -0
- package/docs/migration/v2.md +6 -3
- package/docs/quickstart.md +5 -5
- package/docs/services/resolver.md +32 -0
- package/docs/testing.md +1 -1
- package/package.json +5 -5
- package/dist/application-CM6hKnSK.mjs.map +0 -1
- package/dist/application-CXNaUNhv.mjs +0 -3
- package/dist/globals-TfAVItuK.mjs.map +0 -1
package/dist/cli/lib.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as assertDefined } from "../assert-DBxo8jPo.mjs";
|
|
2
|
-
import { $ as getOrganization, A as truncate, At as getExecutorJob, B as show, Bt as getWorkflowExecution, Cn as createSnapshotFromLocalTypes, Ct as getFunctionRegistry, D as resumeWorkflow, Dn as getMigrationFilePath, Dt as triggerExecutor, En as getMigrationDirPath, Fn as formatMigrationDiff, Gn as generateUserTypes, Gt as deploy, In as hasChanges, It as startWorkflow, J as organizationTree, Jn as assertWritable, Jt as listWorkspaces, Ln as getNamespacesWithMigrations, M as generate$1, Nt as listExecutorJobs, On as getMigrationFiles, Pn as formatDiffSummary, Pt as watchExecutorJob, Rt as getWorkflow, S as getAppHealth, Sn as compareSnapshots, T as waitWorkflowExecution, Tn as getLatestMigrationNumber, Vt as listWorkflowExecutions, W as remove, Wn as PluginManager, Wt as getExecutor, Xt as createWorkspace, Yn as loadConfig, Z as listOrganizations, _ as getWorkspace, _n as MIGRATE_FILE_NAME, _t as listMachineUsers, at as getFolder, b as listApps, d as listUsers, dt as listOAuth2Clients, en as executeScript, er as loadAccessToken, gn as INITIAL_SCHEMA_NUMBER, h as restoreWorkspace, hn as DIFF_FILE_NAME, i as query, jn as reconstructSnapshotFromMigrations, jt as getExecutorWaitFailureMessage, k as listWorkflows, kn as getNextMigrationNumber, kt as listExecutors, l as removeUser, lt as createFolder, mn as DB_TYPES_FILE_NAME, mt as getMachineUserToken, n as errorToJson, nn as bundleMigrationScript, or as loadWorkspaceId, p as inviteUser, pt as getOAuth2Client, q as updateOrganization, qn as apiCall, r as serializeError, rt as listFolders, s as updateUser, sn as MIGRATION_LABEL_KEY, st as deleteFolder, t as registerTsHook, tn as waitForExecution, tt as updateFolder, vn as SCHEMA_FILE_NAME, vt as generate, wt as listWebhookExecutors, xn as compareLocalTypesWithSnapshot, xt as listFunctionRegistries, y as deleteWorkspace, yt as getAuthInput, z as deployStaticWebsite } from "../register-ts-hook-
|
|
3
|
-
import {
|
|
2
|
+
import { $ as getOrganization, A as truncate, At as getExecutorJob, B as show, Bt as getWorkflowExecution, Cn as createSnapshotFromLocalTypes, Ct as getFunctionRegistry, D as resumeWorkflow, Dn as getMigrationFilePath, Dt as triggerExecutor, En as getMigrationDirPath, Fn as formatMigrationDiff, Gn as generateUserTypes, Gt as deploy, In as hasChanges, It as startWorkflow, J as organizationTree, Jn as assertWritable, Jt as listWorkspaces, Ln as getNamespacesWithMigrations, M as generate$1, Nt as listExecutorJobs, On as getMigrationFiles, Pn as formatDiffSummary, Pt as watchExecutorJob, Rt as getWorkflow, S as getAppHealth, Sn as compareSnapshots, T as waitWorkflowExecution, Tn as getLatestMigrationNumber, Vt as listWorkflowExecutions, W as remove, Wn as PluginManager, Wt as getExecutor, Xt as createWorkspace, Yn as loadConfig, Z as listOrganizations, _ as getWorkspace, _n as MIGRATE_FILE_NAME, _t as listMachineUsers, at as getFolder, b as listApps, d as listUsers, dt as listOAuth2Clients, en as executeScript, er as loadAccessToken, gn as INITIAL_SCHEMA_NUMBER, h as restoreWorkspace, hn as DIFF_FILE_NAME, i as query, jn as reconstructSnapshotFromMigrations, jt as getExecutorWaitFailureMessage, k as listWorkflows, kn as getNextMigrationNumber, kt as listExecutors, l as removeUser, lt as createFolder, mn as DB_TYPES_FILE_NAME, mt as getMachineUserToken, n as errorToJson, nn as bundleMigrationScript, or as loadWorkspaceId, p as inviteUser, pt as getOAuth2Client, q as updateOrganization, qn as apiCall, r as serializeError, rt as listFolders, s as updateUser, sn as MIGRATION_LABEL_KEY, st as deleteFolder, t as registerTsHook, tn as waitForExecution, tt as updateFolder, vn as SCHEMA_FILE_NAME, vt as generate, wt as listWebhookExecutors, xn as compareLocalTypesWithSnapshot, xt as listFunctionRegistries, y as deleteWorkspace, yt as getAuthInput, z as deployStaticWebsite } from "../register-ts-hook-BU18uU44.mjs";
|
|
3
|
+
import { A as getDistDir, E as createBundleLog, K as initOperatorClient, S as platformBundleDefinePlugin, b as createTsconfigPathsPlugin, g as assertUniqueLocalTailorDBTypeNames, t as defineApplication, y as createGeneratedEntryResolverPlugin } from "../application-D77KJFKD.mjs";
|
|
4
4
|
import { t as multiline } from "../multiline-sfHpTZZK.mjs";
|
|
5
5
|
import { t as isPluginGeneratedType } from "../type-source-DH_LH20p.mjs";
|
|
6
6
|
import { a as generateIdpTruncateScriptCode, i as generateIdpSeedScriptCode, o as processIdpUser, r as processLinesDb, t as SeedGeneratorID } from "../seed-B-yckgQY.mjs";
|
package/dist/cli/main.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import { r as parseInputFields } from "../schema--xYWRGfe.mjs";
|
|
|
3
3
|
import { At as PATScope, Ct as AuthInvokerSchema, E as CustomDomainStatus, W as FunctionExecution_Type } from "../workspace_resource_pb-DXnO2AT-.mjs";
|
|
4
4
|
import { t as assertDefined } from "../assert-DBxo8jPo.mjs";
|
|
5
5
|
import { n as logger, r as styles } from "../logger-CXQq9YIp.mjs";
|
|
6
|
-
import { $n as hasUserTokenEntry, $t as ensureConfigId, An as loadDiff, Bn as sdkAppIdLabelKey, C as healthCommand, Cn as createSnapshotFromLocalTypes, Cr as resolveMachineUserInputSource, Dn as getMigrationFilePath, E as resumeCommand, Et as triggerCommand, F as writeDbTypesFile, Fn as formatMigrationDiff, Ft as startCommand, G as removeCommand$1, H as extractOwnedNamespaces, Hn as sdkVersionLabelKey, Ht as functionExecutionStatusToString, I as getConfiguredEditorCommand, In as hasChanges, Jn as assertWritable, K as updateCommand$3, Kn as prompt, Kt as deployFromCLI, L as openInConfiguredEditor, Ln as getNamespacesWithMigrations, Lt as getCommand$6, Mn as formatMigrationNumber, Mt as jobsCommand, N as generateCommand$1, Nn as parseMigrationNumberArg, O as listCommand$14, On as getMigrationFiles, Ot as listCommand$8, P as generateMigrationScript, Pn as formatDiffSummary, Q as getCommand$5, Qn as hasAnyUserTokenEntry, Qt as workspaceNameSchema, R as deployCommand$1, Rn as selectTargetNamespace, Sr as paginationArgs, St as getCommand$2, Tr as workspaceArgs, Tt as webhookCommand, U as logBetaWarning, Un as writeMetadataLabels, Ut as getCommand$1, V as showCommand, Vn as sdkNameLabelKey, Wn as PluginManager, X as listCommand$13, Xn as deleteUserTokens, Y as treeCommand, Yn as loadConfig, Yt as createCommand$4, Zn as fetchLatestToken, Zt as formatKeyValueTable, _r as confirmationArgs, a as queryCommand, an as toTailorDBDeployInput, ar as loadStoredUserTokens, bn as assertValidMigrationFiles, br as multiConfigArg, bt as listCommand$9, c as removeCommand, cn as handleOptionalToRequiredError, cr as readPlatformConfig, ct as createCommand$3, dn as compareSnapshotWithRemote, dr as resolveUserTokenKey, en as executeScript, er as loadAccessToken, et as updateCommand$2, f as inviteCommand, fn as generateAllTypeManifestsFromSnapshot, fr as saveUserTokens, ft as getCommand$3, g as getCommand$7, gn as INITIAL_SCHEMA_NUMBER, gr as configArg, gt as listCommand$10, hr as commonArgs, ht as tokenCommand$1, in as logRemoteDriftGuidance, ir as loadPlatformClientConfig, it as getCommand$4, j as truncateCommand, jn as reconstructSnapshotFromMigrations, ln as parseMigrationLabelNumber, lr as removeLegacyUserAlias, m as restoreCommand, mr as defineAppCommand, nr as loadConsoleBaseUrl, nt as listCommand$12, o as updateCommand$4, on as verifyRemoteSchema, or as loadWorkspaceId, ot as deleteCommand$4, pn as protoGqlPermission, pr as writePlatformConfig, qn as apiCall, qt as listCommand$17, r as serializeError, rn as checkMigrationDiffs, rr as loadMachineUserName, sn as MIGRATION_LABEL_KEY, sr as platformConfigFromProfile, t as registerTsHook, tr as loadConfigPath, u as listCommand$16, un as sanitizeMigrationLabel, ur as resolveConfigUser, ut as listCommand$11, v as deleteCommand$5, vr as deploymentArgs, vt as generate, w as waitCommand, wn as formatSchemaDrifts, wr as toPageDirection, x as listCommand$15, xn as compareLocalTypesWithSnapshot, xr as pagedLogArgs, yn as assertMigrationNumberExists, yr as isVerbose, zn as resourceTrn, zt as executionsCommand } from "../register-ts-hook-
|
|
7
|
-
import { C as
|
|
6
|
+
import { $n as hasUserTokenEntry, $t as ensureConfigId, An as loadDiff, Bn as sdkAppIdLabelKey, C as healthCommand, Cn as createSnapshotFromLocalTypes, Cr as resolveMachineUserInputSource, Dn as getMigrationFilePath, E as resumeCommand, Et as triggerCommand, F as writeDbTypesFile, Fn as formatMigrationDiff, Ft as startCommand, G as removeCommand$1, H as extractOwnedNamespaces, Hn as sdkVersionLabelKey, Ht as functionExecutionStatusToString, I as getConfiguredEditorCommand, In as hasChanges, Jn as assertWritable, K as updateCommand$3, Kn as prompt, Kt as deployFromCLI, L as openInConfiguredEditor, Ln as getNamespacesWithMigrations, Lt as getCommand$6, Mn as formatMigrationNumber, Mt as jobsCommand, N as generateCommand$1, Nn as parseMigrationNumberArg, O as listCommand$14, On as getMigrationFiles, Ot as listCommand$8, P as generateMigrationScript, Pn as formatDiffSummary, Q as getCommand$5, Qn as hasAnyUserTokenEntry, Qt as workspaceNameSchema, R as deployCommand$1, Rn as selectTargetNamespace, Sr as paginationArgs, St as getCommand$2, Tr as workspaceArgs, Tt as webhookCommand, U as logBetaWarning, Un as writeMetadataLabels, Ut as getCommand$1, V as showCommand, Vn as sdkNameLabelKey, Wn as PluginManager, X as listCommand$13, Xn as deleteUserTokens, Y as treeCommand, Yn as loadConfig, Yt as createCommand$4, Zn as fetchLatestToken, Zt as formatKeyValueTable, _r as confirmationArgs, a as queryCommand, an as toTailorDBDeployInput, ar as loadStoredUserTokens, bn as assertValidMigrationFiles, br as multiConfigArg, bt as listCommand$9, c as removeCommand, cn as handleOptionalToRequiredError, cr as readPlatformConfig, ct as createCommand$3, dn as compareSnapshotWithRemote, dr as resolveUserTokenKey, en as executeScript, er as loadAccessToken, et as updateCommand$2, f as inviteCommand, fn as generateAllTypeManifestsFromSnapshot, fr as saveUserTokens, ft as getCommand$3, g as getCommand$7, gn as INITIAL_SCHEMA_NUMBER, gr as configArg, gt as listCommand$10, hr as commonArgs, ht as tokenCommand$1, in as logRemoteDriftGuidance, ir as loadPlatformClientConfig, it as getCommand$4, j as truncateCommand, jn as reconstructSnapshotFromMigrations, ln as parseMigrationLabelNumber, lr as removeLegacyUserAlias, m as restoreCommand, mr as defineAppCommand, nr as loadConsoleBaseUrl, nt as listCommand$12, o as updateCommand$4, on as verifyRemoteSchema, or as loadWorkspaceId, ot as deleteCommand$4, pn as protoGqlPermission, pr as writePlatformConfig, qn as apiCall, qt as listCommand$17, r as serializeError, rn as checkMigrationDiffs, rr as loadMachineUserName, sn as MIGRATION_LABEL_KEY, sr as platformConfigFromProfile, t as registerTsHook, tr as loadConfigPath, u as listCommand$16, un as sanitizeMigrationLabel, ur as resolveConfigUser, ut as listCommand$11, v as deleteCommand$5, vr as deploymentArgs, vt as generate, w as waitCommand, wn as formatSchemaDrifts, wr as toPageDirection, x as listCommand$15, xn as compareLocalTypesWithSnapshot, xr as pagedLogArgs, yn as assertMigrationNumberExists, yr as isVerbose, zn as resourceTrn, zt as executionsCommand } from "../register-ts-hook-BU18uU44.mjs";
|
|
7
|
+
import { A as getDistDir, B as fetchUserInfo, C as composeFunctionTreeshakeOptions, E as createBundleLog, F as fetchAll, G as initOAuth2Client, H as getOAuth2ClientId, I as fetchAllTolerant, K as initOperatorClient, N as closeConnectionPool, P as defaultPlatformBaseUrl, R as fetchPaged, S as platformBundleDefinePlugin, T as resolveBundleLogLevel, U as getOrNull, W as getPlatformBaseUrl, a as resolveInlineSourcemap, b as createTsconfigPathsPlugin, c as WorkflowJobSchema, f as INVOKER_EXPR, g as assertUniqueLocalTailorDBTypeNames, h as buildResolverPermissionAndInputCheckExpr, l as resolveResolverDefaultPermissionForFile, q as isDefaultPlatform, u as ResolverSchema, w as createLogLevelTreeshakeOptions, x as resolveTSConfigWithFallback, y as createGeneratedEntryResolverPlugin, z as fetchPlatformMachineUserToken } from "../application-D77KJFKD.mjs";
|
|
8
8
|
import { i as ExecutorSchema, r as stripExecutorTriggerArgs } from "../service-k1xy_A5G.mjs";
|
|
9
9
|
import { t as multiline } from "../multiline-sfHpTZZK.mjs";
|
|
10
10
|
import { t as readPackageJson } from "../package-json-8b0O9TlX.mjs";
|
|
@@ -1694,7 +1694,14 @@ async function bundleForTestRun(options) {
|
|
|
1694
1694
|
const baseName = `test-run--${detected.name}`;
|
|
1695
1695
|
const scriptName = `${baseName}.js`;
|
|
1696
1696
|
const entryPath = path.join(outputDir, `${baseName}.entry.js`);
|
|
1697
|
-
const entryContent = generateEntry(
|
|
1697
|
+
const entryContent = generateEntry({
|
|
1698
|
+
detected,
|
|
1699
|
+
sourceFile,
|
|
1700
|
+
env,
|
|
1701
|
+
machineUser,
|
|
1702
|
+
workspaceId,
|
|
1703
|
+
defaultPermission: options.defaultPermission
|
|
1704
|
+
});
|
|
1698
1705
|
fs.writeFileSync(entryPath, entryContent);
|
|
1699
1706
|
const tsconfig = await resolveTSConfigWithFallback(baseDir);
|
|
1700
1707
|
const bundleLog = createBundleLog({ tsconfig });
|
|
@@ -1725,14 +1732,11 @@ async function bundleForTestRun(options) {
|
|
|
1725
1732
|
}
|
|
1726
1733
|
/**
|
|
1727
1734
|
* Generate entry file content based on the detected function type.
|
|
1728
|
-
* @param
|
|
1729
|
-
* @param sourceFile - Absolute path to the source file
|
|
1730
|
-
* @param env - Environment variables for workflow job bundles
|
|
1731
|
-
* @param machineUser - Resolved machine user info
|
|
1732
|
-
* @param workspaceId - Workspace ID
|
|
1735
|
+
* @param options - Detected function info and the context embedded into the entry
|
|
1733
1736
|
* @returns Entry file content string
|
|
1734
1737
|
*/
|
|
1735
|
-
function generateEntry(
|
|
1738
|
+
function generateEntry(options) {
|
|
1739
|
+
const { detected, sourceFile, env, machineUser, workspaceId, defaultPermission } = options;
|
|
1736
1740
|
const absoluteSourcePath = path.resolve(sourceFile);
|
|
1737
1741
|
switch (detected.type) {
|
|
1738
1742
|
case "plain":
|
|
@@ -1745,7 +1749,10 @@ function generateEntry(detected, sourceFile, env, machineUser, workspaceId) {
|
|
|
1745
1749
|
`;
|
|
1746
1750
|
case "resolver": {
|
|
1747
1751
|
const principalExpr = buildMachinePrincipalExpr(machineUser, workspaceId);
|
|
1748
|
-
const guardAndInputCheckExpr = buildResolverPermissionAndInputCheckExpr(
|
|
1752
|
+
const guardAndInputCheckExpr = buildResolverPermissionAndInputCheckExpr({
|
|
1753
|
+
permission: detected.permission,
|
|
1754
|
+
defaultPermission
|
|
1755
|
+
});
|
|
1749
1756
|
return multiline`
|
|
1750
1757
|
import _internalResolver from "${absoluteSourcePath}";
|
|
1751
1758
|
import { t } from "@tailor-platform/sdk";
|
|
@@ -2027,10 +2034,16 @@ When a \`.js\` file is provided, detection and bundling are skipped and the file
|
|
|
2027
2034
|
args.arg = void 0;
|
|
2028
2035
|
}
|
|
2029
2036
|
logger.info("Bundling...");
|
|
2037
|
+
const baseDir = path.dirname(config.path);
|
|
2030
2038
|
({bundledCode, scriptName} = await bundleForTestRun({
|
|
2031
2039
|
detected,
|
|
2032
2040
|
sourceFile: filePath,
|
|
2033
|
-
baseDir
|
|
2041
|
+
baseDir,
|
|
2042
|
+
defaultPermission: detected.type === "resolver" ? resolveResolverDefaultPermissionForFile({
|
|
2043
|
+
config: config.resolver,
|
|
2044
|
+
filePath,
|
|
2045
|
+
baseDir
|
|
2046
|
+
}) : void 0,
|
|
2034
2047
|
env: config.env ?? {},
|
|
2035
2048
|
inlineSourcemap: config.inlineSourcemap,
|
|
2036
2049
|
logLevel: config.logLevel,
|
|
@@ -3871,7 +3884,7 @@ var action_default = "# __HEADER__\nname: __WORKSPACE_NAME__\ndescription: >-\n
|
|
|
3871
3884
|
|
|
3872
3885
|
//#endregion
|
|
3873
3886
|
//#region src/cli/commands/setup/branch.workflow.yml
|
|
3874
|
-
var branch_workflow_default = "# __HEADER__\nname: Tailor (__WORKSPACE_NAME__)\n\non:\n # __PULL_REQUEST_START__\n pull_request:\n branches: [\"__BRANCH__\"]\n # __PATHS__\n # __PULL_REQUEST_END__\n push:\n branches: [\"__BRANCH__\"]\n # __PATHS__\n workflow_dispatch:\n # __DISPATCH_INPUTS_START__\n inputs:\n dry-run:\n description: Preview changes without deploying\n type: boolean\n default: false\n # __DISPATCH_INPUTS_END__\n\npermissions:\n contents: read\n\njobs:\n # __PLAN_JOB_START__\n tailor-plan:\n if: >-\n github.event_name == 'pull_request' ||\n (github.event_name == 'workflow_dispatch' && inputs['dry-run'])\n runs-on: ubuntu-latest\n timeout-minutes: 30\n environment: __ENVIRONMENT__\n permissions:\n contents: read\n pull-requests: write\n concurrency:\n group: tailor-plan-__WORKSPACE_NAME__-${{ github.event.pull_request.number || github.run_id }}\n cancel-in-progress: true\n steps:\n - id: tailor-checkout\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n - id: tailor-setup\n uses: tailor-platform/actions/setup@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-install\n uses: tailor-platform/actions/install@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-generate-check\n uses: tailor-platform/actions/generate-check@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __SEED_VALIDATE_START__\n - id: tailor-seed-validate\n run: __TAILOR_CLI__ seed validate\n # __WORKING_DIRECTORY__\n # __SEED_VALIDATE_END__\n - id: tailor-drift-check\n uses: tailor-platform/actions/drift-check@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __MIGRATION_DRIFT_CHECK_START__\n - id: tailor-migration-drift-check\n uses: tailor-platform/actions/migration-drift-check@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __MIGRATION_DRIFT_CHECK_END__\n - id: tailor-plan\n # Fork PRs cannot read secrets; the checks above still run for them.\n if: github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork\n uses: tailor-platform/actions/plan@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n workspace-id: ${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}\n package-manager: __PACKAGE_MANAGER__\n label: __WORKSPACE_NAME__\n # __WORKING_DIRECTORY__\n platform-client-id: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}\n platform-client-secret: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}\n github-token: ${{ secrets.GITHUB_TOKEN }}\n # __PLAN_JOB_END__\n # __ERD_PREVIEW_JOB_START__\n tailor-erd-preview-matrix:\n if: github.event_name == 'pull_request'\n runs-on: ubuntu-latest\n timeout-minutes: 5\n permissions:\n contents: read\n outputs:\n namespaces: ${{ steps.tailor-erd-preview-matrix.outputs.namespaces }}\n base-app-dir: ${{ steps.tailor-erd-preview-matrix.outputs['base-app-dir'] }}\n steps:\n - id: tailor-checkout\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n with:\n persist-credentials: false\n - id: tailor-checkout-base\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n with:\n repository: ${{ github.event.pull_request.base.repo.full_name }}\n ref: ${{ github.event.pull_request.base.sha }}\n path: .tailor-erd-base\n persist-credentials: false\n - id: tailor-erd-preview-matrix\n shell: bash\n env:\n APP_DIR: \"__APP_DIR__\"\n WORKSPACE_NAME: \"__WORKSPACE_NAME__\"\n run: |\n set -euo pipefail\n node <<'NODE'\n const fs = require(\"node:fs\");\n\n const appDir = process.env.APP_DIR || \".\";\n const workspaceName = process.env.WORKSPACE_NAME;\n const output = process.env.GITHUB_OUTPUT;\n const dirPattern = /^[A-Za-z0-9._/-]+$/;\n const namespacePattern = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\n\n function lockTarget(file) {\n try {\n const lock = JSON.parse(fs.readFileSync(file, \"utf8\"));\n return lock.targets?.find(\n (candidate) =>\n candidate.kind === \"branch\" &&\n candidate.workspaceName === workspaceName,\n );\n } catch (error) {\n if (error && error.code === \"ENOENT\") return undefined;\n throw error;\n }\n }\n\n function namespacesFromTarget(target, label) {\n const namespaces =\n target?.inputs?.erdPreview === true && Array.isArray(target.inputs?.erdNamespaces)\n ? target.inputs.erdNamespaces\n : [];\n for (const namespace of namespaces) {\n if (typeof namespace !== \"string\" || !namespacePattern.test(namespace)) {\n throw new Error(`Invalid ERD namespace in ${label}: ${String(namespace)}`);\n }\n }\n return namespaces;\n }\n\n function normalizeDir(value, label) {\n const raw = typeof value === \"string\" && value.length > 0 ? value : appDir;\n const normalized =\n raw.replaceAll(\"\\\\\", \"/\").replace(/\\/{2,}/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/$/, \"\") ||\n \".\";\n if (\n !dirPattern.test(normalized) ||\n normalized.startsWith(\"/\") ||\n normalized.split(\"/\").includes(\"..\")\n ) {\n throw new Error(`Invalid ERD app dir in ${label}: ${raw}`);\n }\n return normalized;\n }\n\n const headTarget = lockTarget(\".github/tailor.lock\");\n const baseTarget = lockTarget(\".tailor-erd-base/.github/tailor.lock\");\n const baseAppDir = normalizeDir(baseTarget?.inputs?.dir, \"base setup lock\");\n const namespaces = [\n ...new Set([\n ...namespacesFromTarget(headTarget, \"head setup lock\"),\n ...namespacesFromTarget(baseTarget, \"base setup lock\"),\n ]),\n ].sort((a, b) => a.localeCompare(b));\n\n if (namespaces.length === 0) {\n console.error(\"No ERD preview namespaces found in the head or base setup lock.\");\n process.exit(1);\n }\n\n fs.appendFileSync(output, `namespaces=${JSON.stringify(namespaces)}\\n`);\n fs.appendFileSync(output, `base-app-dir=${baseAppDir}\\n`);\n NODE\n\n tailor-erd-preview:\n needs: tailor-erd-preview-matrix\n if: github.event_name == 'pull_request'\n runs-on: ubuntu-latest\n timeout-minutes: 15\n permissions:\n contents: read\n strategy:\n fail-fast: false\n matrix:\n namespace: ${{ fromJSON(needs.tailor-erd-preview-matrix.outputs.namespaces) }}\n steps:\n - id: tailor-checkout\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n with:\n persist-credentials: false\n - id: tailor-setup\n uses: tailor-platform/actions/setup@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-checkout-base\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n with:\n repository: ${{ github.event.pull_request.base.repo.full_name }}\n ref: ${{ github.event.pull_request.base.sha }}\n path: .tailor-erd-base\n persist-credentials: false\n - id: tailor-detect-base-package-manager\n shell: bash\n run: |\n set -euo pipefail\n cd .tailor-erd-base\n base_package_manager=\"$(\n if [ -f pnpm-lock.yaml ]; then\n echo pnpm\n elif [ -f yarn.lock ]; then\n echo yarn\n elif [ -f bun.lockb ] || [ -f bun.lock ]; then\n echo bun\n elif [ -f package-lock.json ]; then\n echo npm\n else\n echo \"__PACKAGE_MANAGER__\"\n fi\n )\"\n echo \"package-manager=$base_package_manager\" >> \"$GITHUB_OUTPUT\"\n if [ \"$base_package_manager\" = \"pnpm\" ]; then\n base_pnpm_version=\"$(node <<'NODE'\n const fs = require(\"node:fs\");\n\n const fallback = \"10\";\n\n function readManifest(file) {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return {};\n }\n }\n\n function pnpmVersion(manifest) {\n const packageManager = manifest.packageManager;\n if (typeof packageManager === \"string\" && packageManager.startsWith(\"pnpm@\")) {\n return packageManager.slice(\"pnpm@\".length).split(\"+\")[0];\n }\n\n const devPackageManager = manifest.devEngines?.packageManager;\n if (devPackageManager?.name === \"pnpm\" && devPackageManager.version) {\n return devPackageManager.version;\n }\n\n return undefined;\n }\n\n process.stdout.write(\n pnpmVersion(readManifest(\"package.json\")) ?? fallback,\n );\n NODE\n )\"\n echo \"pnpm-version=$base_pnpm_version\" >> \"$GITHUB_OUTPUT\"\n fi\n - id: tailor-setup-base-pnpm\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'pnpm'\n uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9\n with:\n version: ${{ steps.tailor-detect-base-package-manager.outputs['pnpm-version'] }}\n package_json_file: .tailor-erd-base/package.json\n run_install: false\n - id: tailor-setup-base-node\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] != 'bun'\n uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7\n with:\n node-version-file: .tailor-erd-base/package.json\n - id: tailor-setup-base-yarn\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'yarn'\n shell: bash\n working-directory: .tailor-erd-base\n run: |\n set -euo pipefail\n corepack enable\n - id: tailor-setup-base-bun\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'bun'\n uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0\n - id: tailor-install-base\n shell: bash\n working-directory: .tailor-erd-base\n env:\n BASE_PACKAGE_MANAGER: ${{ steps.tailor-detect-base-package-manager.outputs['package-manager'] }}\n run: |\n set -euo pipefail\n case \"$BASE_PACKAGE_MANAGER\" in\n pnpm) pnpm install --frozen-lockfile ;;\n npm) npm ci ;;\n yarn)\n if grep -q '^__metadata:' yarn.lock; then\n yarn install --immutable\n else\n yarn install --frozen-lockfile\n fi\n ;;\n bun) bun install --frozen-lockfile ;;\n *)\n echo \"::error::Unsupported base package-manager '$BASE_PACKAGE_MANAGER' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n - id: tailor-restore-head-setup\n uses: tailor-platform/actions/setup@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-build-erd-preview\n shell: bash\n env:\n APP_DIR: \"__APP_DIR__\"\n BASE_APP_DIR: ${{ needs.tailor-erd-preview-matrix.outputs['base-app-dir'] }}\n BASE_PACKAGE_MANAGER: ${{ steps.tailor-detect-base-package-manager.outputs['package-manager'] }}\n NAMESPACE: ${{ matrix.namespace }}\n run: |\n set -euo pipefail\n\n run_tailor_cli() {\n case \"__PACKAGE_MANAGER__\" in\n pnpm) pnpm exec tailor \"$@\" ;;\n npm) npx tailor \"$@\" ;;\n yarn) yarn tailor \"$@\" ;;\n bun) bunx tailor \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n }\n\n run_head_node() {\n case \"__PACKAGE_MANAGER__\" in\n pnpm) pnpm exec node \"$@\" ;;\n npm) node \"$@\" ;;\n yarn) yarn node \"$@\" ;;\n bun) node \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n }\n\n tailor_cli_bin=\"$(\n run_head_node - <<'NODE'\n const path = require(\"node:path\");\n const { createRequire } = require(\"node:module\");\n const appDir = process.env.APP_DIR || \".\";\n const githubWorkspace = process.env.GITHUB_WORKSPACE;\n if (!githubWorkspace) {\n throw new Error(\"GITHUB_WORKSPACE is required.\");\n }\n\n let lastError;\n for (const manifestPath of [\n path.join(githubWorkspace, appDir, \"package.json\"),\n path.join(githubWorkspace, \"package.json\"),\n ]) {\n try {\n const requireFromManifest = createRequire(manifestPath);\n process.stdout.write(\n path.join(\n path.dirname(requireFromManifest.resolve(\"@tailor-platform/sdk/cli\")),\n \"index.mjs\",\n ),\n );\n process.exit(0);\n } catch (error) {\n lastError = error;\n }\n }\n throw lastError || new Error(\"Failed to resolve @tailor-platform/sdk/cli.\");\n NODE\n )\"\n\n run_head_tailor_cli_bin() {\n local command_cwd=\"$1\"\n shift\n\n run_head_cli_env() {\n env TAILOR_CLI_BIN=\"$tailor_cli_bin\" TAILOR_CLI_CWD=\"$command_cwd\" \"$@\"\n }\n\n (\n cd \"$GITHUB_WORKSPACE\" || exit 1\n case \"__PACKAGE_MANAGER__\" in\n pnpm) run_head_cli_env pnpm exec node \"$head_cli_runner\" \"$@\" ;;\n npm) run_head_cli_env node \"$head_cli_runner\" \"$@\" ;;\n yarn) run_head_cli_env yarn node \"$head_cli_runner\" \"$@\" ;;\n bun) run_head_cli_env bun \"$head_cli_runner\" \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n )\n }\n\n run_base_tailor_cli_bin() {\n local command_cwd=\"$1\"\n shift\n\n run_head_cli_env() {\n env TAILOR_CLI_BIN=\"$tailor_cli_bin\" TAILOR_CLI_CWD=\"$command_cwd\" \"$@\"\n }\n\n (\n cd \"$command_cwd\" || exit 1\n case \"$BASE_PACKAGE_MANAGER\" in\n pnpm) run_head_cli_env pnpm exec node \"$head_cli_runner\" \"$@\" ;;\n npm) run_head_cli_env node \"$head_cli_runner\" \"$@\" ;;\n yarn) run_head_cli_env yarn node \"$head_cli_runner\" \"$@\" ;;\n bun) run_head_cli_env bun \"$head_cli_runner\" \"$@\" ;;\n *)\n echo \"::error::Unsupported base package-manager '$BASE_PACKAGE_MANAGER' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n )\n }\n\n head_output=\"$RUNNER_TEMP/tailor-erd/head\"\n base_output=\"$RUNNER_TEMP/tailor-erd/base\"\n preview_output=\"$RUNNER_TEMP/tailor-erd/preview\"\n dts_output=\"$RUNNER_TEMP/tailor-erd/dts\"\n head_cli_runner=\"$RUNNER_TEMP/tailor-erd/run-head-cli.mjs\"\n head_log=\"$RUNNER_TEMP/tailor-erd/head-$NAMESPACE.log\"\n base_log=\"$RUNNER_TEMP/tailor-erd/base-$NAMESPACE.log\"\n rm -rf \"$head_output\" \"$base_output\" \"$preview_output\" \"$dts_output\"\n mkdir -p \"$head_output\" \"$base_output\" \"$preview_output\" \"$dts_output\"\n cat > \"$head_cli_runner\" <<'NODE'\n import { pathToFileURL } from \"node:url\";\n\n const cliBin = process.env.TAILOR_CLI_BIN;\n const commandCwd = process.env.TAILOR_CLI_CWD;\n if (!cliBin || !commandCwd) {\n throw new Error(\"TAILOR_CLI_BIN and TAILOR_CLI_CWD are required.\");\n }\n\n process.chdir(commandCwd);\n process.argv = [process.argv[0], cliBin, ...process.argv.slice(2)];\n await import(pathToFileURL(cliBin).href);\n NODE\n\n head_config=\"$GITHUB_WORKSPACE/$APP_DIR/tailor.config.ts\"\n base_config=\"$GITHUB_WORKSPACE/.tailor-erd-base/$BASE_APP_DIR/tailor.config.ts\"\n head_html=\"$head_output/$NAMESPACE/dist/index.html\"\n base_html=\"$base_output/$NAMESPACE/dist/index.html\"\n preview_html=\"$preview_output/$NAMESPACE-viewer.html\"\n\n head_missing=\"false\"\n if [ ! -f \"$head_config\" ]; then\n echo \"Head ERD config not found; rendering base objects as removed.\"\n head_missing=\"true\"\n elif ! (\n cd \"$GITHUB_WORKSPACE/$APP_DIR\" || exit 1\n TAILOR_PLATFORM_SDK_DTS_PATH=\"$dts_output/head-$NAMESPACE.d.ts\" \\\n run_tailor_cli tailordb erd export --config \"$head_config\" --namespace \"$NAMESPACE\" --output \"$head_output\"\n ) >\"$head_log\" 2>&1; then\n if grep -q 'not found in local config.db' \"$head_log\"; then\n cat \"$head_log\"\n echo \"Head ERD namespace '$NAMESPACE' not found; rendering base objects as removed.\"\n head_missing=\"true\"\n else\n cat \"$head_log\"\n exit 1\n fi\n elif [ -s \"$head_log\" ]; then\n cat \"$head_log\"\n fi\n\n base_missing=\"false\"\n if [ ! -f \"$base_config\" ]; then\n echo \"Base ERD config not found; rendering current objects as added.\"\n base_missing=\"true\"\n elif ! (\n TAILOR_PLATFORM_SDK_DTS_PATH=\"$dts_output/base-$NAMESPACE.d.ts\" \\\n run_base_tailor_cli_bin \"$GITHUB_WORKSPACE/.tailor-erd-base/$BASE_APP_DIR\" tailordb erd export --config \"$base_config\" --namespace \"$NAMESPACE\" --output \"$base_output\"\n ) >\"$base_log\" 2>&1; then\n if grep -q 'not found in local config.db' \"$base_log\"; then\n cat \"$base_log\"\n echo \"Base ERD namespace '$NAMESPACE' not found; rendering current objects as added.\"\n base_missing=\"true\"\n else\n cat \"$base_log\"\n exit 1\n fi\n elif [ -s \"$base_log\" ]; then\n cat \"$base_log\"\n fi\n\n if [ \"$head_missing\" = \"true\" ] && [ \"$base_missing\" = \"true\" ]; then\n echo \"::error::ERD namespace '$NAMESPACE' was not found in head or base.\"\n exit 1\n fi\n if [ \"$head_missing\" = \"false\" ] && [ ! -f \"$head_html\" ]; then\n echo \"::error::Head ERD viewer was not generated at $head_html\"\n exit 1\n fi\n if [ \"$base_missing\" = \"false\" ] && [ ! -f \"$base_html\" ]; then\n echo \"::error::Base ERD viewer was not generated at $base_html\"\n exit 1\n fi\n\n diff_args=(--namespace \"$NAMESPACE\" --output \"$preview_html\")\n if [ \"$head_missing\" = \"false\" ]; then\n diff_args+=(--head-html \"$head_html\")\n fi\n if [ \"$base_missing\" = \"false\" ]; then\n diff_args+=(--base-html \"$base_html\")\n fi\n run_head_tailor_cli_bin \"$GITHUB_WORKSPACE\" tailordb erd diff \"${diff_args[@]}\"\n - id: tailor-upload-erd-viewer\n uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1\n with:\n name: ${{ matrix.namespace }}-viewer.html\n path: ${{ runner.temp }}/tailor-erd/preview/${{ matrix.namespace }}-viewer.html\n if-no-files-found: error\n archive: false\n retention-days: 7\n\n # __ERD_PREVIEW_JOB_END__\n # __ERD_PREVIEW_COMMENT_JOB_START__\n tailor-erd-preview-comment:\n needs: tailor-erd-preview\n if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository\n runs-on: ubuntu-latest\n timeout-minutes: 5\n permissions:\n actions: read\n pull-requests: write\n steps:\n - id: tailor-comment-erd-preview\n env:\n GH_TOKEN: ${{ github.token }}\n REPO: ${{ github.repository }}\n RUN_ID: ${{ github.run_id }}\n SERVER: ${{ github.server_url }}\n PR_NUMBER: ${{ github.event.pull_request.number }}\n BASE_REF: ${{ github.event.pull_request.base.ref }}\n HEAD_SHA: ${{ github.event.pull_request.head.sha }}\n MARKER: \"<!-- tailor-erd-preview: __WORKSPACE_NAME__ -->\"\n run: |\n set -euo pipefail\n\n current_head=$(gh api \"repos/$REPO/pulls/$PR_NUMBER\" --jq '.head.sha')\n if [ \"$current_head\" != \"$HEAD_SHA\" ]; then\n echo \"Skipping stale ERD preview comment for $HEAD_SHA; current head is $current_head.\"\n exit 0\n fi\n\n body=\"$MARKER\"$'\\n'\"### TailorDB ERD preview (__WORKSPACE_NAME__)\"$'\\n\\n'\n body+=\"Self-contained ERD viewer HTML artifacts for this pull request. Each viewer can switch between the current schema and a diff against base branch \\`$BASE_REF\\`.\"$'\\n'\n\n while IFS=$'\\t' read -r name id; do\n [ -z \"$name\" ] && continue\n if [[ \"$name\" != *-viewer.html ]]; then\n continue\n fi\n ns=${name%-viewer.html}\n label=\"$ns viewer\"\n body+=$'\\n'\"- **$label**: [$name]($SERVER/$REPO/actions/runs/$RUN_ID/artifacts/$id)\"\n done < <(gh api \"repos/$REPO/actions/runs/$RUN_ID/artifacts\" --paginate \\\n --jq '.artifacts[] | select(.name | endswith(\"-viewer.html\")) | [.name, (.id|tostring)] | @tsv' | sort)\n\n existing=$(gh api \"repos/$REPO/issues/$PR_NUMBER/comments\" --paginate \\\n --jq 'map(select(.body | contains(env.MARKER))) | .[0].id // empty')\n if [ -n \"$existing\" ]; then\n gh api --method PATCH \"repos/$REPO/issues/comments/$existing\" -f body=\"$body\" >/dev/null\n else\n gh api --method POST \"repos/$REPO/issues/$PR_NUMBER/comments\" -f body=\"$body\" >/dev/null\n fi\n\n # __ERD_PREVIEW_COMMENT_JOB_END__\n tailor-deploy:\n # __DEPLOY_IF__\n runs-on: ubuntu-latest\n timeout-minutes: 30\n permissions:\n contents: read\n environment: __ENVIRONMENT__\n concurrency:\n group: tailor-deploy-__WORKSPACE_NAME__\n cancel-in-progress: false\n steps:\n - id: tailor-checkout\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n - id: tailor-setup\n uses: tailor-platform/actions/setup@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-install\n uses: tailor-platform/actions/install@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-apply\n uses: tailor-platform/actions/deploy@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n workspace-id: ${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n platform-client-id: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}\n platform-client-secret: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}\n # __SEED_DATA_START__\n - id: seed-data\n if: false\n shell: bash\n # __WORKING_DIRECTORY__\n run: |\n # Uncomment and implement to seed data on deploy.\n # Run after apply so the schema is ready.\n # Example: node scripts/seed.mjs\n true\n # __SEED_DATA_END__\n - id: slack-prereq\n if: always()\n shell: bash\n env:\n SLACK_TOKEN: ${{ secrets.TAILOR_SLACK_BOT_TOKEN }}\n SLACK_CHANNEL_ID: ${{ vars.TAILOR_SLACK_CHANNEL_ID }}\n run: |\n if [[ -n \"$SLACK_TOKEN\" && -n \"$SLACK_CHANNEL_ID\" ]]; then\n echo \"ready=true\" >> \"$GITHUB_OUTPUT\"\n fi\n - id: tailor-notify\n if: always() && steps.slack-prereq.outputs.ready == 'true'\n uses: tailor-platform/actions/notify@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n provider: slack\n status: ${{ job.status }}\n workspace-name: __WORKSPACE_NAME__\n slack-token: ${{ secrets.TAILOR_SLACK_BOT_TOKEN }}\n slack-channel-id: ${{ vars.TAILOR_SLACK_CHANNEL_ID }}\n # user-mapping: ${{ vars.TAILOR_SLACK_USER_MAPPING }}\n";
|
|
3887
|
+
var branch_workflow_default = "# __HEADER__\nname: Tailor (__WORKSPACE_NAME__)\n\non:\n # __PULL_REQUEST_START__\n pull_request:\n branches: [\"__BRANCH__\"]\n # __PATHS__\n # __PULL_REQUEST_END__\n push:\n branches: [\"__BRANCH__\"]\n # __PATHS__\n workflow_dispatch:\n # __DISPATCH_INPUTS_START__\n inputs:\n dry-run:\n description: Preview changes without deploying\n type: boolean\n default: false\n # __DISPATCH_INPUTS_END__\n\npermissions:\n contents: read\n\njobs:\n # __PLAN_JOB_START__\n tailor-plan:\n if: >-\n github.event_name == 'pull_request' ||\n (github.event_name == 'workflow_dispatch' && inputs['dry-run'])\n runs-on: ubuntu-latest\n timeout-minutes: 30\n environment: __ENVIRONMENT__\n permissions:\n contents: read\n pull-requests: write\n concurrency:\n group: tailor-plan-__WORKSPACE_NAME__-${{ github.event.pull_request.number || github.run_id }}\n cancel-in-progress: true\n steps:\n - id: tailor-checkout\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n - id: tailor-setup\n uses: tailor-platform/actions/setup@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-install\n uses: tailor-platform/actions/install@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-generate-check\n uses: tailor-platform/actions/generate-check@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __SEED_VALIDATE_START__\n - id: tailor-seed-validate\n run: __TAILOR_CLI__ seed validate\n # __WORKING_DIRECTORY__\n # __SEED_VALIDATE_END__\n - id: tailor-drift-check\n uses: tailor-platform/actions/drift-check@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __MIGRATION_DRIFT_CHECK_START__\n - id: tailor-migration-drift-check\n uses: tailor-platform/actions/migration-drift-check@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n # __MIGRATION_DRIFT_CHECK_END__\n - id: tailor-plan\n # Fork PRs cannot read secrets; the checks above still run for them.\n if: github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork\n uses: tailor-platform/actions/plan@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n workspace-id: ${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}\n package-manager: __PACKAGE_MANAGER__\n label: __WORKSPACE_NAME__\n # __WORKING_DIRECTORY__\n platform-client-id: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}\n platform-client-secret: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}\n github-token: ${{ secrets.GITHUB_TOKEN }}\n # __PLAN_JOB_END__\n # __ERD_PREVIEW_JOB_START__\n tailor-erd-preview-matrix:\n if: github.event_name == 'pull_request'\n runs-on: ubuntu-latest\n timeout-minutes: 5\n permissions:\n contents: read\n outputs:\n namespaces: ${{ steps.tailor-erd-preview-matrix.outputs.namespaces }}\n base-app-dir: ${{ steps.tailor-erd-preview-matrix.outputs['base-app-dir'] }}\n steps:\n - id: tailor-checkout\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n with:\n persist-credentials: false\n - id: tailor-checkout-base\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n with:\n repository: ${{ github.event.pull_request.base.repo.full_name }}\n ref: ${{ github.event.pull_request.base.sha }}\n path: .tailor-erd-base\n persist-credentials: false\n - id: tailor-erd-preview-matrix\n shell: bash\n env:\n APP_DIR: \"__APP_DIR__\"\n WORKSPACE_NAME: \"__WORKSPACE_NAME__\"\n run: |\n set -euo pipefail\n node <<'NODE'\n const fs = require(\"node:fs\");\n\n const appDir = process.env.APP_DIR || \".\";\n const workspaceName = process.env.WORKSPACE_NAME;\n const output = process.env.GITHUB_OUTPUT;\n const dirPattern = /^[A-Za-z0-9._/-]+$/;\n const namespacePattern = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\n\n function lockTarget(file) {\n try {\n const lock = JSON.parse(fs.readFileSync(file, \"utf8\"));\n return lock.targets?.find(\n (candidate) =>\n candidate.kind === \"branch\" &&\n candidate.workspaceName === workspaceName,\n );\n } catch (error) {\n if (error && error.code === \"ENOENT\") return undefined;\n throw error;\n }\n }\n\n function namespacesFromTarget(target, label) {\n const namespaces =\n target?.inputs?.erdPreview === true && Array.isArray(target.inputs?.erdNamespaces)\n ? target.inputs.erdNamespaces\n : [];\n for (const namespace of namespaces) {\n if (typeof namespace !== \"string\" || !namespacePattern.test(namespace)) {\n throw new Error(`Invalid ERD namespace in ${label}: ${String(namespace)}`);\n }\n }\n return namespaces;\n }\n\n function normalizeDir(value, label) {\n const raw = typeof value === \"string\" && value.length > 0 ? value : appDir;\n const normalized =\n raw.replaceAll(\"\\\\\", \"/\").replace(/\\/{2,}/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/$/, \"\") ||\n \".\";\n if (\n !dirPattern.test(normalized) ||\n normalized.startsWith(\"/\") ||\n normalized.split(\"/\").includes(\"..\")\n ) {\n throw new Error(`Invalid ERD app dir in ${label}: ${raw}`);\n }\n return normalized;\n }\n\n const headTarget = lockTarget(\".github/tailor.lock\");\n const baseTarget = lockTarget(\".tailor-erd-base/.github/tailor.lock\");\n const baseAppDir = normalizeDir(baseTarget?.inputs?.dir, \"base setup lock\");\n const namespaces = [\n ...new Set([\n ...namespacesFromTarget(headTarget, \"head setup lock\"),\n ...namespacesFromTarget(baseTarget, \"base setup lock\"),\n ]),\n ].sort((a, b) => a.localeCompare(b));\n\n if (namespaces.length === 0) {\n console.error(\"No ERD preview namespaces found in the head or base setup lock.\");\n process.exit(1);\n }\n\n fs.appendFileSync(output, `namespaces=${JSON.stringify(namespaces)}\\n`);\n fs.appendFileSync(output, `base-app-dir=${baseAppDir}\\n`);\n NODE\n\n tailor-erd-preview:\n needs: tailor-erd-preview-matrix\n if: github.event_name == 'pull_request'\n runs-on: ubuntu-latest\n timeout-minutes: 15\n permissions:\n contents: read\n strategy:\n fail-fast: false\n matrix:\n namespace: ${{ fromJSON(needs.tailor-erd-preview-matrix.outputs.namespaces) }}\n steps:\n - id: tailor-checkout\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n with:\n persist-credentials: false\n - id: tailor-setup\n uses: tailor-platform/actions/setup@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-checkout-base\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n with:\n repository: ${{ github.event.pull_request.base.repo.full_name }}\n ref: ${{ github.event.pull_request.base.sha }}\n path: .tailor-erd-base\n persist-credentials: false\n - id: tailor-detect-base-package-manager\n shell: bash\n run: |\n set -euo pipefail\n cd .tailor-erd-base\n base_package_manager=\"$(\n if [ -f pnpm-lock.yaml ]; then\n echo pnpm\n elif [ -f yarn.lock ]; then\n echo yarn\n elif [ -f bun.lockb ] || [ -f bun.lock ]; then\n echo bun\n elif [ -f package-lock.json ]; then\n echo npm\n else\n echo \"__PACKAGE_MANAGER__\"\n fi\n )\"\n echo \"package-manager=$base_package_manager\" >> \"$GITHUB_OUTPUT\"\n if [ \"$base_package_manager\" = \"pnpm\" ]; then\n base_pnpm_version=\"$(node <<'NODE'\n const fs = require(\"node:fs\");\n\n const fallback = \"10\";\n\n function readManifest(file) {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\"));\n } catch {\n return {};\n }\n }\n\n function pnpmVersion(manifest) {\n const packageManager = manifest.packageManager;\n if (typeof packageManager === \"string\" && packageManager.startsWith(\"pnpm@\")) {\n return packageManager.slice(\"pnpm@\".length).split(\"+\")[0];\n }\n\n const devPackageManager = manifest.devEngines?.packageManager;\n if (devPackageManager?.name === \"pnpm\" && devPackageManager.version) {\n return devPackageManager.version;\n }\n\n return undefined;\n }\n\n process.stdout.write(\n pnpmVersion(readManifest(\"package.json\")) ?? fallback,\n );\n NODE\n )\"\n echo \"pnpm-version=$base_pnpm_version\" >> \"$GITHUB_OUTPUT\"\n fi\n - id: tailor-setup-base-pnpm\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'pnpm'\n uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10\n with:\n version: ${{ steps.tailor-detect-base-package-manager.outputs['pnpm-version'] }}\n package_json_file: .tailor-erd-base/package.json\n run_install: false\n - id: tailor-setup-base-node\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] != 'bun'\n uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7\n with:\n node-version-file: .tailor-erd-base/package.json\n - id: tailor-setup-base-yarn\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'yarn'\n shell: bash\n working-directory: .tailor-erd-base\n run: |\n set -euo pipefail\n corepack enable\n - id: tailor-setup-base-bun\n if: steps.tailor-detect-base-package-manager.outputs['package-manager'] == 'bun'\n uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0\n - id: tailor-install-base\n shell: bash\n working-directory: .tailor-erd-base\n env:\n BASE_PACKAGE_MANAGER: ${{ steps.tailor-detect-base-package-manager.outputs['package-manager'] }}\n run: |\n set -euo pipefail\n case \"$BASE_PACKAGE_MANAGER\" in\n pnpm) pnpm install --frozen-lockfile ;;\n npm) npm ci ;;\n yarn)\n if grep -q '^__metadata:' yarn.lock; then\n yarn install --immutable\n else\n yarn install --frozen-lockfile\n fi\n ;;\n bun) bun install --frozen-lockfile ;;\n *)\n echo \"::error::Unsupported base package-manager '$BASE_PACKAGE_MANAGER' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n - id: tailor-restore-head-setup\n uses: tailor-platform/actions/setup@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-build-erd-preview\n shell: bash\n env:\n APP_DIR: \"__APP_DIR__\"\n BASE_APP_DIR: ${{ needs.tailor-erd-preview-matrix.outputs['base-app-dir'] }}\n BASE_PACKAGE_MANAGER: ${{ steps.tailor-detect-base-package-manager.outputs['package-manager'] }}\n NAMESPACE: ${{ matrix.namespace }}\n run: |\n set -euo pipefail\n\n run_tailor_cli() {\n case \"__PACKAGE_MANAGER__\" in\n pnpm) pnpm exec tailor \"$@\" ;;\n npm) npx @tailor-platform/sdk \"$@\" ;;\n yarn) yarn tailor \"$@\" ;;\n bun) bun run tailor \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n }\n\n run_head_node() {\n case \"__PACKAGE_MANAGER__\" in\n pnpm) pnpm exec node \"$@\" ;;\n npm) node \"$@\" ;;\n yarn) yarn node \"$@\" ;;\n bun) node \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n }\n\n tailor_cli_bin=\"$(\n run_head_node - <<'NODE'\n const path = require(\"node:path\");\n const { createRequire } = require(\"node:module\");\n const appDir = process.env.APP_DIR || \".\";\n const githubWorkspace = process.env.GITHUB_WORKSPACE;\n if (!githubWorkspace) {\n throw new Error(\"GITHUB_WORKSPACE is required.\");\n }\n\n let lastError;\n for (const manifestPath of [\n path.join(githubWorkspace, appDir, \"package.json\"),\n path.join(githubWorkspace, \"package.json\"),\n ]) {\n try {\n const requireFromManifest = createRequire(manifestPath);\n process.stdout.write(\n path.join(\n path.dirname(requireFromManifest.resolve(\"@tailor-platform/sdk/cli\")),\n \"index.mjs\",\n ),\n );\n process.exit(0);\n } catch (error) {\n lastError = error;\n }\n }\n throw lastError || new Error(\"Failed to resolve @tailor-platform/sdk/cli.\");\n NODE\n )\"\n\n run_head_tailor_cli_bin() {\n local command_cwd=\"$1\"\n shift\n\n run_head_cli_env() {\n env TAILOR_CLI_BIN=\"$tailor_cli_bin\" TAILOR_CLI_CWD=\"$command_cwd\" \"$@\"\n }\n\n (\n cd \"$GITHUB_WORKSPACE\" || exit 1\n case \"__PACKAGE_MANAGER__\" in\n pnpm) run_head_cli_env pnpm exec node \"$head_cli_runner\" \"$@\" ;;\n npm) run_head_cli_env node \"$head_cli_runner\" \"$@\" ;;\n yarn) run_head_cli_env yarn node \"$head_cli_runner\" \"$@\" ;;\n bun) run_head_cli_env bun \"$head_cli_runner\" \"$@\" ;;\n *)\n echo \"::error::Unsupported package-manager '__PACKAGE_MANAGER__' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n )\n }\n\n run_base_tailor_cli_bin() {\n local command_cwd=\"$1\"\n shift\n\n run_head_cli_env() {\n env TAILOR_CLI_BIN=\"$tailor_cli_bin\" TAILOR_CLI_CWD=\"$command_cwd\" \"$@\"\n }\n\n (\n cd \"$command_cwd\" || exit 1\n case \"$BASE_PACKAGE_MANAGER\" in\n pnpm) run_head_cli_env pnpm exec node \"$head_cli_runner\" \"$@\" ;;\n npm) run_head_cli_env node \"$head_cli_runner\" \"$@\" ;;\n yarn) run_head_cli_env yarn node \"$head_cli_runner\" \"$@\" ;;\n bun) run_head_cli_env bun \"$head_cli_runner\" \"$@\" ;;\n *)\n echo \"::error::Unsupported base package-manager '$BASE_PACKAGE_MANAGER' (expected pnpm, npm, yarn, or bun)\"\n exit 1\n ;;\n esac\n )\n }\n\n head_output=\"$RUNNER_TEMP/tailor-erd/head\"\n base_output=\"$RUNNER_TEMP/tailor-erd/base\"\n preview_output=\"$RUNNER_TEMP/tailor-erd/preview\"\n dts_output=\"$RUNNER_TEMP/tailor-erd/dts\"\n head_cli_runner=\"$RUNNER_TEMP/tailor-erd/run-head-cli.mjs\"\n head_log=\"$RUNNER_TEMP/tailor-erd/head-$NAMESPACE.log\"\n base_log=\"$RUNNER_TEMP/tailor-erd/base-$NAMESPACE.log\"\n rm -rf \"$head_output\" \"$base_output\" \"$preview_output\" \"$dts_output\"\n mkdir -p \"$head_output\" \"$base_output\" \"$preview_output\" \"$dts_output\"\n cat > \"$head_cli_runner\" <<'NODE'\n import { pathToFileURL } from \"node:url\";\n\n const cliBin = process.env.TAILOR_CLI_BIN;\n const commandCwd = process.env.TAILOR_CLI_CWD;\n if (!cliBin || !commandCwd) {\n throw new Error(\"TAILOR_CLI_BIN and TAILOR_CLI_CWD are required.\");\n }\n\n process.chdir(commandCwd);\n process.argv = [process.argv[0], cliBin, ...process.argv.slice(2)];\n await import(pathToFileURL(cliBin).href);\n NODE\n\n head_config=\"$GITHUB_WORKSPACE/$APP_DIR/tailor.config.ts\"\n base_config=\"$GITHUB_WORKSPACE/.tailor-erd-base/$BASE_APP_DIR/tailor.config.ts\"\n head_html=\"$head_output/$NAMESPACE/dist/index.html\"\n base_html=\"$base_output/$NAMESPACE/dist/index.html\"\n preview_html=\"$preview_output/$NAMESPACE-viewer.html\"\n\n head_missing=\"false\"\n if [ ! -f \"$head_config\" ]; then\n echo \"Head ERD config not found; rendering base objects as removed.\"\n head_missing=\"true\"\n elif ! (\n cd \"$GITHUB_WORKSPACE/$APP_DIR\" || exit 1\n TAILOR_PLATFORM_SDK_DTS_PATH=\"$dts_output/head-$NAMESPACE.d.ts\" \\\n run_tailor_cli tailordb erd export --config \"$head_config\" --namespace \"$NAMESPACE\" --output \"$head_output\"\n ) >\"$head_log\" 2>&1; then\n if grep -q 'not found in local config.db' \"$head_log\"; then\n cat \"$head_log\"\n echo \"Head ERD namespace '$NAMESPACE' not found; rendering base objects as removed.\"\n head_missing=\"true\"\n else\n cat \"$head_log\"\n exit 1\n fi\n elif [ -s \"$head_log\" ]; then\n cat \"$head_log\"\n fi\n\n base_missing=\"false\"\n if [ ! -f \"$base_config\" ]; then\n echo \"Base ERD config not found; rendering current objects as added.\"\n base_missing=\"true\"\n elif ! (\n TAILOR_PLATFORM_SDK_DTS_PATH=\"$dts_output/base-$NAMESPACE.d.ts\" \\\n run_base_tailor_cli_bin \"$GITHUB_WORKSPACE/.tailor-erd-base/$BASE_APP_DIR\" tailordb erd export --config \"$base_config\" --namespace \"$NAMESPACE\" --output \"$base_output\"\n ) >\"$base_log\" 2>&1; then\n if grep -q 'not found in local config.db' \"$base_log\"; then\n cat \"$base_log\"\n echo \"Base ERD namespace '$NAMESPACE' not found; rendering current objects as added.\"\n base_missing=\"true\"\n else\n cat \"$base_log\"\n exit 1\n fi\n elif [ -s \"$base_log\" ]; then\n cat \"$base_log\"\n fi\n\n if [ \"$head_missing\" = \"true\" ] && [ \"$base_missing\" = \"true\" ]; then\n echo \"::error::ERD namespace '$NAMESPACE' was not found in head or base.\"\n exit 1\n fi\n if [ \"$head_missing\" = \"false\" ] && [ ! -f \"$head_html\" ]; then\n echo \"::error::Head ERD viewer was not generated at $head_html\"\n exit 1\n fi\n if [ \"$base_missing\" = \"false\" ] && [ ! -f \"$base_html\" ]; then\n echo \"::error::Base ERD viewer was not generated at $base_html\"\n exit 1\n fi\n\n diff_args=(--namespace \"$NAMESPACE\" --output \"$preview_html\")\n if [ \"$head_missing\" = \"false\" ]; then\n diff_args+=(--head-html \"$head_html\")\n fi\n if [ \"$base_missing\" = \"false\" ]; then\n diff_args+=(--base-html \"$base_html\")\n fi\n run_head_tailor_cli_bin \"$GITHUB_WORKSPACE\" tailordb erd diff \"${diff_args[@]}\"\n - id: tailor-upload-erd-viewer\n uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1\n with:\n name: ${{ matrix.namespace }}-viewer.html\n path: ${{ runner.temp }}/tailor-erd/preview/${{ matrix.namespace }}-viewer.html\n if-no-files-found: error\n archive: false\n retention-days: 7\n\n # __ERD_PREVIEW_JOB_END__\n # __ERD_PREVIEW_COMMENT_JOB_START__\n tailor-erd-preview-comment:\n needs: tailor-erd-preview\n if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository\n runs-on: ubuntu-latest\n timeout-minutes: 5\n permissions:\n actions: read\n pull-requests: write\n steps:\n - id: tailor-comment-erd-preview\n env:\n GH_TOKEN: ${{ github.token }}\n REPO: ${{ github.repository }}\n RUN_ID: ${{ github.run_id }}\n SERVER: ${{ github.server_url }}\n PR_NUMBER: ${{ github.event.pull_request.number }}\n BASE_REF: ${{ github.event.pull_request.base.ref }}\n HEAD_SHA: ${{ github.event.pull_request.head.sha }}\n MARKER: \"<!-- tailor-erd-preview: __WORKSPACE_NAME__ -->\"\n run: |\n set -euo pipefail\n\n current_head=$(gh api \"repos/$REPO/pulls/$PR_NUMBER\" --jq '.head.sha')\n if [ \"$current_head\" != \"$HEAD_SHA\" ]; then\n echo \"Skipping stale ERD preview comment for $HEAD_SHA; current head is $current_head.\"\n exit 0\n fi\n\n body=\"$MARKER\"$'\\n'\"### TailorDB ERD preview (__WORKSPACE_NAME__)\"$'\\n\\n'\n body+=\"Self-contained ERD viewer HTML artifacts for this pull request. Each viewer can switch between the current schema and a diff against base branch \\`$BASE_REF\\`.\"$'\\n'\n\n while IFS=$'\\t' read -r name id; do\n [ -z \"$name\" ] && continue\n if [[ \"$name\" != *-viewer.html ]]; then\n continue\n fi\n ns=${name%-viewer.html}\n label=\"$ns viewer\"\n body+=$'\\n'\"- **$label**: [$name]($SERVER/$REPO/actions/runs/$RUN_ID/artifacts/$id)\"\n done < <(gh api \"repos/$REPO/actions/runs/$RUN_ID/artifacts\" --paginate \\\n --jq '.artifacts[] | select(.name | endswith(\"-viewer.html\")) | [.name, (.id|tostring)] | @tsv' | sort)\n\n existing=$(gh api \"repos/$REPO/issues/$PR_NUMBER/comments\" --paginate \\\n --jq 'map(select(.body | contains(env.MARKER))) | .[0].id // empty')\n if [ -n \"$existing\" ]; then\n gh api --method PATCH \"repos/$REPO/issues/comments/$existing\" -f body=\"$body\" >/dev/null\n else\n gh api --method POST \"repos/$REPO/issues/$PR_NUMBER/comments\" -f body=\"$body\" >/dev/null\n fi\n\n # __ERD_PREVIEW_COMMENT_JOB_END__\n tailor-deploy:\n # __DEPLOY_IF__\n runs-on: ubuntu-latest\n timeout-minutes: 30\n permissions:\n contents: read\n environment: __ENVIRONMENT__\n concurrency:\n group: tailor-deploy-__WORKSPACE_NAME__\n cancel-in-progress: false\n steps:\n - id: tailor-checkout\n uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n - id: tailor-setup\n uses: tailor-platform/actions/setup@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-install\n uses: tailor-platform/actions/install@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n package-manager: __PACKAGE_MANAGER__\n - id: tailor-apply\n uses: tailor-platform/actions/deploy@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n workspace-id: ${{ vars.TAILOR_PLATFORM_WORKSPACE_ID }}\n package-manager: __PACKAGE_MANAGER__\n # __WORKING_DIRECTORY__\n platform-client-id: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_ID }}\n platform-client-secret: ${{ secrets.TAILOR_PLATFORM_MACHINE_USER_CLIENT_SECRET }}\n # __SEED_DATA_START__\n - id: seed-data\n if: false\n shell: bash\n # __WORKING_DIRECTORY__\n run: |\n # Uncomment and implement to seed data on deploy.\n # Run after apply so the schema is ready.\n # Example: node scripts/seed.mjs\n true\n # __SEED_DATA_END__\n - id: slack-prereq\n if: always()\n shell: bash\n env:\n SLACK_TOKEN: ${{ secrets.TAILOR_SLACK_BOT_TOKEN }}\n SLACK_CHANNEL_ID: ${{ vars.TAILOR_SLACK_CHANNEL_ID }}\n run: |\n if [[ -n \"$SLACK_TOKEN\" && -n \"$SLACK_CHANNEL_ID\" ]]; then\n echo \"ready=true\" >> \"$GITHUB_OUTPUT\"\n fi\n - id: tailor-notify\n if: always() && steps.slack-prereq.outputs.ready == 'true'\n uses: tailor-platform/actions/notify@1f2d0cc26b84b9fdae8a3a0427526df31e6c966b # v2.0.0\n with:\n provider: slack\n status: ${{ job.status }}\n workspace-name: __WORKSPACE_NAME__\n slack-token: ${{ secrets.TAILOR_SLACK_BOT_TOKEN }}\n slack-channel-id: ${{ vars.TAILOR_SLACK_CHANNEL_ID }}\n # user-mapping: ${{ vars.TAILOR_SLACK_USER_MAPPING }}\n";
|
|
3875
3888
|
|
|
3876
3889
|
//#endregion
|
|
3877
3890
|
//#region src/cli/commands/setup/coordinate.workflow.yml
|
|
@@ -3889,9 +3902,9 @@ var tag_workflow_default = "# __HEADER__\nname: Tailor (__WORKSPACE_NAME__)\n\no
|
|
|
3889
3902
|
//#region src/cli/commands/setup/templates.ts
|
|
3890
3903
|
const TAILOR_CLI_COMMANDS = {
|
|
3891
3904
|
pnpm: "pnpm exec tailor",
|
|
3892
|
-
npm: "npx tailor",
|
|
3905
|
+
npm: "npx @tailor-platform/sdk",
|
|
3893
3906
|
yarn: "yarn tailor",
|
|
3894
|
-
bun: "
|
|
3907
|
+
bun: "bun run tailor"
|
|
3895
3908
|
};
|
|
3896
3909
|
const HEADER = `# Generated by \`tailor setup\` — managed by the Tailor SDK.
|
|
3897
3910
|
#
|
|
@@ -4608,7 +4621,7 @@ async function setupTarget(options) {
|
|
|
4608
4621
|
kind: resolved.kind,
|
|
4609
4622
|
workspaceName: resolved.workspaceName,
|
|
4610
4623
|
file: resolved.file,
|
|
4611
|
-
templateVersion:
|
|
4624
|
+
templateVersion: 9,
|
|
4612
4625
|
inputs: resolved.inputs,
|
|
4613
4626
|
generatedIds: resolved.render.generatedIds,
|
|
4614
4627
|
ejectedIds: existing?.ejectedIds ?? [],
|
|
@@ -4676,7 +4689,7 @@ async function setupCoordinate(options) {
|
|
|
4676
4689
|
seenNames.add(name);
|
|
4677
4690
|
const entry = actionTargets.get(name);
|
|
4678
4691
|
if (!entry) throw new Error(`Action target "${name}" not found in .github/tailor.lock. Run \`tailor setup action --name ${name}\` first.`);
|
|
4679
|
-
if (names.length > 1 && entry.templateVersion <
|
|
4692
|
+
if (names.length > 1 && entry.templateVersion < 9) throw new Error(`Action target "${name}" was generated with an older setup template. Run \`tailor setup action --name ${name} --force\` before grouping it in setup coordinate.`);
|
|
4680
4693
|
validateDir(entry.inputs.dir);
|
|
4681
4694
|
return {
|
|
4682
4695
|
name,
|
|
@@ -4728,7 +4741,7 @@ async function setupCoordinate(options) {
|
|
|
4728
4741
|
kind: "coordinate",
|
|
4729
4742
|
workspaceName: coordinatorName,
|
|
4730
4743
|
file,
|
|
4731
|
-
templateVersion:
|
|
4744
|
+
templateVersion: 9,
|
|
4732
4745
|
inputs: {
|
|
4733
4746
|
branch,
|
|
4734
4747
|
branchAutoDetected: coordinateKind === "branch" ? branchAutoDetected : branch !== null ? false : void 0,
|
|
@@ -4916,7 +4929,7 @@ async function checkGitHub(options) {
|
|
|
4916
4929
|
currentHash,
|
|
4917
4930
|
configExists,
|
|
4918
4931
|
defaultBranch,
|
|
4919
|
-
templateVersion:
|
|
4932
|
+
templateVersion: 9,
|
|
4920
4933
|
erdNamespaces,
|
|
4921
4934
|
hasMigrations,
|
|
4922
4935
|
hasSeeds,
|
|
@@ -5808,7 +5821,7 @@ async function fetchRemoteTypes(client, workspaceId, namespace) {
|
|
|
5808
5821
|
async function assertMigrationsReproduceLocalTypes(loaded, target) {
|
|
5809
5822
|
const { config, plugins } = loaded;
|
|
5810
5823
|
const pluginManager = plugins.length > 0 ? new PluginManager(plugins) : void 0;
|
|
5811
|
-
const { defineApplication, generatePluginFilesIfNeeded } = await import("../application-
|
|
5824
|
+
const { defineApplication, generatePluginFilesIfNeeded } = await import("../application-Af1zIqSI.mjs");
|
|
5812
5825
|
const application = defineApplication({
|
|
5813
5826
|
config,
|
|
5814
5827
|
pluginManager
|
|
@@ -6078,7 +6091,7 @@ async function collectValidationReports(options) {
|
|
|
6078
6091
|
const targetNamespaces = options.namespace ? namespacesWithMigrations.filter((ns) => ns.namespace === options.namespace) : namespacesWithMigrations;
|
|
6079
6092
|
if (targetNamespaces.length === 0) throw new Error(`Namespace "${options.namespace}" not found or does not have migrations configured`);
|
|
6080
6093
|
const pluginManager = plugins.length > 0 ? new PluginManager(plugins) : void 0;
|
|
6081
|
-
const { defineApplication } = await import("../application-
|
|
6094
|
+
const { defineApplication } = await import("../application-Af1zIqSI.mjs");
|
|
6082
6095
|
const application = defineApplication({
|
|
6083
6096
|
config,
|
|
6084
6097
|
pluginManager
|