11import { mkdirSync , writeFileSync } from "node:fs" ;
22import { chdir } from "node:process" ;
3+ import { execa } from "execa" ;
34import { http , HttpResponse } from "msw" ;
45import dedent from "ts-dedent" ;
56import { version } from "../../../package.json" ;
@@ -9,6 +10,7 @@ import { isRoutesJSONSpec } from "../../pages/functions/routes-validation";
910import { endEventLoop } from "../helpers/end-event-loop" ;
1011import { mockAccountId , mockApiToken } from "../helpers/mock-account-id" ;
1112import { mockConsoleMethods } from "../helpers/mock-console" ;
13+ import { mockPrompt } from "../helpers/mock-dialogs" ;
1214import { mockGetUploadTokenRequest } from "../helpers/mock-get-pages-upload-token" ;
1315import { useMockIsTTY } from "../helpers/mock-istty" ;
1416import { 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.
0 commit comments