UNPKG

wuffle

Version:

A multi-repository task board for GitHub issues

153 lines (117 loc) 2.88 kB
import { repoAndOwner, Cache } from '../../util/index.js'; /** * This component updates the stored issues based on GitHub events. * * @constructor * * @param {import('../webhook-events/WebhookEvents.js').default} webhookEvents * @param {import('../../events.js').default} events * @param {import('../github-client/GithubClient.js').default} githubClient * @param {import('../../store.js').default} store */ export default function GithubChecks(webhookEvents, events, githubClient, store) { // issues ///////////////////// // one day const CACHE_TTL = process.env.NODE_ENV === 'development' ? 1000 * 15 : 1000 * 60 * 60 * 24; const cache = new Cache(CACHE_TTL); async function fetchCheckRuns(pullRequest) { const { head, repository } = pullRequest; const { sha } = head; const runs = await cache.get(`${repository.id}/${sha}`, async () => { const { repo, owner } = repoAndOwner(pullRequest); const github = await githubClient.getOrgScoped(owner); const { data: result } = await github.rest.checks.listForRef({ owner, repo, ref: sha, filter: 'latest' }); return result.check_runs.map(filterCheckRun); }); return runs; } events.on('backgroundSync.sync', async (event) => { const { issue } = event; if (!issue.pull_request) { return; } const { id } = issue; const checkRuns = await fetchCheckRuns(issue); await store.queueUpdate({ id, check_runs: checkRuns }); }); webhookEvents.on([ 'check_run' ], async ({ payload }) => { const { check_run: _check_run, repository } = payload; const check_run = filterCheckRun(_check_run); // invalidate cached PR checks cache.remove(`${repository.id}/${check_run.head_sha}`); const issueIds = _check_run.pull_requests.map(pr => `${ pr.base.repo.id }-${pr.number}`); await store.updateIssues(issue => { if (issueIds.indexOf(issue.id) !== -1) { return { check_runs: addOrUpdate(issue.check_runs || [], check_run) }; } }); }); // periodically clear cache setInterval(() => { cache.evict(); }, 1000 * 60); } function filterCheckRun(check_suite) { const { id, node_id, conclusion, head_sha, html_url, name, status } = check_suite; return { id, node_id, conclusion, head_sha, html_url, name, status }; } function addOrUpdate(check_runs, check_run) { const index = check_runs.findIndex(run => run.name === check_run.name); return index !== -1 ? [ ...check_runs.slice(0, index), check_run, ...check_runs.slice(index + 1) ] : [ ...check_runs, check_run ]; }