diff --git a/action.yml b/action.yml index a1c037d003f..731c872334b 100644 --- a/action.yml +++ b/action.yml @@ -807,6 +807,10 @@ inputs: description: Skipped repositories default: + plugin_notable_organizations_skipped: + description: Skipped organizations + default: + plugin_notable_from: description: Repository owner account type filter default: diff --git a/source/app/metrics/utils.mjs b/source/app/metrics/utils.mjs index f210b9e8f10..23f78adf83d 100644 --- a/source/app/metrics/utils.mjs +++ b/source/app/metrics/utils.mjs @@ -417,6 +417,43 @@ export const filters = { console.debug(`metrics/filters/repo > filter ${repo} (${include ? "included" : "excluded"})`) return include }, + /**Organization filter (exclusion list, same semantics as repo) */ + organization(organizationLogin, patterns, {debug = true} = {}) { + if (!patterns.length) + return true + + const org = `${organizationLogin}`.toLocaleLowerCase() + + let include = true + if (patterns[0] === "@use.patterns") { + if (debug) + console.debug(`metrics/filters/organization > ${org} > using advanced pattern matching`) + const options = {nocase: true} + for (let pattern of patterns) { + if (pattern.startsWith("#")) + continue + let action = false + if ((pattern.startsWith("+")) || (pattern.startsWith("-"))) { + action = pattern.charAt(0) === "+" + pattern = pattern.substring(1) + } + if (minimatch(org, pattern, options)) { + if (debug) + console.debug(`metrics/filters/organization > ${org} matches ${action ? "including" : "excluding"} pattern ${pattern}`) + include = action + } + } + } + else { + if (debug) + console.debug(`metrics/filters/organization > ${org} > using basic pattern matching`) + include = !patterns.includes(org) + } + + if (debug) + console.debug(`metrics/filters/organization > filter ${org} (${include ? "included" : "excluded"})`) + return include + }, /**Text filter*/ text(text, patterns, {debug = true} = {}) { //Disable filtering when no pattern is provided diff --git a/source/plugins/notable/README.md b/source/plugins/notable/README.md index c57c48c2f4e..69f70002d48 100644 --- a/source/plugins/notable/README.md +++ b/source/plugins/notable/README.md @@ -67,6 +67,17 @@ Some repositories may not be able to reported advanced stats and in the case the type: array (newline-separated)
+ + +

plugin_notable_organizations_skipped

+

Skipped organizations. Exclude contributions from these organizations in both badges and repository lists. Supports the same pattern syntax as plugin_notable_skipped (basic and @use.patterns with minimatch for wildcards, e.g. org-*).

+ + + + type: array +(newline-separated) +
+default: ""

plugin_notable_from

@@ -159,6 +170,19 @@ with: base: "" plugin_notable: yes +``` +```yaml +name: Contributions (excluding organizations) +uses: lowlighter/metrics@latest +with: + filename: metrics.plugin.notable.svg + token: ${{ secrets.METRICS_TOKEN }} + base: "" + plugin_notable: yes + plugin_notable_organizations_skipped: | + my-org + other-org + ``` ```yaml name: Indepth analysis diff --git a/source/plugins/notable/index.mjs b/source/plugins/notable/index.mjs index c9adc3b7d0f..488a7cb7bb2 100644 --- a/source/plugins/notable/index.mjs +++ b/source/plugins/notable/index.mjs @@ -7,7 +7,7 @@ export default async function({login, q, imports, rest, graphql, data, account, return null //Load inputs - let {filter, skipped, repositories, types, from, indepth, self} = imports.metadata.plugins.notable.inputs({data, account, q}) + let {filter, skipped, "organizations.skipped": organizationsSkipped = [], repositories, types, from, indepth, self} = imports.metadata.plugins.notable.inputs({data, account, q}) skipped.push(...data.shared["repositories.skipped"]) //Iterate through contributed repositories @@ -21,6 +21,7 @@ export default async function({login, q, imports, rest, graphql, data, account, cursor = edges?.[edges?.length - 1]?.cursor edges .filter(({node}) => imports.filters.repo(node, skipped)) + .filter(({node}) => !node.isInOrganization || imports.filters.organization(node.owner.login, organizationsSkipped)) .filter(({node}) => ({all: true, organization: node.isInOrganization, user: !node.isInOrganization}[from])) .filter(({node}) => imports.filters.github(filter, {name: node.nameWithOwner, user: node.owner.login, stars: node.stargazers.totalCount, watchers: node.watchers.totalCount, forks: node.forks.totalCount})) .map(({node}) => contributions.push({handle: node.nameWithOwner, stars: node.stargazers.totalCount, issues: node.issues.totalCount, pulls: node.pullRequests.totalCount, organization: node.isInOrganization, avatarUrl: node.owner.avatarUrl})) diff --git a/source/plugins/notable/metadata.yml b/source/plugins/notable/metadata.yml index f1004fa8e12..8183246eb56 100644 --- a/source/plugins/notable/metadata.yml +++ b/source/plugins/notable/metadata.yml @@ -42,6 +42,19 @@ inputs: example: my-repo-1, my-repo-2, owner/repo-3, ... inherits: repositories_skipped + plugin_notable_organizations_skipped: + description: | + Skipped organizations + + Exclude contributions from these organizations in both badges and repository lists. + Supports the same pattern syntax as [`plugin_notable_skipped`](/source/plugins/notable/README.md#plugin_notable_skipped) (basic and `@use.patterns` with minimatch for wildcards, e.g. `org-*`). + type: array + format: + - newline-separated + - comma-separated + default: "" + example: my-org, other-org, ... + plugin_notable_from: description: | Repository owner account type filter