diff --git a/netlify/functions/metrics.ts b/netlify/functions/metrics.ts index 84737a8..8abf3a6 100644 --- a/netlify/functions/metrics.ts +++ b/netlify/functions/metrics.ts @@ -7,7 +7,7 @@ const handler: Handler = async (event: HandlerEvent) => { try { const eventSignature = event.headers["x-github-event"] || "unknown"; const body = getEventBody(event); - await collectMetricsHandler({ ...body, eventSignature }); + await collectMetricsHandler({ eventSignature, ...body }); return { statusCode: 200, body: "success", diff --git a/package-lock.json b/package-lock.json index 94c40d0..b10b46d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "@deven-org/telemetry-functions", - "version": "1.2.0", + "version": "1.1.0", "license": "MIT", "dependencies": { "@netlify/functions": "^1.4.0", @@ -22366,6 +22366,7 @@ "node_modules/netlify-cli/node_modules/unix-dgram": { "version": "2.0.6", "dev": true, + "hasInstallScript": true, "license": "ISC", "optional": true, "dependencies": { diff --git a/src/__tests__/handler.test.ts b/src/__tests__/handler.test.ts index 8a0f0ae..c2947b8 100644 --- a/src/__tests__/handler.test.ts +++ b/src/__tests__/handler.test.ts @@ -1,32 +1,99 @@ +import * as moduleAddSignature from "../core/addSignature"; +import * as moduleCollectMetrics from "../core/collectMetrics"; +import * as moduleStoreData from "../core/storeData"; import { handler } from "../handler"; -import mergedCompletedSuccessfully from "./fixtures/merged-completed-successful.json"; +import { logger } from "../core/logger"; +import { DataEventSignature } from "../interfaces"; +import { LogErrors, LogWarnings } from "../shared/logMessages"; -describe("Handler", () => { - beforeEach(() => {}); +jest.mock("../core/logger", () => ({ + __esModule: true, + logger: { + start: jest.fn(), + config: jest.fn(), + info: jest.fn(), + warning: jest.fn(), + error: jest.fn(), + complete: jest.fn(), + }, +})); - afterEach(() => {}); +const spyOnAddSignature = jest.spyOn(moduleAddSignature, "addSignature"); +const spyOnCollectMetrics = jest.spyOn(moduleCollectMetrics, "collectMetrics"); +const spyOnStoreData = jest.spyOn(moduleCollectMetrics, "collectMetrics"); - it.only("returns the payload enhanced with relative matrix", async () => { - const data = { - signature: "packages", +describe("handler", () => { + it("calls addSignature passing the given event payload", async () => { + const event = { foo: "foo", bar: "bar", + eventSignature: "toolingUsage", }; - const output = await handler(data); + await handler(event); + expect(spyOnAddSignature).toBeCalledWith({ + bar: "bar", + foo: "foo", + eventSignature: "toolingUsage", + }); + }); + it("calls collectMetrics passing a signed event, given that the event is known", async () => { + const event = { + foo: "foo", + bar: "bar", + eventSignature: "toolingUsage", + }; + + await handler(event); - expect(output).toMatchObject({ + expect(spyOnCollectMetrics).toBeCalledWith({ created_at: expect.any(Number), - output: data, - dataEventSignature: "packages", + dataEventSignature: "deven-tooling-usage", + owner: "", + repo: "", + output: {}, + payload: { + foo: "foo", + bar: "bar", + eventSignature: "toolingUsage", + }, }); }); - it("...", async () => { - const output = await handler(mergedCompletedSuccessfully); + it("doesn't call collectMetrics if the event is unknown", async () => { + const event = { + foo: "foo", + bar: "bar", + eventSignature: "foo", + }; + + await handler(event); + + expect(spyOnCollectMetrics).not.toBeCalled(); + expect(logger.warning).toBeCalledWith( + LogWarnings.signingEventSignatureNotRecognized + ); + }); + + it("calls storeData passing an enhanced data event, given that the metrics can be collects", async () => { + const event = { + foo: "foo", + bar: "bar", + eventSignature: "toolingUsage", + }; + + await handler(event); - expect(output).toMatchObject({ + expect(spyOnStoreData).toBeCalledWith({ created_at: expect.any(Number), - dataEventSignature: "merged-pr", + dataEventSignature: "deven-tooling-usage", + output: {}, + owner: "", + payload: { + bar: "bar", + eventSignature: "toolingUsage", + foo: "foo", + }, + repo: "", }); }); }); diff --git a/src/__tests__/setup.js b/src/__tests__/setup.js index b0fbbf4..f5255f7 100644 --- a/src/__tests__/setup.js +++ b/src/__tests__/setup.js @@ -2,11 +2,11 @@ const dotenv = require("dotenv"); global.console = { ...console, - //log: jest.fn(), + // log: jest.fn(), debug: jest.fn(), info: jest.fn(), warn: jest.fn(), - error: jest.fn(), + // error: jest.fn(), }; dotenv.config({ path: ".test.env" }); diff --git a/src/core/addSignature.ts b/src/core/addSignature.ts index ae08d14..ce96985 100644 --- a/src/core/addSignature.ts +++ b/src/core/addSignature.ts @@ -1,9 +1,7 @@ -import { createDataEvent, Errors, getRejectionReason, logger } from "."; -import { cond, T, always, pipe, clone } from "ramda"; -import { isWorkflowJobCompleted } from "./signingConditions"; -import { LogInfos } from "../shared/logMessages"; +import { createDataEvent, getRejectionReason, logger } from "."; +import { cond, pipe, clone, T, always } from "ramda"; +import { LogInfos, LogWarnings } from "../shared/logMessages"; import { DataEventSignature, DataEvent } from "../interfaces"; -import { isPullRequestClosed } from "../metrics/pull_requests/signatureConditions"; import signatureConditions from "../signatureConditions"; const createSignedDataEvent = @@ -14,25 +12,29 @@ const createSignedDataEvent = dataEventSignature: signature, output: {}, payload: data, + owner: "", + repo: "", }); }; -const signDataEvent = cond( - signatureConditions.map((cond) => [ - cond[0], - createSignedDataEvent(cond[1] as DataEventSignature), - ]) -); +const signDataEvent = cond([ + ...signatureConditions.map((item) => [ + item[0], + createSignedDataEvent(item[1]), + ]), + [T, always(false)], +]); export const addSignature = (data: any): Promise => { return new Promise((res, rej) => { const signedDataEvent = pipe(clone, signDataEvent)(data); + signedDataEvent ? res(signedDataEvent) : rej( getRejectionReason({ - level: "warn", - message: Errors.signingEventSignatureNotRecognized, + level: "warning", + message: LogWarnings.signingEventSignatureNotRecognized, }) ); }); diff --git a/src/metrics/collectMetrics.ts b/src/core/collectMetrics.ts similarity index 76% rename from src/metrics/collectMetrics.ts rename to src/core/collectMetrics.ts index 29f1cf3..4ca9288 100644 --- a/src/metrics/collectMetrics.ts +++ b/src/core/collectMetrics.ts @@ -1,13 +1,14 @@ -import { getRejectionReason } from "../core"; -import { logger } from "../core/logger"; -import { cond, clone, pipe, omit } from "ramda"; +import { getRejectionReason } from "."; +import { logger } from "./logger"; +import { cond, clone, pipe, omit, T, always } from "ramda"; import metricsConditions from "../metricsConditions"; import { LogErrors, LogInfos } from "../shared/logMessages"; import { DataEvent, EnhancedDataEvent } from "../interfaces"; const collectMetricsBySignature = cond( - metricsConditions.map((cond) => [cond[0], cond[1]]) + [metricsConditions.map((cond) => [cond[0], cond[1]])], + [T, always(false)] ); export const collectMetrics = async ( diff --git a/src/core/errorCatcher.ts b/src/core/errorCatcher.ts index 2a466f5..6890176 100644 --- a/src/core/errorCatcher.ts +++ b/src/core/errorCatcher.ts @@ -1,12 +1,7 @@ import { logger } from "./logger"; -export enum Errors { - collectMetricsSignatureNotRecognized = "The signature of the data event is not recognized.", - signingEventSignatureNotRecognized = "Can't identify the signature of the data event. Skipping.", -} - export interface ErrorForCatcher { - level: "error" | "warn"; + level: "error" | "warning"; message: string; } diff --git a/src/handler.ts b/src/handler.ts index cc33017..b292516 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -1,4 +1,4 @@ -import { collectMetrics } from "./metrics/collectMetrics"; +import { collectMetrics } from "./core/collectMetrics"; import { storeData, errorCatcher } from "./core"; import { logger } from "./core/logger"; import { pipeWith, tap } from "ramda"; diff --git a/src/interfaces.ts b/src/interfaces.ts index ad59eef..722dd2f 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -2,22 +2,32 @@ import { PullRequestClosedPayload, PullRequestClosedOutput, } from "./metrics/pull_requests/interfaces"; +import { + ToolingUsageOutput, + ToolingUsagePayload, +} from "./metrics/tooling_usage/interfaces"; -import { WorkflowJobCompletedPayload } from "./metrics/workflows/interfaces"; +import { + WorkflowJobCompletedOutput, + WorkflowJobCompletedPayload, +} from "./metrics/workflows/interfaces"; export enum DataEventSignature { PullRequestClosed = "pull_request-completed", WorkflowJobCompleted = "workflow-job-completed", + ToolingUsage = "deven-tooling-usage", } interface DataEventPayloadMap { [DataEventSignature.PullRequestClosed]: PullRequestClosedPayload; [DataEventSignature.WorkflowJobCompleted]: WorkflowJobCompletedPayload; + [DataEventSignature.ToolingUsage]: ToolingUsagePayload; } interface DataEventOutputMap { [DataEventSignature.PullRequestClosed]: PullRequestClosedOutput; - [DataEventSignature.WorkflowJobCompleted]: WorkflowJobCompletedPayload; + [DataEventSignature.WorkflowJobCompleted]: WorkflowJobCompletedOutput; + [DataEventSignature.ToolingUsage]: ToolingUsageOutput; } export type EnhancedDataEvent = Omit; diff --git a/src/metrics/packages/index.ts b/src/metrics/packages/index.ts deleted file mode 100644 index 17c316a..0000000 --- a/src/metrics/packages/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { DataEvent } from "../../core"; - -export const collectPackagesMetrics = ( - dataEvent: DataEvent -): Promise => { - return new Promise((res) => { - res({ ...dataEvent, output: dataEvent.payload }); - }); -}; diff --git a/src/metrics/pull_requests/signatureConditions.ts b/src/metrics/pull_requests/signatureConditions.ts index 78f0afe..cc1fb56 100644 --- a/src/metrics/pull_requests/signatureConditions.ts +++ b/src/metrics/pull_requests/signatureConditions.ts @@ -1,10 +1,9 @@ import { allPass, propEq } from "ramda"; import { DataEventSignature } from "../../interfaces"; -export const isPullRequestClosed = () => - allPass([ - propEq("eventSignature", "pull_request"), - propEq("action", "closed"), - ]); +export const isPullRequestClosed = allPass([ + propEq("eventSignature", "pull_request"), + propEq("action", "closed"), +]); export default [[isPullRequestClosed, DataEventSignature.PullRequestClosed]]; diff --git a/src/metrics/tooling_usage/__tests__/fixtures/merged-completed-successful.json b/src/metrics/tooling_usage/__tests__/fixtures/merged-completed-successful.json new file mode 100644 index 0000000..73c8769 --- /dev/null +++ b/src/metrics/tooling_usage/__tests__/fixtures/merged-completed-successful.json @@ -0,0 +1,535 @@ +{ + "action": "closed", + "number": 12, + "pull_request": { + "url": "https://api.github.com/repos/deven-org/telemetry-functions/pulls/12", + "id": 1257191273, + "node_id": "PR_kwDOI7W9J85K7zdp", + "html_url": "https://github.com/deven-org/telemetry-functions/pull/12", + "diff_url": "https://github.com/deven-org/telemetry-functions/pull/12.diff", + "patch_url": "https://github.com/deven-org/telemetry-functions/pull/12.patch", + "issue_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues/12", + "number": 12, + "state": "closed", + "locked": false, + "title": "chore(main): release 1.2.1", + "user": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "body": ":robot: I have created a release *beep* *boop*\n---\n\n\n## [1.2.0](https://github.com/deven-org/telemetry-functions/compare/v1.1.0...v1.2.0) (2023-03-06)\n\n\n### Features\n\n* **functions:** write JSON files instead of base64 ([3471b10](https://github.com/deven-org/telemetry-functions/commit/3471b101c5f5db7af44dcfc516fc298883678012))\n\n\n### Bug Fixes\n\n* show push error ([64ce354](https://github.com/deven-org/telemetry-functions/commit/64ce354dc5588a7e3ca9336d6f0223616c96ed26))\n* show push error ([ea31bd2](https://github.com/deven-org/telemetry-functions/commit/ea31bd20fe32c935a0bcbd1d8f145dfa16ed4c55))\n* show push error ([64f2eb3](https://github.com/deven-org/telemetry-functions/commit/64f2eb39f4a6c81f9d5d86419586c713cbe37321))\n* show push error ([aca964f](https://github.com/deven-org/telemetry-functions/commit/aca964f6ab0a9547b47c174ffe4309fa664bbd6c))\n* show push error ([21fecfb](https://github.com/deven-org/telemetry-functions/commit/21fecfb4f09770e9d978d7f30e343ad093dccc77))\n\n---\nThis PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).", + "created_at": "2023-02-28T14:02:15Z", + "updated_at": "2023-03-13T15:22:57Z", + "closed_at": "2023-03-13T15:22:57Z", + "merged_at": "2023-03-13T15:22:57Z", + "merge_commit_sha": "9a104bbffd39546de230f96ecba5bbab0204f783", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [ + { + "id": 5208092354, + "node_id": "LA_kwDOI7W9J88AAAABNm0uwg", + "url": "https://api.github.com/repos/deven-org/telemetry-functions/labels/autorelease:%20pending", + "name": "autorelease: pending", + "color": "ededed", + "default": false, + "description": null + } + ], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/deven-org/telemetry-functions/pulls/12/commits", + "review_comments_url": "https://api.github.com/repos/deven-org/telemetry-functions/pulls/12/comments", + "review_comment_url": "https://api.github.com/repos/deven-org/telemetry-functions/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues/12/comments", + "statuses_url": "https://api.github.com/repos/deven-org/telemetry-functions/statuses/abb8528c80bb8eff88493a61a0e0432a2ba7852c", + "head": { + "label": "deven-org:release-please--branches--main--components--documentation-skeleton", + "ref": "release-please--branches--main--components--documentation-skeleton", + "sha": "abb8528c80bb8eff88493a61a0e0432a2ba7852c", + "user": { + "login": "deven-org", + "id": 118735834, + "node_id": "O_kgDOBxPD2g", + "avatar_url": "https://avatars.githubusercontent.com/u/118735834?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/deven-org", + "html_url": "https://github.com/deven-org", + "followers_url": "https://api.github.com/users/deven-org/followers", + "following_url": "https://api.github.com/users/deven-org/following{/other_user}", + "gists_url": "https://api.github.com/users/deven-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/deven-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/deven-org/subscriptions", + "organizations_url": "https://api.github.com/users/deven-org/orgs", + "repos_url": "https://api.github.com/users/deven-org/repos", + "events_url": "https://api.github.com/users/deven-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/deven-org/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 599112999, + "node_id": "R_kgDOI7W9Jw", + "name": "telemetry-functions", + "full_name": "deven-org/telemetry-functions", + "private": false, + "owner": { + "login": "deven-org", + "id": 118735834, + "node_id": "O_kgDOBxPD2g", + "avatar_url": "https://avatars.githubusercontent.com/u/118735834?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/deven-org", + "html_url": "https://github.com/deven-org", + "followers_url": "https://api.github.com/users/deven-org/followers", + "following_url": "https://api.github.com/users/deven-org/following{/other_user}", + "gists_url": "https://api.github.com/users/deven-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/deven-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/deven-org/subscriptions", + "organizations_url": "https://api.github.com/users/deven-org/orgs", + "repos_url": "https://api.github.com/users/deven-org/repos", + "events_url": "https://api.github.com/users/deven-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/deven-org/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/deven-org/telemetry-functions", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/deven-org/telemetry-functions", + "forks_url": "https://api.github.com/repos/deven-org/telemetry-functions/forks", + "keys_url": "https://api.github.com/repos/deven-org/telemetry-functions/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/deven-org/telemetry-functions/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/deven-org/telemetry-functions/teams", + "hooks_url": "https://api.github.com/repos/deven-org/telemetry-functions/hooks", + "issue_events_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues/events{/number}", + "events_url": "https://api.github.com/repos/deven-org/telemetry-functions/events", + "assignees_url": "https://api.github.com/repos/deven-org/telemetry-functions/assignees{/user}", + "branches_url": "https://api.github.com/repos/deven-org/telemetry-functions/branches{/branch}", + "tags_url": "https://api.github.com/repos/deven-org/telemetry-functions/tags", + "blobs_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/deven-org/telemetry-functions/statuses/{sha}", + "languages_url": "https://api.github.com/repos/deven-org/telemetry-functions/languages", + "stargazers_url": "https://api.github.com/repos/deven-org/telemetry-functions/stargazers", + "contributors_url": "https://api.github.com/repos/deven-org/telemetry-functions/contributors", + "subscribers_url": "https://api.github.com/repos/deven-org/telemetry-functions/subscribers", + "subscription_url": "https://api.github.com/repos/deven-org/telemetry-functions/subscription", + "commits_url": "https://api.github.com/repos/deven-org/telemetry-functions/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/deven-org/telemetry-functions/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/deven-org/telemetry-functions/contents/{+path}", + "compare_url": "https://api.github.com/repos/deven-org/telemetry-functions/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/deven-org/telemetry-functions/merges", + "archive_url": "https://api.github.com/repos/deven-org/telemetry-functions/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/deven-org/telemetry-functions/downloads", + "issues_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues{/number}", + "pulls_url": "https://api.github.com/repos/deven-org/telemetry-functions/pulls{/number}", + "milestones_url": "https://api.github.com/repos/deven-org/telemetry-functions/milestones{/number}", + "notifications_url": "https://api.github.com/repos/deven-org/telemetry-functions/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/deven-org/telemetry-functions/labels{/name}", + "releases_url": "https://api.github.com/repos/deven-org/telemetry-functions/releases{/id}", + "deployments_url": "https://api.github.com/repos/deven-org/telemetry-functions/deployments", + "created_at": "2023-02-08T13:35:04Z", + "updated_at": "2023-02-15T14:56:23Z", + "pushed_at": "2023-03-13T15:22:56Z", + "git_url": "git://github.com/deven-org/telemetry-functions.git", + "ssh_url": "git@github.com:deven-org/telemetry-functions.git", + "clone_url": "https://github.com/deven-org/telemetry-functions.git", + "svn_url": "https://github.com/deven-org/telemetry-functions", + "homepage": null, + "size": 329, + "stargazers_count": 0, + "watchers_count": 0, + "language": "JavaScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 5, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 5, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "base": { + "label": "deven-org:main", + "ref": "main", + "sha": "64ce354dc5588a7e3ca9336d6f0223616c96ed26", + "user": { + "login": "deven-org", + "id": 118735834, + "node_id": "O_kgDOBxPD2g", + "avatar_url": "https://avatars.githubusercontent.com/u/118735834?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/deven-org", + "html_url": "https://github.com/deven-org", + "followers_url": "https://api.github.com/users/deven-org/followers", + "following_url": "https://api.github.com/users/deven-org/following{/other_user}", + "gists_url": "https://api.github.com/users/deven-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/deven-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/deven-org/subscriptions", + "organizations_url": "https://api.github.com/users/deven-org/orgs", + "repos_url": "https://api.github.com/users/deven-org/repos", + "events_url": "https://api.github.com/users/deven-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/deven-org/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 599112999, + "node_id": "R_kgDOI7W9Jw", + "name": "telemetry-functions", + "full_name": "deven-org/telemetry-functions", + "private": false, + "owner": { + "login": "deven-org", + "id": 118735834, + "node_id": "O_kgDOBxPD2g", + "avatar_url": "https://avatars.githubusercontent.com/u/118735834?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/deven-org", + "html_url": "https://github.com/deven-org", + "followers_url": "https://api.github.com/users/deven-org/followers", + "following_url": "https://api.github.com/users/deven-org/following{/other_user}", + "gists_url": "https://api.github.com/users/deven-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/deven-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/deven-org/subscriptions", + "organizations_url": "https://api.github.com/users/deven-org/orgs", + "repos_url": "https://api.github.com/users/deven-org/repos", + "events_url": "https://api.github.com/users/deven-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/deven-org/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/deven-org/telemetry-functions", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/deven-org/telemetry-functions", + "forks_url": "https://api.github.com/repos/deven-org/telemetry-functions/forks", + "keys_url": "https://api.github.com/repos/deven-org/telemetry-functions/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/deven-org/telemetry-functions/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/deven-org/telemetry-functions/teams", + "hooks_url": "https://api.github.com/repos/deven-org/telemetry-functions/hooks", + "issue_events_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues/events{/number}", + "events_url": "https://api.github.com/repos/deven-org/telemetry-functions/events", + "assignees_url": "https://api.github.com/repos/deven-org/telemetry-functions/assignees{/user}", + "branches_url": "https://api.github.com/repos/deven-org/telemetry-functions/branches{/branch}", + "tags_url": "https://api.github.com/repos/deven-org/telemetry-functions/tags", + "blobs_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/deven-org/telemetry-functions/statuses/{sha}", + "languages_url": "https://api.github.com/repos/deven-org/telemetry-functions/languages", + "stargazers_url": "https://api.github.com/repos/deven-org/telemetry-functions/stargazers", + "contributors_url": "https://api.github.com/repos/deven-org/telemetry-functions/contributors", + "subscribers_url": "https://api.github.com/repos/deven-org/telemetry-functions/subscribers", + "subscription_url": "https://api.github.com/repos/deven-org/telemetry-functions/subscription", + "commits_url": "https://api.github.com/repos/deven-org/telemetry-functions/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/deven-org/telemetry-functions/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/deven-org/telemetry-functions/contents/{+path}", + "compare_url": "https://api.github.com/repos/deven-org/telemetry-functions/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/deven-org/telemetry-functions/merges", + "archive_url": "https://api.github.com/repos/deven-org/telemetry-functions/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/deven-org/telemetry-functions/downloads", + "issues_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues{/number}", + "pulls_url": "https://api.github.com/repos/deven-org/telemetry-functions/pulls{/number}", + "milestones_url": "https://api.github.com/repos/deven-org/telemetry-functions/milestones{/number}", + "notifications_url": "https://api.github.com/repos/deven-org/telemetry-functions/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/deven-org/telemetry-functions/labels{/name}", + "releases_url": "https://api.github.com/repos/deven-org/telemetry-functions/releases{/id}", + "deployments_url": "https://api.github.com/repos/deven-org/telemetry-functions/deployments", + "created_at": "2023-02-08T13:35:04Z", + "updated_at": "2023-02-15T14:56:23Z", + "pushed_at": "2023-03-13T15:22:56Z", + "git_url": "git://github.com/deven-org/telemetry-functions.git", + "ssh_url": "git@github.com:deven-org/telemetry-functions.git", + "clone_url": "https://github.com/deven-org/telemetry-functions.git", + "svn_url": "https://github.com/deven-org/telemetry-functions", + "homepage": null, + "size": 329, + "stargazers_count": 0, + "watchers_count": 0, + "language": "JavaScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 5, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 5, + "watchers": 0, + "default_branch": "main", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "allow_auto_merge": false, + "delete_branch_on_merge": false, + "allow_update_branch": false, + "use_squash_pr_title_as_default": false, + "squash_merge_commit_message": "COMMIT_MESSAGES", + "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", + "merge_commit_message": "PR_TITLE", + "merge_commit_title": "MERGE_MESSAGE" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/deven-org/telemetry-functions/pulls/12" + }, + "html": { + "href": "https://github.com/deven-org/telemetry-functions/pull/12" + }, + "issue": { + "href": "https://api.github.com/repos/deven-org/telemetry-functions/issues/12" + }, + "comments": { + "href": "https://api.github.com/repos/deven-org/telemetry-functions/issues/12/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/deven-org/telemetry-functions/pulls/12/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/deven-org/telemetry-functions/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/deven-org/telemetry-functions/pulls/12/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/deven-org/telemetry-functions/statuses/abb8528c80bb8eff88493a61a0e0432a2ba7852c" + } + }, + "author_association": "CONTRIBUTOR", + "auto_merge": null, + "active_lock_reason": null, + "merged": true, + "mergeable": null, + "rebaseable": null, + "mergeable_state": "unknown", + "merged_by": { + "login": "pixari", + "id": 7393475, + "node_id": "MDQ6VXNlcjczOTM0NzU=", + "avatar_url": "https://avatars.githubusercontent.com/u/7393475?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pixari", + "html_url": "https://github.com/pixari", + "followers_url": "https://api.github.com/users/pixari/followers", + "following_url": "https://api.github.com/users/pixari/following{/other_user}", + "gists_url": "https://api.github.com/users/pixari/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pixari/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pixari/subscriptions", + "organizations_url": "https://api.github.com/users/pixari/orgs", + "repos_url": "https://api.github.com/users/pixari/repos", + "events_url": "https://api.github.com/users/pixari/events{/privacy}", + "received_events_url": "https://api.github.com/users/pixari/received_events", + "type": "User", + "site_admin": false + }, + "comments": 3, + "review_comments": 0, + "maintainer_can_modify": false, + "commits": 1, + "additions": 18, + "deletions": 2, + "changed_files": 3 + }, + "repository": { + "id": 599112999, + "node_id": "R_kgDOI7W9Jw", + "name": "telemetry-functions", + "full_name": "deven-org/telemetry-functions", + "private": false, + "owner": { + "login": "deven-org", + "id": 118735834, + "node_id": "O_kgDOBxPD2g", + "avatar_url": "https://avatars.githubusercontent.com/u/118735834?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/deven-org", + "html_url": "https://github.com/deven-org", + "followers_url": "https://api.github.com/users/deven-org/followers", + "following_url": "https://api.github.com/users/deven-org/following{/other_user}", + "gists_url": "https://api.github.com/users/deven-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/deven-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/deven-org/subscriptions", + "organizations_url": "https://api.github.com/users/deven-org/orgs", + "repos_url": "https://api.github.com/users/deven-org/repos", + "events_url": "https://api.github.com/users/deven-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/deven-org/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/deven-org/telemetry-functions", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/deven-org/telemetry-functions", + "forks_url": "https://api.github.com/repos/deven-org/telemetry-functions/forks", + "keys_url": "https://api.github.com/repos/deven-org/telemetry-functions/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/deven-org/telemetry-functions/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/deven-org/telemetry-functions/teams", + "hooks_url": "https://api.github.com/repos/deven-org/telemetry-functions/hooks", + "issue_events_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues/events{/number}", + "events_url": "https://api.github.com/repos/deven-org/telemetry-functions/events", + "assignees_url": "https://api.github.com/repos/deven-org/telemetry-functions/assignees{/user}", + "branches_url": "https://api.github.com/repos/deven-org/telemetry-functions/branches{/branch}", + "tags_url": "https://api.github.com/repos/deven-org/telemetry-functions/tags", + "blobs_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/deven-org/telemetry-functions/statuses/{sha}", + "languages_url": "https://api.github.com/repos/deven-org/telemetry-functions/languages", + "stargazers_url": "https://api.github.com/repos/deven-org/telemetry-functions/stargazers", + "contributors_url": "https://api.github.com/repos/deven-org/telemetry-functions/contributors", + "subscribers_url": "https://api.github.com/repos/deven-org/telemetry-functions/subscribers", + "subscription_url": "https://api.github.com/repos/deven-org/telemetry-functions/subscription", + "commits_url": "https://api.github.com/repos/deven-org/telemetry-functions/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/deven-org/telemetry-functions/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/deven-org/telemetry-functions/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/deven-org/telemetry-functions/contents/{+path}", + "compare_url": "https://api.github.com/repos/deven-org/telemetry-functions/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/deven-org/telemetry-functions/merges", + "archive_url": "https://api.github.com/repos/deven-org/telemetry-functions/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/deven-org/telemetry-functions/downloads", + "issues_url": "https://api.github.com/repos/deven-org/telemetry-functions/issues{/number}", + "pulls_url": "https://api.github.com/repos/deven-org/telemetry-functions/pulls{/number}", + "milestones_url": "https://api.github.com/repos/deven-org/telemetry-functions/milestones{/number}", + "notifications_url": "https://api.github.com/repos/deven-org/telemetry-functions/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/deven-org/telemetry-functions/labels{/name}", + "releases_url": "https://api.github.com/repos/deven-org/telemetry-functions/releases{/id}", + "deployments_url": "https://api.github.com/repos/deven-org/telemetry-functions/deployments", + "created_at": "2023-02-08T13:35:04Z", + "updated_at": "2023-02-15T14:56:23Z", + "pushed_at": "2023-03-13T15:22:56Z", + "git_url": "git://github.com/deven-org/telemetry-functions.git", + "ssh_url": "git@github.com:deven-org/telemetry-functions.git", + "clone_url": "https://github.com/deven-org/telemetry-functions.git", + "svn_url": "https://github.com/deven-org/telemetry-functions", + "homepage": null, + "size": 329, + "stargazers_count": 0, + "watchers_count": 0, + "language": "JavaScript", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "has_discussions": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 5, + "license": null, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [], + "visibility": "public", + "forks": 0, + "open_issues": 5, + "watchers": 0, + "default_branch": "main" + }, + "organization": { + "login": "deven-org", + "id": 118735834, + "node_id": "O_kgDOBxPD2g", + "url": "https://api.github.com/orgs/deven-org", + "repos_url": "https://api.github.com/orgs/deven-org/repos", + "events_url": "https://api.github.com/orgs/deven-org/events", + "hooks_url": "https://api.github.com/orgs/deven-org/hooks", + "issues_url": "https://api.github.com/orgs/deven-org/issues", + "members_url": "https://api.github.com/orgs/deven-org/members{/member}", + "public_members_url": "https://api.github.com/orgs/deven-org/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/118735834?v=4", + "description": "Developer Enviroment / Enablement / Enhancement" + }, + "sender": { + "login": "pixari", + "id": 7393475, + "node_id": "MDQ6VXNlcjczOTM0NzU=", + "avatar_url": "https://avatars.githubusercontent.com/u/7393475?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/pixari", + "html_url": "https://github.com/pixari", + "followers_url": "https://api.github.com/users/pixari/followers", + "following_url": "https://api.github.com/users/pixari/following{/other_user}", + "gists_url": "https://api.github.com/users/pixari/gists{/gist_id}", + "starred_url": "https://api.github.com/users/pixari/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/pixari/subscriptions", + "organizations_url": "https://api.github.com/users/pixari/orgs", + "repos_url": "https://api.github.com/users/pixari/repos", + "events_url": "https://api.github.com/users/pixari/events{/privacy}", + "received_events_url": "https://api.github.com/users/pixari/received_events", + "type": "User", + "site_admin": false + }, + "installation": { + "id": 34494610, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMzQ0OTQ2MTA=" + } +} diff --git a/src/metrics/tooling_usage/__tests__/fixtures/mocked-package.json b/src/metrics/tooling_usage/__tests__/fixtures/mocked-package.json new file mode 100644 index 0000000..6125b45 --- /dev/null +++ b/src/metrics/tooling_usage/__tests__/fixtures/mocked-package.json @@ -0,0 +1,56 @@ +{ + "name": "@deven-org/telemetry-functions", + "version": "1.1.0", + "description": "@deven-org/telemetry-functions", + "repository": { + "type": "git", + "url": "https://github.com/deven-org/telemetry-functions.git" + }, + "publishConfig": { + "@deven-org:registry": "https://npm.pkg.github.com" + }, + "keywords": [ + "deven", + "telemetry", + "functions", + "serverless" + ], + "homepage": "https://github.com/deven-org/telemetry-functions", + "engines": { + "node": ">= 16" + }, + "author": "Deven Team", + "license": "MIT", + "bugs": { + "url": "https://github.com/deven-org/telemetry-functions/issues" + }, + "scripts": { + "build": "rm -fr dist && microbundle --target node -f umd", + "prettier": "prettier --config .prettierrc.js 'src/**/*.ts' --write", + "lint": "eslint --fix --max-warnings 0 **/*.ts", + "test": "jest", + "test:coverage": "jest --coverage", + "test:dev": "jest --watch", + "doc:install": "deven-documentation-skeleton install", + "doc:check": "deven-documentation-skeleton check", + "doc:update": "deven-documentation-skeleton update" + }, + "dependencies": { + "@netlify/functions": "^1.4.0", + "@octokit/rest": "^19.0.7", + "dotenv": "^16.0.3", + "js-base64": "^3.7.5" + }, + "devDependencies": { + "@types/jest": "^29.4.1", + "@types/node": "^18.13.0", + "deven-documentation-skeleton": "^2.0.0", + "moment": "^2.29.4", + "netlify": "^13.1.2", + "netlify-cli": "^13.0.1", + "ramda": "^0.28.0", + "semver": "^7.3.8", + "signale": "^1.4.0", + "ts-jest": "^29.0.5" + } +} diff --git a/src/metrics/tooling_usage/__tests__/toolingUsage.test.ts b/src/metrics/tooling_usage/__tests__/toolingUsage.test.ts new file mode 100644 index 0000000..9fb664a --- /dev/null +++ b/src/metrics/tooling_usage/__tests__/toolingUsage.test.ts @@ -0,0 +1,135 @@ +import { DataEventSignature } from "../../../interfaces"; +import { handler } from "../../../handler"; +import mergedCompletedSuccessfully from "./fixtures/merged-completed-successful.json"; +import { encode, decode } from "js-base64"; +import mockedPackageWithDocSkeleton from "./fixtures/mocked-package.json"; + +let octokitResponse = {}; + +jest.mock("./../../../core/octokit.ts", () => ({ + __esModule: true, + default: { + request: () => octokitResponse, + }, +})); + +describe("Tooling_Usage", () => { + beforeEach(() => {}); + + afterEach(() => {}); + + it("event gets signed as a toolingUsage event", async () => { + const eventBody = { + eventSignature: "toolingUsage", + }; + + octokitResponse = { + data: { + content: encode(JSON.stringify(mockedPackageWithDocSkeleton)), + }, + }; + + const output = await handler(eventBody); + + expect(output).toMatchObject({ + created_at: expect.any(Number), + output: {}, + dataEventSignature: DataEventSignature.ToolingUsage, + }); + }); + + it("returns true if package has deven-documentation-skeleton", async () => { + const eventBody = { + eventSignature: "toolingUsage", + }; + + octokitResponse = { + data: { + content: encode(JSON.stringify(mockedPackageWithDocSkeleton)), + }, + }; + + const output = await handler(eventBody); + + expect(output).toMatchObject({ + created_at: expect.any(Number), + output: { hasDocumentationSkeleton: true }, + dataEventSignature: DataEventSignature.ToolingUsage, + }); + }); + + it("returns false if package does not have deven-documentation-skeleton ", async () => { + const eventBody = { + eventSignature: "toolingUsage", + }; + + let mockedPackageWithoutDocSkeleton = JSON.parse( + JSON.stringify(mockedPackageWithDocSkeleton) + ); + + delete mockedPackageWithoutDocSkeleton.devDependencies[ + "deven-documentation-skeleton" + ]; + + octokitResponse = { + data: { + content: encode(JSON.stringify(mockedPackageWithoutDocSkeleton)), + }, + }; + + const output = await handler(eventBody); + + expect(output).toMatchObject({ + created_at: expect.any(Number), + output: { hasDocumentationSkeleton: false }, + dataEventSignature: DataEventSignature.ToolingUsage, + }); + }); + + it("returns false if there are no devDependencies", async () => { + const eventBody = { + eventSignature: "toolingUsage", + }; + + let mockedPackageWithoutDocSkeleton = JSON.parse( + JSON.stringify(mockedPackageWithDocSkeleton) + ); + + delete mockedPackageWithoutDocSkeleton.devDependencies; + delete mockedPackageWithoutDocSkeleton.dependencies; + + octokitResponse = { + data: { + content: encode(JSON.stringify(mockedPackageWithoutDocSkeleton)), + }, + }; + + const output = await handler(eventBody); + + expect(output).toMatchObject({ + created_at: expect.any(Number), + output: { hasDocumentationSkeleton: false }, + dataEventSignature: DataEventSignature.ToolingUsage, + }); + }); + + it("return hasValidPackageJson=false if package.json is invalid", async () => { + const eventBody = { + eventSignature: "toolingUsage", + }; + + octokitResponse = { + data: { + content: undefined, + }, + }; + + const output = await handler(eventBody); + + expect(output).toMatchObject({ + created_at: expect.any(Number), + output: { hasValidPackageJson: false }, + dataEventSignature: DataEventSignature.ToolingUsage, + }); + }); +}); diff --git a/src/metrics/tooling_usage/index.ts b/src/metrics/tooling_usage/index.ts new file mode 100644 index 0000000..a707cee --- /dev/null +++ b/src/metrics/tooling_usage/index.ts @@ -0,0 +1,67 @@ +import { logger } from "../../core"; +import { DataEvent, EnhancedDataEvent } from "../../interfaces"; +import { ToolingUsageOutput, ToolingUsagePayload } from "./interfaces"; +import { keys, pipe, mergeAll, includes } from "ramda"; +import octokit from "../../core/octokit"; +import { encode, decode } from "js-base64"; +import { invalid } from "moment"; +import { LogWarnings } from "../../shared/logMessages"; + +export const collectToolingUsageMetrics = async ( + dataEvent: DataEvent +): Promise => { + const payload = dataEvent.payload as ToolingUsagePayload; + + let output: ToolingUsageOutput; + + try { + const response = await octokit.request( + "GET /repos/{owner}/{repo}/contents/{path}", + { + owner: payload.owner, + repo: payload.repo, + path: "package.json", + } + ); + const { dependencies, devDependencies } = JSON.parse( + decode(response.data["content"]) + ); + + const hasDocumentationSkeleton = pipe( + keys, + includes("deven-documentation-skeleton") + )(mergeAll([devDependencies, dependencies])); + + output = { + hasDocumentationSkeleton, + dependencies: dependencies, + devDependencies: devDependencies, + owner: payload.owner, + repo: payload.repo, + hasValidPackageJson: true, + }; + } catch (error) { + output = { + hasDocumentationSkeleton: false, + dependencies: [], + devDependencies: [], + owner: payload.owner, + repo: payload.repo, + hasValidPackageJson: false, + }; + logger.warn( + LogWarnings.invalidPackageJson, + `${payload.owner}/${payload.repo}` + ); + } + + logger.success( + `Collected metrics for "${dataEvent.dataEventSignature}": %s`, + keys(output).join(", ") + ); + + return { + ...dataEvent, + output, + }; +}; diff --git a/src/metrics/tooling_usage/interfaces.d.ts b/src/metrics/tooling_usage/interfaces.d.ts new file mode 100644 index 0000000..6bbfbe4 --- /dev/null +++ b/src/metrics/tooling_usage/interfaces.d.ts @@ -0,0 +1,13 @@ +export type ToolingUsagePayload = { + repo: string; + owner: string; +}; + +export interface ToolingUsageOutput { + hasDocumentationSkeleton: boolean; + devDependencies: object; + dependencies: object; + repo: string; + owner: string; + hasValidPackageJson: boolean; +} diff --git a/src/metrics/tooling_usage/metricsConditions.ts b/src/metrics/tooling_usage/metricsConditions.ts new file mode 100644 index 0000000..435a069 --- /dev/null +++ b/src/metrics/tooling_usage/metricsConditions.ts @@ -0,0 +1,7 @@ +import { collectToolingUsageMetrics } from "."; +import { DataEvent, DataEventSignature } from "../../interfaces"; + +const isSignedAsToolingUsage = (dataEvent: DataEvent) => + dataEvent.dataEventSignature === DataEventSignature.ToolingUsage; + +export default [[isSignedAsToolingUsage, collectToolingUsageMetrics]]; diff --git a/src/metrics/tooling_usage/signatureConditions.ts b/src/metrics/tooling_usage/signatureConditions.ts new file mode 100644 index 0000000..7444454 --- /dev/null +++ b/src/metrics/tooling_usage/signatureConditions.ts @@ -0,0 +1,8 @@ +import { allPass, propEq } from "ramda"; +import { DataEventSignature } from "../../interfaces"; + +export const isToolingUsed = allPass([ + propEq("eventSignature", "toolingUsage"), +]); + +export default [[isToolingUsed, DataEventSignature.ToolingUsage]]; diff --git a/src/metricsConditions.ts b/src/metricsConditions.ts index 95b3e03..1360aa5 100644 --- a/src/metricsConditions.ts +++ b/src/metricsConditions.ts @@ -1,5 +1,9 @@ import { always, T } from "ramda"; import pullRequestsMetricsConditions from "./metrics/pull_requests/metricsConditions"; +import toolingUsageMetricsConditions from "./metrics/tooling_usage/metricsConditions"; -export default [...pullRequestsMetricsConditions, [T, always(false)]]; +export default [ + ...pullRequestsMetricsConditions, + ...toolingUsageMetricsConditions, +]; diff --git a/src/shared/logMessages.ts b/src/shared/logMessages.ts index 1f0b38a..14325e3 100644 --- a/src/shared/logMessages.ts +++ b/src/shared/logMessages.ts @@ -1,6 +1,5 @@ export enum LogErrors { collectMetricsSignatureNotRecognized = "The signature of the data event is not recognized.", - signingEventSignatureNotRecognized = "Can't identify the signature of the data event. Skipping.", } export enum LogInfos { @@ -8,3 +7,8 @@ export enum LogInfos { eventSigned = "Event has been signed as: '%s'", startCollectingMetrics = "Trying to collect metrics...", } + +export enum LogWarnings { + invalidPackageJson = "Package.json is invalid. Owner/Repo is: '%s'", + signingEventSignatureNotRecognized = "Can't identify the signature of the data event. Skipping.", +} diff --git a/src/signatureConditions.ts b/src/signatureConditions.ts index 5f04284..0d2d92e 100644 --- a/src/signatureConditions.ts +++ b/src/signatureConditions.ts @@ -1,5 +1,6 @@ import { always, T } from "ramda"; import pullRequestsConditions from "./metrics/pull_requests/signatureConditions"; +import toolingUsageConditions from "./metrics/tooling_usage/signatureConditions"; -export default [...pullRequestsConditions, [T, always(false)]]; +export default [...pullRequestsConditions, ...toolingUsageConditions];