googleapis / googleapis/release-please
proxy-server input is silently ignored (request.agent dropped by @octokit/request v8 native fetch)
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 588
- Avg merge
- 12h 16m
- Merged PRs (30d)
- 7
Description
Thanks for stopping by to let us know something could be better!
Please provide the following details.
#### Environment details
- OS: Linux (self-hosted CI runner, behind a corporate HTTP proxy)
- Node.js version: 24.x (also reproduces on 22.x)
- npm version: 10.x
- `release-please` version: 17.10.1 (via googleapis/release-please-action@v5), also present on earlier v17 lines
#### Steps to reproduce
1. Run release-please on a machine whose only egress to `api.github.com` is through an HTTP proxy, and set the `proxy-server` input (action) or `--proxy-server`-equivalent option (library), e.g. `proxy-server: proxy.example.com:912`.
2. Observe that requests do NOT go through the proxy. On a network where direct egress is blocked, the run fails to reach the API (in our case the org IP allow list rejects the runner's raw egress IP); on a network where direct egress is allowed, requests silently bypass the proxy entirely.
3. Set `NODE_USE_ENV_PROXY=1` together with a standard `HTTPS_PROXY` env var, and requests now go through the proxy correctly, even though `proxy-server` is unchanged. This is what makes the bug easy to miss: the env var does the work while `proxy-server` appears to be responsible.
#### What's happening (root cause)
`GitHub.create()` builds an `HttpsProxyAgent`/`HttpProxyAgent` from the `proxy` option and passes it as `request.agent` to Octokit and to the GraphQL client:
```ts
// src/github-api.ts
octokit: new Octokit({
baseUrl: apiUrl,
auth: options.token,
request: {
agent: this.createDefaultAgent(apiUrl, options.proxy), // <- dropped downstream
fetch: options.fetch,
},
}),
// ...and the same request.agent on graphql.defaults({ ... })
```
But the library depends on `@octokit/request` `^8.3.1`. In `@octokit/request` v8, the fetch-wrapper calls native `fetch` and forwards only a fixed set of options:
```js
// @octokit/request@8.4.1 dist-node/index.js (fetch-wrapper)
return fetch(requestOptions.url, {
method: requestOptions.method,
body: requestOptions.body,
headers: requestOptions.headers,
signal: requestOptions.request?.signal,
...(requestOptions.body && { duplex: "half" })
});
```
`request.agent` is not among them, so the proxy agent is silently discarded. This is consistent with the `@octokit/request` v8.0.0 breaking changes, which state: "Replace support for Node.js http(s) Agents with documentation on using fetch dispatchers instead" and "Remove ability to pass custom request options, except method, headers, body, signal, data."
Net effect: the documented `proxy-server` input (README: "Configure a proxy server in the form of `:`"; action.yml: "set proxy server when you run this action behind a proxy") is dead code. It is accepted, produces no error, and has no effect. Worse, if a user also sets `NODE_USE_ENV_PROXY=1` + `HTTPS_PROXY` (Node's own env-proxy support), proxying starts working and `proxy-server` looks like it is doing the job when it is not.
#### Suggested fix
Follow the same migration Octokit documents for v8: instead of passing `request.agent`, pass a custom `fetch` that uses an undici `ProxyAgent` as its `dispatcher`, e.g.
```ts
import { ProxyAgent } from 'undici';
const dispatcher = proxy ? new ProxyAgent(`http://${proxy.host}:${proxy.port}`) : undefined;
const proxyFetch = dispatcher
? (url, opts) => fetch(url, { ...opts, dispatcher })
: undefined;
new Octokit({ baseUrl: apiUrl, auth: token, request: { fetch: proxyFetch ?? options.fetch } });
```
(and the equivalent for the GraphQL client). That restores the `proxy-server` contract on native fetch. Alternatively, if the intent is to rely on Node's env-proxy support, the docs for `proxy-server` should say so and point at `NODE_USE_ENV_PROXY`.
I could not find an existing issue for this specific case (#1654 was a related but different graphql-proxy bug predating the octokit v8 bump; #2259 is about HTTP CONNECT tunneling). Happy to open a PR if a fix along these lines is welcome.
Thank you!
Contributor guide
Research direction
Start in src/github-api.ts, then inspect how the Octokit and GraphQL clients receive fetch and proxy options, alongside the @octokit/request v8 fetch-wrapper behavior described in the issue. The work is done when the documented proxy-server option routes both REST and GraphQL requests through the configured proxy without relying on environment proxy variables.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, node.js, typescript
- Domain
- api, backend, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100