Skip to content

Commit 19b3f14

Browse files
committed
Refactor action inputs
1 parent 54900bc commit 19b3f14

File tree

2 files changed

+110
-107
lines changed

2 files changed

+110
-107
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "metrics",
3-
"version": "2.10.0-beta",
3+
"version": "3.0.0-beta",
44
"description": "An image generator with 20+ metrics about your GitHub account such as activity, community, repositories, coding habits, website performances, music played, starred topics, etc. that you can put on your profile or elsewhere !",
55
"main": "index.mjs",
66
"scripts": {

source/app/action/index.mjs

Lines changed: 109 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,23 @@
77
import metrics from "../metrics.mjs"
88

99
;((async function () {
10-
//Yaml boolean converter
11-
const bool = (value, defaulted = false) => typeof value === "string" ? /^(?:[Tt]rue|[Oo]n|[Yy]es)$/.test(value) : defaulted
10+
//Input parser
11+
const input = {
12+
get:(name) => decodeURIComponent(`${core.getInput(name)}`.trim()),
13+
bool:(name, {default:defaulted = undefined} = {}) => /^(?:[Tt]rue|[Oo]n|[Yy]es)$/.test(input.get(name)) ? true : /^(?:[Ff]alse|[Oo]ff|[Nn]o)$/.test(input.get(name)) ? false : defaulted,
14+
number:(name, {default:defaulted = undefined} = {}) => Number.isFinite(Number(input.get(name))) ? Number(input.get(name)) : defaulted,
15+
string:(name, {default:defaulted = undefined} = {}) => input.get(name) || defaulted,
16+
array:(name, {separator = ","} = {}) => input.get(name).split(separator).map(value => value.trim()).filter(value => value),
17+
object:(name) => JSON.parse(input.get(name) || "{}"),
18+
}
19+
//Info logger
20+
const info = (left, right, {token = false} = {}) => console.log(`${`${left}`.padEnd(48)}${
21+
Array.isArray(right) ? right.join(", ") || "(none)" :
22+
right === undefined ? "(default)" :
23+
token ? /^MOCKED/.test(right) ? "(MOCKED TOKEN)" : (right ? "(provided)" : "(missing)") :
24+
typeof right === "object" ? JSON.stringify(right) :
25+
right
26+
}`)
1227
//Debug message buffer
1328
const debugged = []
1429
//Runner
@@ -29,47 +44,51 @@
2944

3045
//Load configuration
3146
const {conf, Plugins, Templates} = await setup({log:false})
32-
console.log(`Configuration │ loaded`)
33-
console.log(`Version${conf.package.version}`)
47+
info("Setup", "complete")
48+
info("Version", conf.package.version)
3449

3550
//Debug mode
36-
const debug = bool(core.getInput("debug"))
51+
const debug = input.bool("debug", {default:false})
52+
info("Debug mode", debug)
3753
if (!debug)
3854
console.debug = message => debugged.push(message)
39-
console.log(`Debug mode │ ${debug}`)
40-
const dflags = (core.getInput("debug_flags") || "").split(" ").filter(flag => flag)
41-
console.log(`Debug flags │ ${dflags.join(" ") || "(none)"}`)
55+
const dflags = input.array("debug_flags", {separator:" "})
56+
info("Debug flags", dflags)
4257

4358
//Load svg template, style, fonts and query
44-
const template = core.getInput("template") || "classic"
45-
console.log(`Template to use │ ${template}`)
59+
const template = input.string("template", {default:"classic"})
60+
info("Template used", template)
4661

4762
//Token for data gathering
48-
const token = core.getInput("token") || ""
49-
console.log(`Github token${/^MOCKED/.test(token) ? "(MOCKED)" : token ? "provided" : "missing"}`)
63+
const token = input.string("token")
64+
info("GitHub token", token, {token:true})
5065
if (!token)
5166
throw new Error("You must provide a valid GitHub token to gather your metrics")
5267
const api = {}
5368
api.graphql = octokit.graphql.defaults({headers:{authorization: `token ${token}`}})
54-
console.log(`Github GraphQL API │ ok`)
69+
info("Github GraphQL API", "ok")
5570
api.rest = github.getOctokit(token)
56-
console.log(`Github REST API │ ok`)
71+
info("Github REST API", "ok")
5772
//Apply mocking if needed
58-
if (bool(core.getInput("use_mocked_data"))) {
73+
if (input.bool("use_mocked_data", {default:false})) {
5974
Object.assign(api, await mocks(api))
60-
console.log(`Mocked Github API │ ok`)
75+
info("Use mocked API", true)
6176
}
6277
//Extract octokits
6378
const {graphql, rest} = api
6479

6580
//SVG output
66-
const filename = core.getInput("filename") || "github-metrics.svg"
67-
console.log(`SVG output file │ ${filename}`)
81+
const filename = input.string("filename", {default:"github-metrics.svg"})
82+
info("SVG output", filename)
6883

6984
//SVG optimization
70-
const optimize = bool(core.getInput("optimize"), true)
85+
const optimize = input.bool("optimize", {default:true})
7186
conf.optimize = optimize
72-
console.log(`SVG optimization │ ${optimize}`)
87+
info("SVG optimization", optimize)
88+
89+
//Verify svg
90+
const verify = input.bool("verify")
91+
info("SVG verification after generation", verify)
7392

7493
//GitHub user
7594
let authenticated
@@ -79,157 +98,142 @@
7998
catch {
8099
authenticated = github.context.repo.owner
81100
}
82-
const user = core.getInput("user") || authenticated
83-
console.log(`GitHub user${user}`)
101+
const user = input.string("user", {default:authenticated})
102+
info("Target GitHub user", user)
84103

85104
//Base elements
86105
const base = {}
87-
let parts = (core.getInput("base") || "").split(",").map(part => part.trim())
106+
const parts = input.array("base")
88107
for (const part of conf.settings.plugins.base.parts)
89108
base[`base.${part}`] = parts.includes(part)
90-
console.log(`Base parts${parts.join(", ") || "(none)"}`)
109+
info("Base parts", parts)
91110

92111
//Config
93112
const config = {
94-
"config.timezone":core.getInput("config_timezone") || ""
113+
"config.timezone":input.string("config_timezone")
95114
}
96-
console.log(`Timezone${config["config.timezone"] || "(system default)"}`)
115+
info("Timezone", config["config.timezone"] ?? "(system default)")
97116

98117
//Additional plugins
99118
const plugins = {
100-
lines:{enabled:bool(core.getInput("plugin_lines"))},
101-
traffic:{enabled:bool(core.getInput("plugin_traffic"))},
102-
pagespeed:{enabled:bool(core.getInput("plugin_pagespeed"))},
103-
habits:{enabled:bool(core.getInput("plugin_habits"))},
104-
languages:{enabled:bool(core.getInput("plugin_languages"))},
105-
followup:{enabled:bool(core.getInput("plugin_followup"))},
106-
music:{enabled:bool(core.getInput("plugin_music"))},
107-
posts:{enabled:bool(core.getInput("plugin_posts"))},
108-
isocalendar:{enabled:bool(core.getInput("plugin_isocalendar"))},
109-
gists:{enabled:bool(core.getInput("plugin_gists"))},
110-
topics:{enabled:bool(core.getInput("plugin_topics"))},
111-
projects:{enabled:bool(core.getInput("plugin_projects"))},
112-
tweets:{enabled:bool(core.getInput("plugin_tweets"))},
119+
lines:{enabled:input.bool("plugin_lines")},
120+
traffic:{enabled:input.bool("plugin_traffic")},
121+
pagespeed:{enabled:input.bool("plugin_pagespeed")},
122+
habits:{enabled:input.bool("plugin_habits")},
123+
languages:{enabled:input.bool("plugin_languages")},
124+
followup:{enabled:input.bool("plugin_followup")},
125+
music:{enabled:input.bool("plugin_music")},
126+
posts:{enabled:input.bool("plugin_posts")},
127+
isocalendar:{enabled:input.bool("plugin_isocalendar")},
128+
gists:{enabled:input.bool("plugin_gists")},
129+
topics:{enabled:input.bool("plugin_topics")},
130+
projects:{enabled:input.bool("plugin_projects")},
131+
tweets:{enabled:input.bool("plugin_tweets")},
113132
}
114133
let q = Object.fromEntries(Object.entries(plugins).filter(([key, plugin]) => plugin.enabled).map(([key]) => [key, true]))
115-
console.log(`Plugins enabled${Object.entries(plugins).filter(([key, plugin]) => plugin.enabled).map(([key]) => key).join(", ")}`)
134+
info("Plugins enabled", Object.entries(plugins).filter(([key, plugin]) => plugin.enabled).map(([key]) => key))
116135
//Additional plugins options
117136
//Pagespeed
118137
if (plugins.pagespeed.enabled) {
119-
plugins.pagespeed.token = core.getInput("plugin_pagespeed_token") || ""
120-
q[`pagespeed.detailed`] = bool(core.getInput(`plugin_pagespeed_detailed`))
121-
q[`pagespeed.screenshot`] = bool(core.getInput(`plugin_pagespeed_screenshot`))
122-
console.log(`Pagespeed token │ ${/^MOCKED/.test(plugins.pagespeed.token) ? "(MOCKED)" : plugins.pagespeed.token ? "provided" : "missing"}`)
123-
console.log(`Pagespeed detailed │ ${q["pagespeed.detailed"]}`)
124-
console.log(`Pagespeed screenshot │ ${q["pagespeed.screenshot"]}`)
138+
plugins.pagespeed.token = input.string("plugin_pagespeed_token")
139+
info("Pagespeed token", plugins.pagespeed.token, {token:true})
140+
for (const option of ["detailed", "screenshot"])
141+
info(`Pagespeed ${option}`, q[`pagespeed.${option}`] = input.bool(`plugin_pagespeed_${option}`))
125142
}
126143
//Languages
127144
if (plugins.languages.enabled) {
128145
for (const option of ["ignored", "skipped"])
129-
q[`languages.${option}`] = core.getInput(`plugin_languages_${option}`) || null
130-
console.log(`Languages ignored │ ${q["languages.ignored"] || "(none)"}`)
131-
console.log(`Languages skipped repos │ ${q["languages.skipped"] || "(none)"}`)
146+
info(`Languages ${option}`, q[`languages.${option}`] = input.array(`plugin_languages_${option}`))
132147
}
133148
//Habits
134149
if (plugins.habits.enabled) {
150+
for (const option of ["facts", "charts"])
151+
info(`Habits ${option}`, q[`habits.${option}`] = input.bool(`plugin_habits_${option}`))
135152
for (const option of ["from", "days"])
136-
q[`habits.${option}`] = core.getInput(`plugin_habits_${option}`) || null
137-
q[`habits.facts`] = bool(core.getInput(`plugin_habits_facts`))
138-
q[`habits.charts`] = bool(core.getInput(`plugin_habits_charts`))
139-
console.log(`Habits facts │ ${q["habits.facts"]}`)
140-
console.log(`Habits charts │ ${q["habits.charts"]}`)
141-
console.log(`Habits events to use │ ${q["habits.from"] || "(default)"}`)
142-
console.log(`Habits days to keep │ ${q["habits.days"] || "(default)"}`)
153+
info(`Habits ${option}`, q[`habits.${option}`] = input.number(`plugin_habits_${option}`))
143154
}
144155
//Music
145156
if (plugins.music.enabled) {
146-
plugins.music.token = core.getInput("plugin_music_token") || ""
147-
for (const option of ["provider", "mode", "playlist", "limit"])
148-
q[`music.${option}`] = core.getInput(`plugin_music_${option}`) || null
149-
console.log(`Music provider │ ${q["music.provider"] || "(none)"}`)
150-
console.log(`Music plugin mode │ ${q["music.mode"] || "(none)"}`)
151-
console.log(`Music playlist │ ${q["music.playlist"] || "(none)"}`)
152-
console.log(`Music tracks limit │ ${q["music.limit"] || "(default)"}`)
153-
console.log(`Music token │ ${/^MOCKED/.test(plugins.music.token) ? "(MOCKED)" : plugins.music.token ? "provided" : "missing"}`)
157+
plugins.music.token = input.string("plugin_music_token")
158+
info("Music token", plugins.music.token, {token:true})
159+
for (const option of ["provider", "mode", "playlist"])
160+
info(`Music ${option}`, q[`music.${option}`] = input.string(`plugin_music_${option}`))
161+
for (const option of ["limit"])
162+
info(`Music ${option}`, q[`music.${option}`] = input.number(`plugin_music_${option}`))
154163
}
155164
//Posts
156165
if (plugins.posts.enabled) {
157-
for (const option of ["source", "limit"])
158-
q[`posts.${option}`] = core.getInput(`plugin_posts_${option}`) || null
159-
console.log(`Posts source │ ${q["posts.source"] || "(none)"}`)
160-
console.log(`Posts limit │ ${q["posts.limit"] || "(default)"}`)
166+
for (const option of ["source"])
167+
info(`Posts ${option}`, q[`posts.${option}`] = input.string(`plugin_posts_${option}`))
168+
for (const option of ["limit"])
169+
info(`Posts ${option}`, q[`posts.${option}`] = input.number(`plugin_posts_${option}`))
161170
}
162171
//Isocalendar
163172
if (plugins.isocalendar.enabled) {
164-
q["isocalendar.duration"] = core.getInput("plugin_isocalendar_duration") || "half-year"
165-
console.log(`Isocalendar duration │ ${q["isocalendar.duration"]}`)
173+
for (const option of ["duration"])
174+
info(`Isocalendar ${option}`, q[`isocalendar.${option}`] = input.string(`plugin_isocalendar_${option}`))
166175
}
167176
//Topics
168177
if (plugins.topics.enabled) {
169-
for (const option of ["mode", "sort", "limit"])
170-
q[`topics.${option}`] = core.getInput(`plugin_topics_${option}`) || null
171-
console.log(`Topics mode │ ${q["topics.mode"] || "(default)"}`)
172-
console.log(`Topics sort mode │ ${q["topics.sort"] || "(default)"}`)
173-
console.log(`Topics limit │ ${q["topics.limit"] || "(default)"}`)
178+
for (const option of ["mode", "sort"])
179+
info(`Topics ${option}`, q[`topics.${option}`] = input.string(`plugin_topics_${option}`))
180+
for (const option of ["limit"])
181+
info(`Topics ${option}`, q[`topics.${option}`] = input.number(`plugin_topics_${option}`))
174182
}
175183
//Projects
176184
if (plugins.projects.enabled) {
177-
for (const option of ["limit", "repositories"])
178-
q[`projects.${option}`] = core.getInput(`plugin_projects_${option}`) || null
179-
console.log(`Projects limit │ ${q["projects.limit"] || "(default)"}`)
180-
console.log(`Projects repositories │ ${q["projects.repositories"] || "(none)"}`)
185+
for (const option of ["repositories"])
186+
info(`Projects ${option}`, q[`projects.${option}`] = input.string(`plugin_projects_${option}`))
187+
for (const option of ["limit"])
188+
info(`Projects ${option}`, q[`projects.${option}`] = input.number(`plugin_projects_${option}`))
181189
}
182190
//Tweets
183191
if (plugins.tweets.enabled) {
184-
plugins.tweets.token = core.getInput("plugin_tweets_token") || null
192+
plugins.tweets.token = input.string("plugin_tweets_token")
193+
info("Tweets token", plugins.tweets.token, {token:true})
185194
for (const option of ["limit"])
186-
q[`tweets.${option}`] = core.getInput(`plugin_tweets_${option}`) || null
187-
console.log(`Twitter token │ ${/^MOCKED/.test(plugins.tweets.token) ? "(MOCKED)" : plugins.tweets.token ? "provided" : "missing"}`)
188-
console.log(`Tweets limit │ ${q["tweets.limit"] || "(default)"}`)
195+
info(`Tweets ${option}`, q[`tweets.${option}`] = input.number(`plugin_tweets_${option}`))
189196
}
190197

191198
//Repositories to use
192-
const repositories = Number(core.getInput("repositories")) || 100
193-
console.log(`Repositories to use │ ${repositories}`)
199+
const repositories = input.number("repositories")
200+
info("Repositories to process", repositories)
194201

195202
//Die on plugins errors
196-
const die = bool(core.getInput("plugins_errors_fatal"))
197-
console.log(`Plugin errors │ ${die ? "die" : "warn"}`)
198-
199-
//Verify svg
200-
const verify = bool(core.getInput("verify"))
201-
console.log(`Verify SVG │ ${verify}`)
203+
const die = input.bool("plugins_errors_fatal")
204+
info("Plugin errors", die ? "(exit with error)" : "(displayed in generated SVG)")
202205

203206
//Build query
204-
const query = JSON.parse(core.getInput("query") || "{}")
205-
console.log(`Query additional params${JSON.stringify(query)}`)
207+
const query = input.object("query")
208+
info("Query additional params", query)
206209
q = {...query, ...q, base:false, ...base, ...config, repositories, template}
207210

208211
//Render metrics
209212
const rendered = await metrics({login:user, q, dflags}, {graphql, rest, plugins, conf, die, verify}, {Plugins, Templates})
213+
info("Rendering", "complete")
210214
console.log(`Render │ complete`)
211215

212216
//Commit to repository
213-
const dryrun = bool(core.getInput("dryrun"))
217+
const dryrun = input.bool("dryrun")
214218
if (dryrun)
215-
console.log(`Dry-runcomplete`)
219+
info("Dry-run", "complete")
216220
else {
217221
//Repository and branch
218222
const branch = github.context.ref.replace(/^refs[/]heads[/]/, "")
219-
console.log(`Repository │ ${github.context.repo.owner}/${github.context.repo.repo}`)
220-
console.log(`Branch │ ${branch}`)
223+
info("Current repository", `${github.context.repo.owner}/${github.context.repo.repo}`)
224+
info("Current branch", branch)
221225
//Committer token
222-
const token = core.getInput("committer_token") || core.getInput("token") || ""
223-
console.log(`Committer token${/^MOCKED/.test(token) ? "(MOCKED)" : token ? "provided" : "missing"}`)
226+
const token = input.string("committer_token", {default:input.string("token")})
227+
info("Committer token", token, {token:true})
224228
if (!token)
225229
throw new Error("You must provide a valid GitHub token to commit your metrics")
226230
const rest = github.getOctokit(token)
227-
console.log(`Committer REST API │ ok`)
231+
info("Committer REST API", "ok")
228232
try {
229-
console.log(`Committer${(await rest.users.getAuthenticated()).data.login}`)
233+
info("Committer", (await rest.users.getAuthenticated()).data.login)
230234
}
231235
catch {
232-
console.log(`Committer(github-actions)`)
236+
info("Committer", "(github-actions)")
233237
}
234238
//Retrieve previous render SHA to be able to update file content through API
235239
let sha = null
@@ -244,25 +248,24 @@
244248
)
245249
sha = oid
246250
} catch (error) { console.debug(error) }
247-
console.log(`Previous render sha${sha ?? "(none)"}`)
251+
info("Previous render sha", sha ?? "(none)")
248252
//Update file content through API
249253
await rest.repos.createOrUpdateFileContents({
250254
...github.context.repo, path:filename, message:`Update ${filename} - [Skip GitHub Action]`,
251255
content:Buffer.from(rendered).toString("base64"),
252256
...(sha ? {sha} : {})
253257
})
254-
console.log(`Commit to repo │ ok`)
258+
info("Commit to current repository", "ok")
255259
}
256260

257261
//Success
258262
console.log(`Success, thanks for using metrics !`)
259263
process.exit(0)
260-
261264
}
262265
//Errors
263266
catch (error) {
264267
console.error(error)
265-
if (!bool(core.getInput("debug")))
268+
if (!input.bool("debug"))
266269
for (const log of ["─".repeat(64), "An error occured, logging debug message :", ...debugged])
267270
console.log(log)
268271
core.setFailed(error.message)

0 commit comments

Comments
 (0)