Skip to content

Commit

Permalink
feat: set x-github-delivery header to event.id for all requests s…
Browse files Browse the repository at this point in the history
…ent from `context.octokit` in event handlers (#2026)
  • Loading branch information
gr2m committed Jun 3, 2024
1 parent 117b42e commit f1985e5
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 8 deletions.
10 changes: 10 additions & 0 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ export class Context<E extends WebhookEvents = WebhookEvents> {

this.octokit = octokit;
this.log = aliasLog(log);

// set `x-github-delivery` header on all requests sent in response to the current
// event. This allows GitHub Support to correlate the request with the event.
// This is not documented and not considered public API, the header may change.
// Once we document this as best practice on https://docs.github.com/en/rest/guides/best-practices-for-integrators
// we will make it official
/* istanbul ignore next */
octokit.hook.before("request", (options) => {
options.headers["x-github-delivery"] = event.id;
});
}

/**
Expand Down
69 changes: 61 additions & 8 deletions test/context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ describe("Context", () => {
name: "push",
payload: pushEventPayload,
};
let octokit = {
hook: {
before: jest.fn(),
},
};
let context: Context<"push"> = new Context<"push">(
event,
{} as any,
octokit as any,
{} as any
);

Expand All @@ -51,7 +56,12 @@ describe("Context", () => {
payload: pushEventPayload,
};

context = new Context<"push">(event, {} as any, {} as any);
let octokit = {
hook: {
before: jest.fn(),
},
};
context = new Context<"push">(event, octokit as any, {} as any);
});

it("returns attributes from repository payload", () => {
Expand Down Expand Up @@ -82,7 +92,12 @@ describe("Context", () => {
it("properly handles the push event", () => {
event.payload = require("./fixtures/webhook/push") as PushEvent;

context = new Context<"push">(event, {} as any, {} as any);
let octokit = {
hook: {
before: jest.fn(),
},
};
context = new Context<"push">(event, octokit as any, {} as any);
expect(context.repo()).toEqual({ owner: "bkeepers-inc", repo: "test" });
});

Expand All @@ -93,7 +108,12 @@ describe("Context", () => {
payload: { ...pushEventPayload, repository: undefined as any },
};

context = new Context<"push">(event, {} as any, {} as any);
let octokit = {
hook: {
before: jest.fn(),
},
};
context = new Context<"push">(event, octokit as any, {} as any);
try {
context.repo();
} catch (e: any) {
Expand All @@ -114,7 +134,12 @@ describe("Context", () => {
payload: issuesEventPayload,
};

context = new Context<"issues">(event, {} as any, {} as any);
let octokit = {
hook: {
before: jest.fn(),
},
};
context = new Context<"issues">(event, octokit as any, {} as any);
});
it("returns attributes from repository payload", () => {
expect(context.issue()).toEqual({
Expand Down Expand Up @@ -153,7 +178,12 @@ describe("Context", () => {
payload: pullRequestEventPayload,
};

context = new Context<"pull_request">(event, {} as any, {} as any);
let octokit = {
hook: {
before: jest.fn(),
},
};
context = new Context<"pull_request">(event, octokit as any, {} as any);
});
it("returns attributes from repository payload", () => {
expect(context.pullRequest()).toEqual({
Expand Down Expand Up @@ -246,19 +276,42 @@ describe("Context", () => {
expect(customMerge).toHaveBeenCalled();
expect(mock.activeMocks()).toStrictEqual([]);
});

it("sets x-github-delivery header to event id", async () => {
const mock = nock("https://api.github.com", {
reqheaders: {
"x-github-delivery": event.id,
},
})
.get("/repos/Codertocat/Hello-World/contents/.github%2Ftest-file.yml")
.reply(200, nockConfigResponseDataFile("basic.yml"));

await context.config("test-file.yml");
expect(mock.activeMocks()).toStrictEqual([]);
});
});

describe("isBot", () => {
test("returns true if sender is a bot", () => {
event.payload.sender.type = "Bot";
context = new Context(event, {} as any, {} as any);
let octokit = {
hook: {
before: jest.fn(),
},
};
context = new Context(event, octokit as any, {} as any);

expect(context.isBot).toBe(true);
});

test("returns false if sender is not a bot", () => {
event.payload.sender.type = "User";
context = new Context(event, {} as any, {} as any);
let octokit = {
hook: {
before: jest.fn(),
},
};
context = new Context(event, octokit as any, {} as any);

expect(context.isBot).toBe(false);
});
Expand Down

0 comments on commit f1985e5

Please sign in to comment.