diff --git a/src/commands/deploy/deploy.ts b/src/commands/deploy/deploy.ts index a4299b5ce07..1a5ab4f012e 100644 --- a/src/commands/deploy/deploy.ts +++ b/src/commands/deploy/deploy.ts @@ -345,6 +345,55 @@ const deployProgressCb = function () { } } +const uploadDeployBlobs = async ({ + cachedConfig, + deployId, + options, + silent, + siteId, +}: { + cachedConfig: any + deployId: string + options: OptionValues + silent: boolean + siteId: string +}) => { + const statusCb = silent ? () => {} : deployProgressCb() + + statusCb({ + type: 'blobs-uploading', + msg: 'Uploading blobs to deploy store...\n', + phase: 'start', + }) + + const [token] = await getToken(false) + + const { success } = await runCoreSteps(['blobs_upload'], { + ...options, + quiet: silent, + cachedConfig, + deployId, + siteId, + token, + }) + + if (!success) { + statusCb({ + type: 'blobs-uploading', + msg: 'Deploy aborted due to error while uploading blobs to deploy store', + phase: 'error', + }) + + error('Error while uploading blobs to deploy store') + } + + statusCb({ + type: 'blobs-uploading', + msg: 'Finished uploading blobs to deploy store', + phase: 'stop', + }) +} + const runDeploy = async ({ // @ts-expect-error TS(7031) FIXME: Binding element 'alias' implicitly has an 'any' ty... Remove this comment to see the full error message alias, @@ -364,6 +413,8 @@ const runDeploy = async ({ functionsConfig, // @ts-expect-error TS(7031) FIXME: Binding element 'functionsFolder' implicitly has a... Remove this comment to see the full error message functionsFolder, + // @ts-expect-error TS(7031) FIXME: Binding element 'options' implicitly has an 'a... Remove this comment to see the full error message + options, // @ts-expect-error TS(7031) FIXME: Binding element 'packagePath' implicitly has an 'a... Remove this comment to see the full error message packagePath, // @ts-expect-error TS(7031) FIXME: Binding element 'silent' implicitly has an 'any' t... Remove this comment to see the full error message @@ -421,6 +472,7 @@ const runDeploy = async ({ }) config.headers = headers + uploadDeployBlobs({ deployId, siteId, silent, options, cachedConfig: command.netlify.cachedConfig }) results = await deploySite(api, siteId, deployFolder, { config, @@ -690,6 +742,7 @@ const prepAndRunDeploy = async ({ functionsConfig, // pass undefined functionsFolder if doesn't exist functionsFolder: functionsFolderStat && functionsFolder, + options, packagePath: command.workspacePackage, silent: options.json || options.silent, site, diff --git a/tests/integration/commands/deploy/deploy.test.js b/tests/integration/commands/deploy/deploy.test.js index 3861592aef4..a092e147fa2 100644 --- a/tests/integration/commands/deploy/deploy.test.js +++ b/tests/integration/commands/deploy/deploy.test.js @@ -2,6 +2,7 @@ import path from 'path' import process from 'process' import { fileURLToPath } from 'url' +import execa from 'execa' import fetch from 'node-fetch' import { afterAll, beforeAll, describe, test } from 'vitest' @@ -817,4 +818,59 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co t.expect(response).toEqual('Bundled at deployment') }) }) + + test('should upload blobs when saved into .netlify directory', async (t) => { + await withSiteBuilder('site-with-blobs', async (builder) => { + await builder + .withNetlifyToml({ + config: { + build: { publish: 'dist', functions: 'functions' }, + }, + }) + .withContentFile({ + path: 'dist/.netlify/blobs/deploy/hello', + content: 'hello from the blob', + }) + .withPackageJson({ + packageJson: { + dependencies: { + '@netlify/blobs': '^6.3.0', + '@netlify/functions': '^2.4.0', + }, + }, + }) + .withContentFile({ + path: 'functions/read-blob.ts', + content: ` + import { getDeployStore } from "@netlify/blobs" + import { Config, Context } from "@netlify/functions" + + export default async (req: Request, context: Context) => { + const store = getDeployStore() + const blob = await store.get('hello') + + return new Response(blob) + } + + export const config: Config = { + path: "/read-blob" + } + `, + }) + .buildAsync() + + await execa.command('npm install', { cwd: builder.directory }) + const { deploy_url: deployUrl } = await callCli( + ['deploy', '--json'], + { + cwd: builder.directory, + env: { NETLIFY_SITE_ID: context.siteId }, + }, + true, + ) + + const response = await fetch(`${deployUrl}/read-blob`).then((res) => res.text()) + t.expect(response).toEqual('hello from the blob') + }) + }) })