diff --git a/action.yml b/action.yml index 656a494a..9d8e5383 100644 --- a/action.yml +++ b/action.yml @@ -8,35 +8,35 @@ inputs: base: description: Base content - default: header, activity, community, repositories, metadata + default: repositories: description: Repositories to fetch - default: 100 + default: repositories_batch: description: Repositories to fetch at a time - default: 100 + default: repositories_forks: description: Include forks - default: no + default: repositories_affiliations: description: Repositories affiliations - default: owner + default: repositories_skipped: description: Default skipped repositories - default: "" + default: users_ignored: description: Default ignored users - default: github-actions[bot], dependabot[bot], dependabot-preview[bot] + default: commits_authoring: description: Identifiers that has been used for authoring commits - default: .user.login + default: # ==================================================================================== # 🧱 Core @@ -47,446 +47,441 @@ inputs: user: description: GitHub username - default: "" + default: repo: description: GitHub repository - default: "" + default: committer_token: description: GitHub Token used to commit metrics - default: ${{ github.token }} + default: committer_branch: description: Target branch - default: "" + default: committer_message: description: Commit message - default: Update ${filename} - [Skip GitHub Action] + default: committer_gist: description: Gist id - default: "" + default: filename: description: Output path - default: github-metrics.* + default: markdown: description: Markdown template path - default: TEMPLATE.md + default: markdown_cache: description: Markdown file cache - default: .cache + default: output_action: description: Output action - default: commit + default: output_condition: description: Output condition optimize: description: Optimization features - default: css, xml + default: setup_community_templates: description: Community templates to setup - default: "" + default: template: description: Template - default: classic + default: query: description: Query parameters - default: "{}" + default: extras_css: description: Extra CSS - default: "" + default: extras_js: description: Extra JavaScript - default: "" + default: config_timezone: description: Timezone for dates - default: "" + default: config_order: description: Plugin order - default: "" + default: config_twemoji: description: Use twemojis - default: no + default: config_gemoji: description: Use GitHub custom emojis - default: yes + default: config_display: description: Display width (for image output formats) - default: regular + default: config_animations: description: Use CSS animations - default: yes + default: config_base64: description: Base64-encoded images - default: yes + default: config_padding: description: Output padding - default: 0, 8 + 11% + default: config_output: description: Output format - default: auto + default: config_presets: description: Configuration presets - default: "" + default: retries: description: Retries in case of failures (for rendering) - default: 3 + default: retries_delay: description: Delay between each retry (in seconds, for rendering) - default: 300 + default: retries_output_action: description: Retries in case of failures (for output action) - default: 5 + default: retries_delay_output_action: description: Delay between each retry (in seconds, for output action) - default: 120 + default: delay: description: Job delay - default: 0 + default: use_prebuilt_image: description: >- Use pre-built docker image from [GitHub container registry](https://github.com/lowlighter/metrics/pkgs/container/metrics) - default: yes + default: plugins_errors_fatal: description: Fatal plugin errors - default: no + default: debug: description: Debug mode - default: no + default: verify: description: SVG validity check - default: no + default: debug_flags: description: Debug flags - default: "" + default: dryrun: description: Dry-run - default: no + default: experimental_features: description: Experimental features - default: "" + default: use_mocked_data: description: Use mocked data instead of live APIs - default: no + default: # ==================================================================================== # 📅 Isometric commit calendar plugin_isocalendar: description: Enable isocalendar plugin - default: no + default: plugin_isocalendar_duration: description: Time range - default: half-year + default: # ==================================================================================== # 🈷️ Most used languages plugin_languages: description: Enable languages plugin - default: no + default: plugin_languages_ignored: description: Ignored languages - default: "" + default: plugin_languages_skipped: description: Skipped repositories - default: "" + default: plugin_languages_limit: description: Display limit - default: 8 + default: plugin_languages_threshold: description: Display threshold (percentage) - default: 0% + default: plugin_languages_colors: description: Custom languages colors - default: github + default: plugin_languages_aliases: description: Custom languages names - default: "" + default: plugin_languages_sections: description: Displayed sections - default: most-used + default: plugin_languages_details: description: Additional details - default: "" + default: plugin_languages_indepth: description: Indepth mode (⚠️ read documentation first) - default: false + default: plugin_languages_analysis_timeout: description: Indepth mode - Analysis timeout - default: 15 + default: plugin_languages_categories: description: Indepth mode - Displayed categories (most-used section) - default: markup, programming + default: plugin_languages_recent_categories: description: Indepth mode - Displayed categories (recently-used section) - default: markup, programming + default: plugin_languages_recent_load: description: Events to load (recently-used section) - default: 300 + default: plugin_languages_recent_days: description: Events maximum age (day, recently-used section) - default: 14 + default: # ==================================================================================== # 📌 Starred topics plugin_topics: description: Enable topics plugin - default: no + default: plugin_topics_mode: description: "Display mode:" - default: starred + default: plugin_topics_sort: description: "Sorting method:" - default: stars + default: plugin_topics_limit: description: Display limit - default: 15 + default: # ==================================================================================== # 🌟 Recently starred repositories plugin_stars: description: Enable stars plugin - default: no + default: plugin_stars_limit: description: Display limit - default: 4 + default: # ==================================================================================== # 📜 Repository licenses plugin_licenses: description: Enable licenses plugin - default: no + default: plugin_licenses_setup: description: Setup command - default: "" + default: plugin_licenses_ratio: description: Display used licenses ratio - default: no + default: plugin_licenses_legal: description: Display permissions, limitations and conditions about licenses - default: yes + default: # ==================================================================================== # 💡 Coding habits plugin_habits: description: Enable habits plugin - default: no + default: plugin_habits_from: description: Events to use - default: 200 + default: plugin_habits_days: description: Event maximum age - default: 14 + default: plugin_habits_facts: description: Toggle midly interesting facts display - default: yes + default: plugin_habits_charts: description: Toggle charts display - default: no + default: plugin_habits_trim: description: Trim unused hours on charts - default: no + default: # ==================================================================================== # 🏅 Repository contributors plugin_contributors: description: Enable contributors plugin - default: no + default: plugin_contributors_base: description: Base reference (commit, tag, branch, etc.) - default: "" + default: plugin_contributors_head: description: Head reference (commit, tag, branch, etc.) - default: master + default: plugin_contributors_ignored: description: Ignored users - default: "" + default: plugin_contributors_contributions: description: Toggle number of contributions display - default: no + default: plugin_contributors_sections: description: Displayed sections - default: contributors + default: plugin_contributors_categories: description: Configure contribution categories - default: | - { - "📚 Documentation": ["README.md", "docs/**"], - "💻 Code": ["source/**", "src/**"], - "#️⃣ Others": ["*"] - } + default: # ==================================================================================== # 🎟️ Follow-up of issues and pull requests plugin_followup: description: Enable followup plugin - default: no + default: plugin_followup_sections: description: Displayed sections - default: repositories + default: plugin_followup_indepth: description: Indepth analysis - default: no + default: # ==================================================================================== # 🎭 Comment reactions plugin_reactions: description: Enable reactions plugin - default: no + default: plugin_reactions_limit: description: Display limit (issues and pull requests comments) - default: 200 + default: plugin_reactions_limit_issues: description: Display limit (issues and pull requests, first comment) - default: 100 + default: plugin_reactions_limit_discussions: description: Display limit (discussions, first comment) - default: 100 + default: plugin_reactions_limit_discussions_comments: description: Display limit (discussions comments) - default: 100 + default: plugin_reactions_days: description: Comments maximum age - default: 0 + default: plugin_reactions_display: description: Display mode - default: absolute + default: plugin_reactions_details: description: Additional details - default: "" + default: plugin_reactions_ignored: description: Ignored users - default: "" + default: # ==================================================================================== # 🧑‍🤝‍🧑 People plugin plugin_people: description: Enable people plugin - default: no + default: plugin_people_limit: description: Display limit - default: 24 + default: plugin_people_identicons: description: Toggle identicons display - default: no + default: plugin_people_size: description: Profile picture display size - default: 28 + default: plugin_people_types: description: Displayed sections (order is respected) - default: followers, following + default: plugin_people_thanks: description: Special thanks - default: "" + default: plugin_people_sponsors_custom: description: Custom sponsors - default: "" + default: plugin_people_shuffle: description: Shuffle data for varied output - default: no + default: # ==================================================================================== # ✨ Stargazers over last weeks plugin_stargazers: description: Enable stargazers plugin - default: no + default: plugin_stargazers_charts_type: description: Charts display type @@ -497,497 +492,497 @@ inputs: plugin_projects: description: Enable projects plugin - default: no + default: plugin_projects_limit: description: Display limit - default: 4 + default: plugin_projects_repositories: description: List of repositories projects - default: "" + default: plugin_projects_descriptions: description: Toggle projects descriptions display - default: no + default: # ==================================================================================== # ♐ Code snippet of the day plugin_code: description: Enable code plugin - default: no + default: plugin_code_lines: description: Display limit for code snippets - default: 12 + default: plugin_code_load: description: Events to load - default: 100 + default: plugin_code_visibility: description: Events visibility - default: public + default: plugin_code_skipped: description: Skipped repositories - default: "" + default: plugin_code_languages: description: Restrict display to specific languages - default: "" + default: # ==================================================================================== # 📰 Recent activity plugin_activity: description: Enable activity plugin - default: no + default: plugin_activity_limit: description: Display limit - default: 5 + default: plugin_activity_load: description: Events to load - default: 300 + default: plugin_activity_days: description: Events maximum age - default: 14 + default: plugin_activity_visibility: description: Events visibility - default: all + default: plugin_activity_timestamps: description: Display events timestamps - default: no + default: plugin_activity_skipped: description: Skipped repositories - default: "" + default: plugin_activity_ignored: description: Ignored users - default: "" + default: plugin_activity_filter: description: Events types - default: all + default: # ==================================================================================== # 🏆 Achievements plugin_achievements: description: Enable achievements plugin - default: no + default: plugin_achievements_threshold: description: Display rank threshold - default: C + default: plugin_achievements_secrets: description: Display secrets achievements - default: yes + default: plugin_achievements_display: description: Display style - default: detailed + default: plugin_achievements_limit: description: Display limit - default: 0 + default: plugin_achievements_ignored: description: Hide specified achievements - default: "" + default: plugin_achievements_only: description: Restrict display to specified achievements - default: "" + default: # ==================================================================================== # 🎩 Notable contributions plugin_notable: description: Enable notable plugin - default: no + default: plugin_notable_filter: description: Query filter - default: "" + default: plugin_notable_skipped: description: Skipped repositories - default: "" + default: plugin_notable_from: description: Filter by repository owner account type - default: organization + default: plugin_notable_repositories: description: Toggle repository name display - default: no + default: plugin_notable_indepth: description: Indepth mode - default: no + default: # ==================================================================================== # 💬 Discussions plugin_discussions: description: Enable discussions plugin - default: no + default: plugin_discussions_categories: description: Toggle discussion categories display - default: yes + default: plugin_discussions_categories_limit: description: Display limit (categories) - default: 0 + default: # ==================================================================================== # 💭 GitHub Community Support plugin_support: description: Enable support plugin - default: no + default: # ==================================================================================== # 👨‍💻 Lines of code changed plugin_lines: description: Enable lines plugin - default: no + default: plugin_lines_skipped: description: Skipped repositories - default: "" + default: # ==================================================================================== # 🧮 Repositories traffic plugin_traffic: description: Enable traffic plugin - default: no + default: plugin_traffic_skipped: description: Skipped repositories - default: "" + default: # ==================================================================================== # 📓 Repositories plugin_repositories: description: Enable repositories plugin - default: no + default: plugin_repositories_featured: description: List of featured repositories - default: "" + default: # ==================================================================================== # 🎫 Gists plugin_gists: description: Enable gists plugin - default: no + default: # ==================================================================================== # 🙋 Introduction plugin_introduction: description: Display account or repository introduction - default: no + default: plugin_introduction_title: description: Display introduction section title - default: yes + default: # ==================================================================================== # 💕 GitHub Sponsors plugin_sponsors: description: Enable sponsors plugin - default: no + default: plugin_sponsors_sections: description: Displayed sections - default: goal, about + default: # ==================================================================================== # 💫 Starlists plugin_starlists: description: Enable starlists plugin - default: no + default: plugin_starlists_limit: description: Display limit (star lists) - default: 2 + default: plugin_starlists_limit_repositories: description: Display limit (repositories per star list) - default: 2 + default: plugin_starlists_shuffle_repositories: description: Shuffle data for varied outputs - default: yes + default: plugin_starlists_ignored: description: Skipped star lists - default: "" + default: plugin_starlists_only: description: Restrict display to specified star lists - default: "" + default: # ==================================================================================== # 🌇 GitHub Skyline 3D calendar plugin_skyline: description: Enable skyline plugin - default: no + default: plugin_skyline_year: description: Displayed year - default: current-year + default: plugin_skyline_frames: description: Frames count - default: 60 + default: plugin_skyline_quality: description: Image quality - default: 0.5 + default: plugin_skyline_compatibility: description: Compatibility mode - default: no + default: # ==================================================================================== # ⏱️ Website performances plugin_pagespeed: description: Enable pagespeed plugin - default: no + default: plugin_pagespeed_url: description: Audited website - default: .user.website + default: plugin_pagespeed_detailed: description: Detailed results - default: no + default: plugin_pagespeed_screenshot: description: Display a website screenshot - default: no + default: plugin_pagespeed_token: description: PageSpeed token - default: "" + default: # ==================================================================================== # 🎼 Music plugin plugin_music: description: Enable music plugin - default: no + default: plugin_music_provider: description: Music provider - default: "" + default: plugin_music_token: description: Music provider token - default: "" + default: plugin_music_mode: description: Display mode - default: "" + default: plugin_music_playlist: description: Playlist URL - default: "" + default: plugin_music_limit: description: Display limit - default: 4 + default: plugin_music_played_at: description: Recently played - Toggle last played timestamp display - default: no + default: plugin_music_time_range: description: Top tracks - Time range for `top` mode - default: short + default: plugin_music_top_type: description: Top tracks - Display type - default: tracks + default: plugin_music_user: description: Music provider username - default: .user.login + default: # ==================================================================================== # 🗨️ StackOverflow plugin plugin_stackoverflow: description: Enable stackoverflow plugin - default: no + default: plugin_stackoverflow_user: description: Stackoverflow user id - default: 0 + default: plugin_stackoverflow_sections: description: Displayed sections - default: answers-top, questions-recent + default: plugin_stackoverflow_limit: description: Display limit (per section) - default: 2 + default: plugin_stackoverflow_lines: description: Display limit for questions and answers - default: 4 + default: plugin_stackoverflow_lines_snippet: description: Display limit for code snippets - default: 2 + default: # ==================================================================================== # 🌸 Anilist watch list and reading list plugin_anilist: description: Enable aniList plugin - default: no + default: plugin_anilist_medias: description: Display medias types - default: anime, manga + default: plugin_anilist_sections: description: Displayed sections - default: favorites + default: plugin_anilist_limit: description: Display limit (medias) - default: 2 + default: plugin_anilist_limit_characters: description: Display limit (characters) - default: 22 + default: plugin_anilist_shuffle: description: Shuffle data for varied outputs - default: yes + default: plugin_anilist_user: description: AniList login - default: .user.login + default: # ==================================================================================== # 🐤 Latest tweets plugin_tweets: description: Enable tweets plugin - default: no + default: plugin_tweets_token: description: Twitter API token - default: "" + default: plugin_tweets_attachments: description: Display tweets attachments (images, video previews, etc.) - default: no + default: plugin_tweets_limit: description: Display limit - default: 2 + default: plugin_tweets_user: description: Twitter username - default: .user.twitter + default: # ==================================================================================== # ✒️ Recent posts plugin_posts: description: Enable posts plugin - default: no + default: plugin_posts_source: description: External source - default: "" + default: plugin_posts_descriptions: description: Toggle posts descriptions display - default: no + default: plugin_posts_covers: description: Toggle posts cover images display - default: no + default: plugin_posts_limit: description: Display limit - default: 4 + default: plugin_posts_user: description: External source username - default: .user.login + default: # ==================================================================================== # 🗼 Rss feed plugin_rss: description: Enable rss plugin - default: no + default: plugin_rss_source: description: RSS feed source - default: "" + default: plugin_rss_limit: description: Display limit - default: 4 + default: # ==================================================================================== # ⏰ WakaTime plugin plugin_wakatime: description: Enable wakatime plugin - default: no + default: plugin_wakatime_token: description: WakaTime API token - default: "" + default: plugin_wakatime_days: description: Time range - default: 7 + default: plugin_wakatime_sections: description: Displayed sections - default: time, projects, projects-graphs, languages, languages-graphs, editors, os + default: plugin_wakatime_limit: description: Display limit (per graph) - default: 5 + default: plugin_wakatime_url: description: WakaTime url - default: https://wakatime.com + default: plugin_wakatime_user: description: WakaTime username - default: current + default: # ==================================================================================== # 🥠 Fortune @@ -1001,92 +996,92 @@ inputs: plugin_nightscout: description: Enable nightscout plugin - default: no + default: plugin_nightscout_url: description: Nightscout URL - default: https://example.herokuapp.com + default: plugin_nightscout_datapoints: description: Number of datapoints shown the graph - default: 12 + default: plugin_nightscout_lowalert: description: Threshold for low blood sugar - default: 80 + default: plugin_nightscout_highalert: description: Threshold for high blood sugar - default: 180 + default: plugin_nightscout_urgentlowalert: description: Threshold for urgently low blood sugar - default: 50 + default: plugin_nightscout_urgenthighalert: description: Threshold for urgently high blood sugar - default: 250 + default: # ==================================================================================== # 💩 PoopMap plugin plugin_poopmap: description: Enable poopmap plugin - default: no + default: plugin_poopmap_token: description: PoopMap API token - default: "" + default: plugin_poopmap_days: description: Time range - default: 7 + default: # ==================================================================================== # 📸 Website screenshot plugin_screenshot: description: Enable screenshot plugin - default: no + default: plugin_screenshot_title: description: Title caption - default: Screenshot + default: plugin_screenshot_url: description: Website url - default: "" + default: plugin_screenshot_selector: description: CSS Selector - default: body + default: plugin_screenshot_background: description: Display background - default: yes + default: # ==================================================================================== # 💹 Stock prices plugin_stock: description: Enable stock plugin - default: no + default: plugin_stock_token: description: Yahoo Finance token - default: "" + default: plugin_stock_symbol: description: Company stock symbol - default: "" + default: plugin_stock_duration: description: Time range (relative to current date) - default: 1d + default: plugin_stock_interval: description: Time interval between points - default: 5m + default: # ==================================================================================== diff --git a/source/app/action/index.mjs b/source/app/action/index.mjs index 391c084b..73abe773 100644 --- a/source/app/action/index.mjs +++ b/source/app/action/index.mjs @@ -9,6 +9,7 @@ import sgit from "simple-git" import mocks from "../../../tests/mocks/index.mjs" import metrics from "../metrics/index.mjs" import setup from "../metrics/setup.mjs" +import presets from "../metrics/presets.mjs" process.on("unhandledRejection", error => { throw error }) @@ -17,6 +18,9 @@ process.on("unhandledRejection", error => { let DEBUG = true const debugged = [] +//Preset +const preset = {} + //Info logger const info = (left, right, {token = false} = {}) => console.log(`${`${left}`.padEnd(63 + 9 * (/0m$/.test(left)))} │ ${ Array.isArray(right) @@ -33,7 +37,7 @@ info.section = (left = "", right = " ") => info(`\x1b[36m${left}\x1b[0m`, right) info.group = ({metadata, name, inputs}) => { info.section(metadata.plugins[name]?.name?.match(/(?
[\w\s]+)/i)?.groups?.section?.trim(), " ") for (const [input, value] of Object.entries(inputs)) - info(metadata.plugins[name]?.inputs[input]?.description?.split("\n")[0] ?? metadata.plugins[name]?.inputs[input]?.description ?? input, value, {token:metadata.plugins[name]?.inputs[input]?.type === "token"}) + info(metadata.plugins[name]?.inputs[input]?.description?.split("\n")[0] ?? metadata.plugins[name]?.inputs[input]?.description ?? input, `${input in preset ? "*" : ""}${value}`, {token:metadata.plugins[name]?.inputs[input]?.type === "token"}) } info.break = () => console.log("─".repeat(88)) @@ -91,6 +95,7 @@ async function retry(func, {retries = 1, delay = 0} = {}) { info("Version", conf.package.version) //Core inputs + Object.assign(preset, await presets(core.getInput("config_presets"), {log:true, core})) const { user:_user, repo:_repo, @@ -120,7 +125,7 @@ async function retry(func, {retries = 1, delay = 0} = {}) { "output.condition":_output_condition, delay, ...config - } = metadata.plugins.core.inputs.action({core}) + } = metadata.plugins.core.inputs.action({core, preset}) const q = {...query, ...(_repo ? {repo:_repo} : null), template} const _output = ["svg", "jpeg", "png", "json", "markdown", "markdown-pdf", "insights"].includes(config["config.output"]) ? config["config.output"] : metadata.templates[template].formats[0] ?? null const filename = _filename.replace(/[*]/g, {jpeg:"jpg", markdown:"md", "markdown-pdf":"pdf", insights:"html"}[_output] ?? _output) @@ -293,7 +298,7 @@ async function retry(func, {retries = 1, delay = 0} = {}) { //Base content info.break() - const {base:parts, repositories:_repositories, ...base} = metadata.plugins.base.inputs.action({core}) + const {base:parts, repositories:_repositories, ...base} = metadata.plugins.base.inputs.action({core, preset}) conf.settings.repositories = _repositories info.group({metadata, name:"base", inputs:{repositories:conf.settings.repositories, ...base}}) info("Base sections", parts) @@ -306,7 +311,7 @@ async function retry(func, {retries = 1, delay = 0} = {}) { const plugins = {} for (const name of Object.keys(Plugins).filter(key => !["base", "core"].includes(key))) { //Parse inputs - const {[name]:enabled, ...inputs} = metadata.plugins[name].inputs.action({core}) + const {[name]:enabled, ...inputs} = metadata.plugins[name].inputs.action({core, preset}) plugins[name] = {enabled} //Register user inputs if (enabled) { diff --git a/source/app/metrics/metadata.mjs b/source/app/metrics/metadata.mjs index f21ddc57..d5bd5cb2 100644 --- a/source/app/metrics/metadata.mjs +++ b/source/app/metrics/metadata.mjs @@ -228,17 +228,34 @@ metadata.plugin = async function({__plugins, __templates, name, logger}) { key, { comment:comments[key] ?? `# ${value.description}`, - descriptor:yaml.dump({[key]:Object.fromEntries(Object.entries(value).filter(([key]) => ["description", "default", "required"].includes(key)).map(([k, v]) => k === "description" ? [k, v.split("\n")[0]] : [k, v]))}, {quotingType:'"', noCompatMode:true}), + descriptor:yaml.dump({[key]:Object.fromEntries(Object.entries(value).filter(([key]) => ["description", "default", "required"].includes(key)).map(([k, v]) => k === "description" ? [k, v.split("\n")[0]] : k === "default" ? [k, ""] : [k, v]))}, {quotingType:'"', noCompatMode:true}), }, ]), ) //Action inputs - meta.inputs.action = function({core}) { + meta.inputs.action = function({core, preset = {}}) { //Build query object from inputs const q = {} for (const key of Object.keys(inputs)) { - const value = `${core.getInput(key)}`.trim() + const unspecified = process.env[`INPUT_${key.replace(/ /g, "_").toUpperCase()}`] === "" + let value + //From presets + if ((key in preset)&&(unspecified)) { + logger(`metrics/inputs > ${key} has been set by preset value`) + q[key] = preset[key] + continue + } + //From defaults + else if (unspecified) { + logger(`metrics/inputs > ${key} has been set by default value`) + value = metadata.inputs[key]?.default + } + //From user + else { + logger(`metrics/inputs > ${key} has been set by user`) + value = `${core.getInput(key)}`.trim() + } try { q[key] = decodeURIComponent(value) }