-
Notifications
You must be signed in to change notification settings - Fork 8
Add label management functionality #549
Description
Context
GitHub repositories use labels to categorize issues and pull requests. Labels are essential for workflow automation, issue triage, and project organization. Organization administrators and automation scripts frequently need to create, update, and manage labels across repositories programmatically.
Request
The GitHub PowerShell module currently has no label-related functions, classes, or types. There is no way to manage repository labels, issue labels, or milestone labels through the module.
Desired capability
Users should be able to perform full CRUD operations on repository labels and manage label associations on issues (including pull requests, since they share the issues API). This includes creating, reading, updating, and deleting labels on repositories, and adding, replacing, or removing labels on individual issues.
REST API endpoints
The following REST API endpoints for labels are involved:
| Method | Endpoint | Description |
|---|---|---|
GET |
/repos/{owner}/{repo}/labels |
List labels for a repository |
GET |
/repos/{owner}/{repo}/labels/{name} |
Get a label |
POST |
/repos/{owner}/{repo}/labels |
Create a label |
PATCH |
/repos/{owner}/{repo}/labels/{name} |
Update a label |
DELETE |
/repos/{owner}/{repo}/labels/{name} |
Delete a label |
GET |
/repos/{owner}/{repo}/issues/{issue_number}/labels |
List labels for an issue |
POST |
/repos/{owner}/{repo}/issues/{issue_number}/labels |
Add labels to an issue |
PUT |
/repos/{owner}/{repo}/issues/{issue_number}/labels |
Set labels for an issue |
DELETE |
/repos/{owner}/{repo}/issues/{issue_number}/labels/{name} |
Remove a label from an issue |
DELETE |
/repos/{owner}/{repo}/issues/{issue_number}/labels |
Remove all labels from an issue |
GET |
/repos/{owner}/{repo}/milestones/{milestone_number}/labels |
List labels for issues in a milestone |
Label object properties
| Property | Type | Description |
|---|---|---|
id |
integer | Label database ID |
node_id |
string | Node ID |
url |
string | API URL |
name |
string | Label name |
description |
string | Label description |
color |
string | Hex color code (without #) |
default |
boolean | Whether this is a default label |
Acceptance criteria
- Repository labels can be listed, retrieved by name, created, updated, and deleted
- Issue labels can be listed, added, replaced (set), and removed (individually and all at once)
- Milestone labels can be listed
- All commands follow module conventions (
Verb-GitHubNoun, pipeline support, context resolution, typed output) GitHubLabelclass output with proper formatting- Tab completion for label names
Technical decisions
Public function design: Consolidate getters into Get-GitHubLabel with parameter sets (following the Get-GitHubTeam pattern), keep issue label operations as separate public functions since they operate on a different resource relationship (issue-label association vs repo-label CRUD):
| Public function | Parameter sets | Description |
|---|---|---|
Get-GitHubLabel |
'List labels for a repository' (default), 'Get a label', 'List labels for an issue', 'List labels for issues in a milestone' |
Consolidated getter |
New-GitHubLabel |
Single | Create a repo label |
Update-GitHubLabel |
Single | Update a repo label |
Set-GitHubLabel |
Single | Upsert a repo label (Get → New or Update) |
Remove-GitHubLabel |
Single | Delete a repo label (ConfirmImpact = 'High') |
Add-GitHubIssueLabel |
Single | Add labels to an issue |
Set-GitHubIssueLabel |
Single | Replace all labels on an issue |
Remove-GitHubIssueLabel |
'Remove a label from an issue', 'Remove all labels from an issue' |
Remove one or all labels |
Parameter naming: The -Issue parameter uses aliases -PullRequest and -PR since every PR is an issue in GitHub's API. This follows module conventions.
Separation of repo vs issue label operations: Add-GitHubIssueLabel, Set-GitHubIssueLabel, and Remove-GitHubIssueLabel remain separate because they manage an association (issue ↔ label) rather than the label resource itself. This follows the Add-GitHubReleaseAsset / Add-GitHubSecretSelectedRepository pattern.
Private functions (one per API endpoint):
| Private function | API endpoint |
|---|---|
Get-GitHubLabelListByRepo |
GET /repos/{o}/{r}/labels |
Get-GitHubLabelByName |
GET /repos/{o}/{r}/labels/{name} |
Get-GitHubLabelListByIssue |
GET /repos/{o}/{r}/issues/{n}/labels |
Get-GitHubLabelListByMilestone |
GET /repos/{o}/{r}/milestones/{n}/labels |
New-GitHubLabelOnRepository |
POST /repos/{o}/{r}/labels |
Update-GitHubLabelOnRepository |
PATCH /repos/{o}/{r}/labels/{name} |
Remove-GitHubLabelFromRepository |
DELETE /repos/{o}/{r}/labels/{name} |
Add-GitHubLabelToIssue |
POST /repos/{o}/{r}/issues/{n}/labels |
Set-GitHubLabelOnIssue |
PUT /repos/{o}/{r}/issues/{n}/labels |
Remove-GitHubLabelFromIssue |
DELETE /repos/{o}/{r}/issues/{n}/labels/{name} |
Remove-GitHubLabelFromIssueAll |
DELETE /repos/{o}/{r}/issues/{n}/labels |
Class design: GitHubLabel class extending GitHubNode (provides ID and NodeID). Properties: Name, Description, Color, Default, Url. Types file adds alias Label → Name.
File structure:
src/
classes/public/GitHubLabel.ps1
formats/GitHubLabel.Format.ps1xml
types/GitHubLabel.Types.ps1xml
functions/
public/Labels/ (8 public functions)
private/Labels/ (11 private functions)
Test approach: Integration tests covering all label operations per auth case.
Implementation plan
Classes and types
- Create
GitHubLabelclass insrc/classes/public/GitHubLabel.ps1 - Create
GitHubLabel.Types.ps1xmlinsrc/types/ - Create
GitHubLabel.Format.ps1xmlinsrc/formats/
Private functions
-
Get-GitHubLabelListByRepo—GET /repos/{o}/{r}/labels -
Get-GitHubLabelByName—GET /repos/{o}/{r}/labels/{name} -
Get-GitHubLabelListByIssue—GET /repos/{o}/{r}/issues/{n}/labels -
Get-GitHubLabelListByMilestone—GET /repos/{o}/{r}/milestones/{n}/labels -
New-GitHubLabelOnRepository—POST /repos/{o}/{r}/labels -
Update-GitHubLabelOnRepository—PATCH /repos/{o}/{r}/labels/{name} -
Remove-GitHubLabelFromRepository—DELETE /repos/{o}/{r}/labels/{name} -
Add-GitHubLabelToIssue—POST /repos/{o}/{r}/issues/{n}/labels -
Set-GitHubLabelOnIssue—PUT /repos/{o}/{r}/issues/{n}/labels -
Remove-GitHubLabelFromIssue—DELETE /repos/{o}/{r}/issues/{n}/labels/{name} -
Remove-GitHubLabelFromIssueAll—DELETE /repos/{o}/{r}/issues/{n}/labels
Public functions
-
Get-GitHubLabel— List repo labels / get by name / list by issue / list by milestone -
New-GitHubLabel— Create a repo label -
Update-GitHubLabel— Update a repo label -
Set-GitHubLabel— Upsert a repo label -
Add-GitHubIssueLabel— Add labels to an issue -
Set-GitHubIssueLabel— Replace all labels on an issue -
Remove-GitHubLabel— Delete a repo label -
Remove-GitHubIssueLabel— Remove a label / all labels from an issue
Completers
- Add tab-completion for label names
Tests
- Integration tests for all label functions
Metadata
Metadata
Labels
Type
Projects
Status