diff --git a/.github/workflows/email.yml b/.github/workflows/email.yml index 94c0662..0f9d23b 100644 --- a/.github/workflows/email.yml +++ b/.github/workflows/email.yml @@ -1,8 +1,8 @@ name: Email Copilot Report on: workflow_dispatch: - schedule: - - cron: '0 0 * * 0' # Sunday at midnight (00:00). + # schedule: + # - cron: '0 0 * * 0' # Sunday at midnight (00:00). permissions: contents: read @@ -11,39 +11,25 @@ jobs: name: Copilot Usage runs-on: ubuntu-latest steps: - - uses: austenstone/copilot-usage@main - id: usage - with: - organization: ${{ secrets.ORG }} - github-token: ${{ secrets.TOKEN }} - - uses: austenstone/job-summary@v2.0 - id: pdf - with: - name: copilot-usage + # - uses: austenstone/copilot-usage@main + # id: usage + # with: + # enterprise: 'secorp' + # github-token: ${{ secrets.SECORP }} + # - uses: austenstone/job-summary@v2.0 + # id: pdf + # with: + # name: copilot-usage - uses: dawidd6/action-send-mail@v3 with: - server_address: smtp.gmail.com - server_port: 465 - username: ${{ secrets.EMAIL }} - password: ${{ secrets.PASSWORD }} - from: ${{ secrets.EMAIL }} - to: ${{ secrets.EMAIL }} # Recipient email - subject: "Copilot Usage Report (${{ steps.usage.outputs.since }} - ${{ steps.usage.outputs.until }})" - html_body: | - - - - -

Copilot Usage Report

-

Attached is the Copilot Usage Report for ${{ steps.usage.outputs.since }} - ${{ steps.usage.outputs.until }}!

-

- View the full report on - GitHub.com -

- - ${{ steps.pdf.outputs.job-summary-html }} - - - - - attachments: ${{ steps.pdf.outputs.pdf-file }} \ No newline at end of file + # server_address: smtp.gmail.com + # server_port: 465 + server_address: smtp.office365.com + server_port: 587 + username: ${{ secrets.OUTLOOK_USERNAME }} + password: ${{ secrets.OUTLOOK_PASSWORD }} + from: ${{ secrets.OUTLOOK_USERNAME }} + to: ${{ secrets.OUTLOOK_USERNAME }} # Recipient email + subject: "Copilot Usage Report" + body: | + Hello diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index 908d660..234685e 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -3,7 +3,7 @@ import dotenv from 'dotenv' dotenv.config({ override: true }) import { createJobSummarySeatAssignments, createJobSummarySeatInfo, createJobSummaryUsage } from '../src/job-summary'; import { summary } from '@actions/core/lib/summary'; -import { exampleResponseEnterprise, exampleResponseOrg, exampleResponseTeam, exampleSeatAssignmentResponse, exampleSeatInfoResponse } from './mock/mock-data'; +import { exampleResponseEnterprise, exampleSeatAssignmentResponse, exampleSeatInfoResponse } from './mock/mock-data'; import { readFileSync } from 'fs'; const getSummaryBuffer = (_summary: typeof summary): string => { @@ -27,17 +27,17 @@ test('createJobSummaryUsage(enterpriseUsage)', async () => { expect(getSummaryBuffer(summary)).toEqual(readFileSync('./__tests__/mock/enterprise-usage-summary.md', 'utf-8')); }); -test('createJobSummaryUsage(orgUsage)', async () => { - const summary = await createJobSummaryUsage(exampleResponseOrg); - expect(summary).toBeDefined(); - expect(getSummaryBuffer(summary)).toEqual(readFileSync('./__tests__/mock/org-usage-summary.md', 'utf-8')); -}); - -test('createJobSummaryUsage(teamUsage)', async () => { - const summary = await createJobSummaryUsage(exampleResponseTeam); - expect(summary).toBeDefined(); - expect(getSummaryBuffer(summary)).toEqual(readFileSync('./__tests__/mock/team-usage-summary.md', 'utf-8')); -}); +// test('createJobSummaryUsage(orgUsage)', async () => { +// const summary = await createJobSummaryUsage(exampleResponseOrg); +// expect(summary).toBeDefined(); +// expect(getSummaryBuffer(summary)).toEqual(readFileSync('./__tests__/mock/org-usage-summary.md', 'utf-8')); +// }); + +// test('createJobSummaryUsage(teamUsage)', async () => { +// const summary = await createJobSummaryUsage(exampleResponseTeam); +// expect(summary).toBeDefined(); +// expect(getSummaryBuffer(summary)).toEqual(readFileSync('./__tests__/mock/team-usage-summary.md', 'utf-8')); +// }); test('createJobSummarySeatInfo(orgSeatInfo)', async () => { const summary = await createJobSummarySeatInfo(exampleSeatInfoResponse); diff --git a/__tests__/mock/mock-data.ts b/__tests__/mock/mock-data.ts index 17c76cf..d6e0ee8 100644 --- a/__tests__/mock/mock-data.ts +++ b/__tests__/mock/mock-data.ts @@ -116,171 +116,171 @@ export const exampleResponseEnterprise: CopilotUsageResponse = [ } ]; -export const exampleResponseOrg: CopilotUsageResponse = [ - { - "day": "2023-10-15", - "total_suggestions_count": 1000, - "total_acceptances_count": 800, - "total_lines_suggested": 1800, - "total_lines_accepted": 1200, - "total_active_users": 10, - "total_chat_acceptances": 32, - "total_chat_turns": 200, - "total_active_chat_users": 4, - "breakdown": [ - { - "language": "python", - "editor": "vscode", - "suggestions_count": 300, - "acceptances_count": 250, - "lines_suggested": 900, - "lines_accepted": 700, - "active_users": 5 - }, - { - "language": "python", - "editor": "jetbrains", - "suggestions_count": 300, - "acceptances_count": 200, - "lines_suggested": 400, - "lines_accepted": 300, - "active_users": 2 - }, - { - "language": "ruby", - "editor": "vscode", - "suggestions_count": 400, - "acceptances_count": 350, - "lines_suggested": 500, - "lines_accepted": 200, - "active_users": 3 - } - ] - }, - { - "day": "2023-10-16", - "total_suggestions_count": 800, - "total_acceptances_count": 600, - "total_lines_suggested": 1100, - "total_lines_accepted": 700, - "total_active_users": 12, - "total_chat_acceptances": 57, - "total_chat_turns": 426, - "total_active_chat_users": 8, - "breakdown": [ - { - "language": "python", - "editor": "vscode", - "suggestions_count": 300, - "acceptances_count": 200, - "lines_suggested": 600, - "lines_accepted": 300, - "active_users": 2 - }, - { - "language": "python", - "editor": "jetbrains", - "suggestions_count": 300, - "acceptances_count": 150, - "lines_suggested": 300, - "lines_accepted": 250, - "active_users": 6 - }, - { - "language": "ruby", - "editor": "vscode", - "suggestions_count": 200, - "acceptances_count": 150, - "lines_suggested": 200, - "lines_accepted": 150, - "active_users": 3 - } - ] - } -]; +// export const exampleResponseOrg: CopilotUsageResponse = [ +// { +// "day": "2023-10-15", +// "total_suggestions_count": 1000, +// "total_acceptances_count": 800, +// "total_lines_suggested": 1800, +// "total_lines_accepted": 1200, +// "total_active_users": 10, +// "total_chat_acceptances": 32, +// "total_chat_turns": 200, +// "total_active_chat_users": 4, +// "breakdown": [ +// { +// "language": "python", +// "editor": "vscode", +// "suggestions_count": 300, +// "acceptances_count": 250, +// "lines_suggested": 900, +// "lines_accepted": 700, +// "active_users": 5 +// }, +// { +// "language": "python", +// "editor": "jetbrains", +// "suggestions_count": 300, +// "acceptances_count": 200, +// "lines_suggested": 400, +// "lines_accepted": 300, +// "active_users": 2 +// }, +// { +// "language": "ruby", +// "editor": "vscode", +// "suggestions_count": 400, +// "acceptances_count": 350, +// "lines_suggested": 500, +// "lines_accepted": 200, +// "active_users": 3 +// } +// ] +// }, +// { +// "day": "2023-10-16", +// "total_suggestions_count": 800, +// "total_acceptances_count": 600, +// "total_lines_suggested": 1100, +// "total_lines_accepted": 700, +// "total_active_users": 12, +// "total_chat_acceptances": 57, +// "total_chat_turns": 426, +// "total_active_chat_users": 8, +// "breakdown": [ +// { +// "language": "python", +// "editor": "vscode", +// "suggestions_count": 300, +// "acceptances_count": 200, +// "lines_suggested": 600, +// "lines_accepted": 300, +// "active_users": 2 +// }, +// { +// "language": "python", +// "editor": "jetbrains", +// "suggestions_count": 300, +// "acceptances_count": 150, +// "lines_suggested": 300, +// "lines_accepted": 250, +// "active_users": 6 +// }, +// { +// "language": "ruby", +// "editor": "vscode", +// "suggestions_count": 200, +// "acceptances_count": 150, +// "lines_suggested": 200, +// "lines_accepted": 150, +// "active_users": 3 +// } +// ] +// } +// ]; -export const exampleResponseTeam: CopilotUsageResponse = [ - { - "day": "2023-10-15", - "total_suggestions_count": 1000, - "total_acceptances_count": 800, - "total_lines_suggested": 1800, - "total_lines_accepted": 1200, - "total_active_users": 10, - "total_chat_acceptances": 32, - "total_chat_turns": 200, - "total_active_chat_users": 4, - "breakdown": [ - { - "language": "python", - "editor": "vscode", - "suggestions_count": 300, - "acceptances_count": 250, - "lines_suggested": 900, - "lines_accepted": 700, - "active_users": 5 - }, - { - "language": "python", - "editor": "jetbrains", - "suggestions_count": 300, - "acceptances_count": 200, - "lines_suggested": 400, - "lines_accepted": 300, - "active_users": 2 - }, - { - "language": "ruby", - "editor": "vscode", - "suggestions_count": 400, - "acceptances_count": 350, - "lines_suggested": 500, - "lines_accepted": 200, - "active_users": 3 - } - ] - }, - { - "day": "2023-10-16", - "total_suggestions_count": 800, - "total_acceptances_count": 600, - "total_lines_suggested": 1100, - "total_lines_accepted": 700, - "total_active_users": 12, - "total_chat_acceptances": 57, - "total_chat_turns": 426, - "total_active_chat_users": 8, - "breakdown": [ - { - "language": "python", - "editor": "vscode", - "suggestions_count": 300, - "acceptances_count": 200, - "lines_suggested": 600, - "lines_accepted": 300, - "active_users": 2 - }, - { - "language": "python", - "editor": "jetbrains", - "suggestions_count": 300, - "acceptances_count": 150, - "lines_suggested": 300, - "lines_accepted": 250, - "active_users": 6 - }, - { - "language": "ruby", - "editor": "vscode", - "suggestions_count": 200, - "acceptances_count": 150, - "lines_suggested": 200, - "lines_accepted": 150, - "active_users": 3 - } - ] - } -]; +// export const exampleResponseTeam: CopilotUsageResponse = [ +// { +// "day": "2023-10-15", +// "total_suggestions_count": 1000, +// "total_acceptances_count": 800, +// "total_lines_suggested": 1800, +// "total_lines_accepted": 1200, +// "total_active_users": 10, +// "total_chat_acceptances": 32, +// "total_chat_turns": 200, +// "total_active_chat_users": 4, +// "breakdown": [ +// { +// "language": "python", +// "editor": "vscode", +// "suggestions_count": 300, +// "acceptances_count": 250, +// "lines_suggested": 900, +// "lines_accepted": 700, +// "active_users": 5 +// }, +// { +// "language": "python", +// "editor": "jetbrains", +// "suggestions_count": 300, +// "acceptances_count": 200, +// "lines_suggested": 400, +// "lines_accepted": 300, +// "active_users": 2 +// }, +// { +// "language": "ruby", +// "editor": "vscode", +// "suggestions_count": 400, +// "acceptances_count": 350, +// "lines_suggested": 500, +// "lines_accepted": 200, +// "active_users": 3 +// } +// ] +// }, +// { +// "day": "2023-10-16", +// "total_suggestions_count": 800, +// "total_acceptances_count": 600, +// "total_lines_suggested": 1100, +// "total_lines_accepted": 700, +// "total_active_users": 12, +// "total_chat_acceptances": 57, +// "total_chat_turns": 426, +// "total_active_chat_users": 8, +// "breakdown": [ +// { +// "language": "python", +// "editor": "vscode", +// "suggestions_count": 300, +// "acceptances_count": 200, +// "lines_suggested": 600, +// "lines_accepted": 300, +// "active_users": 2 +// }, +// { +// "language": "python", +// "editor": "jetbrains", +// "suggestions_count": 300, +// "acceptances_count": 150, +// "lines_suggested": 300, +// "lines_accepted": 250, +// "active_users": 6 +// }, +// { +// "language": "ruby", +// "editor": "vscode", +// "suggestions_count": 200, +// "acceptances_count": 150, +// "lines_suggested": 200, +// "lines_accepted": 150, +// "active_users": 3 +// } +// ] +// } +// ]; export const exampleSeatInfoResponse: RestEndpointMethodTypes["copilot"]["getCopilotOrganizationDetails"]["response"]["data"] = { "seat_breakdown": { @@ -365,4 +365,4 @@ export const exampleSeatAssignmentResponse: RestEndpointMethodTypes["copilot"][" "site_admin": false } } -]; \ No newline at end of file +]; diff --git a/action.yml b/action.yml index 2b67858..f2a8aca 100644 --- a/action.yml +++ b/action.yml @@ -12,13 +12,13 @@ inputs: enterprise: description: The GitHub enterprise slug required: false - organization: - description: The organization slug - default: ${{ github.repository_owner }} - required: false - team: - description: The team slug - required: false + # organization: + # description: The organization slug + # default: ${{ github.repository_owner }} + # required: false + # team: + # description: The team slug + # required: false days: description: The number of days to show usage metrics for. required: false diff --git a/dist/run.js b/dist/run.js index ea7ca7e..264898c 100644 --- a/dist/run.js +++ b/dist/run.js @@ -9,9 +9,9 @@ import { warn } from "console"; const getInputs = () => { const result = {}; result.token = getInput("github-token").trim(); - result.organization = getInput("organization").trim(); + // result.organization = getInput("organization").trim(); result.enterprise = getInput("enterprise").trim(); - result.team = getInput("team").trim(); + // result.team = getInput("team").trim(); result.jobSummary = getBooleanInput("job-summary"); result.days = parseInt(getInput("days")); result.since = getInput("since"); @@ -49,24 +49,24 @@ const run = async () => { ...params }); } - else if (input.team) { - if (!input.organization) { - throw new Error("organization is required when team is provided"); - } - info(`Fetching Copilot usage for team ${input.team} inside organization ${input.organization}`); - req = octokit.paginate("GET /orgs/{org}/team/{team}/copilot/usage", { - org: input.organization, - team: input.team, - ...params - }); - } - else if (input.organization) { - info(`Fetching Copilot usage for organization ${input.organization}`); - req = octokit.paginate("GET /orgs/{org}/copilot/usage", { - org: input.organization, - ...params - }); - } + // else if (input.team) { + // if (!input.organization) { + // throw new Error("organization is required when team is provided"); + // } + // info(`Fetching Copilot usage for team ${input.team} inside organization ${input.organization}`); + // req = octokit.paginate("GET /orgs/{org}/team/{team}/copilot/usage", { + // org: input.organization, + // team: input.team, + // ...params + // }); + // } + // else if (input.organization) { + // info(`Fetching Copilot usage for organization ${input.organization}`); + // req = octokit.paginate("GET /orgs/{org}/copilot/usage", { + // org: input.organization, + // ...params + // }); + // } else { throw new Error("organization, enterprise or team input is required"); } @@ -78,25 +78,25 @@ const run = async () => { info(`Fetched Copilot usage data for ${data.length} days (${data[0].day} to ${data[data.length - 1].day})`); if (input.jobSummary) { await createJobSummaryUsage(data).write(); - if (input.organization && !input.team) { - info(`Fetching Copilot details for organization ${input.organization}`); - const orgSeatInfo = await octokit.rest.copilot.getCopilotOrganizationDetails({ - org: input.organization - }); - if (orgSeatInfo?.data) { - await createJobSummarySeatInfo(orgSeatInfo.data).write(); - } - info(`Fetching Copilot seat assignments for organization ${input.organization}`); - const orgSeatAssignments = await octokit.rest.copilot.listCopilotSeats({ - org: input.organization - }); - if (orgSeatAssignments?.data?.seats) { - await createJobSummarySeatAssignments(orgSeatAssignments.data.seats)?.write(); - } - } - if (input.organization) { - (await createJobSummaryFooter(input.organization)).write(); - } + // // if (input.organization && !input.team) { + // // info(`Fetching Copilot details for organization ${input.organization}`); + // // const orgSeatInfo = await octokit.rest.copilot.getCopilotOrganizationDetails({ + // // org: input.organization + // // }); + // if (orgSeatInfo?.data) { + // await createJobSummarySeatInfo(orgSeatInfo.data).write(); + // } + // info(`Fetching Copilot seat assignments for organization ${input.organization}`); + // const orgSeatAssignments = await octokit.rest.copilot.listCopilotSeats({ + // org: input.organization + // }); + // if (orgSeatAssignments?.data?.seats) { + // await createJobSummarySeatAssignments(orgSeatAssignments.data.seats)?.write(); + // } + // } + // if (input.organization) { + // (await createJobSummaryFooter(input.organization)).write(); + // } } if (input.csv || input.xml) { const artifact = new DefaultArtifactClient(); @@ -115,4 +115,4 @@ const run = async () => { setOutput("days", data.length.toString()); }; export default run; -//# sourceMappingURL=run.js.map \ No newline at end of file +//# sourceMappingURL=run.js.map diff --git a/src/run.ts b/src/run.ts index 3202ad5..7c542c5 100644 --- a/src/run.ts +++ b/src/run.ts @@ -55,9 +55,9 @@ interface Input { const getInputs = (): Input => { const result = {} as Input; result.token = getInput("github-token").trim(); - result.organization = getInput("organization").trim(); + // result.organization = getInput("organization").trim(); result.enterprise = getInput("enterprise").trim(); - result.team = getInput("team").trim(); + // result.team = getInput("team").trim(); result.jobSummary = getBooleanInput("job-summary"); result.days = parseInt(getInput("days")); result.since = getInput("since"); @@ -93,22 +93,22 @@ const run = async (): Promise => { enterprise: input.enterprise, ...params }); - } else if (input.team) { - if (!input.organization) { - throw new Error("organization is required when team is provided"); - } - info(`Fetching Copilot usage for team ${input.team} inside organization ${input.organization}`); - req = octokit.paginate("GET /orgs/{org}/team/{team}/copilot/usage", { - org: input.organization, - team: input.team, - ...params - }); - } else if (input.organization) { - info(`Fetching Copilot usage for organization ${input.organization}`); - req = octokit.paginate("GET /orgs/{org}/copilot/usage", { - org: input.organization, - ...params - }); + // } else if (input.team) { + // if (!input.organization) { + // throw new Error("organization is required when team is provided"); + // } + // info(`Fetching Copilot usage for team ${input.team} inside organization ${input.organization}`); + // req = octokit.paginate("GET /orgs/{org}/team/{team}/copilot/usage", { + // org: input.organization, + // team: input.team, + // ...params + // }); + // } else if (input.organization) { + // info(`Fetching Copilot usage for organization ${input.organization}`); + // req = octokit.paginate("GET /orgs/{org}/copilot/usage", { + // org: input.organization, + // ...params + // }); } else { throw new Error("organization, enterprise or team input is required"); } @@ -123,27 +123,27 @@ const run = async (): Promise => { if (input.jobSummary) { await createJobSummaryUsage(data).write(); - if (input.organization && !input.team) { // refuse to fetch organization seat info if looking for team usage - info(`Fetching Copilot details for organization ${input.organization}`); - const orgSeatInfo = await octokit.rest.copilot.getCopilotOrganizationDetails({ - org: input.organization - }); - if (orgSeatInfo?.data) { - await createJobSummarySeatInfo(orgSeatInfo.data).write(); - } + // if (input.organization && !input.team) { // refuse to fetch organization seat info if looking for team usage + // info(`Fetching Copilot details for organization ${input.organization}`); + // const orgSeatInfo = await octokit.rest.copilot.getCopilotOrganizationDetails({ + // org: input.organization + // }); + // if (orgSeatInfo?.data) { + // await createJobSummarySeatInfo(orgSeatInfo.data).write(); + // } - info(`Fetching Copilot seat assignments for organization ${input.organization}`); - const orgSeatAssignments = await octokit.rest.copilot.listCopilotSeats({ - org: input.organization - }); - if (orgSeatAssignments?.data?.seats) { - await createJobSummarySeatAssignments(orgSeatAssignments.data.seats)?.write(); - } - } + // info(`Fetching Copilot seat assignments for organization ${input.organization}`); + // const orgSeatAssignments = await octokit.rest.copilot.listCopilotSeats({ + // org: input.organization + // }); + // if (orgSeatAssignments?.data?.seats) { + // await createJobSummarySeatAssignments(orgSeatAssignments.data.seats)?.write(); + // } + // } - if (input.organization) { - (await createJobSummaryFooter(input.organization)).write(); - } + // if (input.organization) { + // (await createJobSummaryFooter(input.organization)).write(); + // } } if (input.csv || input.xml) { @@ -164,4 +164,4 @@ const run = async (): Promise => { setOutput("days", data.length.toString()); }; -export default run; \ No newline at end of file +export default run;