Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Rollout Feature #80

Merged
merged 49 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
7d83e61
Initial deployment update
jonjozwiak Jan 8, 2024
957a8ed
Adding logging
jonjozwiak Jan 8, 2024
a5b9537
Adding logging
jonjozwiak Jan 8, 2024
d6b48ec
Adding logging
jonjozwiak Jan 8, 2024
d9adc94
Adding logging
jonjozwiak Jan 8, 2024
97e4c9d
Updating CSV parsing login
jonjozwiak Jan 8, 2024
b1c19cc
Updating CSV parsing login
jonjozwiak Jan 8, 2024
d43485b
Updating CSV parsing login
jonjozwiak Jan 8, 2024
3865445
Updating CSV parsing login
jonjozwiak Jan 8, 2024
edb6d68
Updating CSV parsing login
jonjozwiak Jan 8, 2024
fd0fedb
Updating CSV parsing login
jonjozwiak Jan 8, 2024
ff75e52
Cleanup CSV parsing logic
jonjozwiak Jan 8, 2024
a0678e9
Add date window logic
jonjozwiak Jan 9, 2024
dcfef28
Add date window logic
jonjozwiak Jan 9, 2024
1c0de70
Splitting out getOrgData and getInactiveSeats to allow to save data a…
jonjozwiak Jan 9, 2024
07aa442
Cleanup from function split and adding debug logging
jonjozwiak Jan 9, 2024
8c0c704
Fixing deploy logging
jonjozwiak Jan 9, 2024
6448cd1
Fixing deploy logging
jonjozwiak Jan 9, 2024
ef29374
Adding deploy user capability
jonjozwiak Jan 17, 2024
3d45f96
Adding error trapping and updating dist
jonjozwiak Jan 17, 2024
f576d95
Move get members for each org outside of deployed users loop
jonjozwiak Jan 17, 2024
5048583
Update error for org not found
jonjozwiak Jan 17, 2024
5d99f0a
Update error for org not found
jonjozwiak Jan 17, 2024
21c216d
Update error for org members not found
jonjozwiak Jan 17, 2024
8d2455a
Update error for org members not found
jonjozwiak Jan 17, 2024
3344eb2
Ensuring org must exist for user add attempt
jonjozwiak Jan 17, 2024
6b02957
Troubleshooting user not found in copilot seats
jonjozwiak Jan 17, 2024
78eb07d
Updating error trapping for org members and log groups
jonjozwiak Jan 17, 2024
de86cd6
Updating error trapping for copilot add user
jonjozwiak Jan 17, 2024
2ff4862
Updating error trapping for copilot add user
jonjozwiak Jan 17, 2024
a6a6024
Updating error trapping and API call for copilot add user
jonjozwiak Jan 17, 2024
4cbc718
Updating error trapping and API call for copilot add user
jonjozwiak Jan 17, 2024
9996dac
Updating error trapping for copilot add user
jonjozwiak Jan 17, 2024
f509d47
Change to deploy one user at a time vs async
jonjozwiak Jan 17, 2024
5c52022
Update to continue with each user even if the last failed when deploying
jonjozwiak Jan 17, 2024
e687765
Test adding capture of deployed user
jonjozwiak Jan 17, 2024
a2693be
Test adding capture of deployed user
jonjozwiak Jan 17, 2024
31826e9
Test adding capture of deployed user
jonjozwiak Jan 17, 2024
317fa75
Adding list of deployed users
jonjozwiak Jan 17, 2024
f73e1b2
Troubleshooting re-add of existing seat
jonjozwiak Jan 17, 2024
f681ac5
Updating orgData to retain existing data when adding members
jonjozwiak Jan 17, 2024
180ad41
Adding debug logging for checking existing users
jonjozwiak Jan 18, 2024
5b34691
Adding summary of deployed users and updating readme
jonjozwiak Jan 18, 2024
aa9561e
Updating to redeploy if pending cancellation
jonjozwiak Jan 18, 2024
627a7b7
Updating deployment summary status
jonjozwiak Jan 18, 2024
bf3762d
Updating core summary to avoid printing twice
jonjozwiak Jan 18, 2024
a44db0f
Cleaning up code and updating a few dependencies
jonjozwiak Jan 18, 2024
69f921b
Clean up linting errors
jonjozwiak Jan 18, 2024
1b361d7
Updating readme example
jonjozwiak Jan 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 66 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,30 @@

Run this action on a schedule to automatically remove inactive Copilot licenses. It also creates a report as a job summary and csv.

In addition to this it can also deploy users from a CSV file. This is useful as you are adopting Copilot as it can help facilitate the process of adding users to your organization.

## Usage
Create a workflow (eg: `.github/workflows/copilot-license-cleanup.yml`). See [Creating a Workflow file](https://help.github.com/en/articles/configuring-a-workflow#creating-a-workflow-file).

### Deploying users from a CSV file

If you want to deploy users from a CSV file you will need to create a CSV file with the following columns:
- `organization` - The organization to add the user to
- `deployment_group` - An arbitrary group name used to track the deployments
- `login` - The user's GitHub Login name to add
- `activation_date` - The date the user should be activated (YYYY-MM-DD)

Example:

```csv
organization,deployment_group,login,activation_date
exampleorg1,group1,octocat,2024-01-15
exampleorg1,group1,octodog,2024-01-15
```

This requires the users to already exist as members of the enterprise and target organization.

If you are using Enterprise Managed Users, it may be easier to use a group from your identity provider to manage the users. You can assign the group to a team in an organization and assign that team to Copilot. This will allow you to manage the users in your identity provider and have them automatically added/removed from Copilot as group membership changes.

### PAT(Personal Access Token)

Expand All @@ -29,14 +50,14 @@ jobs:
name: Copilot Seats
runs-on: ubuntu-latest
steps:
- uses: austenstone/copilot-license-cleanup@v1.1
- uses: austenstone/copilot-license-cleanup@v1.2
with:
github-token: ${{ secrets.TOKEN }}
```

#### Example Auto remove
```yml
- uses: austenstone/copilot-license-cleanup@v1.1
- uses: austenstone/copilot-license-cleanup@v1.2
with:
github-token: ${{ secrets.TOKEN }}
remove: true
Expand All @@ -45,7 +66,7 @@ jobs:

#### Example Custom days before inactive
```yml
- uses: austenstone/copilot-license-cleanup@v1.1
- uses: austenstone/copilot-license-cleanup@v1.2
with:
github-token: ${{ secrets.TOKEN }}
remove: true
Expand All @@ -55,23 +76,23 @@ jobs:

#### Example Specifying multiple organizations:
```yml
- uses: austenstone/copilot-license-cleanup@v1.1
- uses: austenstone/copilot-license-cleanup@v1.2
with:
github-token: ${{ secrets.TOKEN }}
organization: exampleorg1, demoorg2, myorg3
```

#### Example specifying a GitHub Enterprise (to run on all organizations in the enterprise):
```yml
- uses: austenstone/copilot-license-cleanup@v1.1
- uses: austenstone/copilot-license-cleanup@v1.2
with:
github-token: ${{ secrets.TOKEN }}
enterprise: octodemo
```

#### Example uploading inactive users JSON artifact
#### Example uploading inactive users JSON artifact (same could be done with deployed-seats)
```yml
- uses: austenstone/copilot-license-cleanup@v1.1
- uses: austenstone/copilot-license-cleanup@v1.2
id: copilot
with:
github-token: ${{ secrets.TOKEN }}
Expand All @@ -85,6 +106,38 @@ jobs:
path: inactive-seats.json
```

#### Example deploying users from a CSV file

```yml
name: Copilot License Review
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
jobs:
copilot:
name: Copilot Seats
runs-on: ubuntu-latest
# Checkout your repo so we can access the CSV file
- name: Checkout code
uses: actions/checkout@v4

- uses: austenstone/[email protected]
id: copilot_job
with:
organization: octodemo, avocadocorp
github-token: ${{ secrets.TOKEN }}
remove: false
remove-from-team: false
inactive-days: 30
deploy-users: true
csv: true
# Optional inputs
deploy-users-dry-run: false # Default is true
deploy-users-csv: ./copilot-users.csv
deploy-validation-time: 3
```

<details>
<summary>Job summary example</summary>

Expand All @@ -106,6 +159,10 @@ Various inputs are defined in [`action.yml`](action.yml):
| inactive&#x2011;days | The number of days to consider a user inactive | 90 |
| job-summary | Whether to output a summary of the job | true |
| csv | Whether to output a CSV of inactive users | false |
| deploy-users | Whether to deploy users from a CSV file | false |
| deploy-users-dry-run | Whether to perform a dry run when deploying users | true |
| deploy-users-csv | CSV file location if deploying users | ./copilot-users.csv |
| deploy-validation-time | The number of days to attempt to deploy the user beyond activation date | 3 |

## ⬅️ Outputs
| Name | Description |
Expand All @@ -114,6 +171,8 @@ Various inputs are defined in [`action.yml`](action.yml):
| inactive-seat-count | The number of inactive seats |
| removed-seats | The number of seats removed |
| seat-count | The total number of seats |
| deployed-seats | JSON array of deployed seats |
| deployed-seat-count | The number of deployed seats |

## How does it work?
We're simply leveraging the [GitHub Copilot API](https://docs.github.com/en/rest/copilot). First we fetch all the Copilot seats and filter them to only inactive seats. Then if the seat is assigned directly we remove it but if it's assigned through a team we remove the user from the team. Those inactive users are reported as a CSV and a job summary table.
Expand Down
20 changes: 20 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ inputs:
description: Whether to output a CSV of the inactive users
default: false
required: false
deploy-users:
description: Whether to deploy users from a CSV file
default: false
required: false
deploy-users-dry-run:
description: Whether to do a dry run of deploying users but not actually deploy
default: true
required: false
deploy-users-csv:
description: CSV file location if deploying users
default: ./copilot-users.csv
required: false
deploy-validation-time:
description: The number of days to attempt to deploy the user beyond activation date
default: 3
required: false

outputs:
inactive-seats:
Expand All @@ -48,6 +64,10 @@ outputs:
description: The number of seats removed
seat-count:
description: The total number of seats
deployed-seats:
description: JSON array of deployed seats
deployed-seat-count:
description: The number of deployed seats

runs:
using: "node16"
Expand Down
Loading
Loading