-
Notifications
You must be signed in to change notification settings - Fork 142
Description
Current behavior
When running @semantic-release/github
against a GitHub Enterprise Server behind our corporate proxy, the plugin cannot establish a connection.
The current implementation (branch: master
) uses HttpProxyAgent
/HttpsProxyAgent
with an agent
option passed to Octokit
's request
. Example from the codebase:
// https://github.com/semantic-release/github/blob/master/lib/octokit.js#L64-L77
const agent = options.proxy
? baseUrl && new URL(baseUrl).protocol.replace(":", "") === "http"
? new HttpProxyAgent(options.proxy, options.proxy)
: new HttpsProxyAgent(options.proxy, options.proxy)
: undefined;
return {
...(baseUrl ? { baseUrl } : {}),
auth: options.githubToken,
request: {
agent,
},
};
However, since Octokit
now relies on undici
as its fetch implementation, the agent
option is no longer respected. Instead, undici
expects a dispatcher
to be passed into fetch
.
Expected behavior
According to the @octokit/core
unit tests, proxy support requires ProxyAgent
from undici@6+
to be injected into fetch
like so:
import { fetch as undiciFetch, ProxyAgent } from "undici";
const myFetch = (url, opts) => {
return undiciFetch(url, {
...opts,
dispatcher: new ProxyAgent({
uri: proxyUrl,
keepAliveTimeout: 10,
keepAliveMaxTimeout: 10,
}),
});
};
const octokit = new Octokit({
baseUrl: serverUrl,
request: { fetch: myFetch },
});
This means, @semantic-release/github
should provide a patched fetch
with the appropriate dispatcher
instead of configuring agent
.
semantic-release
version
22, 23, 24
CI environment
GitHub Enterprise Server
Plugins used
@semantic-release/commit-analyzer
@semantic-release/release-notes-generator
@semantic-release/changelog
@semantic-release/exec
@semantic-release/npm
@semantic-release/github
@semantic-release/git
semantic-release
configuration
{
"branches": [
"+([0-9])?(.{+([0-9]),x}).x",
"main",
"next",
{ "name": "beta", "prerelease": true },
{ "name": "alpha", "prerelease": true }
],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
}
],
[
"@semantic-release/exec",
{
"prepareCmd": "cp CHANGELOG.md dist/my-repo/CHANGELOG.md"
}
],
[
"@semantic-release/npm",
{
"pkgRoot": "dist/my-repo",
"tarballDir": "dist"
}
],
[
"@semantic-release/github",
{
"assets": [
"dist/*.tgz"
]
}
],
[
"@semantic-release/git",
{
"assets": [
"CHANGELOG.md",
],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
}
CI logs
[6:37:12 AM] [semantic-release] › ℹ Start step "publish" of plugin "@semantic-release/github"
2025-09-16T06:37:12.586Z semantic-release:github release object: {
owner: 'my-org',
repo: 'my-repo',
tag_name: 'v3.0.0-beta.1',
target_commitish: 'beta',
name: 'v3.0.0-beta.1',
body: '[REDACTED]',
prerelease: true
}
NET 907: emit close
TLS 907: client _init handle? true
NET 907: pipe false undefined
NET 907: connect: find host github.redacted-hostname.com
NET 907: connect: dns options { family: undefined, hints: 32 }
NET 907: connect: autodetecting
TLS 907: client initRead handle? true buffered? false
NET 907: _read - n 16384 isConnecting? true hasHandle? true
NET 907: _read wait for connection
NET 907: connect/multiple: only one address found, switching back to single connection
NET 907: connect: attempting to connect to 4.x.x.x:443 (addressType: 4)
NET 907: destroy
NET 907: close
NET 907: close handle
[6:38:08 AM] [semantic-release] › ✘ Failed step "publish" of plugin "@semantic-release/github"
[6:38:08 AM] [semantic-release] › ✘ An error occurred while running semantic-release: RequestError [HttpError]: Connect Timeout Error (attempted address: github.redacted-hostname.com:443, timeout: 10000ms)
at /home/runner/_work/my-repo/my-repo/node_modules/@octokit/request/dist-node/index.js:157:11
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async requestWithGraphqlErrorHandling (/home/runner/_work/feedback-nudge/feedback-nudge/node_modules/@octokit/plugin-retry/dist-node/index.js:71:20)
at async Job.doExecute (/home/runner/_work/feedback-nudge/feedback-nudge/node_modules/bottleneck/light.js:405:18) {
status: 500,
request: {
method: 'POST',
url: 'https://github.redacted-hostname.com/api/v3/repos/my-org/my-repo/releases',
headers: {
accept: 'application/vnd.github.v3+json',
'user-agent': '@semantic-release/github v9.2.6 octokit-core.js/5.2.0 Node.js/20.19.5 (linux; x64)',
authorization: 'token [REDACTED]',
'content-type': 'application/json; charset=utf-8'
},
body: '{"tag_name":"v3.0.0-beta.1","target_commitish":"beta","name":"v3.0.0-beta.1","body":"...","prerelease":true,"draft":true}',
request: {
agent: [HttpsProxyAgent],
hook: [Function: bound bound register],
retryCount: 3,
retries: 3,
retryAfter: 16
}
},
pluginName: '@semantic-release/github'
}