Skip to content

Commit 136b13c

Browse files
committed
[wrangler] Add PR metadata to preview deployments
1 parent 5fd6127 commit 136b13c

4 files changed

Lines changed: 545 additions & 13 deletions

File tree

packages/deploy-helpers/src/preview/api.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ export interface DeploymentResource {
7979
limits?: CfUserLimits;
8080
placement?: CfPlacement;
8181
cache?: CacheOptions;
82+
annotations?: {
83+
"workers/message"?: string;
84+
"workers/pull_request_number"?: string;
85+
"workers/pull_request_url"?: string;
86+
"workers/repository_url"?: string;
87+
"workers/tag"?: string;
88+
};
8289
env?: EnvBindings;
8390
created_on: string;
8491
}
@@ -102,6 +109,9 @@ export type CreatePreviewDeploymentRequestParams = {
102109
compatibility_flags?: string[];
103110
annotations?: {
104111
"workers/message"?: string;
112+
"workers/pull_request_number"?: string;
113+
"workers/pull_request_url"?: string;
114+
"workers/repository_url"?: string;
105115
"workers/tag"?: string;
106116
};
107117
migrations?: CfWorkerInit["migrations"];

packages/deploy-helpers/src/preview/preview.ts

Lines changed: 118 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ import {
2727
getBranchName,
2828
getHeadCommitMessage,
2929
getHeadCommitRef,
30+
getPullRequestMetadata,
31+
getRepositoryUrl,
3032
resolveWorkerName,
3133
shouldUseCIMetadataFallback,
3234
} from "./shared";
35+
import type { PullRequestMetadata } from "./shared";
3336
import type { WorkerBuildResult } from "../shared/types";
3437
import type {
3538
Binding,
@@ -81,6 +84,10 @@ type MergedVersionLevel = {
8184
value: Config["cache"];
8285
fromConfig: boolean;
8386
};
87+
pull_request?: {
88+
value: string;
89+
fromConfig: false;
90+
};
8491
assets?: {
8592
value: {
8693
directory?: string;
@@ -240,6 +247,8 @@ async function assemblePreviewDeploymentSettings(
240247
options: {
241248
message?: string;
242249
tag?: string;
250+
repositoryUrl?: string;
251+
pullRequest?: PullRequestMetadata;
243252
assetsOptions?: PreviewAssetsOptions;
244253
}
245254
): Promise<CreatePreviewDeploymentRequestParams> {
@@ -276,9 +285,16 @@ async function assemblePreviewDeploymentSettings(
276285
if (config.compatibility_flags && config.compatibility_flags.length > 0) {
277286
request.compatibility_flags = config.compatibility_flags;
278287
}
279-
if (options.message || options.tag) {
288+
const repositoryUrl = options.repositoryUrl;
289+
const pullRequest = options.pullRequest;
290+
if (options.message || options.tag || repositoryUrl || pullRequest) {
280291
request.annotations = {
281292
...(options.message && { "workers/message": options.message }),
293+
...(pullRequest?.number && {
294+
"workers/pull_request_number": pullRequest.number,
295+
}),
296+
...(pullRequest?.url && { "workers/pull_request_url": pullRequest.url }),
297+
...(repositoryUrl && { "workers/repository_url": repositoryUrl }),
282298
...(options.tag && { "workers/tag": options.tag }),
283299
};
284300
}
@@ -374,7 +390,9 @@ function buildMergedScriptLevel(
374390

375391
function buildMergedVersionLevel(
376392
config: Config,
377-
deployment: DeploymentResource
393+
deployment: DeploymentResource,
394+
repositoryUrl?: string,
395+
pullRequest?: PullRequestMetadata
378396
): MergedVersionLevel {
379397
const previews = config.previews as PreviewsConfig | undefined;
380398
const configBindingNames = new Set(
@@ -429,6 +447,17 @@ function buildMergedVersionLevel(
429447
fromConfig: previews?.cache !== undefined || config.cache !== undefined,
430448
};
431449
}
450+
const deploymentPullRequestUrl =
451+
deployment.annotations?.["workers/pull_request_url"] ?? pullRequest?.url;
452+
const deploymentPullRequestNumber =
453+
deployment.annotations?.["workers/pull_request_number"] ??
454+
pullRequest?.number;
455+
if (deploymentPullRequestUrl || deploymentPullRequestNumber) {
456+
result.pull_request = {
457+
value: deploymentPullRequestUrl ?? `#${deploymentPullRequestNumber}`,
458+
fromConfig: false,
459+
};
460+
}
432461
if (config.assets) {
433462
result.assets = {
434463
value: {
@@ -448,6 +477,49 @@ function buildMergedVersionLevel(
448477
return result;
449478
}
450479

480+
function hasPreviewMetadataAnnotations(
481+
request: CreatePreviewDeploymentRequestParams
482+
): boolean {
483+
return !!(
484+
request.annotations?.["workers/pull_request_number"] ||
485+
request.annotations?.["workers/pull_request_url"] ||
486+
request.annotations?.["workers/repository_url"]
487+
);
488+
}
489+
490+
function omitPreviewMetadataAnnotations(
491+
request: CreatePreviewDeploymentRequestParams
492+
): CreatePreviewDeploymentRequestParams {
493+
const annotations = {
494+
...(request.annotations?.["workers/message"] && {
495+
"workers/message": request.annotations["workers/message"],
496+
}),
497+
...(request.annotations?.["workers/tag"] && {
498+
"workers/tag": request.annotations["workers/tag"],
499+
}),
500+
};
501+
502+
return {
503+
...request,
504+
annotations:
505+
Object.keys(annotations).length > 0 ? annotations : undefined,
506+
};
507+
}
508+
509+
function isPreviewMetadataAnnotationsUnsupportedError(error: unknown): boolean {
510+
if (typeof error !== "object" || error === null) {
511+
return false;
512+
}
513+
514+
const message = error instanceof Error ? error.message : String(error);
515+
516+
return (
517+
message.includes("annotations not allowed") &&
518+
(message.includes("workers/pull_request") ||
519+
message.includes("workers/repository_url"))
520+
);
521+
}
522+
451523
function formatPreviewResource(
452524
previewResource: PreviewResource,
453525
scriptLevel: MergedScriptLevel,
@@ -565,6 +637,13 @@ function formatDeploymentResource(
565637
versionLevel.cache.fromConfig,
566638
]);
567639
}
640+
if (versionLevel.pull_request !== undefined) {
641+
settingsRows.push([
642+
"pull_request",
643+
versionLevel.pull_request.value,
644+
versionLevel.pull_request.fromConfig,
645+
]);
646+
}
568647
if (settingsRows.length > 0) {
569648
lines.push("");
570649
lines.push(...formatAlignedRows(settingsRows));
@@ -682,6 +761,8 @@ export async function preview(
682761
!args.message && shouldUseCIMetadataFallback()
683762
? getHeadCommitMessage()
684763
: undefined;
764+
const repositoryUrl = getRepositoryUrl();
765+
const pullRequest = getPullRequestMetadata();
685766

686767
let existingPreview: PreviewResource | null = null;
687768
try {
@@ -732,25 +813,51 @@ export async function preview(
732813
{
733814
message: args.message ?? fallbackMessage,
734815
tag: args.tag ?? fallbackTag,
816+
repositoryUrl,
817+
pullRequest,
735818
assetsOptions,
736819
}
737820
);
738-
const deployment = await createPreviewDeployment(
739-
config,
740-
accountId,
741-
workerName,
742-
previewResource.id,
743-
deploymentRequest,
744-
{ ignoreDefaults }
745-
);
821+
let deployment: DeploymentResource;
822+
try {
823+
deployment = await createPreviewDeployment(
824+
config,
825+
accountId,
826+
workerName,
827+
previewResource.id,
828+
deploymentRequest,
829+
{ ignoreDefaults }
830+
);
831+
} catch (error) {
832+
if (
833+
hasPreviewMetadataAnnotations(deploymentRequest) &&
834+
isPreviewMetadataAnnotationsUnsupportedError(error)
835+
) {
836+
deployment = await createPreviewDeployment(
837+
config,
838+
accountId,
839+
workerName,
840+
previewResource.id,
841+
omitPreviewMetadataAnnotations(deploymentRequest),
842+
{ ignoreDefaults }
843+
);
844+
} else {
845+
throw error;
846+
}
847+
}
746848

747849
if (args.json) {
748850
logger.log(
749851
JSON.stringify({ preview: previewResource, deployment }, null, 2)
750852
);
751853
} else {
752854
const scriptLevel = buildMergedScriptLevel(config, previewResource);
753-
const versionLevel = buildMergedVersionLevel(config, deployment);
855+
const versionLevel = buildMergedVersionLevel(
856+
config,
857+
deployment,
858+
repositoryUrl,
859+
pullRequest
860+
);
754861
const configName = configFileName(config.configPath);
755862
logger.log(
756863
formatPreviewResource(

0 commit comments

Comments
 (0)