You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.3 KiB
JavaScript
145 lines
4.3 KiB
JavaScript
2 years ago
|
const debug = require("debug")("action-dashboard:webhooks");
|
||
|
const { Webhooks, createNodeMiddleware } = require("@octokit/webhooks");
|
||
|
const http = require("http");
|
||
|
|
||
|
class WebHooks {
|
||
|
constructor(
|
||
|
sitePort,
|
||
|
secret,
|
||
|
webhookPort,
|
||
|
webhookPath,
|
||
|
gitHub,
|
||
|
actions,
|
||
|
expressApp
|
||
|
) {
|
||
|
if (secret) {
|
||
|
this._secret = secret;
|
||
|
this._webhookPort = webhookPort;
|
||
|
this._sitePort = sitePort;
|
||
|
this._gitHub = gitHub;
|
||
|
this._actions = actions;
|
||
|
if (sitePort === webhookPort) {
|
||
|
this._defaultPath = "/webhook";
|
||
|
} else {
|
||
|
this._defaultPath = "/";
|
||
|
}
|
||
|
this._path = webhookPath || this._defaultPath;
|
||
|
|
||
|
// Fail in the case that the ports for the main site and webhooks
|
||
|
// are the same and the path is explicitly set to /
|
||
|
if (sitePort === webhookPort && this._path === "/") {
|
||
|
throw new Error(
|
||
|
"Path cannot be / when the webhooks are running on the same port as the main site"
|
||
|
);
|
||
|
}
|
||
|
|
||
|
this._expressApp = expressApp;
|
||
|
this._enabled = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
start() {
|
||
|
if (this._enabled) {
|
||
|
debug(
|
||
|
`Setting up webhooks port: ${this._webhookPort}, path: ${this._path}`
|
||
|
);
|
||
|
// OctoKit webhooks, not this module
|
||
|
const webhooks = new Webhooks({
|
||
|
secret: this._secret,
|
||
|
});
|
||
|
|
||
|
webhooks.onError((error) => {
|
||
|
console.dir(error);
|
||
|
// console.error(
|
||
|
// `Webhook error occured in "${error.event.name} handler: ${error.stack}"`
|
||
|
// );
|
||
|
});
|
||
|
|
||
|
const middleware = createNodeMiddleware(webhooks, { path: this._path });
|
||
|
webhooks.on("workflow_run", this.workflowRun);
|
||
|
|
||
|
if (this._sitePort !== this._webhookPort) {
|
||
|
this._server = http
|
||
|
.createServer((req, res) => {
|
||
|
debug(`received request path: ${req.url}`);
|
||
|
if (req.url === "/ping") {
|
||
|
debug("ping");
|
||
|
res.statusCode = 200;
|
||
|
res.end();
|
||
|
} else {
|
||
|
middleware(req, res);
|
||
|
}
|
||
|
})
|
||
|
.listen({ port: this._webhookPort }, () => {
|
||
|
console.log(
|
||
|
`Listening for webhooks on ${this._webhookPort} at ${this._path}`
|
||
|
);
|
||
|
});
|
||
|
} else {
|
||
|
this._expressApp.use(this._path, middleware);
|
||
|
console.log(
|
||
|
`Listening for webhooks on ${this._webhookPort} at ${this._path}`
|
||
|
);
|
||
|
}
|
||
|
} else {
|
||
|
debug("Webhooks disabled");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Mainly used by testing functions to cleanly shutdown web server
|
||
|
stop() {
|
||
|
if (this._enabled && this._server && this._server.listening) {
|
||
|
this._server.close();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
workflowRun = async ({ id, name, payload }) => {
|
||
|
try {
|
||
|
debug(`workflow_run received id: ${id}, name: ${name}`, payload);
|
||
|
let usage = null;
|
||
|
|
||
|
if (payload.workflow_run.status === "completed") {
|
||
|
debug(`getting usage for id: ${id}, name: ${name}`);
|
||
|
usage = await this._gitHub.getUsage(
|
||
|
payload.workflow_run.repository.owner.login,
|
||
|
payload.workflow_run.repository.name,
|
||
|
payload.workflow_run.workflow_id,
|
||
|
payload.workflow_run.id
|
||
|
);
|
||
|
}
|
||
|
|
||
|
debug(`merging runs for id: ${id}, name: ${name}`);
|
||
|
this._actions.mergeRuns([
|
||
|
{
|
||
|
runId: payload.workflow_run.id,
|
||
|
repo: payload.workflow_run.repository.name,
|
||
|
owner: payload.workflow_run.repository.owner.login,
|
||
|
workflowId: payload.workflow_run.workflow_id,
|
||
|
runNumber: payload.workflow_run.run_number,
|
||
|
workflow: payload.workflow_run.name,
|
||
|
branch: payload.workflow_run.head_branch,
|
||
|
sha: payload.workflow_run.head_sha,
|
||
|
message: payload.workflow_run.head_commit.message,
|
||
|
committer: payload.workflow_run.head_commit.committer.name,
|
||
|
status:
|
||
|
payload.workflow_run.status === "completed"
|
||
|
? payload.workflow_run.conclusion
|
||
|
: payload.workflow_run.status,
|
||
|
createdAt: payload.workflow_run.created_at,
|
||
|
updatedAt: payload.workflow_run.updated_at,
|
||
|
durationMs: usage?.run_duration_ms,
|
||
|
},
|
||
|
]);
|
||
|
debug(`runs merged for id: ${id}, name: ${name}`);
|
||
|
} catch (e) {
|
||
|
console.dir(e);
|
||
|
console.error(
|
||
|
`Error processing workflow_run received id: ${id}, name: ${name}`,
|
||
|
payload
|
||
|
);
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
module.exports = WebHooks;
|