From 31069aa43c84ced62c16e5a68668c959bc0a0a88 Mon Sep 17 00:00:00 2001 From: npiccolo Date: Wed, 3 Jun 2026 16:38:45 -0300 Subject: [PATCH 1/2] feat(automerge): allow multiple bot identities via array allow-list Replace the hardcoded `svc-cli-bot` author check in cli:release:automerge with a small allow-list array (`ALLOWED_BOT_USERS`) and an exported `isAllowedBotUser()` helper. Adds `svc-idee-bot` to the list so the IDE Experience team's nightly release-PR automerge stops failing with 'PR must be created by "svc-cli-bot"'. New bots can be added by reviewed PR to that constant. Tests added for the helper. --- src/commands/cli/release/automerge.ts | 14 ++++++-- test/commands/cli.release.automerge.test.ts | 39 +++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test/commands/cli.release.automerge.test.ts diff --git a/src/commands/cli/release/automerge.ts b/src/commands/cli/release/automerge.ts index 50a9f6653..c97ebdcd3 100644 --- a/src/commands/cli/release/automerge.ts +++ b/src/commands/cli/release/automerge.ts @@ -16,6 +16,16 @@ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('@salesforce/plugin-release-management', 'cli.release.automerge'); +/** + * Bot accounts whose PRs are eligible for automerge. Add to this list (via + * reviewed PR) to onboard a new bot. + */ +export const ALLOWED_BOT_USERS = ['svc-cli-bot', 'svc-idee-bot'] as const; + +export function isAllowedBotUser(login: string | undefined | null): boolean { + return !!login && (ALLOWED_BOT_USERS as readonly string[]).includes(login); +} + type BaseRepoParams = { owner: string; repo: string; @@ -102,8 +112,8 @@ export default class AutoMerge extends SfCommand { stop(`Missing automerge label: [${automergeLabels.join(', ')}]`); } - if (prData.user?.login !== 'svc-cli-bot') { - stop('PR must be created by "svc-cli-bot"'); + if (!isAllowedBotUser(prData.user?.login)) { + stop(`PR must be created by one of: [${ALLOWED_BOT_USERS.join(', ')}]`); } if (!(await this.isGreen(prData, verbose))) { diff --git a/test/commands/cli.release.automerge.test.ts b/test/commands/cli.release.automerge.test.ts new file mode 100644 index 000000000..f409d1e10 --- /dev/null +++ b/test/commands/cli.release.automerge.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2026, salesforce.com, inc. + * All rights reserved. + * Licensed under the BSD 3-Clause license. + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ + +import { expect } from 'chai'; +import { ALLOWED_BOT_USERS, isAllowedBotUser } from '../../src/commands/cli/release/automerge.js'; + +describe('cli:release:automerge bot allow-list', () => { + it('accepts svc-cli-bot', () => { + expect(isAllowedBotUser('svc-cli-bot')).to.equal(true); + }); + + it('accepts svc-idee-bot', () => { + expect(isAllowedBotUser('svc-idee-bot')).to.equal(true); + }); + + it('rejects an unknown user', () => { + expect(isAllowedBotUser('random-user')).to.equal(false); + }); + + it('rejects undefined login', () => { + expect(isAllowedBotUser(undefined)).to.equal(false); + }); + + it('rejects null login', () => { + expect(isAllowedBotUser(null)).to.equal(false); + }); + + it('rejects empty string login', () => { + expect(isAllowedBotUser('')).to.equal(false); + }); + + it('exports the canonical allow-list', () => { + expect(ALLOWED_BOT_USERS).to.deep.equal(['svc-cli-bot', 'svc-idee-bot']); + }); +}); From c677ccb65009fa46dffbe98a29ef6dad8b62c835 Mon Sep 17 00:00:00 2001 From: npiccolo Date: Wed, 3 Jun 2026 16:38:49 -0300 Subject: [PATCH 2/2] refactor(automerge): apply review feedback on allow-list typing --- src/commands/cli/release/automerge.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/cli/release/automerge.ts b/src/commands/cli/release/automerge.ts index c97ebdcd3..5769b72c9 100644 --- a/src/commands/cli/release/automerge.ts +++ b/src/commands/cli/release/automerge.ts @@ -20,10 +20,10 @@ const messages = Messages.loadMessages('@salesforce/plugin-release-management', * Bot accounts whose PRs are eligible for automerge. Add to this list (via * reviewed PR) to onboard a new bot. */ -export const ALLOWED_BOT_USERS = ['svc-cli-bot', 'svc-idee-bot'] as const; +export const ALLOWED_BOT_USERS = ['svc-cli-bot', 'svc-idee-bot']; export function isAllowedBotUser(login: string | undefined | null): boolean { - return !!login && (ALLOWED_BOT_USERS as readonly string[]).includes(login); + return !!login && ALLOWED_BOT_USERS.includes(login); } type BaseRepoParams = {