Skip to content

Commit cc853cf

Browse files
authored
fix: pages deploy fails with git rev-parse error on new repo (#7687)
* add try catch * add tests * changeset
1 parent 85ebde7 commit cc853cf

File tree

3 files changed

+220
-8
lines changed

3 files changed

+220
-8
lines changed

.changeset/loud-ants-prove.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
fix: bug where Pages deployments that create new projects were failing with a new repo

packages/wrangler/src/__tests__/pages/deploy.test.ts

+203
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { mkdirSync, writeFileSync } from "node:fs";
22
import { chdir } from "node:process";
3+
import { execa } from "execa";
34
import { http, HttpResponse } from "msw";
45
import dedent from "ts-dedent";
56
import { version } from "../../../package.json";
@@ -9,6 +10,7 @@ import { isRoutesJSONSpec } from "../../pages/functions/routes-validation";
910
import { endEventLoop } from "../helpers/end-event-loop";
1011
import { mockAccountId, mockApiToken } from "../helpers/mock-account-id";
1112
import { mockConsoleMethods } from "../helpers/mock-console";
13+
import { mockPrompt } from "../helpers/mock-dialogs";
1214
import { mockGetUploadTokenRequest } from "../helpers/mock-get-pages-upload-token";
1315
import { useMockIsTTY } from "../helpers/mock-istty";
1416
import { mockSetTimeout } from "../helpers/mock-set-timeout";
@@ -1736,6 +1738,207 @@ describe("pages deploy", () => {
17361738
expect(std.err).toMatchInlineSnapshot(`""`);
17371739
});
17381740

1741+
// regression test for issue #3629
1742+
it("should not error when deploying a new project with a new repo", async () => {
1743+
vi.stubEnv("CI", "false");
1744+
setIsTTY(true);
1745+
await execa("git", ["init"]);
1746+
writeFileSync("logo.png", "foobar");
1747+
mockGetUploadTokenRequest(
1748+
"<<funfetti-auth-jwt>>",
1749+
"some-account-id",
1750+
"foo"
1751+
);
1752+
1753+
let getProjectRequestCount = 0;
1754+
msw.use(
1755+
http.post(
1756+
"*/pages/assets/check-missing",
1757+
async ({ request }) => {
1758+
const body = (await request.json()) as { hashes: string[] };
1759+
1760+
expect(request.headers.get("Authorization")).toBe(
1761+
"Bearer <<funfetti-auth-jwt>>"
1762+
);
1763+
expect(body).toMatchObject({
1764+
hashes: ["2082190357cfd3617ccfe04f340c6247"],
1765+
});
1766+
1767+
return HttpResponse.json(
1768+
{
1769+
success: true,
1770+
errors: [],
1771+
messages: [],
1772+
result: body.hashes,
1773+
},
1774+
{ status: 200 }
1775+
);
1776+
},
1777+
{ once: true }
1778+
),
1779+
http.post(
1780+
"*/pages/assets/upload",
1781+
async ({ request }) => {
1782+
expect(request.headers.get("Authorization")).toMatchInlineSnapshot(
1783+
`"Bearer <<funfetti-auth-jwt>>"`
1784+
);
1785+
expect(await request.json()).toMatchObject([
1786+
{
1787+
key: "2082190357cfd3617ccfe04f340c6247",
1788+
value: Buffer.from("foobar").toString("base64"),
1789+
metadata: {
1790+
contentType: "image/png",
1791+
},
1792+
base64: true,
1793+
},
1794+
]);
1795+
return HttpResponse.json(
1796+
{ success: true, errors: [], messages: [], result: null },
1797+
{ status: 200 }
1798+
);
1799+
},
1800+
{ once: true }
1801+
),
1802+
http.post(
1803+
"*/accounts/:accountId/pages/projects/foo/deployments",
1804+
async ({ request, params }) => {
1805+
expect(params.accountId).toEqual("some-account-id");
1806+
expect(await request.formData()).toMatchInlineSnapshot(`
1807+
FormData {
1808+
Symbol(state): Array [
1809+
Object {
1810+
"name": "manifest",
1811+
"value": "{\\"/logo.png\\":\\"2082190357cfd3617ccfe04f340c6247\\"}",
1812+
},
1813+
Object {
1814+
"name": "commit_dirty",
1815+
"value": "true",
1816+
},
1817+
],
1818+
}
1819+
`);
1820+
return HttpResponse.json(
1821+
{
1822+
success: true,
1823+
errors: [],
1824+
messages: [],
1825+
result: {
1826+
id: "123-456-789",
1827+
url: "https://abcxyz.foo.pages.dev/",
1828+
},
1829+
},
1830+
{ status: 200 }
1831+
);
1832+
},
1833+
{ once: true }
1834+
),
1835+
http.get(
1836+
"*/accounts/:accountId/pages/projects/foo/deployments/:deploymentId",
1837+
async ({ params }) => {
1838+
expect(params.accountId).toEqual("some-account-id");
1839+
expect(params.deploymentId).toEqual("123-456-789");
1840+
1841+
return HttpResponse.json(
1842+
{
1843+
success: true,
1844+
errors: [],
1845+
messages: [],
1846+
result: {
1847+
id: "123-456-789",
1848+
latest_stage: {
1849+
name: "deploy",
1850+
status: "success",
1851+
},
1852+
},
1853+
},
1854+
{ status: 200 }
1855+
);
1856+
},
1857+
{ once: true }
1858+
),
1859+
http.get("*/accounts/:accountId/pages/projects", async ({ params }) => {
1860+
getProjectRequestCount++;
1861+
1862+
expect(params.accountId).toEqual("some-account-id");
1863+
1864+
return HttpResponse.json(
1865+
{
1866+
success: true,
1867+
errors: [],
1868+
messages: [],
1869+
result: [],
1870+
},
1871+
{ status: 200 }
1872+
);
1873+
}),
1874+
http.post(
1875+
"*/accounts/:accountId/pages/projects",
1876+
async ({ request, params }) => {
1877+
const body = (await request.json()) as Record<string, unknown>;
1878+
1879+
expect(params.accountId).toEqual("some-account-id");
1880+
console.dir(body);
1881+
expect(body).toEqual({
1882+
name: "foo",
1883+
production_branch: "main",
1884+
});
1885+
1886+
return HttpResponse.json(
1887+
{
1888+
success: true,
1889+
errors: [],
1890+
messages: [],
1891+
result: {
1892+
...body,
1893+
subdomain: "foo.pages.dev",
1894+
},
1895+
},
1896+
{ status: 200 }
1897+
);
1898+
},
1899+
{ once: true }
1900+
),
1901+
http.get(
1902+
"*/accounts/:accountId/pages/projects/foo",
1903+
async ({ params }) => {
1904+
getProjectRequestCount++;
1905+
1906+
expect(params.accountId).toEqual("some-account-id");
1907+
1908+
return HttpResponse.json(
1909+
{
1910+
success: true,
1911+
errors: [],
1912+
messages: [],
1913+
result: {
1914+
deployment_configs: { production: {}, preview: {} },
1915+
},
1916+
},
1917+
{ status: 200 }
1918+
);
1919+
}
1920+
)
1921+
);
1922+
mockPrompt({
1923+
text: "Enter the name of your new project:",
1924+
result: "foo",
1925+
});
1926+
mockPrompt({
1927+
text: "Enter the production branch name:",
1928+
result: "main",
1929+
});
1930+
await runWrangler("pages deploy .");
1931+
1932+
expect(getProjectRequestCount).toBe(2);
1933+
expect(normalizeProgressSteps(std.out)).toMatchInlineSnapshot(`
1934+
"✨ Successfully created the 'foo' project.
1935+
✨ Success! Uploaded 1 files (TIMINGS)
1936+
1937+
🌎 Deploying...
1938+
✨ Deployment complete! Take a peek over at https://abcxyz.foo.pages.dev/"
1939+
`);
1940+
});
1941+
17391942
describe("with Pages Functions", () => {
17401943
it("should upload a Functions project", async () => {
17411944
// set up the directory of static files to upload.

packages/wrangler/src/pages/deploy.ts

+12-8
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,18 @@ export const Handler = async (args: PagesDeployArgs) => {
264264
isGitDir = false;
265265
}
266266

267-
const productionBranch = await prompt(
268-
"Enter the production branch name:",
269-
{
270-
defaultValue: isGitDir
271-
? execSync(`git rev-parse --abbrev-ref HEAD`).toString().trim()
272-
: "production",
273-
}
274-
);
267+
let productionBranch: string | undefined;
268+
if (isGitDir) {
269+
try {
270+
productionBranch = execSync(`git rev-parse --abbrev-ref HEAD`)
271+
.toString()
272+
.trim();
273+
} catch (err) {}
274+
}
275+
276+
productionBranch = await prompt("Enter the production branch name:", {
277+
defaultValue: productionBranch ?? "production",
278+
});
275279

276280
if (!productionBranch) {
277281
throw new FatalError("Must specify a production branch.", 1);

0 commit comments

Comments
 (0)