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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# GitHub Toolkit

A [GitHub App](https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps) that could do a variety of things, but currently adds all new issues created in the GitHub organization to some specific project.
A [GitHub App](https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps) that could do a variety of things, but currently adds all new issues and pull requests created in the GitHub organization to some specific project.
99 changes: 56 additions & 43 deletions src/webhook-endpoint/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,65 @@ import { App } from "octokit";

const OK_RESPONSE = { statusCode: 200 };

async function handleIssue(payload) {
console.log(JSON.stringify(payload));
if (payload.action === "opened" && payload.issue.state === "open") {
const app = new App({
appId: 311508,
// If the envar is added directly to the Lambda function it will
// probably look like:
// -----BEGIN RSA PRIVATE KEY-----\nMIIEo…
// with the newlines replaced with literal "\n".
// Those will be replaced with real newlines below.
// If the envar is added via CloudFormation or AWS SAM, it will
// maintain actual newlines and the `replace` will be a no-op.
// When generating a private key for a GitHub app, it will download a
// .pem file. The contents of that file is the private key.
privateKey: process.env.GITHUB_APP_PRIVATE_KEY.replace(/\\n/g, "\n"),
});
async function addToProject(installationId, contentId) {
const app = new App({
appId: 311508,
// If the envar is added directly to the Lambda function it will
// probably look like:
// -----BEGIN RSA PRIVATE KEY-----\nMIIEo…
// with the newlines replaced with literal "\n".
// Those will be replaced with real newlines below.
// If the envar is added via CloudFormation or AWS SAM, it will
// maintain actual newlines and the `replace` will be a no-op.
// When generating a private key for a GitHub app, it will download a
// .pem file. The contents of that file is the private key.
privateKey: process.env.GITHUB_APP_PRIVATE_KEY.replace(/\\n/g, "\n"),
});

const octokit = await app.getInstallationOctokit(payload.installation.id);
const octokit = await app.getInstallationOctokit(installationId);

const projectOwnerName = "PRX";
const projectNumber = 3;
const ownerType = "organization";
const projectOwnerName = "PRX";
const projectNumber = 3;
const ownerType = "organization";

const idResp = await octokit.graphql(
`query getProject($projectOwnerName: String!, $projectNumber: Int!) {
${ownerType}(login: $projectOwnerName) {
projectV2(number: $projectNumber) {
id
}
const idResp = await octokit.graphql(
`query getProject($projectOwnerName: String!, $projectNumber: Int!) {
${ownerType}(login: $projectOwnerName) {
projectV2(number: $projectNumber) {
id
}
}`,
{
projectOwnerName,
projectNumber,
},
);
}
}`,
{
projectOwnerName,
projectNumber,
},
);

const projectId = idResp[ownerType]?.projectV2.id;
const contentId = payload.issue.node_id;
const projectId = idResp[ownerType]?.projectV2.id;

await octokit.graphql(
`mutation addIssueToProject {
addProjectV2ItemById(
input: {projectId: "${projectId}", contentId: "${contentId}"}
) {
clientMutationId
}
}`,
);
await octokit.graphql(
`mutation addItemToProject {
addProjectV2ItemById(
input: {projectId: "${projectId}", contentId: "${contentId}"}
) {
clientMutationId
}
}`,
);
}

async function handleIssue(payload) {
console.log(JSON.stringify(payload));
if (payload.action === "opened" && payload.issue.state === "open") {
await addToProject(payload.installation.id, payload.issue.node_id);
}
}

async function handlePullRequest(payload) {
console.log(JSON.stringify(payload));
if (payload.action === "opened" && payload.pull_request.state === "open") {
await addToProject(payload.installation.id, payload.pull_request.node_id);
}
}

Expand All @@ -78,6 +88,9 @@ export const handler = async (event) => {
case "issues":
await handleIssue(JSON.parse(body));
break;
case "pull_request":
await handlePullRequest(JSON.parse(body));
break;
default:
break;
}
Expand Down
3 changes: 2 additions & 1 deletion template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ Resources:
Architectures: [arm64]
CodeUri: src/webhook-endpoint
Description: >-
Receives GitHub webhooks for issues and performs some actions
Receives GitHub webhooks for issues and pull requests and performs
some actions
Environment:
Variables:
GITHUB_WEBHOOK_SECRET: !Ref GitHubWebhookSecret
Expand Down