Skip to content

Commit

Permalink
add settings to control input and output file names (#30)
Browse files Browse the repository at this point in the history
* change input to function as props obj

* move file names into props, let caller decide

* add copilot user counts and a total sum to the report

* add ability to generate a detailed report in addition to the summary

* add settings to control input and output file names

* update readme indicating changes made to copilot associations report

* add test data file for reference
  • Loading branch information
scottluskcis authored Dec 16, 2024
1 parent 1df1336 commit 90daa72
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 62 deletions.
53 changes: 37 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,29 +53,38 @@ The reports available in this repository are noted below
### Copilot Associations
The purpose of [this report](./src/report/copilot-associations-report.ts) is to show what users exist in an organizations teams that do not have a copilot seat in the org but may have a relation to someone else on the team that does have a copilot seat.
The purpose of [this report](./src/report/copilot-associations-report.ts) is to show what users exist in an organizations teams that do not have a copilot seat in the org but may have a relation (aka association) to someone else on the team that does have a copilot seat.
A CSV file named `copilot_associations.csv` is generated for this report containing the data. You will see the following values in the report:
There are two reports that are generated as a result of running this report and the names of these files can be managed via [settings](#optional-settings):
* **org_name**: Name of the organization the report was run for
* **user_name**: Name of a user found in the org as either a Team Member in one of the orgs teams or an active user in one of the repositories found in the org
* **user_has_org_copilot_seat**: whether or not the user has been assigned a copilot seat directly by the org. This does not indicate if the user may have been assigned a copilot seat by another org
* **association**: The association the user has noted in this report. This will either be the name of a Team in the org or the name of a Repository in the org
* **association_type**: The type of association the user has
#### Summary Report
> [!NOTE]
> This will either be **team** indicating the user is a member of a team within the org or **repository** indicating the user is an active user in one of the repositories
This report is intended to summarize members that do not have copilot seats and counts to identify there association with users that do have copilot seats in the organization.
> [!IMPORTANT]
> The TIME_PERIOD configuration value noted in the setup section above determines what time period a user is considered to be an active user
A CSV file named `copilot_associations_summary.csv` is generated for this report containing the data. You will see the following values in the report:
* **member_name**: name of the member that does not have a copilot seat
* **count_teams**: number of teams this member is a member of that has someone with a copilot seat also as a member of that same team
* **count_repos**: number of repositories this member is a contributor in that has someone with a copilot seat that is also a contributor to that repository
* **count_copilot_users**: number of distinct users with a copilot seat that the member is connected to either through a team or a repository
* **total_sum**: count_teams + count_repos + count_copilot, this could be used as a rank and sorted by to determine which members are closer to a higher number of users with copilot seats
* **related_copilot_user_name**: If any other users found within the team or repository have a copilot license they are indicated here as an association to the user that doesn't have a copilot license
> [!NOTE]
> If the value is "Unknown" then this indicates no other active users in the repository or team members were found with a copilot seat for the org
> Use the total_sum column to rank your members, those with a higher number are likely potential opportunities to utilize a copilot seat because of their relationship to users with copilot seats
#### Detailed Report
This report is a more detailed report that helps identify the actual associations between a member without a copilot seat and those that do have a copilot seat.
A CSV file named `copilot_associations_detailed.csv` is generated for this report containing the data. You will see the following values in the report:
* **member_name**: name of the member that does not have a copilot seat
* **association_type**: either team or repository, the association this member has with a user that has a copilot seat
* **association_name**: either the name of the team or name of the repository that links this member to a user with a copilot seat
* **copilot_user**: the user with a copilot seat identified as being linked to a member
> [!NOTE]
> IF the value is "Self" then this indicates this is a user that has a copilot seat assigned from the org any they exist in the repostiory or team. You can filter the report to see what teams and repositories a user with a copilot seat in the org may be currently active in
> Filter the results by copilot_user to see all teams and repositories that user is a member of or is a contributor in
## Settings
Expand All @@ -95,7 +104,7 @@ ORGANIZATION=<your org name here>
### Optional Settings
Optional settings and their defaut values if not specified
Optional settings and their defaut values if not specified that can be added to the `.env.local` file.
```
# the version of the GitHub API to use
Expand All @@ -108,6 +117,18 @@ TIME_PERIOD=month
# any teams to exclude from the results (comma separated list)
EXCLUDE_TEAMS=team1,team2

# true to make the call to generate data, useful to set to false if data already generated and you just want a report
GENERATE_DATA=true

# name of the file to give to generated data file or file to use if you already have one
INPUT_FILE_NAME=copilot-associations.json

# file that will be summary of report
OUTPUT_FILE_NAME=copilot_associations_summary.csv

# file that will contain all details for report
DETAILED_OUTPUT_FILE_NAME=copilot_associations_detailed.csv

# pretty, json, hidden
LOG_TYPE=pretty

Expand Down
144 changes: 144 additions & 0 deletions data/test-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
{
"copilot_seats": [
{ "assignee": "user1", "last_activity_at": "2023-01-01" },
{ "assignee": "user2", "last_activity_at": "2023-01-02" },
{ "assignee": "user3", "last_activity_at": "2023-01-03" },
{ "assignee": "user4", "last_activity_at": "2023-01-04" }
],
"teams": {
"team1": {
"team_name": "team1",
"members": ["member1", "member2", "member3"],
"copilot_users": ["user1"]
},
"team2": {
"team_name": "team2",
"members": ["member4", "member5"],
"copilot_users": ["user2"]
},
"team3": {
"team_name": "team3",
"members": ["member3", "member6"],
"copilot_users": ["user3"]
},
"team4": {
"team_name": "team4",
"members": ["member3", "member5"],
"copilot_users": ["user4"]
},
"team5": {
"team_name": "team5",
"members": ["member3"],
"copilot_users": ["user1"]
},
"team6": {
"team_name": "team6",
"members": ["member1", "member3"],
"copilot_users": ["user2"]
},
"team7": {
"team_name": "team7",
"members": ["member5", "member6"],
"copilot_users": ["user3"]
},
"team8": {
"team_name": "team8",
"members": ["member2"],
"copilot_users": ["user4"]
},
"team9": {
"team_name": "team9",
"members": ["member5", "member6"],
"copilot_users": ["user1"]
},
"team10": {
"team_name": "team10",
"members": ["member3"],
"copilot_users": ["user2"]
},
"team11": {
"team_name": "team11",
"members": ["member1", "member2"],
"copilot_users": ["user3"]
},
"team12": {
"team_name": "team12",
"members": ["member5", "member6"],
"copilot_users": ["user4"]
}
},
"repositories": {
"repo1": {
"repo_owner": "owner1",
"repo_name": "repo1",
"contributors": ["member1", "member2", "member3"],
"associated_copilot_users": ["user1"]
},
"repo2": {
"repo_owner": "owner2",
"repo_name": "repo2",
"contributors": ["member1", "member5"],
"associated_copilot_users": ["user2"]
},
"repo3": {
"repo_owner": "owner3",
"repo_name": "repo3",
"contributors": ["member2", "member3"],
"associated_copilot_users": ["user3"]
},
"repo4": {
"repo_owner": "owner4",
"repo_name": "repo4",
"contributors": ["member1", "member2", "member5"],
"associated_copilot_users": ["user4"]
},
"repo5": {
"repo_owner": "owner5",
"repo_name": "repo5",
"contributors": ["member6"],
"associated_copilot_users": ["user1"]
},
"repo6": {
"repo_owner": "owner6",
"repo_name": "repo6",
"contributors": ["member2"],
"associated_copilot_users": ["user2"]
},
"repo7": {
"repo_owner": "owner7",
"repo_name": "repo7",
"contributors": ["member5", "member6"],
"associated_copilot_users": ["user3"]
},
"repo8": {
"repo_owner": "owner8",
"repo_name": "repo8",
"contributors": ["member2"],
"associated_copilot_users": ["user4"]
},
"repo9": {
"repo_owner": "owner9",
"repo_name": "repo9",
"contributors": ["member5", "member6"],
"associated_copilot_users": ["user1"]
},
"repo10": {
"repo_owner": "owner10",
"repo_name": "repo10",
"contributors": ["member2"],
"associated_copilot_users": ["user2"]
},
"repo11": {
"repo_owner": "owner11",
"repo_name": "repo11",
"contributors": ["member1", "member2"],
"associated_copilot_users": ["user3"]
},
"repo12": {
"repo_owner": "owner12",
"repo_name": "repo12",
"contributors": ["member5", "member6"],
"associated_copilot_users": ["user4"]
}
}
}
9 changes: 8 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import logger from "./shared/app-logger";
import { runCopilotAssociationsReport } from "./report/copilot-associations-report";
import { AppConfig } from "./shared/app-config";
import { App } from "octokit";

// for now one report, more to come
logger.info("START - Running copilot associations report...");
runCopilotAssociationsReport().then((output_file) => {
runCopilotAssociationsReport({
should_generate_data: AppConfig.GENERATE_DATA,
input_file_name: AppConfig.INPUT_FILE_NAME,
output_file_name: AppConfig.OUTPUT_FILE_NAME,
detailed_output_file_name: AppConfig.DETAILED_OUTPUT_FILE_NAME,
}).then((output_file) => {
logger.info(`END - Generated copilot associations report ${output_file}`);
});

Expand Down
Loading

0 comments on commit 90daa72

Please sign in to comment.