Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/proxy-fetch-undici-version-mismatch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@slack/slack-github-action": patch
---

fix: proxy input always fails due to an undici version mismatch
9 changes: 6 additions & 3 deletions src/proxies.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { ProxyAgent } from "undici";
import { ProxyAgent, fetch as undiciFetch } from "undici";
import SlackError from "./errors.js";

/**
* Return a fetch function that routes requests through a configured proxy.
*
* Uses undici's own fetch, not the global fetch, since Node may bundle a
* different (incompatible) undici version for the latter.
*
* @param {import("./config.js").default} config
* @param {string?} [destination] - A provided request destination.
* @returns {typeof globalThis.fetch | undefined}
* @returns {typeof undiciFetch | undefined}
*/
export function fetch(config, destination) {
const dispatcher = proxies(config, destination);
if (!dispatcher) {
return undefined;
}
return (url, init) => globalThis.fetch(url, { ...init, dispatcher });
return (url, init) => undiciFetch(url, { ...init, dispatcher });
}

/**
Expand Down
19 changes: 19 additions & 0 deletions test/proxies.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import assert from "node:assert";
import { beforeEach, describe, it } from "node:test";
import { errors as undiciErrors } from "undici";
import Config from "../src/config.js";
import SlackError from "../src/errors.js";
import { fetch, proxies } from "../src/proxies.js";
Expand All @@ -20,6 +21,24 @@ describe("proxies", () => {
assert.strictEqual(typeof fetchFn, "function");
});

it("dispatches requests through the proxy without a request handler mismatch", async () => {
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
mocks.core.getInput.withArgs("token").returns("xoxb-example");
mocks.core.getInput.withArgs("proxy").returns("http://127.0.0.1:1");
const config = new Config(mocks.core);
const fetchFn = fetch(config);
await assert.rejects(
// ".invalid" is reserved by RFC 2606 to never resolve.
fetchFn("https://slack-github-action.invalid/api/chat.postMessage", {
method: "POST",
}),
(err) => {
assert.ok(!(err.cause instanceof undiciErrors.InvalidArgumentError));
return true;
},
);
});

it("returns undefined when no proxy is configured", async () => {
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
mocks.core.getInput.withArgs("token").returns("xoxb-example");
Expand Down
Loading