-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🚀 [Feature]: GitHub App creation and installation management (#281)
## Description ### Added functions for Enterprise App management. src/functions/private/Apps/GitHub Apps/Get-GitHubEnterpriseOrganizationAppInstallation.ps1 - Fixes #277 ### General alignments: * Adds a guidance file that defines conventions for a module `CodingStandards.md` - will be promoted to the `docs` repository later. * Remove most re-throw `try{...} catch { throw $_ }` statements. * Fixes #289 * Added `#Requires -Modules` statements to ensure necessary modules are marked as requirements for the module. * Parameter hashtables for Invoke-GitHubAPI is now sorted like: - Method: UPPERCASED - Endpoint - Header related stuff - Body related stuff - Context * Function name aligning: * Parameter name aligning: * Changed `Repo` to `Repository` - throughout the module. The repo abbreviation can still be used, but in classes, object and commands, we standardize on Repository. * Clean up aliases: * Remove all but one alias for Connect/Disconnect-GitHub * Remove org alias for Organization parameters #### Private functions: * Made `Context` mandatory in private functions * Removed `Resolve-GitHubContext` in private functions #### Public functions: - Fixes #297 - Fixes #249 ## Type of change <!-- Use the check-boxes [x] on the options that are relevant. --> - [ ] 📖 [Docs] - [ ] 🪲 [Fix] - [ ] 🩹 [Patch] - [ ]⚠️ [Security fix] - [x] 🚀 [Feature] - [ ] 🌟 [Breaking change] ## Checklist <!-- Use the check-boxes [x] on the options that are relevant. --> - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas
- Loading branch information
1 parent
048b37c
commit e01341e
Showing
258 changed files
with
4,725 additions
and
5,329 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
# Coding Standards for `GitHub` | ||
|
||
Start by reading the general coding standards for [`PSModule`](https://psmodule.io/docs) which is the basis for all modules in the framework. | ||
Additions or adjustments to those defaults are covered in this document to ensure that the modules drive consistancy for all developers. | ||
|
||
## General Coding Standards | ||
|
||
1. **PowerShell Keywords** | ||
- All PowerShell keywords (e.g. `if`, `return`, `throw`, `function`, `param`) **must** be in lowercase. | ||
|
||
2. **Brace Style** | ||
- Use **One True Bracing Style (OTBS)**. | ||
- Opening brace on the same line as the statement; closing brace on its own line. | ||
|
||
3. **Coverage** | ||
- We do **not** need 100% coverage of the GitHub API. | ||
- Maintain a separate file listing the endpoints you intentionally **do not** cover, so the coverage report can mark them accordingly (e.g., ⚠️). | ||
|
||
4. **Convert Filter Types** | ||
- Wherever filters are used, ensure they are implemented as standard PowerShell functions with `begin`, `process`, and `end` blocks. | ||
|
||
--- | ||
|
||
## Functions | ||
|
||
- **Grouping** | ||
- Group functions by the *object type* they handle, using folders named for that object type (e.g. “Repository”), **not** by the API endpoint URL. | ||
|
||
- **Naming** | ||
- Public function name format: **`Verb-GitHubNoun`**. | ||
- Private function name format: **`Verb-GitHubNoun`** (same style but no aliases). | ||
- **`Get-`** functions must **not** include `[CmdletBinding(SupportsShouldProcess)]`. You only use `SupportsShouldProcess` on commands that change or remove data (`Set-`, `Remove-`, `Add-`, etc.). | ||
|
||
- **Default Parameter Sets** | ||
- Do **not** declare `DefaultParameterSetName = '__AllParameterSets'`. | ||
- Only specify a `DefaultParameterSetName` if it is actually different from the first parameter set. | ||
|
||
- **One API Call = One Function** | ||
- If you find that a single function is handling multiple distinct API calls, split it into multiple functions. | ||
|
||
- **Public vs. Private** | ||
1. **Public Functions** | ||
- Support pipeline input if appropriate. | ||
- Should begin by calling `Resolve-GitHubContext` to handle the `Context` parameter, which can be either a string or a `GitHubContext` object. | ||
- Use parameter sets (with `begin`, `process`, `end`) if you have multiple ways to call the same logical operation. | ||
- If choosing among multiple underlying private functions, use a `switch` statement in the `process` block keyed on the parameter set name. | ||
- If a parameter like `$Repository` is missing, you can default to `$Context.Repo`. If no value is found, **throw** an error. | ||
2. **Private Functions** | ||
- **No pipeline input**. | ||
- No aliases on either the function or its parameters. | ||
- **`Context` is mandatory** (type `GitHubContext`), since public functions should already have resolved it. | ||
- **`Owner`, `Organization`, `ID`, `Repository`** are also mandatory if required by the endpoint. | ||
- Must not contain logic to default parameters from `Context`; that is resolved in public functions. | ||
|
||
--- | ||
|
||
## Documentation for Functions | ||
|
||
All function documentation follows standard PowerShell help conventions, with some notes: | ||
|
||
1. **.SYNOPSIS**, **.DESCRIPTION**, **.EXAMPLES** | ||
- Examples in your code should include fencing (e.g., triple backticks) because the PSModule framework removes default fences. | ||
|
||
2. **.PARAMETER** | ||
- Do **not** store parameter documentation in a comment block separate from the parameter. Instead, use inline parameter documentation via the `[Parameter()]` attribute and descriptions in triple-slash (`///`) comments above each parameter. | ||
|
||
3. **.NOTES** | ||
- Include a link to the official documentation (if any) that the function is based on, so it’s discoverable via online help. | ||
|
||
4. **.LINK** | ||
- First link should be the function’s own local documentation (generated for the PowerShell module). | ||
- Additional links can point to official GitHub or API documentation. | ||
|
||
--- | ||
|
||
## Parameter Guidelines | ||
|
||
1. **Always Declare [Parameter()]** | ||
- Every parameter must explicitly have a `[Parameter()]` attribute, even if empty. | ||
- Place these attributes in a consistent order (see **Parameter Attributes Order** below). | ||
|
||
2. **Parameter Types** | ||
- Always specify a type, e.g. `[string] $Owner` (rather than `$Owner` alone). | ||
|
||
3. **Parameter Naming** | ||
- Use **PascalCase** for parameters. | ||
- Convert snake_case from the API docs to **PascalCase** in the function. | ||
- **`ID`** should be the short name. If needed, add an alias for a long form (e.g., `[Alias('SomeLongName')]`) or for a different style (`'id'`, `'Id'`), depending on user expectations. | ||
- If the function name implies the object (e.g., `Get-GitHubRepository`), do **not** name the parameter `RepositoryId`. Just `ID` (or `Name`, etc.) suffices. Keep it object-oriented rather than repeating the context. | ||
- `Owner` should always have the aliases: `Organization` and `User`. | ||
- `Username` can have the alias `Login` if relevant for a particular API. | ||
- Use `Repository` (not `Repo`). If you need an alias for backward compatibility, add `[Alias('Repo')]`. | ||
|
||
4. **Parameter Attribute Order** | ||
1. `[Parameter()]` | ||
2. `[ValidateNotNullOrEmpty()]` or other validation attributes | ||
3. `[Alias()]` if any | ||
4. Then the parameter definition itself: `[string] $ParamName` | ||
|
||
5. **Parameter Defaulting** | ||
- For **public** functions, if the user hasn’t provided a parameter (like `$Repository`), default it from the context: | ||
```powershell | ||
if (-not $Repository) { | ||
$Repository = $Context.Repo | ||
} | ||
if (-not $Repository) { | ||
throw "Repository not specified and not found in the context." | ||
} | ||
``` | ||
- For **private** functions, the calling function should already have done this. Private functions assume mandatory parameters. | ||
6. **Remove `[org]` Alias** | ||
- Do not use `[Alias('org')]` on the `$Organization` parameter. Use `[Alias('User','Organization')]` on `$Owner` instead. | ||
--- | ||
## Function Content & Flow | ||
1. **Structure** | ||
- Always use `begin`, `process`, and `end` blocks. | ||
- **`begin`**: Validate parameters, call `Assert-GitHubContext` if needed, set up any local state. | ||
- Add a comment stating which permissions are required for the API call. | ||
- **`process`**: Main logic, including pipeline handling if public. | ||
- **`end`**: Cleanup if necessary. | ||
2. **ShouldProcess** | ||
- Only use `[CmdletBinding(SupportsShouldProcess)]` for commands that create, update, or remove data. **Do not** apply it to `Get-` commands. | ||
3. **API Method Naming** | ||
- Use PascalCase for the method in your splat (e.g., `Post`, `Delete`, `Put`, `Get`). | ||
- The `Method` property in your hashtable to `Invoke-GitHubAPI` (or other REST calls) should reflect that standard. | ||
4. **Splatting** | ||
- Always splat the API call. The standard order in the splat is: | ||
1. `Method` | ||
2. `APIEndpoint` (or `Endpoint`, with `APIEndpoint` as an alias if necessary) | ||
3. `Body` | ||
4. `Context` | ||
- Body is always a hashtable containing the payload for `POST`, `PATCH`, or `PUT` calls. | ||
5. **Removing String Checks** | ||
- Do **not** use `if ([string]::IsNullOrEmpty($Param))`. Instead, check `-not $Param` or rely on `[ValidateNotNullOrEmpty()]`. | ||
6. **Pipeline Output** | ||
- After calling `Invoke-GitHubAPI @inputObject`, you can **either**: | ||
- `ForEach-Object { Write-Output $_.Response }` | ||
- or `Select-Object -ExpandProperty Response` | ||
- Choose which pattern best fits your scenario, but be consistent within a function. | ||
--- | ||
## Classes | ||
1. **One Class per Resource** | ||
- Each distinct resource type gets its own `.ps1` or `.psm1` with a single class definition. | ||
2. **Property and Method Naming** | ||
- Use PascalCase for all public properties and methods. | ||
3. **Return Types / Interfaces** | ||
- Each class that you return should have a consistent interface. | ||
- Remove any properties that are purely “API wrapper” fields (e.g., raw HTTP artifacts that aren’t relevant to the user). | ||
--- | ||
## Additional Notes | ||
1. **Endpoint Coverage File** | ||
- Maintain a list of endpoints you’re deliberately **not** implementing, so that your coverage reporting can include a ⚠️ for them. | ||
2. **Parameter Name Design** | ||
- Use object-oriented naming that reflects the entity. For example, if the function is `Remove-GitHubRepository`, simply use `-ID` (or `-Name`) rather than `-RepositoryID`. | ||
3. **Aliases** | ||
- Private functions have **no** aliases (function-level or parameter-level). | ||
- Public functions can add aliases where it makes sense (`Owner` has `-User`/`-Organization`, `Repository` might have `-Repo` alias if needed, `Username` might have `-Login`). | ||
4. **Mandatory Context for Private** | ||
- Private functions must always expect a resolved `[GitHubContext] $Context`. Public functions handle any string-based or null context resolution logic. | ||
5. **We Do Not Have to Cover Every Possible API** | ||
- Some endpoints (e.g., “hovercards” or other rarely used features) can be excluded. | ||
--- | ||
That’s it. This spec captures all the bullet points and original guidelines in one place. Use it as the authoritative reference for coding style, function naming, parameter declarations, and general best practices in your module. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.