canopycms 0.0.67 → 0.0.68-int.101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -17
- package/dist/ai/handler.js +8 -0
- package/dist/api/admin-branch-health.js +17 -20
- package/dist/api/admin.d.ts +30 -9
- package/dist/api/admin.js +32 -2
- package/dist/api/assets.js +84 -76
- package/dist/api/branch-create-window.d.ts +12 -0
- package/dist/api/branch-create-window.js +13 -0
- package/dist/api/branch-review.d.ts +3 -3
- package/dist/api/branch-review.js +14 -5
- package/dist/api/branch-status.d.ts +5 -5
- package/dist/api/branch-status.js +26 -6
- package/dist/api/branch-withdraw.d.ts +2 -2
- package/dist/api/branch-withdraw.js +7 -2
- package/dist/api/branch.d.ts +15 -2
- package/dist/api/branch.js +118 -92
- package/dist/api/client.d.ts +18 -6
- package/dist/api/client.js +79 -12
- package/dist/api/content.d.ts +6 -5
- package/dist/api/content.js +44 -41
- package/dist/api/entries.js +16 -15
- package/dist/api/github-sync.d.ts +19 -1
- package/dist/api/github-sync.js +57 -10
- package/dist/api/index.d.ts +1 -1
- package/dist/api/reference-options.js +1 -1
- package/dist/api/resolve-references.js +14 -40
- package/dist/api/settings-helpers.d.ts +1 -1
- package/dist/api/settings-helpers.js +1 -4
- package/dist/api/user.d.ts +3 -0
- package/dist/api/user.js +3 -0
- package/dist/assets/asset-url.d.ts +22 -16
- package/dist/assets/asset-url.js +42 -25
- package/dist/assets/factory.d.ts +5 -0
- package/dist/assets/factory.js +5 -0
- package/dist/assets/finalize.js +3 -0
- package/dist/assets/index.d.ts +1 -1
- package/dist/assets/materialize.d.ts +153 -0
- package/dist/assets/materialize.js +402 -0
- package/dist/assets/store-local.d.ts +19 -5
- package/dist/assets/store-local.js +69 -10
- package/dist/assets/store-s3.d.ts +38 -7
- package/dist/assets/store-s3.js +128 -22
- package/dist/assets/transform-directives.d.ts +52 -13
- package/dist/assets/transform-directives.js +87 -27
- package/dist/assets/transform.d.ts +3 -3
- package/dist/assets/transform.js +13 -8
- package/dist/assets/types.d.ts +31 -4
- package/dist/auth/file-based-auth-cache.js +7 -8
- package/dist/authorization/content.d.ts +5 -4
- package/dist/authorization/content.js +5 -5
- package/dist/authorization/path.d.ts +11 -6
- package/dist/authorization/path.js +11 -6
- package/dist/authorization/types.d.ts +2 -2
- package/dist/branch-health.d.ts +7 -1
- package/dist/branch-health.js +8 -3
- package/dist/branch-metadata.d.ts +5 -5
- package/dist/branch-metadata.js +44 -36
- package/dist/branch-provisioning.d.ts +167 -0
- package/dist/branch-provisioning.js +501 -0
- package/dist/branch-schema-cache.d.ts +5 -3
- package/dist/branch-schema-cache.js +29 -11
- package/dist/branch-sparse.d.ts +23 -0
- package/dist/branch-sparse.js +118 -0
- package/dist/branch-workspace.d.ts +42 -3
- package/dist/branch-workspace.js +240 -94
- package/dist/build/asset-refs.d.ts +93 -0
- package/dist/build/asset-refs.js +251 -0
- package/dist/build-identity.d.ts +3 -0
- package/dist/build-identity.js +13 -0
- package/dist/cli/asset-refs.d.ts +52 -0
- package/dist/cli/asset-refs.js +194 -0
- package/dist/cli/cli.d.ts +15 -1
- package/dist/cli/cli.js +5928 -2195
- package/dist/cli/configured-asset-store.d.ts +12 -0
- package/dist/cli/configured-asset-store.js +46 -0
- package/dist/cli/generate-ai-content.js +2185 -587
- package/dist/cli/github-app-manifest.d.ts +4 -3
- package/dist/cli/github-app-manifest.js +4 -3
- package/dist/cli/init.js +30 -27
- package/dist/cli/migrate.js +12 -8
- package/dist/cli/sync.js +83 -37
- package/dist/cli/template-files/Dockerfile.cms.template +8 -0
- package/dist/cli/template-files/cdk-app.ts.template +4 -0
- package/dist/cli/template-files/cms-stack.ts.template +23 -12
- package/dist/cli/template-files/deploy-cms.yml.template +2 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/config/helpers.js +1 -2
- package/dist/config/schemas/config.d.ts +19 -32
- package/dist/config/schemas/config.js +9 -11
- package/dist/config/schemas/field.js +1 -0
- package/dist/config/schemas/media.d.ts +4 -13
- package/dist/config/schemas/media.js +5 -8
- package/dist/config/schemas/url.d.ts +4 -20
- package/dist/config/schemas/url.js +6 -22
- package/dist/config/types.d.ts +30 -20
- package/dist/config/validation.d.ts +6 -0
- package/dist/config/validation.js +37 -0
- package/dist/content-listing.d.ts +12 -12
- package/dist/content-listing.js +10 -6
- package/dist/content-reader.d.ts +11 -2
- package/dist/content-reader.js +22 -14
- package/dist/content-store.d.ts +37 -9
- package/dist/content-store.js +70 -43
- package/dist/content-tree.d.ts +1 -1
- package/dist/content-tree.js +2 -2
- package/dist/context.d.ts +27 -9
- package/dist/context.js +154 -70
- package/dist/editor/BranchManager.d.ts +7 -1
- package/dist/editor/BranchManager.js +29 -14
- package/dist/editor/CanopyEditor.d.ts +1 -1
- package/dist/editor/CanopyEditor.js +2 -6
- package/dist/editor/Editor.d.ts +4 -3
- package/dist/editor/Editor.js +32 -22
- package/dist/editor/FormRenderer.js +34 -18
- package/dist/editor/PreviewFrame.d.ts +24 -0
- package/dist/editor/PreviewFrame.js +140 -0
- package/dist/editor/admin/SystemHealthPanel.js +47 -7
- package/dist/editor/components/BranchesDrawer.d.ts +9 -0
- package/dist/editor/components/BranchesDrawer.js +4 -0
- package/dist/editor/components/NoEditPermissionNotice.d.ts +10 -0
- package/dist/editor/components/NoEditPermissionNotice.js +17 -0
- package/dist/editor/context/AssetContext.d.ts +18 -35
- package/dist/editor/context/AssetContext.js +20 -29
- package/dist/editor/context/index.d.ts +1 -1
- package/dist/editor/context/index.js +1 -1
- package/dist/editor/editor-config.d.ts +1 -2
- package/dist/editor/editor-config.js +0 -23
- package/dist/editor/editor-utils.d.ts +24 -21
- package/dist/editor/editor-utils.js +75 -62
- package/dist/editor/fields/BlockField.d.ts +1 -0
- package/dist/editor/fields/BlockField.js +6 -4
- package/dist/editor/fields/CodeField.d.ts +1 -0
- package/dist/editor/fields/CodeField.js +2 -2
- package/dist/editor/fields/DateTimeField.d.ts +1 -0
- package/dist/editor/fields/DateTimeField.js +2 -2
- package/dist/editor/fields/FieldDescription.d.ts +16 -0
- package/dist/editor/fields/FieldDescription.js +11 -0
- package/dist/editor/fields/ImageField.d.ts +1 -0
- package/dist/editor/fields/ImageField.js +3 -2
- package/dist/editor/fields/InlineGroupField.js +4 -1
- package/dist/editor/fields/MarkdownField.d.ts +1 -0
- package/dist/editor/fields/MarkdownField.js +115 -20
- package/dist/editor/fields/NumberField.d.ts +1 -0
- package/dist/editor/fields/NumberField.js +2 -2
- package/dist/editor/fields/NumberListField.d.ts +1 -0
- package/dist/editor/fields/NumberListField.js +2 -2
- package/dist/editor/fields/ObjectField.d.ts +1 -0
- package/dist/editor/fields/ObjectField.js +5 -2
- package/dist/editor/fields/ReferenceField.d.ts +1 -0
- package/dist/editor/fields/ReferenceField.js +5 -4
- package/dist/editor/fields/SelectField.d.ts +1 -0
- package/dist/editor/fields/SelectField.js +2 -2
- package/dist/editor/fields/StringListField.d.ts +1 -0
- package/dist/editor/fields/StringListField.js +2 -2
- package/dist/editor/fields/TextField.d.ts +1 -0
- package/dist/editor/fields/TextField.js +2 -2
- package/dist/editor/fields/ToggleField.d.ts +1 -0
- package/dist/editor/fields/ToggleField.js +7 -4
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +1 -1
- package/dist/editor/fields/entry-link/InsertEntryLink.js +3 -2
- package/dist/editor/fields/mdx-jsx-support.d.ts +1 -0
- package/dist/editor/fields/mdx-jsx-support.js +137 -0
- package/dist/editor/hooks/create-branch-request.d.ts +20 -0
- package/dist/editor/hooks/create-branch-request.js +52 -0
- package/dist/editor/hooks/useBranchActions.d.ts +13 -2
- package/dist/editor/hooks/useBranchActions.js +48 -17
- package/dist/editor/hooks/useBranchManager.d.ts +21 -0
- package/dist/editor/hooks/useBranchManager.js +204 -37
- package/dist/editor/hooks/useBranchesData.d.ts +6 -0
- package/dist/editor/hooks/useBranchesData.js +9 -3
- package/dist/editor/hooks/useCommentSystem.js +25 -6
- package/dist/editor/hooks/useDraftManager.d.ts +16 -1
- package/dist/editor/hooks/useDraftManager.js +193 -36
- package/dist/editor/hooks/useEntriesData.js +3 -3
- package/dist/editor/hooks/useEntryManager.d.ts +2 -1
- package/dist/editor/hooks/useEntryManager.js +34 -19
- package/dist/editor/media/AssetCard.d.ts +1 -1
- package/dist/editor/media/crop-math.d.ts +3 -4
- package/dist/editor/media/crop-math.js +11 -22
- package/dist/editor/media/editor-image-src.d.ts +7 -0
- package/dist/editor/media/editor-image-src.js +12 -0
- package/dist/editor/preview-asset-base.d.ts +8 -0
- package/dist/editor/preview-asset-base.js +13 -0
- package/dist/editor/preview-bridge.d.ts +9 -21
- package/dist/editor/preview-bridge.js +19 -139
- package/dist/editor/preview-path.d.ts +10 -0
- package/dist/editor/preview-path.js +20 -0
- package/dist/editor/theme.js +2 -2
- package/dist/entry-schema-registry.d.ts +4 -4
- package/dist/entry-schema-registry.js +10 -6
- package/dist/entry-schema.d.ts +27 -4
- package/dist/entry-schema.js +20 -3
- package/dist/git-manager.d.ts +173 -6
- package/dist/git-manager.js +594 -76
- package/dist/github-service.d.ts +15 -0
- package/dist/github-service.js +19 -1
- package/dist/http/handler.js +37 -13
- package/dist/http/index.d.ts +2 -0
- package/dist/http/index.js +2 -0
- package/dist/http/router.d.ts +2 -0
- package/dist/http/router.js +2 -1
- package/dist/http/types.d.ts +2 -0
- package/dist/http/worker-not-ready.d.ts +10 -0
- package/dist/http/worker-not-ready.js +24 -0
- package/dist/operating-mode/client-unsafe-strategy.js +0 -6
- package/dist/operating-mode/types.d.ts +1 -4
- package/dist/paths/branch-name.d.ts +5 -0
- package/dist/paths/branch-name.js +9 -0
- package/dist/paths/branch.d.ts +6 -2
- package/dist/paths/branch.js +16 -10
- package/dist/paths/index.d.ts +3 -3
- package/dist/paths/index.js +3 -3
- package/dist/paths/normalize.d.ts +7 -0
- package/dist/paths/normalize.js +9 -0
- package/dist/paths/validation.js +0 -2
- package/dist/preview.d.ts +8 -0
- package/dist/preview.js +7 -0
- package/dist/reference-resolver.d.ts +5 -21
- package/dist/reference-resolver.js +9 -44
- package/dist/resolve-canopy-user.js +2 -1
- package/dist/schema/schema-store.d.ts +54 -31
- package/dist/schema/schema-store.js +77 -31
- package/dist/server.d.ts +64 -9
- package/dist/server.js +48 -8
- package/dist/services.d.ts +18 -6
- package/dist/services.js +85 -70
- package/dist/settings-workspace.d.ts +23 -3
- package/dist/settings-workspace.js +197 -45
- package/dist/static/seo.d.ts +2 -14
- package/dist/static/seo.js +2 -25
- package/dist/submission-attribution.d.ts +73 -0
- package/dist/submission-attribution.js +221 -0
- package/dist/sync-core.d.ts +12 -1
- package/dist/sync-core.js +31 -13
- package/dist/task-queue/worker-status.d.ts +8 -0
- package/dist/task-queue/worker-status.js +17 -0
- package/dist/types.d.ts +31 -2
- package/dist/utils/content-serialize.d.ts +5 -2
- package/dist/utils/content-serialize.js +98 -24
- package/dist/utils/content-write-lock.d.ts +18 -7
- package/dist/utils/content-write-lock.js +18 -9
- package/dist/utils/debug.d.ts +8 -0
- package/dist/utils/debug.js +10 -2
- package/dist/utils/git.d.ts +32 -0
- package/dist/utils/git.js +42 -0
- package/dist/utils/occ-json-write.js +10 -2
- package/dist/utils/provision-log.d.ts +25 -0
- package/dist/utils/provision-log.js +49 -0
- package/dist/utils/provisioning-lock.d.ts +35 -5
- package/dist/utils/provisioning-lock.js +73 -12
- package/dist/utils/request-timing.d.ts +25 -0
- package/dist/utils/request-timing.js +101 -0
- package/dist/utils/sanitize-href.d.ts +8 -22
- package/dist/utils/sanitize-href.js +11 -28
- package/dist/utils/url-prefix.d.ts +30 -0
- package/dist/utils/url-prefix.js +61 -0
- package/dist/utils/yaml-source-splice.d.ts +58 -0
- package/dist/utils/yaml-source-splice.js +515 -0
- package/dist/validation/entry-validator.js +9 -3
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/worker/canopy-state.d.ts +45 -0
- package/dist/worker/canopy-state.js +75 -0
- package/dist/worker/cms-worker.d.ts +8 -3
- package/dist/worker/cms-worker.js +38 -2
- package/dist/worker/git-sync.d.ts +30 -12
- package/dist/worker/git-sync.js +253 -58
- package/dist/worker/history-rewrite.d.ts +1 -1
- package/dist/worker/history-rewrite.js +1 -1
- package/dist/worker/provisioned-workspace.d.ts +35 -0
- package/dist/worker/provisioned-workspace.js +50 -0
- package/dist/worker/rebase.d.ts +1 -1
- package/dist/worker/rebase.js +95 -23
- package/dist/worker/remote-git-maintenance.d.ts +3 -0
- package/dist/worker/remote-git-maintenance.js +11 -0
- package/dist/worker/sparse-cone.d.ts +20 -0
- package/dist/worker/sparse-cone.js +132 -0
- package/dist/worker/task-runner.js +99 -14
- package/dist/worker/worker-context.d.ts +6 -1
- package/package.json +8 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import { simpleGit } from 'simple-git';
|
|
3
3
|
import { completeTask, dequeueTask, failTask, recoverOrphanedTasks, retryTask, } from '../task-queue/cms-task-queue.js';
|
|
4
|
-
import { createOrUpdatePullRequest } from '../github-service.js';
|
|
5
|
-
import { BranchMetadataFileManager, getBranchMetadataFileManager } from '../branch-metadata.js';
|
|
6
|
-
import { sanitizeBranchName } from '../paths/branch-name.js';
|
|
4
|
+
import { createOrUpdatePullRequest, isRefAlreadyGoneError } from '../github-service.js';
|
|
5
|
+
import { BranchMetadataCorruptError, BranchMetadataFileManager, getBranchMetadataFileManager, } from '../branch-metadata.js';
|
|
6
|
+
import { sanitizeBranchName, RESERVED_SETTINGS_BRANCH_PREFIX } from '../paths/branch-name.js';
|
|
7
7
|
import { gitNetworkChildEnv } from '../git-manager.js';
|
|
8
8
|
import { getErrorMessage, redactCredentials } from '../utils/error.js';
|
|
9
|
-
import { isNonFastForwardRejection, isStaleLeaseRejection } from '../utils/git.js';
|
|
9
|
+
import { isNonFastForwardRejection, isStaleLeaseRejection, workflowPushRefusalFile, } from '../utils/git.js';
|
|
10
10
|
import { clearHistoryRewrittenMarker, readPublishedSha } from './history-rewrite.js';
|
|
11
11
|
import { writeWorkerStatus } from '../task-queue/worker-status.js';
|
|
12
12
|
import { workerLog, workerLogError } from './log.js';
|
|
@@ -90,6 +90,15 @@ function isRateLimitSignal403(err) {
|
|
|
90
90
|
return false;
|
|
91
91
|
}
|
|
92
92
|
// Payload validation helpers — fail fast with clear errors instead of silent `as` casts
|
|
93
|
+
/**
|
|
94
|
+
* Whether `branch` carries the reserved settings-branch prefix. Matching on the prefix
|
|
95
|
+
* alone, never on a configured name, is what keeps a content branch out: branch creation
|
|
96
|
+
* rejects the prefix, while a configured name the worker and API disagree on could be a
|
|
97
|
+
* content branch's.
|
|
98
|
+
*/
|
|
99
|
+
function isSettingsBranch(branch) {
|
|
100
|
+
return branch.startsWith(RESERVED_SETTINGS_BRANCH_PREFIX);
|
|
101
|
+
}
|
|
93
102
|
function requireString(payload, key) {
|
|
94
103
|
const val = payload[key];
|
|
95
104
|
if (typeof val !== 'string')
|
|
@@ -282,6 +291,13 @@ export async function executeTask(ctx, task, signal) {
|
|
|
282
291
|
if (sanitizeBranchName(branch) === ctx.sanitizedBaseBranch) {
|
|
283
292
|
throw new PermanentTaskError(`Refusing to push-and-create-or-update-pr for "${branch}": it is the base branch -- submitting the base branch is never valid`);
|
|
284
293
|
}
|
|
294
|
+
// The settings branch is an orphan with no history in common with the
|
|
295
|
+
// base, so GitHub 422s a PR for it: push it and stop.
|
|
296
|
+
if (isSettingsBranch(branch)) {
|
|
297
|
+
await ctx.pushBranchToGitHub(branch);
|
|
298
|
+
workerLog(`Pushed settings branch ${branch}; settings branches never get a PR`);
|
|
299
|
+
return { pushed: true };
|
|
300
|
+
}
|
|
285
301
|
await ctx.pushBranchToGitHub(branch);
|
|
286
302
|
const result = await createOrUpdatePullRequest({
|
|
287
303
|
octokit: ctx.octokit(),
|
|
@@ -291,9 +307,9 @@ export async function executeTask(ctx, task, signal) {
|
|
|
291
307
|
base,
|
|
292
308
|
title: optionalString(payload, 'title', `Submit ${branch}`),
|
|
293
309
|
body: optionalString(payload, 'body', ''),
|
|
294
|
-
// Content submits (api/github-sync.ts) set
|
|
295
|
-
// syncs (services.ts) deliberately don't.
|
|
310
|
+
// Content submits (api/github-sync.ts) set both.
|
|
296
311
|
markReadyIfDraft: payload.markReadyIfDraft === true,
|
|
312
|
+
mergeSectionIntoBody: payload.mergeSectionIntoBody === true,
|
|
297
313
|
signal,
|
|
298
314
|
});
|
|
299
315
|
workerLog(result.created
|
|
@@ -330,23 +346,73 @@ export async function executeTask(ctx, task, signal) {
|
|
|
330
346
|
}
|
|
331
347
|
case 'delete-remote-branch': {
|
|
332
348
|
const branch = requireString(payload, 'branch');
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
349
|
+
// Defense-in-depth behind the delete handler's own refusal.
|
|
350
|
+
if (sanitizeBranchName(branch) === ctx.sanitizedBaseBranch || isSettingsBranch(branch)) {
|
|
351
|
+
throw new PermanentTaskError(`Refusing to delete "${branch}" on GitHub: the base and settings branches are never deleted`);
|
|
352
|
+
}
|
|
353
|
+
// A branch that reused the name after this task was queued (a requeued task can run long
|
|
354
|
+
// after) owns the GitHub branch once its own submit recorded a different PR. Without one,
|
|
355
|
+
// the ref is taken to be the deleted branch's, which is wrong only if that submit pushed
|
|
356
|
+
// and then lost its PR number. Unparseable metadata keeps the GitHub branch; other read
|
|
357
|
+
// errors retry.
|
|
358
|
+
const deletedPr = typeof payload.pullRequestNumber === 'number' ? payload.pullRequestNumber : undefined;
|
|
359
|
+
let live = null;
|
|
360
|
+
let unreadable = false;
|
|
361
|
+
try {
|
|
362
|
+
live = await BranchMetadataFileManager.loadOnly(ctx.branchWorkspacePath(branch));
|
|
363
|
+
}
|
|
364
|
+
catch (err) {
|
|
365
|
+
if (!(err instanceof BranchMetadataCorruptError))
|
|
366
|
+
throw err;
|
|
367
|
+
unreadable = true;
|
|
368
|
+
}
|
|
369
|
+
if (unreadable ||
|
|
370
|
+
(live !== null && (typeof live.branch !== 'object' || live.branch === null))) {
|
|
371
|
+
workerLog(`Not deleting GitHub branch ${branch}: the branch now under that name is unreadable`);
|
|
372
|
+
return { deleted: false, skipped: 'metadata-unreadable' };
|
|
373
|
+
}
|
|
374
|
+
const livePr = live?.branch.pullRequestNumber;
|
|
375
|
+
if (livePr !== undefined && livePr !== deletedPr) {
|
|
376
|
+
workerLog(`Not deleting GitHub branch ${branch}: a newer branch's PR #${livePr} uses it`);
|
|
377
|
+
return { deleted: false, skipped: 'name-reused' };
|
|
378
|
+
}
|
|
379
|
+
try {
|
|
380
|
+
await ctx.octokit().git.deleteRef({
|
|
381
|
+
owner: ctx.githubOwner,
|
|
382
|
+
repo: ctx.githubRepo,
|
|
383
|
+
ref: `heads/${branch}`,
|
|
384
|
+
request: { signal },
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
catch (err) {
|
|
388
|
+
// Already gone is the outcome this task wants; failing it would only park it in failed/.
|
|
389
|
+
if (!isRefAlreadyGoneError(err))
|
|
390
|
+
throw err;
|
|
391
|
+
workerLog(`GitHub branch ${branch} was already deleted`);
|
|
392
|
+
return { deleted: false, alreadyGone: true };
|
|
393
|
+
}
|
|
394
|
+
workerLog(`Deleted GitHub branch ${branch}`);
|
|
339
395
|
return { deleted: true };
|
|
340
396
|
}
|
|
341
397
|
default:
|
|
342
398
|
throw new PermanentTaskError(`Unknown task action: ${action}`);
|
|
343
399
|
}
|
|
344
400
|
}
|
|
401
|
+
/**
|
|
402
|
+
* The branch whose metadata records a task's outcome, or null when none does. A
|
|
403
|
+
* delete-remote-branch task names a branch already deleted here, so a workspace under that
|
|
404
|
+
* name is leftover or a newer branch's that reused the name.
|
|
405
|
+
*/
|
|
406
|
+
function metadataBranchOf(task) {
|
|
407
|
+
if (task.action === 'delete-remote-branch')
|
|
408
|
+
return null;
|
|
409
|
+
return typeof task.payload.branch === 'string' ? task.payload.branch : null;
|
|
410
|
+
}
|
|
345
411
|
/**
|
|
346
412
|
* Update branch metadata after successful task completion.
|
|
347
413
|
*/
|
|
348
414
|
export async function updateBranchMetadata(ctx, task, result) {
|
|
349
|
-
const branch =
|
|
415
|
+
const branch = metadataBranchOf(task);
|
|
350
416
|
if (!branch)
|
|
351
417
|
return;
|
|
352
418
|
const branchPath = ctx.branchWorkspacePath(branch);
|
|
@@ -395,7 +461,7 @@ export async function updateBranchMetadata(ctx, task, result) {
|
|
|
395
461
|
* syncFailureReason so the editor can show WHY, not just that it failed.
|
|
396
462
|
*/
|
|
397
463
|
async function updateBranchMetadataOnFailure(ctx, task, error) {
|
|
398
|
-
const branch =
|
|
464
|
+
const branch = metadataBranchOf(task);
|
|
399
465
|
if (!branch)
|
|
400
466
|
return;
|
|
401
467
|
const branchPath = ctx.branchWorkspacePath(branch);
|
|
@@ -415,6 +481,23 @@ async function updateBranchMetadataOnFailure(ctx, task, error) {
|
|
|
415
481
|
workerLogError(`Failed to update failure metadata for ${branch}:`, err instanceof Error ? err.message : err);
|
|
416
482
|
}
|
|
417
483
|
}
|
|
484
|
+
/**
|
|
485
|
+
* Fail fast when GitHub refused the push for adding workflow content it does not already hold: the
|
|
486
|
+
* worker's credential deliberately lacks the workflows permission, so the identical push can never
|
|
487
|
+
* succeed. Rebasing onto a base that changed a workflow does not trigger it; a workflow edit made
|
|
488
|
+
* outside the editor, auto-merged by the rebase with a base change to the same file, does.
|
|
489
|
+
*/
|
|
490
|
+
function throwIfWorkflowRefusal(branch, message) {
|
|
491
|
+
const file = workflowPushRefusalFile(message);
|
|
492
|
+
if (file === null)
|
|
493
|
+
return;
|
|
494
|
+
throw new PermanentTaskError(`Push refused for branch "${branch}": it would put a version of ${file} on GitHub that ` +
|
|
495
|
+
`GitHub does not already have, and this deployment's GitHub credential is deliberately not ` +
|
|
496
|
+
`allowed to change workflow files. Such a change usually comes from outside the editor, ` +
|
|
497
|
+
`such as a direct push to this branch. Nothing was pushed, and ` +
|
|
498
|
+
`retrying will not help until a developer with permission to change workflow files ` +
|
|
499
|
+
`resolves it on GitHub.`);
|
|
500
|
+
}
|
|
418
501
|
export async function pushBranchToGitHub(ctx, branch) {
|
|
419
502
|
const git = simpleGit({
|
|
420
503
|
baseDir: ctx.remoteGitPath,
|
|
@@ -473,6 +556,7 @@ export async function pushBranchToGitHub(ctx, branch) {
|
|
|
473
556
|
}
|
|
474
557
|
catch (err) {
|
|
475
558
|
const message = getErrorMessage(err);
|
|
559
|
+
throwIfWorkflowRefusal(branch, message);
|
|
476
560
|
// A refused lease means GitHub is not at the commit we rewrote, so the
|
|
477
561
|
// marker is stale -- routine, not exceptional: tasks are re-run after a
|
|
478
562
|
// crash (recoverOrphanedTasks) and the marker survives any failure to
|
|
@@ -494,6 +578,7 @@ export async function pushBranchToGitHub(ctx, branch) {
|
|
|
494
578
|
}
|
|
495
579
|
catch (retryErr) {
|
|
496
580
|
const retryMessage = getErrorMessage(retryErr);
|
|
581
|
+
throwIfWorkflowRefusal(branch, retryMessage);
|
|
497
582
|
if (isNonFastForwardRejection(retryMessage)) {
|
|
498
583
|
throw new PermanentTaskError(`Push rejected for branch "${branch}": GitHub's tip is neither the commit this ` +
|
|
499
584
|
`deployment last published nor an ancestor of what it is pushing, so the branch ` +
|
|
@@ -38,7 +38,12 @@ export interface WorkerContext {
|
|
|
38
38
|
readonly sanitizedBaseBranch: SanitizedBranchName;
|
|
39
39
|
/** `{workspacePath}/.tasks` — the task queue and worker-status.json. */
|
|
40
40
|
readonly taskDir: string;
|
|
41
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* `{workspacePath}/remote.git` — the shared bare repo. The worker fetches
|
|
43
|
+
* into and pushes from a workspace clone against this path, never the
|
|
44
|
+
* clone's `origin`: that holds the path the CLONING process saw (usually
|
|
45
|
+
* the Lambda), and the clone's config is Lambda-writable.
|
|
46
|
+
*/
|
|
42
47
|
readonly remoteGitPath: string;
|
|
43
48
|
/** `{workspacePath}/content-branches` — the branch workspace root. */
|
|
44
49
|
readonly contentBranchesPath: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//": "@codemirror/language, @lezer/highlight: workaround — @mdxeditor/editor uses cm6-theme-basic-light which peer-requires these but mdxeditor doesn't declare them as dependencies",
|
|
3
3
|
"name": "canopycms",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.68-int.101",
|
|
5
5
|
"description": "CanopyCMS core package: schema-driven content, branch-aware editing, and editor UI for Next.js.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
"import": "./dist/client.js",
|
|
28
28
|
"require": "./dist/client.js"
|
|
29
29
|
},
|
|
30
|
+
"./preview": {
|
|
31
|
+
"types": "./dist/preview.d.ts",
|
|
32
|
+
"import": "./dist/preview.js",
|
|
33
|
+
"require": "./dist/preview.js"
|
|
34
|
+
},
|
|
30
35
|
"./server": {
|
|
31
36
|
"types": "./dist/server.d.ts",
|
|
32
37
|
"import": "./dist/server.js",
|
|
@@ -85,8 +90,9 @@
|
|
|
85
90
|
"node": ">=22.12.0"
|
|
86
91
|
},
|
|
87
92
|
"dependencies": {
|
|
88
|
-
"@aws-sdk/client-s3": "^3.
|
|
93
|
+
"@aws-sdk/client-s3": "^3.1092.0",
|
|
89
94
|
"@aws-sdk/s3-presigned-post": "^3.600.0",
|
|
95
|
+
"@aws-sdk/s3-request-presigner": "^3.600.0",
|
|
90
96
|
"@clack/prompts": "^1.1.0",
|
|
91
97
|
"@codemirror/language": "^6.0.0",
|
|
92
98
|
"@dnd-kit/core": "^6.3.1",
|