From f6c994580d91658cd716c62c55e87098d70a81f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 27 Mar 2026 10:53:46 +0000 Subject: [PATCH 1/4] feat: set `branch` as `alias` on `deploy` command --- src/lib/build.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/build.ts b/src/lib/build.ts index dafc5d07f2f..0599c7c4f3f 100644 --- a/src/lib/build.ts +++ b/src/lib/build.ts @@ -138,7 +138,7 @@ export const getRunBuildOptions = async ({ defaultConfig, deployHandler, deployId, - options: { context, cwd, debug, dry, json, offline, silent }, + options: { alias, branch: branchOption, context, cwd, debug, dry, json, offline, silent }, packagePath, skewProtectionToken, token, @@ -176,6 +176,13 @@ export const getRunBuildOptions = async ({ } } + // For non-production contexts, use the alias as the branch name so that + // branch-aware steps (e.g. DB setup) can create isolated resources for this + // deploy. In production, we leave it undefined so that @netlify/config + // resolves it from git as usual. + const isProductionContext = !context || context === 'production' + const branch = isProductionContext ? undefined : alias || branchOption + return { cachedConfig, defaultConfig: defaultConfig ?? {}, @@ -186,6 +193,7 @@ export const getRunBuildOptions = async ({ token: token ?? undefined, dry, debug, + branch, context, mode: 'cli', telemetry: false, From 0aef9f1eb496b68498e12b933bc4a9e6ceb3a948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 27 Mar 2026 13:35:47 +0000 Subject: [PATCH 2/4] refactor: simplify --- src/lib/build.ts | 11 ++------- tests/unit/lib/build.test.ts | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 tests/unit/lib/build.test.ts diff --git a/src/lib/build.ts b/src/lib/build.ts index 0599c7c4f3f..975aa107d37 100644 --- a/src/lib/build.ts +++ b/src/lib/build.ts @@ -138,7 +138,7 @@ export const getRunBuildOptions = async ({ defaultConfig, deployHandler, deployId, - options: { alias, branch: branchOption, context, cwd, debug, dry, json, offline, silent }, + options: { alias, context, cwd, debug, dry, json, offline, silent }, packagePath, skewProtectionToken, token, @@ -176,13 +176,6 @@ export const getRunBuildOptions = async ({ } } - // For non-production contexts, use the alias as the branch name so that - // branch-aware steps (e.g. DB setup) can create isolated resources for this - // deploy. In production, we leave it undefined so that @netlify/config - // resolves it from git as usual. - const isProductionContext = !context || context === 'production' - const branch = isProductionContext ? undefined : alias || branchOption - return { cachedConfig, defaultConfig: defaultConfig ?? {}, @@ -193,7 +186,7 @@ export const getRunBuildOptions = async ({ token: token ?? undefined, dry, debug, - branch, + branch: alias, context, mode: 'cli', telemetry: false, diff --git a/tests/unit/lib/build.test.ts b/tests/unit/lib/build.test.ts new file mode 100644 index 00000000000..8305a468cd4 --- /dev/null +++ b/tests/unit/lib/build.test.ts @@ -0,0 +1,45 @@ +import { describe, expect, test, vi } from 'vitest' + +import { getRunBuildOptions } from '../../../src/lib/build.js' + +vi.mock('../../../src/lib/edge-functions/bootstrap.js', () => ({ + getBootstrapURL: () => Promise.resolve('https://example.com/bootstrap'), +})) + +const createMockCachedConfig = () => ({ + accounts: [], + buildDir: '/test', + env: {}, + repositoryRoot: '/test', + siteInfo: { + id: 'site_id', + account_id: 'account_id', + feature_flags: {}, + }, + config: { + build: { base: '/test' }, + plugins: [], + }, +}) + +describe('getRunBuildOptions', () => { + test('should use alias as branch when alias is set', async () => { + const result = await getRunBuildOptions({ + cachedConfig: createMockCachedConfig(), + currentDir: '/test', + options: { alias: 'custom-alias' }, + }) + + expect(result.branch).toBe('custom-alias') + }) + + test('should leave branch undefined when alias is not set', async () => { + const result = await getRunBuildOptions({ + cachedConfig: createMockCachedConfig(), + currentDir: '/test', + options: {}, + }) + + expect(result.branch).toBeUndefined() + }) +}) From 571b076bc4138e54d46ca36742e6b7e882486cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 27 Mar 2026 13:38:27 +0000 Subject: [PATCH 3/4] chore: fix test --- tests/unit/lib/build.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/unit/lib/build.test.ts b/tests/unit/lib/build.test.ts index 8305a468cd4..726d870cbe5 100644 --- a/tests/unit/lib/build.test.ts +++ b/tests/unit/lib/build.test.ts @@ -9,6 +9,7 @@ vi.mock('../../../src/lib/edge-functions/bootstrap.js', () => ({ const createMockCachedConfig = () => ({ accounts: [], buildDir: '/test', + context: 'production', env: {}, repositoryRoot: '/test', siteInfo: { @@ -30,7 +31,7 @@ describe('getRunBuildOptions', () => { options: { alias: 'custom-alias' }, }) - expect(result.branch).toBe('custom-alias') + expect((result as Record).branch).toBe('custom-alias') }) test('should leave branch undefined when alias is not set', async () => { @@ -40,6 +41,6 @@ describe('getRunBuildOptions', () => { options: {}, }) - expect(result.branch).toBeUndefined() + expect((result as Record).branch).toBeUndefined() }) }) From bd329d6ed7d835b59f836d30ea4cb5d189210035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Bou=C3=A7as?= Date: Fri, 27 Mar 2026 13:51:07 +0000 Subject: [PATCH 4/4] chore: add test --- .../commands/deploy/deploy.test.ts | 42 +++++++++++++++++ tests/unit/lib/build.test.ts | 46 ------------------- 2 files changed, 42 insertions(+), 46 deletions(-) delete mode 100644 tests/unit/lib/build.test.ts diff --git a/tests/integration/commands/deploy/deploy.test.ts b/tests/integration/commands/deploy/deploy.test.ts index 553d66cb9aa..1490cf5215c 100644 --- a/tests/integration/commands/deploy/deploy.test.ts +++ b/tests/integration/commands/deploy/deploy.test.ts @@ -1441,6 +1441,48 @@ describe.concurrent('deploy command', () => { }) }) + test('should use alias as the branch for both the deploy request and the build', async (t) => { + await withMockDeploy(async (mockApi) => { + await withSiteBuilder(t, async (builder) => { + builder + .withContentFile({ + path: 'public/index.html', + content: '

test

', + }) + .withNetlifyToml({ + config: { + build: { publish: 'public' }, + plugins: [{ package: './plugins/log-branch' }], + }, + }) + .withBuildPlugin({ + name: 'log-branch', + plugin: { + async onPreBuild() { + console.log(`TEST_BRANCH: ${require('process').env.BRANCH}`) + }, + }, + }) + + await builder.build() + + const output: string = await callCli( + ['deploy', '--alias', 'custom-alias', '--context', 'deploy-preview'], + getCLIOptions({ apiUrl: mockApi.apiUrl, builder }), + ) + + const [, branch] = output.match(/TEST_BRANCH: (.+)/) ?? [] + expect(branch).toBe('custom-alias') + + const createDeployRequest = mockApi.requests.find( + (req) => req.method === 'POST' && req.path === '/api/v1/sites/site_id/deploys', + ) + expect(createDeployRequest).toBeDefined() + expect((createDeployRequest!.body as Record).branch).toBe('custom-alias') + }) + }) + }) + test('should include build_version in deploy body', async (t) => { await withMockDeploy(async (mockApi, deployState) => { await withSiteBuilder(t, async (builder) => { diff --git a/tests/unit/lib/build.test.ts b/tests/unit/lib/build.test.ts deleted file mode 100644 index 726d870cbe5..00000000000 --- a/tests/unit/lib/build.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { describe, expect, test, vi } from 'vitest' - -import { getRunBuildOptions } from '../../../src/lib/build.js' - -vi.mock('../../../src/lib/edge-functions/bootstrap.js', () => ({ - getBootstrapURL: () => Promise.resolve('https://example.com/bootstrap'), -})) - -const createMockCachedConfig = () => ({ - accounts: [], - buildDir: '/test', - context: 'production', - env: {}, - repositoryRoot: '/test', - siteInfo: { - id: 'site_id', - account_id: 'account_id', - feature_flags: {}, - }, - config: { - build: { base: '/test' }, - plugins: [], - }, -}) - -describe('getRunBuildOptions', () => { - test('should use alias as branch when alias is set', async () => { - const result = await getRunBuildOptions({ - cachedConfig: createMockCachedConfig(), - currentDir: '/test', - options: { alias: 'custom-alias' }, - }) - - expect((result as Record).branch).toBe('custom-alias') - }) - - test('should leave branch undefined when alias is not set', async () => { - const result = await getRunBuildOptions({ - cachedConfig: createMockCachedConfig(), - currentDir: '/test', - options: {}, - }) - - expect((result as Record).branch).toBeUndefined() - }) -})