From 944d3fa82e29f3469b1aeeab2c4b191f05cc7d7e Mon Sep 17 00:00:00 2001 From: enyineer Date: Fri, 10 Oct 2025 09:50:35 +0200 Subject: [PATCH 1/8] Bootstrap Proxy agent if proxy configured Signed-off-by: enyineer --- packages/create-app/src/lib/tasks.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/create-app/src/lib/tasks.ts b/packages/create-app/src/lib/tasks.ts index 230590e99c..327094f7cd 100644 --- a/packages/create-app/src/lib/tasks.ts +++ b/packages/create-app/src/lib/tasks.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +maybeBootstrapProxy(); + import chalk from 'chalk'; import fs from 'fs-extra'; import handlebars from 'handlebars'; @@ -30,6 +32,26 @@ import { packageVersions } from './versions'; import { promisify } from 'util'; import os from 'os'; +function maybeBootstrapProxy() { + // see https://www.npmjs.com/package/global-agent + const globalAgentNamespace = + process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE ?? 'GLOBAL_AGENT_'; + if ( + process.env[`${globalAgentNamespace}HTTP_PROXY`] || + process.env[`${globalAgentNamespace}HTTPS_PROXY`] + ) { + const globalAgent = + require('global-agent') as typeof import('global-agent'); + globalAgent.bootstrap(); + } + + if (process.env.HTTP_PROXY || process.env.HTTPS_PROXY) { + const { setGlobalDispatcher, EnvHttpProxyAgent } = + require('undici') as typeof import('undici'); + setGlobalDispatcher(new EnvHttpProxyAgent()); + } +} + const TASK_NAME_MAX_LENGTH = 14; const TEN_MINUTES_MS = 1000 * 60 * 10; const exec = promisify(execCb); From cdbec2e0d5673db61ec94116e239f1d7639c2b12 Mon Sep 17 00:00:00 2001 From: enyineer Date: Fri, 10 Oct 2025 10:09:47 +0200 Subject: [PATCH 2/8] Add proxy to create-app tasks Signed-off-by: enyineer --- packages/cli-common/src/index.ts | 1 + .../cli-common/src/proxyBootstrap.test.ts | 108 ++++++++++++++++++ packages/cli-common/src/proxyBootstrap.ts | 35 ++++++ .../modules/migrate/commands/versions/bump.ts | 22 +--- packages/create-app/package.json | 5 +- packages/create-app/src/lib/tasks.test.ts | 9 ++ packages/create-app/src/lib/tasks.ts | 21 +--- yarn.lock | 12 ++ 8 files changed, 171 insertions(+), 42 deletions(-) create mode 100644 packages/cli-common/src/proxyBootstrap.test.ts create mode 100644 packages/cli-common/src/proxyBootstrap.ts diff --git a/packages/cli-common/src/index.ts b/packages/cli-common/src/index.ts index 8809764b43..194644db95 100644 --- a/packages/cli-common/src/index.ts +++ b/packages/cli-common/src/index.ts @@ -23,3 +23,4 @@ export { findPaths, BACKSTAGE_JSON } from './paths'; export { isChildPath } from './isChildPath'; export type { Paths, ResolveFunc } from './paths'; +export { maybeBootstrapProxy } from './proxyBootstrap'; diff --git a/packages/cli-common/src/proxyBootstrap.test.ts b/packages/cli-common/src/proxyBootstrap.test.ts new file mode 100644 index 0000000000..1132e640f0 --- /dev/null +++ b/packages/cli-common/src/proxyBootstrap.test.ts @@ -0,0 +1,108 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { maybeBootstrapProxy } from './proxyBootstrap'; + +jest.mock('global-agent', () => ({ + bootstrap: jest.fn(), +})); + +jest.mock('undici', () => ({ + setGlobalDispatcher: jest.fn(), + EnvHttpProxyAgent: jest.fn(), +})); + +describe('maybeBootstrapProxy', () => { + const originalEnv = process.env; + + beforeEach(() => { + jest.resetModules(); + process.env = { ...originalEnv }; + }); + + afterEach(() => { + process.env = originalEnv; + jest.clearAllMocks(); + }); + + it('should bootstrap global-agent if GLOBAL_AGENT_HTTP_PROXY is set', () => { + process.env.GLOBAL_AGENT_HTTP_PROXY = 'http://proxy.example.com'; + + const { bootstrap } = + require('global-agent') as typeof import('global-agent'); + maybeBootstrapProxy(); + + expect(bootstrap).toHaveBeenCalledTimes(1); + }); + + it('should bootstrap global-agent if GLOBAL_AGENT_HTTPS_PROXY is set', () => { + process.env.GLOBAL_AGENT_HTTPS_PROXY = 'https://proxy.example.com'; + + const { bootstrap } = + require('global-agent') as typeof import('global-agent'); + maybeBootstrapProxy(); + + expect(bootstrap).toHaveBeenCalledTimes(1); + }); + + it('should use undici EnvHttpProxyAgent if HTTP_PROXY is set', () => { + process.env.HTTP_PROXY = 'http://proxy.example.com'; + + const { setGlobalDispatcher, EnvHttpProxyAgent } = + require('undici') as typeof import('undici'); + maybeBootstrapProxy(); + + expect(EnvHttpProxyAgent).toHaveBeenCalledTimes(1); + expect(setGlobalDispatcher).toHaveBeenCalledWith( + expect.any(EnvHttpProxyAgent), + ); + }); + + it('should use undici EnvHttpProxyAgent if HTTPS_PROXY is set', () => { + process.env.HTTPS_PROXY = 'https://proxy.example.com'; + + const { setGlobalDispatcher, EnvHttpProxyAgent } = + require('undici') as typeof import('undici'); + maybeBootstrapProxy(); + + expect(EnvHttpProxyAgent).toHaveBeenCalledTimes(1); + expect(setGlobalDispatcher).toHaveBeenCalledWith( + expect.any(EnvHttpProxyAgent), + ); + }); + + it('should not bootstrap global-agent or set undici dispatcher if no proxy is set', () => { + const { bootstrap } = + require('global-agent') as typeof import('global-agent'); + const { setGlobalDispatcher } = + require('undici') as typeof import('undici'); + + maybeBootstrapProxy(); + + expect(bootstrap).not.toHaveBeenCalled(); + expect(setGlobalDispatcher).not.toHaveBeenCalled(); + }); + + it('should respect GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE', () => { + process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE = 'CUSTOM_AGENT_'; + process.env.CUSTOM_AGENT_HTTP_PROXY = 'http://proxy.example.com'; + + const { bootstrap } = + require('global-agent') as typeof import('global-agent'); + maybeBootstrapProxy(); + + expect(bootstrap).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/cli-common/src/proxyBootstrap.ts b/packages/cli-common/src/proxyBootstrap.ts new file mode 100644 index 0000000000..6632a9054f --- /dev/null +++ b/packages/cli-common/src/proxyBootstrap.ts @@ -0,0 +1,35 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function maybeBootstrapProxy() { + // see https://www.npmjs.com/package/global-agent + const globalAgentNamespace = + process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE ?? 'GLOBAL_AGENT_'; + if ( + process.env[`${globalAgentNamespace}HTTP_PROXY`] || + process.env[`${globalAgentNamespace}HTTPS_PROXY`] + ) { + const globalAgent = + require('global-agent') as typeof import('global-agent'); + globalAgent.bootstrap(); + } + + if (process.env.HTTP_PROXY || process.env.HTTPS_PROXY) { + const { setGlobalDispatcher, EnvHttpProxyAgent } = + require('undici') as typeof import('undici'); + setGlobalDispatcher(new EnvHttpProxyAgent()); + } +} diff --git a/packages/cli/src/modules/migrate/commands/versions/bump.ts b/packages/cli/src/modules/migrate/commands/versions/bump.ts index 39cfeddbd5..010b3de673 100644 --- a/packages/cli/src/modules/migrate/commands/versions/bump.ts +++ b/packages/cli/src/modules/migrate/commands/versions/bump.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { BACKSTAGE_JSON, maybeBootstrapProxy } from '@backstage/cli-common'; maybeBootstrapProxy(); @@ -31,7 +32,6 @@ import { Lockfile, YarnInfoInspectData, } from '../../../../lib/versioning'; -import { BACKSTAGE_JSON } from '@backstage/cli-common'; import { runParallelWorkers } from '../../../../lib/parallel'; import { getManifestByReleaseLine, @@ -42,26 +42,6 @@ import { migrateMovedPackages } from './migrate'; import { runYarnInstall } from '../../lib/utils'; import { run } from '../../../../lib/run'; -function maybeBootstrapProxy() { - // see https://www.npmjs.com/package/global-agent - const globalAgentNamespace = - process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE ?? 'GLOBAL_AGENT_'; - if ( - process.env[`${globalAgentNamespace}HTTP_PROXY`] || - process.env[`${globalAgentNamespace}HTTPS_PROXY`] - ) { - const globalAgent = - require('global-agent') as typeof import('global-agent'); - globalAgent.bootstrap(); - } - - if (process.env.HTTP_PROXY || process.env.HTTPS_PROXY) { - const { setGlobalDispatcher, EnvHttpProxyAgent } = - require('undici') as typeof import('undici'); - setGlobalDispatcher(new EnvHttpProxyAgent()); - } -} - const DEP_TYPES = [ 'dependencies', 'devDependencies', diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 9fa8af4c1b..65d8801859 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -47,16 +47,19 @@ "chalk": "^4.0.0", "commander": "^12.0.0", "fs-extra": "^11.2.0", + "global-agent": "^3.0.0", "handlebars": "^4.7.3", "inquirer": "^8.2.0", "ora": "^5.3.0", - "recursive-readdir": "^2.2.2" + "recursive-readdir": "^2.2.2", + "undici": "^7.2.3" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^11.0.0", + "@types/global-agent": "^3", "@types/inquirer": "^8.1.3", "@types/node": "^20.16.0", "@types/recursive-readdir": "^2.2.0", diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index 86a7008b4d..0556cbf1da 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -36,6 +36,15 @@ import { import { http, HttpResponse, delay } from 'msw'; import { setupServer } from 'msw/node'; +// Avoid mutating the global agents used in other tests +jest.mock('global-agent', () => ({ + bootstrap: jest.fn(), +})); +jest.mock('undici', () => ({ + setGlobalDispatcher: jest.fn(), + EnvHttpProxyAgent: class {}, +})); + jest.spyOn(Task, 'log').mockReturnValue(undefined); jest.spyOn(Task, 'error').mockReturnValue(undefined); jest.spyOn(Task, 'section').mockReturnValue(undefined); diff --git a/packages/create-app/src/lib/tasks.ts b/packages/create-app/src/lib/tasks.ts index 327094f7cd..1bd42a108a 100644 --- a/packages/create-app/src/lib/tasks.ts +++ b/packages/create-app/src/lib/tasks.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { maybeBootstrapProxy } from '@backstage/cli-common'; maybeBootstrapProxy(); @@ -32,26 +33,6 @@ import { packageVersions } from './versions'; import { promisify } from 'util'; import os from 'os'; -function maybeBootstrapProxy() { - // see https://www.npmjs.com/package/global-agent - const globalAgentNamespace = - process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE ?? 'GLOBAL_AGENT_'; - if ( - process.env[`${globalAgentNamespace}HTTP_PROXY`] || - process.env[`${globalAgentNamespace}HTTPS_PROXY`] - ) { - const globalAgent = - require('global-agent') as typeof import('global-agent'); - globalAgent.bootstrap(); - } - - if (process.env.HTTP_PROXY || process.env.HTTPS_PROXY) { - const { setGlobalDispatcher, EnvHttpProxyAgent } = - require('undici') as typeof import('undici'); - setGlobalDispatcher(new EnvHttpProxyAgent()); - } -} - const TASK_NAME_MAX_LENGTH = 14; const TEN_MINUTES_MS = 1000 * 60 * 10; const exec = promisify(execCb); diff --git a/yarn.lock b/yarn.lock index 865c2a931e..58105e4d68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2802,6 +2802,8 @@ __metadata: dependencies: "@backstage/cli": "workspace:^" "@types/node": "npm:^20.16.0" + global-agent: "npm:^3.0.0" + undici: "npm:^7.2.3" languageName: unknown linkType: soft @@ -3259,18 +3261,21 @@ __metadata: "@backstage/cli-common": "workspace:^" "@types/command-exists": "npm:^1.2.0" "@types/fs-extra": "npm:^11.0.0" + "@types/global-agent": "npm:^3" "@types/inquirer": "npm:^8.1.3" "@types/node": "npm:^20.16.0" "@types/recursive-readdir": "npm:^2.2.0" chalk: "npm:^4.0.0" commander: "npm:^12.0.0" fs-extra: "npm:^11.2.0" + global-agent: "npm:^3.0.0" handlebars: "npm:^4.7.3" inquirer: "npm:^8.2.0" msw: "npm:^2.0.0" nodemon: "npm:^3.0.1" ora: "npm:^5.3.0" recursive-readdir: "npm:^2.2.2" + undici: "npm:^7.2.3" bin: backstage-create-app: bin/backstage-create-app languageName: unknown @@ -19972,6 +19977,13 @@ __metadata: languageName: node linkType: hard +"@types/global-agent@npm:^3": + version: 3.0.0 + resolution: "@types/global-agent@npm:3.0.0" + checksum: 10/f961aaf493176e651dcb1bdb8f31b3f933f7ba86a74901c40399622e7f09621d84e0c12cca62ddee12bd8d783656359d25ec88aa57bba3fbcbd58f60f8cbdb18 + languageName: node + linkType: hard + "@types/google-protobuf@npm:^3.7.2": version: 3.15.12 resolution: "@types/google-protobuf@npm:3.15.12" From f553c56556c6bcf4524f80e1c217ce946a97c772 Mon Sep 17 00:00:00 2001 From: enyineer Date: Fri, 10 Oct 2025 10:10:12 +0200 Subject: [PATCH 3/8] Add undici and global-agent as dependencies Signed-off-by: enyineer --- packages/cli-common/package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/cli-common/package.json b/packages/cli-common/package.json index d8242fd325..edd81dbe5f 100644 --- a/packages/cli-common/package.json +++ b/packages/cli-common/package.json @@ -34,6 +34,10 @@ "start": "backstage-cli package start", "test": "backstage-cli package test" }, + "dependencies": { + "global-agent": "^3.0.0", + "undici": "^7.2.3" + }, "devDependencies": { "@backstage/cli": "workspace:^", "@types/node": "^20.16.0" From c8c2329dd1f28a8719a09f360c9fc96f197cf2a2 Mon Sep 17 00:00:00 2001 From: enyineer Date: Fri, 10 Oct 2025 10:12:34 +0200 Subject: [PATCH 4/8] Add changeset Signed-off-by: enyineer --- .changeset/short-groups-knock.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/short-groups-knock.md diff --git a/.changeset/short-groups-knock.md b/.changeset/short-groups-knock.md new file mode 100644 index 0000000000..0b622a71ed --- /dev/null +++ b/.changeset/short-groups-knock.md @@ -0,0 +1,7 @@ +--- +'@backstage/cli-common': patch +'@backstage/create-app': patch +'@backstage/cli': patch +--- + +Add proxy configuration from env-vars to create-app tasks From 235c67ae99e8a2a863bc3970a50c4b96ba91dafd Mon Sep 17 00:00:00 2001 From: enyineer Date: Fri, 10 Oct 2025 10:38:34 +0200 Subject: [PATCH 5/8] Add API doc for maybeBootstrapProxy Signed-off-by: enyineer --- packages/cli-common/report.api.md | 3 +++ packages/cli-common/src/proxyBootstrap.ts | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/packages/cli-common/report.api.md b/packages/cli-common/report.api.md index 34f56c3f19..d541166bf1 100644 --- a/packages/cli-common/report.api.md +++ b/packages/cli-common/report.api.md @@ -12,6 +12,9 @@ export function findPaths(searchDir: string): Paths; // @public export function isChildPath(base: string, path: string): boolean; +// @public +export function maybeBootstrapProxy(): void; + // @public export type Paths = { ownDir: string; diff --git a/packages/cli-common/src/proxyBootstrap.ts b/packages/cli-common/src/proxyBootstrap.ts index 6632a9054f..d338611cb1 100644 --- a/packages/cli-common/src/proxyBootstrap.ts +++ b/packages/cli-common/src/proxyBootstrap.ts @@ -14,6 +14,20 @@ * limitations under the License. */ +/** + * This function can be called to setup undici and node-fetch Proxy agents. + * + * You can set GLOBAL_AGENT_HTTP(S)_PROXY to configure a proxy to be used in the + * CLIs. + * + * You can also configure a custom namespace by setting + * GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE which will replace the default + * "GLOBAL_AGENT_" env-var prefix. + * + * Make sure to call this function before any other imports. + * + * @public + */ export function maybeBootstrapProxy() { // see https://www.npmjs.com/package/global-agent const globalAgentNamespace = From 84a0dff66ff8f7468a1ce4603379d6c0e68f1f97 Mon Sep 17 00:00:00 2001 From: enyineer Date: Wed, 12 Nov 2025 15:02:04 +0100 Subject: [PATCH 6/8] Refactor naming of proxy bootstrapping function Signed-off-by: enyineer --- packages/cli-common/report.api.md | 6 +++--- packages/cli-common/src/index.ts | 2 +- packages/cli-common/src/proxyBootstrap.test.ts | 16 ++++++++-------- packages/cli-common/src/proxyBootstrap.ts | 2 +- .../modules/migrate/commands/versions/bump.ts | 4 ++-- packages/create-app/src/lib/tasks.ts | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/cli-common/report.api.md b/packages/cli-common/report.api.md index d541166bf1..0e3c80afa4 100644 --- a/packages/cli-common/report.api.md +++ b/packages/cli-common/report.api.md @@ -6,15 +6,15 @@ // @public export const BACKSTAGE_JSON = 'backstage.json'; +// @public +export function bootstrapEnvProxyAgents(): void; + // @public export function findPaths(searchDir: string): Paths; // @public export function isChildPath(base: string, path: string): boolean; -// @public -export function maybeBootstrapProxy(): void; - // @public export type Paths = { ownDir: string; diff --git a/packages/cli-common/src/index.ts b/packages/cli-common/src/index.ts index 194644db95..11e5d05f4f 100644 --- a/packages/cli-common/src/index.ts +++ b/packages/cli-common/src/index.ts @@ -23,4 +23,4 @@ export { findPaths, BACKSTAGE_JSON } from './paths'; export { isChildPath } from './isChildPath'; export type { Paths, ResolveFunc } from './paths'; -export { maybeBootstrapProxy } from './proxyBootstrap'; +export { bootstrapEnvProxyAgents } from './proxyBootstrap'; diff --git a/packages/cli-common/src/proxyBootstrap.test.ts b/packages/cli-common/src/proxyBootstrap.test.ts index 1132e640f0..5b6bf295df 100644 --- a/packages/cli-common/src/proxyBootstrap.test.ts +++ b/packages/cli-common/src/proxyBootstrap.test.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { maybeBootstrapProxy } from './proxyBootstrap'; +import { bootstrapEnvProxyAgents } from './proxyBootstrap'; jest.mock('global-agent', () => ({ bootstrap: jest.fn(), @@ -24,7 +24,7 @@ jest.mock('undici', () => ({ EnvHttpProxyAgent: jest.fn(), })); -describe('maybeBootstrapProxy', () => { +describe('bootstrapEnvProxyAgents', () => { const originalEnv = process.env; beforeEach(() => { @@ -42,7 +42,7 @@ describe('maybeBootstrapProxy', () => { const { bootstrap } = require('global-agent') as typeof import('global-agent'); - maybeBootstrapProxy(); + bootstrapEnvProxyAgents(); expect(bootstrap).toHaveBeenCalledTimes(1); }); @@ -52,7 +52,7 @@ describe('maybeBootstrapProxy', () => { const { bootstrap } = require('global-agent') as typeof import('global-agent'); - maybeBootstrapProxy(); + bootstrapEnvProxyAgents(); expect(bootstrap).toHaveBeenCalledTimes(1); }); @@ -62,7 +62,7 @@ describe('maybeBootstrapProxy', () => { const { setGlobalDispatcher, EnvHttpProxyAgent } = require('undici') as typeof import('undici'); - maybeBootstrapProxy(); + bootstrapEnvProxyAgents(); expect(EnvHttpProxyAgent).toHaveBeenCalledTimes(1); expect(setGlobalDispatcher).toHaveBeenCalledWith( @@ -75,7 +75,7 @@ describe('maybeBootstrapProxy', () => { const { setGlobalDispatcher, EnvHttpProxyAgent } = require('undici') as typeof import('undici'); - maybeBootstrapProxy(); + bootstrapEnvProxyAgents(); expect(EnvHttpProxyAgent).toHaveBeenCalledTimes(1); expect(setGlobalDispatcher).toHaveBeenCalledWith( @@ -89,7 +89,7 @@ describe('maybeBootstrapProxy', () => { const { setGlobalDispatcher } = require('undici') as typeof import('undici'); - maybeBootstrapProxy(); + bootstrapEnvProxyAgents(); expect(bootstrap).not.toHaveBeenCalled(); expect(setGlobalDispatcher).not.toHaveBeenCalled(); @@ -101,7 +101,7 @@ describe('maybeBootstrapProxy', () => { const { bootstrap } = require('global-agent') as typeof import('global-agent'); - maybeBootstrapProxy(); + bootstrapEnvProxyAgents(); expect(bootstrap).toHaveBeenCalledTimes(1); }); diff --git a/packages/cli-common/src/proxyBootstrap.ts b/packages/cli-common/src/proxyBootstrap.ts index d338611cb1..b7375b6e55 100644 --- a/packages/cli-common/src/proxyBootstrap.ts +++ b/packages/cli-common/src/proxyBootstrap.ts @@ -28,7 +28,7 @@ * * @public */ -export function maybeBootstrapProxy() { +export function bootstrapEnvProxyAgents() { // see https://www.npmjs.com/package/global-agent const globalAgentNamespace = process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE ?? 'GLOBAL_AGENT_'; diff --git a/packages/cli/src/modules/migrate/commands/versions/bump.ts b/packages/cli/src/modules/migrate/commands/versions/bump.ts index 010b3de673..b424d41576 100644 --- a/packages/cli/src/modules/migrate/commands/versions/bump.ts +++ b/packages/cli/src/modules/migrate/commands/versions/bump.ts @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BACKSTAGE_JSON, maybeBootstrapProxy } from '@backstage/cli-common'; +import { BACKSTAGE_JSON, bootstrapEnvProxyAgents } from '@backstage/cli-common'; -maybeBootstrapProxy(); +bootstrapEnvProxyAgents(); import fs from 'fs-extra'; import chalk from 'chalk'; diff --git a/packages/create-app/src/lib/tasks.ts b/packages/create-app/src/lib/tasks.ts index 1bd42a108a..0ab31dd5f4 100644 --- a/packages/create-app/src/lib/tasks.ts +++ b/packages/create-app/src/lib/tasks.ts @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { maybeBootstrapProxy } from '@backstage/cli-common'; +import { bootstrapEnvProxyAgents } from '@backstage/cli-common'; -maybeBootstrapProxy(); +bootstrapEnvProxyAgents(); import chalk from 'chalk'; import fs from 'fs-extra'; From 1a483ed02f7a649ebb8fbce32b15ef23f562d858 Mon Sep 17 00:00:00 2001 From: enyineer Date: Wed, 19 Nov 2025 10:11:12 +0100 Subject: [PATCH 7/8] Remove undici and old mocks Signed-off-by: enyineer --- packages/cli-common/src/proxyBootstrap.test.ts | 2 +- packages/create-app/package.json | 3 +-- packages/create-app/src/lib/tasks.test.ts | 9 --------- yarn.lock | 1 - 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/cli-common/src/proxyBootstrap.test.ts b/packages/cli-common/src/proxyBootstrap.test.ts index 5b6bf295df..cefa1bd36e 100644 --- a/packages/cli-common/src/proxyBootstrap.test.ts +++ b/packages/cli-common/src/proxyBootstrap.test.ts @@ -15,10 +15,10 @@ */ import { bootstrapEnvProxyAgents } from './proxyBootstrap'; +// Avoid mutating the global agents used in other tests jest.mock('global-agent', () => ({ bootstrap: jest.fn(), })); - jest.mock('undici', () => ({ setGlobalDispatcher: jest.fn(), EnvHttpProxyAgent: jest.fn(), diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 65d8801859..fc69b0dcff 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -51,8 +51,7 @@ "handlebars": "^4.7.3", "inquirer": "^8.2.0", "ora": "^5.3.0", - "recursive-readdir": "^2.2.2", - "undici": "^7.2.3" + "recursive-readdir": "^2.2.2" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index 0556cbf1da..86a7008b4d 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -36,15 +36,6 @@ import { import { http, HttpResponse, delay } from 'msw'; import { setupServer } from 'msw/node'; -// Avoid mutating the global agents used in other tests -jest.mock('global-agent', () => ({ - bootstrap: jest.fn(), -})); -jest.mock('undici', () => ({ - setGlobalDispatcher: jest.fn(), - EnvHttpProxyAgent: class {}, -})); - jest.spyOn(Task, 'log').mockReturnValue(undefined); jest.spyOn(Task, 'error').mockReturnValue(undefined); jest.spyOn(Task, 'section').mockReturnValue(undefined); diff --git a/yarn.lock b/yarn.lock index 58105e4d68..c64a2d0e41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3275,7 +3275,6 @@ __metadata: nodemon: "npm:^3.0.1" ora: "npm:^5.3.0" recursive-readdir: "npm:^2.2.2" - undici: "npm:^7.2.3" bin: backstage-create-app: bin/backstage-create-app languageName: unknown From ab017b991882d275027e502af3c6f7392c3c0874 Mon Sep 17 00:00:00 2001 From: enyineer Date: Wed, 19 Nov 2025 10:42:45 +0100 Subject: [PATCH 8/8] Remove global-agent from create-app Signed-off-by: enyineer --- packages/create-app/package.json | 2 -- yarn.lock | 9 --------- 2 files changed, 11 deletions(-) diff --git a/packages/create-app/package.json b/packages/create-app/package.json index fc69b0dcff..9fa8af4c1b 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -47,7 +47,6 @@ "chalk": "^4.0.0", "commander": "^12.0.0", "fs-extra": "^11.2.0", - "global-agent": "^3.0.0", "handlebars": "^4.7.3", "inquirer": "^8.2.0", "ora": "^5.3.0", @@ -58,7 +57,6 @@ "@backstage/cli": "workspace:^", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^11.0.0", - "@types/global-agent": "^3", "@types/inquirer": "^8.1.3", "@types/node": "^20.16.0", "@types/recursive-readdir": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index c64a2d0e41..1fc092a603 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3261,14 +3261,12 @@ __metadata: "@backstage/cli-common": "workspace:^" "@types/command-exists": "npm:^1.2.0" "@types/fs-extra": "npm:^11.0.0" - "@types/global-agent": "npm:^3" "@types/inquirer": "npm:^8.1.3" "@types/node": "npm:^20.16.0" "@types/recursive-readdir": "npm:^2.2.0" chalk: "npm:^4.0.0" commander: "npm:^12.0.0" fs-extra: "npm:^11.2.0" - global-agent: "npm:^3.0.0" handlebars: "npm:^4.7.3" inquirer: "npm:^8.2.0" msw: "npm:^2.0.0" @@ -19976,13 +19974,6 @@ __metadata: languageName: node linkType: hard -"@types/global-agent@npm:^3": - version: 3.0.0 - resolution: "@types/global-agent@npm:3.0.0" - checksum: 10/f961aaf493176e651dcb1bdb8f31b3f933f7ba86a74901c40399622e7f09621d84e0c12cca62ddee12bd8d783656359d25ec88aa57bba3fbcbd58f60f8cbdb18 - languageName: node - linkType: hard - "@types/google-protobuf@npm:^3.7.2": version: 3.15.12 resolution: "@types/google-protobuf@npm:3.15.12"