bypass Vercel deployment protection on preview API calls

action API calls to preview deployments were getting 401'd by Vercel's
deployment protection. add x-vercel-protection-bypass header to the 3
server-to-server fetch sites when VERCEL_AUTOMATION_BYPASS_SECRET is set.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Colin McDonnell
2026-02-13 15:25:32 +00:00
committed by pullfrog[bot]
parent d7759734f2
commit dc611c9f78
7 changed files with 1633 additions and 1597 deletions
+16 -1
View File
@@ -1,3 +1,5 @@
import { log } from "./cli.ts";
/**
* resolve the Pullfrog API base URL.
*
@@ -5,5 +7,18 @@
* in local dev: API_URL=http://localhost:3000 (from .env).
*/
export function getApiUrl(): string {
return process.env.API_URL || "https://pullfrog.com";
const url = process.env.API_URL || "https://pullfrog.com";
log.debug(`resolved API_URL: ${url}`);
return url;
}
/**
* returns headers needed to bypass Vercel deployment protection on preview deployments.
* when VERCEL_AUTOMATION_BYPASS_SECRET is set (preview repos), includes the bypass header.
* otherwise returns an empty object (production / local dev).
*/
export function getVercelBypassHeaders(): Record<string, string> {
const secret = process.env.VERCEL_AUTOMATION_BYPASS_SECRET;
if (!secret) return {};
return { "x-vercel-protection-bypass": secret };
}
+2 -1
View File
@@ -2,7 +2,7 @@ import { createSign } from "node:crypto";
import * as core from "@actions/core";
import { throttling } from "@octokit/plugin-throttling";
import { Octokit } from "@octokit/rest";
import { getApiUrl } from "./apiUrl.ts";
import { getApiUrl, getVercelBypassHeaders } from "./apiUrl.ts";
import { retry } from "./retry.ts";
export interface InstallationToken {
@@ -109,6 +109,7 @@ async function acquireTokenViaOIDC(opts?: AcquireTokenOptions): Promise<string>
headers: {
Authorization: `Bearer ${oidcToken}`,
"Content-Type": "application/json",
...getVercelBypassHeaders(),
},
signal: controller.signal,
};
+2 -1
View File
@@ -1,5 +1,5 @@
import type { AgentName, BashPermission, PushPermission, ToolPermission } from "../external.ts";
import { getApiUrl } from "./apiUrl.ts";
import { getApiUrl, getVercelBypassHeaders } from "./apiUrl.ts";
import type { RepoContext } from "./github.ts";
export interface Mode {
@@ -65,6 +65,7 @@ export async function fetchRunContext(params: {
headers: {
Authorization: `Bearer ${params.token}`,
"Content-Type": "application/json",
...getVercelBypassHeaders(),
},
signal: controller.signal,
}