import dotnenv from 'dotenv'; import fs from 'fs'; import ejs from 'ejs'; import remark from 'remark'; import toc from 'remark-toc'; import GithubApi from './api'; import link from './link'; import git from './git'; import * as core from '@actions/core'; const fsp = fs.promises; import type { SortedLanguageList, PaginationLink, Stars, Star, ApiGetStarResponse, } from './types'; const REPO_USERNAME = process.env.GITHUB_REPOSITORY?.split('/')[0]; const OUTPUT_FILENAME: string = core.getInput('output-filename') || 'README.md'; const USERNAME = process.env.GITHUB_ACTOR || 'simonecorsi'; const API_STARRED_URL = `'https://api.github.com/users/${REPO_USERNAME}/starred'`; const renderer = async (data: any) => { try { const MD_TEMPLATE = await fsp.readFile('fixtures/template.md.ejs', 'utf-8'); return ejs.render(MD_TEMPLATE, data); } catch (error) { core.error('#renderer'); core.error(error); return ''; } }; const wait = (time = 200) => new Promise((resolve) => setTimeout(resolve, time)); async function apiGetStar(url: string): Promise { const { headers, body }: any = await GithubApi.get(url); return { data: body, links: link.parse(headers.link).refs.reduce( (acc, val) => ({ ...acc, [val.rel]: val.uri, }), {} ), }; } function isLastPage(links: PaginationLink): boolean { return links.next === links.last; } export function generateMd(data: string): Promise { return new Promise((resolve) => { remark() .use(toc) .process(data, function (error, file) { if (error) { core.error('#generateMd'); core.error(error); return resolve(''); } return resolve(String(file)); }); }); } export async function main(): Promise { let links: PaginationLink = { next: API_STARRED_URL, last: undefined, }; let results: Stars = []; do { const r = await apiGetStar(links.next); links = r.links; results = results.concat(r.data); await wait(); } while (!isLastPage(links)); const sortedByLanguages = results.reduce( (acc: SortedLanguageList, val: Star) => { const language = val.language || 'generic'; if (!acc[language]) { acc[language] = [val]; } else { acc[language].push(val); } return acc; }, {} ); const rendered = await renderer({ username: USERNAME, stars: Object.entries(sortedByLanguages), updatedAt: Date.now(), }); const markdown: string = await generateMd(rendered); await fsp.writeFile(OUTPUT_FILENAME, markdown); await git.add(OUTPUT_FILENAME); await git.commit(`chore(${OUTPUT_FILENAME}): updated ${OUTPUT_FILENAME}`); await git.push(); } export async function run(): Promise { try { await main(); process.exit(0); } catch (error) { core.error('#catchAll:'); core.error(error); process.exit(1); } } const catchAll = (info: any) => { core.error('#catchAll'); core.error(info); process.exit(1); }; process.on('unhandledRejection', catchAll); process.on('uncaughtException', catchAll); run();