From 7a2c6462a2780db5b6e17dc1a9a54b4cedc96774 Mon Sep 17 00:00:00 2001
From: linguist <22963968+lowlighter@users.noreply.github.com>
Date: Mon, 28 Dec 2020 21:55:06 +0100
Subject: [PATCH] Fix workflow
---
.github/workflows/workflow.yml | 32 ++++++++++++++++----------------
action.yml | 2 +-
action/dist/index.js | 2 +-
src/plugins/topics/index.mjs | 4 +++-
utils/build.mjs | 2 +-
5 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index e4ce1d35..08598a56 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -57,7 +57,7 @@ jobs:
template: ${{ matrix.template }}
base: header, activity, community, repositories, metadata
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
- name: ${{ matrix.template }} > Plugin > PageSpeed
uses: lowlighter/metrics@master
@@ -68,7 +68,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_pagespeed: yes
plugin_pagespeed_token: ${{ secrets.PAGESPEED_TOKEN }}
plugin_pagespeed_detailed: yes
@@ -83,7 +83,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_music: yes
plugin_music_playlist: ${{ secrets.MUSIC_PLAYLIST_APPLE }}
@@ -96,7 +96,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_music: yes
plugin_music_playlist: ${{ secrets.MUSIC_PLAYLIST_SPOTIFY }}
@@ -109,7 +109,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_music: yes
plugin_music_provider: spotify
plugin_music_token: ${{ secrets.SPOTIFY_TOKENS }}
@@ -123,7 +123,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_posts: yes
plugin_posts_source: dev.to
@@ -136,7 +136,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_isocalendar: yes
plugin_isocalendar_duration: full-year
@@ -149,7 +149,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_habits: yes
plugin_habits_from: 5
plugin_habits_charts: yes
@@ -163,7 +163,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_languages: yes
- name: ${{ matrix.template }} > Plugin > Follow-up
@@ -175,7 +175,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_followup: yes
- name: ${{ matrix.template }} > Plugin > Lines and Traffic
@@ -187,7 +187,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_lines: yes
plugin_traffic: yes
@@ -200,7 +200,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_gists: yes
- name: ${{ matrix.template }} > Plugin > Topics (starred)
@@ -212,7 +212,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_topics: yes
plugin_topics_mode: starred
plugin_topics_sort: random
@@ -226,7 +226,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_topics: yes
plugin_topics_mode: mastered
plugin_topics_sort: stars
@@ -240,7 +240,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_projects: yes
plugin_projects_repositories: lowlighter/metrics/projects/1
plugin_projects_limit: 2
@@ -254,7 +254,7 @@ jobs:
template: ${{ matrix.template }}
base: ""
plugins_errors_fatal: yes
- q: {"repo":"metrics"}
+ q: '{"repo":"metrics"}'
plugin_tweets: yes
plugin_tweets_limit: 2
plugin_tweets_token: ${{ secrets.TWITTER_TOKEN }}
diff --git a/action.yml b/action.yml
index df485ecc..68d9d178 100644
--- a/action.yml
+++ b/action.yml
@@ -278,7 +278,7 @@ inputs:
# If more topics must be displayed, they will be grouped in an ellipsis
plugin_topics_limit:
description: Number of starred topics to display
- default: 0
+ default: ""
# Projects plugin
# Display active projects
diff --git a/action/dist/index.js b/action/dist/index.js
index 4961213a..2443ce65 100644
--- a/action/dist/index.js
+++ b/action/dist/index.js
@@ -11,7 +11,7 @@ module.exports=(()=>{var _Mathhypot=Math.hypot,_Mathacos=Math.acos,_Mathtan=Math
- `,i++}S+=``,b++}return S+=``,{streak:g,max:m,average:f,svg:S,duration:o}}catch(e){throw{error:{message:"An error occured",instance:e}}}},languages:async function({login:e,data:t,q:r},{enabled:n=!1}={}){try{if(!n||!r.languages)return null;let{"languages.ignored":a="","languages.skipped":o=""}=r;a=decodeURIComponent(a).split(",").map(e=>e.trim().toLocaleLowerCase()).filter(e=>e),o=decodeURIComponent(o).split(",").map(e=>e.trim().toLocaleLowerCase()).filter(e=>e),console.debug(`metrics/compute/${e}/plugins > languages > processing ${t.user.repositories.nodes.length} repositories`);const s={colors:{},total:0,stats:{}};for(const r of t.user.repositories.nodes){if(o.includes(r.name.toLocaleLowerCase())){console.debug(`metrics/compute/${e}/plugins > languages > skipped repository ${r.name}`);continue}for(const{size:t,node:{color:n,name:o}}of Object.values(r.languages.edges)){if(a.includes(o.toLocaleLowerCase())){console.debug(`metrics/compute/${e}/plugins > languages > ignored language ${o}`);continue}s.stats[o]=(s.stats[o]??0)+t,s.colors[o]=n??"#ededed",s.total+=t}}console.debug(`metrics/compute/${e}/plugins > languages > computing stats`),Object.keys(s.stats).map(e=>s.stats[e]/=s.total),s.favorites=Object.entries(s.stats).sort(([e,t],[r,n])=>n-t).slice(0,8).map(([e,t])=>({name:e,value:t,color:s.colors[e],x:0}));for(let e=1;ee)??[];console.debug(`metrics/compute/${e}/plugins > lines > querying api`);const s={added:0,deleted:0},l=await Promise.all(i.map(async t=>await n.repos.getContributorsStats({owner:e,repo:t})));return console.debug(`metrics/compute/${e}/plugins > lines > computing total diff`),l.map(({data:t})=>{if(Array.isArray(t)){const[r]=t.filter(({author:t})=>t.login===e);r&&r.weeks.forEach(({a:e,d:t})=>(s.added+=e,s.deleted+=t))}}),s.added=r.format(s.added),s.deleted=r.format(s.deleted),s}catch(e){throw{error:{message:"An error occured",instance:e}}}},music:a,pagespeed:async function({login:e,imports:t,data:r,q:n},{enabled:a=!1,token:o=null}={}){try{if(!a||!n.pagespeed||!r.user.websiteUrl)return null;let{"pagespeed.detailed":i=!1,"pagespeed.screenshot":s=!1}=n;i=!!i;let l=r.user.websiteUrl;/^https?:[/][/]/.test(l)||(l=`https://${l}`);const d={url:l,detailed:i,scores:[],metrics:{}};console.debug(`metrics/compute/${e}/plugins > pagespeed > querying api for ${l}`);const p=new Map;if(await Promise.all(["performance","accessibility","best-practices","seo"].map(async r=>{console.debug(`metrics/compute/${e}/plugins > pagespeed > performing audit ${r}`);const n=await t.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?category=${r}&url=${l}&key=${o}`);console.debug(n.data);const{score:a,title:i}=n.data.lighthouseResult.categories[r];p.set(r,{score:a,title:i}),console.debug(`metrics/compute/${e}/plugins > pagespeed > performed audit ${r} (status code ${n.status})`),s&&"performance"===r&&(d.screenshot=n.data.lighthouseResult.audits["final-screenshot"].details.data,console.debug(`metrics/compute/${e}/plugins > pagespeed > performed audit ${r} (status code ${n.status})`))})),d.scores=[p.get("performance"),p.get("accessibility"),p.get("best-practices"),p.get("seo")],i){console.debug(`metrics/compute/${e}/plugins > pagespeed > performing detailed audit`);const r=await t.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?&url=${l}&key=${o}`);console.debug(r.data),Object.assign(d.metrics,...r.data.lighthouseResult.audits.metrics.details.items),console.debug(`metrics/compute/${e}/plugins > pagespeed > performed detailed audit (status code ${r.status})`)}return d}catch(e){let t="An error occured";if(e.isAxiosError){const r=e.response?.status,n=e.response?.data?.error?.message?.match(/Lighthouse returned error: (?[A-Z_]+)/)?.groups?.description??null;t=`API returned ${r}${n?` (${n})`:""}`,e=e.response?.data??null}throw{error:{message:t,instance:e}}}},posts:async function({imports:e,data:t,q:r},{enabled:n=!1}={}){try{if(!n||!r.posts)return null;const a=t.user.login;let{"posts.source":o="","posts.limit":i=4}=r;i=_Mathmax(1,_Mathmin(30,+i)),console.debug(`metrics/compute/${a}/plugins > posts > processing with source ${o}`);let s=null;switch(o){case"dev.to":{console.debug(`metrics/compute/${a}/plugins > posts > querying api`),s=(await e.axios.get(`https://dev.to/api/articles?username=${a}&state=fresh`)).data.map(({title:e,readable_publish_date:t})=>({title:e,date:t}));break}default:throw{error:{message:`Unsupported source "${o}"`}};}if(Array.isArray(s))return 0 posts > keeping only ${i} posts`),s.splice(i)),{source:o,list:s};throw{error:{message:`An error occured (could not retrieve posts)`}}}catch(e){throw{error:{message:"An error occured",instance:e}}}},projects:async function({login:e,graphql:t,q:r,queries:n},{enabled:a=!1}={}){try{if(!a||!r.projects)return null;let{"projects.limit":o=4,"projects.repositories":i=""}=r;i=i?.split(",").map(e=>e.trim()).filter(e=>/[-\w]+[/][-\w]+[/]projects[/]\d+/.test(e))??[],o=_Mathmax(i.length,_Mathmin(100,+o)),console.debug(`metrics/compute/${e}/plugins > projects > querying api`);const{user:{projects:s}}=await t(n.projects({login:e,limit:o}));for(const r of i){console.debug(`metrics/compute/${e}/plugins > projects > querying api for ${r}`);const{user:a,repository:o,id:i}=r.match(/(?[-\w]+)[/](?[-\w]+)[/]projects[/](?\d+)/)?.groups,{user:{repository:{project:l}}}=await t(n["projects.repository"]({user:a,repository:o,id:i}));console.debug(`metrics/compute/${e}/plugins > projects > registering ${r}`),l.name=`${l.name} (${a}/${o})`,s.nodes.unshift(l),s.totalCount++}console.debug(`metrics/compute/${e}/plugins > projects > processing ${s.nodes.length} projects`);const l=[];for(const e of s.nodes){const t=(Date.now()-new Date(e.updatedAt).getTime())/86400000;let r=1>t?"less than 1 day ago":30>t?`${_Mathfloor(t)} day${2<=t?"s":""} ago`:new Date(e.updatedAt).toDateString().substring(4);const{enabled:n,todoCount:a,inProgressCount:o,doneCount:i}=e.progress;l.push({name:e.name,updated:r,progress:{enabled:n,todo:a,doing:o,done:i,total:a+o+i}})}return console.debug(`metrics/compute/${e}/plugins > projects > keeping only ${o} projects`),l.splice(o),{list:l,totalCount:s.totalCount}}catch(e){let t="An error occured";throw e.errors?.map(({type:e})=>e)?.includes("INSUFFICIENT_SCOPES")&&(t="Insufficient token rights"),{error:{message:t,instance:e}}}},topics:async function({login:e,imports:t,q:r},{enabled:n=!1}={}){try{if(!n||!r.topics)return null;let{"topics.sort":a="stars","topics.mode":o="starred","topics.limit":i="mastered"===o?0:15}=r;const s="random"===a;a={starred:"created",activity:"updated",stars:"stars",random:"created"}[a]??"starred",i=_Mathmax(0,_Mathmin(20,+i)),o=["starred","mastered"].includes(o)?o:"starred",console.debug(`metrics/compute/${e}/plugins > topics > searching starred topics`);let l=[];console.debug(`metrics/compute/${e}/plugins > topics > starting browser`);const d=await t.puppeteer.launch({headless:!0,executablePath:process.env.PUPPETEER_BROWSER_PATH,args:["--no-sandbox","--disable-extensions","--disable-setuid-sandbox","--disable-dev-shm-usage"]});console.debug(`metrics/compute/${e}/plugins > topics > started ${await d.version()}`);const p=await d.newPage();for(let t=1;100>=t;t++){console.debug(`metrics/compute/${e}/plugins > topics > loading page ${t}`),await p.goto(`https://github.com/stars/${e}/topics?direction=desc&page=${t}&sort=${a}`);const r=p.mainFrame();await Promise.race([r.waitForSelector("ul.repo-list"),r.waitForSelector(".blankslate")]);const n=await r.evaluate(()=>[...document.querySelectorAll("ul.repo-list li")].map(e=>({name:e.querySelector(".f3").innerText,description:e.querySelector(".f5").innerText,icon:e.querySelector("img")?.src??null})));if(console.debug(`metrics/compute/${e}/plugins > topics > extracted ${n.length} starred topics`),!n.length){console.debug(`metrics/compute/${e}/plugins > topics > no more page to load`);break}l.push(...n)}if(console.debug(`metrics/compute/${e}/plugins > music > closing browser`),await d.close(),s&&(console.debug(`metrics/compute/${e}/plugins > topics > shuffling topics`),l=t.shuffle(l)),"starred"===o&&0 topics > keeping only ${i} topics`);const t=l.splice(i);l.push({name:`And ${t.length} more...`,description:t.map(({name:e})=>e).join(", "),icon:null})}console.debug(`metrics/compute/${e}/plugins > topics > loading artworks`);for(const r of l)r.icon&&(console.debug(`metrics/compute/${e}/plugins > topics > processing ${r.name}`),r.icon=await t.imgb64(r.icon)),r.description=t.htmlescape(r.description);return"mastered"===o&&(console.debug(`metrics/compute/${e}/plugins > topics > filtering topics with icon`),l=l.filter(({icon:e})=>e)),"mastered"===o&&0 topics > keeping only ${i} topics`),l.splice(i)),{mode:o,list:l}}catch(e){throw{error:{message:"An error occured",instance:e}}}},traffic:async function({login:e,imports:t,data:r,rest:n,q:a},{enabled:o=!1}={}){try{if(!o||!a.traffic)return null;const i=r.user.repositories.nodes.map(({name:e})=>e)??[];console.debug(`metrics/compute/${e}/plugins > traffic > querying api`);const s={count:0,uniques:0},l=await Promise.all(i.map(async t=>await n.repos.getViews({owner:e,repo:t})));return console.debug(`metrics/compute/${e}/plugins > traffic > computing stats`),l.filter(({data:e})=>e).map(({data:{count:e,uniques:t}})=>(s.count+=e,s.uniques+=t)),s.count=t.format(s.count),s.uniques=t.format(s.uniques),{views:s}}catch(e){let t="An error occured";throw 403===e.status&&(t="Insufficient token rights"),{error:{message:t,instance:e}}}},tweets:async function({login:e,imports:t,data:r,q:n},{enabled:a=!1,token:o=null}={}){try{if(!a||!n.tweets)return null;let{"tweets.limit":i=2}=n;i=_Mathmax(1,_Mathmin(10,+i));const s=r.user.twitterUsername;console.debug(`metrics/compute/${e}/plugins > tweets > loading twitter profile (@${s})`);const{data:{data:l=null}}=await t.axios.get(`https://api.twitter.com/2/users/by/username/${s}?user.fields=profile_image_url,verified`,{headers:{Authorization:`Bearer ${o}`}});console.debug(`metrics/compute/${e}/plugins > tweets > querying api`);const{data:{data:d=[]}}=await t.axios.get(`https://api.twitter.com/2/tweets/search/recent?query=from:${s}&tweet.fields=created_at&expansions=entities.mentions.username`,{headers:{Authorization:`Bearer ${o}`}});return l?.profile_image_url&&(console.debug(`metrics/compute/${e}/plugins > tweets > loading profile image`),l.profile_image=await t.imgb64(l.profile_image_url)),0 tweets > keeping only ${i} tweets`),d.splice(i)),await Promise.all(d.map(async r=>{r.mentions=r.entities?.mentions.map(({username:e})=>e)??[],console.debug(`metrics/compute/${e}/plugins > tweets > formatting tweet ${r.id}`),r.text=t.htmlescape(t.htmlescape(r.text,{"<":!0,">":!0}).replace(new RegExp(`@(${r.mentions.join("|")})`,"gi"),` @$1 `).replace(/(?#$1 `).replace(/\n/g,"
").replace(/https?:[/][/](t.co[/]\w+)/g,` $1 `),{"&":!0})})),{username:s,profile:l,list:d}}catch(e){let t="An error occured";if(e.isAxiosError){const r=e.response?.status,n=e.response?.data?.errors?.[0]?.message??null;t=`API returned ${r}${n?` (${n})`:""}`,e=e.response?.data??null}throw{error:{message:t,instance:e}}}}},E={classic:async function({login:e,q:t},{conf:r,data:n,rest:a,graphql:i,plugins:l,queries:d},{s:p,pending:s,imports:c}){await o(...arguments)},repository:async function({login:e,q:t},{conf:r,data:n,rest:a,graphql:i,plugins:l,queries:d},{s:p,pending:s,imports:c}){const{repo:u}=t;if(!u)return console.debug(`metrics/compute/${e}/${u} > error, repo was undefined`),n.errors.push({error:{message:`You must pass a "repo" argument to use this template`}}),await o(...arguments);console.debug(`metrics/compute/${e}/${u} > retrieving single repository ${u}`);const{user:{repository:m}}=await i(d.repository({login:e,repo:u}));n.user.repositories.nodes=[m],console.debug(`metrics/compute/${e}/${u} > querying api for commits`);const g=[];for(let o=0;1>o;o++){console.debug(`metrics/compute/${e}/${u} > loading page ${o}`);const{data:t}=await a.repos.listCommits({owner:e,repo:u,per_page:100,page:o});if(!t.length){console.debug(`metrics/compute/${e}/${u} > no more page to load`);break}g.push(...t)}console.debug(`metrics/compute/${e}/${u} > ${g.length} commits loaded`),n.user.createdAt=m.createdAt,n.user.repositories.totalDiskUsage=m.diskUsage;const h=new Date;h.setHours(0,0,0,0);const f=g.map(({commit:e})=>_Mathabs(_Mathceil((h-new Date(e.committer.date))/86400000))).slice(0,14),y=Array(14).fill(0);for(const o of f)y[o]++;const b=_Mathmax(...y);n.user.calendar.contributionCalendar.weeks=y.map(e=>({contributionDays:{color:e?`var(--color-calendar-graph-day-L${_Mathceil(e/b/.25)}-bg)`:"var(--color-calendar-graph-day-bg)"}})),t["projects.limit"]=0,await o(...arguments),await Promise.all(s),n.plugins.projects&&n.plugins.projects.list?.map(t=>t.name=t.name.replace(`(${e}/${u})`,"").trim())},terminal:async function({login:e,q:t},{conf:r,data:n,rest:a,graphql:i,plugins:l,queries:d},{s:p,pending:s,imports:c}){await o(...arguments),t.raw=!0}};var A=r(34651),O=r(78835),P=r(63129);const L=require("fs/promises");var z=r(12087),R=r(3584),I=r.t(R),M=r(32882),W=r.t(M),q=r(29483),B=r.t(q);(async function(){const[e,t,n,a,o]=[W,B,I,h,f].map(e=>e&&e.default?e.default:e),i=(e,t=!1)=>"string"==typeof e?/^(?:[Tt]rue|[Oo]n|[Yy]es)$/.test(e):t,s=[];try{console.log(`GitHub metrics`),console.log(`========================================================`),console.log(`Version | 2.10.0-beta`),process.on("unhandledRejection",e=>{throw e}),"push"===t.context.eventName&&t.context.payload&&t.context.payload.head_commit&&/\[Skip GitHub Action\]/.test(t.context.payload.head_commit.message)&&(console.log(`Skipped because [Skip GitHub Action] is in commit message`),process.exit(0));const l=await a({log:!1});console.log(`Configuration | loaded`);const d=e.getInput("template")||"classic";console.log(`Template to use | ${d}`);const p=e.getInput("token")||"";if(console.log(`Github token | ${p?"provided":"missing"}`),!p)throw new Error("You must provide a valid GitHub token to gather your metrics");const c=n.graphql.defaults({headers:{authorization:`token ${p}`}});console.log(`Github GraphQL API | ok`);const u=t.getOctokit(p);console.log(`Github REST API | ok`);const m=e.getInput("filename")||"github-metrics.svg";console.log(`SVG output file | ${m}`);const g=i(e.getInput("optimize"),!0);l.optimize=g,console.log(`SVG optimization | ${g}`);let h;try{h=(await u.users.getAuthenticated()).data.login}catch{h=t.context.repo.owner}const f=e.getInput("user")||h;console.log(`GitHub user | ${f}`);const y=i(e.getInput("debug"));y||(console.debug=e=>s.push(e)),console.log(`Debug mode | ${y}`);const b=(e.getInput("debug_flags")||"").split(" ").filter(e=>e);console.log(`Debug flags | ${b.join(" ")||"(none)"}`);const S={};let x=(e.getInput("base")||"").split(",").map(e=>e.trim());for(const e of l.settings.plugins.base.parts)S[`base.${e}`]=x.includes(e);console.log(`Base parts | ${x.join(", ")||"(none)"}`);const v={"config.timezone":e.getInput("config_timezone")||""};console.log(`Timezone | ${v["config.timezone"]||"(system default)"}`);const k={lines:{enabled:i(e.getInput("plugin_lines"))},traffic:{enabled:i(e.getInput("plugin_traffic"))},pagespeed:{enabled:i(e.getInput("plugin_pagespeed"))},habits:{enabled:i(e.getInput("plugin_habits"))},languages:{enabled:i(e.getInput("plugin_languages"))},followup:{enabled:i(e.getInput("plugin_followup"))},music:{enabled:i(e.getInput("plugin_music"))},posts:{enabled:i(e.getInput("plugin_posts"))},isocalendar:{enabled:i(e.getInput("plugin_isocalendar"))},gists:{enabled:i(e.getInput("plugin_gists"))},topics:{enabled:i(e.getInput("plugin_topics"))},projects:{enabled:i(e.getInput("plugin_projects"))},tweets:{enabled:i(e.getInput("plugin_tweets"))}};let C=Object.fromEntries(Object.entries(k).filter(([e,t])=>t.enabled).map(([e])=>[e,!0]));if(console.log(`Plugins enabled | ${Object.entries(k).filter(([e,t])=>t.enabled).map(([e])=>e).join(", ")}`),k.pagespeed.enabled&&(k.pagespeed.token=e.getInput("plugin_pagespeed_token")||"",C[`pagespeed.detailed`]=i(e.getInput(`plugin_pagespeed_detailed`)),C[`pagespeed.screenshot`]=i(e.getInput(`plugin_pagespeed_screenshot`)),console.log(`Pagespeed token | ${k.pagespeed.token?"provided":"missing"}`),console.log(`Pagespeed detailed | ${C["pagespeed.detailed"]}`),console.log(`Pagespeed screenshot | ${C["pagespeed.screenshot"]}`)),k.languages.enabled){for(const t of["ignored","skipped"])C[`languages.${t}`]=e.getInput(`plugin_languages_${t}`)||null;console.log(`Languages ignored | ${C["languages.ignored"]||"(none)"}`),console.log(`Languages skipped repos | ${C["languages.skipped"]||"(none)"}`)}if(k.habits.enabled){for(const t of["from","days"])C[`habits.${t}`]=e.getInput(`plugin_habits_${t}`)||null;C[`habits.facts`]=i(e.getInput(`plugin_habits_facts`)),C[`habits.charts`]=i(e.getInput(`plugin_habits_charts`)),console.log(`Habits facts | ${C["habits.facts"]}`),console.log(`Habits charts | ${C["habits.charts"]}`),console.log(`Habits events to use | ${C["habits.from"]||"(default)"}`),console.log(`Habits days to keep | ${C["habits.days"]||"(default)"}`)}if(k.music.enabled){k.music.token=e.getInput("plugin_music_token")||"";for(const t of["provider","mode","playlist","limit"])C[`music.${t}`]=e.getInput(`plugin_music_${t}`)||null;console.log(`Music provider | ${C["music.provider"]||"(none)"}`),console.log(`Music plugin mode | ${C["music.mode"]||"(none)"}`),console.log(`Music playlist | ${C["music.playlist"]||"(none)"}`),console.log(`Music tracks limit | ${C["music.limit"]||"(default)"}`),console.log(`Music token | ${k.music.token?"provided":"missing"}`)}if(k.posts.enabled){for(const t of["source","limit"])C[`posts.${t}`]=e.getInput(`plugin_posts_${t}`)||null;console.log(`Posts source | ${C["posts.source"]||"(none)"}`),console.log(`Posts limit | ${C["posts.limit"]||"(default)"}`)}if(k.isocalendar.enabled&&(C["isocalendar.duration"]=e.getInput("plugin_isocalendar_duration")||"half-year",console.log(`Isocalendar duration | ${C["isocalendar.duration"]}`)),k.topics.enabled){for(const t of["mode","sort","limit"])C[`topics.${t}`]=e.getInput(`plugin_topics_${t}`)||null;console.log(`Topics mode | ${C["topics.mode"]||"(default)"}`),console.log(`Topics sort mode | ${C["topics.sort"]||"(default)"}`),console.log(`Topics limit | ${C["topics.limit"]||"(default)"}`)}if(k.projects.enabled){for(const t of["limit","repositories"])C[`projects.${t}`]=e.getInput(`plugin_projects_${t}`)||null;console.log(`Projects limit | ${C["projects.limit"]||"(default)"}`),console.log(`Projects repositories | ${C["projects.repositories"]||"(none)"}`)}if(k.tweets.enabled){k.tweets.token=e.getInput("plugin_tweets_token")||null;for(const t of["limit"])C[`tweets.${t}`]=e.getInput(`plugin_tweets_${t}`)||null;console.log(`Twitter token | ${k.tweets.token?"provided":"missing"}`),console.log(`Tweets limit | ${C["tweets.limit"]||"(default)"}`)}const _=+e.getInput("repositories")||100;console.log(`Repositories to use | ${_}`);const w=i(e.getInput("plugins_errors_fatal"));console.log(`Plugin errors | ${w?"die":"warn"}`);const T=JSON.parse(e.getInput("query")||"{}");console.log(`Query additional params | ${JSON.stringify(T)}`),C={...T,...C,base:!1,...S,...v,repositories:_,template:d};const E=await o({login:f,q:C,dflags:b},{graphql:c,rest:u,plugins:k,conf:l,die:w});console.log(`Render | complete`);const A=i(e.getInput("verify"));if(console.log(`Verify SVG | ${A}`),A){const[e]=[await r.e(344).then(r.t.bind(r,53344,1))].map(e=>e&&e.default?e.default:e),t=e.parseXml(E);if(t.errors.length)throw new Error(`Malformed SVG : \n${t.errors.join("\n")}`);console.log(`SVG valid | yes`)}const O=i(e.getInput("dryrun"));if(O)console.log(`Dry-run | complete`);else{const r=t.context.ref.replace(/^refs[/]heads[/]/,"");console.log(`Repository | ${t.context.repo.owner}/${t.context.repo.repo}`),console.log(`Branch | ${r}`);const n=e.getInput("committer_token")||e.getInput("token")||"";if(console.log(`Committer token | ${n?"provided":"missing"}`),!n)throw new Error("You must provide a valid GitHub token to commit your metrics");const a=t.getOctokit(n);console.log(`Committer REST API | ok`);try{console.log(`Committer | ${(await a.users.getAuthenticated()).data.login}`)}catch{console.log(`Committer | (github-actions)`)}let o=null;try{const{repository:{object:{oid:e}}}=await c(`
+ `,i++}S+=``,b++}return S+=``,{streak:g,max:m,average:f,svg:S,duration:o}}catch(e){throw{error:{message:"An error occured",instance:e}}}},languages:async function({login:e,data:t,q:r},{enabled:n=!1}={}){try{if(!n||!r.languages)return null;let{"languages.ignored":a="","languages.skipped":o=""}=r;a=decodeURIComponent(a).split(",").map(e=>e.trim().toLocaleLowerCase()).filter(e=>e),o=decodeURIComponent(o).split(",").map(e=>e.trim().toLocaleLowerCase()).filter(e=>e),console.debug(`metrics/compute/${e}/plugins > languages > processing ${t.user.repositories.nodes.length} repositories`);const s={colors:{},total:0,stats:{}};for(const r of t.user.repositories.nodes){if(o.includes(r.name.toLocaleLowerCase())){console.debug(`metrics/compute/${e}/plugins > languages > skipped repository ${r.name}`);continue}for(const{size:t,node:{color:n,name:o}}of Object.values(r.languages.edges)){if(a.includes(o.toLocaleLowerCase())){console.debug(`metrics/compute/${e}/plugins > languages > ignored language ${o}`);continue}s.stats[o]=(s.stats[o]??0)+t,s.colors[o]=n??"#ededed",s.total+=t}}console.debug(`metrics/compute/${e}/plugins > languages > computing stats`),Object.keys(s.stats).map(e=>s.stats[e]/=s.total),s.favorites=Object.entries(s.stats).sort(([e,t],[r,n])=>n-t).slice(0,8).map(([e,t])=>({name:e,value:t,color:s.colors[e],x:0}));for(let e=1;ee)??[];console.debug(`metrics/compute/${e}/plugins > lines > querying api`);const s={added:0,deleted:0},l=await Promise.all(i.map(async t=>await n.repos.getContributorsStats({owner:e,repo:t})));return console.debug(`metrics/compute/${e}/plugins > lines > computing total diff`),l.map(({data:t})=>{if(Array.isArray(t)){const[r]=t.filter(({author:t})=>t.login===e);r&&r.weeks.forEach(({a:e,d:t})=>(s.added+=e,s.deleted+=t))}}),s.added=r.format(s.added),s.deleted=r.format(s.deleted),s}catch(e){throw{error:{message:"An error occured",instance:e}}}},music:a,pagespeed:async function({login:e,imports:t,data:r,q:n},{enabled:a=!1,token:o=null}={}){try{if(!a||!n.pagespeed||!r.user.websiteUrl)return null;let{"pagespeed.detailed":i=!1,"pagespeed.screenshot":s=!1}=n;i=!!i;let l=r.user.websiteUrl;/^https?:[/][/]/.test(l)||(l=`https://${l}`);const d={url:l,detailed:i,scores:[],metrics:{}};console.debug(`metrics/compute/${e}/plugins > pagespeed > querying api for ${l}`);const p=new Map;if(await Promise.all(["performance","accessibility","best-practices","seo"].map(async r=>{console.debug(`metrics/compute/${e}/plugins > pagespeed > performing audit ${r}`);const n=await t.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?category=${r}&url=${l}&key=${o}`);console.debug(n.data);const{score:a,title:i}=n.data.lighthouseResult.categories[r];p.set(r,{score:a,title:i}),console.debug(`metrics/compute/${e}/plugins > pagespeed > performed audit ${r} (status code ${n.status})`),s&&"performance"===r&&(d.screenshot=n.data.lighthouseResult.audits["final-screenshot"].details.data,console.debug(`metrics/compute/${e}/plugins > pagespeed > performed audit ${r} (status code ${n.status})`))})),d.scores=[p.get("performance"),p.get("accessibility"),p.get("best-practices"),p.get("seo")],i){console.debug(`metrics/compute/${e}/plugins > pagespeed > performing detailed audit`);const r=await t.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?&url=${l}&key=${o}`);console.debug(r.data),Object.assign(d.metrics,...r.data.lighthouseResult.audits.metrics.details.items),console.debug(`metrics/compute/${e}/plugins > pagespeed > performed detailed audit (status code ${r.status})`)}return d}catch(e){let t="An error occured";if(e.isAxiosError){const r=e.response?.status,n=e.response?.data?.error?.message?.match(/Lighthouse returned error: (?[A-Z_]+)/)?.groups?.description??null;t=`API returned ${r}${n?` (${n})`:""}`,e=e.response?.data??null}throw{error:{message:t,instance:e}}}},posts:async function({imports:e,data:t,q:r},{enabled:n=!1}={}){try{if(!n||!r.posts)return null;const a=t.user.login;let{"posts.source":o="","posts.limit":i=4}=r;i=_Mathmax(1,_Mathmin(30,+i)),console.debug(`metrics/compute/${a}/plugins > posts > processing with source ${o}`);let s=null;switch(o){case"dev.to":{console.debug(`metrics/compute/${a}/plugins > posts > querying api`),s=(await e.axios.get(`https://dev.to/api/articles?username=${a}&state=fresh`)).data.map(({title:e,readable_publish_date:t})=>({title:e,date:t}));break}default:throw{error:{message:`Unsupported source "${o}"`}};}if(Array.isArray(s))return 0 posts > keeping only ${i} posts`),s.splice(i)),{source:o,list:s};throw{error:{message:`An error occured (could not retrieve posts)`}}}catch(e){throw{error:{message:"An error occured",instance:e}}}},projects:async function({login:e,graphql:t,q:r,queries:n},{enabled:a=!1}={}){try{if(!a||!r.projects)return null;let{"projects.limit":o=4,"projects.repositories":i=""}=r;i=i?.split(",").map(e=>e.trim()).filter(e=>/[-\w]+[/][-\w]+[/]projects[/]\d+/.test(e))??[],o=_Mathmax(i.length,_Mathmin(100,+o)),console.debug(`metrics/compute/${e}/plugins > projects > querying api`);const{user:{projects:s}}=await t(n.projects({login:e,limit:o}));for(const r of i){console.debug(`metrics/compute/${e}/plugins > projects > querying api for ${r}`);const{user:a,repository:o,id:i}=r.match(/(?[-\w]+)[/](?[-\w]+)[/]projects[/](?\d+)/)?.groups,{user:{repository:{project:l}}}=await t(n["projects.repository"]({user:a,repository:o,id:i}));console.debug(`metrics/compute/${e}/plugins > projects > registering ${r}`),l.name=`${l.name} (${a}/${o})`,s.nodes.unshift(l),s.totalCount++}console.debug(`metrics/compute/${e}/plugins > projects > processing ${s.nodes.length} projects`);const l=[];for(const e of s.nodes){const t=(Date.now()-new Date(e.updatedAt).getTime())/86400000;let r=1>t?"less than 1 day ago":30>t?`${_Mathfloor(t)} day${2<=t?"s":""} ago`:new Date(e.updatedAt).toDateString().substring(4);const{enabled:n,todoCount:a,inProgressCount:o,doneCount:i}=e.progress;l.push({name:e.name,updated:r,progress:{enabled:n,todo:a,doing:o,done:i,total:a+o+i}})}return console.debug(`metrics/compute/${e}/plugins > projects > keeping only ${o} projects`),l.splice(o),{list:l,totalCount:s.totalCount}}catch(e){let t="An error occured";throw e.errors?.map(({type:e})=>e)?.includes("INSUFFICIENT_SCOPES")&&(t="Insufficient token rights"),{error:{message:t,instance:e}}}},topics:async function({login:e,imports:t,q:r},{enabled:n=!1}={}){var a=Number.isFinite;try{if(!n||!r.topics)return null;let{"topics.sort":s="stars","topics.mode":l="starred","topics.limit":o}=r;const d="random"===s;s={starred:"created",activity:"updated",stars:"stars",random:"created"}[s]??"starred",a(o)||(o="mastered"===l?0:15),o=_Mathmax(0,_Mathmin(20,+o)),l=["starred","mastered"].includes(l)?l:"starred",console.debug(`metrics/compute/${e}/plugins > topics > searching starred topics`);let p=[];console.debug(`metrics/compute/${e}/plugins > topics > starting browser`);const c=await t.puppeteer.launch({headless:!0,executablePath:process.env.PUPPETEER_BROWSER_PATH,args:["--no-sandbox","--disable-extensions","--disable-setuid-sandbox","--disable-dev-shm-usage"]});console.debug(`metrics/compute/${e}/plugins > topics > started ${await c.version()}`);const u=await c.newPage();for(let t=1;100>=t;t++){console.debug(`metrics/compute/${e}/plugins > topics > loading page ${t}`),await u.goto(`https://github.com/stars/${e}/topics?direction=desc&page=${t}&sort=${s}`);const r=u.mainFrame();await Promise.race([r.waitForSelector("ul.repo-list"),r.waitForSelector(".blankslate")]);const n=await r.evaluate(()=>[...document.querySelectorAll("ul.repo-list li")].map(e=>({name:e.querySelector(".f3").innerText,description:e.querySelector(".f5").innerText,icon:e.querySelector("img")?.src??null})));if(console.debug(`metrics/compute/${e}/plugins > topics > extracted ${n.length} starred topics`),!n.length){console.debug(`metrics/compute/${e}/plugins > topics > no more page to load`);break}p.push(...n)}if(console.debug(`metrics/compute/${e}/plugins > music > closing browser`),await c.close(),d&&(console.debug(`metrics/compute/${e}/plugins > topics > shuffling topics`),p=t.shuffle(p)),"starred"===l&&0 topics > keeping only ${o} topics`);const t=p.splice(o);p.push({name:`And ${t.length} more...`,description:t.map(({name:e})=>e).join(", "),icon:null})}console.debug(`metrics/compute/${e}/plugins > topics > loading artworks`);for(const r of p)r.icon&&(console.debug(`metrics/compute/${e}/plugins > topics > processing ${r.name}`),r.icon=await t.imgb64(r.icon)),r.description=t.htmlescape(r.description);return"mastered"===l&&(console.debug(`metrics/compute/${e}/plugins > topics > filtering topics with icon`),p=p.filter(({icon:e})=>e)),"mastered"===l&&0 topics > keeping only ${o} topics`),p.splice(o)),{mode:l,list:p}}catch(e){throw{error:{message:"An error occured",instance:e}}}},traffic:async function({login:e,imports:t,data:r,rest:n,q:a},{enabled:o=!1}={}){try{if(!o||!a.traffic)return null;const i=r.user.repositories.nodes.map(({name:e})=>e)??[];console.debug(`metrics/compute/${e}/plugins > traffic > querying api`);const s={count:0,uniques:0},l=await Promise.all(i.map(async t=>await n.repos.getViews({owner:e,repo:t})));return console.debug(`metrics/compute/${e}/plugins > traffic > computing stats`),l.filter(({data:e})=>e).map(({data:{count:e,uniques:t}})=>(s.count+=e,s.uniques+=t)),s.count=t.format(s.count),s.uniques=t.format(s.uniques),{views:s}}catch(e){let t="An error occured";throw 403===e.status&&(t="Insufficient token rights"),{error:{message:t,instance:e}}}},tweets:async function({login:e,imports:t,data:r,q:n},{enabled:a=!1,token:o=null}={}){try{if(!a||!n.tweets)return null;let{"tweets.limit":i=2}=n;i=_Mathmax(1,_Mathmin(10,+i));const s=r.user.twitterUsername;console.debug(`metrics/compute/${e}/plugins > tweets > loading twitter profile (@${s})`);const{data:{data:l=null}}=await t.axios.get(`https://api.twitter.com/2/users/by/username/${s}?user.fields=profile_image_url,verified`,{headers:{Authorization:`Bearer ${o}`}});console.debug(`metrics/compute/${e}/plugins > tweets > querying api`);const{data:{data:d=[]}}=await t.axios.get(`https://api.twitter.com/2/tweets/search/recent?query=from:${s}&tweet.fields=created_at&expansions=entities.mentions.username`,{headers:{Authorization:`Bearer ${o}`}});return l?.profile_image_url&&(console.debug(`metrics/compute/${e}/plugins > tweets > loading profile image`),l.profile_image=await t.imgb64(l.profile_image_url)),0 tweets > keeping only ${i} tweets`),d.splice(i)),await Promise.all(d.map(async r=>{r.mentions=r.entities?.mentions.map(({username:e})=>e)??[],console.debug(`metrics/compute/${e}/plugins > tweets > formatting tweet ${r.id}`),r.text=t.htmlescape(t.htmlescape(r.text,{"<":!0,">":!0}).replace(new RegExp(`@(${r.mentions.join("|")})`,"gi"),` @$1 `).replace(/(?#$1 `).replace(/\n/g,"
").replace(/https?:[/][/](t.co[/]\w+)/g,` $1 `),{"&":!0})})),{username:s,profile:l,list:d}}catch(e){let t="An error occured";if(e.isAxiosError){const r=e.response?.status,n=e.response?.data?.errors?.[0]?.message??null;t=`API returned ${r}${n?` (${n})`:""}`,e=e.response?.data??null}throw{error:{message:t,instance:e}}}}},E={classic:async function({login:e,q:t},{conf:r,data:n,rest:a,graphql:i,plugins:l,queries:d},{s:p,pending:s,imports:c}){await o(...arguments)},repository:async function({login:e,q:t},{conf:r,data:n,rest:a,graphql:i,plugins:l,queries:d},{s:p,pending:s,imports:c}){const{repo:u}=t;if(!u)return console.debug(`metrics/compute/${e}/${u} > error, repo was undefined`),n.errors.push({error:{message:`You must pass a "repo" argument to use this template`}}),await o(...arguments);console.debug(`metrics/compute/${e}/${u} > retrieving single repository ${u}`);const{user:{repository:m}}=await i(d.repository({login:e,repo:u}));n.user.repositories.nodes=[m],console.debug(`metrics/compute/${e}/${u} > querying api for commits`);const g=[];for(let o=0;1>o;o++){console.debug(`metrics/compute/${e}/${u} > loading page ${o}`);const{data:t}=await a.repos.listCommits({owner:e,repo:u,per_page:100,page:o});if(!t.length){console.debug(`metrics/compute/${e}/${u} > no more page to load`);break}g.push(...t)}console.debug(`metrics/compute/${e}/${u} > ${g.length} commits loaded`),n.user.createdAt=m.createdAt,n.user.repositories.totalDiskUsage=m.diskUsage;const h=new Date;h.setHours(0,0,0,0);const f=g.map(({commit:e})=>_Mathabs(_Mathceil((h-new Date(e.committer.date))/86400000))).slice(0,14),y=Array(14).fill(0);for(const o of f)y[o]++;const b=_Mathmax(...y);n.user.calendar.contributionCalendar.weeks=y.map(e=>({contributionDays:{color:e?`var(--color-calendar-graph-day-L${_Mathceil(e/b/.25)}-bg)`:"var(--color-calendar-graph-day-bg)"}})),t["projects.limit"]=0,await o(...arguments),await Promise.all(s),n.plugins.projects&&n.plugins.projects.list?.map(t=>t.name=t.name.replace(`(${e}/${u})`,"").trim())},terminal:async function({login:e,q:t},{conf:r,data:n,rest:a,graphql:i,plugins:l,queries:d},{s:p,pending:s,imports:c}){await o(...arguments),t.raw=!0}};var A=r(34651),O=r(78835),P=r(63129);const L=require("fs/promises");var z=r(12087),R=r(3584),I=r.t(R),M=r(32882),W=r.t(M),q=r(29483),B=r.t(q);(async function(){const[e,t,n,a,o]=[W,B,I,h,f].map(e=>e&&e.default?e.default:e),i=(e,t=!1)=>"string"==typeof e?/^(?:[Tt]rue|[Oo]n|[Yy]es)$/.test(e):t,s=[];try{console.log(`GitHub metrics`),console.log(`========================================================`),console.log(`Version | 2.10.0-beta`),process.on("unhandledRejection",e=>{throw e}),"push"===t.context.eventName&&t.context.payload&&t.context.payload.head_commit&&/\[Skip GitHub Action\]/.test(t.context.payload.head_commit.message)&&(console.log(`Skipped because [Skip GitHub Action] is in commit message`),process.exit(0));const l=await a({log:!1});console.log(`Configuration | loaded`);const d=e.getInput("template")||"classic";console.log(`Template to use | ${d}`);const p=e.getInput("token")||"";if(console.log(`Github token | ${p?"provided":"missing"}`),!p)throw new Error("You must provide a valid GitHub token to gather your metrics");const c=n.graphql.defaults({headers:{authorization:`token ${p}`}});console.log(`Github GraphQL API | ok`);const u=t.getOctokit(p);console.log(`Github REST API | ok`);const m=e.getInput("filename")||"github-metrics.svg";console.log(`SVG output file | ${m}`);const g=i(e.getInput("optimize"),!0);l.optimize=g,console.log(`SVG optimization | ${g}`);let h;try{h=(await u.users.getAuthenticated()).data.login}catch{h=t.context.repo.owner}const f=e.getInput("user")||h;console.log(`GitHub user | ${f}`);const y=i(e.getInput("debug"));y||(console.debug=e=>s.push(e)),console.log(`Debug mode | ${y}`);const b=(e.getInput("debug_flags")||"").split(" ").filter(e=>e);console.log(`Debug flags | ${b.join(" ")||"(none)"}`);const S={};let x=(e.getInput("base")||"").split(",").map(e=>e.trim());for(const e of l.settings.plugins.base.parts)S[`base.${e}`]=x.includes(e);console.log(`Base parts | ${x.join(", ")||"(none)"}`);const v={"config.timezone":e.getInput("config_timezone")||""};console.log(`Timezone | ${v["config.timezone"]||"(system default)"}`);const k={lines:{enabled:i(e.getInput("plugin_lines"))},traffic:{enabled:i(e.getInput("plugin_traffic"))},pagespeed:{enabled:i(e.getInput("plugin_pagespeed"))},habits:{enabled:i(e.getInput("plugin_habits"))},languages:{enabled:i(e.getInput("plugin_languages"))},followup:{enabled:i(e.getInput("plugin_followup"))},music:{enabled:i(e.getInput("plugin_music"))},posts:{enabled:i(e.getInput("plugin_posts"))},isocalendar:{enabled:i(e.getInput("plugin_isocalendar"))},gists:{enabled:i(e.getInput("plugin_gists"))},topics:{enabled:i(e.getInput("plugin_topics"))},projects:{enabled:i(e.getInput("plugin_projects"))},tweets:{enabled:i(e.getInput("plugin_tweets"))}};let C=Object.fromEntries(Object.entries(k).filter(([e,t])=>t.enabled).map(([e])=>[e,!0]));if(console.log(`Plugins enabled | ${Object.entries(k).filter(([e,t])=>t.enabled).map(([e])=>e).join(", ")}`),k.pagespeed.enabled&&(k.pagespeed.token=e.getInput("plugin_pagespeed_token")||"",C[`pagespeed.detailed`]=i(e.getInput(`plugin_pagespeed_detailed`)),C[`pagespeed.screenshot`]=i(e.getInput(`plugin_pagespeed_screenshot`)),console.log(`Pagespeed token | ${k.pagespeed.token?"provided":"missing"}`),console.log(`Pagespeed detailed | ${C["pagespeed.detailed"]}`),console.log(`Pagespeed screenshot | ${C["pagespeed.screenshot"]}`)),k.languages.enabled){for(const t of["ignored","skipped"])C[`languages.${t}`]=e.getInput(`plugin_languages_${t}`)||null;console.log(`Languages ignored | ${C["languages.ignored"]||"(none)"}`),console.log(`Languages skipped repos | ${C["languages.skipped"]||"(none)"}`)}if(k.habits.enabled){for(const t of["from","days"])C[`habits.${t}`]=e.getInput(`plugin_habits_${t}`)||null;C[`habits.facts`]=i(e.getInput(`plugin_habits_facts`)),C[`habits.charts`]=i(e.getInput(`plugin_habits_charts`)),console.log(`Habits facts | ${C["habits.facts"]}`),console.log(`Habits charts | ${C["habits.charts"]}`),console.log(`Habits events to use | ${C["habits.from"]||"(default)"}`),console.log(`Habits days to keep | ${C["habits.days"]||"(default)"}`)}if(k.music.enabled){k.music.token=e.getInput("plugin_music_token")||"";for(const t of["provider","mode","playlist","limit"])C[`music.${t}`]=e.getInput(`plugin_music_${t}`)||null;console.log(`Music provider | ${C["music.provider"]||"(none)"}`),console.log(`Music plugin mode | ${C["music.mode"]||"(none)"}`),console.log(`Music playlist | ${C["music.playlist"]||"(none)"}`),console.log(`Music tracks limit | ${C["music.limit"]||"(default)"}`),console.log(`Music token | ${k.music.token?"provided":"missing"}`)}if(k.posts.enabled){for(const t of["source","limit"])C[`posts.${t}`]=e.getInput(`plugin_posts_${t}`)||null;console.log(`Posts source | ${C["posts.source"]||"(none)"}`),console.log(`Posts limit | ${C["posts.limit"]||"(default)"}`)}if(k.isocalendar.enabled&&(C["isocalendar.duration"]=e.getInput("plugin_isocalendar_duration")||"half-year",console.log(`Isocalendar duration | ${C["isocalendar.duration"]}`)),k.topics.enabled){for(const t of["mode","sort","limit"])C[`topics.${t}`]=e.getInput(`plugin_topics_${t}`)||null;console.log(`Topics mode | ${C["topics.mode"]||"(default)"}`),console.log(`Topics sort mode | ${C["topics.sort"]||"(default)"}`),console.log(`Topics limit | ${C["topics.limit"]||"(default)"}`)}if(k.projects.enabled){for(const t of["limit","repositories"])C[`projects.${t}`]=e.getInput(`plugin_projects_${t}`)||null;console.log(`Projects limit | ${C["projects.limit"]||"(default)"}`),console.log(`Projects repositories | ${C["projects.repositories"]||"(none)"}`)}if(k.tweets.enabled){k.tweets.token=e.getInput("plugin_tweets_token")||null;for(const t of["limit"])C[`tweets.${t}`]=e.getInput(`plugin_tweets_${t}`)||null;console.log(`Twitter token | ${k.tweets.token?"provided":"missing"}`),console.log(`Tweets limit | ${C["tweets.limit"]||"(default)"}`)}const _=+e.getInput("repositories")||100;console.log(`Repositories to use | ${_}`);const w=i(e.getInput("plugins_errors_fatal"));console.log(`Plugin errors | ${w?"die":"warn"}`);const T=JSON.parse(e.getInput("query")||"{}");console.log(`Query additional params | ${JSON.stringify(T)}`),C={...T,...C,base:!1,...S,...v,repositories:_,template:d};const E=await o({login:f,q:C,dflags:b},{graphql:c,rest:u,plugins:k,conf:l,die:w});console.log(`Render | complete`);const A=i(e.getInput("verify"));if(console.log(`Verify SVG | ${A}`),A){const[e]=[await r.e(344).then(r.t.bind(r,53344,1))].map(e=>e&&e.default?e.default:e),t=e.parseXml(E);if(t.errors.length)throw new Error(`Malformed SVG : \n${t.errors.join("\n")}`);console.log(`SVG valid | yes`)}const O=i(e.getInput("dryrun"));if(O)console.log(`Dry-run | complete`);else{const r=t.context.ref.replace(/^refs[/]heads[/]/,"");console.log(`Repository | ${t.context.repo.owner}/${t.context.repo.repo}`),console.log(`Branch | ${r}`);const n=e.getInput("committer_token")||e.getInput("token")||"";if(console.log(`Committer token | ${n?"provided":"missing"}`),!n)throw new Error("You must provide a valid GitHub token to commit your metrics");const a=t.getOctokit(n);console.log(`Committer REST API | ok`);try{console.log(`Committer | ${(await a.users.getAuthenticated()).data.login}`)}catch{console.log(`Committer | (github-actions)`)}let o=null;try{const{repository:{object:{oid:e}}}=await c(`
query Sha {
repository(owner: "${t.context.repo.owner}", name: "${t.context.repo.repo}") {
object(expression: "${r}:${m}") { ... on Blob { oid } }
diff --git a/src/plugins/topics/index.mjs b/src/plugins/topics/index.mjs
index feeb4e93..3f079847 100644
--- a/src/plugins/topics/index.mjs
+++ b/src/plugins/topics/index.mjs
@@ -6,12 +6,14 @@
if ((!enabled)||(!q.topics))
return null
//Parameters override
- let {"topics.sort":sort = "stars", "topics.mode":mode = "starred", "topics.limit":limit = (mode === "mastered" ? 0 : 15)} = q
+ let {"topics.sort":sort = "stars", "topics.mode":mode = "starred", "topics.limit":limit} = q
//Shuffle
const shuffle = (sort === "random")
//Sort method
sort = {starred:"created", activity:"updated", stars:"stars", random:"created"}[sort] ?? "starred"
//Limit
+ if (!Number.isFinite(limit))
+ limit = (mode === "mastered" ? 0 : 15)
limit = Math.max(0, Math.min(20, Number(limit)))
//Mode
mode = ["starred", "mastered"].includes(mode) ? mode : "starred"
diff --git a/utils/build.mjs b/utils/build.mjs
index e98650c9..a3284e04 100644
--- a/utils/build.mjs
+++ b/utils/build.mjs
@@ -75,7 +75,7 @@
template:"${{ matrix.template }}",
base:"",
plugins_errors_fatal:true,
- q:'{"repo":"metrics"}',
+ q:`'{"repo":"metrics"}'`,
...context
}).map(([key, value]) => `${" ".repeat(5)}${key}: ${
typeof value === "boolean" ? (value ? "yes" : "no") :