Skip to content

Instantly share code, notes, and snippets.

@laughedelic
Last active April 5, 2021 02:43
Show Gist options
  • Save laughedelic/1dbc334e2987286e6e1c536f2396523e to your computer and use it in GitHub Desktop.
Save laughedelic/1dbc334e2987286e6e1c536f2396523e to your computer and use it in GitHub Desktop.

GitHub App request CLI using Deno

This is a simple script that authenticates as a GitHub App, generates an installation token and runs a GitHub API request with this token built from the CLI arguments.

You can create a simple shell-script wrapper to run it:

#!/usr/bin/env sh
deno run --allow-read --allow-net https://gist.githubusercontent.com/laughedelic/1dbc334e2987286e6e1c536f2396523e/raw/dde6222a7bf7e368000a7029cb5dd011a279bb4b/github-app-request.ts --appId=123456 --installationId=12345678 --privateKey=private-key.pem $@

save it as github-app-request.sh and make executable: chmod +x github-app-request.sh, then you can call it like this:

./github-app-request.sh GET /repos/octokit/hello-world/deployments

You can pass any extra parameters as normal command line options:

./github-app-request.sh POST /repos/octokit/hello-world/deployments --ref='master'

Use jq to extract information from the response and use it in the next request:

deployment_id=$(./github-app-request.sh POST /repos/octokit/hello-world/deployments --ref='master' | jq -r '.id')
./github-app-request.sh POST /repos/octokit/hello-world/deployments/$deployment_id/statuses \
  --environment=staging \
  --state=in_progress

This will create a deployment, save its ID to a var and then run a request to update this deployment status.

#!/usr/bin/env deno run --allow-read --allow-net
import getopts from "https://cdn.skypack.dev/getopts";
import { request } from "https://cdn.skypack.dev/@octokit/request";
import { create, getNumericDate } from "https://deno.land/x/djwt/mod.ts";
const opts = getopts(Deno.args);
const { _, appId, installationId, privateKey, ...params } = opts as any;
const endpoint = _.join(" ");
const jwt = await create(
{ alg: "RS256", typ: "JWT" },
{
iss: appId.toString(), // issuer
iat: getNumericDate(-30), // issued at time
exp: getNumericDate(60), // expiration time 1 minute
},
Deno.readTextFileSync(privateKey)
);
const installationAuth = await request(
`POST /app/installations/${installationId}/access_tokens`,
{ headers: { authorization: `bearer ${jwt}` } }
);
const { data } = await request(endpoint, {
headers: { authorization: `token ${installationAuth.data.token}` },
...params,
});
console.log(JSON.stringify(data, null, 2));
@laughedelic
Copy link
Author

laughedelic commented Apr 5, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment