From 5545d7d185f32c443c29481afeb034a0521cda5d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 17:38:16 +0200 Subject: [PATCH 001/224] Fix --- .github/PSModule.yml | 14 +++++++++ src/formats/GitHubOwner.Format.ps1xml | 6 ++++ src/formats/GitHubRepository.Format.ps1xml | 6 ++++ .../{Releases => }/Get-GitHubReleaseAll.ps1 | 0 .../{Releases => }/Get-GitHubReleaseByID.ps1 | 0 .../Get-GitHubReleaseByTagName.ps1 | 0 .../Get-GitHubReleaseLatest.ps1 | 0 .../{Releases => }/Get-GitHubRelease.ps1 | 9 ++---- .../{Releases => }/New-GitHubRelease.ps1 | 29 +++++++++---------- .../{Releases => }/New-GitHubReleaseNote.ps1 | 11 ++++--- .../{Releases => }/Remove-GitHubRelease.ps1 | 0 .../{Releases => }/Set-GitHubRelease.ps1 | 0 .../Repositories/Get-GitHubRepository.ps1 | 2 +- .../Repositories/New-GitHubRepository.ps1 | 25 +++++----------- 14 files changed, 56 insertions(+), 46 deletions(-) rename src/functions/private/Releases/{Releases => }/Get-GitHubReleaseAll.ps1 (100%) rename src/functions/private/Releases/{Releases => }/Get-GitHubReleaseByID.ps1 (100%) rename src/functions/private/Releases/{Releases => }/Get-GitHubReleaseByTagName.ps1 (100%) rename src/functions/private/Releases/{Releases => }/Get-GitHubReleaseLatest.ps1 (100%) rename src/functions/public/Releases/{Releases => }/Get-GitHubRelease.ps1 (96%) rename src/functions/public/Releases/{Releases => }/New-GitHubRelease.ps1 (84%) rename src/functions/public/Releases/{Releases => }/New-GitHubReleaseNote.ps1 (95%) rename src/functions/public/Releases/{Releases => }/Remove-GitHubRelease.ps1 (100%) rename src/functions/public/Releases/{Releases => }/Set-GitHubRelease.ps1 (100%) diff --git a/.github/PSModule.yml b/.github/PSModule.yml index 6d578178e..fda04e6e0 100644 --- a/.github/PSModule.yml +++ b/.github/PSModule.yml @@ -1,3 +1,17 @@ Test: + SourceCode: + Skip: true + PSModule: + Skip: true + Module: + Skip: true + Windows: + Skip: true + MacOS: + Skip: true CodeCoverage: + Skip: true PercentTarget: 50 +Build: + Docs: + Skip: true diff --git a/src/formats/GitHubOwner.Format.ps1xml b/src/formats/GitHubOwner.Format.ps1xml index 811305706..3eeb337b2 100644 --- a/src/formats/GitHubOwner.Format.ps1xml +++ b/src/formats/GitHubOwner.Format.ps1xml @@ -23,6 +23,9 @@ + + + @@ -42,6 +45,9 @@ Plan + + Url + diff --git a/src/formats/GitHubRepository.Format.ps1xml b/src/formats/GitHubRepository.Format.ps1xml index 5f853e01c..569c20d43 100644 --- a/src/formats/GitHubRepository.Format.ps1xml +++ b/src/formats/GitHubRepository.Format.ps1xml @@ -17,6 +17,9 @@ + + + @@ -33,6 +36,9 @@ Visibility + + Url + [math]::Round($_.Size / 1024, 2) diff --git a/src/functions/private/Releases/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 similarity index 100% rename from src/functions/private/Releases/Releases/Get-GitHubReleaseAll.ps1 rename to src/functions/private/Releases/Get-GitHubReleaseAll.ps1 diff --git a/src/functions/private/Releases/Releases/Get-GitHubReleaseByID.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 similarity index 100% rename from src/functions/private/Releases/Releases/Get-GitHubReleaseByID.ps1 rename to src/functions/private/Releases/Get-GitHubReleaseByID.ps1 diff --git a/src/functions/private/Releases/Releases/Get-GitHubReleaseByTagName.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 similarity index 100% rename from src/functions/private/Releases/Releases/Get-GitHubReleaseByTagName.ps1 rename to src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 diff --git a/src/functions/private/Releases/Releases/Get-GitHubReleaseLatest.ps1 b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 similarity index 100% rename from src/functions/private/Releases/Releases/Get-GitHubReleaseLatest.ps1 rename to src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 diff --git a/src/functions/public/Releases/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 similarity index 96% rename from src/functions/public/Releases/Releases/Get-GitHubRelease.ps1 rename to src/functions/public/Releases/Get-GitHubRelease.ps1 index ede7522d6..e8d409ad1 100644 --- a/src/functions/public/Releases/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -28,7 +28,9 @@ Gets the release with the ID '1234567' for the repository 'hello-world' owned by 'octocat'. - .NOTES + .LINK + https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ + [List releases](https://docs.github.com/rest/releases/releases#list-releases) [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) #> @@ -37,8 +39,6 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. @@ -62,7 +62,6 @@ Mandatory, ParameterSetName = 'Tag' )] - [Alias('tag_name')] [string] $Tag, # The unique identifier of the release. @@ -70,7 +69,6 @@ Mandatory, ParameterSetName = 'ID' )] - [Alias('release_id')] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -101,7 +99,6 @@ Get-GitHubReleaseByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context } } - } end { diff --git a/src/functions/public/Releases/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 similarity index 84% rename from src/functions/public/Releases/Releases/New-GitHubRelease.ps1 rename to src/functions/public/Releases/New-GitHubRelease.ps1 index 021a3900a..13a8cc550 100644 --- a/src/functions/public/Releases/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -15,7 +15,10 @@ Creates a release for the repository 'octocat/hello-world' with the tag 'v1.0.0' and the target commitish 'main'. - .NOTES + .LINK + https://psmodule.io/GitHub/Functions/Releases/New-GitHubRelease/ + + .LINK [Create a release](https://docs.github.com/rest/releases/releases#create-a-release) #> [OutputType([pscustomobject])] @@ -24,8 +27,6 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. @@ -34,14 +35,12 @@ # The name of the tag. [Parameter(Mandatory)] - [Alias('tag_name')] [string] $TagName, # Specifies the commitish value that determines where the Git tag is created from. # Can be any branch or commit SHA. Unused if the Git tag already exists. # API Default: the repository's default branch. [Parameter()] - [Alias('target_commitish')] [string] $TargetCommitish = 'main', # The name of the release. @@ -64,19 +63,19 @@ # The value must be a category that already exists in the repository. # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). [Parameter()] - [Alias('discussion_category_name')] [string] $DiscussionCategoryName, - # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise,a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. + # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, + # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. [Parameter()] - [Alias('generate_release_notes')] [switch] $GenerateReleaseNotes, - # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation date and higher semantic version. + # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. + # Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation + # date and higher semantic version. [Parameter()] - [Alias('make_latest')] [ValidateSet('true', 'false', 'legacy')] - [string] $MakeLatest = 'true', + [string] $Latest = 'true', # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -98,10 +97,10 @@ name = $Name body = $Body discussion_category_name = $DiscussionCategoryName - make_latest = $MakeLatest - generate_release_notes = $GenerateReleaseNotes - draft = $Draft - prerelease = $Prerelease + make_latest = $Latest + generate_release_notes = [bool]$GenerateReleaseNotes + draft = [bool]$Draft + prerelease = [bool]$Prerelease } $body | Remove-HashtableEntry -NullOrEmptyValues diff --git a/src/functions/public/Releases/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 similarity index 95% rename from src/functions/public/Releases/Releases/New-GitHubReleaseNote.ps1 rename to src/functions/public/Releases/New-GitHubReleaseNote.ps1 index 849b1ed34..cd9f55a5e 100644 --- a/src/functions/public/Releases/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 @@ -48,7 +48,10 @@ The release notes will be based on the changes between the tags 'v0.9.2' and 'v1.0.0' and generated based on the configuration file located in the repository at '.github/custom_release_config.yml'. - .NOTES + .LINK + https://psmodule.io/GitHub/Functions/Releases/New-GitHubReleaseNote/ + + .LINK [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#list-releases) #> [OutputType([pscustomobject])] @@ -68,20 +71,17 @@ # The tag name for the release. This can be an existing tag or a new one. [Parameter(Mandatory)] - [Alias('tag_name')] [string] $TagName, # Specifies the commitish value that will be the target for the release's tag. # Required if the supplied tag_name does not reference an existing tag. # Ignored if the tag_name already exists. [Parameter()] - [Alias('target_commitish')] [string] $TargetCommitish, # The name of the previous tag to use as the starting point for the release notes. # Use to manually specify the range for the set of changes considered as part this release. [Parameter()] - [Alias('previous_tag_name')] [string] $PreviousTagName, @@ -89,7 +89,6 @@ # If unspecified, the configuration file located in the repository at '.github/release.yml' or '.github/release.yaml' will be used. # If that is not present, the default configuration will be used. [Parameter()] - [Alias('configuration_file_path')] [string] $ConfigurationFilePath, # The context to run the command in. Used to get the details for the API call. @@ -120,7 +119,7 @@ Body = $body } - if ($PSCmdlet.ShouldProcess("$Owner/$Repository", 'Create release notes')) { + if ($PSCmdlet.ShouldProcess("release notes for release on $Owner/$Repository", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } diff --git a/src/functions/public/Releases/Releases/Remove-GitHubRelease.ps1 b/src/functions/public/Releases/Remove-GitHubRelease.ps1 similarity index 100% rename from src/functions/public/Releases/Releases/Remove-GitHubRelease.ps1 rename to src/functions/public/Releases/Remove-GitHubRelease.ps1 diff --git a/src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 similarity index 100% rename from src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 rename to src/functions/public/Releases/Set-GitHubRelease.ps1 diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 4ce8739d3..8c49e434c 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -63,7 +63,7 @@ filter Get-GitHubRepository { # Default: owner, collaborator, organization_member [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] [ValidateSet('owner', 'collaborator', 'organization_member')] - [string[]] $Affiliation = @('owner', 'collaborator', 'organization_member'), + [string[]] $Affiliation = 'owner', # A repository ID. Only return repositories with an ID greater than this ID. [Parameter(ParameterSetName = 'ListByID')] diff --git a/src/functions/public/Repositories/New-GitHubRepository.ps1 b/src/functions/public/Repositories/New-GitHubRepository.ps1 index 1efad5036..b5189db87 100644 --- a/src/functions/public/Repositories/New-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/New-GitHubRepository.ps1 @@ -124,30 +124,21 @@ filter New-GitHubRepository { [string] $Name, # The account owner of the template repository. The name is not case sensitive. - [Parameter( - Mandatory, - ParameterSetName = 'template' - )] + [Parameter(Mandatory, ParameterSetName = 'template')] [string] $TemplateOwner, # The name of the template repository without the .git extension. The name is not case sensitive. - [Parameter( - Mandatory, - ParameterSetName = 'template' + [Parameter(Mandatory, ParameterSetName = 'template' )] [string] $TemplateRepository, # The account owner of the repository. The name is not case sensitive. - [Parameter( - Mandatory, - ParameterSetName = 'fork' + [Parameter(Mandatory, ParameterSetName = 'fork' )] [string] $ForkOwner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter( - Mandatory, - ParameterSetName = 'fork' + [Parameter(Mandatory, ParameterSetName = 'fork' )] [string] $ForkRepo, @@ -216,7 +207,7 @@ filter New-GitHubRepository { # Pass true to create an initial commit with empty README. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] - [switch] $AutoInit, + [switch] $AddReadme, # Whether to allow squash merges for pull requests. [Parameter(ParameterSetName = 'user')] @@ -287,8 +278,7 @@ filter New-GitHubRepository { $DynamicParamDictionary = New-DynamicParamDictionary $dynParam = @{ - Name = 'GitignoreTemplate' - Alias = 'gitignore_template' + Name = 'Gitignore' Type = [string] ValidateSet = Get-GitHubGitignore DynamicParamDictionary = $DynamicParamDictionary @@ -296,8 +286,7 @@ filter New-GitHubRepository { New-DynamicParam @dynParam $dynParam2 = @{ - Name = 'LicenseTemplate' - Alias = 'license_template' + Name = 'License' Type = [string] ValidateSet = Get-GitHubLicense | Select-Object -ExpandProperty key DynamicParamDictionary = $DynamicParamDictionary From f6c80c1ee2824bcce205286d19bed41566bbee23 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 19:03:32 +0200 Subject: [PATCH 002/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20XML=20t?= =?UTF-8?q?ype=20definitions=20for=20GitHubWorkflow=20and=20GitHubWorkflow?= =?UTF-8?q?Run?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/GitHubWorkflow.Types.ps1xml | 12 ++++++++++++ src/types/GitHubWorkflowRun.Types.ps1xml | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/types/GitHubWorkflow.Types.ps1xml create mode 100644 src/types/GitHubWorkflowRun.Types.ps1xml diff --git a/src/types/GitHubWorkflow.Types.ps1xml b/src/types/GitHubWorkflow.Types.ps1xml new file mode 100644 index 000000000..cd6ddb51a --- /dev/null +++ b/src/types/GitHubWorkflow.Types.ps1xml @@ -0,0 +1,12 @@ + + + + GitHubWorkflow + + + Workflow + $this.ID + + + + diff --git a/src/types/GitHubWorkflowRun.Types.ps1xml b/src/types/GitHubWorkflowRun.Types.ps1xml new file mode 100644 index 000000000..0a65f47a4 --- /dev/null +++ b/src/types/GitHubWorkflowRun.Types.ps1xml @@ -0,0 +1,12 @@ + + + + GitHubWorkflowRun + + + WorkflowRun + $this.ID + + + + From fc39c44da25898d14f9d33a56a15eeab0e0bf622 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 19:07:45 +0200 Subject: [PATCH 003/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20para?= =?UTF-8?q?meter=20names=20and=20descriptions=20in=20artifact=20functions?= =?UTF-8?q?=20for=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/Artifacts/Get-GitHubArtifact.ps1 | 52 +++++++++++-------- .../Artifacts/Remove-GitHubArtifact.ps1 | 4 -- .../public/Artifacts/Save-GitHubArtifact.ps1 | 46 ++++++++++------ 3 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/functions/public/Artifacts/Get-GitHubArtifact.ps1 b/src/functions/public/Artifacts/Get-GitHubArtifact.ps1 index 23984b9bf..02cb653be 100644 --- a/src/functions/public/Artifacts/Get-GitHubArtifact.ps1 +++ b/src/functions/public/Artifacts/Get-GitHubArtifact.ps1 @@ -5,7 +5,7 @@ function Get-GitHubArtifact { .DESCRIPTION .EXAMPLE - Get-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' -ArtifactID '123456' + Get-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' -ID '123456' Output: ```powershell @@ -15,10 +15,10 @@ function Get-GitHubArtifact { CreatedAt : 2024-12-01T10:00:00Z ``` - Retrieves a single GitHub Actions artifact using its unique ArtifactID. + Retrieves a single GitHub Actions artifact using its unique artifact ID. .EXAMPLE - Get-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' -ID '987654321' -AllVersions + Get-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' -WorkflowRunID '987654321' Output: ```powershell @@ -28,7 +28,25 @@ function Get-GitHubArtifact { CreatedAt : 2025-01-15T15:25:00Z ``` - Retrieves all versions of artifacts from the specified workflow run. + Retrieves the latest version of all artifacts from the specified workflow run. + + .EXAMPLE + Get-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' -WorkflowRunID '987654321' -AllVersions + + Output: + ```powershell + Name : test-results + ID : 4564584673 + SizeInBytes : 4096 + CreatedAt : 2025-01-15T14:25:00Z + + Name : test-results + ID : 4564584674 + SizeInBytes : 4096 + CreatedAt : 2025-01-15T15:25:00Z + ``` + + Retrieves the latest version of all artifacts from the specified workflow run. .EXAMPLE Get-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' @@ -57,33 +75,25 @@ function Get-GitHubArtifact { [CmdletBinding(DefaultParameterSetName = 'FromRepository')] param( # The owner of the repository (GitHub user or org name). - [Parameter(Mandatory, ParameterSetName = 'ById')] + [Parameter(Mandatory, ParameterSetName = 'ById', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'FromWorkflowRun', ValueFromPipelineByPropertyName)] - [Parameter(Mandatory, ParameterSetName = 'FromRepository')] + [Parameter(Mandatory, ParameterSetName = 'FromRepository', ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. - [Parameter(Mandatory, ParameterSetName = 'ById')] + [Parameter(Mandatory, ParameterSetName = 'ById', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'FromWorkflowRun', ValueFromPipelineByPropertyName)] - [Parameter(Mandatory, ParameterSetName = 'FromRepository')] + [Parameter(Mandatory, ParameterSetName = 'FromRepository', ValueFromPipelineByPropertyName)] [string] $Repository, # Retrieves a single artifact by its unique ID. - [Parameter( - Mandatory, - ParameterSetName = 'ById', - ValueFromPipelineByPropertyName - )] - [string] $ArtifactID, + [Parameter(Mandatory, ParameterSetName = 'ById', ValueFromPipelineByPropertyName)] + [string] $ID, # Retrieves artifacts from a specific workflow run. - [Parameter( - Mandatory, - ParameterSetName = 'FromWorkflowRun', - ValueFromPipelineByPropertyName - )] - [Alias('WorkflowRunID', 'RunID', 'DatabaseID')] - [string] $ID, + [Parameter(Mandatory, ParameterSetName = 'FromWorkflowRun', ValueFromPipelineByPropertyName)] + [Alias('WorkflowRun')] + [string] $WorkflowRunId, # Retrieves artifacts by name or all artifacts across a repo. [Parameter(ParameterSetName = 'FromRepository')] diff --git a/src/functions/public/Artifacts/Remove-GitHubArtifact.ps1 b/src/functions/public/Artifacts/Remove-GitHubArtifact.ps1 index b69c20f46..accbca68d 100644 --- a/src/functions/public/Artifacts/Remove-GitHubArtifact.ps1 +++ b/src/functions/public/Artifacts/Remove-GitHubArtifact.ps1 @@ -43,16 +43,12 @@ function Remove-GitHubArtifact { # The unique identifier of the artifact. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] - [Alias('ArtifactID', 'DatabaseID')] [string] $ID, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] [object] $Context = (Get-GitHubContext) - - # [Parameter(Mandatory)] - # [object] $Context ) begin { diff --git a/src/functions/public/Artifacts/Save-GitHubArtifact.ps1 b/src/functions/public/Artifacts/Save-GitHubArtifact.ps1 index 21d2f9350..28a934d9d 100644 --- a/src/functions/public/Artifacts/Save-GitHubArtifact.ps1 +++ b/src/functions/public/Artifacts/Save-GitHubArtifact.ps1 @@ -1,13 +1,12 @@ function Save-GitHubArtifact { <# .SYNOPSIS - Downloads a GitHub Actions artifact from a workflow run. + Downloads a GitHub Actions artifact. .DESCRIPTION - Retrieves a specific artifact associated with a workflow run in the specified GitHub repository. - The artifact is downloaded as a ZIP file to the specified path or the current directory by default. - Users must have read access to the repository. For private repositories, personal access tokens (classic) - or OAuth tokens with the `repo` scope are required. + Downloads an artifact from a repository. The artifact is downloaded as a ZIP file to the specified path + or the current directory by default. Users must have read access to the repository. For private repositories, + personal access tokens (classic) or OAuth tokens with the `repo` scope are required. .EXAMPLE Save-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' -ID '123456' -Path 'C:\Artifacts' @@ -21,6 +20,20 @@ function Save-GitHubArtifact { d----- 03/31/2025 12:00 artifact-123456.zip ``` + Downloads artifact ID '123456' from the 'Hello-World' repository owned by 'octocat' to the specified path. + + .EXAMPLE + Save-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' -Name 'module' -Path 'C:\Artifacts\module' -Expand -Cleanup + + Output: + ```powershell + Directory: C:\Artifacts + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + d----- 03/31/2025 12:00 artifact-123456.zip + ``` + Downloads artifact ID 123456 from the 'Hello-World' repository owned by 'octocat' to the specified path. .INPUTS @@ -52,7 +65,6 @@ function Save-GitHubArtifact { # The unique identifier of the artifact. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] - [Alias('ArtifactID', 'DatabaseID')] [string] $ID, # Path to the file or folder for the download. Accepts relative or absolute paths. @@ -64,9 +76,9 @@ function Save-GitHubArtifact { [Alias('Extract')] [switch] $Expand, - # When specified (and only meaningful if -Expand is also used), removes the ZIP file after extracting. + # When specified, the zip file or the folder where the zip file was extracted to is returned. [Parameter()] - [switch] $Cleanup, + [switch] $PassThru, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -113,16 +125,16 @@ function Save-GitHubArtifact { [System.IO.File]::WriteAllBytes($Path, $_.Response) if ($Expand) { - $destFolder = Join-Path -Path $folder -ChildPath ([System.IO.Path]::GetFileNameWithoutExtension($Path)) - Write-Debug "Expanding artifact [$Path] to [$destFolder]" - Expand-Archive -LiteralPath $Path -DestinationPath $destFolder -Force -PassThru - - if ($Cleanup) { - Write-Debug "Removing downloaded ZIP [$Path]" - Remove-Item -LiteralPath $Path -Force + Write-Debug "Expanding artifact to [$folder]" + Expand-Archive -LiteralPath $Path -DestinationPath $folder -Force + Write-Debug "Removing downloaded ZIP [$Path]" + Remove-Item -LiteralPath $Path -Force + if ($PassThru) { + return $folder } - } else { - Get-Item -Path $Path + } + if ($PassThru) { + return Get-Item -Path $Path } } } From fa57a1a5f2db308b7a4cf515e403b156bd84cb5d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 21:43:04 +0200 Subject: [PATCH 004/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20input?= =?UTF-8?q?=20documentation=20and=20improve=20parameter=20binding=20in=20G?= =?UTF-8?q?et-GitHubRepository=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 3 + .../Repositories/Get-GitHubMyRepositories.ps1 | 12 +-- .../Get-GitHubRepositoryListByID.ps1 | 4 +- .../Get-GitHubRepositoryListByOrg.ps1 | 12 +-- .../Get-GitHubRepositoryListByUser.ps1 | 13 +-- .../New-GitHubRepositoryAsFork.ps1 | 25 +++-- .../New-GitHubRepositoryFromTemplate.ps1 | 3 - .../Repositories/New-GitHubRepositoryOrg.ps1 | 92 ++++--------------- .../Repositories/New-GitHubRepositoryUser.ps1 | 62 +++---------- .../Members/Get-GitHubOrganizationMember.ps1 | 2 +- ...et-GitHubOrganizationPendingInvitation.ps1 | 2 +- .../New-GitHubOrganizationInvitation.ps1 | 8 +- .../Remove-GitHubOrganizationInvitation.ps1 | 18 +++- .../Repositories/Get-GitHubRepository.ps1 | 42 ++++----- .../Repositories/New-GitHubRepository.ps1 | 45 ++++----- src/types/GitHubUser.Types.ps1xml | 16 ++++ tools/utilities/Local-Testing.ps1 | 4 +- 17 files changed, 137 insertions(+), 226 deletions(-) create mode 100644 examples/Artifacts/SaveArtifacts.ps1 create mode 100644 src/types/GitHubUser.Types.ps1xml diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 new file mode 100644 index 000000000..6e96665ad --- /dev/null +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -0,0 +1,3 @@ +$modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 +Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | + Save-GitHubArtifact -Path $modulesPath -Extract diff --git a/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 b/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 index 4602d4315..7b7b34a98 100644 --- a/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 +++ b/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 @@ -61,9 +61,7 @@ [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Private function, not exposed to user.')] param( # Limit results to repositories with the specified visibility. - [Parameter( - ParameterSetName = 'Aff-Vis' - )] + [Parameter(ParameterSetName = 'Aff-Vis')] [ValidateSet('all', 'public', 'private')] [string] $Visibility = 'all', @@ -73,16 +71,12 @@ # - organization_member: Repositories that the user has access to through being a member of an organization. # This includes every repository on every team that the user is on. # Default: owner, collaborator, organization_member - [Parameter( - ParameterSetName = 'Aff-Vis' - )] + [Parameter(ParameterSetName = 'Aff-Vis')] [ValidateSet('owner', 'collaborator', 'organization_member')] [string[]] $Affiliation = @('owner', 'collaborator', 'organization_member'), # Specifies the types of repositories you want returned. - [Parameter( - ParameterSetName = 'Type' - )] + [Parameter(ParameterSetName = 'Type')] [ValidateSet('all', 'owner', 'public', 'private', 'member')] [string] $Type = 'all', diff --git a/src/functions/private/Repositories/Get-GitHubRepositoryListByID.ps1 b/src/functions/private/Repositories/Get-GitHubRepositoryListByID.ps1 index 3de5b8856..1e9f2630a 100644 --- a/src/functions/private/Repositories/Get-GitHubRepositoryListByID.ps1 +++ b/src/functions/private/Repositories/Get-GitHubRepositoryListByID.ps1 @@ -1,7 +1,7 @@ filter Get-GitHubRepositoryListByID { <# .SYNOPSIS - List public repositories + List public repositories. .DESCRIPTION Lists all public repositories in the order that they were created. @@ -13,7 +13,7 @@ to get the URL for the next page of repositories. .EXAMPLE - Get-GitHubRepositoryListByID -Since '123456789 + Get-GitHubRepositoryListByID -Since 123456789 Gets the repositories with an ID equals and greater than 123456789. diff --git a/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 b/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 index e54235048..e20f8af7e 100644 --- a/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 +++ b/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 @@ -1,7 +1,7 @@ filter Get-GitHubRepositoryListByOrg { <# .SYNOPSIS - List organization repositories + List organization repositories. .DESCRIPTION Lists repositories for the specified organization. @@ -10,17 +10,17 @@ For more information, see "[Managing security managers in your organization](https://docs.github.com/organizations/managing-peoples-access-to-your-organization-with-roles/managing-security-managers-in-your-organization)." .EXAMPLE - Get-GitHubRepositoryListByOrg -Owner 'octocat' + Get-GitHubRepositoryListByOrg -Organization 'octocat' Gets the repositories for the organization 'octocat'. .EXAMPLE - Get-GitHubRepositoryListByOrg -Owner 'octocat' -Type 'public' + Get-GitHubRepositoryListByOrg -Organization 'octocat' -Type 'public' Gets the public repositories for the organization 'octocat'. .EXAMPLE - Get-GitHubRepositoryListByOrg -Owner 'octocat' -Sort 'created' -Direction 'asc' + Get-GitHubRepositoryListByOrg -Organization 'octocat' -Sort 'created' -Direction 'asc' Gets the repositories for the organization 'octocat' sorted by creation date in ascending order. @@ -36,7 +36,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [string] $Owner, + [string] $Organization, # Specifies the types of repositories you want returned. [Parameter()] @@ -81,7 +81,7 @@ $inputObject = @{ Method = 'GET' - APIEndpoint = "/orgs/$Owner/repos" + APIEndpoint = "/orgs/$Organization/repos" Body = $body Context = $Context } diff --git a/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 b/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 index 817d44488..7321a9977 100644 --- a/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 +++ b/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 @@ -32,28 +32,23 @@ [CmdletBinding()] param( # The handle for the GitHub user account. - [Parameter( - Mandatory, - ValueFromPipeline, - ValueFromPipelineByPropertyName - )] - [Alias('login')] + [Parameter(Mandatory)] [string] $Username, # Specifies the types of repositories you want returned. [Parameter()] - [validateSet('all', 'owner', 'member')] + [ValidateSet('all', 'owner', 'member')] [string] $Type = 'all', # The property to sort the results by. [Parameter()] - [validateSet('created', 'updated', 'pushed', 'full_name')] + [ValidateSet('created', 'updated', 'pushed', 'full_name')] [string] $Sort = 'created', # The order to sort by. # Default: asc when using full_name, otherwise desc. [Parameter()] - [validateSet('asc', 'desc')] + [ValidateSet('asc', 'desc')] [string] $Direction, # The number of results per page (max 100). diff --git a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 index 314c9c9ac..666e1f684 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 @@ -13,23 +13,23 @@ repositories and on the source account with access to the source repository. .EXAMPLE - New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' + New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepository 'Hello-World' Fork the repository `Hello-World` owned by `github` for the authenticated user. Repo will be named `Hello-World`, and all branches and tags will be forked. .EXAMPLE - New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' -Name 'Hello-World-2' + New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepository 'Hello-World' -Name 'Hello-World-2' Fork the repository `Hello-World` owned by `github` for the authenticated user, naming the resulting repository `Hello-World-2`. .EXAMPLE - New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' -Organization 'octocat' + New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepository 'Hello-World' -Owner 'octocat' Fork the repository `Hello-World` owned by `github` for the organization `octocat`, naming the resulting repository `Hello-World`. .EXAMPLE - New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' -DefaultBranchOnly + New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepository 'Hello-World' -DefaultBranchOnly Fork the repository `Hello-World` owned by `github` for the authenticated user, forking only the default branch. @@ -42,18 +42,18 @@ [OutputType([GitHubRepository])] [CmdletBinding(SupportsShouldProcess)] param( - # The account owner of the repository. The name is not case sensitive. + # The account ForkOwner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [string] $Owner, + [string] $ForkOwner, # The name of the repository without the .git extension. The name is not case sensitive. [Parameter(Mandatory)] - [string] $Repository, + [string] $ForkRepository, # The organization or person who will own the new repository. # To create a new repository in an organization, the authenticated user must be a member of the specified organization. - [Parameter(Mandatory)] - [string] $Organization, + [Parameter()] + [string] $Owner, # The name of the new repository. [Parameter()] @@ -61,7 +61,6 @@ # When forking from an existing repository, fork with only the default branch. [Parameter()] - [Alias('default_branch_only')] [switch] $DefaultBranchOnly, # The context to run the command in. Used to get the details for the API call. @@ -78,19 +77,19 @@ process { $body = @{ - organization = $Organization + organization = $Owner name = $Name default_branch_only = $DefaultBranchOnly } $inputObject = @{ Method = 'POST' - APIEndpoint = "/repos/$Owner/$Repository/forks" + APIEndpoint = "/repos/$ForkOwner/$ForkRepository/forks" Body = $body Context = $Context } - if ($PSCmdlet.ShouldProcess("Repository [$Organization/$Name] as fork of [$Owner/$Repository]", 'Create')) { + if ($PSCmdlet.ShouldProcess("Repository [$Owner/$Name] as fork of [$ForkOwner/$ForkRepository]", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { [GitHubRepository]::New($_.Response) } diff --git a/src/functions/private/Repositories/New-GitHubRepositoryFromTemplate.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryFromTemplate.ps1 index 50f96c81d..a67efc639 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryFromTemplate.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryFromTemplate.ps1 @@ -42,12 +42,10 @@ param( # The account owner of the template repository. The name is not case sensitive. [Parameter(Mandatory)] - [Alias('template_owner')] [string] $TemplateOwner, # The name of the template repository without the .git extension. The name is not case sensitive. [Parameter(Mandatory)] - [Alias('template_repo')] [string] $TemplateRepo, # The organization or person who will own the new repository. @@ -66,7 +64,6 @@ # Set to true to include the directory structure and files from all branches in the template repository, # and not just the default branch. [Parameter()] - [Alias('include_all_branches')] [switch] $IncludeAllBranches, # Either true to create a new private repository or false to create a new public one. diff --git a/src/functions/private/Repositories/New-GitHubRepositoryOrg.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryOrg.ps1 index e9cacfe9b..21f0d0985 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryOrg.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryOrg.ps1 @@ -1,6 +1,4 @@ -#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } - -filter New-GitHubRepositoryOrg { +filter New-GitHubRepositoryOrg { <# .SYNOPSIS Create an organization repository @@ -26,7 +24,7 @@ filter New-GitHubRepositoryOrg { HasWiki = $true HasDownloads = $true IsTemplate = $true - AutoInit = $true + AddReadme = $true AllowSquashMerge = $true AllowAutoMerge = $true DeleteBranchOnMerge = $true @@ -37,38 +35,18 @@ filter New-GitHubRepositoryOrg { Creates a new public repository named "Hello-World" owned by the organization "PSModule". - .PARAMETER GitignoreTemplate - Desired language or platform .gitignore template to apply. Use the name of the template without the extension. For example, "Haskell". - - .PARAMETER LicenseTemplate - Choose an open source license template that best suits your needs, and then use the license keyword as the license_template string. - For example, "mit" or "mpl-2.0". - .OUTPUTS GitHubRepository .LINK [Create an organization repository](https://docs.github.com/rest/repos/repos#create-an-organization-repository) - #> [OutputType([GitHubRepository])] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSUseDeclaredVarsMoreThanAssignments', - 'GitignoreTemplate', - Justification = 'Parameter is used in dynamic parameter validation.' - )] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSUseDeclaredVarsMoreThanAssignments', - 'LicenseTemplate', - Justification = 'Parameter is used in dynamic parameter validation.' - )] [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] - [string] $Owner, + [string] $Organization, # The name of the repository. [Parameter(Mandatory)] @@ -80,75 +58,70 @@ filter New-GitHubRepositoryOrg { # A URL with more information about the repository. [Parameter()] - [ValidateNotNullOrEmpty()] [uri] $Homepage, # The visibility of the repository. [Parameter()] - [ValidateSet('public', 'private')] + [ValidateSet('public', 'private', 'internal')] [string] $Visibility = 'public', # Either true to enable issues for this repository or false to disable them. [Parameter()] - [Alias('has_issues')] [switch] $HasIssues, # Either true to enable projects for this repository or false to disable them. # Note: If you're creating a repository in an organization that has disabled repository projects, the default is false, # and if you pass true, the API returns an error. [Parameter()] - [Alias('has_projects')] [switch] $HasProjects, # Either true to enable the wiki for this repository or false to disable it. [Parameter()] - [Alias('has_wiki')] [switch] $HasWiki, # Whether downloads are enabled. [Parameter()] - [Alias('has_downloads')] [switch] $HasDownloads, # Either true to make this repo available as a template repository or false to prevent it. [Parameter()] - [Alias('is_template')] [switch] $IsTemplate, # The ID of the team that will be granted access to this repository. This is only valid when creating a repository in an organization. [Parameter()] - [Alias('team_id')] [System.Nullable[int]] $TeamId, # Pass true to create an initial commit with empty README. [Parameter()] - [Alias('auto_init')] - [switch] $AutoInit, + [switch] $AddReadme, + + # The desired language or platform to apply to the .gitignore. + [Parameter()] + [string] $Gitignore, + + #The license keyword of the open source license for this repository. + [Parameter()] + [string] $License, # Either true to allow squash-merging pull requests, or false to prevent squash-merging. [Parameter()] - [Alias('allow_squash_merge')] [switch] $AllowSquashMerge, # Either true to allow merging pull requests with a merge commit, or false to prevent merging pull requests with merge commits. [Parameter()] - [Alias('allow_merge_commit')] [switch] $AllowMergeCommit, # Either true to allow rebase-merging pull requests, or false to prevent rebase-merging. [Parameter()] - [Alias('allow_rebase_merge')] [switch] $AllowRebaseMerge, # Either true to allow auto-merge on pull requests, or false to disallow auto-merge. [Parameter()] - [Alias('allow_auto_merge')] [switch] $AllowAutoMerge, # Either true to allow automatically deleting head branches when pull requests are merged, or false to prevent automatic deletion. # The authenticated user must be an organization owner to set this property to true. [Parameter()] - [Alias('delete_branch_on_merge')] [switch] $DeleteBranchOnMerge, # The default value for a squash merge commit title: @@ -156,7 +129,6 @@ filter New-GitHubRepositoryOrg { # - COMMIT_OR_PR_TITLE - default to the commit's title (if only one commit) or the pull request's title (when more than one commit). [Parameter()] [ValidateSet('PR_TITLE', 'COMMIT_OR_PR_TITLE')] - [Alias('squash_merge_commit_title')] [string] $SquashMergeCommitTitle, # The default value for a squash merge commit message: @@ -165,7 +137,6 @@ filter New-GitHubRepositoryOrg { # - BLANK - default to a blank commit message. [Parameter()] [ValidateSet('PR_BODY', 'COMMIT_MESSAGES', 'BLANK')] - [Alias('squash_merge_commit_message')] [string] $SquashMergeCommitMessage, # The default value for a merge commit title. @@ -173,7 +144,6 @@ filter New-GitHubRepositoryOrg { # - MERGE_MESSAGE - default to the classic title for a merge message (e.g.,Merge pull request #123 from branch-name). [Parameter()] [ValidateSet('PR_TITLE', 'MERGE_MESSAGE')] - [Alias('merge_commit_title')] [string] $MergeCommitTitle, # The default value for a merge commit message. @@ -182,7 +152,6 @@ filter New-GitHubRepositoryOrg { # - BLANK - default to a blank commit message. [Parameter()] [ValidateSet('PR_BODY', 'PR_TITLE', 'BLANK')] - [Alias('merge_commit_message')] [string] $MergeCommitMessage, # The context to run the command in. Used to get the details for the API call. @@ -191,30 +160,6 @@ filter New-GitHubRepositoryOrg { [object] $Context ) - dynamicparam { - $DynamicParamDictionary = New-DynamicParamDictionary - - $dynParam = @{ - Name = 'GitignoreTemplate' - Alias = 'gitignore_template' - Type = [string] - ValidateSet = Get-GitHubGitignore - DynamicParamDictionary = $DynamicParamDictionary - } - New-DynamicParam @dynParam - - $dynParam2 = @{ - Name = 'LicenseTemplate' - Alias = 'license_template' - Type = [string] - ValidateSet = Get-GitHubLicense | Select-Object -ExpandProperty key - DynamicParamDictionary = $DynamicParamDictionary - } - New-DynamicParam @dynParam2 - - return $DynamicParamDictionary - } - begin { $stackPath = Get-PSCallStackPath Write-Debug "[$stackPath] - Start" @@ -222,8 +167,6 @@ filter New-GitHubRepositoryOrg { } process { - $GitignoreTemplate = $PSBoundParameters['GitignoreTemplate'] - $LicenseTemplate = $PSBoundParameters['LicenseTemplate'] $body = @{ name = $Name description = $Description @@ -234,7 +177,9 @@ filter New-GitHubRepositoryOrg { has_downloads = [bool]$HasDownloads is_template = [bool]$IsTemplate team_id = $TeamId - auto_init = [bool]$AutoInit + auto_init = [bool]$AddReadme + gitignore_template = $Gitignore + license_template = $License allow_squash_merge = [bool]$AllowSquashMerge allow_merge_commit = [bool]$AllowMergeCommit allow_rebase_merge = [bool]$AllowRebaseMerge @@ -245,17 +190,18 @@ filter New-GitHubRepositoryOrg { merge_commit_title = $MergeCommitTitle merge_commit_message = $MergeCommitMessage private = $Visibility -eq 'private' + visibility = $Visibility } $body | Remove-HashtableEntry -NullOrEmptyValues $inputObject = @{ Method = 'POST' - APIEndpoint = "/orgs/$Owner/repos" + APIEndpoint = "/orgs/$Organization/repos" Body = $body Context = $Context } - if ($PSCmdlet.ShouldProcess("Repository [$Name] in organization [$Owner]", 'Create')) { + if ($PSCmdlet.ShouldProcess("Repository [$Name] in organization [$Organization]", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { [GitHubRepository]::New($_.Response) } diff --git a/src/functions/private/Repositories/New-GitHubRepositoryUser.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryUser.ps1 index 437c8e0fa..4742d2b5f 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryUser.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryUser.ps1 @@ -1,6 +1,4 @@ -#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } - -filter New-GitHubRepositoryUser { +filter New-GitHubRepositoryUser { <# .SYNOPSIS Create a repository for the authenticated user @@ -25,7 +23,7 @@ filter New-GitHubRepositoryUser { HasWiki = $true HasDownloads = $true IsTemplate = $true - AutoInit = $true + AddReadme = $true AllowSquashMerge = $true AllowAutoMerge = $true DeleteBranchOnMerge = $true @@ -36,28 +34,12 @@ filter New-GitHubRepositoryUser { Creates a new public repository named "Hello-World" owned by the authenticated user. - .PARAMETER GitignoreTemplate - The desired language or platform to apply to the .gitignore. - - .PARAMETER LicenseTemplate - The license keyword of the open source license for this repository. - .OUTPUTS GitHubRepository .LINK [Create a repository for the authenticated user](https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user) #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSUseDeclaredVarsMoreThanAssignments', - 'GitignoreTemplate', - Justification = 'Parameter is used in dynamic parameter validation.' - )] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSUseDeclaredVarsMoreThanAssignments', - 'LicenseTemplate', - Justification = 'Parameter is used in dynamic parameter validation.' - )] [OutputType([GitHubRepository])] [CmdletBinding(SupportsShouldProcess)] param( @@ -109,7 +91,15 @@ filter New-GitHubRepositoryUser { # Pass true to create an initial commit with empty README. [Parameter()] - [switch] $AutoInit, + [switch] $AddReadme, + + # The desired language or platform to apply to the .gitignore. + [Parameter()] + [string] $Gitignore, + + #The license keyword of the open source license for this repository. + [Parameter()] + [string] $License, # Whether to allow squash merges for pull requests. [Parameter()] @@ -167,30 +157,6 @@ filter New-GitHubRepositoryUser { [object] $Context ) - dynamicparam { - $DynamicParamDictionary = New-DynamicParamDictionary - - $dynParam = @{ - Name = 'GitignoreTemplate' - Alias = 'gitignore_template' - Type = [string] - ValidateSet = Get-GitHubGitignore - DynamicParamDictionary = $DynamicParamDictionary - } - New-DynamicParam @dynParam - - $dynParam2 = @{ - Name = 'LicenseTemplate' - Alias = 'license_template' - Type = [string] - ValidateSet = Get-GitHubLicense | Select-Object -ExpandProperty key - DynamicParamDictionary = $DynamicParamDictionary - } - New-DynamicParam @dynParam2 - - return $DynamicParamDictionary - } - begin { $stackPath = Get-PSCallStackPath Write-Debug "[$stackPath] - Start" @@ -198,8 +164,6 @@ filter New-GitHubRepositoryUser { } process { - $GitignoreTemplate = $PSBoundParameters['GitignoreTemplate'] - $LicenseTemplate = $PSBoundParameters['LicenseTemplate'] $body = @{ name = $Name description = $Description @@ -210,7 +174,9 @@ filter New-GitHubRepositoryUser { has_downloads = [bool]$HasDownloads is_template = [bool]$IsTemplate team_id = $TeamId - auto_init = [bool]$AutoInit + auto_init = [bool]$AddReadme + gitignore_template = $Gitignore + license_template = $License allow_squash_merge = [bool]$AllowSquashMerge allow_merge_commit = [bool]$AllowMergeCommit allow_rebase_merge = [bool]$AllowRebaseMerge diff --git a/src/functions/public/Organization/Members/Get-GitHubOrganizationMember.ps1 b/src/functions/public/Organization/Members/Get-GitHubOrganizationMember.ps1 index e2c5e9119..055bc84f8 100644 --- a/src/functions/public/Organization/Members/Get-GitHubOrganizationMember.ps1 +++ b/src/functions/public/Organization/Members/Get-GitHubOrganizationMember.ps1 @@ -20,7 +20,7 @@ [CmdletBinding()] param( # The organization name. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $Organization, # Filter members returned in the list. diff --git a/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 b/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 index 242b6a036..2442424f4 100644 --- a/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 +++ b/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 @@ -25,7 +25,7 @@ [CmdletBinding()] param( # The organization name. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $Organization, # Filter invitations by their member role. diff --git a/src/functions/public/Organization/Members/New-GitHubOrganizationInvitation.ps1 b/src/functions/public/Organization/Members/New-GitHubOrganizationInvitation.ps1 index 128a7d0f6..93148c902 100644 --- a/src/functions/public/Organization/Members/New-GitHubOrganizationInvitation.ps1 +++ b/src/functions/public/Organization/Members/New-GitHubOrganizationInvitation.ps1 @@ -28,7 +28,7 @@ [CmdletBinding(SupportsShouldProcess)] param( # The organization name. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $Organization, # GitHub user ID for the person you are inviting. @@ -36,8 +36,8 @@ Mandatory, ParameterSetName = 'UserID' )] - [Alias('invitee_id', 'user_id', 'ID')] - [Nullable[int]] $InviteeID, + [Alias('invitee_id', 'user_id', 'InviteeID')] + [System.Nullable[int]] $ID, # Email address of the person you are inviting, which can be an existing GitHub user. [Parameter( @@ -77,7 +77,7 @@ process { $body = @{ - invitee_id = $PSBoundParameters.ContainsKey('InviteeID') ? $InviteeID : $null + invitee_id = $PSBoundParameters.ContainsKey('ID') ? $ID : $null email = $Email role = $Role team_ids = $TeamIDs diff --git a/src/functions/public/Organization/Members/Remove-GitHubOrganizationInvitation.ps1 b/src/functions/public/Organization/Members/Remove-GitHubOrganizationInvitation.ps1 index 38f4ba031..ee5d03ee8 100644 --- a/src/functions/public/Organization/Members/Remove-GitHubOrganizationInvitation.ps1 +++ b/src/functions/public/Organization/Members/Remove-GitHubOrganizationInvitation.ps1 @@ -8,20 +8,28 @@ This endpoint triggers [notifications](https://docs.github.com/github/managing-subscriptions-and-notifications-on-github/about-notifications). - .EXAMPLE Remove-GitHubOrganizationInvitation -Organization 'github' -InvitationID '12345678' Cancel the invitation with the ID '12345678' for the organization `github`. - .NOTES + .INPUTS + GitHubOrganization + + .OUTPUTS + void + + .LINK + https://psmodule.io/GitHub/Functions/Organization/Members/Remove-GitHubOrganizationInvitation + + .LINK [Cancel an organization invitation](https://docs.github.com/rest/orgs/members#cancel-an-organization-invitation) #> - [OutputType([bool])] + [OutputType([void])] [CmdletBinding(SupportsShouldProcess)] param( # The organization name. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $Organization, # The unique identifier of the invitation. @@ -50,7 +58,7 @@ } if ($PSCmdlet.ShouldProcess('GitHub Organization invitation', 'Remove')) { - Invoke-GitHubAPI @inputObject + $null = Invoke-GitHubAPI @inputObject } } diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 8c49e434c..237da1168 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -37,10 +37,13 @@ filter Get-GitHubRepository { Gets the repositories with an ID equals and greater than 123456789. .EXAMPLE - Get-GitHubRepository -Owner 'github' -Name 'octocat' + Get-GitHubRepository -Organization 'github' -Name 'octocat' Gets the specified repository. + .INPUTS + GitHubOwner + .OUTPUTS GithubRepository @@ -80,25 +83,18 @@ filter Get-GitHubRepository { [datetime] $Before, # The account owner of the repository. The name is not case sensitive. - [Parameter(ParameterSetName = 'ByName')] - [Parameter(ParameterSetName = 'ListByOrg')] - [string] $Owner, + [Parameter(ParameterSetName = 'ByName', ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName = 'ListByOrg', ValueFromPipelineByPropertyName)] + [string] $Organization, + + # The handle for the GitHub user account. + [Parameter(Mandatory, ParameterSetName = 'ListByUser', ValueFromPipelineByPropertyName)] + [string] $Username, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter( - Mandatory, - ParameterSetName = 'ByName' - )] + [Parameter(Mandatory, ParameterSetName = 'ByName')] [string] $Name, - # The handle for the GitHub user account. - [Parameter( - Mandatory, - ValueFromPipeline, - ValueFromPipelineByPropertyName, - ParameterSetName = 'ListByUser' - )] - [string] $Username, # The property to sort the results by. [Parameter(ParameterSetName = 'MyRepos_Type')] @@ -203,7 +199,7 @@ filter Get-GitHubRepository { 'ByName' { $params = @{ Context = $Context - Owner = $Owner + Owner = $Organization ?? $Username Name = $Name } $params | Remove-HashtableEntry -NullOrEmptyValues @@ -221,12 +217,12 @@ filter Get-GitHubRepository { } 'ListByOrg' { $params = @{ - Context = $Context - Owner = $Owner - Type = $Type - Sort = $Sort - Direction = $Direction - PerPage = $PerPage + Context = $Context + Organization = $Organization + Type = $Type + Sort = $Sort + Direction = $Direction + PerPage = $PerPage } $params | Remove-HashtableEntry -NullOrEmptyValues Write-Verbose ($params | Format-List | Out-String) diff --git a/src/functions/public/Repositories/New-GitHubRepository.ps1 b/src/functions/public/Repositories/New-GitHubRepository.ps1 index b5189db87..70449505e 100644 --- a/src/functions/public/Repositories/New-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/New-GitHubRepository.ps1 @@ -26,7 +26,7 @@ filter New-GitHubRepository { HasDiscussions = $true HasDownloads = $true IsTemplate = $true - AutoInit = $true + AddReadme = $true AllowSquashMerge = $true AllowAutoMerge = $true DeleteBranchOnMerge = $true @@ -48,7 +48,7 @@ filter New-GitHubRepository { HasWiki = $true HasDownloads = $true IsTemplate = $true - AutoInit = $true + AddReadme = $true AllowSquashMerge = $true AllowAutoMerge = $true DeleteBranchOnMerge = $true @@ -86,12 +86,11 @@ filter New-GitHubRepository { Creates a new repository named `MyNewRepo` as a fork of `Hello-World` owned by `octocat`. Only the default branch will be forked. - .PARAMETER GitignoreTemplate - Desired language or platform .gitignore template to apply. Use the name of the template without the extension. For example, "Haskell". + .PARAMETER Gitignore + The desired language or platform to apply to the .gitignore. - .PARAMETER LicenseTemplate - Choose an open source license template that best suits your needs, and then use the license keyword as the license_template string. - For example, "mit" or "mpl-2.0". + .PARAMETER License + The license keyword of the open source license for this repository. .OUTPUTS GitHubRepository @@ -106,10 +105,7 @@ filter New-GitHubRepository { [Create an organization repository](https://docs.github.com/rest/repos/repos#create-an-organization-repository) #> [OutputType([GitHubRepository])] - [CmdletBinding( - SupportsShouldProcess, - DefaultParameterSetName = 'user' - )] + [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'user')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(ParameterSetName = 'org')] @@ -128,18 +124,15 @@ filter New-GitHubRepository { [string] $TemplateOwner, # The name of the template repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory, ParameterSetName = 'template' - )] + [Parameter(Mandatory, ParameterSetName = 'template')] [string] $TemplateRepository, # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory, ParameterSetName = 'fork' - )] + [Parameter(Mandatory, ParameterSetName = 'fork')] [string] $ForkOwner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory, ParameterSetName = 'fork' - )] + [Parameter(Mandatory, ParameterSetName = 'fork')] [string] $ForkRepo, # When forking from an existing repository, fork with only the default branch. @@ -304,8 +297,6 @@ filter New-GitHubRepository { } process { - $GitignoreTemplate = $PSBoundParameters['GitignoreTemplate'] - $LicenseTemplate = $PSBoundParameters['LicenseTemplate'] Write-Verbose "ParameterSetName: $($PSCmdlet.ParameterSetName)" switch ($PSCmdlet.ParameterSetName) { 'user' { @@ -322,7 +313,7 @@ filter New-GitHubRepository { HasDownloads = $HasDownloads IsTemplate = $IsTemplate TeamId = $TeamId - AutoInit = $AutoInit + AddReadme = $AddReadme AllowSquashMerge = $AllowSquashMerge AllowMergeCommit = $AllowMergeCommit AllowRebaseMerge = $AllowRebaseMerge @@ -332,8 +323,8 @@ filter New-GitHubRepository { SquashMergeCommitMessage = $SquashMergeCommitMessage MergeCommitTitle = $MergeCommitTitle MergeCommitMessage = $MergeCommitMessage - GitignoreTemplate = $GitignoreTemplate - LicenseTemplate = $LicenseTemplate + Gitignore = $PSBoundParameters['Gitignore'] + License = $PSBoundParameters['License'] } $params | Remove-HashtableEntry -NullOrEmptyValues if ($PSCmdlet.ShouldProcess("repository for user [$Name]", 'Create')) { @@ -354,7 +345,7 @@ filter New-GitHubRepository { HasDownloads = $HasDownloads IsTemplate = $IsTemplate TeamId = $TeamId - AutoInit = $AutoInit + AddReadme = $AddReadme AllowSquashMerge = $AllowSquashMerge AllowMergeCommit = $AllowMergeCommit AllowRebaseMerge = $AllowRebaseMerge @@ -364,8 +355,8 @@ filter New-GitHubRepository { SquashMergeCommitMessage = $SquashMergeCommitMessage MergeCommitTitle = $MergeCommitTitle MergeCommitMessage = $MergeCommitMessage - GitignoreTemplate = $GitignoreTemplate - LicenseTemplate = $LicenseTemplate + Gitignore = $PSBoundParameters['Gitignore'] + License = $PSBoundParameters['License'] } $params | Remove-HashtableEntry -NullOrEmptyValues if ($PSCmdlet.ShouldProcess("repository for organization [$Owner/$Name]", 'Create')) { @@ -395,8 +386,8 @@ filter New-GitHubRepository { if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] as fork from [$ForkOwner/$ForkRepo]", 'Create')) { $params = @{ Context = $Context - Owner = $ForkOwner - Repo = $ForkRepo + ForkOwner = $ForkOwner + ForkRepo = $ForkRepo Organization = $Owner Name = $Name DefaultBranchOnly = $DefaultBranchOnly diff --git a/src/types/GitHubUser.Types.ps1xml b/src/types/GitHubUser.Types.ps1xml new file mode 100644 index 000000000..c2085168c --- /dev/null +++ b/src/types/GitHubUser.Types.ps1xml @@ -0,0 +1,16 @@ + + + + GitHubUser + + + User + $this.Name + + + Username + $this.Name + + + + diff --git a/tools/utilities/Local-Testing.ps1 b/tools/utilities/Local-Testing.ps1 index a08d585da..7919a2476 100644 --- a/tools/utilities/Local-Testing.ps1 +++ b/tools/utilities/Local-Testing.ps1 @@ -108,7 +108,7 @@ $params = @{ HasDownloads = $true IsTemplate = $true # TeamID = 12345679 - AutoInit = $true + AddReadme = $true # GitignoreTemplate = 'VisualStudio' # LicenseTemplate = 'MIT' AllowSquashMerge = $true @@ -137,7 +137,7 @@ $params = @{ HasDownloads = $true IsTemplate = $true # TeamID = 12345679 - AutoInit = $true + AddReadme = $true # GitignoreTemplate = 'VisualStudio' # LicenseTemplate = 'MIT' AllowSquashMerge = $true From 8bf9c52d7599a2cede1215790ab63003bd1d37f9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 21:53:24 +0200 Subject: [PATCH 005/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Remove=20defa?= =?UTF-8?q?ult=20values=20for=20parameters=20in=20Get-GitHubMyRepositories?= =?UTF-8?q?=20and=20Get-GitHubRepository=20functions=20for=20improved=20fl?= =?UTF-8?q?exibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../private/Repositories/Get-GitHubMyRepositories.ps1 | 8 ++++---- .../public/Repositories/Get-GitHubRepository.ps1 | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 b/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 index 7b7b34a98..98ce0c6be 100644 --- a/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 +++ b/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 @@ -63,7 +63,7 @@ # Limit results to repositories with the specified visibility. [Parameter(ParameterSetName = 'Aff-Vis')] [ValidateSet('all', 'public', 'private')] - [string] $Visibility = 'all', + [string] $Visibility, # Comma-separated list of values. Can include: # - owner: Repositories that are owned by the authenticated user. @@ -73,17 +73,17 @@ # Default: owner, collaborator, organization_member [Parameter(ParameterSetName = 'Aff-Vis')] [ValidateSet('owner', 'collaborator', 'organization_member')] - [string[]] $Affiliation = @('owner', 'collaborator', 'organization_member'), + [string[]] $Affiliation, # Specifies the types of repositories you want returned. [Parameter(ParameterSetName = 'Type')] [ValidateSet('all', 'owner', 'public', 'private', 'member')] - [string] $Type = 'all', + [string] $Type, # The property to sort the results by. [Parameter()] [ValidateSet('created', 'updated', 'pushed', 'full_name')] - [string] $Sort = 'created', + [string] $Sort, # The order to sort by. # Default: asc when using full_name, otherwise desc. diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 237da1168..129b07d9a 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -95,7 +95,6 @@ filter Get-GitHubRepository { [Parameter(Mandatory, ParameterSetName = 'ByName')] [string] $Name, - # The property to sort the results by. [Parameter(ParameterSetName = 'MyRepos_Type')] [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] From 1c2946703a7e5ff54dc2cd445490180de8e66235 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 22:17:05 +0200 Subject: [PATCH 006/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20input?= =?UTF-8?q?=20documentation=20and=20improve=20parameter=20binding=20in=20r?= =?UTF-8?q?epository=20functions=20for=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/Get-GitHubRepository.ps1 | 4 +++- .../Repositories/Move-GitHubRepository.ps1 | 7 +++++-- .../Repositories/Remove-GitHubRepository.ps1 | 13 +++++-------- .../Repositories/Update-GitHubRepository.ps1 | 19 +++++++++++-------- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 129b07d9a..d599232f5 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -203,7 +203,9 @@ filter Get-GitHubRepository { } $params | Remove-HashtableEntry -NullOrEmptyValues Write-Verbose ($params | Format-List | Out-String) - Get-GitHubRepositoryByName @params + try { + Get-GitHubRepositoryByName @params + } catch { $null } } 'ListByID' { $params = @{ diff --git a/src/functions/public/Repositories/Move-GitHubRepository.ps1 b/src/functions/public/Repositories/Move-GitHubRepository.ps1 index aca60343f..9e1b32232 100644 --- a/src/functions/public/Repositories/Move-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Move-GitHubRepository.ps1 @@ -16,6 +16,9 @@ Moves the GitHub repository to the PSModule organization and renames it to GitHub. + .INPUTS + GitHubRepository + .OUTPUTS GitHubRepository @@ -29,11 +32,11 @@ [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Name, # The username or organization name the repository will be transferred to. diff --git a/src/functions/public/Repositories/Remove-GitHubRepository.ps1 b/src/functions/public/Repositories/Remove-GitHubRepository.ps1 index bf828287c..e10e0c47e 100644 --- a/src/functions/public/Repositories/Remove-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Remove-GitHubRepository.ps1 @@ -14,6 +14,9 @@ Deletes the repository `Hello-World` in the `PSModule` organization. + .INPUTS + GitHubRepository + .LINK https://psmodule.io/GitHub/Functions/Repositories/Remove-GitHubRepository/ @@ -23,17 +26,11 @@ [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param( # The account owner of the repository. The name is not case sensitive. - [Parameter( - Mandatory, - ValueFromPipelineByPropertyName - )] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter( - Mandatory, - ValueFromPipelineByPropertyName - )] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Name, # The context to run the command in. Used to get the details for the API call. diff --git a/src/functions/public/Repositories/Update-GitHubRepository.ps1 b/src/functions/public/Repositories/Update-GitHubRepository.ps1 index d361b0830..0f00fa82d 100644 --- a/src/functions/public/Repositories/Update-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Update-GitHubRepository.ps1 @@ -20,6 +20,9 @@ } Update-GitHubRepository @params + .INPUTS + GitHubRepository + .OUTPUTS GitHubRepository @@ -33,11 +36,11 @@ [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Name, # The name of the repository. @@ -115,7 +118,7 @@ # Either true to always allow a pull request head branch that is behind its base branch # to be updated even if it is not required to be up to date before merging, or false otherwise. [Parameter()] - [switch] $AllowUpdateMerge, + [switch] $AllowUpdateBranch, # The default value for a squash merge commit title: # - PR_TITLE - default to the pull request's title. @@ -181,10 +184,6 @@ visibility = $Visibility private = $Visibility -eq 'private' default_branch = $DefaultBranch - squash_merge_commit_title = $SquashMergeCommitTitle - squash_merge_commit_message = $SquashMergeCommitMessage - merge_commit_title = $MergeCommitTitle - merge_commit_message = $MergeCommitMessage advanced_security = $EnableAdvancedSecurity ? @{ status = $EnableAdvancedSecurity ? 'enabled' : 'disabled' } : $null @@ -199,10 +198,14 @@ has_wiki = $HasWiki ? $HasWiki : $null is_template = $IsTemplate ? $IsTemplate : $null allow_squash_merge = $AllowSquashMerge ? $AllowSquashMerge : $null + squash_merge_commit_title = $SquashMergeCommitTitle + squash_merge_commit_message = $SquashMergeCommitMessage allow_merge_commit = $AllowMergeCommit ? $AllowMergeCommit : $null + merge_commit_title = $MergeCommitTitle + merge_commit_message = $MergeCommitMessage allow_rebase_merge = $AllowRebaseMerge ? $AllowRebaseMerge : $null allow_auto_merge = $AllowAutoMerge ? $AllowAutoMerge : $null - allow_update_branch = $AllowUpdateMerge ? $AllowUpdateMerge : $null + allow_update_branch = $AllowUpdateBranch ? $AllowUpdateBranch : $null delete_branch_on_merge = $DeleteBranchOnMerge ? $DeleteBranchOnMerge : $null archived = $Archived ? $Archived : $null allow_forking = $AllowForking ? $AllowForking : $null From c4103280ae9b7f1b4bff3cad70ae0094136d2ce7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 22:24:44 +0200 Subject: [PATCH 007/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20paramet?= =?UTF-8?q?er=20set=20for=20Organization=20and=20enhance=20Username=20para?= =?UTF-8?q?meter=20in=20Get-GitHubRepository=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/Repositories/Get-GitHubRepository.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index d599232f5..8ad1a2a23 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -88,6 +88,7 @@ filter Get-GitHubRepository { [string] $Organization, # The handle for the GitHub user account. + [Parameter(ParameterSetName = 'ByName', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'ListByUser', ValueFromPipelineByPropertyName)] [string] $Username, From a0b4a8ed141ffcf01f616211bacddb97b722e6c9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 22:56:37 +0200 Subject: [PATCH 008/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Type?= =?UTF-8?q?=20parameter=20handling=20in=20Get-GitHubRepository=20function?= =?UTF-8?q?=20for=20improved=20default=20value=20assignment=20based=20on?= =?UTF-8?q?=20parameter=20sets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/Get-GitHubRepository.ps1 | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 8ad1a2a23..905513d53 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -164,7 +164,22 @@ filter Get-GitHubRepository { } process { - $Type = $PSBoundParameters['Type'] + $Type = if ($null -eq $PSBoundParameters['Type']) { + switch ($PSCmdlet.ParameterSetName) { + 'MyRepos_Type' { + 'owner' + } + 'ListByOrg' { + 'all' + } + 'ListByUser' { + 'owner' + } + } + } else { + $PSBoundParameters['Type'] + } + Write-Debug "ParamSet: [$($PSCmdlet.ParameterSetName)]" switch ($PSCmdlet.ParameterSetName) { 'MyRepos_Type' { From fb48180eda9620d5c7332d201c137a88760efe19 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 23:13:20 +0200 Subject: [PATCH 009/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Enhance=20Sav?= =?UTF-8?q?e-GitHubArtifact=20function=20to=20include=20-Force=20parameter?= =?UTF-8?q?=20for=20overwriting=20existing=20files=20during=20download=20a?= =?UTF-8?q?nd=20extraction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 2 +- .../public/Artifacts/Save-GitHubArtifact.ps1 | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 6e96665ad..302fb3f37 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -1,3 +1,3 @@ $modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | - Save-GitHubArtifact -Path $modulesPath -Extract + Save-GitHubArtifact -Path $modulesPath -Extract -Force diff --git a/src/functions/public/Artifacts/Save-GitHubArtifact.ps1 b/src/functions/public/Artifacts/Save-GitHubArtifact.ps1 index 28a934d9d..7f5a6f288 100644 --- a/src/functions/public/Artifacts/Save-GitHubArtifact.ps1 +++ b/src/functions/public/Artifacts/Save-GitHubArtifact.ps1 @@ -23,7 +23,7 @@ function Save-GitHubArtifact { Downloads artifact ID '123456' from the 'Hello-World' repository owned by 'octocat' to the specified path. .EXAMPLE - Save-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' -Name 'module' -Path 'C:\Artifacts\module' -Expand -Cleanup + Save-GitHubArtifact -Owner 'octocat' -Repository 'Hello-World' -Name 'module' -Path 'C:\Artifacts\module' -Expand -Cleanup -Force Output: ```powershell @@ -34,7 +34,8 @@ function Save-GitHubArtifact { d----- 03/31/2025 12:00 artifact-123456.zip ``` - Downloads artifact ID 123456 from the 'Hello-World' repository owned by 'octocat' to the specified path. + Downloads artifact ID 123456 from the 'Hello-World' repository owned by 'octocat' to the specified path, + overwriting existing files during download and extraction. .INPUTS GitHubArtifact @@ -76,6 +77,10 @@ function Save-GitHubArtifact { [Alias('Extract')] [switch] $Expand, + # When specified, overwrites existing files during download and extraction. + [Parameter()] + [switch] $Force, + # When specified, the zip file or the folder where the zip file was extracted to is returned. [Parameter()] [switch] $PassThru, @@ -126,7 +131,7 @@ function Save-GitHubArtifact { if ($Expand) { Write-Debug "Expanding artifact to [$folder]" - Expand-Archive -LiteralPath $Path -DestinationPath $folder -Force + Expand-Archive -LiteralPath $Path -DestinationPath $folder -Force:$Force Write-Debug "Removing downloaded ZIP [$Path]" Remove-Item -LiteralPath $Path -Force if ($PassThru) { From c12eb278818c2361f5d89df9ff8f7151e751a72c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 23:21:47 +0200 Subject: [PATCH 010/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Refactor=20ow?= =?UTF-8?q?ner=20assignment=20logic=20in=20Get-GitHubRepository=20function?= =?UTF-8?q?=20to=20improve=20clarity=20and=20handle=20Username=20and=20Org?= =?UTF-8?q?anization=20parameters=20more=20effectively?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/Repositories/Get-GitHubRepository.ps1 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 905513d53..f1c7f216e 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -212,9 +212,16 @@ filter Get-GitHubRepository { Get-GitHubMyRepositories @params } 'ByName' { + $owner = if ($PSBoundParameters.ContainsKey('Username')) { + $Username + } elseif ($PSBoundParameters.ContainsKey('Organization')) { + $Organization + } else { + (Get-GitHubUser -Context $Context).Name + } $params = @{ Context = $Context - Owner = $Organization ?? $Username + Owner = $owner Name = $Name } $params | Remove-HashtableEntry -NullOrEmptyValues From 0b4ac2d56c87e98e7dd5a49dafc209b8971e103a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 23:45:37 +0200 Subject: [PATCH 011/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20para?= =?UTF-8?q?meter=20attributes=20in=20Get-GitHubArtifact=20function=20to=20?= =?UTF-8?q?remove=20unnecessary=20ValueFromPipelineByPropertyName=20for=20?= =?UTF-8?q?ID=20parameter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/Artifacts/Get-GitHubArtifact.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/public/Artifacts/Get-GitHubArtifact.ps1 b/src/functions/public/Artifacts/Get-GitHubArtifact.ps1 index 02cb653be..29cee004e 100644 --- a/src/functions/public/Artifacts/Get-GitHubArtifact.ps1 +++ b/src/functions/public/Artifacts/Get-GitHubArtifact.ps1 @@ -87,7 +87,7 @@ function Get-GitHubArtifact { [string] $Repository, # Retrieves a single artifact by its unique ID. - [Parameter(Mandatory, ParameterSetName = 'ById', ValueFromPipelineByPropertyName)] + [Parameter(Mandatory, ParameterSetName = 'ById')] [string] $ID, # Retrieves artifacts from a specific workflow run. From dbd318b57e92e94dcda913d8c8b5134e492b546e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Fri, 11 Apr 2025 23:56:07 +0200 Subject: [PATCH 012/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20Get-Git?= =?UTF-8?q?HubBranchList=20function=20to=20list=20branches=20from=20a=20re?= =?UTF-8?q?pository=20with=20mandatory=20parameters=20for=20Owner,=20Repos?= =?UTF-8?q?itory,=20and=20Context?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Branches/Get-GitHubBranch.ps1} | 13 ++++--------- .../public/Environments/Get-GitHubEnvironment.ps1 | 13 +++++-------- 2 files changed, 9 insertions(+), 17 deletions(-) rename src/functions/{public/Branches/Get-GitHubRepoBranch.ps1 => private/Branches/Get-GitHubBranch.ps1} (79%) diff --git a/src/functions/public/Branches/Get-GitHubRepoBranch.ps1 b/src/functions/private/Branches/Get-GitHubBranch.ps1 similarity index 79% rename from src/functions/public/Branches/Get-GitHubRepoBranch.ps1 rename to src/functions/private/Branches/Get-GitHubBranch.ps1 index 868519613..a036ccae7 100644 --- a/src/functions/public/Branches/Get-GitHubRepoBranch.ps1 +++ b/src/functions/private/Branches/Get-GitHubBranch.ps1 @@ -1,4 +1,4 @@ -filter Get-GitHubRepoBranch { +filter Get-GitHubBranchList { <# .SYNOPSIS List branches @@ -7,7 +7,7 @@ Lists all branches from a repository .EXAMPLE - Get-GitHubRepoBranch -Owner 'octocat' -Repository 'Hello-World' + Get-GitHubBranchList -Owner 'octocat' -Repository 'Hello-World' Gets all the branches from the 'Hello-World' repository owned by 'octocat' @@ -18,8 +18,6 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. @@ -28,14 +26,13 @@ # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. - [Parameter()] - [object] $Context = (Get-GitHubContext) + [Parameter(Mandatory)] + [object] $Context ) begin { $stackPath = Get-PSCallStackPath Write-Debug "[$stackPath] - Start" - $Context = Resolve-GitHubContext -Context $Context Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT } @@ -55,5 +52,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Environments/Get-GitHubEnvironment.ps1 b/src/functions/public/Environments/Get-GitHubEnvironment.ps1 index 5399ac61b..4920c05f1 100644 --- a/src/functions/public/Environments/Get-GitHubEnvironment.ps1 +++ b/src/functions/public/Environments/Get-GitHubEnvironment.ps1 @@ -53,6 +53,9 @@ filter Get-GitHubEnvironment { Lists all environments available in the "EnvironmentTest" repository owned by "PSModule". + .INPUTS + GitHubRepository + .OUTPUTS GitHubEnvironment[] @@ -66,18 +69,12 @@ filter Get-GitHubEnvironment { [CmdletBinding()] param( # The name of the organization. - [Parameter( - Mandatory, - ValueFromPipelineByPropertyName - )] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('Organization', 'User')] [string] $Owner, # The name of the Repository. - [Parameter( - Mandatory, - ValueFromPipelineByPropertyName - )] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The name of the environment. From 0aa548abd832e26d4d41d664a0f00d971214754d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 00:34:25 +0200 Subject: [PATCH 013/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20GitHubE?= =?UTF-8?q?nvironment=20type=20definition=20with=20Environment=20script=20?= =?UTF-8?q?property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/GitHubEnvironment.Types.ps1xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/types/GitHubEnvironment.Types.ps1xml diff --git a/src/types/GitHubEnvironment.Types.ps1xml b/src/types/GitHubEnvironment.Types.ps1xml new file mode 100644 index 000000000..e058ce6f6 --- /dev/null +++ b/src/types/GitHubEnvironment.Types.ps1xml @@ -0,0 +1,12 @@ + + + + GitHubEnvironment + + + Environment + $this.Name + + + + From e36bb1eedcff249c24e2f337f85bde4d0eb54e83 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 00:34:32 +0200 Subject: [PATCH 014/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20rele?= =?UTF-8?q?ase=20functions=20to=20enhance=20documentation=20and=20improve?= =?UTF-8?q?=20parameter=20handling;=20add=20GitHubRelease=20and=20ReleaseA?= =?UTF-8?q?sset=20classes=20for=20structured=20release=20data.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/classes/public/Releases/GitHubRelease.ps1 | 116 ++++++++++++++++++ .../private/Releases/Get-GitHubReleaseAll.ps1 | 21 ++-- .../Releases/Get-GitHubReleaseByID.ps1 | 13 +- .../Releases/Get-GitHubReleaseByTagName.ps1 | 13 +- .../Releases/Get-GitHubReleaseLatest.ps1 | 12 +- ...et-GitHubOrganizationPendingInvitation.ps1 | 2 +- .../public/Releases/Get-GitHubRelease.ps1 | 58 +++++---- 7 files changed, 187 insertions(+), 48 deletions(-) create mode 100644 src/classes/public/Releases/GitHubRelease.ps1 diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 new file mode 100644 index 000000000..7fc8859ce --- /dev/null +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -0,0 +1,116 @@ +class ReleaseAsset : GitHubNode { + # Description: URL for downloading the asset + # Example: "https://github.com/PSModule/GitHub/releases/download/v0.22.1/asset.zip" + [string] $Url + + # Description: The file name of the asset + # Example: "Team Environment" + [string] $Name + + # Description: Label for the asset, can be null + # Example: null + [string] $Label + + # Description: State of the release asset (e.g., uploaded, open) + # Example: "uploaded" + [string] $State + + # Description: MIME type of the asset + # Example: "application/zip" + [string] $ContentType + + # Description: Size of the asset in bytes + # Example: 1024 + [int] $Size + + # Description: Number of times the asset was downloaded + # Example: 100 + [int] $Downloads + + # Description: Timestamp when the asset was created + # Example: "2025-04-11T09:03:38Z" + [datetime] $CreatedAt + + # Description: Timestamp when the asset was last updated + # Example: "2025-04-11T09:03:38Z" + [datetime] $UpdatedAt + + # Description: User who uploaded the asset, can be null + # Example: GitHubUser object or null + [GitHubUser] $Uploader +} + +class GitHubRelease : GitHubNode { + # GitHub URL for the release + # Example: "https://github.com/PSModule/GitHub/releases/tag/v0.22.1" + [string] $Url + + # User who authored the release + [GitHubUser] $Author + + # The name of the tag + # Example: "v0.22.1" + [string] $TagName + + # Specifies the commitish value that determines where the Git tag is created from + # Example: "main" + [string] $TargetCommitish + + # Name of the release, can be null + # Example: "v0.22.1" + [string] $Name + + # True to create a draft (unpublished) release, false to create a published one + # Example: false + [bool] $Draft + + # Whether to identify the release as a prerelease or a full release + # Example: false + [bool] $Prerelease + + # Timestamp when the release was created + # Example: "2025-04-11T09:03:38Z" + [System.Nullable[datetime]] $CreatedAt + + # Timestamp when the release was published, can be null + # Example: "2025-04-11T13:41:34Z" + [System.Nullable[datetime]] $PublishedAt + + # URL for the release tarball, can be null + # Example: "https://api.github.com/repos/PSModule/GitHub/tarball/v0.22.1" + [string] $TarballUrl + + # URL for the release zipball, can be null + # Example: "https://api.github.com/repos/PSModule/GitHub/zipball/v0.22.1" + [string] $ZipballUrl + + # Release notes or changelog, can be null + # Example: "## What's Changed\n### Other Changes\n* Fix: Enhance repository deletion feedback and fix typo..." + [string] $Body + + # Number of mentions in the release notes + # Example: 1 + [int] $Mentions + + GitHubRelease() {} + + GitHubRelease([PSCustomObject] $Object) { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + $this.Url = $Object.html_url + $this.Author = [GitHubUser]::new($Object.author) + $this.TagName = $Object.tag_name + $this.TargetCommitish = $Object.target_commitish + $this.Name = $Object.name + $this.Draft = $Object.draft + $this.Prerelease = $Object.prerelease + $this.CreatedAt = $Object.created_at + $this.PublishedAt = $Object.published_at + $this.Assets = $Object.assets | ForEach-Object { [GitHubReleaseAsset]::new($_) } + $this.TarballUrl = $Object.tarball_url + $this.ZipballUrl = $Object.zipball_url + $this.Body = $Object.body + $this.Mentions = $Object.mentions_count + } + +} diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index bd5c52614..f739ca2b7 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -13,11 +13,17 @@ Gets all the releases for the repository 'hello-world' owned by 'octocat'. - .NOTES - https://docs.github.com/rest/releases/releases#list-releases + .INPUTS + GitHubRepository + .OUTPUTS + GitHubRelease + + .LINK + [List releases](https://docs.github.com/rest/releases/releases#list-releases) #> - [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] + [OutputType([GitHubRelease])] + [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] @@ -28,7 +34,7 @@ [string] $Repository, # The number of results per page (max 100). - [Parameter(ParameterSetName = 'AllUsers')] + [Parameter()] [ValidateRange(0, 100)] [int] $PerPage, @@ -45,19 +51,16 @@ } process { - $body = @{ - per_page = $PerPage - } - $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases" Body = $body + PerPage = $PerPage Context = $Context } Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + $_.Response | ForEach-Object { [GitHubRelease]::new($_) } } } end { diff --git a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 index dc0c5c030..1303c2f85 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 @@ -12,10 +12,16 @@ Gets the release with the ID '1234567' for the repository 'hello-world' owned by 'octocat'. - .NOTES - https://docs.github.com/rest/releases/releases#get-a-release + .INPUTS + GitHubRepository + .OUTPUTS + GitHubRelease + + .LINK + [Get a release](https://docs.github.com/rest/releases/releases#get-a-release) #> + [OutputType([GitHubRelease])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -28,7 +34,6 @@ # The unique identifier of the release. [Parameter(Mandatory)] - [Alias('release_id')] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -51,7 +56,7 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubRelease]::new($_.Response) } } diff --git a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 index 519cf54f4..71affe7c0 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 @@ -11,10 +11,16 @@ Gets the release with the tag 'v1.0.0' for the repository 'hello-world' owned by 'octocat'. - .NOTES - https://docs.github.com/rest/releases/releases#get-a-release-by-tag-name + .INPUTS + GitHubRepository + .OUTPUTS + GitHubRelease + + .LINK + [Get a release by tag name](https://docs.github.com/rest/releases/releases#get-a-release-by-tag-name) #> + [OutputType([GitHubRelease])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -27,7 +33,6 @@ # The name of the tag to get a release from. [Parameter(Mandatory)] - [Alias('tag_name')] [string] $Tag, # The context to run the command in. Used to get the details for the API call. @@ -50,7 +55,7 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubRelease]::new($_.Response) } } diff --git a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 index 80f7a6936..59b68e46d 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 @@ -13,10 +13,16 @@ Gets the latest releases for the repository 'hello-world' owned by 'octocat'. - .NOTES - https://docs.github.com/rest/releases/releases#get-the-latest-release + .INPUTS + GitHubRepository + .OUTPUTS + GitHubRelease + + .LINK + [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) #> + [OutputType([GitHubRelease])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -47,7 +53,7 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubRelease]::new($_.Response) } } diff --git a/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 b/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 index 2442424f4..e9e647627 100644 --- a/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 +++ b/src/functions/public/Organization/Members/Get-GitHubOrganizationPendingInvitation.ps1 @@ -60,13 +60,13 @@ $body = @{ role = $Role invitation_source = $InvitationSource - per_page = $PerPage } $inputObject = @{ Method = 'GET' APIEndpoint = "/orgs/$Organization/invitations" Body = $body + PerPage = $PerPage Context = $Context } diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index e8d409ad1..31a846253 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -1,7 +1,7 @@ filter Get-GitHubRelease { <# .SYNOPSIS - List releases + List releases. .DESCRIPTION This returns a list of releases, which does not include regular Git tags that have not been associated with a release. @@ -14,9 +14,9 @@ Gets the releases for the repository 'hello-world' owned by 'octocat'. .EXAMPLE - Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Latest + Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -All - Gets the latest releases for the repository 'hello-world' owned by 'octocat'. + Gets all releases for the repository 'hello-world' owned by 'octocat'. .EXAMPLE Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' @@ -28,21 +28,28 @@ Gets the release with the ID '1234567' for the repository 'hello-world' owned by 'octocat'. + .INPUTS + GitHubRepository + + .OUTPUTS + GitHubRelease + .LINK https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ [List releases](https://docs.github.com/rest/releases/releases#list-releases) [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) #> - [CmdletBinding(DefaultParameterSetName = 'All')] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Latest', Justification = 'Required for parameter set')] + [OutputType([GitHubRelease])] + [CmdletBinding(DefaultParameterSetName = 'Latest')] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The number of results per page (max 100). @@ -50,25 +57,16 @@ [ValidateRange(0, 100)] [int] $PerPage, - # Get the latest release only - [Parameter( - Mandatory, - ParameterSetName = 'Latest' - )] - [switch] $Latest, + # Get all releases. + [Parameter(Mandatory, ParameterSetName = 'All')] + [switch] $All, # The name of the tag to get a release from. - [Parameter( - Mandatory, - ParameterSetName = 'Tag' - )] + [Parameter(Mandatory, ParameterSetName = 'Tag')] [string] $Tag, # The unique identifier of the release. - [Parameter( - Mandatory, - ParameterSetName = 'ID' - )] + [Parameter(Mandatory, ParameterSetName = 'ID')] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -85,18 +83,24 @@ } process { + Write-Debug "ParameterSet: $($PSCmdlet.ParameterSetName)" + $params = @{ + Owner = $Owner + Repository = $Repository + Context = $Context + } switch ($PSCmdlet.ParameterSetName) { 'All' { - Get-GitHubReleaseAll -Owner $Owner -Repository $Repository -PerPage $PerPage -Context $Context - } - 'Latest' { - Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context + Get-GitHubReleaseAll @params -PerPage $PerPage } 'Tag' { - Get-GitHubReleaseByTagName -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + Get-GitHubReleaseByTagName @params -Tag $Tag } 'ID' { - Get-GitHubReleaseByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context + Get-GitHubReleaseByID @params -ID $ID + } + 'Latest' { + Get-GitHubReleaseLatest @params } } } From bf8ffc67c6b13aac21ee3c2dde70c667466ead99 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 00:38:11 +0200 Subject: [PATCH 015/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Rename=20Rele?= =?UTF-8?q?aseAsset=20class=20to=20GitHubReleaseAsset=20for=20consistency?= =?UTF-8?q?=20and=20clarity=20in=20naming=20conventions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/classes/public/Releases/GitHubRelease.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index 7fc8859ce..81b995306 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -1,4 +1,4 @@ -class ReleaseAsset : GitHubNode { +class GitHubReleaseAsset : GitHubNode { # Description: URL for downloading the asset # Example: "https://github.com/PSModule/GitHub/releases/download/v0.22.1/asset.zip" [string] $Url From 8ea0b607df4cdf00201ae5d5a0c754de4e4a6b34 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 00:45:25 +0200 Subject: [PATCH 016/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20Assets?= =?UTF-8?q?=20property=20to=20GitHubRelease=20class=20to=20store=20uploade?= =?UTF-8?q?d=20release=20assets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/classes/public/Releases/GitHubRelease.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index 81b995306..5e295a137 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -84,6 +84,9 @@ class GitHubRelease : GitHubNode { # Example: "https://api.github.com/repos/PSModule/GitHub/zipball/v0.22.1" [string] $ZipballUrl + # Assets that are uploaded to the release. + [GitHubReleaseAsset[]] $Assets + # Release notes or changelog, can be null # Example: "## What's Changed\n### Other Changes\n* Fix: Enhance repository deletion feedback and fix typo..." [string] $Body From 433edd6c73344a1663f555315c665570907f2b1e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 00:52:08 +0200 Subject: [PATCH 017/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Modify=20erro?= =?UTF-8?q?r=20handling=20in=20Get-GitHubRepository=20function=20to=20retu?= =?UTF-8?q?rn=20null=20instead=20of=20suppressing=20exceptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/Repositories/Get-GitHubRepository.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index f1c7f216e..d824b0253 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -228,7 +228,7 @@ filter Get-GitHubRepository { Write-Verbose ($params | Format-List | Out-String) try { Get-GitHubRepositoryByName @params - } catch { $null } + } catch { return } } 'ListByID' { $params = @{ From 32e7753e027d08bc2861bf772977a44a8bdd2e3f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 01:17:52 +0200 Subject: [PATCH 018/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20GitHubR?= =?UTF-8?q?elease=20format=20configuration=20for=20table=20and=20list=20vi?= =?UTF-8?q?ews=20with=20detailed=20property=20mappings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/formats/GitHubRelease.Format.ps1xml | 141 ++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/formats/GitHubRelease.Format.ps1xml diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml new file mode 100644 index 000000000..1aaa7bd48 --- /dev/null +++ b/src/formats/GitHubRelease.Format.ps1xml @@ -0,0 +1,141 @@ + + + + + GitHubReleaseTable + + GitHubRelease + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name + + + TagName + + + Author + + + Prerelease + + + Draft + + + CreatedAt + + + PublishedAt + + + + + + + + GitHubReleaseList + + GitHubRelease + + + + + + + + Name + + + + TagName + + + + Url + + + + Author + + + + TargetCommitish + + + + Draft + + + + Prerelease + + + + CreatedAt + + + + PublishedAt + + + + TarballUrl + + + + ZipballUrl + + + + Assets + + + + Body + + + + Mentions + + + + ID + + + + NodeID + + + + + + + + From 4cc9a300ea14e09946010fc413846dc30516c36b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 01:25:49 +0200 Subject: [PATCH 019/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20prop?= =?UTF-8?q?erty=20mappings=20in=20GitHubRelease=20and=20GitHubWorkflow=20f?= =?UTF-8?q?ormat=20files=20for=20consistency=20and=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/formats/GitHubRelease.Format.ps1xml | 24 ++++-------------------- src/formats/GitHubWorkflow.Format.ps1xml | 2 -- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml index 1aaa7bd48..c08db8d3e 100644 --- a/src/formats/GitHubRelease.Format.ps1xml +++ b/src/formats/GitHubRelease.Format.ps1xml @@ -49,10 +49,10 @@ Draft - CreatedAt + CreatedAt - PublishedAt + PublishedAt @@ -69,67 +69,51 @@ - Name - TagName - Url - Author - TargetCommitish - Draft - Prerelease - - CreatedAt + CreatedAt - - PublishedAt + PublishedAt - TarballUrl - ZipballUrl - Assets - Body - Mentions - ID - NodeID diff --git a/src/formats/GitHubWorkflow.Format.ps1xml b/src/formats/GitHubWorkflow.Format.ps1xml index 29fa7a7d0..ac8f0c1bc 100644 --- a/src/formats/GitHubWorkflow.Format.ps1xml +++ b/src/formats/GitHubWorkflow.Format.ps1xml @@ -57,11 +57,9 @@ CreatedAt - Right UpdatedAt - Right From f3efc9c7fd86836bec832ccdb122083310d016f4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 01:42:09 +0200 Subject: [PATCH 020/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20Latest?= =?UTF-8?q?=20property=20to=20GitHubRelease=20class=20and=20update=20relat?= =?UTF-8?q?ed=20functions=20to=20track=20the=20latest=20release=20status?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/classes/public/Releases/GitHubRelease.ps1 | 7 ++++++- src/formats/GitHubRelease.Format.ps1xml | 9 +++++++++ src/functions/private/Releases/Get-GitHubReleaseAll.ps1 | 7 ++++++- src/functions/private/Releases/Get-GitHubReleaseByID.ps1 | 5 ++++- .../private/Releases/Get-GitHubReleaseByTagName.ps1 | 5 ++++- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index 5e295a137..94e00c35e 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -60,6 +60,10 @@ class GitHubRelease : GitHubNode { # Example: "v0.22.1" [string] $Name + # True if the release is the latest release on the repo. + # Example: true + [bool] $Latest + # True to create a draft (unpublished) release, false to create a published one # Example: false [bool] $Draft @@ -97,7 +101,7 @@ class GitHubRelease : GitHubNode { GitHubRelease() {} - GitHubRelease([PSCustomObject] $Object) { + GitHubRelease([PSCustomObject] $Object, [bool] $Latest) { $this.ID = $Object.id $this.NodeID = $Object.node_id $this.Url = $Object.html_url @@ -105,6 +109,7 @@ class GitHubRelease : GitHubNode { $this.TagName = $Object.tag_name $this.TargetCommitish = $Object.target_commitish $this.Name = $Object.name + $this.Latest = $Latest $this.Draft = $Object.draft $this.Prerelease = $Object.prerelease $this.CreatedAt = $Object.created_at diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml index c08db8d3e..1d96d825e 100644 --- a/src/formats/GitHubRelease.Format.ps1xml +++ b/src/formats/GitHubRelease.Format.ps1xml @@ -17,6 +17,9 @@ + + + @@ -42,6 +45,9 @@ Author + + Latest + Prerelease @@ -74,6 +80,9 @@ TagName + + Latest + Url diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index f739ca2b7..3a472cbcb 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -51,6 +51,8 @@ } process { + $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context + $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases" @@ -60,7 +62,10 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - $_.Response | ForEach-Object { [GitHubRelease]::new($_) } + $_.Response | ForEach-Object { + $isLatest = $_.id -eq $latest.id + [GitHubRelease]::new($_, $isLatest) + } } } end { diff --git a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 index 1303c2f85..a689ded2f 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 @@ -49,6 +49,8 @@ } process { + $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context + $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" @@ -56,7 +58,8 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response) + $isLatest = $_.Response.id -eq $latest.id + [GitHubRelease]::new($_.Response, $isLatest) } } diff --git a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 index 71affe7c0..d40aa3cc6 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 @@ -48,6 +48,8 @@ } process { + $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context + $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases/tags/$Tag" @@ -55,7 +57,8 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response) + $isLatest = $_.Response.id -eq $latest.id + [GitHubRelease]::new($_.Response, $isLatest) } } From f7da76e4e23559776eda5b56f7959d11d999ae22 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 01:45:38 +0200 Subject: [PATCH 021/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Get-?= =?UTF-8?q?GitHubReleaseLatest=20to=20instantiate=20GitHubRelease=20with?= =?UTF-8?q?=20the=20'isLatest'=20flag=20set=20to=20true?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 index 59b68e46d..226ad245c 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 @@ -53,7 +53,7 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response) + [GitHubRelease]::new($_.Response, $true) } } From 498f440b8e3ff109edc939505d0aafa6ea5a431d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 01:53:30 +0200 Subject: [PATCH 022/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Rename=20TagN?= =?UTF-8?q?ame=20property=20to=20Tag=20in=20GitHubRelease=20class=20and=20?= =?UTF-8?q?update=20related=20format=20files=20for=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/classes/public/Releases/GitHubRelease.ps1 | 4 ++-- src/formats/GitHubRelease.Format.ps1xml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index 94e00c35e..2450cfd4d 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -50,7 +50,7 @@ class GitHubRelease : GitHubNode { # The name of the tag # Example: "v0.22.1" - [string] $TagName + [string] $Tag # Specifies the commitish value that determines where the Git tag is created from # Example: "main" @@ -106,7 +106,7 @@ class GitHubRelease : GitHubNode { $this.NodeID = $Object.node_id $this.Url = $Object.html_url $this.Author = [GitHubUser]::new($Object.author) - $this.TagName = $Object.tag_name + $this.Tag = $Object.tag_name $this.TargetCommitish = $Object.target_commitish $this.Name = $Object.name $this.Latest = $Latest diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml index 1d96d825e..119150850 100644 --- a/src/formats/GitHubRelease.Format.ps1xml +++ b/src/formats/GitHubRelease.Format.ps1xml @@ -12,7 +12,7 @@ - + @@ -40,7 +40,7 @@ Name - TagName + Tag Author @@ -78,7 +78,7 @@ Name - TagName + Tag Latest From 453171539df7354e6c2eb06b5d8d1bce56503a8a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 01:58:26 +0200 Subject: [PATCH 023/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20example?= =?UTF-8?q?=20commands=20for=20creating=20and=20managing=20a=20GitHub=20re?= =?UTF-8?q?pository=20and=20release=20in=20SaveArtifacts.ps1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 302fb3f37..1b328b77a 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -1,3 +1,17 @@ $modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | Save-GitHubArtifact -Path $modulesPath -Extract -Force + + + +New-GitHubRepository -Name mytest -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio +Get-GitHubRepository -Username MariusStorhaug -Name mytest | Remove-GitHubRepository +New-GitHubRelease -Owner MariusStorhaug -Repository mytest -Name mytest -Tag v1.0 -Body 'Initial release' + + +Get-GitHubOrganization -Name PSModule | Get-GitHubRepository -Name GitHub | Get-GitHubWorkflow -Name Process-PSModule +Get-GitHubOrganization | Get-GitHubRepository -Name GitHub | Get-GitHubRelease +Get-GitHubUser | Get-GitHubRepository -Name mytest + + +Get-GitHubRelease -Owner PSModule -Repository GitHub From cce05d8921114972f7eee2885d0440f7f0682f10 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 09:52:16 +0200 Subject: [PATCH 024/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Refactor=20Gi?= =?UTF-8?q?tHub=20release=20functions=20to=20include=20error=20handling=20?= =?UTF-8?q?and=20improve=20debug=20output?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 8 ++------ .../private/Releases/Get-GitHubReleaseAll.ps1 | 13 ++++++++----- .../private/Releases/Get-GitHubReleaseByID.ps1 | 10 ++++++---- .../private/Releases/Get-GitHubReleaseByTagName.ps1 | 10 ++++++---- .../private/Releases/Get-GitHubReleaseLatest.ps1 | 8 +++++--- src/functions/public/Releases/Get-GitHubRelease.ps1 | 2 +- 6 files changed, 28 insertions(+), 23 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 1b328b77a..d9f6061fd 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -2,16 +2,12 @@ Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | Save-GitHubArtifact -Path $modulesPath -Extract -Force - - New-GitHubRepository -Name mytest -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio -Get-GitHubRepository -Username MariusStorhaug -Name mytest | Remove-GitHubRepository -New-GitHubRelease -Owner MariusStorhaug -Repository mytest -Name mytest -Tag v1.0 -Body 'Initial release' - +Get-GitHubRepository -Username MariusStorhaug -Name mytest | Remove-GitHubRepository -Confirm:$false +New-GitHubRelease -Owner MariusStorhaug -Repository mytest -Name 'mytest' -Tag 'v1.0' -Body 'Initial release' -Debug Get-GitHubOrganization -Name PSModule | Get-GitHubRepository -Name GitHub | Get-GitHubWorkflow -Name Process-PSModule Get-GitHubOrganization | Get-GitHubRepository -Name GitHub | Get-GitHubRelease Get-GitHubUser | Get-GitHubRepository -Name mytest - Get-GitHubRelease -Owner PSModule -Repository GitHub diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index 3a472cbcb..5d77341e6 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -61,13 +61,16 @@ Context = $Context } - Invoke-GitHubAPI @inputObject | ForEach-Object { - $_.Response | ForEach-Object { - $isLatest = $_.id -eq $latest.id - [GitHubRelease]::new($_, $isLatest) + try { + Invoke-GitHubAPI @inputObject | ForEach-Object { + $_.Response | ForEach-Object { + $isLatest = $_.id -eq $latest.id + [GitHubRelease]::new($_, $isLatest) + } } - } + } catch { return } } + end { Write-Debug "[$stackPath] - End" } diff --git a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 index a689ded2f..5028bd021 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 @@ -57,10 +57,12 @@ Context = $Context } - Invoke-GitHubAPI @inputObject | ForEach-Object { - $isLatest = $_.Response.id -eq $latest.id - [GitHubRelease]::new($_.Response, $isLatest) - } + try { + Invoke-GitHubAPI @inputObject | ForEach-Object { + $isLatest = $_.Response.id -eq $latest.id + [GitHubRelease]::new($_.Response, $isLatest) + } + } catch { return } } end { diff --git a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 index d40aa3cc6..7641df841 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 @@ -56,10 +56,12 @@ Context = $Context } - Invoke-GitHubAPI @inputObject | ForEach-Object { - $isLatest = $_.Response.id -eq $latest.id - [GitHubRelease]::new($_.Response, $isLatest) - } + try { + Invoke-GitHubAPI @inputObject | ForEach-Object { + $isLatest = $_.Response.id -eq $latest.id + [GitHubRelease]::new($_.Response, $isLatest) + } + } catch { return } } end { diff --git a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 index 226ad245c..b44d0c90a 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 @@ -52,9 +52,11 @@ Context = $Context } - Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response, $true) - } + try { + Invoke-GitHubAPI @inputObject | ForEach-Object { + [GitHubRelease]::new($_.Response, $true) + } + } catch { return } } end { diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index 31a846253..ba80de6c2 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -83,12 +83,12 @@ } process { - Write-Debug "ParameterSet: $($PSCmdlet.ParameterSetName)" $params = @{ Owner = $Owner Repository = $Repository Context = $Context } + Write-Debug "ParameterSet: $($PSCmdlet.ParameterSetName)" switch ($PSCmdlet.ParameterSetName) { 'All' { Get-GitHubReleaseAll @params -PerPage $PerPage From f6eb2dc05b6183ac92f82f7c0f1c24323aaab70a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 10:21:33 +0200 Subject: [PATCH 025/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Save?= =?UTF-8?q?Artifacts.ps1=20to=20include=20Get-GitHubWorkflowRun=20and=20im?= =?UTF-8?q?prove=20GitHubRelease=20function=20parameters=20for=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 7 +++- .../public/Releases/Get-GitHubRelease.ps1 | 5 ++- .../public/Releases/New-GitHubRelease.ps1 | 39 +++++++++++-------- .../public/Releases/New-GitHubReleaseNote.ps1 | 14 +++---- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index d9f6061fd..fadc77fbf 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -6,8 +6,11 @@ New-GitHubRepository -Name mytest -AllowSquashMerge -AddReadme -License mit -Git Get-GitHubRepository -Username MariusStorhaug -Name mytest | Remove-GitHubRepository -Confirm:$false New-GitHubRelease -Owner MariusStorhaug -Repository mytest -Name 'mytest' -Tag 'v1.0' -Body 'Initial release' -Debug -Get-GitHubOrganization -Name PSModule | Get-GitHubRepository -Name GitHub | Get-GitHubWorkflow -Name Process-PSModule +Get-GitHubOrganization -Name PSModule | Get-GitHubRepository -Name GitHub | Get-GitHubWorkflow -Name Process-PSModule | Get-gitHubWorkflowRun Get-GitHubOrganization | Get-GitHubRepository -Name GitHub | Get-GitHubRelease -Get-GitHubUser | Get-GitHubRepository -Name mytest +Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease Get-GitHubRelease -Owner PSModule -Repository GitHub + + +Get-GitHubUser diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index ba80de6c2..062a2cba6 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -40,12 +40,15 @@ [List releases](https://docs.github.com/rest/releases/releases#list-releases) [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSReviewUnusedParameter', 'All', + Justification = 'Using the ParameterSetName to determine the context of the command.' + )] [OutputType([GitHubRelease])] [CmdletBinding(DefaultParameterSetName = 'Latest')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] - [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 index 13a8cc550..56e506d77 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -15,6 +15,12 @@ Creates a release for the repository 'octocat/hello-world' with the tag 'v1.0.0' and the target commitish 'main'. + .INPUTS + GitHubRepository + + .OUTPUTS + GitHubRelease + .LINK https://psmodule.io/GitHub/Functions/Releases/New-GitHubRelease/ @@ -26,30 +32,30 @@ [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The name of the tag. [Parameter(Mandatory)] - [string] $TagName, + [string] $Tag, - # Specifies the commitish value that determines where the Git tag is created from. + # Specifies the reference value that determines where the Git tag is created from. # Can be any branch or commit SHA. Unused if the Git tag already exists. # API Default: the repository's default branch. [Parameter()] - [string] $TargetCommitish = 'main', + [string] $Target = 'main', # The name of the release. [Parameter()] - [string] $Name, + [string] $Title, # Text describing the contents of the tag. [Parameter()] - [string] $Body, + [string] $Notes, # Whether the release is a draft. [Parameter()] @@ -71,11 +77,11 @@ [switch] $GenerateReleaseNotes, # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. - # Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation - # date and higher semantic version. + # If not specified the latest release is determined based on the release creation date and higher semantic version. + # If set to true, the release will be set as the latest release for the repository. + # If set to false, the release will not be set as the latest release for the repository. [Parameter()] - [ValidateSet('true', 'false', 'legacy')] - [string] $Latest = 'true', + [switch] $Latest, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -91,13 +97,14 @@ } process { + $latestString = ($PSBoundParameters.ContainsKey('Latest') ? [string]$Latest : 'legacy').ToLower() $body = @{ - tag_name = $TagName - target_commitish = $TargetCommitish - name = $Name - body = $Body + tag_name = $Tag + target_commitish = $Target + name = $Title + body = $Notes discussion_category_name = $DiscussionCategoryName - make_latest = $Latest + make_latest = $latestString generate_release_notes = [bool]$GenerateReleaseNotes draft = [bool]$Draft prerelease = [bool]$Prerelease diff --git a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 index cd9f55a5e..915f5bea0 100644 --- a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 @@ -11,9 +11,9 @@ .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - TagName = 'v1.0.0' + Owner = 'octocat' + Repo = 'hello-world' + TagName = 'v1.0.0' } New-GitHubReleaseNote @params @@ -23,10 +23,10 @@ .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - TagName = 'v1.0.0' - TargetCommitish = 'main' + Owner = 'octocat' + Repo = 'hello-world' + TagName = 'v1.0.0' + TargetCommitish = 'main' } New-GitHubReleaseNote @params From cb18efa1d4cb43a0540fbd78f1afde2f286f207c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 11:11:57 +0200 Subject: [PATCH 026/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Save?= =?UTF-8?q?Artifacts.ps1=20to=20create=20a=20new=20GitHub=20release=20with?= =?UTF-8?q?=20initial=20release=20notes;=20refactor=20GitHubRelease=20clas?= =?UTF-8?q?s=20to=20include=20additional=20properties;=20modify=20New-GitH?= =?UTF-8?q?ubRelease=20and=20Set-GitHubRelease=20functions=20for=20paramet?= =?UTF-8?q?er=20consistency=20and=20improved=20output=20handling.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 3 +- src/classes/public/Releases/GitHubRelease.ps1 | 44 +++++++++++-------- .../public/Releases/New-GitHubRelease.ps1 | 12 ++--- .../public/Releases/Remove-GitHubRelease.ps1 | 4 +- .../public/Releases/Set-GitHubRelease.ps1 | 33 ++++++-------- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index fadc77fbf..194d800a1 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -12,5 +12,4 @@ Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease Get-GitHubRelease -Owner PSModule -Repository GitHub - -Get-GitHubUser +Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.0' -Title 'mytest' -Notes 'Initial release' diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index 2450cfd4d..4a69cfd12 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -41,24 +41,27 @@ } class GitHubRelease : GitHubNode { - # GitHub URL for the release - # Example: "https://github.com/PSModule/GitHub/releases/tag/v0.22.1" - [string] $Url + # Name of the release, can be null + # Example: "v0.22.1" + [string] $Name - # User who authored the release - [GitHubUser] $Author + # The repository where the environment is. + [string] $Repository + + # The owner of the environment. + [string] $Owner # The name of the tag # Example: "v0.22.1" [string] $Tag + # Release notes or changelog, can be null + # Example: "## What's Changed\n### Other Changes\n* Fix: Enhance repository deletion feedback and fix typo..." + [string] $Notes + # Specifies the commitish value that determines where the Git tag is created from # Example: "main" - [string] $TargetCommitish - - # Name of the release, can be null - # Example: "v0.22.1" - [string] $Name + [string] $Target # True if the release is the latest release on the repo. # Example: true @@ -72,6 +75,13 @@ class GitHubRelease : GitHubNode { # Example: false [bool] $Prerelease + # GitHub URL for the release + # Example: "https://github.com/PSModule/GitHub/releases/tag/v0.22.1" + [string] $Url + + # User who authored the release + [GitHubUser] $Author + # Timestamp when the release was created # Example: "2025-04-11T09:03:38Z" [System.Nullable[datetime]] $CreatedAt @@ -91,24 +101,23 @@ class GitHubRelease : GitHubNode { # Assets that are uploaded to the release. [GitHubReleaseAsset[]] $Assets - # Release notes or changelog, can be null - # Example: "## What's Changed\n### Other Changes\n* Fix: Enhance repository deletion feedback and fix typo..." - [string] $Body - # Number of mentions in the release notes # Example: 1 [int] $Mentions GitHubRelease() {} - GitHubRelease([PSCustomObject] $Object, [bool] $Latest) { + GitHubRelease([PSCustomObject] $Object, [string]$Repository, [string] $Owner, [bool] $Latest) { $this.ID = $Object.id $this.NodeID = $Object.node_id + $this.Name = $Object.name + $this.Repository = $Repository + $this.Owner = $Owner + $this.Notes = $Object.body $this.Url = $Object.html_url $this.Author = [GitHubUser]::new($Object.author) $this.Tag = $Object.tag_name - $this.TargetCommitish = $Object.target_commitish - $this.Name = $Object.name + $this.Target = $Object.target_commitish $this.Latest = $Latest $this.Draft = $Object.draft $this.Prerelease = $Object.prerelease @@ -117,7 +126,6 @@ class GitHubRelease : GitHubNode { $this.Assets = $Object.assets | ForEach-Object { [GitHubReleaseAsset]::new($_) } $this.TarballUrl = $Object.tarball_url $this.ZipballUrl = $Object.zipball_url - $this.Body = $Object.body $this.Mentions = $Object.mentions_count } diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 index 56e506d77..7edb5174b 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -11,9 +11,9 @@ and "[Dealing with secondary rate limits](https://docs.github.com/rest/guides/best-practices-for-integrators#dealing-with-secondary-rate-limits)" for details. .EXAMPLE - New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -TagName 'v1.0.0' -TargetCommitish 'main' -Body 'Release notes' + New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Target 'main' -Notes 'Release notes' - Creates a release for the repository 'octocat/hello-world' with the tag 'v1.0.0' and the target commitish 'main'. + Creates a release for the repository 'octocat/hello-world' on the 'main' branch with the tag 'v1.0.0'. .INPUTS GitHubRepository @@ -27,7 +27,7 @@ .LINK [Create a release](https://docs.github.com/rest/releases/releases#create-a-release) #> - [OutputType([pscustomobject])] + [OutputType([GitHubRelease])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding(SupportsShouldProcess)] param( @@ -51,7 +51,7 @@ # The name of the release. [Parameter()] - [string] $Title, + [string] $Name, # Text describing the contents of the tag. [Parameter()] @@ -101,7 +101,7 @@ $body = @{ tag_name = $Tag target_commitish = $Target - name = $Title + name = $Name body = $Notes discussion_category_name = $DiscussionCategoryName make_latest = $latestString @@ -120,7 +120,7 @@ if ($PSCmdlet.ShouldProcess("$Owner/$Repository", 'Create a release')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubRelease]::new($_.Response) } } } diff --git a/src/functions/public/Releases/Remove-GitHubRelease.ps1 b/src/functions/public/Releases/Remove-GitHubRelease.ps1 index 1184c427e..359494802 100644 --- a/src/functions/public/Releases/Remove-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Remove-GitHubRelease.ps1 @@ -55,9 +55,7 @@ } if ($PSCmdlet.ShouldProcess("Release with ID [$ID] in [$Owner/$Repository]", 'DELETE')) { - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } + $null = Invoke-GitHubAPI @inputObject } } diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 1559ef234..f538db3bd 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -1,4 +1,4 @@ -filter Set-GitHubRelease { +filter Update-GitHubRelease { <# .SYNOPSIS Update a release @@ -7,7 +7,7 @@ Users with push access to the repository can edit a release. .EXAMPLE - Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Body 'Release notes' + Update-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Body 'Release notes' Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the body 'Release notes'. @@ -30,20 +30,17 @@ # The unique identifier of the release. [Parameter(Mandatory)] - [Alias('release_id')] [string] $ID, # The name of the tag. [Parameter()] - [Alias('tag_name')] - [string] $TagName, + [string] $Tag, # Specifies the commitish value that determines where the Git tag is created from. # Can be any branch or commit SHA. Unused if the Git tag already exists. # API Default: the repository's default branch. [Parameter()] - [Alias('target_commitish')] - [string] $TargetCommitish, + [string] $Target, # The name of the release. [Parameter()] @@ -51,7 +48,7 @@ # Text describing the contents of the tag. [Parameter()] - [string] $Body, + [string] $Notes, # Whether the release is a draft. [Parameter()] @@ -65,16 +62,14 @@ # The value must be a category that already exists in the repository. # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). [Parameter()] - [Alias('discussion_category_name')] [string] $DiscussionCategoryName, # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. - # Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation - # date and higher semantic version. + # If not specified the latest release is determined based on the release creation date and higher semantic version. + # If set to true, the release will be set as the latest release for the repository. + # If set to false, the release will not be set as the latest release for the repository. [Parameter()] - [Alias('make_latest')] - [ValidateSet('true', 'false', 'legacy')] - [string] $MakeLatest = 'true', + [switch] $Latest, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -91,12 +86,12 @@ process { $body = @{ - tag_name = $TagName - target_commitish = $TargetCommitish + tag_name = $Tag + target_commitish = $Target name = $Name - body = $Body + body = $Notes discussion_category_name = $DiscussionCategoryName - make_latest = $MakeLatest + make_latest = $Latest draft = $Draft prerelease = $Prerelease } @@ -111,7 +106,7 @@ if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubRelease]::new($_.Response) } } } From 4e494c23a262083e8f8c2f32d929c8d67574faa3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 11:13:26 +0200 Subject: [PATCH 027/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20GitH?= =?UTF-8?q?ubRelease=20instantiation=20in=20multiple=20release=20retrieval?= =?UTF-8?q?=20functions=20to=20include=20Owner=20and=20Repository=20parame?= =?UTF-8?q?ters=20for=20improved=20context.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/private/Releases/Get-GitHubReleaseAll.ps1 | 2 +- src/functions/private/Releases/Get-GitHubReleaseByID.ps1 | 2 +- src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 | 2 +- src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index 5d77341e6..00ed59b3f 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -65,7 +65,7 @@ Invoke-GitHubAPI @inputObject | ForEach-Object { $_.Response | ForEach-Object { $isLatest = $_.id -eq $latest.id - [GitHubRelease]::new($_, $isLatest) + [GitHubRelease]::new($_, $Owner, $Repository, $isLatest) } } } catch { return } diff --git a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 index 5028bd021..350bed5f1 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 @@ -60,7 +60,7 @@ try { Invoke-GitHubAPI @inputObject | ForEach-Object { $isLatest = $_.Response.id -eq $latest.id - [GitHubRelease]::new($_.Response, $isLatest) + [GitHubRelease]::new($_.Response, $Owner, $Repository, $isLatest) } } catch { return } } diff --git a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 index 7641df841..3854a5ec1 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 @@ -59,7 +59,7 @@ try { Invoke-GitHubAPI @inputObject | ForEach-Object { $isLatest = $_.Response.id -eq $latest.id - [GitHubRelease]::new($_.Response, $isLatest) + [GitHubRelease]::new($_.Response, $Owner, $Repository, $isLatest) } } catch { return } } diff --git a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 index b44d0c90a..c699e2589 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 @@ -54,7 +54,7 @@ try { Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response, $true) + [GitHubRelease]::new($_.Response, $Owner, $Repository, $true) } } catch { return } } From 1b021e8022cc701d701b7aa2651e67f8e183f55c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 11:17:33 +0200 Subject: [PATCH 028/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20New-?= =?UTF-8?q?GitHubRelease=20to=20simplify=20Latest=20parameter=20handling?= =?UTF-8?q?=20and=20enhance=20GitHubRelease=20instantiation=20with=20Owner?= =?UTF-8?q?,=20Repository,=20and=20Latest=20parameters.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/Releases/New-GitHubRelease.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 index 7edb5174b..168811ea0 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -97,7 +97,7 @@ } process { - $latestString = ($PSBoundParameters.ContainsKey('Latest') ? [string]$Latest : 'legacy').ToLower() + $latestString = $Latest ? 'true' : 'false' $body = @{ tag_name = $Tag target_commitish = $Target @@ -120,7 +120,7 @@ if ($PSCmdlet.ShouldProcess("$Owner/$Repository", 'Create a release')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response) + [GitHubRelease]::new($_.Response , $Owner, $Repository, $Latest) } } } From fa5a66b0c0ad0ddd7c98200b859b34e932df2061 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 11:22:16 +0200 Subject: [PATCH 029/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Save?= =?UTF-8?q?Artifacts.ps1=20to=20change=20release=20tag=20from=20'v1.0'=20t?= =?UTF-8?q?o=20'v1.1'=20for=20the=20new=20GitHub=20release;=20modify=20New?= =?UTF-8?q?-GitHubRelease=20parameters=20for=20consistency.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 2 +- src/classes/public/Releases/GitHubRelease.ps1 | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 194d800a1..d72e78d00 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -12,4 +12,4 @@ Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease Get-GitHubRelease -Owner PSModule -Repository GitHub -Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.0' -Title 'mytest' -Notes 'Initial release' +Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.1' -Name 'mytest' -Notes 'Initial release' diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index 4a69cfd12..02c20db53 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -128,5 +128,4 @@ class GitHubRelease : GitHubNode { $this.ZipballUrl = $Object.zipball_url $this.Mentions = $Object.mentions_count } - } From 541fccf733265277f0680ce749952d5e76421b07 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 11:48:25 +0200 Subject: [PATCH 030/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Save?= =?UTF-8?q?Artifacts.ps1=20to=20change=20release=20tag=20from=20'v1.1'=20t?= =?UTF-8?q?o=20'v1.4'=20for=20the=20new=20GitHub=20release;=20modify=20Get?= =?UTF-8?q?-GitHubRelease=20to=20include=20-Latest=20parameter.=20Refactor?= =?UTF-8?q?=20Get-GitHubRelease=20and=20New-GitHubReleaseNote=20for=20impr?= =?UTF-8?q?oved=20parameter=20handling=20and=20output=20types.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 2 +- .../public/Releases/GitHubReleaseNote.ps1 | 16 ++++++++++ .../public/Releases/Get-GitHubRelease.ps1 | 3 -- .../public/Releases/New-GitHubReleaseNote.ps1 | 30 +++++++++---------- .../public/Releases/Remove-GitHubRelease.ps1 | 23 +++++++------- 5 files changed, 44 insertions(+), 30 deletions(-) create mode 100644 src/classes/public/Releases/GitHubReleaseNote.ps1 diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index d72e78d00..4b3fafe1b 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -12,4 +12,4 @@ Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease Get-GitHubRelease -Owner PSModule -Repository GitHub -Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.1' -Name 'mytest' -Notes 'Initial release' +Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.4' -Notes 'Initial release' -Latest diff --git a/src/classes/public/Releases/GitHubReleaseNote.ps1 b/src/classes/public/Releases/GitHubReleaseNote.ps1 new file mode 100644 index 000000000..9214c7885 --- /dev/null +++ b/src/classes/public/Releases/GitHubReleaseNote.ps1 @@ -0,0 +1,16 @@ +class GitHubReleaseNote { + # Description: The file name of the asset + # Example: "Team Environment" + [string] $Name + + # Release notes or changelog, can be null + # Example: "## What's Changed\n### Other Changes\n* Fix: Enhance repository deletion feedback and fix typo..." + [string] $Notes + + GitHubReleaseNote() {} + + GitHubReleaseNote([PSCustomObject] $Object) { + $this.Name = $Object.name + $this.Notes = $Object.body + } +} diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index 062a2cba6..179c409d5 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -36,9 +36,6 @@ .LINK https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ - - [List releases](https://docs.github.com/rest/releases/releases#list-releases) - [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSReviewUnusedParameter', 'All', diff --git a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 index 915f5bea0..1f2c1724b 100644 --- a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 @@ -48,42 +48,42 @@ The release notes will be based on the changes between the tags 'v0.9.2' and 'v1.0.0' and generated based on the configuration file located in the repository at '.github/custom_release_config.yml'. + .OUTPUTS + GitHubReleaseNote + .LINK https://psmodule.io/GitHub/Functions/Releases/New-GitHubReleaseNote/ .LINK - [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#list-releases) + [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#generate-release-notes-content-for-a-release) #> - [OutputType([pscustomobject])] + [OutputType([GitHubReleaseNote])] [Alias('Generate-GitHubReleaseNotes')] [Alias('New-GitHubReleaseNotes')] [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The tag name for the release. This can be an existing tag or a new one. - [Parameter(Mandatory)] - [string] $TagName, + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Tag, # Specifies the commitish value that will be the target for the release's tag. # Required if the supplied tag_name does not reference an existing tag. # Ignored if the tag_name already exists. [Parameter()] - [string] $TargetCommitish, + [string] $Target, # The name of the previous tag to use as the starting point for the release notes. # Use to manually specify the range for the set of changes considered as part this release. [Parameter()] - [string] $PreviousTagName, - + [string] $PreviousTag, # Specifies a path to a file in the repository containing configuration settings used for generating the release notes. # If unspecified, the configuration file located in the repository at '.github/release.yml' or '.github/release.yaml' will be used. @@ -106,9 +106,9 @@ process { $body = @{ - tag_name = $TagName - target_commitish = $TargetCommitish - previous_tag_name = $PreviousTagName + tag_name = $Tag + target_commitish = $Target + previous_tag_name = $PreviousTag configuration_file_path = $ConfigurationFilePath } $body | Remove-HashtableEntry -NullOrEmptyValues @@ -121,7 +121,7 @@ if ($PSCmdlet.ShouldProcess("release notes for release on $Owner/$Repository", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubReleaseNote]::($_.Response) } } } diff --git a/src/functions/public/Releases/Remove-GitHubRelease.ps1 b/src/functions/public/Releases/Remove-GitHubRelease.ps1 index 359494802..fcf93b6a4 100644 --- a/src/functions/public/Releases/Remove-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Remove-GitHubRelease.ps1 @@ -11,27 +11,28 @@ Deletes the release with the ID '1234567' for the repository 'octocat/hello-world'. - .NOTES + .INPUTS + GitHubRelease + + .LINK + https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ + + .LINK [Delete a release](https://docs.github.com/rest/releases/releases#delete-a-release) #> - [OutputType([pscustomobject])] + [OutputType([void])] [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The unique identifier of the release. - [Parameter( - Mandatory - )] - [Alias('release_id')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -54,7 +55,7 @@ Context = $Context } - if ($PSCmdlet.ShouldProcess("Release with ID [$ID] in [$Owner/$Repository]", 'DELETE')) { + if ($PSCmdlet.ShouldProcess("Release with ID [$ID] in [$Owner/$Repository]", 'Delete')) { $null = Invoke-GitHubAPI @inputObject } } From 0b193393023b6d8fb8e7afcc94ae4931e6c684e3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 11:56:57 +0200 Subject: [PATCH 031/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Save?= =?UTF-8?q?Artifacts.ps1=20to=20change=20release=20tag=20to=20'v1.6.3'=20a?= =?UTF-8?q?nd=20include=20-GenerateReleaseNotes;=20modify=20GitHubRelease?= =?UTF-8?q?=20constructor=20parameter=20order=20for=20consistency=20and=20?= =?UTF-8?q?update=20Set-GitHubRelease=20to=20match=20new=20constructor=20s?= =?UTF-8?q?ignature.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 4 +++- src/classes/public/Releases/GitHubRelease.ps1 | 2 +- src/functions/public/Releases/Set-GitHubRelease.ps1 | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 4b3fafe1b..ad363fce2 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -12,4 +12,6 @@ Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease Get-GitHubRelease -Owner PSModule -Repository GitHub -Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.4' -Notes 'Initial release' -Latest +Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.6.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' +Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease -All | Select * + diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index 02c20db53..edc79ecc0 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -107,7 +107,7 @@ class GitHubRelease : GitHubNode { GitHubRelease() {} - GitHubRelease([PSCustomObject] $Object, [string]$Repository, [string] $Owner, [bool] $Latest) { + GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository, [bool] $Latest) { $this.ID = $Object.id $this.NodeID = $Object.node_id $this.Name = $Object.name diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index f538db3bd..21d36521c 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -106,7 +106,7 @@ if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response) + [GitHubRelease]::new($_.Response, $Owner, $Repository, $Latest) } } } From 62e96d848639cdaf3154323c7e77e9af7dbdebd2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 12:02:07 +0200 Subject: [PATCH 032/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Save?= =?UTF-8?q?Artifacts.ps1=20to=20remove=20unnecessary=20blank=20lines;=20mo?= =?UTF-8?q?dify=20GitHubRelease.Format.ps1xml=20to=20add=20'Owner'=20and?= =?UTF-8?q?=20'Repository'=20columns=20and=20adjust=20existing=20column=20?= =?UTF-8?q?labels=20for=20clarity.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 4 +++- src/formats/GitHubRelease.Format.ps1xml | 32 +++++++++++++++---------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index ad363fce2..cd1000519 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -7,6 +7,9 @@ Get-GitHubRepository -Username MariusStorhaug -Name mytest | Remove-GitHubReposi New-GitHubRelease -Owner MariusStorhaug -Repository mytest -Name 'mytest' -Tag 'v1.0' -Body 'Initial release' -Debug Get-GitHubOrganization -Name PSModule | Get-GitHubRepository -Name GitHub | Get-GitHubWorkflow -Name Process-PSModule | Get-gitHubWorkflowRun + + + Get-GitHubOrganization | Get-GitHubRepository -Name GitHub | Get-GitHubRelease Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease @@ -14,4 +17,3 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.6.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease -All | Select * - diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml index 119150850..bffb8dbed 100644 --- a/src/formats/GitHubRelease.Format.ps1xml +++ b/src/formats/GitHubRelease.Format.ps1xml @@ -8,11 +8,17 @@ + + + - + + + + @@ -26,12 +32,6 @@ - - - - - - @@ -43,22 +43,22 @@ Tag - Author + Owner - Latest + Repository - Prerelease + Author - Draft + Latest - CreatedAt + Prerelease - PublishedAt + Draft @@ -83,6 +83,12 @@ Latest + + Owner + + + Repository + Url From a0d30770619de210d7fec2fc23cb4b78bba22e40 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 12:07:51 +0200 Subject: [PATCH 033/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20GitH?= =?UTF-8?q?ubRelease.Format.ps1xml=20to=20remove=20'Author'=20column=20and?= =?UTF-8?q?=20add=20'Url'=20column=20for=20improved=20clarity;=20modify=20?= =?UTF-8?q?SaveArtifacts.ps1=20to=20streamline=20GitHubRelease=20retrieval?= =?UTF-8?q?=20commands.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 4 ++-- src/formats/GitHubRelease.Format.ps1xml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index cd1000519..d5a17d016 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -10,8 +10,8 @@ Get-GitHubOrganization -Name PSModule | Get-GitHubRepository -Name GitHub | Get- -Get-GitHubOrganization | Get-GitHubRepository -Name GitHub | Get-GitHubRelease -Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease +Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease +Get-GitHubUser | Get-GitHubRepository | Get-GitHubRelease Get-GitHubRelease -Owner PSModule -Repository GitHub diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml index bffb8dbed..afaf993a4 100644 --- a/src/formats/GitHubRelease.Format.ps1xml +++ b/src/formats/GitHubRelease.Format.ps1xml @@ -20,9 +20,6 @@ - - - @@ -32,6 +29,9 @@ + + + @@ -48,9 +48,6 @@ Repository - - Author - Latest @@ -60,6 +57,9 @@ Draft + + Url + From cc3ca5d328841498ca40e03e9bbcd98640a0aeb0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 12:55:16 +0200 Subject: [PATCH 034/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Save?= =?UTF-8?q?Artifacts.ps1=20to=20add=20new=20GitHub=20API=20calls=20for=20b?= =?UTF-8?q?ranch=20creation=20and=20retrieval;=20modify=20GitHubRelease.Fo?= =?UTF-8?q?rmat.ps1xml=20to=20include=20'Url'=20column=20and=20remove=20'A?= =?UTF-8?q?uthor'=20column=20for=20improved=20clarity.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 13 ++++++- src/formats/GitHubRelease.Format.ps1xml | 45 +++++++------------------ 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index d5a17d016..aeff3af9f 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -16,4 +16,15 @@ Get-GitHubUser | Get-GitHubRepository | Get-GitHubRelease Get-GitHubRelease -Owner PSModule -Repository GitHub Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.6.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease -All | Select * +Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease -All + + +Invoke-GitHubAPI -ApiEndpoint '/repos/PSModule/Github/git/matching-refs/' | Select-Object -ExpandProperty Response | Select * | Format-Table + +Invoke-GitHubAPI -ApiEndpoint '/repos/MariusStorhaug/mytest/branches' | Select-Object -ExpandProperty Response + + +Invoke-GitHubAPI -Method POST -ApiEndpoint '/repos/MariusStorhaug/mytest/git/refs' -Body @{ + ref = 'refs/heads/test' + sha = 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0' +} diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml index afaf993a4..fcdceb8ad 100644 --- a/src/formats/GitHubRelease.Format.ps1xml +++ b/src/formats/GitHubRelease.Format.ps1xml @@ -11,15 +11,15 @@ - - - + + + @@ -29,16 +29,10 @@ - - - - - Name - Tag @@ -48,6 +42,9 @@ Repository + + Url + Latest @@ -57,9 +54,6 @@ Draft - - Url - @@ -74,15 +68,9 @@ - - Name - Tag - - Latest - Owner @@ -96,7 +84,10 @@ Author - TargetCommitish + Target + + + Latest Draft @@ -110,26 +101,14 @@ PublishedAt - - TarballUrl - - - ZipballUrl - Assets - Body - - - Mentions - - - ID + Name - NodeID + Notes From a11dfafcbb10a678c144d6dce6f4b4f893fb6d46 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 13:10:46 +0200 Subject: [PATCH 035/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Refactor=20Sa?= =?UTF-8?q?veArtifacts.ps1=20to=20streamline=20GitHub=20release=20commands?= =?UTF-8?q?=20and=20improve=20readability;=20add=20multiple=20New-GitHubRe?= =?UTF-8?q?lease=20calls=20for=20versioning;=20remove=20unused=20Invoke-Gi?= =?UTF-8?q?tHubAPI=20calls.=20Reintroduce=20Update-GitHubRelease=20functio?= =?UTF-8?q?n=20with=20enhanced=20parameters=20for=20better=20release=20man?= =?UTF-8?q?agement.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 22 +++++++++---------- ...ubRelease.ps1 => Update-GitHubRelease.ps1} | 19 +++++++--------- 2 files changed, 18 insertions(+), 23 deletions(-) rename src/functions/public/Releases/{Set-GitHubRelease.ps1 => Update-GitHubRelease.ps1} (86%) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index aeff3af9f..b0d0fd50c 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -6,7 +6,7 @@ New-GitHubRepository -Name mytest -AllowSquashMerge -AddReadme -License mit -Git Get-GitHubRepository -Username MariusStorhaug -Name mytest | Remove-GitHubRepository -Confirm:$false New-GitHubRelease -Owner MariusStorhaug -Repository mytest -Name 'mytest' -Tag 'v1.0' -Body 'Initial release' -Debug -Get-GitHubOrganization -Name PSModule | Get-GitHubRepository -Name GitHub | Get-GitHubWorkflow -Name Process-PSModule | Get-gitHubWorkflowRun +Get-GitHubOrganization -Name PSModule | Get-GitHubRepository -Name GitHub | Get-GitHubWorkflow -Name Process-PSModule | Get-GitHubWorkflowRun @@ -15,16 +15,14 @@ Get-GitHubUser | Get-GitHubRepository | Get-GitHubRelease Get-GitHubRelease -Owner PSModule -Repository GitHub -Get-GitHubUser | Get-GitHubRepository -Name mytest | New-GitHubRelease -Tag 'v1.6.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -Get-GitHubUser | Get-GitHubRepository -Name mytest | Get-GitHubRelease -All +$repo = Get-GitHubUser | Get-GitHubRepository -Name mytest +$repo | Get-GitHubRelease -All +$repo | New-GitHubRelease -Tag 'v1.0' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' +$repo | New-GitHubRelease -Tag 'v1.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' +$repo | New-GitHubRelease -Tag 'v1.2' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' +$repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' +$repo | Get-GitHubRelease -All +$repo | Update-GitHubRelease -Tag 'v1.3' -Draft -PreRelease +$repo | Get-GitHubRelease -All | Remove-GitHubRelease -Invoke-GitHubAPI -ApiEndpoint '/repos/PSModule/Github/git/matching-refs/' | Select-Object -ExpandProperty Response | Select * | Format-Table - -Invoke-GitHubAPI -ApiEndpoint '/repos/MariusStorhaug/mytest/branches' | Select-Object -ExpandProperty Response - - -Invoke-GitHubAPI -Method POST -ApiEndpoint '/repos/MariusStorhaug/mytest/git/refs' -Body @{ - ref = 'refs/heads/test' - sha = 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0' -} diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 similarity index 86% rename from src/functions/public/Releases/Set-GitHubRelease.ps1 rename to src/functions/public/Releases/Update-GitHubRelease.ps1 index 21d36521c..ed9146a69 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -19,17 +19,15 @@ [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The unique identifier of the release. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $ID, # The name of the tag. @@ -91,9 +89,9 @@ name = $Name body = $Notes discussion_category_name = $DiscussionCategoryName - make_latest = $Latest - draft = $Draft - prerelease = $Prerelease + make_latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest : $null + draft = $PSBoundParameters.ContainsKey('Draft') ? [bool]$Draft : $null + prerelease = $PSBoundParameters.ContainsKey('Prerelease') ? [bool]$Prerelease : $null } $body | Remove-HashtableEntry -NullOrEmptyValues @@ -105,10 +103,9 @@ } if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { - Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response, $Owner, $Repository, $Latest) - } + Invoke-GitHubAPI @inputObject } + Get-GitHubReleaseByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context } end { From 0bd3867d93344413f5a3d43494d72dea6cb9b924 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 13:37:01 +0200 Subject: [PATCH 036/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Clean=20up=20?= =?UTF-8?q?SaveArtifacts.ps1=20by=20removing=20unused=20GitHub=20commands;?= =?UTF-8?q?=20add=20new=20Releases.ps1=20script=20to=20demonstrate=20GitHu?= =?UTF-8?q?b=20release=20management=20with=20repository=20creation=20and?= =?UTF-8?q?=20release=20tagging.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 25 --------------- examples/Releases/Releases.ps1 | 31 +++++++++++++++++++ .../public/Releases/Get-GitHubRelease.ps1 | 7 ++++- 3 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 examples/Releases/Releases.ps1 diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index b0d0fd50c..302fb3f37 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -1,28 +1,3 @@ $modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | Save-GitHubArtifact -Path $modulesPath -Extract -Force - -New-GitHubRepository -Name mytest -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio -Get-GitHubRepository -Username MariusStorhaug -Name mytest | Remove-GitHubRepository -Confirm:$false -New-GitHubRelease -Owner MariusStorhaug -Repository mytest -Name 'mytest' -Tag 'v1.0' -Body 'Initial release' -Debug - -Get-GitHubOrganization -Name PSModule | Get-GitHubRepository -Name GitHub | Get-GitHubWorkflow -Name Process-PSModule | Get-GitHubWorkflowRun - - - -Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease -Get-GitHubUser | Get-GitHubRepository | Get-GitHubRelease - -Get-GitHubRelease -Owner PSModule -Repository GitHub - -$repo = Get-GitHubUser | Get-GitHubRepository -Name mytest -$repo | Get-GitHubRelease -All -$repo | New-GitHubRelease -Tag 'v1.0' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | New-GitHubRelease -Tag 'v1.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | New-GitHubRelease -Tag 'v1.2' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | Get-GitHubRelease -All -$repo | Update-GitHubRelease -Tag 'v1.3' -Draft -PreRelease - -$repo | Get-GitHubRelease -All | Remove-GitHubRelease - diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 new file mode 100644 index 000000000..aa6ac4024 --- /dev/null +++ b/examples/Releases/Releases.ps1 @@ -0,0 +1,31 @@ +# Get the latest release for a specific repository +Get-GitHubRelease -Owner PSModule -Repository GitHub + +# Get all the releases for a specific repository +Get-GitHubRelease -Owner PSModule -Repository GitHub -All + +# Get the latest releases for all repos in the organization +Get-GitHubOrganization -Name GitHub | Get-GitHubRepository | Get-GitHubRelease + +# Get all the releases for all repos in the organization +Get-GitHubOrganization -Name GitHub | Get-GitHubRepository | Get-GitHubRelease + + +$repoName = 'mytest' +New-GitHubRepository -Name $repoName -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio + +$repo = Get-GitHubUser | Get-GitHubRepository -Name $repoName +$repo | Get-GitHubRelease -All +$repo | New-GitHubRelease -Tag 'v1.0' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' +$repo | New-GitHubRelease -Tag 'v1.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' +$repo | New-GitHubRelease -Tag 'v1.2' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' +$repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' +$repo | Get-GitHubRelease -All +$repo | New-GitHubRelease -Tag 'v1.4' -Draft +$repo | Get-GitHubRelease -Tag 'v1.4' +$repo | Update-GitHubRelease -Tag 'v1.3' -Draft -Prerelease + +$repo | Get-GitHubRelease -All | Remove-GitHubRelease + + +Get-GitHubRepository -Username MariusStorhaug -Name $repoName | Remove-GitHubRepository -Confirm:$false diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index 179c409d5..085683b3d 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -94,7 +94,12 @@ Get-GitHubReleaseAll @params -PerPage $PerPage } 'Tag' { - Get-GitHubReleaseByTagName @params -Tag $Tag + $release = Get-GitHubReleaseByTagName @params -Tag $Tag + if ($release) { + $release + } else { + Get-GithubReleaseAll @params -PerPage $PerPage | Where-Object { $_.TagName -eq $Tag } + } } 'ID' { Get-GitHubReleaseByID @params -ID $ID From 74aa828fb6b43e2b2fdc89d4935f1625e638ec46 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 13:40:32 +0200 Subject: [PATCH 037/224] Update Releases.ps1 to include debug option for Get-GitHubRelease; modify Get-GitHubRelease function to use 'Tag' instead of 'TagName' for improved accuracy. --- examples/Releases/Releases.ps1 | 2 +- src/functions/public/Releases/Get-GitHubRelease.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index aa6ac4024..16769c536 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -22,7 +22,7 @@ $repo | New-GitHubRelease -Tag 'v1.2' -Latest -GenerateReleaseNotes -Notes 'Rele $repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' $repo | Get-GitHubRelease -All $repo | New-GitHubRelease -Tag 'v1.4' -Draft -$repo | Get-GitHubRelease -Tag 'v1.4' +$repo | Get-GitHubRelease -Tag 'v1.4' -Debug $repo | Update-GitHubRelease -Tag 'v1.3' -Draft -Prerelease $repo | Get-GitHubRelease -All | Remove-GitHubRelease diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index 085683b3d..0ec5f9a3d 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -98,7 +98,7 @@ if ($release) { $release } else { - Get-GithubReleaseAll @params -PerPage $PerPage | Where-Object { $_.TagName -eq $Tag } + Get-GithubReleaseAll @params -PerPage $PerPage | Where-Object { $_.Tag -eq $Tag } } } 'ID' { From 85a0bdce8c3bdbe1e5e8e4356e8309810d127933 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 13:49:58 +0200 Subject: [PATCH 038/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Rele?= =?UTF-8?q?ases.ps1=20to=20include=20release=20name=20for=20v1.4;=20modify?= =?UTF-8?q?=20Update-GitHubRelease.ps1=20to=20suppress=20output=20of=20Inv?= =?UTF-8?q?oke-GitHubAPI=20for=20cleaner=20execution.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Releases/Releases.ps1 | 5 ++--- src/functions/public/Releases/Update-GitHubRelease.ps1 | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 16769c536..3c2b10d28 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -21,9 +21,8 @@ $repo | New-GitHubRelease -Tag 'v1.1' -Latest -GenerateReleaseNotes -Notes 'Rele $repo | New-GitHubRelease -Tag 'v1.2' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' $repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' $repo | Get-GitHubRelease -All -$repo | New-GitHubRelease -Tag 'v1.4' -Draft -$repo | Get-GitHubRelease -Tag 'v1.4' -Debug -$repo | Update-GitHubRelease -Tag 'v1.3' -Draft -Prerelease +$repo | New-GitHubRelease -Tag 'v1.4' -Draft -Name 'test' +$repo | Get-GitHubRelease -Tag 'v1.4' | Update-GitHubRelease -Prerelease -Draft:$false $repo | Get-GitHubRelease -All | Remove-GitHubRelease diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index ed9146a69..3e5412127 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -103,7 +103,7 @@ } if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { - Invoke-GitHubAPI @inputObject + $null = Invoke-GitHubAPI @inputObject } Get-GitHubReleaseByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context } From 13756c7176a8c41bec77f42f7319e6fcac1171cd Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 14:08:01 +0200 Subject: [PATCH 039/224] =?UTF-8?q?=F0=9F=A9=B9=20[Feature]:=20Add=20Set-G?= =?UTF-8?q?itHubRelease=20function=20to=20create=20or=20update=20GitHub=20?= =?UTF-8?q?releases=20with=20enhanced=20parameters=20for=20better=20releas?= =?UTF-8?q?e=20management.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/Releases/Set-GitHubRelease.ps1 | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/functions/public/Releases/Set-GitHubRelease.ps1 diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 new file mode 100644 index 000000000..af85e5220 --- /dev/null +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -0,0 +1,124 @@ +filter Set-GitHubRelease { + <# + .SYNOPSIS + Creates or updates a release. + + .DESCRIPTION + + + .EXAMPLE + Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Target 'main' -Notes 'Release notes' + + .INPUTS + GitHubRepository + + .OUTPUTS + GitHubRelease + + .LINK + https://psmodule.io/GitHub/Functions/Releases/Set-GitHubRelease/ + #> + [OutputType([GitHubRelease])] + [CmdletBinding(SupportsShouldProcess)] + param( + # The account owner of the repository. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Repository, + + # The name of the tag. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Tag, + + # Specifies the reference value that determines where the Git tag is created from. + # Can be any branch or commit SHA. Unused if the Git tag already exists. + # API Default: the repository's default branch. + [Parameter()] + [string] $Target = 'main', + + # The name of the release. + [Parameter()] + [string] $Name, + + # Text describing the contents of the tag. + [Parameter()] + [string] $Notes, + + # Whether the release is a draft. + [Parameter()] + [switch] $Draft, + + # Whether to identify the release as a prerelease. + [Parameter()] + [switch] $Prerelease, + + # If specified, a discussion of the specified category is created and linked to the release. + # The value must be a category that already exists in the repository. + [Parameter()] + [string] $DiscussionCategoryName, + + # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, + # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. + [Parameter()] + [switch] $GenerateReleaseNotes, + + # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. + # If not specified the latest release is determined based on the release creation date and higher semantic version. + # If set to true, the release will be set as the latest release for the repository. + # If set to false, the release will not be set as the latest release for the repository. + [Parameter()] + [switch] $Latest, + + # The context to run the command in. Used to get the details for the API call. + # Can be either a string or a GitHubContext object. + [Parameter()] + [object] $Context = (Get-GitHubContext) + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + $Context = Resolve-GitHubContext -Context $Context + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + } + + process { + $scope = @{ + Owner = $Owner + Repository = $Repository + Context = $Context + } + + $params = @{ + Tag = $Tag + Target = $Target + Name = $Name + Notes = $Notes + DiscussionCategoryName = $DiscussionCategoryName + Latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest : $null + Draft = $PSBoundParameters.ContainsKey('Draft') ? [bool]$Draft : $null + Prerelease = $PSBoundParameters.ContainsKey('Prerelease') ? [bool]$Prerelease : $null + } + $params | Remove-HashtableEntry -NullOrEmptyValues + + if (Get-GitHubRelease @scope -Tag $Tag) { + if ($PSBoundParameters.ContainsKey('GenerateReleaseNotes')) { + $params['GenerateReleaseNotes'] = $GenerateReleaseNotes + } + $null = Update-GitHubRelease @scope @params + } else { + $null = New-GitHubRelease @scope @params + } + + Get-GitHubRelease @scope -Tag $Tag + } + + end { + Write-Debug "[$stackPath] - End" + } +} + +#SkipTest:FunctionTest:Will add a test for this function in a future PR From 14990b8cf296bb6122c0bce803729bf1f270b81e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 18:16:57 +0200 Subject: [PATCH 040/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Remove=20unus?= =?UTF-8?q?ed=20code=20from=20SaveArtifacts.ps1;=20update=20Releases.ps1?= =?UTF-8?q?=20to=20use=20PSModule=20for=20organization=20queries;=20refact?= =?UTF-8?q?or=20Set-GitHubRelease=20to=20improve=20release=20handling=20lo?= =?UTF-8?q?gic.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 4 +--- examples/Releases/Releases.ps1 | 12 ++++++------ src/functions/public/Releases/Set-GitHubRelease.ps1 | 5 +++-- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 302fb3f37..19a76f130 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -1,3 +1 @@ -$modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 -Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | - Save-GitHubArtifact -Path $modulesPath -Extract -Force + \ No newline at end of file diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 3c2b10d28..8a17cbf4d 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -5,12 +5,12 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub Get-GitHubRelease -Owner PSModule -Repository GitHub -All # Get the latest releases for all repos in the organization -Get-GitHubOrganization -Name GitHub | Get-GitHubRepository | Get-GitHubRelease +Get-GitHubOrganization -Name PSModule | Get-GitHubRepository | Get-GitHubRelease # Get all the releases for all repos in the organization -Get-GitHubOrganization -Name GitHub | Get-GitHubRepository | Get-GitHubRelease - +Get-GitHubOrganization -Name PSModule | Get-GitHubRepository | Get-GitHubRelease -All +# Create a new release for a specific repository $repoName = 'mytest' New-GitHubRepository -Name $repoName -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio @@ -20,9 +20,9 @@ $repo | New-GitHubRelease -Tag 'v1.0' -Latest -GenerateReleaseNotes -Notes 'Rele $repo | New-GitHubRelease -Tag 'v1.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' $repo | New-GitHubRelease -Tag 'v1.2' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' $repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | Get-GitHubRelease -All -$repo | New-GitHubRelease -Tag 'v1.4' -Draft -Name 'test' -$repo | Get-GitHubRelease -Tag 'v1.4' | Update-GitHubRelease -Prerelease -Draft:$false +$repo | Get-GitHubRelease -All | Where-Object Tag -eq 'v1.4' | Select ID +$repo | Set-GitHubRelease -Tag 'v1.4' -Draft -Name 'test' +$repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft:$false $repo | Get-GitHubRelease -All | Remove-GitHubRelease diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index af85e5220..d9074a13f 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -104,11 +104,12 @@ } $params | Remove-HashtableEntry -NullOrEmptyValues - if (Get-GitHubRelease @scope -Tag $Tag) { + $release = Get-GitHubRelease @scope -Tag $Tag + if ($release) { if ($PSBoundParameters.ContainsKey('GenerateReleaseNotes')) { $params['GenerateReleaseNotes'] = $GenerateReleaseNotes } - $null = Update-GitHubRelease @scope @params + $null = Update-GitHubRelease @scope @params -ID $release.ID } else { $null = New-GitHubRelease @scope @params } From 203cc07450463696d9750b1dde13ff2a44f2b3f8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 18:45:38 +0200 Subject: [PATCH 041/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Enhance=20Set?= =?UTF-8?q?-GitHubRelease=20and=20Update-GitHubRelease=20functions=20to=20?= =?UTF-8?q?improve=20release=20management;=20add=20detailed=20notes=20for?= =?UTF-8?q?=20v1.4=20release=20in=20Releases.ps1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Releases/Releases.ps1 | 24 ++++++++++++++++++- .../public/Releases/Set-GitHubRelease.ps1 | 14 ++--------- .../public/Releases/Update-GitHubRelease.ps1 | 11 +++++---- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 8a17cbf4d..6ab50f231 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -20,10 +20,32 @@ $repo | New-GitHubRelease -Tag 'v1.0' -Latest -GenerateReleaseNotes -Notes 'Rele $repo | New-GitHubRelease -Tag 'v1.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' $repo | New-GitHubRelease -Tag 'v1.2' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' $repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | Get-GitHubRelease -All | Where-Object Tag -eq 'v1.4' | Select ID +$repo | Get-GitHubRelease -All | Where-Object Tag -EQ 'v1.4' | Select-Object ID $repo | Set-GitHubRelease -Tag 'v1.4' -Draft -Name 'test' $repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft:$false +$repo | Set-GitHubRelease -Tag 'v1.4' -Notes @' +## This is a test release. + +This is a test release. +This is a test release. + +## This is a test release. + +This is a test release. +This is a test release. +This is a test release. + +| Header 1 | Header 2 | +|---------|---------| +| Row 1 | Row 2 | +| Row 3 | Row 4 | +| Row 5 | Row 6 | + +'@ +$repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease:$false -Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Latest + $repo | Get-GitHubRelease -All | Remove-GitHubRelease diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index d9074a13f..31883a2c0 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -60,15 +60,8 @@ [Parameter()] [string] $DiscussionCategoryName, - # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, - # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. - [Parameter()] - [switch] $GenerateReleaseNotes, - - # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. - # If not specified the latest release is determined based on the release creation date and higher semantic version. - # If set to true, the release will be set as the latest release for the repository. - # If set to false, the release will not be set as the latest release for the repository. + # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting + # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. [Parameter()] [switch] $Latest, @@ -106,9 +99,6 @@ $release = Get-GitHubRelease @scope -Tag $Tag if ($release) { - if ($PSBoundParameters.ContainsKey('GenerateReleaseNotes')) { - $params['GenerateReleaseNotes'] = $GenerateReleaseNotes - } $null = Update-GitHubRelease @scope @params -ID $release.ID } else { $null = New-GitHubRelease @scope @params diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 3e5412127..62ade50cc 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -62,10 +62,8 @@ [Parameter()] [string] $DiscussionCategoryName, - # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. - # If not specified the latest release is determined based on the release creation date and higher semantic version. - # If set to true, the release will be set as the latest release for the repository. - # If set to false, the release will not be set as the latest release for the repository. + # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting + # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. [Parameter()] [switch] $Latest, @@ -83,6 +81,11 @@ } process { + if ($Latest) { + $Draft = $false + $Prerelease = $false + } + $body = @{ tag_name = $Tag target_commitish = $Target From 4f27a0bee7315aef2ee67501519940dff2a8a5c0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 19:12:08 +0200 Subject: [PATCH 042/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Add=20missing?= =?UTF-8?q?=20code=20to=20SaveArtifacts.ps1=20for=20retrieving=20and=20sav?= =?UTF-8?q?ing=20GitHub=20artifacts.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Artifacts/SaveArtifacts.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 19a76f130..302fb3f37 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -1 +1,3 @@ - \ No newline at end of file +$modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 +Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | + Save-GitHubArtifact -Path $modulesPath -Extract -Force From a993f7c7f5cc78521da3dc2dc6f5246a17870d64 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 19:12:15 +0200 Subject: [PATCH 043/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Simplify=20er?= =?UTF-8?q?ror=20handling=20in=20Invoke-GitHubAPI=20by=20replacing=20compl?= =?UTF-8?q?ex=20error=20throwing=20with=20a=20direct=20throw=20statement.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 9bb09fc89..5c73b4772 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -327,14 +327,8 @@ $($errorResult | Format-List | Out-String -Stream | ForEach-Object { " $_`n" "@ - $PSCmdlet.ThrowTerminatingError( - [System.Management.Automation.ErrorRecord]::new( - [System.Exception]::new($exception), - 'GitHubAPIError', - [System.Management.Automation.ErrorCategory]::InvalidOperation, - $errorResult - ) - ) + throw $exception + } } From 1a2f70ed1229d6582b360850e8b6b5d3ecb2088b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 19:12:47 +0200 Subject: [PATCH 044/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Simplify=20er?= =?UTF-8?q?ror=20output=20formatting=20in=20Invoke-GitHubAPI=20by=20removi?= =?UTF-8?q?ng=20unnecessary=20ForEach-Object=20usage.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 5c73b4772..03e1dfadd 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -322,7 +322,7 @@ filter Invoke-GitHubAPI { ---------------------------------- Error details: -$($errorResult | Format-List | Out-String -Stream | ForEach-Object { " $_`n" }) +$($errorResult | Format-List | Out-String -Stream) ---------------------------------- "@ From 9a3e7ecc64c2a7b538d3c6131ca92ed67ae71d93 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 19:13:04 +0200 Subject: [PATCH 045/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Simplify=20er?= =?UTF-8?q?ror=20output=20formatting=20in=20Invoke-GitHubAPI=20by=20removi?= =?UTF-8?q?ng=20unnecessary=20-Stream=20parameter=20from=20Format-List.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 03e1dfadd..71dbd2f3f 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -321,8 +321,7 @@ filter Invoke-GitHubAPI { $exception = @" ---------------------------------- -Error details: -$($errorResult | Format-List | Out-String -Stream) +$($errorResult | Format-List | Out-String) ---------------------------------- "@ From c82b98a7aa4f0182362d11d5210b30818a8d1a1e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 19:28:11 +0200 Subject: [PATCH 046/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Improve=20err?= =?UTF-8?q?or=20handling=20in=20Invoke-GitHubAPI=20by=20replacing=20throw?= =?UTF-8?q?=20statement=20with=20structured=20error=20record.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 71dbd2f3f..8781f996d 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -319,15 +319,21 @@ filter Invoke-GitHubAPI { $APICall.Method = $APICall.Method.ToString() $exception = @" - ---------------------------------- $($errorResult | Format-List | Out-String) ---------------------------------- - "@ - - throw $exception - + $tmpErrorView = $ErrorView + $ErrorView = 'NormalView' + $PSCmdlet.ThrowTerminatingError( + [System.Management.Automation.ErrorRecord]::new( + [System.Exception]::new($exception), + 'GitHubAPIError', + [System.Management.Automation.ErrorCategory]::InvalidOperation, + $errorResult + ) + ) + $ErrorView = $tmpErrorView } } From f8719302928b2d2328e82984bad54afceac5a624 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 19:38:50 +0200 Subject: [PATCH 047/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Enhance=20err?= =?UTF-8?q?or=20handling=20in=20Invoke-GitHubAPI=20by=20writing=20errors?= =?UTF-8?q?=20directly=20and=20removing=20temporary=20error=20view=20manag?= =?UTF-8?q?ement.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 8781f996d..fb301d3fd 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -323,8 +323,8 @@ filter Invoke-GitHubAPI { $($errorResult | Format-List | Out-String) ---------------------------------- "@ - $tmpErrorView = $ErrorView - $ErrorView = 'NormalView' + $PSCmdlet.WriteError($exception) + $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( [System.Exception]::new($exception), @@ -333,7 +333,6 @@ $($errorResult | Format-List | Out-String) $errorResult ) ) - $ErrorView = $tmpErrorView } } From 0f08624a716cdbdb5745e634063f9196af51590e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 20:16:34 +0200 Subject: [PATCH 048/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Remove=20redu?= =?UTF-8?q?ndant=20error=20writing=20in=20Invoke-GitHubAPI=20to=20streamli?= =?UTF-8?q?ne=20error=20handling.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index fb301d3fd..76515bfb1 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -323,8 +323,6 @@ filter Invoke-GitHubAPI { $($errorResult | Format-List | Out-String) ---------------------------------- "@ - $PSCmdlet.WriteError($exception) - $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( [System.Exception]::new($exception), From 21662cfd28e5fa8cbcabf18651cd0cc1742e3ba4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 21:19:13 +0200 Subject: [PATCH 049/224] Refactor Update-GitHubRelease to set Draft and Prerelease flags based on Latest parameter conditionally. --- examples/Releases/Releases.ps1 | 2 +- src/functions/public/Releases/Update-GitHubRelease.ps1 | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 6ab50f231..935c0d3d1 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -43,7 +43,7 @@ This is a test release. | Row 5 | Row 6 | '@ -$repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease:$false -Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft $repo | Set-GitHubRelease -Tag 'v1.4' -Latest $repo | Get-GitHubRelease -All | Remove-GitHubRelease diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 62ade50cc..e52156ed1 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -81,11 +81,6 @@ } process { - if ($Latest) { - $Draft = $false - $Prerelease = $false - } - $body = @{ tag_name = $Tag target_commitish = $Target @@ -98,6 +93,11 @@ } $body | Remove-HashtableEntry -NullOrEmptyValues + if ($PSBoundParameters.ContainsKey('Latest') -and [bool]$Latest) { + $body['Draft'] = $false + $body['Prerelease'] = $false + } + $inputObject = @{ Method = 'PATCH' APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" From 3c4ba5cb1ab16c2e62ff729b5a902fa5d093a846 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 22:09:10 +0200 Subject: [PATCH 050/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20para?= =?UTF-8?q?meter=20sets=20in=20Set-GitHubRelease=20and=20Update-GitHubRele?= =?UTF-8?q?ase=20to=20enforce=20mandatory=20parameters=20for=20draft,=20pr?= =?UTF-8?q?erelease,=20and=20latest=20flags.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../public/Releases/New-GitHubRelease.ps1 | 11 +++++------ .../public/Releases/Set-GitHubRelease.ps1 | 14 +++++++------- .../public/Releases/Update-GitHubRelease.ps1 | 10 +++++----- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 index 168811ea0..03bbb1304 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -29,7 +29,7 @@ #> [OutputType([GitHubRelease])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] - [CmdletBinding(SupportsShouldProcess)] + [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] @@ -58,11 +58,11 @@ [string] $Notes, # Whether the release is a draft. - [Parameter()] + [Parameter(ParameterSetName = 'Not latest')] [switch] $Draft, # Whether to identify the release as a prerelease. - [Parameter()] + [Parameter(ParameterSetName = 'Not latest')] [switch] $Prerelease, # If specified, a discussion of the specified category is created and linked to the release. @@ -80,7 +80,7 @@ # If not specified the latest release is determined based on the release creation date and higher semantic version. # If set to true, the release will be set as the latest release for the repository. # If set to false, the release will not be set as the latest release for the repository. - [Parameter()] + [Parameter(ParameterSetName = 'Set latest')] [switch] $Latest, # The context to run the command in. Used to get the details for the API call. @@ -97,14 +97,13 @@ } process { - $latestString = $Latest ? 'true' : 'false' $body = @{ tag_name = $Tag target_commitish = $Target name = $Name body = $Notes discussion_category_name = $DiscussionCategoryName - make_latest = $latestString + make_latest = ([bool]$Latest).ToString().ToLower() generate_release_notes = [bool]$GenerateReleaseNotes draft = [bool]$Draft prerelease = [bool]$Prerelease diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 31883a2c0..a738c16d3 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -19,7 +19,7 @@ https://psmodule.io/GitHub/Functions/Releases/Set-GitHubRelease/ #> [OutputType([GitHubRelease])] - [CmdletBinding(SupportsShouldProcess)] + [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] @@ -48,11 +48,11 @@ [string] $Notes, # Whether the release is a draft. - [Parameter()] + [Parameter(ParameterSetName = 'Not latest')] [switch] $Draft, # Whether to identify the release as a prerelease. - [Parameter()] + [Parameter(ParameterSetName = 'Not latest')] [switch] $Prerelease, # If specified, a discussion of the specified category is created and linked to the release. @@ -62,7 +62,7 @@ # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. - [Parameter()] + [Parameter(Mandatory, ParameterSetName = 'Set latest')] [switch] $Latest, # The context to run the command in. Used to get the details for the API call. @@ -91,9 +91,9 @@ Name = $Name Notes = $Notes DiscussionCategoryName = $DiscussionCategoryName - Latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest : $null - Draft = $PSBoundParameters.ContainsKey('Draft') ? [bool]$Draft : $null - Prerelease = $PSBoundParameters.ContainsKey('Prerelease') ? [bool]$Prerelease : $null + Latest = ([bool]$Latest).ToString().ToLower() + Draft = [bool]$Draft + Prerelease = [bool]$Prerelease } $params | Remove-HashtableEntry -NullOrEmptyValues diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index e52156ed1..f16017211 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -16,7 +16,7 @@ #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] - [CmdletBinding(SupportsShouldProcess)] + [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] @@ -49,11 +49,11 @@ [string] $Notes, # Whether the release is a draft. - [Parameter()] + [Parameter(ParameterSetName = 'Not latest')] [switch] $Draft, # Whether to identify the release as a prerelease. - [Parameter()] + [Parameter(ParameterSetName = 'Not latest')] [switch] $Prerelease, # If specified, a discussion of the specified category is created and linked to the release. @@ -64,7 +64,7 @@ # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. - [Parameter()] + [Parameter(Mandatory, ParameterSetName = 'Set latest')] [switch] $Latest, # The context to run the command in. Used to get the details for the API call. @@ -87,7 +87,7 @@ name = $Name body = $Notes discussion_category_name = $DiscussionCategoryName - make_latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest : $null + make_latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest.ToString().ToLower() : $null draft = $PSBoundParameters.ContainsKey('Draft') ? [bool]$Draft : $null prerelease = $PSBoundParameters.ContainsKey('Prerelease') ? [bool]$Prerelease : $null } From b720530ccc796bd76dcceec9b6e73da0f4f3ecea Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 22:17:24 +0200 Subject: [PATCH 051/224] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20Set-?= =?UTF-8?q?GitHubRelease=20to=20directly=20assign=20Latest=20parameter=20a?= =?UTF-8?q?s=20a=20boolean=20instead=20of=20converting=20to=20string.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/Releases/Releases.ps1 | 1 + src/functions/public/Releases/Set-GitHubRelease.ps1 | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 935c0d3d1..926cc8c0a 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -23,6 +23,7 @@ $repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Rele $repo | Get-GitHubRelease -All | Where-Object Tag -EQ 'v1.4' | Select-Object ID $repo | Set-GitHubRelease -Tag 'v1.4' -Draft -Name 'test' $repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft:$false +$repo | Set-GitHubRelease -Tag 'v1.4' -Latest $repo | Set-GitHubRelease -Tag 'v1.4' -Notes @' ## This is a test release. diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index a738c16d3..5bb849893 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -91,7 +91,7 @@ Name = $Name Notes = $Notes DiscussionCategoryName = $DiscussionCategoryName - Latest = ([bool]$Latest).ToString().ToLower() + Latest = [bool]$Latest Draft = [bool]$Draft Prerelease = [bool]$Prerelease } From 78ca4350d51a1ac768575c6fac3eafc3a3c7fda1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 22:29:05 +0200 Subject: [PATCH 052/224] Refactor Set-GitHubRelease to conditionally assign Latest, Draft, and Prerelease parameters based on the parameter set. --- examples/Releases/Releases.ps1 | 2 +- src/functions/public/Releases/Set-GitHubRelease.ps1 | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 926cc8c0a..1b371d30d 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -21,7 +21,7 @@ $repo | New-GitHubRelease -Tag 'v1.1' -Latest -GenerateReleaseNotes -Notes 'Rele $repo | New-GitHubRelease -Tag 'v1.2' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' $repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' $repo | Get-GitHubRelease -All | Where-Object Tag -EQ 'v1.4' | Select-Object ID -$repo | Set-GitHubRelease -Tag 'v1.4' -Draft -Name 'test' +$repo | Set-GitHubRelease -Tag 'v1.4' -Draft -Name 'test2' $repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft:$false $repo | Set-GitHubRelease -Tag 'v1.4' -Latest diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 5bb849893..99e929aca 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -91,12 +91,19 @@ Name = $Name Notes = $Notes DiscussionCategoryName = $DiscussionCategoryName - Latest = [bool]$Latest - Draft = [bool]$Draft - Prerelease = [bool]$Prerelease } $params | Remove-HashtableEntry -NullOrEmptyValues + switch ($PSCmdlet.ParameterSetName) { + 'Set latest' { + $params['Latest'] = [bool]$Latest + } + 'Not latest' { + $params['Draft'] = [bool]$Draft + $params['Prerelease'] = [bool]$Prerelease + } + } + $release = Get-GitHubRelease @scope -Tag $Tag if ($release) { $null = Update-GitHubRelease @scope @params -ID $release.ID From 8b3076e7b230713ffd7e9fe82b78e10039e42d2f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 22:35:22 +0200 Subject: [PATCH 053/224] Enhance Set-GitHubRelease to include output formatting for release details and remove redundant null checks in parameters. --- examples/Releases/Releases.ps1 | 2 ++ src/functions/public/Releases/Set-GitHubRelease.ps1 | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 1b371d30d..29cad2221 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -25,6 +25,8 @@ $repo | Set-GitHubRelease -Tag 'v1.4' -Draft -Name 'test2' $repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft:$false $repo | Set-GitHubRelease -Tag 'v1.4' -Latest +$repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * | Format-Table + $repo | Set-GitHubRelease -Tag 'v1.4' -Notes @' ## This is a test release. diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 99e929aca..5134dbba4 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -92,7 +92,6 @@ Notes = $Notes DiscussionCategoryName = $DiscussionCategoryName } - $params | Remove-HashtableEntry -NullOrEmptyValues switch ($PSCmdlet.ParameterSetName) { 'Set latest' { @@ -103,7 +102,7 @@ $params['Prerelease'] = [bool]$Prerelease } } - + $release = Get-GitHubRelease @scope -Tag $Tag if ($release) { $null = Update-GitHubRelease @scope @params -ID $release.ID From acf209012dc031f1a0427fd95444c9ead3976c7c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 12 Apr 2025 23:04:14 +0200 Subject: [PATCH 054/224] Refactor Set-GitHubRelease to streamline release updates by consolidating parameter handling and improving boolean assignments for Latest, Draft, and Prerelease flags. --- examples/Releases/Releases.ps1 | 2 +- .../public/Releases/Set-GitHubRelease.ps1 | 60 +++++++++++++------ 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 29cad2221..a4a20fa9e 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -25,7 +25,7 @@ $repo | Set-GitHubRelease -Tag 'v1.4' -Draft -Name 'test2' $repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft:$false $repo | Set-GitHubRelease -Tag 'v1.4' -Latest -$repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * | Format-Table +$repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * $repo | Set-GitHubRelease -Tag 'v1.4' -Notes @' ## This is a test release. diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 5134dbba4..526f4606a 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -85,28 +85,54 @@ Context = $Context } - $params = @{ - Tag = $Tag - Target = $Target - Name = $Name - Notes = $Notes - DiscussionCategoryName = $DiscussionCategoryName - } + $release = Get-GitHubRelease @scope -Tag $Tag + if ($release) { + $ID = $release.ID + $body = @{ + tag_name = $Tag + target_commitish = $Target + name = $Name + body = $Notes + discussion_category_name = $DiscussionCategoryName + make_latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest.ToString().ToLower() : $null + draft = $PSBoundParameters.ContainsKey('Draft') ? [bool]$Draft : $null + prerelease = $PSBoundParameters.ContainsKey('Prerelease') ? [bool]$Prerelease : $null + } - switch ($PSCmdlet.ParameterSetName) { - 'Set latest' { - $params['Latest'] = [bool]$Latest + if ($PSBoundParameters.ContainsKey('Latest') -and [bool]$Latest) { + $body['Draft'] = $false + $body['Prerelease'] = $false } - 'Not latest' { - $params['Draft'] = [bool]$Draft - $params['Prerelease'] = [bool]$Prerelease + + $inputObject = @{ + Method = 'PATCH' + APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" + Body = $body + Context = $Context } - } - $release = Get-GitHubRelease @scope -Tag $Tag - if ($release) { - $null = Update-GitHubRelease @scope @params -ID $release.ID + if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { + $null = Invoke-GitHubAPI @inputObject + } } else { + $params = @{ + Tag = $Tag + Target = $Target + Name = $Name + Notes = $Notes + DiscussionCategoryName = $DiscussionCategoryName + } + + switch ($PSCmdlet.ParameterSetName) { + 'Set latest' { + $params['Latest'] = [bool]$Latest + } + 'Not latest' { + $params['Draft'] = [bool]$Draft + $params['Prerelease'] = [bool]$Prerelease + } + } + $null = New-GitHubRelease @scope @params } From 256b99a515c1381661525fcf3ed486e2e430b30e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 10:14:08 +0200 Subject: [PATCH 055/224] Refactor New-GitHubRepositoryAsFork to rename Owner parameter to Organization and update related references for clarity. --- .../private/Repositories/New-GitHubRepositoryAsFork.ps1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 index 666e1f684..2662814bb 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 @@ -53,7 +53,7 @@ # The organization or person who will own the new repository. # To create a new repository in an organization, the authenticated user must be a member of the specified organization. [Parameter()] - [string] $Owner, + [string] $Organization, # The name of the new repository. [Parameter()] @@ -77,10 +77,11 @@ process { $body = @{ - organization = $Owner + organization = $Organization name = $Name default_branch_only = $DefaultBranchOnly } + $body | Remove-HashtableEntry -NullOrEmptyValues $inputObject = @{ Method = 'POST' @@ -89,7 +90,7 @@ Context = $Context } - if ($PSCmdlet.ShouldProcess("Repository [$Owner/$Name] as fork of [$ForkOwner/$ForkRepository]", 'Create')) { + if ($PSCmdlet.ShouldProcess("Repository [$Organization/$Name] as fork of [$ForkOwner/$ForkRepository]", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { [GitHubRepository]::New($_.Response) } From 14c27e6cc78b471c750e9d89f83b2682fc68276f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 10:35:08 +0200 Subject: [PATCH 056/224] Refactor user retrieval functions to handle different response types (User, Organization, Owner) and update output types accordingly. --- .../private/Users/Get-GitHubAllUser.ps1 | 12 +++++++++++- .../private/Users/Get-GitHubMyUser.ps1 | 12 +++++++++++- .../private/Users/Get-GitHubUserByName.ps1 | 12 +++++++++++- src/functions/public/Users/Get-GitHubUser.ps1 | 19 ++++++++++--------- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/functions/private/Users/Get-GitHubAllUser.ps1 b/src/functions/private/Users/Get-GitHubAllUser.ps1 index 8513acc6f..72f7ac0cb 100644 --- a/src/functions/private/Users/Get-GitHubAllUser.ps1 +++ b/src/functions/private/Users/Get-GitHubAllUser.ps1 @@ -59,7 +59,17 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - $_.Response | ForEach-Object { [GitHubUser]::New($_) } + switch ($_.Response.Type) { + 'Organization' { + [GitHubOrganization]::New($_.Response) + } + 'User' { + [GitHubUser]::New($_.Response) + } + default { + [GitHubOwner]::New($_.Response) + } + } } } diff --git a/src/functions/private/Users/Get-GitHubMyUser.ps1 b/src/functions/private/Users/Get-GitHubMyUser.ps1 index 06b7ce763..3113b4a3a 100644 --- a/src/functions/private/Users/Get-GitHubMyUser.ps1 +++ b/src/functions/private/Users/Get-GitHubMyUser.ps1 @@ -43,7 +43,17 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubUser]::New($_.Response) + switch ($_.Response.Type) { + 'Organization' { + [GitHubOrganization]::New($_.Response) + } + 'User' { + [GitHubUser]::New($_.Response) + } + default { + [GitHubOwner]::New($_.Response) + } + } } } diff --git a/src/functions/private/Users/Get-GitHubUserByName.ps1 b/src/functions/private/Users/Get-GitHubUserByName.ps1 index f79fe3cf7..87f1e44b1 100644 --- a/src/functions/private/Users/Get-GitHubUserByName.ps1 +++ b/src/functions/private/Users/Get-GitHubUserByName.ps1 @@ -60,7 +60,17 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubUser]::New($_.Response) + switch ($_.Response.Type) { + 'Organization' { + [GitHubOrganization]::New($_.Response) + } + 'User' { + [GitHubUser]::New($_.Response) + } + default { + [GitHubOwner]::New($_.Response) + } + } } } diff --git a/src/functions/public/Users/Get-GitHubUser.ps1 b/src/functions/public/Users/Get-GitHubUser.ps1 index 0df25843c..498919a71 100644 --- a/src/functions/public/Users/Get-GitHubUser.ps1 +++ b/src/functions/public/Users/Get-GitHubUser.ps1 @@ -24,22 +24,23 @@ Get a list of users, starting with the user 'MariusStorhaug'. .OUTPUTS - GitHubUser + GitHubOwner .NOTES [Get the authenticated user](https://docs.github.com/rest/users/users) #> - [OutputType([GitHubUser])] + [OutputType([GitHubOwner])] + [Alias('Get-GitHubOwner')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSReviewUnusedParameter', 'All', Justification = 'Parameter is used in dynamic parameter validation.' )] - [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] + [CmdletBinding(DefaultParameterSetName = 'Authenticated user')] param( # The handle for the GitHub user account. [Parameter( Mandatory, - ParameterSetName = 'ByName', + ParameterSetName = 'By name', ValueFromPipelineByPropertyName )] [string] $Name, @@ -47,16 +48,16 @@ # List all users. Use '-Since' to start at a specific user ID. [Parameter( Mandatory, - ParameterSetName = 'AllUsers' + ParameterSetName = 'All users' )] [switch] $All, # A user ID. Only return users with an ID greater than this ID. - [Parameter(ParameterSetName = 'AllUsers')] + [Parameter(ParameterSetName = 'All users')] [int] $Since = 0, # The number of results per page (max 100). - [Parameter(ParameterSetName = 'AllUsers')] + [Parameter(ParameterSetName = 'All users')] [ValidateRange(0, 100)] [int] $PerPage, @@ -75,10 +76,10 @@ process { switch ($PSCmdlet.ParameterSetName) { - 'ByName' { + 'By name' { Get-GitHubUserByName -Name $Name -Context $Context } - 'AllUsers' { + 'All users' { Get-GitHubAllUser -Since $Since -PerPage $PerPage -Context $Context } default { From 5e0e26cbd45bbce2b29fec56a19518835f542adf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 11:04:55 +0200 Subject: [PATCH 057/224] Refactor user response handling in Get-GitHubAllUser, Get-GitHubMyUser, and Get-GitHubUserByName to simplify type checks and improve readability. --- .../private/Users/Get-GitHubAllUser.ps1 | 16 +++++++--------- src/functions/private/Users/Get-GitHubMyUser.ps1 | 16 ++++++---------- .../private/Users/Get-GitHubUserByName.ps1 | 16 ++++++---------- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/functions/private/Users/Get-GitHubAllUser.ps1 b/src/functions/private/Users/Get-GitHubAllUser.ps1 index 72f7ac0cb..990ffb028 100644 --- a/src/functions/private/Users/Get-GitHubAllUser.ps1 +++ b/src/functions/private/Users/Get-GitHubAllUser.ps1 @@ -59,15 +59,13 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - switch ($_.Response.Type) { - 'Organization' { - [GitHubOrganization]::New($_.Response) - } - 'User' { - [GitHubUser]::New($_.Response) - } - default { - [GitHubOwner]::New($_.Response) + $_.Response | ForEach-Object { + if ($_.type -eq 'Organization') { + [GitHubOrganization]::New($_) + } elseif ($_.type -eq 'User') { + [GitHubUser]::New($_) + } else { + [GitHubOwner]::New($_) } } } diff --git a/src/functions/private/Users/Get-GitHubMyUser.ps1 b/src/functions/private/Users/Get-GitHubMyUser.ps1 index 3113b4a3a..9f59fa69b 100644 --- a/src/functions/private/Users/Get-GitHubMyUser.ps1 +++ b/src/functions/private/Users/Get-GitHubMyUser.ps1 @@ -43,16 +43,12 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - switch ($_.Response.Type) { - 'Organization' { - [GitHubOrganization]::New($_.Response) - } - 'User' { - [GitHubUser]::New($_.Response) - } - default { - [GitHubOwner]::New($_.Response) - } + if ($_.Response.type -eq 'Organization') { + [GitHubOrganization]::New($_.Response) + } elseif ($_.Response.type -eq 'User') { + [GitHubUser]::New($_.Response) + } else { + [GitHubOwner]::New($_.Response) } } } diff --git a/src/functions/private/Users/Get-GitHubUserByName.ps1 b/src/functions/private/Users/Get-GitHubUserByName.ps1 index 87f1e44b1..5f4de59d9 100644 --- a/src/functions/private/Users/Get-GitHubUserByName.ps1 +++ b/src/functions/private/Users/Get-GitHubUserByName.ps1 @@ -60,16 +60,12 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - switch ($_.Response.Type) { - 'Organization' { - [GitHubOrganization]::New($_.Response) - } - 'User' { - [GitHubUser]::New($_.Response) - } - default { - [GitHubOwner]::New($_.Response) - } + if ($_.Response.type -eq 'Organization') { + [GitHubOrganization]::New($_.Response) + } elseif ($_.Response.type -eq 'User') { + [GitHubUser]::New($_.Response) + } else { + [GitHubOwner]::New($_.Response) } } } From bf709a0a5f10508a1b7c79215c9933a0ff202273 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 11:30:05 +0200 Subject: [PATCH 058/224] Enhance Set-GitHubRelease to retrieve repository details and conditionally include discussion category in release updates. --- .../public/Releases/Set-GitHubRelease.ps1 | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 526f4606a..773685c09 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -84,19 +84,22 @@ Repository = $Repository Context = $Context } - + $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context $release = Get-GitHubRelease @scope -Tag $Tag if ($release) { $ID = $release.ID $body = @{ - tag_name = $Tag - target_commitish = $Target - name = $Name - body = $Notes - discussion_category_name = $DiscussionCategoryName - make_latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest.ToString().ToLower() : $null - draft = $PSBoundParameters.ContainsKey('Draft') ? [bool]$Draft : $null - prerelease = $PSBoundParameters.ContainsKey('Prerelease') ? [bool]$Prerelease : $null + tag_name = $Tag + target_commitish = $Target + name = $Name + body = $Notes + make_latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest.ToString().ToLower() : $null + draft = $PSBoundParameters.ContainsKey('Draft') ? [bool]$Draft : $null + prerelease = $PSBoundParameters.ContainsKey('Prerelease') ? [bool]$Prerelease : $null + } + + if ($repo.HasDiscussions) { + $body['discussion_category_name'] = $DiscussionCategoryName } if ($PSBoundParameters.ContainsKey('Latest') -and [bool]$Latest) { From b9cc3dd0d81c1a5644005f9e83a50380e9dc9f1e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 12:13:37 +0200 Subject: [PATCH 059/224] Refactor Set-GitHubRelease and Update-GitHubRelease to streamline parameter handling and improve clarity in release creation and updates. --- .../public/Releases/New-GitHubRelease.ps1 | 2 +- .../public/Releases/Set-GitHubRelease.ps1 | 69 ++++++------------- .../public/Releases/Update-GitHubRelease.ps1 | 30 ++++++-- 3 files changed, 44 insertions(+), 57 deletions(-) diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 index 03bbb1304..0c7904c65 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -103,8 +103,8 @@ name = $Name body = $Notes discussion_category_name = $DiscussionCategoryName - make_latest = ([bool]$Latest).ToString().ToLower() generate_release_notes = [bool]$GenerateReleaseNotes + make_latest = ([bool]$Latest).ToString().ToLower() draft = [bool]$Draft prerelease = [bool]$Prerelease } diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 773685c09..cde14ed32 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -84,62 +84,33 @@ Repository = $Repository Context = $Context } - $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context - $release = Get-GitHubRelease @scope -Tag $Tag - if ($release) { - $ID = $release.ID - $body = @{ - tag_name = $Tag - target_commitish = $Target - name = $Name - body = $Notes - make_latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest.ToString().ToLower() : $null - draft = $PSBoundParameters.ContainsKey('Draft') ? [bool]$Draft : $null - prerelease = $PSBoundParameters.ContainsKey('Prerelease') ? [bool]$Prerelease : $null - } - if ($repo.HasDiscussions) { - $body['discussion_category_name'] = $DiscussionCategoryName - } + $params = @{ + Tag = $Tag + Target = $Target + Name = $Name + Notes = $Notes + DiscussionCategoryName = $DiscussionCategoryName + } - if ($PSBoundParameters.ContainsKey('Latest') -and [bool]$Latest) { - $body['Draft'] = $false - $body['Prerelease'] = $false + switch ($PSCmdlet.ParameterSetName) { + 'Set latest' { + $params['Latest'] = [bool]$Latest } - - $inputObject = @{ - Method = 'PATCH' - APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" - Body = $body - Context = $Context + 'Not latest' { + $params['Draft'] = [bool]$Draft + $params['Prerelease'] = [bool]$Prerelease } + } - if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { - $null = Invoke-GitHubAPI @inputObject - } + $release = Get-GitHubRelease @scope -Tag $Tag + if ($release) { + $ID = $release.ID + $params['ID'] = $ID + Update-GitHubRelease @scope @params } else { - $params = @{ - Tag = $Tag - Target = $Target - Name = $Name - Notes = $Notes - DiscussionCategoryName = $DiscussionCategoryName - } - - switch ($PSCmdlet.ParameterSetName) { - 'Set latest' { - $params['Latest'] = [bool]$Latest - } - 'Not latest' { - $params['Draft'] = [bool]$Draft - $params['Prerelease'] = [bool]$Prerelease - } - } - - $null = New-GitHubRelease @scope @params + New-GitHubRelease @scope @params } - - Get-GitHubRelease @scope -Tag $Tag } end { diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index f16017211..0fe2cf1f9 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -67,6 +67,11 @@ [Parameter(Mandatory, ParameterSetName = 'Set latest')] [switch] $Latest, + # Takes all parameters and updates the release with the provided _AND_ the default values of the non-provided parameters. + # Used for Set-GitHubRelease. + [Parameter()] + [switch] $Declare, + # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] @@ -81,21 +86,32 @@ } process { + $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context $body = @{ tag_name = $Tag target_commitish = $Target name = $Name body = $Notes discussion_category_name = $DiscussionCategoryName - make_latest = $PSBoundParameters.ContainsKey('Latest') ? [bool]$Latest.ToString().ToLower() : $null - draft = $PSBoundParameters.ContainsKey('Draft') ? [bool]$Draft : $null - prerelease = $PSBoundParameters.ContainsKey('Prerelease') ? [bool]$Prerelease : $null } - $body | Remove-HashtableEntry -NullOrEmptyValues + if ($repo.HasDiscussions) { + $body['discussion_category_name'] = $DiscussionCategoryName + } + if (-not $Declare) { + $body | Remove-HashtableEntry -NullOrEmptyValues + } - if ($PSBoundParameters.ContainsKey('Latest') -and [bool]$Latest) { - $body['Draft'] = $false - $body['Prerelease'] = $false + switch ($PSCmdlet.ParameterSetName) { + 'Set latest' { + $body['make_latest'] = [bool]$Latest.ToString().ToLower() + $body['prerelease'] = $null + $body['draft'] = $null + } + 'Not latest' { + $body['make_latest'] = $null + $body['prerelease'] = [bool]$Prerelease + $body['draft'] = [bool]$Draft + } } $inputObject = @{ From 2b6fe0f3bef48f6675aec51abfc068ba8529944e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 12:17:28 +0200 Subject: [PATCH 060/224] Refactor Get-GitHubRepository to initialize Affiliation parameter with an array of valid values for improved clarity and consistency. --- src/functions/public/Repositories/Get-GitHubRepository.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index d824b0253..05faded5e 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -66,7 +66,7 @@ filter Get-GitHubRepository { # Default: owner, collaborator, organization_member [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] [ValidateSet('owner', 'collaborator', 'organization_member')] - [string[]] $Affiliation = 'owner', + [string[]] $Affiliation = @('owner', 'collaborator', 'organization_member'), # A repository ID. Only return repositories with an ID greater than this ID. [Parameter(ParameterSetName = 'ListByID')] From 2f43d879f3ec6c3e20c7a9d8cdb4c938c3009e86 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 12:19:50 +0200 Subject: [PATCH 061/224] Refactor Update-GitHubRelease to set default values for draft and prerelease parameters to false for improved clarity in release updates. --- src/functions/public/Releases/Update-GitHubRelease.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 0fe2cf1f9..532944eb2 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -104,11 +104,11 @@ switch ($PSCmdlet.ParameterSetName) { 'Set latest' { $body['make_latest'] = [bool]$Latest.ToString().ToLower() - $body['prerelease'] = $null - $body['draft'] = $null + $body['prerelease'] = $false + $body['draft'] = $false } 'Not latest' { - $body['make_latest'] = $null + $body['make_latest'] = $false $body['prerelease'] = [bool]$Prerelease $body['draft'] = [bool]$Draft } From 6fc3820f0a42d64667fa919754d71d904b1c66ae Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 13:25:54 +0200 Subject: [PATCH 062/224] Refactor Set-GitHubRelease and Update-GitHubRelease to include -ErrorAction Stop for improved error handling and streamline response processing in Update-GitHubRelease. --- src/functions/public/Releases/Set-GitHubRelease.ps1 | 4 ++-- src/functions/public/Releases/Update-GitHubRelease.ps1 | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index cde14ed32..4dd85a57f 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -107,9 +107,9 @@ if ($release) { $ID = $release.ID $params['ID'] = $ID - Update-GitHubRelease @scope @params + Update-GitHubRelease @scope @params -ErrorAction Stop } else { - New-GitHubRelease @scope @params + New-GitHubRelease @scope @params -ErrorAction Stop } } diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 532944eb2..5754e9319 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -122,9 +122,10 @@ } if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { - $null = Invoke-GitHubAPI @inputObject + Invoke-GitHubAPI @inputObject | ForEach-Object { + [GitHubRelease]::new($_.Response , $Owner, $Repository, $Latest) + } } - Get-GitHubReleaseByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context } end { From c92f1b28c9ae0497223b7e67e1ecf4018064b0a7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 13:34:50 +0200 Subject: [PATCH 063/224] Refactor Get-GitHubRelease to update parameter set names for clarity, changing DefaultParameterSetName to 'All' and renaming the 'All' switch to 'Latest'. --- src/functions/public/Releases/Get-GitHubRelease.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index 0ec5f9a3d..76d6e81a0 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -38,11 +38,11 @@ https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSReviewUnusedParameter', 'All', + 'PSReviewUnusedParameter', 'Latest', Justification = 'Using the ParameterSetName to determine the context of the command.' )] [OutputType([GitHubRelease])] - [CmdletBinding(DefaultParameterSetName = 'Latest')] + [CmdletBinding(DefaultParameterSetName = 'All')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] @@ -57,9 +57,9 @@ [ValidateRange(0, 100)] [int] $PerPage, - # Get all releases. - [Parameter(Mandatory, ParameterSetName = 'All')] - [switch] $All, + # Get the latest release. + [Parameter(Mandatory, ParameterSetName = 'Latest')] + [switch] $Latest, # The name of the tag to get a release from. [Parameter(Mandatory, ParameterSetName = 'Tag')] From 0841fa45107f1b41068d2ceaede8478fdd3f82c8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 13:57:35 +0200 Subject: [PATCH 064/224] Refactor Get-GitHubOrganization to add an alias for the Username parameter for improved usability and clarity. Remove redundant Username script property from GitHubUser type to streamline the type definition. --- src/functions/public/Organization/Get-GitHubOrganization.ps1 | 1 + src/types/GitHubUser.Types.ps1xml | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/functions/public/Organization/Get-GitHubOrganization.ps1 b/src/functions/public/Organization/Get-GitHubOrganization.ps1 index 20b3e1228..fc7dbe104 100644 --- a/src/functions/public/Organization/Get-GitHubOrganization.ps1 +++ b/src/functions/public/Organization/Get-GitHubOrganization.ps1 @@ -53,6 +53,7 @@ ParameterSetName = 'NamedUser', ValueFromPipelineByPropertyName )] + [Alias('User')] [string] $Username, # List all organizations. Use '-Since' to start at a specific organization ID. diff --git a/src/types/GitHubUser.Types.ps1xml b/src/types/GitHubUser.Types.ps1xml index c2085168c..f81e6433f 100644 --- a/src/types/GitHubUser.Types.ps1xml +++ b/src/types/GitHubUser.Types.ps1xml @@ -7,10 +7,6 @@ User $this.Name - - Username - $this.Name - From 8af94378f9092132ec819b566267d0ec316073ce Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 14:06:17 +0200 Subject: [PATCH 065/224] Refactor Get-GitHubRelease examples for clarity and update Get-GitHubOrganization and Get-GitHubUser to allow ValueFromPipeline for Name parameter. --- examples/Releases/Releases.ps1 | 32 +++++++++---------- .../Organization/Get-GitHubOrganization.ps1 | 1 + .../Remove-GitHubOrganization.ps1 | 2 +- src/functions/public/Users/Get-GitHubUser.ps1 | 1 + 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index a4a20fa9e..4ecd8d932 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -1,28 +1,28 @@ -# Get the latest release for a specific repository +# Get all the releases for a specific repository Get-GitHubRelease -Owner PSModule -Repository GitHub -# Get all the releases for a specific repository -Get-GitHubRelease -Owner PSModule -Repository GitHub -All - -# Get the latest releases for all repos in the organization -Get-GitHubOrganization -Name PSModule | Get-GitHubRepository | Get-GitHubRelease +# Get the latest release for a specific repository +Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest # Get all the releases for all repos in the organization -Get-GitHubOrganization -Name PSModule | Get-GitHubRepository | Get-GitHubRelease -All +'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease + +# Get the latest releases for all repos in the organization +Get-GitHubOrganization -Name PSModule | Get-GitHubRepository | Get-GitHubRelease -Latest # Create a new release for a specific repository $repoName = 'mytest' New-GitHubRepository -Name $repoName -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio $repo = Get-GitHubUser | Get-GitHubRepository -Name $repoName -$repo | Get-GitHubRelease -All -$repo | New-GitHubRelease -Tag 'v1.0' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | New-GitHubRelease -Tag 'v1.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | New-GitHubRelease -Tag 'v1.2' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | New-GitHubRelease -Tag 'v1.3' -Latest -GenerateReleaseNotes -Notes 'Release notes' -Name 'test' -$repo | Get-GitHubRelease -All | Where-Object Tag -EQ 'v1.4' | Select-Object ID -$repo | Set-GitHubRelease -Tag 'v1.4' -Draft -Name 'test2' -$repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft:$false +$repo | Get-GitHubRelease +$repo | New-GitHubRelease -Tag 'v1.0' -Latest +$repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' +$repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' +$repo | Set-GitHubRelease -Tag 'v1.5' -Latest -Name 'test' -Notes 'Release notes' -DiscussionCategoryName 123 | Select-Object * +$repo | Get-GitHubRelease -Tag 'v1.4' +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft | Select-Object * +$repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease | Select-Object * $repo | Set-GitHubRelease -Tag 'v1.4' -Latest $repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * @@ -52,4 +52,4 @@ $repo | Set-GitHubRelease -Tag 'v1.4' -Latest $repo | Get-GitHubRelease -All | Remove-GitHubRelease -Get-GitHubRepository -Username MariusStorhaug -Name $repoName | Remove-GitHubRepository -Confirm:$false +$repo | Remove-GitHubRepository -Confirm:$false diff --git a/src/functions/public/Organization/Get-GitHubOrganization.ps1 b/src/functions/public/Organization/Get-GitHubOrganization.ps1 index fc7dbe104..84afe544a 100644 --- a/src/functions/public/Organization/Get-GitHubOrganization.ps1 +++ b/src/functions/public/Organization/Get-GitHubOrganization.ps1 @@ -43,6 +43,7 @@ [Parameter( Mandatory, ParameterSetName = 'NamedOrg', + ValueFromPipeline, ValueFromPipelineByPropertyName )] [string] $Name, diff --git a/src/functions/public/Organization/Remove-GitHubOrganization.ps1 b/src/functions/public/Organization/Remove-GitHubOrganization.ps1 index a5f1ff009..3f659528d 100644 --- a/src/functions/public/Organization/Remove-GitHubOrganization.ps1 +++ b/src/functions/public/Organization/Remove-GitHubOrganization.ps1 @@ -24,7 +24,7 @@ [Delete an organization](https://docs.github.com/rest/orgs/orgs#delete-an-organization) #> [OutputType([void])] - [CmdletBinding(SupportsShouldProcess)] + [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param( # The organization name. The name is not case sensitive. [Parameter( diff --git a/src/functions/public/Users/Get-GitHubUser.ps1 b/src/functions/public/Users/Get-GitHubUser.ps1 index 498919a71..866e88ee0 100644 --- a/src/functions/public/Users/Get-GitHubUser.ps1 +++ b/src/functions/public/Users/Get-GitHubUser.ps1 @@ -41,6 +41,7 @@ [Parameter( Mandatory, ParameterSetName = 'By name', + ValueFromPipeline, ValueFromPipelineByPropertyName )] [string] $Name, From acf5db43bd352fc638efcef21510655d01382b51 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 14:13:20 +0200 Subject: [PATCH 066/224] Refactor Get-GitHubRepository to add an alias for the Username parameter for improved usability and clarity. --- src/functions/public/Repositories/Get-GitHubRepository.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 05faded5e..0a5cd61d7 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -90,6 +90,7 @@ filter Get-GitHubRepository { # The handle for the GitHub user account. [Parameter(ParameterSetName = 'ByName', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'ListByUser', ValueFromPipelineByPropertyName)] + [Alias('User')] [string] $Username, # The name of the repository without the .git extension. The name is not case sensitive. From a8a1ba28bcb895afa710879e494c2897e6ad04be Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 14:36:14 +0200 Subject: [PATCH 067/224] Refactor Set-GitHubRelease parameters to provide default values for Name and Notes for improved usability. --- examples/Releases/Releases.ps1 | 13 ++++++++----- src/functions/public/Releases/Set-GitHubRelease.ps1 | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 4ecd8d932..3c1bd2209 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -19,11 +19,14 @@ $repo | Get-GitHubRelease $repo | New-GitHubRelease -Tag 'v1.0' -Latest $repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' -$repo | Set-GitHubRelease -Tag 'v1.5' -Latest -Name 'test' -Notes 'Release notes' -DiscussionCategoryName 123 | Select-Object * -$repo | Get-GitHubRelease -Tag 'v1.4' -$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft | Select-Object * -$repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease | Select-Object * -$repo | Set-GitHubRelease -Tag 'v1.4' -Latest +$repo | Set-GitHubRelease -Tag 'v1.5' -Latest -Name 'test' -Notes 'Release notes' | Select-Object * +$repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft -Prerelease | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Prerelease | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Latest | Select-Object Tag, Name, Latest, Prerelease, Draft $repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 4dd85a57f..a36f5b7f2 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -41,11 +41,11 @@ # The name of the release. [Parameter()] - [string] $Name, + [string] $Name = '', # Text describing the contents of the tag. [Parameter()] - [string] $Notes, + [string] $Notes = '', # Whether the release is a draft. [Parameter(ParameterSetName = 'Not latest')] From e82e933620f42bb4051ed25deb33411af9795a68 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 15:13:40 +0200 Subject: [PATCH 068/224] Refactor Get-GitHubRelease examples for improved clarity and performance by using parallel processing and ensuring module import. --- examples/Releases/Releases.ps1 | 9 ++++++++- src/functions/public/Releases/Set-GitHubRelease.ps1 | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 3c1bd2209..fe0d42ef6 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -8,7 +8,14 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest 'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease # Get the latest releases for all repos in the organization -Get-GitHubOrganization -Name PSModule | Get-GitHubRepository | Get-GitHubRelease -Latest +'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | ForEach-Object -ThrottleLimit ([Environment]::ProcessorCount) -Parallel { + do { + Import-Module -Name GitHub + } until ($? -eq $true) + $_ | Get-GitHubRelease -Latest +} -UseNewRunspace + +'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease -Latest # Create a new release for a specific repository $repoName = 'mytest' diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index a36f5b7f2..0fcf88de1 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -107,9 +107,9 @@ if ($release) { $ID = $release.ID $params['ID'] = $ID - Update-GitHubRelease @scope @params -ErrorAction Stop + Update-GitHubRelease @scope @params -Declare } else { - New-GitHubRelease @scope @params -ErrorAction Stop + New-GitHubRelease @scope @params } } From 1e168f4976ffd2be70e7d832ce90d74cab5ee919 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 15:23:47 +0200 Subject: [PATCH 069/224] Refactor SaveArtifacts and Releases examples for improved clarity and consistency in code formatting. --- examples/Artifacts/SaveArtifacts.ps1 | 3 ++- examples/Releases/Releases.ps1 | 2 +- src/functions/public/Releases/Update-GitHubRelease.ps1 | 9 ++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 302fb3f37..27c638df8 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -1,3 +1,4 @@ -$modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 +# This script demonstrates how to save artifacts from a GitHub repository using Save-GitHubArtifact. +$modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | Save-GitHubArtifact -Path $modulesPath -Extract -Force diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index fe0d42ef6..0838c748c 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -59,7 +59,7 @@ This is a test release. $repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft $repo | Set-GitHubRelease -Tag 'v1.4' -Latest -$repo | Get-GitHubRelease -All | Remove-GitHubRelease +$repo | Get-GitHubRelease | Remove-GitHubRelease $repo | Remove-GitHubRepository -Confirm:$false diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 5754e9319..bdfd95bb6 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -88,11 +88,10 @@ process { $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context $body = @{ - tag_name = $Tag - target_commitish = $Target - name = $Name - body = $Notes - discussion_category_name = $DiscussionCategoryName + tag_name = $Tag + target_commitish = $Target + name = $Name + body = $Notes } if ($repo.HasDiscussions) { $body['discussion_category_name'] = $DiscussionCategoryName From f0d015982ea689ac604e6caad62bca2e2a0858ec Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 15:41:27 +0200 Subject: [PATCH 070/224] Refactor release management examples for improved clarity and consistency in parameter usage and notes formatting. --- examples/Releases/Releases.ps1 | 23 ++------------ .../public/Releases/New-GitHubReleaseNote.ps1 | 30 +++++++++---------- tools/utilities/GitHubAPI.ps1 | 4 +-- 3 files changed, 20 insertions(+), 37 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 0838c748c..09bfee560 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -29,35 +29,18 @@ $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes $repo | Set-GitHubRelease -Tag 'v1.5' -Latest -Name 'test' -Notes 'Release notes' | Select-Object * $repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft $repo | Set-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft -$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' | Select-Object Tag, Name, Latest, Prerelease, Draft $repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft | Select-Object Tag, Name, Latest, Prerelease, Draft $repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft -Prerelease | Select-Object Tag, Name, Latest, Prerelease, Draft $repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Prerelease | Select-Object Tag, Name, Latest, Prerelease, Draft $repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Latest | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' | Select-Object Tag, Name, Latest, Prerelease, Draft $repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * -$repo | Set-GitHubRelease -Tag 'v1.4' -Notes @' -## This is a test release. - -This is a test release. -This is a test release. - -## This is a test release. - -This is a test release. -This is a test release. -This is a test release. +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Notes 'Release notes' -| Header 1 | Header 2 | -|---------|---------| -| Row 1 | Row 2 | -| Row 3 | Row 4 | -| Row 5 | Row 6 | -'@ -$repo | Set-GitHubRelease -Tag 'v1.4' -Prerelease -Draft -$repo | Set-GitHubRelease -Tag 'v1.4' -Latest +New-GitHubReleaseNote -Owner PSModule -Repository GitHub -Tag 'v0.22.0' -Target 'main' -PreviousTag 'v0.20.0' $repo | Get-GitHubRelease | Remove-GitHubRelease diff --git a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 index 1f2c1724b..ce05b0479 100644 --- a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 @@ -1,19 +1,18 @@ filter New-GitHubReleaseNote { <# .SYNOPSIS - List releases + Generate release notes content for a release. .DESCRIPTION - Generate a name and body describing a [release](https://docs.github.com/rest/releases/releases#get-a-release). - The body content will be Markdown formatted and contain information like - the changes since last release and users who contributed. The generated release notes are not saved anywhere. They are - intended to be generated and used when creating a new release. + Generate a name and body describing a [release](https://docs.github.com/rest/releases/releases#get-a-release). The body content will be + markdown formatted and contain information like the changes since last release and users who contributed. The generated release notes are not + saved anywhere. They are intended to be generated and used when creating a new release. .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - TagName = 'v1.0.0' + Owner = 'octocat' + Repo = 'hello-world' + Tag = 'v1.0.0' } New-GitHubReleaseNote @params @@ -23,10 +22,10 @@ .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - TagName = 'v1.0.0' - TargetCommitish = 'main' + Owner = 'octocat' + Repo = 'hello-world' + Tag = 'v1.0.0' + Target = 'main' } New-GitHubReleaseNote @params @@ -37,9 +36,9 @@ $params = @{ Owner = 'octocat' Repo = 'hello-world' - TagName = 'v1.0.0' - TargetCommitish = 'main' - PreviousTagName = 'v0.9.2' + Tag = 'v1.0.0' + Target = 'main' + PreviousTag = 'v0.9.2' ConfigurationFilePath = '.github/custom_release_config.yml' } New-GitHubReleaseNote @params @@ -117,6 +116,7 @@ Method = 'POST' APIEndpoint = "/repos/$Owner/$Repository/releases/generate-notes" Body = $body + Context = $Context } if ($PSCmdlet.ShouldProcess("release notes for release on $Owner/$Repository", 'Create')) { diff --git a/tools/utilities/GitHubAPI.ps1 b/tools/utilities/GitHubAPI.ps1 index d6c41d97c..6032a9a1b 100644 --- a/tools/utilities/GitHubAPI.ps1 +++ b/tools/utilities/GitHubAPI.ps1 @@ -22,8 +22,8 @@ $response = Invoke-RestMethod -Uri $APIDocURI -Method Get # @{n = 'PUT'; e = { (($_.value.psobject.Properties.Name) -contains 'PUT') } }, ` # @{n = 'PATCH'; e = { (($_.value.psobject.Properties.Name) -contains 'PATCH') } } | Format-Table -$path = '/repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}' -$method = 'delete' +$path = '/repos/{owner}/{repo}/releases/generate-notes' +$method = 'post' $response.paths.$path.$method $response.paths.$path.$method.tags | clip # -> Namespace/foldername $response.paths.$path.$method.operationId | clip # -> FunctionName From 29066b12921c3199a2b28f5559349293654b969f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 16:01:36 +0200 Subject: [PATCH 071/224] Refactor release note handling in New-GitHubReleaseNote and Update-GitHubRelease for improved clarity and usability by replacing GitHubReleaseNote class with PSCustomObject and adding GenerateReleaseNotes parameter. --- .../public/Releases/GitHubReleaseNote.ps1 | 16 ---------------- .../public/Releases/New-GitHubReleaseNote.ps1 | 14 +++++++++++--- .../public/Releases/Set-GitHubRelease.ps1 | 1 + .../public/Releases/Update-GitHubRelease.ps1 | 14 ++++++++++---- 4 files changed, 22 insertions(+), 23 deletions(-) delete mode 100644 src/classes/public/Releases/GitHubReleaseNote.ps1 diff --git a/src/classes/public/Releases/GitHubReleaseNote.ps1 b/src/classes/public/Releases/GitHubReleaseNote.ps1 deleted file mode 100644 index 9214c7885..000000000 --- a/src/classes/public/Releases/GitHubReleaseNote.ps1 +++ /dev/null @@ -1,16 +0,0 @@ -class GitHubReleaseNote { - # Description: The file name of the asset - # Example: "Team Environment" - [string] $Name - - # Release notes or changelog, can be null - # Example: "## What's Changed\n### Other Changes\n* Fix: Enhance repository deletion feedback and fix typo..." - [string] $Notes - - GitHubReleaseNote() {} - - GitHubReleaseNote([PSCustomObject] $Object) { - $this.Name = $Object.name - $this.Notes = $Object.body - } -} diff --git a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 index ce05b0479..6779c8d88 100644 --- a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 @@ -48,7 +48,12 @@ configuration file located in the repository at '.github/custom_release_config.yml'. .OUTPUTS - GitHubReleaseNote + pscustomobject + + .NOTES + The returned object contains the following properties: + - Name: The name of the release. + - Notes: The body of the release notes. .LINK https://psmodule.io/GitHub/Functions/Releases/New-GitHubReleaseNote/ @@ -56,7 +61,7 @@ .LINK [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#generate-release-notes-content-for-a-release) #> - [OutputType([GitHubReleaseNote])] + [OutputType([pscustomobject])] [Alias('Generate-GitHubReleaseNotes')] [Alias('New-GitHubReleaseNotes')] [CmdletBinding(SupportsShouldProcess)] @@ -121,7 +126,10 @@ if ($PSCmdlet.ShouldProcess("release notes for release on $Owner/$Repository", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubReleaseNote]::($_.Response) + [PSCustomObject]@{ + Name = $_.Response.name + Notes = $_.Response.body + } } } } diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 0fcf88de1..3e495578a 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -90,6 +90,7 @@ Target = $Target Name = $Name Notes = $Notes + GenerateReleaseNotes = [bool]$GenerateReleaseNotes DiscussionCategoryName = $DiscussionCategoryName } diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index bdfd95bb6..2041a18c1 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -62,6 +62,11 @@ [Parameter()] [string] $DiscussionCategoryName, + # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, + # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. + [Parameter()] + [switch] $GenerateReleaseNotes, + # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. [Parameter(Mandatory, ParameterSetName = 'Set latest')] @@ -88,10 +93,11 @@ process { $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context $body = @{ - tag_name = $Tag - target_commitish = $Target - name = $Name - body = $Notes + tag_name = $Tag + target_commitish = $Target + name = $Name + body = $Notes + generate_release_notes = [bool]$GenerateReleaseNotes } if ($repo.HasDiscussions) { $body['discussion_category_name'] = $DiscussionCategoryName From 6334dcee70076a89049dd2d32d86fd4e12ed2108 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 16:11:45 +0200 Subject: [PATCH 072/224] Refactor New-GitHubRepository parameters for consistency by renaming ForkRepo to ForkRepository and updating related logic. --- examples/Releases/Releases.ps1 | 5 +++-- src/functions/public/Repositories/New-GitHubRepository.ps1 | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 09bfee560..2c24eef36 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -19,13 +19,14 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest # Create a new release for a specific repository $repoName = 'mytest' -New-GitHubRepository -Name $repoName -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio +New-GitHubRepository -ForkOwner 'PSModule' -ForkRepository 'Template-PSModule' -Name $repoName -Private $repo = Get-GitHubUser | Get-GitHubRepository -Name $repoName $repo | Get-GitHubRelease $repo | New-GitHubRelease -Tag 'v1.0' -Latest $repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' +$repo | New-GitHubRelease -Tag 'v1.3' -Latest -Name 'test' -GenerateReleaseNotes $repo | Set-GitHubRelease -Tag 'v1.5' -Latest -Name 'test' -Notes 'Release notes' | Select-Object * $repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft $repo | Set-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft @@ -37,7 +38,7 @@ $repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' | Select-Object Tag, Name, L $repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * -$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Notes 'Release notes' +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' New-GitHubReleaseNote -Owner PSModule -Repository GitHub -Tag 'v0.22.0' -Target 'main' -PreviousTag 'v0.20.0' diff --git a/src/functions/public/Repositories/New-GitHubRepository.ps1 b/src/functions/public/Repositories/New-GitHubRepository.ps1 index 70449505e..0ba34376a 100644 --- a/src/functions/public/Repositories/New-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/New-GitHubRepository.ps1 @@ -133,7 +133,7 @@ filter New-GitHubRepository { # The name of the repository without the .git extension. The name is not case sensitive. [Parameter(Mandatory, ParameterSetName = 'fork')] - [string] $ForkRepo, + [string] $ForkRepository, # When forking from an existing repository, fork with only the default branch. [Parameter(ParameterSetName = 'fork')] @@ -381,9 +381,9 @@ filter New-GitHubRepository { } 'fork' { if ([string]::IsNullorEmpty($Name)) { - $Name = $ForkRepo + $Name = $ForkRepository } - if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] as fork from [$ForkOwner/$ForkRepo]", 'Create')) { + if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] as fork from [$ForkOwner/$ForkRepository]", 'Create')) { $params = @{ Context = $Context ForkOwner = $ForkOwner From 6e05f19b2f9f65103eaf9fe8774b5c2ad45b659f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 16:16:17 +0200 Subject: [PATCH 073/224] Refactor New-GitHubRepository and New-GitHubRepositoryAsFork parameters for consistency by renaming ForkRepo to Repository and ForkOwner to Owner. --- examples/Releases/Releases.ps1 | 2 +- .../private/Repositories/New-GitHubRepositoryAsFork.ps1 | 8 ++++---- .../public/Repositories/New-GitHubRepository.ps1 | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 2c24eef36..0f0d193f7 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -19,7 +19,7 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest # Create a new release for a specific repository $repoName = 'mytest' -New-GitHubRepository -ForkOwner 'PSModule' -ForkRepository 'Template-PSModule' -Name $repoName -Private +New-GitHubRepository -ForkOwner 'PSModule' -ForkRepository 'Template-PSModule' $repo = Get-GitHubUser | Get-GitHubRepository -Name $repoName $repo | Get-GitHubRelease diff --git a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 index 2662814bb..ad190ddfd 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 @@ -44,11 +44,11 @@ param( # The account ForkOwner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [string] $ForkOwner, + [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. [Parameter(Mandatory)] - [string] $ForkRepository, + [string] $Repository, # The organization or person who will own the new repository. # To create a new repository in an organization, the authenticated user must be a member of the specified organization. @@ -85,12 +85,12 @@ $inputObject = @{ Method = 'POST' - APIEndpoint = "/repos/$ForkOwner/$ForkRepository/forks" + APIEndpoint = "/repos/$Owner/$Repository/forks" Body = $body Context = $Context } - if ($PSCmdlet.ShouldProcess("Repository [$Organization/$Name] as fork of [$ForkOwner/$ForkRepository]", 'Create')) { + if ($PSCmdlet.ShouldProcess("Repository [$Organization/$Name] as fork of [$Owner/$Repository]", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { [GitHubRepository]::New($_.Response) } diff --git a/src/functions/public/Repositories/New-GitHubRepository.ps1 b/src/functions/public/Repositories/New-GitHubRepository.ps1 index 0ba34376a..280185069 100644 --- a/src/functions/public/Repositories/New-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/New-GitHubRepository.ps1 @@ -386,8 +386,8 @@ filter New-GitHubRepository { if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] as fork from [$ForkOwner/$ForkRepository]", 'Create')) { $params = @{ Context = $Context - ForkOwner = $ForkOwner - ForkRepo = $ForkRepo + Owner = $ForkOwner + Repository = $ForkRepository Organization = $Owner Name = $Name DefaultBranchOnly = $DefaultBranchOnly From 03c918ad45587d41af9c612f4bd1a11d604ce05c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 16:37:05 +0200 Subject: [PATCH 074/224] Refactor release creation logic in Update-GitHubRelease to conditionally generate release notes and improve parameter handling. --- examples/Releases/Releases.ps1 | 1 - .../public/Releases/Update-GitHubRelease.ps1 | 16 +++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 0f0d193f7..bc87ddb7d 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -19,7 +19,6 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest # Create a new release for a specific repository $repoName = 'mytest' -New-GitHubRepository -ForkOwner 'PSModule' -ForkRepository 'Template-PSModule' $repo = Get-GitHubUser | Get-GitHubRepository -Name $repoName $repo | Get-GitHubRelease diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 2041a18c1..682d3a804 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -92,12 +92,18 @@ process { $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context + + if ($GenerateReleaseNotes) { + $notes = New-GitHubReleaseNote -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + $Name = $PSBoundParameters.ContainsKey('Name') ? $Name : $notes.Name + $Notes = $PSBoundParameters.ContainsKey('Notes') ? $Notes, $notes.Body -join "`n" : $notes.Body + } + $body = @{ - tag_name = $Tag - target_commitish = $Target - name = $Name - body = $Notes - generate_release_notes = [bool]$GenerateReleaseNotes + tag_name = $Tag + target_commitish = $Target + name = $Name + body = $Notes } if ($repo.HasDiscussions) { $body['discussion_category_name'] = $DiscussionCategoryName From 7676721adcc2bc2711ae6f4e6ff356e2c71b7d19 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 16:44:37 +0200 Subject: [PATCH 075/224] Add GenerateReleaseNotes parameter to Set-GitHubRelease for automatic release note generation --- examples/Releases/Releases.ps1 | 9 ++++++++- src/functions/public/Releases/Set-GitHubRelease.ps1 | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index bc87ddb7d..6c56823d5 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -26,6 +26,13 @@ $repo | New-GitHubRelease -Tag 'v1.0' -Latest $repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' $repo | New-GitHubRelease -Tag 'v1.3' -Latest -Name 'test' -GenerateReleaseNotes +$repo | Get-GitHubRelease -Tag 'v1.3' | Format-List + +$repo | New-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes +$repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List +$repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' +$repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List + $repo | Set-GitHubRelease -Tag 'v1.5' -Latest -Name 'test' -Notes 'Release notes' | Select-Object * $repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft $repo | Set-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft @@ -40,7 +47,7 @@ $repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * $repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -New-GitHubReleaseNote -Owner PSModule -Repository GitHub -Tag 'v0.22.0' -Target 'main' -PreviousTag 'v0.20.0' +New-GitHubReleaseNote -Owner PSModule -Repository GitHub -Tag 'v0.22.0' -Target 'main' -PreviousTag 'v0.20.0' | Format-List $repo | Get-GitHubRelease | Remove-GitHubRelease diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 3e495578a..5c86cabeb 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -60,6 +60,11 @@ [Parameter()] [string] $DiscussionCategoryName, + # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, + # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. + [Parameter()] + [switch] $GenerateReleaseNotes, + # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. [Parameter(Mandatory, ParameterSetName = 'Set latest')] From fb02429f59771a0fcd6d07e2724a684bde0e37b0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 16:59:46 +0200 Subject: [PATCH 076/224] fix --- src/functions/public/Releases/Update-GitHubRelease.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 682d3a804..c259732e7 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -94,9 +94,9 @@ $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context if ($GenerateReleaseNotes) { - $notes = New-GitHubReleaseNote -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context - $Name = $PSBoundParameters.ContainsKey('Name') ? $Name : $notes.Name - $Notes = $PSBoundParameters.ContainsKey('Notes') ? $Notes, $notes.Body -join "`n" : $notes.Body + $generated = New-GitHubReleaseNote -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + $Name = $PSBoundParameters.ContainsKey('Name') ? $Name : $generated.Name + $Notes = $PSBoundParameters.ContainsKey('Notes') ? $Notes, $generated.Body -join "`n" : $generated.Body } $body = @{ From c279efc7af5e9bce11c9cf1af449b4cecfbcd3f6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 17:13:21 +0200 Subject: [PATCH 077/224] Enhance release management by adding Set-GitHubRelease for version 1.3.1 and improving release note generation logic in Update-GitHubRelease. --- examples/Releases/Releases.ps1 | 1 + src/functions/public/Releases/Update-GitHubRelease.ps1 | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 6c56823d5..435dfcf00 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -30,6 +30,7 @@ $repo | Get-GitHubRelease -Tag 'v1.3' | Format-List $repo | New-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List +$repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes $repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index c259732e7..c94a3c379 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -95,8 +95,8 @@ if ($GenerateReleaseNotes) { $generated = New-GitHubReleaseNote -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context - $Name = $PSBoundParameters.ContainsKey('Name') ? $Name : $generated.Name - $Notes = $PSBoundParameters.ContainsKey('Notes') ? $Notes, $generated.Body -join "`n" : $generated.Body + $Name = -not [string]::IsNullOrEmpty($Name) ? $Name : $generated.Name + $Notes = -not [string]::IsNullOrEmpty($Notes) ? $Notes, $generated.Notes -join "`n" : $generated.Notes } $body = @{ From 7c1c1a65c4849ba4965ac2f44aed388ff93e85d0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 21:10:56 +0200 Subject: [PATCH 078/224] Enhance Update-GitHubRelease to require either ID or Tag parameter and improve parameter handling for release updates. --- examples/Releases/Releases.ps1 | 4 +++- .../public/Releases/Update-GitHubRelease.ps1 | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 435dfcf00..9127ff457 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -13,7 +13,7 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest Import-Module -Name GitHub } until ($? -eq $true) $_ | Get-GitHubRelease -Latest -} -UseNewRunspace +} 'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease -Latest @@ -27,6 +27,8 @@ $repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' $repo | New-GitHubRelease -Tag 'v1.3' -Latest -Name 'test' -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3' | Format-List +$repo | Get-GitHubRelease -Tag 'v1.3' | Update-GithubRelease -Notes 'Release notes' -Debug +$repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' $repo | New-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index c94a3c379..1b5d7af2b 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -27,7 +27,7 @@ [string] $Repository, # The unique identifier of the release. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(ValueFromPipelineByPropertyName)] [string] $ID, # The name of the tag. @@ -91,6 +91,15 @@ } process { + if (-not $PSBoundParameters.ContainsKey('ID') -and -not $PSBoundParameters.ContainsKey('Tag')) { + throw 'You must specify either the ID or the Tag parameter.' + } + + if (-not $PSBoundParameters.ContainsKey('ID') -and $PSBoundParameters.ContainsKey('Tag')) { + $release = Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + $ID = $release.ID + } + $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context if ($GenerateReleaseNotes) { From 558557f11c9de1e82495b0b3c0c6f94cfd6b35f1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 21:18:30 +0200 Subject: [PATCH 079/224] Fix Update-GitHubRelease to reset Tag parameter when ID is not provided, improving parameter handling. --- examples/Releases/Releases.ps1 | 2 +- src/functions/public/Releases/Update-GitHubRelease.ps1 | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 9127ff457..babaa9a31 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -28,7 +28,7 @@ $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes $repo | New-GitHubRelease -Tag 'v1.3' -Latest -Name 'test' -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3' | Format-List $repo | Get-GitHubRelease -Tag 'v1.3' | Update-GithubRelease -Notes 'Release notes' -Debug -$repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' +$repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' -Debug $repo | New-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 1b5d7af2b..66427dbf6 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -98,6 +98,7 @@ if (-not $PSBoundParameters.ContainsKey('ID') -and $PSBoundParameters.ContainsKey('Tag')) { $release = Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context $ID = $release.ID + $Tag = $null } $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context From 1e88d285861605d33c013f948545a885897cd74f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 21:37:41 +0200 Subject: [PATCH 080/224] Refactor Update-GitHubRelease to simplify parameter checks and improve release note generation logic --- examples/Releases/Releases.ps1 | 2 +- .../public/Releases/Update-GitHubRelease.ps1 | 37 +++++++++---------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index babaa9a31..85bfabc4d 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -32,7 +32,7 @@ $repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' -Debug $repo | New-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List -$repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes +$repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Debug $repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 66427dbf6..1be69f0d3 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -91,30 +91,29 @@ } process { - if (-not $PSBoundParameters.ContainsKey('ID') -and -not $PSBoundParameters.ContainsKey('Tag')) { + if (-not $ID -and -not $Tag) { throw 'You must specify either the ID or the Tag parameter.' } - if (-not $PSBoundParameters.ContainsKey('ID') -and $PSBoundParameters.ContainsKey('Tag')) { - $release = Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context - $ID = $release.ID - $Tag = $null - } - - $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context - if ($GenerateReleaseNotes) { $generated = New-GitHubReleaseNote -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context $Name = -not [string]::IsNullOrEmpty($Name) ? $Name : $generated.Name $Notes = -not [string]::IsNullOrEmpty($Notes) ? $Notes, $generated.Notes -join "`n" : $generated.Notes } + if (-not $ID -and $Tag) { + $release = Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + $ID = $release.ID + $Tag = $null + } + $body = @{ tag_name = $Tag target_commitish = $Target name = $Name body = $Notes } + $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context if ($repo.HasDiscussions) { $body['discussion_category_name'] = $DiscussionCategoryName } @@ -122,17 +121,15 @@ $body | Remove-HashtableEntry -NullOrEmptyValues } - switch ($PSCmdlet.ParameterSetName) { - 'Set latest' { - $body['make_latest'] = [bool]$Latest.ToString().ToLower() - $body['prerelease'] = $false - $body['draft'] = $false - } - 'Not latest' { - $body['make_latest'] = $false - $body['prerelease'] = [bool]$Prerelease - $body['draft'] = [bool]$Draft - } + if ($Latest) { + $body['make_latest'] = [bool]$Latest.ToString().ToLower() + $body['prerelease'] = $false + $body['draft'] = $false + } + if ($Draft -or $Prerelease) { + $body['make_latest'] = $false + $body['prerelease'] = [bool]$Prerelease + $body['draft'] = [bool]$Draft } $inputObject = @{ From 77b67d0206ce597f194c13a75483fce912547197 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 22:03:50 +0200 Subject: [PATCH 081/224] Improve Update-GitHubRelease to handle missing ID when Tag is provided, adding error handling for non-existent releases. --- src/functions/public/Releases/Update-GitHubRelease.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 1be69f0d3..f9e190e1d 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -101,8 +101,11 @@ $Notes = -not [string]::IsNullOrEmpty($Notes) ? $Notes, $generated.Notes -join "`n" : $generated.Notes } - if (-not $ID -and $Tag) { + if ([string]::IsNullOrEmpty($ID) -and -not [string]::IsNullOrEmpty($Tag)) { $release = Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + if (-not $release) { + throw "Release with tag [$Tag] not found in [$Owner/$Repository]." + } $ID = $release.ID $Tag = $null } From f3fd5a8c2c29eaf70e564b14f6270613f081e1bf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 22:08:47 +0200 Subject: [PATCH 082/224] Refactor Update-GitHubRelease to streamline body parameter construction and improve tag handling logic. --- .../public/Releases/Update-GitHubRelease.ps1 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index f9e190e1d..d1f227383 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -101,21 +101,22 @@ $Notes = -not [string]::IsNullOrEmpty($Notes) ? $Notes, $generated.Notes -join "`n" : $generated.Notes } + $body = @{ + tag_name = $Tag + target_commitish = $Target + name = $Name + body = $Notes + } + if ([string]::IsNullOrEmpty($ID) -and -not [string]::IsNullOrEmpty($Tag)) { $release = Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context if (-not $release) { throw "Release with tag [$Tag] not found in [$Owner/$Repository]." } $ID = $release.ID - $Tag = $null + $body.Remove('tag_name') } - $body = @{ - tag_name = $Tag - target_commitish = $Target - name = $Name - body = $Notes - } $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context if ($repo.HasDiscussions) { $body['discussion_category_name'] = $DiscussionCategoryName From 3c4e930cd34aee41fe6983926bee8154d6a6e9fa Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 22:16:47 +0200 Subject: [PATCH 083/224] Refactor Update-GitHubRelease to remove mandatory constraint on ID parameter, improving flexibility in release updates. --- examples/Releases/Releases.ps1 | 2 +- src/functions/public/Releases/Update-GitHubRelease.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 85bfabc4d..3705ef606 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -27,7 +27,7 @@ $repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' $repo | New-GitHubRelease -Tag 'v1.3' -Latest -Name 'test' -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3' | Format-List -$repo | Get-GitHubRelease -Tag 'v1.3' | Update-GithubRelease -Notes 'Release notes' -Debug +$repo | Get-GitHubRelease -Tag 'v1.3' | Update-GithubRelease -Notes 'Release notes' $repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' -Debug $repo | New-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index d1f227383..0255b5bb1 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -27,7 +27,7 @@ [string] $Repository, # The unique identifier of the release. - [Parameter(ValueFromPipelineByPropertyName)] + [Parameter()] [string] $ID, # The name of the tag. From c656b07482721a96c4c2a4c96a1e2b3a423ad329 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 13 Apr 2025 22:30:29 +0200 Subject: [PATCH 084/224] Add InputObject parameter to Update-GitHubRelease for improved release updates --- src/functions/public/Releases/Update-GitHubRelease.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 0255b5bb1..1d528ca81 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -77,6 +77,10 @@ [Parameter()] [switch] $Declare, + # The release to update + [Parameter(ValueFromPipeline)] + [GitHubRelease] $InputObject, + # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] @@ -91,6 +95,8 @@ } process { + $ID = $InputObject.ID + if (-not $ID -and -not $Tag) { throw 'You must specify either the ID or the Tag parameter.' } From d5758e5f992df137246ae70edadbf4cb2cc6487c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 14 Apr 2025 18:41:29 +0200 Subject: [PATCH 085/224] Add Get-GitHubReleaseAsset usage example and improve parameter documentation --- examples/Releases/Releases.ps1 | 1 + .../New-GitHubRepositoryAsFork.ps1 | 2 +- .../Assets/Get-GitHubReleaseAsset.ps1 | 31 +++++++++---------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 3705ef606..cd677cd2b 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -35,6 +35,7 @@ $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List $repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Debug $repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List +Get-GitHubReleaseAsset -Owner MariusStorhaug -Repository mytest -ReleaseID $repo | Set-GitHubRelease -Tag 'v1.5' -Latest -Name 'test' -Notes 'Release notes' | Select-Object * $repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft diff --git a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 index ad190ddfd..5cadf695e 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 @@ -42,7 +42,7 @@ [OutputType([GitHubRepository])] [CmdletBinding(SupportsShouldProcess)] param( - # The account ForkOwner of the repository. The name is not case sensitive. + # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] [string] $Owner, diff --git a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 index 5106d462b..795146394 100644 --- a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 @@ -17,35 +17,32 @@ Gets the release assets for the release with the ID '7654321' for the repository 'octocat/hello-world'. - .NOTES - [Get a release asset](https://docs.github.com/rest/releases/assets#get-a-release-asset) + .INPUTS + GitHubRelease + + .OUTPUTS + GitHubReleaseAsset + + .LINK + https://psmodule.io/GitHub/Functions/Releases/Assets/Get-GitHubReleaseAsset #> - [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] + [OutputType([GitHubReleaseAsset])] + [CmdletBinding(DefaultParameterSetName = 'List assets from a release')] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The unique identifier of the asset. - [Parameter( - Mandatory, - ParameterSetName = 'ID' - )] - [Alias('asset_id')] + [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by ID')] [string] $ID, # The unique identifier of the release. - [Parameter( - Mandatory, - ParameterSetName = 'ReleaseID' - )] - [Alias('release_id')] + [Parameter(Mandatory, ParameterSetName = 'List assets from a release', ValueFromPipelineByPropertyName)] [string] $ReleaseID, # The context to run the command in. Used to get the details for the API call. From 8754a93d3653afcec965ef8a18837b08fc0eddec Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 14 Apr 2025 21:12:25 +0200 Subject: [PATCH 086/224] Enhance GitHubRepository and related functions with additional properties and parameter adjustments for improved repository management --- .../public/Repositories/GitHubRepository.ps1 | 22 ++++- .../Repositories/Get-GitHubRepository.ps1 | 92 ------------------- .../Repositories/New-GitHubRepository.ps1 | 16 ++-- 3 files changed, 28 insertions(+), 102 deletions(-) diff --git a/src/classes/public/Repositories/GitHubRepository.ps1 b/src/classes/public/Repositories/GitHubRepository.ps1 index 11e32718b..b71ffbdf8 100644 --- a/src/classes/public/Repositories/GitHubRepository.ps1 +++ b/src/classes/public/Repositories/GitHubRepository.ps1 @@ -7,6 +7,10 @@ # Example: octocat [GitHubOwner] $Owner + # The full name of the repository, including the owner. + # Example: octocat/Hello-World + [string] $FullName + # The HTML URL of the repository. # Example: https://github.com/octocat/Hello-World [string] $Url @@ -175,6 +179,18 @@ # Custom properties for the repository. [PSCustomObject] $CustomProperties + # The clone URL of the repository. + # Example: git://github.com/octocat/Hello-World.git + [string] $CloneUrl + + # The SSH URL of the repository. + # Example: git@github.com:octocat/Hello-World.git + [string] $SshUrl + + # The Git URL of the repository. + # Example: https://github.com/octocat/Hello-World.git + [string] $GitUrl + GitHubRepository() {} GitHubRepository([PSCustomObject]$Object) { @@ -182,6 +198,7 @@ $this.NodeID = $Object.node_id $this.Name = $Object.name $this.Owner = [GitHubOwner]::New($Object.owner) + $this.FullName = $Object.full_name $this.Visibility = $Object.visibility $this.Description = $Object.description $this.Homepage = $Object.homepage @@ -221,9 +238,12 @@ $this.MergeCommitMessage = $Object.merge_commit_message $this.MergeCommitTitle = $Object.merge_commit_title $this.CustomProperties = $Object.custom_properties + $this.TemplateRepository = $null -ne $Object.template_repository ? [GitHubRepository]::New($Object.template_repository) : $null $this.ForkParent = $null -ne $Object.parent ? [GitHubRepository]::New($Object.parent) : $null $this.ForkSource = $null -ne $Object.source ? [GitHubRepository]::New($Object.source) : $null - $this.TemplateRepository = $null -ne $Object.template_repository ? [GitHubRepository]::New($Object.template_repository) : $null + $this.CloneUrl = $Object.clone_url + $this.SshUrl = $Object.ssh_url + $this.GitUrl = $Object.git_url } [string] ToString() { diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 0a5cd61d7..521e7b1cb 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -53,35 +53,6 @@ filter Get-GitHubRepository { [OutputType([GitHubRepository])] [CmdletBinding(DefaultParameterSetName = 'MyRepos_Type')] param( - #Limit results to repositories with the specified visibility. - [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] - [ValidateSet('all', 'public', 'private')] - [string] $Visibility = 'all', - - # Comma-separated list of values. Can include: - # - owner: Repositories that are owned by the authenticated user. - # - collaborator: Repositories that the user has been added to as a collaborator. - # - organization_member: Repositories that the user has access to through being a member of an organization. - # This includes every repository on every team that the user is on. - # Default: owner, collaborator, organization_member - [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] - [ValidateSet('owner', 'collaborator', 'organization_member')] - [string[]] $Affiliation = @('owner', 'collaborator', 'organization_member'), - - # A repository ID. Only return repositories with an ID greater than this ID. - [Parameter(ParameterSetName = 'ListByID')] - [int] $SinceID = 0, - - # Only show repositories updated after the given time. - [Parameter(ParameterSetName = 'MyRepos_Type')] - [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] - [datetime] $Since, - - # Only show repositories updated before the given time. - [Parameter(ParameterSetName = 'MyRepos_Type')] - [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] - [datetime] $Before, - # The account owner of the repository. The name is not case sensitive. [Parameter(ParameterSetName = 'ByName', ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'ListByOrg', ValueFromPipelineByPropertyName)] @@ -97,22 +68,6 @@ filter Get-GitHubRepository { [Parameter(Mandatory, ParameterSetName = 'ByName')] [string] $Name, - # The property to sort the results by. - [Parameter(ParameterSetName = 'MyRepos_Type')] - [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] - [Parameter(ParameterSetName = 'ListByOrg')] - [Parameter(ParameterSetName = 'ListByUser')] - [ValidateSet('created', 'updated', 'pushed', 'full_name')] - [string] $Sort = 'created', - - # The order to sort by. - # Default: asc when using full_name, otherwise desc. - [Parameter(ParameterSetName = 'MyRepos')] - [Parameter(ParameterSetName = 'ListByOrg')] - [Parameter(ParameterSetName = 'ListByUser')] - [ValidateSet('asc', 'desc')] - [string] $Direction = 'asc', - # The number of results per page (max 100). [Parameter(ParameterSetName = 'MyRepos')] [Parameter(ParameterSetName = 'ListByOrg')] @@ -126,37 +81,6 @@ filter Get-GitHubRepository { [object] $Context = (Get-GitHubContext) ) - dynamicparam { - $DynamicParamDictionary = New-DynamicParamDictionary - - if ($PSCmdlet.ParameterSetName -in 'MyRepos_Type', 'ListByOrg', 'ListByUser') { - - switch ($PSCmdlet.ParameterSetName) { - 'MyRepos_Type' { - $ValidateSet = 'all', 'owner', 'public', 'private', 'member' - } - 'ListByOrg' { - $ValidateSet = 'all', 'public', 'private', 'forks', 'sources', 'member' - } - 'ListByUser' { - $ValidateSet = 'all', 'owner', 'member' - } - } - - $dynParam = @{ - Name = 'Type' - ParameterSetName = $PSCmdlet.ParameterSetName - Type = [string] - Mandatory = $false - ValidateSet = $ValidateSet - DynamicParamDictionary = $DynamicParamDictionary - } - New-DynamicParam @dynParam - } - - return $DynamicParamDictionary - } - begin { $stackPath = Get-PSCallStackPath Write-Debug "[$stackPath] - Start" @@ -165,22 +89,6 @@ filter Get-GitHubRepository { } process { - $Type = if ($null -eq $PSBoundParameters['Type']) { - switch ($PSCmdlet.ParameterSetName) { - 'MyRepos_Type' { - 'owner' - } - 'ListByOrg' { - 'all' - } - 'ListByUser' { - 'owner' - } - } - } else { - $PSBoundParameters['Type'] - } - Write-Debug "ParamSet: [$($PSCmdlet.ParameterSetName)]" switch ($PSCmdlet.ParameterSetName) { 'MyRepos_Type' { diff --git a/src/functions/public/Repositories/New-GitHubRepository.ps1 b/src/functions/public/Repositories/New-GitHubRepository.ps1 index 280185069..e5b6a77eb 100644 --- a/src/functions/public/Repositories/New-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/New-GitHubRepository.ps1 @@ -110,13 +110,14 @@ filter New-GitHubRepository { # The account owner of the repository. The name is not case sensitive. [Parameter(ParameterSetName = 'org')] [Parameter(ParameterSetName = 'fork')] + [Parameter(ParameterSetName = 'template')] [string] $Owner, # The name of the repository. [Parameter(ParameterSetName = 'fork')] + [Parameter(ParameterSetName = 'template')] [Parameter(Mandatory, ParameterSetName = 'user')] [Parameter(Mandatory, ParameterSetName = 'org')] - [Parameter(Mandatory, ParameterSetName = 'template')] [string] $Name, # The account owner of the template repository. The name is not case sensitive. @@ -135,10 +136,6 @@ filter New-GitHubRepository { [Parameter(Mandatory, ParameterSetName = 'fork')] [string] $ForkRepository, - # When forking from an existing repository, fork with only the default branch. - [Parameter(ParameterSetName = 'fork')] - [switch] $DefaultBranchOnly, - # A short description of the new repository. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] @@ -148,6 +145,7 @@ filter New-GitHubRepository { # Set to true to include the directory structure and files from all branches in the template repository, # and not just the default branch. [Parameter(ParameterSetName = 'template')] + [Parameter(ParameterSetName = 'fork')] [switch] $IncludeAllBranches, # A URL with more information about the repository. @@ -297,6 +295,9 @@ filter New-GitHubRepository { } process { + if (-not $PSBoundParameters.ContainsKey('Owner')) { + $Owner = $Context.UserName + } Write-Verbose "ParameterSetName: $($PSCmdlet.ParameterSetName)" switch ($PSCmdlet.ParameterSetName) { 'user' { @@ -380,9 +381,6 @@ filter New-GitHubRepository { } } 'fork' { - if ([string]::IsNullorEmpty($Name)) { - $Name = $ForkRepository - } if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] as fork from [$ForkOwner/$ForkRepository]", 'Create')) { $params = @{ Context = $Context @@ -390,7 +388,7 @@ filter New-GitHubRepository { Repository = $ForkRepository Organization = $Owner Name = $Name - DefaultBranchOnly = $DefaultBranchOnly + DefaultBranchOnly = -not $IncludeAllBranches } $params | Remove-HashtableEntry -NullOrEmptyValues New-GitHubRepositoryAsFork @params From d6ccf3cb74bcf2c4598a079f7b00cba8f6a47c7c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 14 Apr 2025 22:40:52 +0200 Subject: [PATCH 087/224] Remove HasDownloads parameter from repository creation functions and update related examples for consistency --- .../Get-GitHubRepositoryListByUser.ps1 | 2 +- .../Repositories/New-GitHubRepositoryOrg.ps1 | 6 -- .../Repositories/New-GitHubRepositoryUser.ps1 | 6 -- .../Repositories/Get-GitHubRepository.ps1 | 73 +++---------------- .../Repositories/New-GitHubRepository.ps1 | 9 --- tools/utilities/Local-Testing.ps1 | 2 - 6 files changed, 13 insertions(+), 85 deletions(-) diff --git a/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 b/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 index 7321a9977..c96601239 100644 --- a/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 +++ b/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 @@ -49,7 +49,7 @@ # Default: asc when using full_name, otherwise desc. [Parameter()] [ValidateSet('asc', 'desc')] - [string] $Direction, + [string] $Direction = 'asc', # The number of results per page (max 100). [Parameter()] diff --git a/src/functions/private/Repositories/New-GitHubRepositoryOrg.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryOrg.ps1 index 21f0d0985..863f61e10 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryOrg.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryOrg.ps1 @@ -22,7 +22,6 @@ HasIssues = $true HasProjects = $true HasWiki = $true - HasDownloads = $true IsTemplate = $true AddReadme = $true AllowSquashMerge = $true @@ -79,10 +78,6 @@ [Parameter()] [switch] $HasWiki, - # Whether downloads are enabled. - [Parameter()] - [switch] $HasDownloads, - # Either true to make this repo available as a template repository or false to prevent it. [Parameter()] [switch] $IsTemplate, @@ -174,7 +169,6 @@ has_issues = [bool]$HasIssues has_projects = [bool]$HasProjects has_wiki = [bool]$HasWiki - has_downloads = [bool]$HasDownloads is_template = [bool]$IsTemplate team_id = $TeamId auto_init = [bool]$AddReadme diff --git a/src/functions/private/Repositories/New-GitHubRepositoryUser.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryUser.ps1 index 4742d2b5f..41bf334ac 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryUser.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryUser.ps1 @@ -21,7 +21,6 @@ HasIssues = $true HasProjects = $true HasWiki = $true - HasDownloads = $true IsTemplate = $true AddReadme = $true AllowSquashMerge = $true @@ -77,10 +76,6 @@ [Parameter()] [switch] $HasDiscussions, - # Whether downloads are enabled. - [Parameter()] - [switch] $HasDownloads, - # Whether this repository acts as a template that can be used to generate new repositories. [Parameter()] [switch] $IsTemplate, @@ -171,7 +166,6 @@ has_issues = [bool]$HasIssues has_projects = [bool]$HasProjects has_wiki = [bool]$HasWiki - has_downloads = [bool]$HasDownloads is_template = [bool]$IsTemplate team_id = $TeamId auto_init = [bool]$AddReadme diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 521e7b1cb..d43b77312 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -6,36 +6,22 @@ filter Get-GitHubRepository { Gets a specific repository or list of repositories. .DESCRIPTION - Gets a specific repository or list of repositories based on parameter sets. + Gets a specific repository or list of repositories. If no parameters are specified, the authenticated user's repositories are returned. - If a Username parameter is specified, the specified user's public repositories are returned. - If the SinceId parameter is specified, the repositories with an ID greater than the specified ID are returned. - If an Owner and Repo parameters are specified, the specified repository is returned. - If the Owner and Repo parameters are specified, the specified repository is returned. - - .PARAMETER Type - Specifies the types of repositories you want returned. + If a username is specified, the user's public repositories are returned. + If an organization is specified, the organization's public repositories are returned. + Can also be used with the name parameter to get a specific repository. .EXAMPLE Get-GitHubRepository - Gets the repositories for the authenticated user. - - .EXAMPLE - Get-GitHubRepository -Type 'owner' - - Gets the repositories owned by the authenticated user. + Gets the authenticated user's repositories. .EXAMPLE Get-GitHubRepository -Username 'octocat' Gets the repositories for the specified user. - .EXAMPLE - Get-GitHubRepository -SinceID 123456789 - - Gets the repositories with an ID equals and greater than 123456789. - .EXAMPLE Get-GitHubRepository -Organization 'github' -Name 'octocat' @@ -51,7 +37,7 @@ filter Get-GitHubRepository { https://psmodule.io/GitHub/Functions/Repositories/Get-GitHubRepository/ #> [OutputType([GitHubRepository])] - [CmdletBinding(DefaultParameterSetName = 'MyRepos_Type')] + [CmdletBinding(DefaultParameterSetName = 'MyRepos')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(ParameterSetName = 'ByName', ValueFromPipelineByPropertyName)] @@ -91,30 +77,10 @@ filter Get-GitHubRepository { process { Write-Debug "ParamSet: [$($PSCmdlet.ParameterSetName)]" switch ($PSCmdlet.ParameterSetName) { - 'MyRepos_Type' { + 'MyRepos' { $params = @{ - Context = $Context - Type = $Type - Sort = $Sort - Direction = $Direction - PerPage = $PerPage - Since = $Since - Before = $Before - } - $params | Remove-HashtableEntry -NullOrEmptyValues - Write-Verbose ($params | Format-List | Out-String) - Get-GitHubMyRepositories @params - } - 'MyRepos_Aff-Vis' { - $params = @{ - Context = $Context - Visibility = $Visibility - Affiliation = $Affiliation - Sort = $Sort - Direction = $Direction - PerPage = $PerPage - Since = $Since - Before = $Before + Context = $Context + PerPage = $PerPage } $params | Remove-HashtableEntry -NullOrEmptyValues Write-Verbose ($params | Format-List | Out-String) @@ -139,22 +105,10 @@ filter Get-GitHubRepository { Get-GitHubRepositoryByName @params } catch { return } } - 'ListByID' { - $params = @{ - Context = $Context - Since = $SinceID - } - $params | Remove-HashtableEntry -NullOrEmptyValues - Write-Verbose ($params | Format-List | Out-String) - Get-GitHubRepositoryListByID @params - } 'ListByOrg' { $params = @{ Context = $Context Organization = $Organization - Type = $Type - Sort = $Sort - Direction = $Direction PerPage = $PerPage } $params | Remove-HashtableEntry -NullOrEmptyValues @@ -163,12 +117,9 @@ filter Get-GitHubRepository { } 'ListByUser' { $params = @{ - Context = $Context - Username = $Username - Type = $Type - Sort = $Sort - Direction = $Direction - PerPage = $PerPage + Context = $Context + Username = $Username + PerPage = $PerPage } $params | Remove-HashtableEntry -NullOrEmptyValues Write-Verbose ($params | Format-List | Out-String) diff --git a/src/functions/public/Repositories/New-GitHubRepository.ps1 b/src/functions/public/Repositories/New-GitHubRepository.ps1 index e5b6a77eb..8c715b5ca 100644 --- a/src/functions/public/Repositories/New-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/New-GitHubRepository.ps1 @@ -24,7 +24,6 @@ filter New-GitHubRepository { HasProjects = $true HasWiki = $true HasDiscussions = $true - HasDownloads = $true IsTemplate = $true AddReadme = $true AllowSquashMerge = $true @@ -46,7 +45,6 @@ filter New-GitHubRepository { HasIssues = $true HasProjects = $true HasWiki = $true - HasDownloads = $true IsTemplate = $true AddReadme = $true AllowSquashMerge = $true @@ -180,11 +178,6 @@ filter New-GitHubRepository { [Parameter(ParameterSetName = 'user')] [switch] $HasDiscussions, - # Whether downloads are enabled. - [Parameter(ParameterSetName = 'user')] - [Parameter(ParameterSetName = 'org')] - [switch] $HasDownloads, - # Whether this repository acts as a template that can be used to generate new repositories. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] @@ -311,7 +304,6 @@ filter New-GitHubRepository { HasProjects = $HasProjects HasWiki = $HasWiki HasDiscussions = $HasDiscussions - HasDownloads = $HasDownloads IsTemplate = $IsTemplate TeamId = $TeamId AddReadme = $AddReadme @@ -343,7 +335,6 @@ filter New-GitHubRepository { HasIssues = $HasIssues HasProjects = $HasProjects HasWiki = $HasWiki - HasDownloads = $HasDownloads IsTemplate = $IsTemplate TeamId = $TeamId AddReadme = $AddReadme diff --git a/tools/utilities/Local-Testing.ps1 b/tools/utilities/Local-Testing.ps1 index 7919a2476..eb68da03a 100644 --- a/tools/utilities/Local-Testing.ps1 +++ b/tools/utilities/Local-Testing.ps1 @@ -105,7 +105,6 @@ $params = @{ HasIssues = $true HasProjects = $true HasWiki = $true - HasDownloads = $true IsTemplate = $true # TeamID = 12345679 AddReadme = $true @@ -134,7 +133,6 @@ $params = @{ HasIssues = $true HasProjects = $true HasWiki = $true - HasDownloads = $true IsTemplate = $true # TeamID = 12345679 AddReadme = $true From a13bef21c649c43185da176c8208f42292c9dd91 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 14 Apr 2025 23:28:47 +0200 Subject: [PATCH 088/224] Update sorting parameters to default to 'pushed' and enhance documentation for repository creation functions --- .../Get-GitHubRepositoryListByOrg.ps1 | 2 +- .../Get-GitHubRepositoryListByUser.ps1 | 4 ++-- .../Repositories/New-GitHubRepositoryAsFork.ps1 | 8 ++++---- .../New-GitHubRepositoryFromTemplate.ps1 | 3 +-- .../Repositories/New-GitHubRepository.ps1 | 17 ++++++++--------- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 b/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 index e20f8af7e..04f8034bf 100644 --- a/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 +++ b/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 @@ -46,7 +46,7 @@ # The property to sort the results by. [Parameter()] [ValidateSet('created', 'updated', 'pushed', 'full_name')] - [string] $Sort = 'created', + [string] $Sort = 'pushed', # The order to sort by. # Default: asc when using full_name, otherwise desc. diff --git a/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 b/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 index c96601239..749295a59 100644 --- a/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 +++ b/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 @@ -38,12 +38,12 @@ # Specifies the types of repositories you want returned. [Parameter()] [ValidateSet('all', 'owner', 'member')] - [string] $Type = 'all', + [string] $Type = 'owner', # The property to sort the results by. [Parameter()] [ValidateSet('created', 'updated', 'pushed', 'full_name')] - [string] $Sort = 'created', + [string] $Sort = 'pushed', # The order to sort by. # Default: asc when using full_name, otherwise desc. diff --git a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 index 5cadf695e..42433e747 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryAsFork.ps1 @@ -29,9 +29,9 @@ Fork the repository `Hello-World` owned by `github` for the organization `octocat`, naming the resulting repository `Hello-World`. .EXAMPLE - New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepository 'Hello-World' -DefaultBranchOnly + New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepository 'Hello-World' -IncludeAllBranches - Fork the repository `Hello-World` owned by `github` for the authenticated user, forking only the default branch. + Fork the repository `Hello-World` owned by `github` for the authenticated user, including all the branches from the source. .OUTPUTS GitHubRepository @@ -59,9 +59,9 @@ [Parameter()] [string] $Name, - # When forking from an existing repository, fork with only the default branch. + # Include all branches from the source repository. [Parameter()] - [switch] $DefaultBranchOnly, + [switch] $IncludeAllBranches, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. diff --git a/src/functions/private/Repositories/New-GitHubRepositoryFromTemplate.ps1 b/src/functions/private/Repositories/New-GitHubRepositoryFromTemplate.ps1 index a67efc639..208dd6902 100644 --- a/src/functions/private/Repositories/New-GitHubRepositoryFromTemplate.ps1 +++ b/src/functions/private/Repositories/New-GitHubRepositoryFromTemplate.ps1 @@ -61,8 +61,7 @@ [Parameter()] [string] $Description, - # Set to true to include the directory structure and files from all branches in the template repository, - # and not just the default branch. + # Include all branches from the source repository. [Parameter()] [switch] $IncludeAllBranches, diff --git a/src/functions/public/Repositories/New-GitHubRepository.ps1 b/src/functions/public/Repositories/New-GitHubRepository.ps1 index 8c715b5ca..6c2a5a012 100644 --- a/src/functions/public/Repositories/New-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/New-GitHubRepository.ps1 @@ -109,7 +109,7 @@ filter New-GitHubRepository { [Parameter(ParameterSetName = 'org')] [Parameter(ParameterSetName = 'fork')] [Parameter(ParameterSetName = 'template')] - [string] $Owner, + [string] $Organization, # The name of the repository. [Parameter(ParameterSetName = 'fork')] @@ -140,8 +140,7 @@ filter New-GitHubRepository { [Parameter(ParameterSetName = 'template')] [string] $Description, - # Set to true to include the directory structure and files from all branches in the template repository, - # and not just the default branch. + # Include all branches from the source repository. [Parameter(ParameterSetName = 'template')] [Parameter(ParameterSetName = 'fork')] [switch] $IncludeAllBranches, @@ -374,12 +373,12 @@ filter New-GitHubRepository { 'fork' { if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] as fork from [$ForkOwner/$ForkRepository]", 'Create')) { $params = @{ - Context = $Context - Owner = $ForkOwner - Repository = $ForkRepository - Organization = $Owner - Name = $Name - DefaultBranchOnly = -not $IncludeAllBranches + Context = $Context + Owner = $ForkOwner + Repository = $ForkRepository + Organization = $Owner + Name = $Name + IncludeAllBranches = $IncludeAllBranches } $params | Remove-HashtableEntry -NullOrEmptyValues New-GitHubRepositoryAsFork @params From dbfad73994de23890be4708b78bb5e9bd50857c2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 14 Apr 2025 23:44:33 +0200 Subject: [PATCH 089/224] Set default parameter values for Visibility, Affiliation, Type, and Sort in Get-GitHubMyRepositories; update PerPage assignment in Get-GitHubRepositoryListByOrg; adjust Direction parameter in Get-GitHubRepositoryListByUser; refine test cleanup logic in Repositories.Tests. --- .../private/Repositories/Get-GitHubMyRepositories.ps1 | 8 ++++---- .../Repositories/Get-GitHubRepositoryListByOrg.ps1 | 2 +- .../Repositories/Get-GitHubRepositoryListByUser.ps1 | 2 +- tests/Repositories.Tests.ps1 | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 b/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 index 98ce0c6be..5a921a7ac 100644 --- a/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 +++ b/src/functions/private/Repositories/Get-GitHubMyRepositories.ps1 @@ -63,7 +63,7 @@ # Limit results to repositories with the specified visibility. [Parameter(ParameterSetName = 'Aff-Vis')] [ValidateSet('all', 'public', 'private')] - [string] $Visibility, + [string] $Visibility = 'all', # Comma-separated list of values. Can include: # - owner: Repositories that are owned by the authenticated user. @@ -73,17 +73,17 @@ # Default: owner, collaborator, organization_member [Parameter(ParameterSetName = 'Aff-Vis')] [ValidateSet('owner', 'collaborator', 'organization_member')] - [string[]] $Affiliation, + [string[]] $Affiliation = 'owner', # Specifies the types of repositories you want returned. [Parameter(ParameterSetName = 'Type')] [ValidateSet('all', 'owner', 'public', 'private', 'member')] - [string] $Type, + [string] $Type = 'owner', # The property to sort the results by. [Parameter()] [ValidateSet('created', 'updated', 'pushed', 'full_name')] - [string] $Sort, + [string] $Sort = 'pushed', # The order to sort by. # Default: asc when using full_name, otherwise desc. diff --git a/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 b/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 index 04f8034bf..349332ca5 100644 --- a/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 +++ b/src/functions/private/Repositories/Get-GitHubRepositoryListByOrg.ps1 @@ -76,13 +76,13 @@ sort = $Sort type = $Type direction = $Direction - per_page = $PerPage } $inputObject = @{ Method = 'GET' APIEndpoint = "/orgs/$Organization/repos" Body = $body + PerPage = $PerPage Context = $Context } diff --git a/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 b/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 index 749295a59..b411f6402 100644 --- a/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 +++ b/src/functions/private/Repositories/Get-GitHubRepositoryListByUser.ps1 @@ -49,7 +49,7 @@ # Default: asc when using full_name, otherwise desc. [Parameter()] [ValidateSet('asc', 'desc')] - [string] $Direction = 'asc', + [string] $Direction, # The number of results per page (max 100). [Parameter()] diff --git a/tests/Repositories.Tests.ps1 b/tests/Repositories.Tests.ps1 index 8c46d6d23..e286c3e1f 100644 --- a/tests/Repositories.Tests.ps1 +++ b/tests/Repositories.Tests.ps1 @@ -43,7 +43,7 @@ Describe 'Repositories' { AfterAll { switch ($OwnerType) { 'user' { - Get-GitHubRepository -Affiliation owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false + Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false } 'organization' { Get-GitHubRepository -Owner $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false From fc14d07150c14221eaa14efb83e0113176f7cc6a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 03:22:44 +0200 Subject: [PATCH 090/224] Refactor GitHubNode subclasses to use databaseId for ID assignment; enhance error handling in GraphQL functions and implement nested pagination for release assets. --- .../public/Artifacts/GitHubArtifact.ps1 | 12 +- .../public/Environment/GitHubEnvironment.ps1 | 12 +- src/classes/public/Owner/GitHubOwner.ps1 | 9 +- .../Owner/GitHubOwner/GitHubOrganization.ps1 | 9 +- .../public/Owner/GitHubOwner/GitHubUser.ps1 | 9 +- src/classes/public/Releases/GitHubRelease.ps1 | 45 ++++- .../public/Repositories/GitHubRepository.ps1 | 12 +- src/classes/public/Secrets/GitHubSecret.ps1 | 1 + .../public/Variables/GitHubVariable.ps1 | 10 +- .../public/Workflows/GitHubWorkflow.ps1 | 12 +- .../public/Workflows/GitHubWorkflowRun.ps1 | 12 +- .../private/Teams/Get-GitHubTeamListByOrg.ps1 | 4 +- .../public/API/Invoke-GitHubGraphQLQuery.ps1 | 74 ++++++++ .../GraphQL/Invoke-GitHubGraphQLQuery.ps1 | 59 ------ .../public/Releases/Get-GitHubReleaseQL.ps1 | 168 ++++++++++++++++++ 15 files changed, 356 insertions(+), 92 deletions(-) create mode 100644 src/functions/public/API/Invoke-GitHubGraphQLQuery.ps1 delete mode 100644 src/functions/public/GraphQL/Invoke-GitHubGraphQLQuery.ps1 create mode 100644 src/functions/public/Releases/Get-GitHubReleaseQL.ps1 diff --git a/src/classes/public/Artifacts/GitHubArtifact.ps1 b/src/classes/public/Artifacts/GitHubArtifact.ps1 index f793696ed..23849b49a 100644 --- a/src/classes/public/Artifacts/GitHubArtifact.ps1 +++ b/src/classes/public/Artifacts/GitHubArtifact.ps1 @@ -38,8 +38,16 @@ GitHubArtifact() {} GitHubArtifact([PSCustomObject]$Object, [string]$Owner, [string]$Repository) { - $this.ID = $Object.id - $this.NodeID = $Object.node_id + # From GitHubNode + if ($Object.databaseId) { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + } else { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + } + + # From GitHubArtifact $this.Name = $Object.name $this.Owner = $Owner $this.Repository = $Repository diff --git a/src/classes/public/Environment/GitHubEnvironment.ps1 b/src/classes/public/Environment/GitHubEnvironment.ps1 index 2345abf17..ead02385f 100644 --- a/src/classes/public/Environment/GitHubEnvironment.ps1 +++ b/src/classes/public/Environment/GitHubEnvironment.ps1 @@ -29,8 +29,16 @@ GitHubEnvironment() {} GitHubEnvironment([PSCustomObject]$Object, [string]$Owner, [string]$Repository) { - $this.ID = $Object.id - $this.NodeID = $Object.node_id + # From GitHubNode + if ($Object.databaseId) { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + } else { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + } + + # From GitHubEnvironment $this.Name = $Object.name $this.Url = $Object.html_url $this.Owner = $Owner diff --git a/src/classes/public/Owner/GitHubOwner.ps1 b/src/classes/public/Owner/GitHubOwner.ps1 index 4c56bbc2a..48abf5c55 100644 --- a/src/classes/public/Owner/GitHubOwner.ps1 +++ b/src/classes/public/Owner/GitHubOwner.ps1 @@ -71,8 +71,13 @@ GitHubOwner([PSCustomObject]$Object) { # From GitHubNode - $this.ID = $Object.id - $this.NodeID = $Object.node_id + if ($Object.databaseId) { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + } else { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + } # From GitHubOwner $this.Name = $Object.login diff --git a/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1 b/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1 index bbc1bae4f..c335373c2 100644 --- a/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1 +++ b/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1 @@ -138,8 +138,13 @@ GitHubOrganization([PSCustomObject]$Object) { # From GitHubNode - $this.ID = $Object.id - $this.NodeID = $Object.node_id + if ($Object.databaseId) { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + } else { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + } # From GitHubOwner $this.Name = $Object.login diff --git a/src/classes/public/Owner/GitHubOwner/GitHubUser.ps1 b/src/classes/public/Owner/GitHubOwner/GitHubUser.ps1 index b6b1d4664..c6dc7c805 100644 --- a/src/classes/public/Owner/GitHubOwner/GitHubUser.ps1 +++ b/src/classes/public/Owner/GitHubOwner/GitHubUser.ps1 @@ -14,8 +14,13 @@ GitHubUser([PSCustomObject]$Object) { # From GitHubNode - $this.ID = $Object.id - $this.NodeID = $Object.node_id + if ($Object.databaseId) { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + } else { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + } # From GitHubOwner $this.Name = $Object.login diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index edc79ecc0..a5c315e0d 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -107,9 +107,17 @@ class GitHubRelease : GitHubNode { GitHubRelease() {} - GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository, [bool] $Latest) { - $this.ID = $Object.id - $this.NodeID = $Object.node_id + GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository) { + # From GitHubNode + if ($Object.databaseId) { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + } else { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + } + + # From GitHubRelease $this.Name = $Object.name $this.Repository = $Repository $this.Owner = $Owner @@ -124,8 +132,33 @@ class GitHubRelease : GitHubNode { $this.CreatedAt = $Object.created_at $this.PublishedAt = $Object.published_at $this.Assets = $Object.assets | ForEach-Object { [GitHubReleaseAsset]::new($_) } - $this.TarballUrl = $Object.tarball_url - $this.ZipballUrl = $Object.zipball_url - $this.Mentions = $Object.mentions_count } } + +# DatabaseID : 211843249 +# Name : v0.22.1 +# Repository : GitHub +# Owner : PSModule +# Tag : v0.22.1 +# Notes : Release notes generated using configuration in .github/release.yml at main --> + +# ## What's Changed +# ### Other Changes +# * 🪲 [Fix]: Enhance repository deletion feedback and fix typo by @MariusStorhaug in https://github.com/PSModule/GitHub/pull/345 + + +# **Full Changelog**: https://github.com/PSModule/GitHub/compare/v0.22.0...v0.22.1 +# Target : main +# Latest : True +# Draft : False +# Prerelease : False +# Url : https://github.com/PSModule/GitHub/releases/tag/v0.22.1 +# Author : github-actions[bot] +# CreatedAt : 11.04.2025 09:03:38 +# PublishedAt : 11.04.2025 13:41:34 +# TarballUrl : https://api.github.com/repos/PSModule/GitHub/tarball/v0.22.1 +# ZipballUrl : https://api.github.com/repos/PSModule/GitHub/zipball/v0.22.1 +# Assets : +# Mentions : 1 +# ID : 211843249 +# NodeID : RE_kwDOGiyhrc4MoHix diff --git a/src/classes/public/Repositories/GitHubRepository.ps1 b/src/classes/public/Repositories/GitHubRepository.ps1 index b71ffbdf8..b2fa44fcf 100644 --- a/src/classes/public/Repositories/GitHubRepository.ps1 +++ b/src/classes/public/Repositories/GitHubRepository.ps1 @@ -194,8 +194,16 @@ GitHubRepository() {} GitHubRepository([PSCustomObject]$Object) { - $this.ID = $Object.id - $this.NodeID = $Object.node_id + # From GitHubNode + if ($Object.databaseId) { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + } else { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + } + + # From GitHubRepository $this.Name = $Object.name $this.Owner = [GitHubOwner]::New($Object.owner) $this.FullName = $Object.full_name diff --git a/src/classes/public/Secrets/GitHubSecret.ps1 b/src/classes/public/Secrets/GitHubSecret.ps1 index b6ae889b2..17efb9dd3 100644 --- a/src/classes/public/Secrets/GitHubSecret.ps1 +++ b/src/classes/public/Secrets/GitHubSecret.ps1 @@ -37,6 +37,7 @@ $this.UpdatedAt = $Object.updated_at $this.Visibility = $Object.visibility $this.SelectedRepositories = $SelectedRepositories + #Set scope based on provided values in Owner, Repository, Environment $this.Scope = if ($Owner -and $Repository -and $Environment) { 'Environment' diff --git a/src/classes/public/Variables/GitHubVariable.ps1 b/src/classes/public/Variables/GitHubVariable.ps1 index 897b1b30e..9dc06c1cb 100644 --- a/src/classes/public/Variables/GitHubVariable.ps1 +++ b/src/classes/public/Variables/GitHubVariable.ps1 @@ -29,17 +29,8 @@ # The ids of the repositories that the variable is visible to. [GitHubRepository[]] $SelectedRepositories - # Simple parameterless constructor GitHubVariable() {} - # Creates a object from a hashtable of key-vaule pairs. - GitHubVariable([hashtable]$Properties) { - foreach ($Property in $Properties.Keys) { - $this.$Property = $Properties.$Property - } - } - - # Creates a object from a PSCustomObject. GitHubVariable([PSCustomObject]$Object, [string]$Owner, [string]$Repository, [string]$Environment, [GitHubRepository[]]$SelectedRepositories) { $this.Name = $Object.name $this.Value = $Object.value @@ -50,6 +41,7 @@ $this.UpdatedAt = $Object.updated_at $this.Visibility = $Object.visibility $this.SelectedRepositories = $SelectedRepositories + #Set scope based on provided values in Owner, Repository, Environment $this.Scope = if ($Owner -and $Repository -and $Environment) { 'Environment' diff --git a/src/classes/public/Workflows/GitHubWorkflow.ps1 b/src/classes/public/Workflows/GitHubWorkflow.ps1 index df13e31ce..ae58d1fd1 100644 --- a/src/classes/public/Workflows/GitHubWorkflow.ps1 +++ b/src/classes/public/Workflows/GitHubWorkflow.ps1 @@ -32,8 +32,16 @@ GitHubWorkflow() {} GitHubWorkflow([PSCustomObject] $Object, [string] $Owner, [string] $Repository) { - $this.ID = $Object.id - $this.NodeID = $Object.node_id + # From GitHubNode + if ($Object.databaseId) { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + } else { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + } + + # From GitHubWorkflow $this.Name = $Object.name $this.Owner = $Owner $this.Repository = $Repository diff --git a/src/classes/public/Workflows/GitHubWorkflowRun.ps1 b/src/classes/public/Workflows/GitHubWorkflowRun.ps1 index b808ab2a0..f2623ea2a 100644 --- a/src/classes/public/Workflows/GitHubWorkflowRun.ps1 +++ b/src/classes/public/Workflows/GitHubWorkflowRun.ps1 @@ -106,11 +106,19 @@ GitHubWorkflowRun() {} GitHubWorkflowRun([PSCustomObject] $Object) { - $this.ID = $_.id + # From GitHubNode + if ($Object.databaseId) { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + } else { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + } + + # From GitHubWorkflowRun $this.Name = $_.name $this.Owner = [GitHubOwner]::new($Object.repository.owner) $this.Repository = [GitHubRepository]::new($Object.repository) - $this.NodeID = $_.node_id $this.CheckSuiteID = $_.check_suite_id $this.CheckSuiteNodeID = $_.check_suite_node_id $this.HeadBranch = $_.head_branch diff --git a/src/functions/private/Teams/Get-GitHubTeamListByOrg.ps1 b/src/functions/private/Teams/Get-GitHubTeamListByOrg.ps1 index 6f51d32a1..dc2d03070 100644 --- a/src/functions/private/Teams/Get-GitHubTeamListByOrg.ps1 +++ b/src/functions/private/Teams/Get-GitHubTeamListByOrg.ps1 @@ -79,7 +79,7 @@ query(`$org: String!, `$after: String) { $hasNextPage = $true $after = $null - while ($hasNextPage) { + do { # Update the cursor for pagination $variables['after'] = $after @@ -113,7 +113,7 @@ query(`$org: String!, `$after: String) { # Check if there's another page to fetch $hasNextPage = $teams.pageInfo.hasNextPage $after = $teams.pageInfo.endCursor - } + } while ($hasNextPage) } end { diff --git a/src/functions/public/API/Invoke-GitHubGraphQLQuery.ps1 b/src/functions/public/API/Invoke-GitHubGraphQLQuery.ps1 new file mode 100644 index 000000000..a64f75361 --- /dev/null +++ b/src/functions/public/API/Invoke-GitHubGraphQLQuery.ps1 @@ -0,0 +1,74 @@ +function Invoke-GitHubGraphQL { + <# + .SYNOPSIS + Invoke a GraphQL requests against the GitHub GraphQL API + + .DESCRIPTION + Use this function to invoke a GraphQL query and mutations against the GitHub GraphQL API with proper error handling. + + .EXAMPLE + Invoke-GitHubGraphQL -Query $query -Variables $Variables + + .EXAMPLE + Invoke-GitHubGraphQL -Mutation $mutation -Variables $Variables + + .LINK + https://psmodule.io/GitHub/Functions/Gr + + .LINK + [GitHub GraphQL API documentation](https://docs.github.com/graphql) + #> + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [string] $Query, + + [Parameter()] + [hashtable] $Variables, + + [Parameter()] + [object] $Context = (Get-GitHubContext) + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + $Context = Resolve-GitHubContext -Context $Context + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + } + + process { + $body = @{ + query = $Query + variables = $Variables + } + + $inputObject = @{ + Method = 'POST' + APIEndpoint = '/graphql' + Body = $body + Context = $Context + } + + try { + $apiResponse = Invoke-GitHubAPI @inputObject + $graphQLResponse = $apiResponse.Response + + # Handle GraphQL-specific errors (200 OK with errors in response) + if ($graphQLResponse.errors) { + $errorMessages = $graphQLResponse.errors | ForEach-Object { + "GraphQL Error [$($_.type)]: $($_.message)`nPath: $($_.path -join '/')`nLocations: $($_.locations.line):$($_.locations.column)" + } + throw "GraphQL errors occurred:`n$($errorMessages -join "`n`n")" + } + + $graphQLResponse.data + } catch { + $PSCmdlet.ThrowTerminatingError($_) + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/public/GraphQL/Invoke-GitHubGraphQLQuery.ps1 b/src/functions/public/GraphQL/Invoke-GitHubGraphQLQuery.ps1 deleted file mode 100644 index d908028ce..000000000 --- a/src/functions/public/GraphQL/Invoke-GitHubGraphQLQuery.ps1 +++ /dev/null @@ -1,59 +0,0 @@ -function Invoke-GitHubGraphQLQuery { - <# - .SYNOPSIS - Invoke a GraphQL query against the GitHub GraphQL API - - .DESCRIPTION - Use this function to invoke a GraphQL query against the GitHub GraphQL API. - - .EXAMPLE - Invoke-GitHubGraphQLQuery -Query $query -Variables $Variables - - .NOTES - [GitHub GraphQL API documentation](https://docs.github.com/graphql) - #> - [CmdletBinding()] - param( - # The GraphQL query to execute. - [Parameter(Mandatory)] - [string] $Query, - - # The variables to pass to the query. - [Parameter()] - [hashtable] $Variables, - - # The context to run the command in. Used to get the details for the API call. - # Can be either a string or a GitHubContext object. - [Parameter()] - [object] $Context = (Get-GitHubContext) - ) - - begin { - $stackPath = Get-PSCallStackPath - Write-Debug "[$stackPath] - Start" - $Context = Resolve-GitHubContext -Context $Context - Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - } - - process { - $body = @{ - 'query' = $Query - 'variables' = $Variables - } - - $inputObject = @{ - Method = 'POST' - APIEndpoint = '/graphql' - Body = $body - Context = $Context - } - - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } - } - - end { - Write-Debug "[$stackPath] - End" - } -} diff --git a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 new file mode 100644 index 000000000..bdb855e74 --- /dev/null +++ b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 @@ -0,0 +1,168 @@ +function Get-GitHubReleaseQL { + <# + .SYNOPSIS + Get all releases with nested pagination for assets + + .DESCRIPTION + Gets all releases with their complete asset lists using nested pagination through both releases and their assets. + + .EXAMPLE + Get-GitHubRelease -Owner 'github' -Repository 'my-repo' -PerPage 10 -Context $context + #> + [OutputType([GitHubRelease])] + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [string] $Owner, + + [Parameter(Mandatory)] + [string] $Repository, + + [ValidateRange(1, 100)] + [int] $PerPage, + + [Parameter()] + [object] $Context = (Get-GitHubContext) + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + + # Initialize pagination state + $releaseCursor = $null + $releaseQuery = @' +query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: Int!) { + repository(owner: $owner, name: $repository) { + releases(first: $perPage, after: $releaseCursor, orderBy: {field: CREATED_AT, direction: DESC}) { + nodes { + id + databaseId + name + tagName + description + isDraft + isPrerelease + isLatest + createdAt + publishedAt + updatedAt + tag { + name + id + } + tagCommit { + oid + } + url + author { + login + id + databaseId + } + releaseAssets(first: $perPage) { + nodes { + name + downloadCount + contentType + size + url + id + } + pageInfo { + hasNextPage + endCursor + } + } + } + pageInfo { + hasNextPage + endCursor + } + } + } +} +'@ + $assetQuery = @' +query($releaseId: ID!, $assetCursor: String, $perPage: Int!) { + node(id: $releaseId) { + ... on Release { + releaseAssets(first: $perPage, after: $assetCursor) { + nodes { + name + downloadCount + contentType + size + url + id + } + pageInfo { + hasNextPage + endCursor + } + } + } + } +} +'@ + } + + process { + do { + # Get page of releases with first page of assets + $releaseVariables = @{ + owner = $Owner + repository = $Repository + releaseCursor = $releaseCursor + perPage = $PerPage + } + + $result = Invoke-GitHubGraphQLQuery -Query $releaseQuery -Variables $releaseVariables -Context $Context + if (-not $result) { break } + + $repositoryData = $result.data.repository + if (-not $repositoryData) { break } + + $releases = $repositoryData.releases + if (-not $releases) { break } + + # Process each release in current page + foreach ($releaseNode in $releases.nodes) { + $releaseId = $releaseNode.id + $assets = @($releaseNode.releaseAssets.nodes) + $assetPageInfo = $releaseNode.releaseAssets.pageInfo + + # Paginate through remaining asset pages + while ($assetPageInfo.hasNextPage) { + $assetVariables = @{ + releaseId = $releaseId + assetCursor = $assetPageInfo.endCursor + perPage = $PerPage + } + + $assetResult = Invoke-GitHubGraphQLQuery -Query $assetQuery -Variables $assetVariables -Context $Context + if (-not $assetResult) { break } + + $releaseAssets = $assetResult.data.node.releaseAssets + if (-not $releaseAssets) { break } + + $assets += $releaseAssets.nodes + $assetPageInfo = $releaseAssets.pageInfo + } + + # Create complete release object with all assets + $releaseNode.releaseAssets.nodes = $assets + # [GitHubRelease]::new($releaseNode) + $releaseNode + } + + # Update release cursor for next page + $releaseCursor = $releases.pageInfo.endCursor + } while ($releases.pageInfo.hasNextPage) + } + + end { + Write-Debug "[$stackPath] - End" + } +} From 6ffbc607e95df1796ed1e93fb0be15cabfe03ca7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 03:32:18 +0200 Subject: [PATCH 091/224] Add Latest parameter to GitHubRelease constructor for improved release handling --- src/classes/public/Releases/GitHubRelease.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index a5c315e0d..a7b316307 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -107,7 +107,7 @@ class GitHubRelease : GitHubNode { GitHubRelease() {} - GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository) { + GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository, [bool] $Latest) { # From GitHubNode if ($Object.databaseId) { $this.ID = $Object.databaseId From c59cdd035f87776ce71a3789fd04e5a4411dbc23 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 03:39:39 +0200 Subject: [PATCH 092/224] Update Invoke-GitHubAPI documentation to include LINK section and correct example descriptions; rename Invoke-GitHubGraphQL to Invoke-GitHubGraphQLQuery for clarity and consistency. --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 3 +++ src/functions/public/API/Invoke-GitHubGraphQLQuery.ps1 | 9 +++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 76515bfb1..2e48f3e0b 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -24,6 +24,9 @@ filter Invoke-GitHubAPI { Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET -Body @{ state = 'open' } -Accept 'application/vnd.github.v3+json' Gets all open pull requests for the specified repository, filtered by the 'state' parameter, and using the specified 'Accept' header. + + .LINK + https://psmodule.io/GitHub/Functions/API/Invoke-GitHubAPI #> [CmdletBinding(DefaultParameterSetName = 'ApiEndpoint')] param( diff --git a/src/functions/public/API/Invoke-GitHubGraphQLQuery.ps1 b/src/functions/public/API/Invoke-GitHubGraphQLQuery.ps1 index a64f75361..655c4941a 100644 --- a/src/functions/public/API/Invoke-GitHubGraphQLQuery.ps1 +++ b/src/functions/public/API/Invoke-GitHubGraphQLQuery.ps1 @@ -1,4 +1,4 @@ -function Invoke-GitHubGraphQL { +function Invoke-GitHubGraphQLQuery { <# .SYNOPSIS Invoke a GraphQL requests against the GitHub GraphQL API @@ -7,13 +7,10 @@ Use this function to invoke a GraphQL query and mutations against the GitHub GraphQL API with proper error handling. .EXAMPLE - Invoke-GitHubGraphQL -Query $query -Variables $Variables - - .EXAMPLE - Invoke-GitHubGraphQL -Mutation $mutation -Variables $Variables + Invoke-GitHubGraphQLQuery -Query $query -Variables $Variables .LINK - https://psmodule.io/GitHub/Functions/Gr + https://psmodule.io/GitHub/Functions/API/Invoke-GitHubGraphQLQuery .LINK [GitHub GraphQL API documentation](https://docs.github.com/graphql) From dba6453f3a5f59464516aefb383bc63d94e10689 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 03:56:45 +0200 Subject: [PATCH 093/224] Fix PerPage assignment logic in Get-GitHubReleaseQL to ensure correct pagination behavior --- src/functions/public/Releases/Get-GitHubReleaseQL.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 index bdb855e74..99d63d8f5 100644 --- a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 +++ b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 @@ -106,6 +106,8 @@ query($releaseId: ID!, $assetCursor: String, $perPage: Int!) { } } '@ + + $PerPage = $PSBoundParameters.ContainsKey('PerPage') ? $PerPage : $Context.PerPage } process { From a7eaebf3fb2c36f049474be54bfbdd4f1b40d994 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 04:11:22 +0200 Subject: [PATCH 094/224] Refactor Get-GitHubReleaseQL to simplify asset handling and improve query structure --- .../public/Releases/Get-GitHubReleaseQL.ps1 | 32 +++---------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 index 99d63d8f5..c7a3d8cf4 100644 --- a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 +++ b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 @@ -123,40 +123,16 @@ query($releaseId: ID!, $assetCursor: String, $perPage: Int!) { $result = Invoke-GitHubGraphQLQuery -Query $releaseQuery -Variables $releaseVariables -Context $Context if (-not $result) { break } - $repositoryData = $result.data.repository + $repositoryData = $result.repository if (-not $repositoryData) { break } $releases = $repositoryData.releases if (-not $releases) { break } # Process each release in current page - foreach ($releaseNode in $releases.nodes) { - $releaseId = $releaseNode.id - $assets = @($releaseNode.releaseAssets.nodes) - $assetPageInfo = $releaseNode.releaseAssets.pageInfo - - # Paginate through remaining asset pages - while ($assetPageInfo.hasNextPage) { - $assetVariables = @{ - releaseId = $releaseId - assetCursor = $assetPageInfo.endCursor - perPage = $PerPage - } - - $assetResult = Invoke-GitHubGraphQLQuery -Query $assetQuery -Variables $assetVariables -Context $Context - if (-not $assetResult) { break } - - $releaseAssets = $assetResult.data.node.releaseAssets - if (-not $releaseAssets) { break } - - $assets += $releaseAssets.nodes - $assetPageInfo = $releaseAssets.pageInfo - } - - # Create complete release object with all assets - $releaseNode.releaseAssets.nodes = $assets - # [GitHubRelease]::new($releaseNode) - $releaseNode + $releases.nodes | ForEach-Object { + $_ + # [GitHubRelease]::new($_) } # Update release cursor for next page From 47f328fa144e4001ae5434dc0490b2273daac567 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 04:20:17 +0200 Subject: [PATCH 095/224] Remove unused asset query and related code from Get-GitHubReleaseQL to streamline release retrieval process --- .../public/Releases/Get-GitHubReleaseQL.ps1 | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 index c7a3d8cf4..615ece0f4 100644 --- a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 +++ b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 @@ -61,20 +61,6 @@ query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: I id databaseId } - releaseAssets(first: $perPage) { - nodes { - name - downloadCount - contentType - size - url - id - } - pageInfo { - hasNextPage - endCursor - } - } } pageInfo { hasNextPage @@ -83,28 +69,6 @@ query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: I } } } -'@ - $assetQuery = @' -query($releaseId: ID!, $assetCursor: String, $perPage: Int!) { - node(id: $releaseId) { - ... on Release { - releaseAssets(first: $perPage, after: $assetCursor) { - nodes { - name - downloadCount - contentType - size - url - id - } - pageInfo { - hasNextPage - endCursor - } - } - } - } -} '@ $PerPage = $PSBoundParameters.ContainsKey('PerPage') ? $PerPage : $Context.PerPage From 76b8fe5e43d26005057d2996f6bdfd35666a103d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 04:26:21 +0200 Subject: [PATCH 096/224] Add detailed release asset fields to Get-GitHubReleaseQL query for enhanced asset information retrieval --- src/functions/public/Releases/Get-GitHubReleaseQL.ps1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 index 615ece0f4..8b0c8052c 100644 --- a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 +++ b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 @@ -61,6 +61,16 @@ query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: I id databaseId } + releaseAssets(first: $perPage) { + nodes { + name + downloadCount + contentType + size + url + id + } + } } pageInfo { hasNextPage From 58e6228f4ea8c4d1ae95493f4f14f26d34b57009 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 04:46:42 +0200 Subject: [PATCH 097/224] Add additional asset fields to Get-GitHubReleaseQL query for enhanced asset details --- src/functions/public/Releases/Get-GitHubReleaseQL.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 index 8b0c8052c..41f98a330 100644 --- a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 +++ b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 @@ -65,7 +65,11 @@ query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: I nodes { name downloadCount + downloadUrl contentType + createdAt + updatedAt + uploadedBy size url id From 11fe72fcb385f9064f96d67a5fbe0c1d4e94bc7c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 04:54:45 +0200 Subject: [PATCH 098/224] Enhance Get-GitHubReleaseQL query to include detailed uploadedBy fields for better asset information --- src/functions/public/Releases/Get-GitHubReleaseQL.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 index 41f98a330..b0db12e9d 100644 --- a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 +++ b/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 @@ -69,7 +69,12 @@ query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: I contentType createdAt updatedAt - uploadedBy + uploadedBy { + login + name + id + databaseId + } size url id From 976a69dbc9fb42ba02d62edf4875b4ad65d1a37d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 09:54:53 +0200 Subject: [PATCH 099/224] Rename parameter $InputObject to $ReleaseObject in Update-GitHubRelease for clarity and consistency --- examples/Releases/Releases.ps1 | 2 +- src/functions/public/Releases/Update-GitHubRelease.ps1 | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index cd677cd2b..1e3f51a9a 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -28,7 +28,7 @@ $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes $repo | New-GitHubRelease -Tag 'v1.3' -Latest -Name 'test' -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3' | Format-List $repo | Get-GitHubRelease -Tag 'v1.3' | Update-GithubRelease -Notes 'Release notes' -$repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' -Debug +$repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' $repo | New-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 1d528ca81..c461ffe27 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -79,7 +79,7 @@ # The release to update [Parameter(ValueFromPipeline)] - [GitHubRelease] $InputObject, + [GitHubRelease] $ReleaseObject, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -95,7 +95,7 @@ } process { - $ID = $InputObject.ID + $ID = $ReleaseObject.ID if (-not $ID -and -not $Tag) { throw 'You must specify either the ID or the Tag parameter.' @@ -115,7 +115,11 @@ } if ([string]::IsNullOrEmpty($ID) -and -not [string]::IsNullOrEmpty($Tag)) { - $release = Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + $release = if ($ReleaseObject) { + $ReleaseObject + } else { + Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + } if (-not $release) { throw "Release with tag [$Tag] not found in [$Owner/$Repository]." } From 58346bbd5dabe79c491bb2cf22886812c7ed5aa0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 10:49:56 +0200 Subject: [PATCH 100/224] Refactor Get-GitHubReleaseQL function for improved asset pagination and remove deprecated code; enhance Get-GitHubRelease for better user context handling --- examples/Releases/Releases.ps1 | 3 +- src/classes/public/Releases/GitHubRelease.ps1 | 52 ++++++------------- .../private/Releases/Get-GitHubReleaseAll.ps1 | 9 ++-- .../dev}/Get-GitHubReleaseQL.ps1 | 5 -- 4 files changed, 24 insertions(+), 45 deletions(-) rename {src/functions/public/Releases => tools/dev}/Get-GitHubReleaseQL.ps1 (93%) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 1e3f51a9a..3cd684fab 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -16,12 +16,13 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest } 'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease -Latest +Get-GitHubUser | Get-GitHubRepository | Get-GitHubRelease -Latest # Create a new release for a specific repository $repoName = 'mytest' $repo = Get-GitHubUser | Get-GitHubRepository -Name $repoName -$repo | Get-GitHubRelease +$repo | Get-GitHubRelease -Debug $repo | New-GitHubRelease -Tag 'v1.0' -Latest $repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index a7b316307..dc2bcab87 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -38,6 +38,21 @@ # Description: User who uploaded the asset, can be null # Example: GitHubUser object or null [GitHubUser] $Uploader + + GitHubReleaseAsset() {} + + GitHubReleaseAsset([PSCustomObject]$Object) { + $this.Url = $Object.url + $this.Name = $Object.name + $this.Label = $Object.label + $this.State = $Object.state + $this.ContentType = $Object.content_type + $this.Size = $Object.size + $this.Downloads = $Object.downloads + $this.CreatedAt = [datetime]::Parse($Object.created_at) + $this.UpdatedAt = [datetime]::Parse($Object.updated_at) + $this.Uploader = [GitHubUser]::new($Object.uploader) + } } class GitHubRelease : GitHubNode { @@ -109,13 +124,8 @@ class GitHubRelease : GitHubNode { GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository, [bool] $Latest) { # From GitHubNode - if ($Object.databaseId) { - $this.ID = $Object.databaseId - $this.NodeID = $Object.id - } else { - $this.ID = $Object.id - $this.NodeID = $Object.node_id - } + $this.ID = $Object.id + $this.NodeID = $Object.node_id # From GitHubRelease $this.Name = $Object.name @@ -134,31 +144,3 @@ class GitHubRelease : GitHubNode { $this.Assets = $Object.assets | ForEach-Object { [GitHubReleaseAsset]::new($_) } } } - -# DatabaseID : 211843249 -# Name : v0.22.1 -# Repository : GitHub -# Owner : PSModule -# Tag : v0.22.1 -# Notes : Release notes generated using configuration in .github/release.yml at main --> - -# ## What's Changed -# ### Other Changes -# * 🪲 [Fix]: Enhance repository deletion feedback and fix typo by @MariusStorhaug in https://github.com/PSModule/GitHub/pull/345 - - -# **Full Changelog**: https://github.com/PSModule/GitHub/compare/v0.22.0...v0.22.1 -# Target : main -# Latest : True -# Draft : False -# Prerelease : False -# Url : https://github.com/PSModule/GitHub/releases/tag/v0.22.1 -# Author : github-actions[bot] -# CreatedAt : 11.04.2025 09:03:38 -# PublishedAt : 11.04.2025 13:41:34 -# TarballUrl : https://api.github.com/repos/PSModule/GitHub/tarball/v0.22.1 -# ZipballUrl : https://api.github.com/repos/PSModule/GitHub/zipball/v0.22.1 -# Assets : -# Mentions : 1 -# ID : 211843249 -# NodeID : RE_kwDOGiyhrc4MoHix diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index 00ed59b3f..26e288a21 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -63,10 +63,11 @@ try { Invoke-GitHubAPI @inputObject | ForEach-Object { - $_.Response | ForEach-Object { - $isLatest = $_.id -eq $latest.id - [GitHubRelease]::new($_, $Owner, $Repository, $isLatest) - } + $_.Response + # $_.Response | ForEach-Object { + # $isLatest = $_.id -eq $latest.id + # [GitHubRelease]::new($_, $Owner, $Repository, $isLatest) + # } } } catch { return } } diff --git a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 b/tools/dev/Get-GitHubReleaseQL.ps1 similarity index 93% rename from src/functions/public/Releases/Get-GitHubReleaseQL.ps1 rename to tools/dev/Get-GitHubReleaseQL.ps1 index b0db12e9d..64dcb4a92 100644 --- a/src/functions/public/Releases/Get-GitHubReleaseQL.ps1 +++ b/tools/dev/Get-GitHubReleaseQL.ps1 @@ -30,7 +30,6 @@ Write-Debug "[$stackPath] - Start" Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - # Initialize pagination state $releaseCursor = $null $releaseQuery = @' query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: Int!) { @@ -95,7 +94,6 @@ query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: I process { do { - # Get page of releases with first page of assets $releaseVariables = @{ owner = $Owner repository = $Repository @@ -112,13 +110,10 @@ query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: I $releases = $repositoryData.releases if (-not $releases) { break } - # Process each release in current page $releases.nodes | ForEach-Object { - $_ # [GitHubRelease]::new($_) } - # Update release cursor for next page $releaseCursor = $releases.pageInfo.endCursor } while ($releases.pageInfo.hasNextPage) } From 8a044d00d4ac853d4bd2e2717ec7c7e20dd3aeee Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 10:56:27 +0200 Subject: [PATCH 101/224] Add newline at the end of SaveArtifacts.ps1 for better file formatting --- examples/Artifacts/SaveArtifacts.ps1 | 1 + .../private/Releases/Get-GitHubReleaseAll.ps1 | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 27c638df8..0e0de51e5 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -2,3 +2,4 @@ $modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | Save-GitHubArtifact -Path $modulesPath -Extract -Force + diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index 26e288a21..bc3f8eb3d 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -63,11 +63,11 @@ try { Invoke-GitHubAPI @inputObject | ForEach-Object { - $_.Response - # $_.Response | ForEach-Object { - # $isLatest = $_.id -eq $latest.id - # [GitHubRelease]::new($_, $Owner, $Repository, $isLatest) - # } + $_.Response | ForEach-Object { + $item = $_ + $isLatest = $item.id -eq $latest.id + [GitHubRelease]::new($item, $Owner, $Repository, $isLatest) + } } } catch { return } } From 0c6d0ef32e7c91901903de05a9279de471451fd8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 10:59:03 +0200 Subject: [PATCH 102/224] Refactor error handling in Get-GitHubReleaseAll to use finally block for better resource management --- src/functions/private/Releases/Get-GitHubReleaseAll.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index bc3f8eb3d..30e0d6e22 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -69,7 +69,7 @@ [GitHubRelease]::new($item, $Owner, $Repository, $isLatest) } } - } catch { return } + } finally {} } end { From 9e90f51f362897e2e8c5457e456b3503b280c9f9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 11:00:50 +0200 Subject: [PATCH 103/224] Refactor Get-GitHubReleaseAll to simplify response handling and improve error management --- src/functions/private/Releases/Get-GitHubReleaseAll.ps1 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index 30e0d6e22..00ed59b3f 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -64,12 +64,11 @@ try { Invoke-GitHubAPI @inputObject | ForEach-Object { $_.Response | ForEach-Object { - $item = $_ - $isLatest = $item.id -eq $latest.id - [GitHubRelease]::new($item, $Owner, $Repository, $isLatest) + $isLatest = $_.id -eq $latest.id + [GitHubRelease]::new($_, $Owner, $Repository, $isLatest) } } - } finally {} + } catch { return } } end { From 97da298993b1367364161649b446757274b0fa09 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 12:18:06 +0200 Subject: [PATCH 104/224] Add initial Pester tests for GitHub API interactions - Created a template test file for general GitHub API interactions. - Implemented user tests including user retrieval and updates in Users.Tests.ps1. - Added variable management tests in Variables.Tests.ps1, covering organization and repository scopes. - Introduced release artifact tests in Releases.Tests.ps1 to manage GitHub releases. - Ensured all tests utilize Pester version 5.7.1 and include necessary suppressions for known issues. --- .github/PSModule.yml | 3 +- examples/Releases/Releases.ps1 | 8 +- .../public/Releases/Update-GitHubRelease.ps1 | 4 +- {tests => tests copy}/Artifacts.Tests.ps1 | 0 {tests => tests copy}/Environments.Tests.ps1 | 0 {tests => tests copy}/GitHub.Tests.ps1 | 0 {tests => tests copy}/Organizations.Tests.ps1 | 0 {tests => tests copy}/README.md | 0 {tests => tests copy}/Repositories.Tests.ps1 | 0 {tests => tests copy}/Secrets.Tests.ps1 | 0 {tests => tests copy}/TEMPLATE.ps1 | 0 {tests => tests copy}/Users.Tests.ps1 | 0 {tests => tests copy}/Variables.Tests.ps1 | 0 tests/Releases.Tests.ps1 | 74 +++++++++++++++++++ 14 files changed, 82 insertions(+), 7 deletions(-) rename {tests => tests copy}/Artifacts.Tests.ps1 (100%) rename {tests => tests copy}/Environments.Tests.ps1 (100%) rename {tests => tests copy}/GitHub.Tests.ps1 (100%) rename {tests => tests copy}/Organizations.Tests.ps1 (100%) rename {tests => tests copy}/README.md (100%) rename {tests => tests copy}/Repositories.Tests.ps1 (100%) rename {tests => tests copy}/Secrets.Tests.ps1 (100%) rename {tests => tests copy}/TEMPLATE.ps1 (100%) rename {tests => tests copy}/Users.Tests.ps1 (100%) rename {tests => tests copy}/Variables.Tests.ps1 (100%) create mode 100644 tests/Releases.Tests.ps1 diff --git a/.github/PSModule.yml b/.github/PSModule.yml index fda04e6e0..80afa1153 100644 --- a/.github/PSModule.yml +++ b/.github/PSModule.yml @@ -4,7 +4,6 @@ Test: PSModule: Skip: true Module: - Skip: true Windows: Skip: true MacOS: @@ -12,6 +11,8 @@ Test: CodeCoverage: Skip: true PercentTarget: 50 + TestResults: + Skip: true Build: Docs: Skip: true diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index 3cd684fab..e853fb744 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -22,16 +22,16 @@ Get-GitHubUser | Get-GitHubRepository | Get-GitHubRelease -Latest $repoName = 'mytest' $repo = Get-GitHubUser | Get-GitHubRepository -Name $repoName -$repo | Get-GitHubRelease -Debug +$repo | Get-GitHubRelease $repo | New-GitHubRelease -Tag 'v1.0' -Latest $repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' $repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' $repo | New-GitHubRelease -Tag 'v1.3' -Latest -Name 'test' -GenerateReleaseNotes $repo | Get-GitHubRelease -Tag 'v1.3' | Format-List -$repo | Get-GitHubRelease -Tag 'v1.3' | Update-GithubRelease -Notes 'Release notes' -$repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' +$repo | Get-GitHubRelease -Tag 'v1.3' | Update-GithubRelease -Notes 'Release notes1' +$repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' -Debug -$repo | New-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes +$repo | New-GitHubRelease -Tag 'v1.3.2' -Latest -GenerateReleaseNotes -Debug $repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List $repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Debug $repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index c461ffe27..46139888c 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -7,9 +7,9 @@ Users with push access to the repository can edit a release. .EXAMPLE - Update-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Body 'Release notes' + Update-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Notes 'Release notes' - Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the body 'Release notes'. + Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the note 'Release notes'. .NOTES [Update a release](https://docs.github.com/rest/releases/releases#update-a-release) diff --git a/tests/Artifacts.Tests.ps1 b/tests copy/Artifacts.Tests.ps1 similarity index 100% rename from tests/Artifacts.Tests.ps1 rename to tests copy/Artifacts.Tests.ps1 diff --git a/tests/Environments.Tests.ps1 b/tests copy/Environments.Tests.ps1 similarity index 100% rename from tests/Environments.Tests.ps1 rename to tests copy/Environments.Tests.ps1 diff --git a/tests/GitHub.Tests.ps1 b/tests copy/GitHub.Tests.ps1 similarity index 100% rename from tests/GitHub.Tests.ps1 rename to tests copy/GitHub.Tests.ps1 diff --git a/tests/Organizations.Tests.ps1 b/tests copy/Organizations.Tests.ps1 similarity index 100% rename from tests/Organizations.Tests.ps1 rename to tests copy/Organizations.Tests.ps1 diff --git a/tests/README.md b/tests copy/README.md similarity index 100% rename from tests/README.md rename to tests copy/README.md diff --git a/tests/Repositories.Tests.ps1 b/tests copy/Repositories.Tests.ps1 similarity index 100% rename from tests/Repositories.Tests.ps1 rename to tests copy/Repositories.Tests.ps1 diff --git a/tests/Secrets.Tests.ps1 b/tests copy/Secrets.Tests.ps1 similarity index 100% rename from tests/Secrets.Tests.ps1 rename to tests copy/Secrets.Tests.ps1 diff --git a/tests/TEMPLATE.ps1 b/tests copy/TEMPLATE.ps1 similarity index 100% rename from tests/TEMPLATE.ps1 rename to tests copy/TEMPLATE.ps1 diff --git a/tests/Users.Tests.ps1 b/tests copy/Users.Tests.ps1 similarity index 100% rename from tests/Users.Tests.ps1 rename to tests copy/Users.Tests.ps1 diff --git a/tests/Variables.Tests.ps1 b/tests copy/Variables.Tests.ps1 similarity index 100% rename from tests/Variables.Tests.ps1 rename to tests copy/Variables.Tests.ps1 diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 new file mode 100644 index 000000000..425e60406 --- /dev/null +++ b/tests/Releases.Tests.ps1 @@ -0,0 +1,74 @@ +#Requires -Modules @{ ModuleName = 'Pester'; RequiredVersion = '5.7.1' } + +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', '', + Justification = 'Pester grouping syntax: known issue.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidUsingConvertToSecureStringWithPlainText', '', + Justification = 'Used to create a secure string for testing.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidUsingWriteHost', '', + Justification = 'Log outputs to GitHub Actions logs.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidLongLines', '', + Justification = 'Long test descriptions and skip switches' +)] +[CmdletBinding()] +param() + +BeforeAll { + $testName = 'ReleasesTests' + $os = $env:RUNNER_OS + $guid = [guid]::NewGuid().ToString() +} + +Describe 'Artifacts' { + $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" + + Context 'As using on ' -ForEach $authCases { + BeforeAll { + $context = Connect-GitHubAccount @connectParams -PassThru -Silent + LogGroup 'Context' { + Write-Host ($context | Format-Table | Out-String) + } + if ($AuthType -eq 'APP') { + LogGroup 'Context - Installation' { + $context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent + Write-Host ($context | Format-Table | Out-String) + } + } + $repoPrefix = "$testName-$os-$TokenType" + $repoName = "$repoPrefix-$guid" + $variablePrefix = ("$testName`_$os`_$TokenType" -replace '-', '_').ToUpper() + $varName = ("$variablePrefix`_$guid" -replace '-', '_').ToUpper() + $environmentName = "$testName-$os-$TokenType-$guid" + + switch ($OwnerType) { + 'user' { + $repo = New-GitHubRepository -Name $repoName -AllowSquashMerge + } + 'organization' { + $repo = New-GitHubRepository -Owner $owner -Name $repoName -AllowSquashMerge + } + } + LogGroup "Repository - [$repoName]" { + Write-Host ($repo | Format-Table | Out-String) + } + } + + AfterAll { + switch ($OwnerType) { + 'user' { + Get-GitHubRepository -Affiliation owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false + } + 'organization' { + Get-GitHubRepository -Owner $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false + } + } + Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent + } + } +} From 1f1aedbf6cd9ff359bc794a2b26121097f1ea5c5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 12:29:06 +0200 Subject: [PATCH 105/224] Enhance Releases.Tests.ps1 to include a test for New-GitHubRelease and refine repository cleanup logic --- tests/Releases.Tests.ps1 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 425e60406..d65081ccf 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -62,7 +62,7 @@ Describe 'Artifacts' { AfterAll { switch ($OwnerType) { 'user' { - Get-GitHubRepository -Affiliation owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false + Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false } 'organization' { Get-GitHubRepository -Owner $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false @@ -70,5 +70,15 @@ Describe 'Artifacts' { } Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent } + + Context "Releases" { + It 'New-GitHubRelease - Creates a new release' { + $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest + LogGroup "Release" { + Write-Host ($item | Format-Table | Out-String) + } + $item | Should -Not -BeNullOrEmpty + } + } } } From ce70ac0a5507afe62b836ec9247931a27463a748 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 13:17:34 +0200 Subject: [PATCH 106/224] Refactor Resolve-GitHubContext and Resolve-GitHubContextSetting for improved parameter handling and documentation; enhance Invoke-GitHubAPI with additional parameters for token management and retry settings. --- .../Auth/Context/Resolve-GitHubContext.ps1 | 11 ++---- .../Context/Resolve-GitHubContextSetting.ps1 | 37 +++++++++++++++---- src/functions/public/API/Invoke-GitHubAPI.ps1 | 24 ++++++++++-- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 index 60f1b3158..6f3afbdd4 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 @@ -25,10 +25,7 @@ param( # The context to resolve into an object. Used to get the details for the API call. # Can be either a string or a GitHubContext object. - [Parameter( - Mandatory, - ValueFromPipeline - )] + [Parameter(ValueFromPipeline)] [object] $Context ) @@ -45,9 +42,9 @@ $Context = Get-GitHubContext -Context $contextName } - if (-not $Context) { - throw "Please provide a valid context or log in using 'Connect-GitHub'." - } + # if (-not $Context) { + # throw "Please provide a valid context or log in using 'Connect-GitHub'." + # } # TODO: Implement App installation context resolution # switch ($Context.Type) { diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index 4b8d8ec7b..e8d96389f 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -5,8 +5,18 @@ .DESCRIPTION This function retrieves a setting value from the specified GitHub context. If a value is provided, it - returns that value; otherwise, it extracts the value from the given context object. This is useful for - resolving API-related settings dynamically. + returns that value; otherwise, it will extract the value from the given context object if provided. As a last resort, + it will return the default value from the GitHub configuration. This is useful for resolving API-related settings dynamically. + + .EXAMPLE + Resolve-GitHubContextSetting -Name 'Repository' -Value 'MyRepo' + + Output: + ```powershell + MyRepo + ``` + + Returns the provided value 'MyRepo' for the 'Repository' setting. .EXAMPLE Resolve-GitHubContextSetting -Name 'Repository' -Context $GitHubContext @@ -18,6 +28,16 @@ Retrieves the 'Repository' setting from the provided GitHub context object. + .EXAMPLE + Resolve-GitHubContextSetting -Name 'ApiBaseUrl' + + Output: + ```powershell + https://api.github.com + ``` + + Returns the default value for the 'ApiBaseUrl' setting from the GitHub configuration when no value or context is provided. + .LINK https://psmodule.io/GitHub/Functions/Resolve-GitHubContextSetting #> @@ -30,16 +50,19 @@ # The value to use for the setting. If not provided, the value will be resolved from the context. [Parameter()] - [string] $Value, + [object] $Value, # The context to resolve into an object. Used to get the details for the API call. # Can be either a string or a GitHubContext object. - [Parameter(Mandatory)] + [Parameter()] [object] $Context ) - if ([string]::IsNullOrEmpty($Value)) { - $Value = $Context.$Name + if ($Value) { + return $Value + } + if ($Context) { + return $Context.$Name } - return $Value + return $script:GitHub.Config.$Name } diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 2e48f3e0b..73742ef87 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -86,17 +86,25 @@ filter Invoke-GitHubAPI { # Specifies how many times PowerShell retries a connection when a failure code between 400 and 599, inclusive or 304 is received. [Parameter()] - [int] $RetryCount = $script:GitHub.Config.RetryCount, + [int] $RetryCount, # Specifies the interval between retries for the connection when a failure code between 400 and 599, inclusive or 304 is received. # When the failure code is 429 and the response includes the Retry-After property in its headers, the cmdlet uses that value for the retry # interval, even if this parameter is specified. [Parameter()] - [int] $RetryInterval = $script:GitHub.Config.RetryInterval, + [int] $RetryInterval, # The number of results per page for paginated GitHub API responses. [Parameter()] - [int] $PerPage, + [System.Nullable[int]] $PerPage, + + # Ad-hoc token (overrides context token if provided, unless -Anonymous is used) + [Parameter()] + [string] $Token, + + # If specified, ignores all tokens and makes an unauthenticated call + [Parameter()] + [switch] $Anonymous, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -116,11 +124,17 @@ filter Invoke-GitHubAPI { } process { - $Token = $Context.Token + if (-not $Anonymous) { + if (-not $PSBoundParameters.ContainsKey('Token')) { + $Token = $Context.Token + } + } $HttpVersion = Resolve-GitHubContextSetting -Name 'HttpVersion' -Value $HttpVersion -Context $Context $ApiBaseUri = Resolve-GitHubContextSetting -Name 'ApiBaseUri' -Value $ApiBaseUri -Context $Context $ApiVersion = Resolve-GitHubContextSetting -Name 'ApiVersion' -Value $ApiVersion -Context $Context + $RetryCount = Resolve-GitHubContextSetting -Name 'RetryCount' -Value $RetryCount -Context $Context + $RetryInterval = Resolve-GitHubContextSetting -Name 'RetryInterval' -Value $RetryInterval -Context $Context $TokenType = Resolve-GitHubContextSetting -Name 'TokenType' -Value $TokenType -Context $Context [pscustomobject]@{ Token = $Token @@ -179,6 +193,8 @@ filter Invoke-GitHubAPI { } elseif (-not $Body.ContainsKey('per_page') -or $Body['per_page'] -eq 0) { Write-Debug "Setting per_page to the default value in context [$($Context.PerPage)]." $Body['per_page'] = $Context.PerPage + } else { + $Body['per_page'] = $script:GitHub.Config.PerPage } $APICall.Uri = New-Uri -BaseUri $Uri -Query $Body -AsString From aea6f401485fcdb3f106a8a0c16ae1875857470b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 13:25:01 +0200 Subject: [PATCH 107/224] Refactor Invoke-GitHubAPI to conditionally resolve GitHub context based on anonymous parameter --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 73742ef87..b52c684cd 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -115,7 +115,7 @@ filter Invoke-GitHubAPI { begin { $stackPath = Get-PSCallStackPath Write-Debug "[$stackPath] - Start" - $Context = Resolve-GitHubContext -Context $Context + $Context = $Anonymous ? $null : (Resolve-GitHubContext -Context $Context) Write-Debug 'Invoking GitHub API...' Write-Debug 'Parent function parameters:' Get-FunctionParameter -Scope 1 | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ } From d9448ba37f158f570c2381d70fe9889c12b2e840 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 13:33:48 +0200 Subject: [PATCH 108/224] Refactor parameter handling in Resolve-GitHubContext and Invoke-GitHubAPI to set default context retrieval --- src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 | 2 +- src/functions/public/API/Invoke-GitHubAPI.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 index 6f3afbdd4..d06c4452b 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 @@ -26,7 +26,7 @@ # The context to resolve into an object. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter(ValueFromPipeline)] - [object] $Context + [object] $Context = (Get-GitHubContext) ) begin { diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index b52c684cd..f575b2d31 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -109,7 +109,7 @@ filter Invoke-GitHubAPI { # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] - [object] $Context = (Get-GitHubContext) + [object] $Context ) begin { From 8ce39299c15a7f6615a2620f93026c60b44ed578 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 13:36:23 +0200 Subject: [PATCH 109/224] Enhance debugging output in Resolve-GitHubContextSetting; update test descriptions and repository creation logic in Releases.Tests.ps1; add argument completers for Gitignore and License parameters in New-GitHubRepository. --- .../private/Auth/Context/Resolve-GitHubContextSetting.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index e8d96389f..87adaad2a 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -59,10 +59,13 @@ ) if ($Value) { + Write-Debug "[$Name] - [$Value] - Provided value" return $Value } if ($Context) { + Write-Debug "[$Name] - [$Context] - Context value" return $Context.$Name } + Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - Default value" return $script:GitHub.Config.$Name } From 4b99ada94c5c6eabd19511002666f1ef2501b2ee Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 13:44:28 +0200 Subject: [PATCH 110/224] Add Initialize-GitHubConfig function to initialize GitHub configuration --- src/scripts/initialize.ps1 | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/scripts/initialize.ps1 diff --git a/src/scripts/initialize.ps1 b/src/scripts/initialize.ps1 new file mode 100644 index 000000000..7200d5c9a --- /dev/null +++ b/src/scripts/initialize.ps1 @@ -0,0 +1 @@ +Initialize-GitHubConfig From f84d65d8a5fa034e1f1137b4b26df690e2331411 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 13:53:22 +0200 Subject: [PATCH 111/224] Enhance Resolve-GitHubContextSetting with improved debug output for default value retrieval; update GitHub configuration to ensure ApiBaseUri is correctly set based on server URL. --- .../private/Auth/Context/Resolve-GitHubContextSetting.ps1 | 8 ++++++-- src/variables/private/GitHub.ps1 | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index 87adaad2a..9d99a5c7a 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -66,6 +66,10 @@ Write-Debug "[$Name] - [$Context] - Context value" return $Context.$Name } - Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - Default value" - return $script:GitHub.Config.$Name + if ($Script:GitHub.Config.$Name) { + Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - Default value from GitHub.Config" + return $script:GitHub.Config.$Name + } + Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - No value found, returning" + return $null } diff --git a/src/variables/private/GitHub.ps1 b/src/variables/private/GitHub.ps1 index 8b9b77b19..3cbe2be43 100644 --- a/src/variables/private/GitHub.ps1 +++ b/src/variables/private/GitHub.ps1 @@ -10,6 +10,7 @@ DefaultConfig = [GitHubConfig]@{ ID = 'PSModule.GitHub' HostName = ($env:GITHUB_SERVER_URL ?? 'github.com') -replace '^https?://' + $ApiBaseUri = "https://api.$(($env:GITHUB_SERVER_URL ?? 'github.com') -replace '^https?://')" AccessTokenGracePeriodInHours = 4 GitHubAppClientID = 'Iv1.f26b61bc99e69405' OAuthAppClientID = '7204ae9b0580f2cb8288' From c7f229c73dc00750e1e5119731346bda66aa4c3a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 14:01:16 +0200 Subject: [PATCH 112/224] Add ApiBaseUri property to GitHubConfig and correct its assignment in DefaultConfig --- src/classes/public/Config/GitHubConfig.ps1 | 3 +++ src/variables/private/GitHub.ps1 | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/classes/public/Config/GitHubConfig.ps1 b/src/classes/public/Config/GitHubConfig.ps1 index fbd86f1ae..fe130929a 100644 --- a/src/classes/public/Config/GitHubConfig.ps1 +++ b/src/classes/public/Config/GitHubConfig.ps1 @@ -14,6 +14,9 @@ # The default host name. [string] $HostName + # The default base URI for the GitHub API, which is used to make API calls. + [string] $ApiBaseUri + # The default OAuth app client ID. [string] $OAuthAppClientID diff --git a/src/variables/private/GitHub.ps1 b/src/variables/private/GitHub.ps1 index 3cbe2be43..0f73ef395 100644 --- a/src/variables/private/GitHub.ps1 +++ b/src/variables/private/GitHub.ps1 @@ -10,7 +10,7 @@ DefaultConfig = [GitHubConfig]@{ ID = 'PSModule.GitHub' HostName = ($env:GITHUB_SERVER_URL ?? 'github.com') -replace '^https?://' - $ApiBaseUri = "https://api.$(($env:GITHUB_SERVER_URL ?? 'github.com') -replace '^https?://')" + ApiBaseUri = "https://api.$(($env:GITHUB_SERVER_URL ?? 'github.com') -replace '^https?://')" AccessTokenGracePeriodInHours = 4 GitHubAppClientID = 'Iv1.f26b61bc99e69405' OAuthAppClientID = '7204ae9b0580f2cb8288' From ab64c425537a91bde5b25ae06002e00b24c056b0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 14:10:15 +0200 Subject: [PATCH 113/224] Add Initialize-GitHubConfig function to initialize GitHub module configuration --- .../{private => public}/Config/Initialize-GitHubConfig.ps1 | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/functions/{private => public}/Config/Initialize-GitHubConfig.ps1 (100%) diff --git a/src/functions/private/Config/Initialize-GitHubConfig.ps1 b/src/functions/public/Config/Initialize-GitHubConfig.ps1 similarity index 100% rename from src/functions/private/Config/Initialize-GitHubConfig.ps1 rename to src/functions/public/Config/Initialize-GitHubConfig.ps1 From 8a63be85b18dfed8947fa6c513b6913d3a646ce7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 14:12:51 +0200 Subject: [PATCH 114/224] Refactor GitHub module configuration and enhance New-GitHubRepository command with argument completers for Gitignore and License parameters; update tests for improved clarity and functionality. --- .../{public => private}/Config/Initialize-GitHubConfig.ps1 | 0 src/functions/public/API/Invoke-GitHubAPI.ps1 | 7 ++++++- 2 files changed, 6 insertions(+), 1 deletion(-) rename src/functions/{public => private}/Config/Initialize-GitHubConfig.ps1 (100%) diff --git a/src/functions/public/Config/Initialize-GitHubConfig.ps1 b/src/functions/private/Config/Initialize-GitHubConfig.ps1 similarity index 100% rename from src/functions/public/Config/Initialize-GitHubConfig.ps1 rename to src/functions/private/Config/Initialize-GitHubConfig.ps1 diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index f575b2d31..60ace1417 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -115,7 +115,12 @@ filter Invoke-GitHubAPI { begin { $stackPath = Get-PSCallStackPath Write-Debug "[$stackPath] - Start" - $Context = $Anonymous ? $null : (Resolve-GitHubContext -Context $Context) + if ($Anonymous) { + Initialize-GitHubConfig + $Context = $null + } else { + $Context = Resolve-GitHubContext -Context $Context + } Write-Debug 'Invoking GitHub API...' Write-Debug 'Parent function parameters:' Get-FunctionParameter -Scope 1 | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ } From a82a56861af2faf546b3af8bca3fe5f6b685b1a6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 14:15:55 +0200 Subject: [PATCH 115/224] Remove Initialize-GitHubConfig function from the initialization script --- src/scripts/initialize.ps1 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/scripts/initialize.ps1 diff --git a/src/scripts/initialize.ps1 b/src/scripts/initialize.ps1 deleted file mode 100644 index 7200d5c9a..000000000 --- a/src/scripts/initialize.ps1 +++ /dev/null @@ -1 +0,0 @@ -Initialize-GitHubConfig From c77188694cb4099065f52dc163a75371caa0a396 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 14:24:31 +0200 Subject: [PATCH 116/224] Refactor Invoke-GitHubAPI to streamline context resolution; remove unnecessary initialization of GitHub configuration for anonymous calls. --- .../private/Auth/Context/Resolve-GitHubContextSetting.ps1 | 4 ++++ src/functions/public/API/Invoke-GitHubAPI.ps1 | 7 +------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index 9d99a5c7a..b3b57245c 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -70,6 +70,10 @@ Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - Default value from GitHub.Config" return $script:GitHub.Config.$Name } + if ($Script:GitHub.DefaultConfig.$Name) { + Write-Debug "[$Name] - [$($script:GitHub.DefaultConfig.$Name)] - Default value from GitHub.DefaultConfig" + return $script:GitHub.DefaultConfig.$Name + } Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - No value found, returning" return $null } diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 60ace1417..f575b2d31 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -115,12 +115,7 @@ filter Invoke-GitHubAPI { begin { $stackPath = Get-PSCallStackPath Write-Debug "[$stackPath] - Start" - if ($Anonymous) { - Initialize-GitHubConfig - $Context = $null - } else { - $Context = Resolve-GitHubContext -Context $Context - } + $Context = $Anonymous ? $null : (Resolve-GitHubContext -Context $Context) Write-Debug 'Invoking GitHub API...' Write-Debug 'Parent function parameters:' Get-FunctionParameter -Scope 1 | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ } From fb214db60436ceb3df0284019926be1ebcce6030 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 14:25:24 +0200 Subject: [PATCH 117/224] Refactor Invoke-GitHubAPI to initialize GitHub configuration for anonymous calls; streamline context resolution. --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index f575b2d31..60ace1417 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -115,7 +115,12 @@ filter Invoke-GitHubAPI { begin { $stackPath = Get-PSCallStackPath Write-Debug "[$stackPath] - Start" - $Context = $Anonymous ? $null : (Resolve-GitHubContext -Context $Context) + if ($Anonymous) { + Initialize-GitHubConfig + $Context = $null + } else { + $Context = Resolve-GitHubContext -Context $Context + } Write-Debug 'Invoking GitHub API...' Write-Debug 'Parent function parameters:' Get-FunctionParameter -Scope 1 | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ } From 77022868088f9d9440aaad2dc6dce82768cbc3e1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 14:54:27 +0200 Subject: [PATCH 118/224] Refactor Invoke-GitHubAPI to utilize Resolve-GitHubContextSetting for 'PerPage' parameter; simplify context handling. --- .../Context/Resolve-GitHubContextSetting.ps1 | 10 ++++++---- src/functions/public/API/Invoke-GitHubAPI.ps1 | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index b3b57245c..49c6a1c46 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -58,13 +58,15 @@ [object] $Context ) - if ($Value) { + if ($PSBoundParameters.ContainsKey('Value')) { Write-Debug "[$Name] - [$Value] - Provided value" return $Value } - if ($Context) { - Write-Debug "[$Name] - [$Context] - Context value" - return $Context.$Name + if ($PSBoundParameters.ContainsKey('Context')) { + if ($Context.PSObject.Properties.GetEnumerator().Name -contains $Name) { + Write-Debug "[$Name] - [$Context] - Context value" + return $Context.$Name + } } if ($Script:GitHub.Config.$Name) { Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - Default value from GitHub.Config" diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 60ace1417..9b8d9a9f0 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -192,15 +192,16 @@ filter Invoke-GitHubAPI { $Body = @{} } - if ($PSBoundParameters.ContainsKey('PerPage')) { - Write-Debug "Using provided PerPage parameter value [$PerPage]." - $Body['per_page'] = $PerPage - } elseif (-not $Body.ContainsKey('per_page') -or $Body['per_page'] -eq 0) { - Write-Debug "Setting per_page to the default value in context [$($Context.PerPage)]." - $Body['per_page'] = $Context.PerPage - } else { - $Body['per_page'] = $script:GitHub.Config.PerPage - } + $Body['per_page'] = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context + # if ($PSBoundParameters.ContainsKey('PerPage')) { + # Write-Debug "Using provided PerPage parameter value [$PerPage]." + # $Body['per_page'] = $PerPage + # } elseif (-not $Body.ContainsKey('per_page') -or $Body['per_page'] -eq 0) { + # Write-Debug "Setting per_page to the default value in context [$($Context.PerPage)]." + # $Body['per_page'] = $Context.PerPage + # } else { + # $Body['per_page'] = $script:GitHub.Config.PerPage + # } $APICall.Uri = New-Uri -BaseUri $Uri -Query $Body -AsString } elseif ($Body) { From 8c2cbe7d1808442a158ae0a774a0c263c5c63a5b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 15:02:01 +0200 Subject: [PATCH 119/224] Refactor Resolve-GitHubContextSetting to simplify value checking; replace parameter key check with direct value evaluation. --- .../private/Auth/Context/Resolve-GitHubContextSetting.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index 49c6a1c46..5bad54e0a 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -58,7 +58,7 @@ [object] $Context ) - if ($PSBoundParameters.ContainsKey('Value')) { + if ($Value) { Write-Debug "[$Name] - [$Value] - Provided value" return $Value } From c7efa1269f658f2c680827f143b2093e6c7b98a7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 15:11:36 +0200 Subject: [PATCH 120/224] Refactor Resolve-GitHubContextSetting to enhance context validation; ensure context is not null before accessing properties. --- .../private/Auth/Context/Resolve-GitHubContextSetting.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index 5bad54e0a..ae2d4995c 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -62,7 +62,7 @@ Write-Debug "[$Name] - [$Value] - Provided value" return $Value } - if ($PSBoundParameters.ContainsKey('Context')) { + if ($PSBoundParameters.ContainsKey('Context') -and $null -ne $Context) { if ($Context.PSObject.Properties.GetEnumerator().Name -contains $Name) { Write-Debug "[$Name] - [$Context] - Context value" return $Context.$Name From 351b0a50427e8c5a2f317573f76c6aca009f8bfd Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 15:19:13 +0200 Subject: [PATCH 121/224] Refactor Resolve-GitHubContextSetting to improve context validation; replace null checks with string validation for better reliability. --- .../private/Auth/Context/Resolve-GitHubContextSetting.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index ae2d4995c..579e32872 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -62,20 +62,20 @@ Write-Debug "[$Name] - [$Value] - Provided value" return $Value } - if ($PSBoundParameters.ContainsKey('Context') -and $null -ne $Context) { + if ($PSBoundParameters.ContainsKey('Context') -and -not [string]::IsNullOrEmpty($Context)) { if ($Context.PSObject.Properties.GetEnumerator().Name -contains $Name) { Write-Debug "[$Name] - [$Context] - Context value" return $Context.$Name } } - if ($Script:GitHub.Config.$Name) { + if (-not [string]::IsNullOrEmpty($Script:GitHub.Config.$Name)) { Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - Default value from GitHub.Config" return $script:GitHub.Config.$Name } - if ($Script:GitHub.DefaultConfig.$Name) { + if (-not [string]::IsNullOrEmpty($Script:GitHub.DefaultConfig.$Name)) { Write-Debug "[$Name] - [$($script:GitHub.DefaultConfig.$Name)] - Default value from GitHub.DefaultConfig" return $script:GitHub.DefaultConfig.$Name } - Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - No value found, returning" + Write-Debug "[$Name] - No value found, returning" return $null } From dcb8eeb89eedf6009ae57427df70e450ecc341bd Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 15:27:20 +0200 Subject: [PATCH 122/224] Refactor Invoke-GitHubAPI to conditionally set authentication for non-anonymous calls; streamline API call configuration. --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 9b8d9a9f0..efb70e09c 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -177,8 +177,6 @@ filter Invoke-GitHubAPI { Uri = $Uri Method = [string]$Method Headers = $Headers - Authentication = 'Bearer' - Token = $Token ContentType = $ContentType InFile = $UploadFilePath HttpVersion = [string]$HttpVersion @@ -187,6 +185,11 @@ filter Invoke-GitHubAPI { } $APICall | Remove-HashtableEntry -NullOrEmptyValues + if (-not $Anonymous) { + $APICall['Authentication'] = 'Bearer' + $APICall['Token'] = $Token + } + if ($Method -eq 'GET') { if (-not $Body) { $Body = @{} From 33fffc65706561f4119b6a5c893c87a6784e780d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 15:46:21 +0200 Subject: [PATCH 123/224] Refactor Invoke-GitHubAPI to remove the ad-hoc token parameter; streamline authentication handling. --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index efb70e09c..b5e8355aa 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -98,10 +98,6 @@ filter Invoke-GitHubAPI { [Parameter()] [System.Nullable[int]] $PerPage, - # Ad-hoc token (overrides context token if provided, unless -Anonymous is used) - [Parameter()] - [string] $Token, - # If specified, ignores all tokens and makes an unauthenticated call [Parameter()] [switch] $Anonymous, From dc31332f5048efc6149ccc44d7b40fad5857d2b2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 15 Apr 2025 15:49:51 +0200 Subject: [PATCH 124/224] Refactor New-GitHubRepository and Get-GitHubRepository filters; remove unnecessary Requires comments and improve code clarity. Add argument completers for Gitignore and License parameters. --- examples/Artifacts/SaveArtifacts.ps1 | 1 - .../Repositories/Get-GitHubRepository.ps1 | 4 +-- .../Repositories/New-GitHubRepository.ps1 | 26 +------------------ .../public/Repositories/completers.ps1 | 15 +++++++++++ tests/Releases.Tests.ps1 | 10 +++---- 5 files changed, 22 insertions(+), 34 deletions(-) create mode 100644 src/functions/public/Repositories/completers.ps1 diff --git a/examples/Artifacts/SaveArtifacts.ps1 b/examples/Artifacts/SaveArtifacts.ps1 index 0e0de51e5..27c638df8 100644 --- a/examples/Artifacts/SaveArtifacts.ps1 +++ b/examples/Artifacts/SaveArtifacts.ps1 @@ -2,4 +2,3 @@ $modulesPath = $env:PSModulePath -Split [IO.Path]::PathSeparator | Select-Object -First 1 Get-GitHubArtifact -Owner PSModule -Repository GitHub -Name module | Save-GitHubArtifact -Path $modulesPath -Extract -Force - diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index d43b77312..dcefcf6b0 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -1,6 +1,4 @@ -#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } - -filter Get-GitHubRepository { +filter Get-GitHubRepository { <# .SYNOPSIS Gets a specific repository or list of repositories. diff --git a/src/functions/public/Repositories/New-GitHubRepository.ps1 b/src/functions/public/Repositories/New-GitHubRepository.ps1 index 6c2a5a012..0c0cfff90 100644 --- a/src/functions/public/Repositories/New-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/New-GitHubRepository.ps1 @@ -1,6 +1,4 @@ -#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } - -filter New-GitHubRepository { +filter New-GitHubRepository { <# .SYNOPSIS Create a repository for a user or an organization. @@ -256,28 +254,6 @@ filter New-GitHubRepository { [Parameter()] [object] $Context = (Get-GitHubContext) ) - #TODO: Move this to argument completers that are linked to all params with this name. - dynamicparam { - $DynamicParamDictionary = New-DynamicParamDictionary - - $dynParam = @{ - Name = 'Gitignore' - Type = [string] - ValidateSet = Get-GitHubGitignore - DynamicParamDictionary = $DynamicParamDictionary - } - New-DynamicParam @dynParam - - $dynParam2 = @{ - Name = 'License' - Type = [string] - ValidateSet = Get-GitHubLicense | Select-Object -ExpandProperty key - DynamicParamDictionary = $DynamicParamDictionary - } - New-DynamicParam @dynParam2 - - return $DynamicParamDictionary - } begin { $stackPath = Get-PSCallStackPath diff --git a/src/functions/public/Repositories/completers.ps1 b/src/functions/public/Repositories/completers.ps1 new file mode 100644 index 000000000..bf0c699a9 --- /dev/null +++ b/src/functions/public/Repositories/completers.ps1 @@ -0,0 +1,15 @@ +Register-ArgumentCompleter -CommandName 'New-GitHubRepository' -ParameterName 'Gitignore' -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) + $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters + Get-GitHubGitignore | Select-Object -ExpandProperty name | Where-Object { $_ -like "*$wordToComplete*" } | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } +} + +Register-ArgumentCompleter -CommandName 'New-GitHubRepository' -ParameterName 'License' -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) + $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters + Get-GitHubLicense | Select-Object -ExpandProperty name | Where-Object { $_ -like "*$wordToComplete*" } | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } +} diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index d65081ccf..9507edce8 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -25,7 +25,7 @@ BeforeAll { $guid = [guid]::NewGuid().ToString() } -Describe 'Artifacts' { +Describe 'Releases' { $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" Context 'As using on ' -ForEach $authCases { @@ -48,10 +48,10 @@ Describe 'Artifacts' { switch ($OwnerType) { 'user' { - $repo = New-GitHubRepository -Name $repoName -AllowSquashMerge + $repo = New-GitHubRepository -Name $repoName -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio } 'organization' { - $repo = New-GitHubRepository -Owner $owner -Name $repoName -AllowSquashMerge + $repo = New-GitHubRepository -Organization $owner -Name $repoName -AllowSquashMerge } } LogGroup "Repository - [$repoName]" { @@ -71,10 +71,10 @@ Describe 'Artifacts' { Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent } - Context "Releases" { + Context 'Releases' { It 'New-GitHubRelease - Creates a new release' { $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest - LogGroup "Release" { + LogGroup 'Release' { Write-Host ($item | Format-Table | Out-String) } $item | Should -Not -BeNullOrEmpty From f1ba156df5da08905163f4c30f55f0273f9bf5ca Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 11:20:44 +0200 Subject: [PATCH 125/224] Add Pester tests for GitHub API functionalities - Created TEMPLATE.ps1 for standardized test structure. - Implemented Teams.Tests.ps1 to test GitHub Teams API, including team creation, retrieval, updating, and deletion. - Added Users.Tests.ps1 to validate user-related API calls, including user retrieval and updates. - Developed Variables.Tests.ps1 to test GitHub variable management across organizations and repositories. - Removed obsolete Get-GitHubReleaseQL.ps1 script. - Updated GitHubAPI.ps1 to reflect changes in API endpoint for deleting environment secrets. --- .github/PSModule.yml | 17 +- examples/Releases/Releases.ps1 | 60 ------- .../public/Artifacts/GitHubArtifact.ps1 | 12 +- .../public/Environment/GitHubEnvironment.ps1 | 12 +- src/classes/public/Owner/GitHubOwner.ps1 | 9 +- .../Owner/GitHubOwner/GitHubOrganization.ps1 | 9 +- .../public/Owner/GitHubOwner/GitHubUser.ps1 | 9 +- src/classes/public/Releases/GitHubRelease.ps1 | 146 --------------- .../public/Repositories/GitHubRepository.ps1 | 12 +- src/classes/public/Teams/GitHubTeam.ps1 | 4 + .../public/Workflows/GitHubWorkflow.ps1 | 12 +- src/formats/GitHubRelease.Format.ps1xml | 119 ------------- .../Context/Resolve-GitHubContextSetting.ps1 | 1 + .../private/Branches/Get-GitHubBranch.ps1 | 54 ------ .../{ => Releases}/Get-GitHubReleaseAll.ps1 | 31 ++-- .../{ => Releases}/Get-GitHubReleaseByID.ps1 | 22 +-- .../Get-GitHubReleaseByTagName.ps1 | 22 +-- .../Get-GitHubReleaseLatest.ps1 | 18 +- .../private/Teams/Get-GitHubTeamBySlug.ps1 | 112 ++++++------ .../private/Teams/Get-GitHubTeamListByOrg.ps1 | 43 ++--- src/functions/public/API/Invoke-GitHubAPI.ps1 | 27 ++- .../Assets/Get-GitHubReleaseAsset.ps1 | 31 ++-- .../{ => Releases}/Get-GitHubRelease.ps1 | 72 ++++---- .../{ => Releases}/New-GitHubRelease.ps1 | 71 ++++---- .../{ => Releases}/New-GitHubReleaseNote.ps1 | 75 ++++---- .../{ => Releases}/Remove-GitHubRelease.ps1 | 27 +-- .../Releases/Releases/Set-GitHubRelease.ps1 | 124 +++++++++++++ .../public/Releases/Set-GitHubRelease.ps1 | 127 ------------- .../public/Releases/Update-GitHubRelease.ps1 | 168 ------------------ .../Repositories/Get-GitHubRepository.ps1 | 2 +- src/functions/public/Teams/Get-GitHubTeam.ps1 | 29 ++- src/functions/public/Teams/New-GitHubTeam.ps1 | 23 +-- .../public/Teams/Remove-GitHubTeam.ps1 | 26 ++- .../public/Teams/Update-GitHubTeam.ps1 | 21 +-- .../Workflows/Disable-GitHubWorkflow.ps1 | 4 +- .../Workflows/Enable-GitHubWorkflow.ps1 | 4 +- .../public/Workflows/Get-GitHubWorkflow.ps1 | 4 +- .../Workflows/Runs/Get-GitHubWorkflowRun.ps1 | 6 +- .../Runs/Remove-GitHubWorkflowRun.ps1 | 4 +- .../Runs/Restart-GitHubWorkflowRun.ps1 | 4 +- .../Workflows/Runs/Stop-GitHubWorkflowRun.ps1 | 4 +- .../public/Workflows/Start-GitHubWorkflow.ps1 | 8 +- src/types/GitHubTeam.Types.ps1xml | 12 ++ {tests copy => tests}/Artifacts.Tests.ps1 | 0 {tests copy => tests}/Environments.Tests.ps1 | 11 +- {tests copy => tests}/GitHub.Tests.ps1 | 30 ++-- {tests copy => tests}/Organizations.Tests.ps1 | 0 {tests copy => tests}/README.md | 0 tests/Releases.Tests.ps1 | 84 --------- {tests copy => tests}/Repositories.Tests.ps1 | 0 {tests copy => tests}/Secrets.Tests.ps1 | 77 ++++---- {tests copy => tests}/TEMPLATE.ps1 | 0 tests/Teams.Tests.ps1 | 136 ++++++++++++++ {tests copy => tests}/Users.Tests.ps1 | 6 +- {tests copy => tests}/Variables.Tests.ps1 | 70 ++++---- tools/dev/Get-GitHubReleaseQL.ps1 | 124 ------------- tools/utilities/GitHubAPI.ps1 | 4 +- 57 files changed, 692 insertions(+), 1447 deletions(-) delete mode 100644 examples/Releases/Releases.ps1 delete mode 100644 src/classes/public/Releases/GitHubRelease.ps1 delete mode 100644 src/formats/GitHubRelease.Format.ps1xml delete mode 100644 src/functions/private/Branches/Get-GitHubBranch.ps1 rename src/functions/private/Releases/{ => Releases}/Get-GitHubReleaseAll.ps1 (71%) rename src/functions/private/Releases/{ => Releases}/Get-GitHubReleaseByID.ps1 (73%) rename src/functions/private/Releases/{ => Releases}/Get-GitHubReleaseByTagName.ps1 (71%) rename src/functions/private/Releases/{ => Releases}/Get-GitHubReleaseLatest.ps1 (78%) rename src/functions/public/Releases/{ => Releases}/Get-GitHubRelease.ps1 (63%) rename src/functions/public/Releases/{ => Releases}/New-GitHubRelease.ps1 (67%) rename src/functions/public/Releases/{ => Releases}/New-GitHubReleaseNote.ps1 (68%) rename src/functions/public/Releases/{ => Releases}/Remove-GitHubRelease.ps1 (79%) create mode 100644 src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 delete mode 100644 src/functions/public/Releases/Set-GitHubRelease.ps1 delete mode 100644 src/functions/public/Releases/Update-GitHubRelease.ps1 create mode 100644 src/types/GitHubTeam.Types.ps1xml rename {tests copy => tests}/Artifacts.Tests.ps1 (100%) rename {tests copy => tests}/Environments.Tests.ps1 (96%) rename {tests copy => tests}/GitHub.Tests.ps1 (96%) rename {tests copy => tests}/Organizations.Tests.ps1 (100%) rename {tests copy => tests}/README.md (100%) delete mode 100644 tests/Releases.Tests.ps1 rename {tests copy => tests}/Repositories.Tests.ps1 (100%) rename {tests copy => tests}/Secrets.Tests.ps1 (89%) rename {tests copy => tests}/TEMPLATE.ps1 (100%) create mode 100644 tests/Teams.Tests.ps1 rename {tests copy => tests}/Users.Tests.ps1 (95%) rename {tests copy => tests}/Variables.Tests.ps1 (91%) delete mode 100644 tools/dev/Get-GitHubReleaseQL.ps1 diff --git a/.github/PSModule.yml b/.github/PSModule.yml index 80afa1153..ed2d635e9 100644 --- a/.github/PSModule.yml +++ b/.github/PSModule.yml @@ -1,18 +1,3 @@ Test: - SourceCode: - Skip: true - PSModule: - Skip: true - Module: - Windows: - Skip: true - MacOS: - Skip: true CodeCoverage: - Skip: true - PercentTarget: 50 - TestResults: - Skip: true -Build: - Docs: - Skip: true + PercentTarget: 40 diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 deleted file mode 100644 index e853fb744..000000000 --- a/examples/Releases/Releases.ps1 +++ /dev/null @@ -1,60 +0,0 @@ -# Get all the releases for a specific repository -Get-GitHubRelease -Owner PSModule -Repository GitHub - -# Get the latest release for a specific repository -Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest - -# Get all the releases for all repos in the organization -'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease - -# Get the latest releases for all repos in the organization -'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | ForEach-Object -ThrottleLimit ([Environment]::ProcessorCount) -Parallel { - do { - Import-Module -Name GitHub - } until ($? -eq $true) - $_ | Get-GitHubRelease -Latest -} - -'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease -Latest -Get-GitHubUser | Get-GitHubRepository | Get-GitHubRelease -Latest - -# Create a new release for a specific repository -$repoName = 'mytest' - -$repo = Get-GitHubUser | Get-GitHubRepository -Name $repoName -$repo | Get-GitHubRelease -$repo | New-GitHubRelease -Tag 'v1.0' -Latest -$repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' -$repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' -$repo | New-GitHubRelease -Tag 'v1.3' -Latest -Name 'test' -GenerateReleaseNotes -$repo | Get-GitHubRelease -Tag 'v1.3' | Format-List -$repo | Get-GitHubRelease -Tag 'v1.3' | Update-GithubRelease -Notes 'Release notes1' -$repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' -Debug - -$repo | New-GitHubRelease -Tag 'v1.3.2' -Latest -GenerateReleaseNotes -Debug -$repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List -$repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Debug -$repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' -$repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List -Get-GitHubReleaseAsset -Owner MariusStorhaug -Repository mytest -ReleaseID - -$repo | Set-GitHubRelease -Tag 'v1.5' -Latest -Name 'test' -Notes 'Release notes' | Select-Object * -$repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft -$repo | Set-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft -$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft | Select-Object Tag, Name, Latest, Prerelease, Draft -$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft -Prerelease | Select-Object Tag, Name, Latest, Prerelease, Draft -$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Prerelease | Select-Object Tag, Name, Latest, Prerelease, Draft -$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Latest | Select-Object Tag, Name, Latest, Prerelease, Draft -$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' | Select-Object Tag, Name, Latest, Prerelease, Draft - -$repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * - -$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' - - -New-GitHubReleaseNote -Owner PSModule -Repository GitHub -Tag 'v0.22.0' -Target 'main' -PreviousTag 'v0.20.0' | Format-List - -$repo | Get-GitHubRelease | Remove-GitHubRelease - - -$repo | Remove-GitHubRepository -Confirm:$false diff --git a/src/classes/public/Artifacts/GitHubArtifact.ps1 b/src/classes/public/Artifacts/GitHubArtifact.ps1 index 23849b49a..f793696ed 100644 --- a/src/classes/public/Artifacts/GitHubArtifact.ps1 +++ b/src/classes/public/Artifacts/GitHubArtifact.ps1 @@ -38,16 +38,8 @@ GitHubArtifact() {} GitHubArtifact([PSCustomObject]$Object, [string]$Owner, [string]$Repository) { - # From GitHubNode - if ($Object.databaseId) { - $this.ID = $Object.databaseId - $this.NodeID = $Object.id - } else { - $this.ID = $Object.id - $this.NodeID = $Object.node_id - } - - # From GitHubArtifact + $this.ID = $Object.id + $this.NodeID = $Object.node_id $this.Name = $Object.name $this.Owner = $Owner $this.Repository = $Repository diff --git a/src/classes/public/Environment/GitHubEnvironment.ps1 b/src/classes/public/Environment/GitHubEnvironment.ps1 index ead02385f..2345abf17 100644 --- a/src/classes/public/Environment/GitHubEnvironment.ps1 +++ b/src/classes/public/Environment/GitHubEnvironment.ps1 @@ -29,16 +29,8 @@ GitHubEnvironment() {} GitHubEnvironment([PSCustomObject]$Object, [string]$Owner, [string]$Repository) { - # From GitHubNode - if ($Object.databaseId) { - $this.ID = $Object.databaseId - $this.NodeID = $Object.id - } else { - $this.ID = $Object.id - $this.NodeID = $Object.node_id - } - - # From GitHubEnvironment + $this.ID = $Object.id + $this.NodeID = $Object.node_id $this.Name = $Object.name $this.Url = $Object.html_url $this.Owner = $Owner diff --git a/src/classes/public/Owner/GitHubOwner.ps1 b/src/classes/public/Owner/GitHubOwner.ps1 index 48abf5c55..4c56bbc2a 100644 --- a/src/classes/public/Owner/GitHubOwner.ps1 +++ b/src/classes/public/Owner/GitHubOwner.ps1 @@ -71,13 +71,8 @@ GitHubOwner([PSCustomObject]$Object) { # From GitHubNode - if ($Object.databaseId) { - $this.ID = $Object.databaseId - $this.NodeID = $Object.id - } else { - $this.ID = $Object.id - $this.NodeID = $Object.node_id - } + $this.ID = $Object.id + $this.NodeID = $Object.node_id # From GitHubOwner $this.Name = $Object.login diff --git a/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1 b/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1 index c335373c2..bbc1bae4f 100644 --- a/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1 +++ b/src/classes/public/Owner/GitHubOwner/GitHubOrganization.ps1 @@ -138,13 +138,8 @@ GitHubOrganization([PSCustomObject]$Object) { # From GitHubNode - if ($Object.databaseId) { - $this.ID = $Object.databaseId - $this.NodeID = $Object.id - } else { - $this.ID = $Object.id - $this.NodeID = $Object.node_id - } + $this.ID = $Object.id + $this.NodeID = $Object.node_id # From GitHubOwner $this.Name = $Object.login diff --git a/src/classes/public/Owner/GitHubOwner/GitHubUser.ps1 b/src/classes/public/Owner/GitHubOwner/GitHubUser.ps1 index c6dc7c805..b6b1d4664 100644 --- a/src/classes/public/Owner/GitHubOwner/GitHubUser.ps1 +++ b/src/classes/public/Owner/GitHubOwner/GitHubUser.ps1 @@ -14,13 +14,8 @@ GitHubUser([PSCustomObject]$Object) { # From GitHubNode - if ($Object.databaseId) { - $this.ID = $Object.databaseId - $this.NodeID = $Object.id - } else { - $this.ID = $Object.id - $this.NodeID = $Object.node_id - } + $this.ID = $Object.id + $this.NodeID = $Object.node_id # From GitHubOwner $this.Name = $Object.login diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 deleted file mode 100644 index dc2bcab87..000000000 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ /dev/null @@ -1,146 +0,0 @@ -class GitHubReleaseAsset : GitHubNode { - # Description: URL for downloading the asset - # Example: "https://github.com/PSModule/GitHub/releases/download/v0.22.1/asset.zip" - [string] $Url - - # Description: The file name of the asset - # Example: "Team Environment" - [string] $Name - - # Description: Label for the asset, can be null - # Example: null - [string] $Label - - # Description: State of the release asset (e.g., uploaded, open) - # Example: "uploaded" - [string] $State - - # Description: MIME type of the asset - # Example: "application/zip" - [string] $ContentType - - # Description: Size of the asset in bytes - # Example: 1024 - [int] $Size - - # Description: Number of times the asset was downloaded - # Example: 100 - [int] $Downloads - - # Description: Timestamp when the asset was created - # Example: "2025-04-11T09:03:38Z" - [datetime] $CreatedAt - - # Description: Timestamp when the asset was last updated - # Example: "2025-04-11T09:03:38Z" - [datetime] $UpdatedAt - - # Description: User who uploaded the asset, can be null - # Example: GitHubUser object or null - [GitHubUser] $Uploader - - GitHubReleaseAsset() {} - - GitHubReleaseAsset([PSCustomObject]$Object) { - $this.Url = $Object.url - $this.Name = $Object.name - $this.Label = $Object.label - $this.State = $Object.state - $this.ContentType = $Object.content_type - $this.Size = $Object.size - $this.Downloads = $Object.downloads - $this.CreatedAt = [datetime]::Parse($Object.created_at) - $this.UpdatedAt = [datetime]::Parse($Object.updated_at) - $this.Uploader = [GitHubUser]::new($Object.uploader) - } -} - -class GitHubRelease : GitHubNode { - # Name of the release, can be null - # Example: "v0.22.1" - [string] $Name - - # The repository where the environment is. - [string] $Repository - - # The owner of the environment. - [string] $Owner - - # The name of the tag - # Example: "v0.22.1" - [string] $Tag - - # Release notes or changelog, can be null - # Example: "## What's Changed\n### Other Changes\n* Fix: Enhance repository deletion feedback and fix typo..." - [string] $Notes - - # Specifies the commitish value that determines where the Git tag is created from - # Example: "main" - [string] $Target - - # True if the release is the latest release on the repo. - # Example: true - [bool] $Latest - - # True to create a draft (unpublished) release, false to create a published one - # Example: false - [bool] $Draft - - # Whether to identify the release as a prerelease or a full release - # Example: false - [bool] $Prerelease - - # GitHub URL for the release - # Example: "https://github.com/PSModule/GitHub/releases/tag/v0.22.1" - [string] $Url - - # User who authored the release - [GitHubUser] $Author - - # Timestamp when the release was created - # Example: "2025-04-11T09:03:38Z" - [System.Nullable[datetime]] $CreatedAt - - # Timestamp when the release was published, can be null - # Example: "2025-04-11T13:41:34Z" - [System.Nullable[datetime]] $PublishedAt - - # URL for the release tarball, can be null - # Example: "https://api.github.com/repos/PSModule/GitHub/tarball/v0.22.1" - [string] $TarballUrl - - # URL for the release zipball, can be null - # Example: "https://api.github.com/repos/PSModule/GitHub/zipball/v0.22.1" - [string] $ZipballUrl - - # Assets that are uploaded to the release. - [GitHubReleaseAsset[]] $Assets - - # Number of mentions in the release notes - # Example: 1 - [int] $Mentions - - GitHubRelease() {} - - GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository, [bool] $Latest) { - # From GitHubNode - $this.ID = $Object.id - $this.NodeID = $Object.node_id - - # From GitHubRelease - $this.Name = $Object.name - $this.Repository = $Repository - $this.Owner = $Owner - $this.Notes = $Object.body - $this.Url = $Object.html_url - $this.Author = [GitHubUser]::new($Object.author) - $this.Tag = $Object.tag_name - $this.Target = $Object.target_commitish - $this.Latest = $Latest - $this.Draft = $Object.draft - $this.Prerelease = $Object.prerelease - $this.CreatedAt = $Object.created_at - $this.PublishedAt = $Object.published_at - $this.Assets = $Object.assets | ForEach-Object { [GitHubReleaseAsset]::new($_) } - } -} diff --git a/src/classes/public/Repositories/GitHubRepository.ps1 b/src/classes/public/Repositories/GitHubRepository.ps1 index b2fa44fcf..b71ffbdf8 100644 --- a/src/classes/public/Repositories/GitHubRepository.ps1 +++ b/src/classes/public/Repositories/GitHubRepository.ps1 @@ -194,16 +194,8 @@ GitHubRepository() {} GitHubRepository([PSCustomObject]$Object) { - # From GitHubNode - if ($Object.databaseId) { - $this.ID = $Object.databaseId - $this.NodeID = $Object.id - } else { - $this.ID = $Object.id - $this.NodeID = $Object.node_id - } - - # From GitHubRepository + $this.ID = $Object.id + $this.NodeID = $Object.node_id $this.Name = $Object.name $this.Owner = [GitHubOwner]::New($Object.owner) $this.FullName = $Object.full_name diff --git a/src/classes/public/Teams/GitHubTeam.ps1 b/src/classes/public/Teams/GitHubTeam.ps1 index d6dff9c09..07c56b209 100644 --- a/src/classes/public/Teams/GitHubTeam.ps1 +++ b/src/classes/public/Teams/GitHubTeam.ps1 @@ -14,6 +14,10 @@ # The description of the team. [string] $Description + # The HTML URL of the team. + # Example: https://github.com/orgs/github/teams/justice-league + [string] $Url + # The notification setting the team has chosen. # $true = notifications_enabled - team members receive notifications when the team is @mentioned. # $false = notifications_disabled - no one receives notifications. diff --git a/src/classes/public/Workflows/GitHubWorkflow.ps1 b/src/classes/public/Workflows/GitHubWorkflow.ps1 index ae58d1fd1..df13e31ce 100644 --- a/src/classes/public/Workflows/GitHubWorkflow.ps1 +++ b/src/classes/public/Workflows/GitHubWorkflow.ps1 @@ -32,16 +32,8 @@ GitHubWorkflow() {} GitHubWorkflow([PSCustomObject] $Object, [string] $Owner, [string] $Repository) { - # From GitHubNode - if ($Object.databaseId) { - $this.ID = $Object.databaseId - $this.NodeID = $Object.id - } else { - $this.ID = $Object.id - $this.NodeID = $Object.node_id - } - - # From GitHubWorkflow + $this.ID = $Object.id + $this.NodeID = $Object.node_id $this.Name = $Object.name $this.Owner = $Owner $this.Repository = $Repository diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml deleted file mode 100644 index fcdceb8ad..000000000 --- a/src/formats/GitHubRelease.Format.ps1xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - GitHubReleaseTable - - GitHubRelease - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tag - - - Owner - - - Repository - - - Url - - - Latest - - - Prerelease - - - Draft - - - - - - - - GitHubReleaseList - - GitHubRelease - - - - - - - Tag - - - Owner - - - Repository - - - Url - - - Author - - - Target - - - Latest - - - Draft - - - Prerelease - - - CreatedAt - - - PublishedAt - - - Assets - - - Name - - - Notes - - - - - - - - diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index 0b1fc13b2..bcfc2f646 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -81,6 +81,7 @@ Write-Debug "[$Name] - [$($script:GitHub.Config.$Name)] - Default value from GitHub.Config" return $script:GitHub.Config.$Name } + if (-not [string]::IsNullOrEmpty($Script:GitHub.DefaultConfig.$Name)) { Write-Debug "[$Name] - [$($script:GitHub.DefaultConfig.$Name)] - Default value from GitHub.DefaultConfig" return $script:GitHub.DefaultConfig.$Name diff --git a/src/functions/private/Branches/Get-GitHubBranch.ps1 b/src/functions/private/Branches/Get-GitHubBranch.ps1 deleted file mode 100644 index a036ccae7..000000000 --- a/src/functions/private/Branches/Get-GitHubBranch.ps1 +++ /dev/null @@ -1,54 +0,0 @@ -filter Get-GitHubBranchList { - <# - .SYNOPSIS - List branches - - .DESCRIPTION - Lists all branches from a repository - - .EXAMPLE - Get-GitHubBranchList -Owner 'octocat' -Repository 'Hello-World' - - Gets all the branches from the 'Hello-World' repository owned by 'octocat' - - .NOTES - [List branches](https://docs.github.com/rest/branches/branches#list-branches) - #> - [CmdletBinding()] - param( - # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [string] $Owner, - - # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] - [string] $Repository, - - # The context to run the command in. Used to get the details for the API call. - # Can be either a string or a GitHubContext object. - [Parameter(Mandatory)] - [object] $Context - ) - - begin { - $stackPath = Get-PSCallStackPath - Write-Debug "[$stackPath] - Start" - Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - } - - process { - $inputObject = @{ - Method = 'GET' - APIEndpoint = "/repos/$Owner/$Repository/branches" - Context = $Context - } - - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } - } - - end { - Write-Debug "[$stackPath] - End" - } -} diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Releases/Get-GitHubReleaseAll.ps1 similarity index 71% rename from src/functions/private/Releases/Get-GitHubReleaseAll.ps1 rename to src/functions/private/Releases/Releases/Get-GitHubReleaseAll.ps1 index 00ed59b3f..bd5c52614 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Releases/Get-GitHubReleaseAll.ps1 @@ -13,17 +13,11 @@ Gets all the releases for the repository 'hello-world' owned by 'octocat'. - .INPUTS - GitHubRepository + .NOTES + https://docs.github.com/rest/releases/releases#list-releases - .OUTPUTS - GitHubRelease - - .LINK - [List releases](https://docs.github.com/rest/releases/releases#list-releases) #> - [OutputType([GitHubRelease])] - [CmdletBinding()] + [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] @@ -34,7 +28,7 @@ [string] $Repository, # The number of results per page (max 100). - [Parameter()] + [Parameter(ParameterSetName = 'AllUsers')] [ValidateRange(0, 100)] [int] $PerPage, @@ -51,26 +45,21 @@ } process { - $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context + $body = @{ + per_page = $PerPage + } $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases" Body = $body - PerPage = $PerPage Context = $Context } - try { - Invoke-GitHubAPI @inputObject | ForEach-Object { - $_.Response | ForEach-Object { - $isLatest = $_.id -eq $latest.id - [GitHubRelease]::new($_, $Owner, $Repository, $isLatest) - } - } - } catch { return } + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } } - end { Write-Debug "[$stackPath] - End" } diff --git a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 b/src/functions/private/Releases/Releases/Get-GitHubReleaseByID.ps1 similarity index 73% rename from src/functions/private/Releases/Get-GitHubReleaseByID.ps1 rename to src/functions/private/Releases/Releases/Get-GitHubReleaseByID.ps1 index 350bed5f1..dc0c5c030 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 +++ b/src/functions/private/Releases/Releases/Get-GitHubReleaseByID.ps1 @@ -12,16 +12,10 @@ Gets the release with the ID '1234567' for the repository 'hello-world' owned by 'octocat'. - .INPUTS - GitHubRepository + .NOTES + https://docs.github.com/rest/releases/releases#get-a-release - .OUTPUTS - GitHubRelease - - .LINK - [Get a release](https://docs.github.com/rest/releases/releases#get-a-release) #> - [OutputType([GitHubRelease])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -34,6 +28,7 @@ # The unique identifier of the release. [Parameter(Mandatory)] + [Alias('release_id')] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -49,20 +44,15 @@ } process { - $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context - $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" Context = $Context } - try { - Invoke-GitHubAPI @inputObject | ForEach-Object { - $isLatest = $_.Response.id -eq $latest.id - [GitHubRelease]::new($_.Response, $Owner, $Repository, $isLatest) - } - } catch { return } + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } } end { diff --git a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 b/src/functions/private/Releases/Releases/Get-GitHubReleaseByTagName.ps1 similarity index 71% rename from src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 rename to src/functions/private/Releases/Releases/Get-GitHubReleaseByTagName.ps1 index 3854a5ec1..519cf54f4 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 +++ b/src/functions/private/Releases/Releases/Get-GitHubReleaseByTagName.ps1 @@ -11,16 +11,10 @@ Gets the release with the tag 'v1.0.0' for the repository 'hello-world' owned by 'octocat'. - .INPUTS - GitHubRepository + .NOTES + https://docs.github.com/rest/releases/releases#get-a-release-by-tag-name - .OUTPUTS - GitHubRelease - - .LINK - [Get a release by tag name](https://docs.github.com/rest/releases/releases#get-a-release-by-tag-name) #> - [OutputType([GitHubRelease])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -33,6 +27,7 @@ # The name of the tag to get a release from. [Parameter(Mandatory)] + [Alias('tag_name')] [string] $Tag, # The context to run the command in. Used to get the details for the API call. @@ -48,20 +43,15 @@ } process { - $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context - $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases/tags/$Tag" Context = $Context } - try { - Invoke-GitHubAPI @inputObject | ForEach-Object { - $isLatest = $_.Response.id -eq $latest.id - [GitHubRelease]::new($_.Response, $Owner, $Repository, $isLatest) - } - } catch { return } + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } } end { diff --git a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 b/src/functions/private/Releases/Releases/Get-GitHubReleaseLatest.ps1 similarity index 78% rename from src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 rename to src/functions/private/Releases/Releases/Get-GitHubReleaseLatest.ps1 index c699e2589..80f7a6936 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 +++ b/src/functions/private/Releases/Releases/Get-GitHubReleaseLatest.ps1 @@ -13,16 +13,10 @@ Gets the latest releases for the repository 'hello-world' owned by 'octocat'. - .INPUTS - GitHubRepository + .NOTES + https://docs.github.com/rest/releases/releases#get-the-latest-release - .OUTPUTS - GitHubRelease - - .LINK - [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) #> - [OutputType([GitHubRelease])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -52,11 +46,9 @@ Context = $Context } - try { - Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response, $Owner, $Repository, $true) - } - } catch { return } + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } } end { diff --git a/src/functions/private/Teams/Get-GitHubTeamBySlug.ps1 b/src/functions/private/Teams/Get-GitHubTeamBySlug.ps1 index b72a5067e..2860a655a 100644 --- a/src/functions/private/Teams/Get-GitHubTeamBySlug.ps1 +++ b/src/functions/private/Teams/Get-GitHubTeamBySlug.ps1 @@ -13,16 +13,15 @@ [OutputType([GitHubTeam])] [CmdletBinding()] param( - # The slug of the team name. - [Parameter(Mandatory)] - [Alias('team_slug')] - [string] $Slug, - # The organization name. The name is not case sensitive. # If not provided, the owner from the context will be used. - [Parameter()] + [Parameter(Mandatory)] [string] $Organization, + # The slug of the team name. + [Parameter(Mandatory)] + [string] $Slug, + # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter(Mandatory)] @@ -36,72 +35,63 @@ } process { - $query = @" -query(`$org: String!, `$teamSlug: String!) { - organization(login: `$org) { - team(slug: `$teamSlug) { - id + $inputObject = @{ + Query = @' +query($org: String!, $teamSlug: String!) { + organization(login: $org) { + team(slug: $teamSlug) { + id + name + slug + url + combinedSlug + databaseId + description + notificationSetting + privacy + parentTeam { name slug - combinedSlug - databaseId - description - notificationSetting - privacy - parentTeam { + } + childTeams(first: 100) { + nodes { name - slug } - organization { - login - } - childTeams(first: 100) { - nodes { - name - } - } - createdAt - updatedAt } + createdAt + updatedAt } } } -"@ - - # Variables hash that will be sent with the query - $variables = @{ - org = $Organization - teamSlug = $Slug +'@ + Variables = @{ + org = $Organization + teamSlug = $Slug + } + Context = $Context } - - # Send the request to the GitHub GraphQL API - $data = Invoke-GitHubGraphQLQuery -Query $query -Variables $variables -Context $Context - - # Extract team data + $data = Invoke-GitHubGraphQLQuery @inputObject $team = $data.organization.team - - # Output the team object - if (-not $team) { - return + if ($team) { + [GitHubTeam]( + @{ + Name = $team.name + Slug = $team.slug + NodeID = $team.id + Url = $team.url + CombinedSlug = $team.CombinedSlug + ID = $team.DatabaseId + Description = $team.description + Notifications = $team.notificationSetting -eq 'NOTIFICATIONS_ENABLED' ? $true : $false + Visible = $team.privacy -eq 'VISIBLE' ? $true : $false + ParentTeam = $team.parentTeam.slug + Organization = $Organization + ChildTeams = $team.childTeams.nodes.name + CreatedAt = $team.createdAt + UpdatedAt = $team.updatedAt + } + ) } - - [GitHubTeam]( - @{ - Name = $team.name - Slug = $team.slug - NodeID = $team.id - CombinedSlug = $team.CombinedSlug - ID = $team.DatabaseId - Description = $team.description - Notifications = $team.notificationSetting -eq 'NOTIFICATIONS_ENABLED' ? $true : $false - Visible = $team.privacy -eq 'VISIBLE' ? $true : $false - ParentTeam = $team.parentTeam.slug - Organization = $team.organization.login - ChildTeams = $team.childTeams.nodes.name - CreatedAt = $team.createdAt - UpdatedAt = $team.updatedAt - } - ) } end { diff --git a/src/functions/private/Teams/Get-GitHubTeamListByOrg.ps1 b/src/functions/private/Teams/Get-GitHubTeamListByOrg.ps1 index ef1d7fca1..ba10d1e12 100644 --- a/src/functions/private/Teams/Get-GitHubTeamListByOrg.ps1 +++ b/src/functions/private/Teams/Get-GitHubTeamListByOrg.ps1 @@ -8,9 +8,6 @@ .EXAMPLE Get-GitHubTeamListByOrg -Organization 'github' - - .NOTES - [List teams](https://docs.github.com/rest/teams/teams#list-teams) #> [OutputType([GitHubTeam[]])] [CmdletBinding()] @@ -33,14 +30,16 @@ } process { - $query = @" -query(`$org: String!, `$after: String) { - organization(login: `$org) { - teams(first: 100, after: `$after) { + $inputObject = @{ + Query = @' +query($org: String!, $after: String) { + organization(login: $org) { + teams(first: 100, after: $after) { nodes { id name slug + url combinedSlug databaseId description @@ -50,9 +49,6 @@ query(`$org: String!, `$after: String) { name slug } - organization { - login - } childTeams(first: 100) { nodes { name @@ -68,49 +64,40 @@ query(`$org: String!, `$after: String) { } } } -"@ - - # Variables hash that will be sent with the query - $variables = @{ - org = $Organization +'@ + Variables = @{ + org = $Organization + } + Context = $Context } - - # Prepare to store results and handle pagination $hasNextPage = $true $after = $null do { # Update the cursor for pagination - $variables['after'] = $after - - # Send the request to the GitHub GraphQL API - $data = Invoke-GitHubGraphQLQuery -Query $query -Variables $variables -Context $Context - - # Extract team data + $inputObject['Variables']['after'] = $after + $data = Invoke-GitHubGraphQLQuery @inputObject $teams = $data.organization.teams - - # Accumulate the teams in results $teams.nodes | ForEach-Object { [GitHubTeam]( @{ Name = $_.name Slug = $_.slug NodeID = $_.id + Url = $_.url CombinedSlug = $_.combinedSlug ID = $_.databaseId Description = $_.description Notifications = $_.notificationSetting -eq 'NOTIFICATIONS_ENABLED' ? $true : $false Visible = $_.privacy -eq 'VISIBLE' ? $true : $false ParentTeam = $_.parentTeam.slug - Organization = $_.organization.login + Organization = $Organization ChildTeams = $_.childTeams.nodes.name CreatedAt = $_.createdAt UpdatedAt = $_.updatedAt } ) } - - # Check if there's another page to fetch $hasNextPage = $teams.pageInfo.hasNextPage $after = $teams.pageInfo.endCursor } while ($hasNextPage) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 55e3790c8..0cf5d8996 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -101,18 +101,13 @@ filter Invoke-GitHubAPI { # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] - [object] $Context + [object] $Context = (Get-GitHubContext) ) begin { $stackPath = Get-PSCallStackPath Write-Debug "[$stackPath] - Start" - if ($Anonymous) { - Initialize-GitHubConfig - $Context = $null - } else { - $Context = Resolve-GitHubContext -Context $Context - } + $Context = Resolve-GitHubContext -Context $Context Write-Debug 'Invoking GitHub API...' Write-Debug 'Parent function parameters:' Get-FunctionParameter -Scope 1 | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ } @@ -121,11 +116,7 @@ filter Invoke-GitHubAPI { } process { - if (-not $Anonymous) { - if (-not $PSBoundParameters.ContainsKey('Token')) { - $Token = $Context.Token - } - } + $Token = $Context.Token $HttpVersion = Resolve-GitHubContextSetting -Name 'HttpVersion' -Value $HttpVersion -Context $Context $ApiBaseUri = Resolve-GitHubContextSetting -Name 'ApiBaseUri' -Value $ApiBaseUri -Context $Context @@ -324,15 +315,21 @@ filter Invoke-GitHubAPI { Information = $errordetails.documentation_url Status = $failure.Exception.Message StatusCode = $errordetails.status + ErrorTime = Get-Date -Format 's' } - $APICall.HttpVersion = $APICall.HttpVersion.ToString() - $APICall.Headers = $APICall.Headers | ConvertTo-Json - $APICall.Method = $APICall.Method.ToString() $exception = @" ---------------------------------- +Request: +$([pscustomobject]$APICall | Format-List -Property Headers, HttpVersion, Method, Uri, ContentType, Authentication, Token | Out-String) +---------------------------------- +Response Headers: +$($headers | Format-List | Out-String) +---------------------------------- +Error: $($errorResult | Format-List | Out-String) ---------------------------------- + "@ $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( diff --git a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 index 795146394..5106d462b 100644 --- a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 @@ -17,32 +17,35 @@ Gets the release assets for the release with the ID '7654321' for the repository 'octocat/hello-world'. - .INPUTS - GitHubRelease - - .OUTPUTS - GitHubReleaseAsset - - .LINK - https://psmodule.io/GitHub/Functions/Releases/Assets/Get-GitHubReleaseAsset + .NOTES + [Get a release asset](https://docs.github.com/rest/releases/assets#get-a-release-asset) #> - [OutputType([GitHubReleaseAsset])] - [CmdletBinding(DefaultParameterSetName = 'List assets from a release')] + [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] + [Alias('Organization')] + [Alias('User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] [string] $Repository, # The unique identifier of the asset. - [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by ID')] + [Parameter( + Mandatory, + ParameterSetName = 'ID' + )] + [Alias('asset_id')] [string] $ID, # The unique identifier of the release. - [Parameter(Mandatory, ParameterSetName = 'List assets from a release', ValueFromPipelineByPropertyName)] + [Parameter( + Mandatory, + ParameterSetName = 'ReleaseID' + )] + [Alias('release_id')] [string] $ReleaseID, # The context to run the command in. Used to get the details for the API call. diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Releases/Get-GitHubRelease.ps1 similarity index 63% rename from src/functions/public/Releases/Get-GitHubRelease.ps1 rename to src/functions/public/Releases/Releases/Get-GitHubRelease.ps1 index 76d6e81a0..ede7522d6 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Releases/Get-GitHubRelease.ps1 @@ -1,7 +1,7 @@ filter Get-GitHubRelease { <# .SYNOPSIS - List releases. + List releases .DESCRIPTION This returns a list of releases, which does not include regular Git tags that have not been associated with a release. @@ -14,9 +14,9 @@ Gets the releases for the repository 'hello-world' owned by 'octocat'. .EXAMPLE - Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -All + Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Latest - Gets all releases for the repository 'hello-world' owned by 'octocat'. + Gets the latest releases for the repository 'hello-world' owned by 'octocat'. .EXAMPLE Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' @@ -28,28 +28,21 @@ Gets the release with the ID '1234567' for the repository 'hello-world' owned by 'octocat'. - .INPUTS - GitHubRepository - - .OUTPUTS - GitHubRelease - - .LINK - https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ + .NOTES + [List releases](https://docs.github.com/rest/releases/releases#list-releases) + [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSReviewUnusedParameter', 'Latest', - Justification = 'Using the ParameterSetName to determine the context of the command.' - )] - [OutputType([GitHubRelease])] [CmdletBinding(DefaultParameterSetName = 'All')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Latest', Justification = 'Required for parameter set')] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] + [Alias('Organization')] + [Alias('User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] [string] $Repository, # The number of results per page (max 100). @@ -57,16 +50,27 @@ [ValidateRange(0, 100)] [int] $PerPage, - # Get the latest release. - [Parameter(Mandatory, ParameterSetName = 'Latest')] + # Get the latest release only + [Parameter( + Mandatory, + ParameterSetName = 'Latest' + )] [switch] $Latest, # The name of the tag to get a release from. - [Parameter(Mandatory, ParameterSetName = 'Tag')] + [Parameter( + Mandatory, + ParameterSetName = 'Tag' + )] + [Alias('tag_name')] [string] $Tag, # The unique identifier of the release. - [Parameter(Mandatory, ParameterSetName = 'ID')] + [Parameter( + Mandatory, + ParameterSetName = 'ID' + )] + [Alias('release_id')] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -83,31 +87,21 @@ } process { - $params = @{ - Owner = $Owner - Repository = $Repository - Context = $Context - } - Write-Debug "ParameterSet: $($PSCmdlet.ParameterSetName)" switch ($PSCmdlet.ParameterSetName) { 'All' { - Get-GitHubReleaseAll @params -PerPage $PerPage + Get-GitHubReleaseAll -Owner $Owner -Repository $Repository -PerPage $PerPage -Context $Context + } + 'Latest' { + Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context } 'Tag' { - $release = Get-GitHubReleaseByTagName @params -Tag $Tag - if ($release) { - $release - } else { - Get-GithubReleaseAll @params -PerPage $PerPage | Where-Object { $_.Tag -eq $Tag } - } + Get-GitHubReleaseByTagName -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context } 'ID' { - Get-GitHubReleaseByID @params -ID $ID - } - 'Latest' { - Get-GitHubReleaseLatest @params + Get-GitHubReleaseByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context } } + } end { diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/Releases/New-GitHubRelease.ps1 similarity index 67% rename from src/functions/public/Releases/New-GitHubRelease.ps1 rename to src/functions/public/Releases/Releases/New-GitHubRelease.ps1 index 0c7904c65..021a3900a 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Releases/New-GitHubRelease.ps1 @@ -11,43 +11,38 @@ and "[Dealing with secondary rate limits](https://docs.github.com/rest/guides/best-practices-for-integrators#dealing-with-secondary-rate-limits)" for details. .EXAMPLE - New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Target 'main' -Notes 'Release notes' + New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -TagName 'v1.0.0' -TargetCommitish 'main' -Body 'Release notes' - Creates a release for the repository 'octocat/hello-world' on the 'main' branch with the tag 'v1.0.0'. + Creates a release for the repository 'octocat/hello-world' with the tag 'v1.0.0' and the target commitish 'main'. - .INPUTS - GitHubRepository - - .OUTPUTS - GitHubRelease - - .LINK - https://psmodule.io/GitHub/Functions/Releases/New-GitHubRelease/ - - .LINK + .NOTES [Create a release](https://docs.github.com/rest/releases/releases#create-a-release) #> - [OutputType([GitHubRelease])] + [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] - [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] + [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] + [Alias('Organization')] + [Alias('User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] [string] $Repository, # The name of the tag. [Parameter(Mandatory)] - [string] $Tag, + [Alias('tag_name')] + [string] $TagName, - # Specifies the reference value that determines where the Git tag is created from. + # Specifies the commitish value that determines where the Git tag is created from. # Can be any branch or commit SHA. Unused if the Git tag already exists. # API Default: the repository's default branch. [Parameter()] - [string] $Target = 'main', + [Alias('target_commitish')] + [string] $TargetCommitish = 'main', # The name of the release. [Parameter()] @@ -55,33 +50,33 @@ # Text describing the contents of the tag. [Parameter()] - [string] $Notes, + [string] $Body, # Whether the release is a draft. - [Parameter(ParameterSetName = 'Not latest')] + [Parameter()] [switch] $Draft, # Whether to identify the release as a prerelease. - [Parameter(ParameterSetName = 'Not latest')] + [Parameter()] [switch] $Prerelease, # If specified, a discussion of the specified category is created and linked to the release. # The value must be a category that already exists in the repository. # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). [Parameter()] + [Alias('discussion_category_name')] [string] $DiscussionCategoryName, - # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, - # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. + # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise,a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. [Parameter()] + [Alias('generate_release_notes')] [switch] $GenerateReleaseNotes, - # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. - # If not specified the latest release is determined based on the release creation date and higher semantic version. - # If set to true, the release will be set as the latest release for the repository. - # If set to false, the release will not be set as the latest release for the repository. - [Parameter(ParameterSetName = 'Set latest')] - [switch] $Latest, + # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation date and higher semantic version. + [Parameter()] + [Alias('make_latest')] + [ValidateSet('true', 'false', 'legacy')] + [string] $MakeLatest = 'true', # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -98,15 +93,15 @@ process { $body = @{ - tag_name = $Tag - target_commitish = $Target + tag_name = $TagName + target_commitish = $TargetCommitish name = $Name - body = $Notes + body = $Body discussion_category_name = $DiscussionCategoryName - generate_release_notes = [bool]$GenerateReleaseNotes - make_latest = ([bool]$Latest).ToString().ToLower() - draft = [bool]$Draft - prerelease = [bool]$Prerelease + make_latest = $MakeLatest + generate_release_notes = $GenerateReleaseNotes + draft = $Draft + prerelease = $Prerelease } $body | Remove-HashtableEntry -NullOrEmptyValues @@ -119,7 +114,7 @@ if ($PSCmdlet.ShouldProcess("$Owner/$Repository", 'Create a release')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response , $Owner, $Repository, $Latest) + Write-Output $_.Response } } } diff --git a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/Releases/New-GitHubReleaseNote.ps1 similarity index 68% rename from src/functions/public/Releases/New-GitHubReleaseNote.ps1 rename to src/functions/public/Releases/Releases/New-GitHubReleaseNote.ps1 index 6779c8d88..849b1ed34 100644 --- a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/Releases/New-GitHubReleaseNote.ps1 @@ -1,18 +1,19 @@ filter New-GitHubReleaseNote { <# .SYNOPSIS - Generate release notes content for a release. + List releases .DESCRIPTION - Generate a name and body describing a [release](https://docs.github.com/rest/releases/releases#get-a-release). The body content will be - markdown formatted and contain information like the changes since last release and users who contributed. The generated release notes are not - saved anywhere. They are intended to be generated and used when creating a new release. + Generate a name and body describing a [release](https://docs.github.com/rest/releases/releases#get-a-release). + The body content will be Markdown formatted and contain information like + the changes since last release and users who contributed. The generated release notes are not saved anywhere. They are + intended to be generated and used when creating a new release. .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - Tag = 'v1.0.0' + Owner = 'octocat' + Repo = 'hello-world' + TagName = 'v1.0.0' } New-GitHubReleaseNote @params @@ -22,10 +23,10 @@ .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - Tag = 'v1.0.0' - Target = 'main' + Owner = 'octocat' + Repo = 'hello-world' + TagName = 'v1.0.0' + TargetCommitish = 'main' } New-GitHubReleaseNote @params @@ -36,9 +37,9 @@ $params = @{ Owner = 'octocat' Repo = 'hello-world' - Tag = 'v1.0.0' - Target = 'main' - PreviousTag = 'v0.9.2' + TagName = 'v1.0.0' + TargetCommitish = 'main' + PreviousTagName = 'v0.9.2' ConfigurationFilePath = '.github/custom_release_config.yml' } New-GitHubReleaseNote @params @@ -47,19 +48,8 @@ The release notes will be based on the changes between the tags 'v0.9.2' and 'v1.0.0' and generated based on the configuration file located in the repository at '.github/custom_release_config.yml'. - .OUTPUTS - pscustomobject - .NOTES - The returned object contains the following properties: - - Name: The name of the release. - - Notes: The body of the release notes. - - .LINK - https://psmodule.io/GitHub/Functions/Releases/New-GitHubReleaseNote/ - - .LINK - [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#generate-release-notes-content-for-a-release) + [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#list-releases) #> [OutputType([pscustomobject])] [Alias('Generate-GitHubReleaseNotes')] @@ -67,32 +57,39 @@ [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] + [Alias('Organization')] + [Alias('User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] [string] $Repository, # The tag name for the release. This can be an existing tag or a new one. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] - [string] $Tag, + [Parameter(Mandatory)] + [Alias('tag_name')] + [string] $TagName, # Specifies the commitish value that will be the target for the release's tag. # Required if the supplied tag_name does not reference an existing tag. # Ignored if the tag_name already exists. [Parameter()] - [string] $Target, + [Alias('target_commitish')] + [string] $TargetCommitish, # The name of the previous tag to use as the starting point for the release notes. # Use to manually specify the range for the set of changes considered as part this release. [Parameter()] - [string] $PreviousTag, + [Alias('previous_tag_name')] + [string] $PreviousTagName, + # Specifies a path to a file in the repository containing configuration settings used for generating the release notes. # If unspecified, the configuration file located in the repository at '.github/release.yml' or '.github/release.yaml' will be used. # If that is not present, the default configuration will be used. [Parameter()] + [Alias('configuration_file_path')] [string] $ConfigurationFilePath, # The context to run the command in. Used to get the details for the API call. @@ -110,9 +107,9 @@ process { $body = @{ - tag_name = $Tag - target_commitish = $Target - previous_tag_name = $PreviousTag + tag_name = $TagName + target_commitish = $TargetCommitish + previous_tag_name = $PreviousTagName configuration_file_path = $ConfigurationFilePath } $body | Remove-HashtableEntry -NullOrEmptyValues @@ -121,15 +118,11 @@ Method = 'POST' APIEndpoint = "/repos/$Owner/$Repository/releases/generate-notes" Body = $body - Context = $Context } - if ($PSCmdlet.ShouldProcess("release notes for release on $Owner/$Repository", 'Create')) { + if ($PSCmdlet.ShouldProcess("$Owner/$Repository", 'Create release notes')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - [PSCustomObject]@{ - Name = $_.Response.name - Notes = $_.Response.body - } + Write-Output $_.Response } } } diff --git a/src/functions/public/Releases/Remove-GitHubRelease.ps1 b/src/functions/public/Releases/Releases/Remove-GitHubRelease.ps1 similarity index 79% rename from src/functions/public/Releases/Remove-GitHubRelease.ps1 rename to src/functions/public/Releases/Releases/Remove-GitHubRelease.ps1 index fcf93b6a4..1184c427e 100644 --- a/src/functions/public/Releases/Remove-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Releases/Remove-GitHubRelease.ps1 @@ -11,28 +11,27 @@ Deletes the release with the ID '1234567' for the repository 'octocat/hello-world'. - .INPUTS - GitHubRelease - - .LINK - https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ - - .LINK + .NOTES [Delete a release](https://docs.github.com/rest/releases/releases#delete-a-release) #> - [OutputType([void])] + [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] + [Alias('Organization')] + [Alias('User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter(Mandatory)] [string] $Repository, # The unique identifier of the release. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Parameter( + Mandatory + )] + [Alias('release_id')] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -55,8 +54,10 @@ Context = $Context } - if ($PSCmdlet.ShouldProcess("Release with ID [$ID] in [$Owner/$Repository]", 'Delete')) { - $null = Invoke-GitHubAPI @inputObject + if ($PSCmdlet.ShouldProcess("Release with ID [$ID] in [$Owner/$Repository]", 'DELETE')) { + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } } } diff --git a/src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 new file mode 100644 index 000000000..1559ef234 --- /dev/null +++ b/src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 @@ -0,0 +1,124 @@ +filter Set-GitHubRelease { + <# + .SYNOPSIS + Update a release + + .DESCRIPTION + Users with push access to the repository can edit a release. + + .EXAMPLE + Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Body 'Release notes' + + Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the body 'Release notes'. + + .NOTES + [Update a release](https://docs.github.com/rest/releases/releases#update-a-release) + #> + [OutputType([pscustomobject])] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] + [CmdletBinding(SupportsShouldProcess)] + param( + # The account owner of the repository. The name is not case sensitive. + [Parameter(Mandatory)] + [Alias('Organization')] + [Alias('User')] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Repository, + + # The unique identifier of the release. + [Parameter(Mandatory)] + [Alias('release_id')] + [string] $ID, + + # The name of the tag. + [Parameter()] + [Alias('tag_name')] + [string] $TagName, + + # Specifies the commitish value that determines where the Git tag is created from. + # Can be any branch or commit SHA. Unused if the Git tag already exists. + # API Default: the repository's default branch. + [Parameter()] + [Alias('target_commitish')] + [string] $TargetCommitish, + + # The name of the release. + [Parameter()] + [string] $Name, + + # Text describing the contents of the tag. + [Parameter()] + [string] $Body, + + # Whether the release is a draft. + [Parameter()] + [switch] $Draft, + + # Whether to identify the release as a prerelease. + [Parameter()] + [switch] $Prerelease, + + # If specified, a discussion of the specified category is created and linked to the release. + # The value must be a category that already exists in the repository. + # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). + [Parameter()] + [Alias('discussion_category_name')] + [string] $DiscussionCategoryName, + + # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. + # Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation + # date and higher semantic version. + [Parameter()] + [Alias('make_latest')] + [ValidateSet('true', 'false', 'legacy')] + [string] $MakeLatest = 'true', + + # The context to run the command in. Used to get the details for the API call. + # Can be either a string or a GitHubContext object. + [Parameter()] + [object] $Context = (Get-GitHubContext) + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + $Context = Resolve-GitHubContext -Context $Context + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + } + + process { + $body = @{ + tag_name = $TagName + target_commitish = $TargetCommitish + name = $Name + body = $Body + discussion_category_name = $DiscussionCategoryName + make_latest = $MakeLatest + draft = $Draft + prerelease = $Prerelease + } + $body | Remove-HashtableEntry -NullOrEmptyValues + + $inputObject = @{ + Method = 'PATCH' + APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" + Body = $body + Context = $Context + } + + if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} + +#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 deleted file mode 100644 index 5c86cabeb..000000000 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ /dev/null @@ -1,127 +0,0 @@ -filter Set-GitHubRelease { - <# - .SYNOPSIS - Creates or updates a release. - - .DESCRIPTION - - - .EXAMPLE - Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Target 'main' -Notes 'Release notes' - - .INPUTS - GitHubRepository - - .OUTPUTS - GitHubRelease - - .LINK - https://psmodule.io/GitHub/Functions/Releases/Set-GitHubRelease/ - #> - [OutputType([GitHubRelease])] - [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] - param( - # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] - [string] $Owner, - - # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] - [string] $Repository, - - # The name of the tag. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] - [string] $Tag, - - # Specifies the reference value that determines where the Git tag is created from. - # Can be any branch or commit SHA. Unused if the Git tag already exists. - # API Default: the repository's default branch. - [Parameter()] - [string] $Target = 'main', - - # The name of the release. - [Parameter()] - [string] $Name = '', - - # Text describing the contents of the tag. - [Parameter()] - [string] $Notes = '', - - # Whether the release is a draft. - [Parameter(ParameterSetName = 'Not latest')] - [switch] $Draft, - - # Whether to identify the release as a prerelease. - [Parameter(ParameterSetName = 'Not latest')] - [switch] $Prerelease, - - # If specified, a discussion of the specified category is created and linked to the release. - # The value must be a category that already exists in the repository. - [Parameter()] - [string] $DiscussionCategoryName, - - # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, - # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. - [Parameter()] - [switch] $GenerateReleaseNotes, - - # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting - # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. - [Parameter(Mandatory, ParameterSetName = 'Set latest')] - [switch] $Latest, - - # The context to run the command in. Used to get the details for the API call. - # Can be either a string or a GitHubContext object. - [Parameter()] - [object] $Context = (Get-GitHubContext) - ) - - begin { - $stackPath = Get-PSCallStackPath - Write-Debug "[$stackPath] - Start" - $Context = Resolve-GitHubContext -Context $Context - Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - } - - process { - $scope = @{ - Owner = $Owner - Repository = $Repository - Context = $Context - } - - $params = @{ - Tag = $Tag - Target = $Target - Name = $Name - Notes = $Notes - GenerateReleaseNotes = [bool]$GenerateReleaseNotes - DiscussionCategoryName = $DiscussionCategoryName - } - - switch ($PSCmdlet.ParameterSetName) { - 'Set latest' { - $params['Latest'] = [bool]$Latest - } - 'Not latest' { - $params['Draft'] = [bool]$Draft - $params['Prerelease'] = [bool]$Prerelease - } - } - - $release = Get-GitHubRelease @scope -Tag $Tag - if ($release) { - $ID = $release.ID - $params['ID'] = $ID - Update-GitHubRelease @scope @params -Declare - } else { - New-GitHubRelease @scope @params - } - } - - end { - Write-Debug "[$stackPath] - End" - } -} - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 deleted file mode 100644 index 46139888c..000000000 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ /dev/null @@ -1,168 +0,0 @@ -filter Update-GitHubRelease { - <# - .SYNOPSIS - Update a release - - .DESCRIPTION - Users with push access to the repository can edit a release. - - .EXAMPLE - Update-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Notes 'Release notes' - - Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the note 'Release notes'. - - .NOTES - [Update a release](https://docs.github.com/rest/releases/releases#update-a-release) - #> - [OutputType([pscustomobject])] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] - [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] - param( - # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] - [string] $Owner, - - # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] - [string] $Repository, - - # The unique identifier of the release. - [Parameter()] - [string] $ID, - - # The name of the tag. - [Parameter()] - [string] $Tag, - - # Specifies the commitish value that determines where the Git tag is created from. - # Can be any branch or commit SHA. Unused if the Git tag already exists. - # API Default: the repository's default branch. - [Parameter()] - [string] $Target, - - # The name of the release. - [Parameter()] - [string] $Name, - - # Text describing the contents of the tag. - [Parameter()] - [string] $Notes, - - # Whether the release is a draft. - [Parameter(ParameterSetName = 'Not latest')] - [switch] $Draft, - - # Whether to identify the release as a prerelease. - [Parameter(ParameterSetName = 'Not latest')] - [switch] $Prerelease, - - # If specified, a discussion of the specified category is created and linked to the release. - # The value must be a category that already exists in the repository. - # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). - [Parameter()] - [string] $DiscussionCategoryName, - - # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, - # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. - [Parameter()] - [switch] $GenerateReleaseNotes, - - # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting - # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. - [Parameter(Mandatory, ParameterSetName = 'Set latest')] - [switch] $Latest, - - # Takes all parameters and updates the release with the provided _AND_ the default values of the non-provided parameters. - # Used for Set-GitHubRelease. - [Parameter()] - [switch] $Declare, - - # The release to update - [Parameter(ValueFromPipeline)] - [GitHubRelease] $ReleaseObject, - - # The context to run the command in. Used to get the details for the API call. - # Can be either a string or a GitHubContext object. - [Parameter()] - [object] $Context = (Get-GitHubContext) - ) - - begin { - $stackPath = Get-PSCallStackPath - Write-Debug "[$stackPath] - Start" - $Context = Resolve-GitHubContext -Context $Context - Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - } - - process { - $ID = $ReleaseObject.ID - - if (-not $ID -and -not $Tag) { - throw 'You must specify either the ID or the Tag parameter.' - } - - if ($GenerateReleaseNotes) { - $generated = New-GitHubReleaseNote -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context - $Name = -not [string]::IsNullOrEmpty($Name) ? $Name : $generated.Name - $Notes = -not [string]::IsNullOrEmpty($Notes) ? $Notes, $generated.Notes -join "`n" : $generated.Notes - } - - $body = @{ - tag_name = $Tag - target_commitish = $Target - name = $Name - body = $Notes - } - - if ([string]::IsNullOrEmpty($ID) -and -not [string]::IsNullOrEmpty($Tag)) { - $release = if ($ReleaseObject) { - $ReleaseObject - } else { - Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context - } - if (-not $release) { - throw "Release with tag [$Tag] not found in [$Owner/$Repository]." - } - $ID = $release.ID - $body.Remove('tag_name') - } - - $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context - if ($repo.HasDiscussions) { - $body['discussion_category_name'] = $DiscussionCategoryName - } - if (-not $Declare) { - $body | Remove-HashtableEntry -NullOrEmptyValues - } - - if ($Latest) { - $body['make_latest'] = [bool]$Latest.ToString().ToLower() - $body['prerelease'] = $false - $body['draft'] = $false - } - if ($Draft -or $Prerelease) { - $body['make_latest'] = $false - $body['prerelease'] = [bool]$Prerelease - $body['draft'] = [bool]$Draft - } - - $inputObject = @{ - Method = 'PATCH' - APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" - Body = $body - Context = $Context - } - - if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { - Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response , $Owner, $Repository, $Latest) - } - } - } - - end { - Write-Debug "[$stackPath] - End" - } -} - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Repositories/Get-GitHubRepository.ps1 b/src/functions/public/Repositories/Get-GitHubRepository.ps1 index 19013936d..42f8ff8b4 100644 --- a/src/functions/public/Repositories/Get-GitHubRepository.ps1 +++ b/src/functions/public/Repositories/Get-GitHubRepository.ps1 @@ -26,7 +26,7 @@ Gets the repositories for the specified user. .EXAMPLE - Get-GitHubRepository -Owner 'github' -Name 'octocat' + Get-GitHubRepository -Organization 'github' -Name 'octocat' Gets the specified repository. diff --git a/src/functions/public/Teams/Get-GitHubTeam.ps1 b/src/functions/public/Teams/Get-GitHubTeam.ps1 index 6560786b1..6c692228e 100644 --- a/src/functions/public/Teams/Get-GitHubTeam.ps1 +++ b/src/functions/public/Teams/Get-GitHubTeam.ps1 @@ -17,23 +17,25 @@ Get-GitHubTeam -Organization 'github' -Slug 'my-team-name' Gets the team with the slug 'my-team-name' in the `github` organization. + + .NOTES + [List teams](https://docs.github.com/rest/teams/teams#list-teams) + + .LINK + https://psmodule.io/GitHub/Functions/Teams/Get-GitHubTeam #> [OutputType([GitHubTeam])] - [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] + [CmdletBinding(DefaultParameterSetName = 'List all teams in an organization')] param( - # The slug of the team name. - [Parameter( - Mandatory, - ParameterSetName = 'BySlug' - )] - [Alias('team_slug')] - [string] $Slug, - # The organization name. The name is not case sensitive. # If not provided, the owner from the context will be used. - [Parameter()] + [Parameter(Mandatory)] [string] $Organization, + # The slug of the team name. + [Parameter(Mandatory, ParameterSetName = 'BySlug')] + [string] $Slug, + # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] @@ -45,11 +47,6 @@ Write-Debug "[$stackPath] - Start" $Context = Resolve-GitHubContext -Context $Context Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - - if ([string]::IsNullOrEmpty($Organization)) { - $Organization = $Context.Owner - } - Write-Debug "Organization: [$Organization]" } process { @@ -71,5 +68,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Teams/New-GitHubTeam.ps1 b/src/functions/public/Teams/New-GitHubTeam.ps1 index 2ec5e4dfc..dbb14f17d 100644 --- a/src/functions/public/Teams/New-GitHubTeam.ps1 +++ b/src/functions/public/Teams/New-GitHubTeam.ps1 @@ -24,21 +24,24 @@ } New-GitHubTeam @params + .LINK + https://psmodule.io/GitHub/Functions/Teams/New-GitHubTeam + .NOTES [Create a team](https://docs.github.com/rest/teams/teams#create-a-team) #> [OutputType([GitHubTeam])] [CmdletBinding(SupportsShouldProcess)] param( - # The name of the team. - [Parameter(Mandatory)] - [string] $Name, - # The organization name. The name is not case sensitive. # If not provided, the organization from the context is used. [Parameter(Mandatory)] [string] $Organization, + # The name of the team. + [Parameter(Mandatory)] + [string] $Name, + # The description of the team. [Parameter()] [string] $Description, @@ -47,7 +50,8 @@ [Parameter()] [string[]] $Maintainers, - # The full name (e.g., "organization-name/repository-name") of repositories to add the team to. + # The full name of repositories to add the team to. + # Example: 'github/octocat' or 'octocat/Hello-World' [Parameter()] [string[]] $RepoNames, @@ -76,7 +80,7 @@ # The ID of a team to set as the parent team. [Parameter()] - [int] $ParentTeamID = 0, + [System.Nullable[int]] $ParentTeamID, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -104,7 +108,7 @@ privacy = $Visible ? 'closed' : 'secret' notification_setting = $Notifications ? 'notifications_enabled' : 'notifications_disabled' permission = $Permission - parent_team_id = $ParentTeamID -eq 0 ? $null : $ParentTeamID + parent_team_id = $ParentTeamID } $body | Remove-HashtableEntry -NullOrEmptyValues @@ -123,13 +127,14 @@ Name = $team.name Slug = $team.slug NodeID = $team.node_id + Url = $team.html_url CombinedSlug = $Organization + '/' + $team.slug ID = $team.id Description = $team.description Notifications = $team.notification_setting -eq 'notifications_enabled' ? $true : $false Visible = $team.privacy -eq 'closed' ? $true : $false ParentTeam = $team.parent.slug - Organization = $team.organization.login + Organization = $Organization ChildTeams = @() CreatedAt = $team.created_at UpdatedAt = $team.updated_at @@ -143,5 +148,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Teams/Remove-GitHubTeam.ps1 b/src/functions/public/Teams/Remove-GitHubTeam.ps1 index 1f3c523e4..bdeabf2d6 100644 --- a/src/functions/public/Teams/Remove-GitHubTeam.ps1 +++ b/src/functions/public/Teams/Remove-GitHubTeam.ps1 @@ -12,26 +12,22 @@ .NOTES [Delete a team](https://docs.github.com/rest/teams/teams#delete-a-team) + + .LINK + https://psmodule.io/GitHub/Functions/Teams/Remove-GitHubTeam #> [OutputType([void])] [CmdletBinding(SupportsShouldProcess)] param( - # The slug of the team name. - [Parameter( - Mandatory, - ValueFromPipelineByPropertyName - )] - [Alias('team_slug', 'Slug')] - [string] $Name, - # The organization name. The name is not case sensitive. # If not provided, the organization from the context is used. - [Parameter( - Mandatory, - ValueFromPipelineByPropertyName - )] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Organization, + # The slug of the team name. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Slug, + # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] @@ -48,11 +44,11 @@ process { $inputObject = @{ Method = 'DELETE' - APIEndpoint = "/orgs/$Organization/teams/$Name" + APIEndpoint = "/orgs/$Organization/teams/$Slug" Context = $Context } - if ($PSCmdlet.ShouldProcess("$Organization/$Name", 'DELETE')) { + if ($PSCmdlet.ShouldProcess("$Organization/$Slug", 'DELETE')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } @@ -63,5 +59,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Teams/Update-GitHubTeam.ps1 b/src/functions/public/Teams/Update-GitHubTeam.ps1 index 8d03d242f..a6c842172 100644 --- a/src/functions/public/Teams/Update-GitHubTeam.ps1 +++ b/src/functions/public/Teams/Update-GitHubTeam.ps1 @@ -24,20 +24,22 @@ .NOTES [Update a team](https://docs.github.com/rest/teams/teams#update-a-team) + + .LINK + https://psmodule.io/GitHub/Functions/Teams/Update-GitHubTeam #> [OutputType([GitHubTeam])] [CmdletBinding(SupportsShouldProcess)] param( - # The slug of the team name. - [Parameter(Mandatory)] - [Alias('team_slug', 'Slug')] - [string] $Name, - # The organization name. The name is not case sensitive. # If you do not provide this parameter, the command will use the organization from the context. [Parameter(Mandatory)] [string] $Organization, + # The slug of the team name. + [Parameter(Mandatory)] + [string] $Slug, + # The new team name. [Parameter()] [Alias()] @@ -102,12 +104,12 @@ $inputObject = @{ Method = 'PATCH' - APIEndpoint = "/orgs/$Organization/teams/$Name" + APIEndpoint = "/orgs/$Organization/teams/$Slug" Body = $body Context = $Context } - if ($PSCmdlet.ShouldProcess("$Organization/$Name", 'Update')) { + if ($PSCmdlet.ShouldProcess("$Organization/$Slug", 'Update')) { Invoke-GitHubAPI @inputObject | ForEach-Object { $team = $_.Response [GitHubTeam]( @@ -115,13 +117,14 @@ Name = $team.name Slug = $team.slug NodeID = $team.node_id + Url = $team.html_url CombinedSlug = $Organization + '/' + $team.slug ID = $team.id Description = $team.description Notifications = $team.notification_setting -eq 'notifications_enabled' ? $true : $false Visible = $team.privacy -eq 'closed' ? $true : $false ParentTeam = $team.parent.slug - Organization = $team.organization.login + Organization = $Organization ChildTeams = @() CreatedAt = $team.created_at UpdatedAt = $team.updated_at @@ -135,5 +138,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Workflows/Disable-GitHubWorkflow.ps1 b/src/functions/public/Workflows/Disable-GitHubWorkflow.ps1 index 982fda969..624b60ac7 100644 --- a/src/functions/public/Workflows/Disable-GitHubWorkflow.ps1 +++ b/src/functions/public/Workflows/Disable-GitHubWorkflow.ps1 @@ -13,9 +13,9 @@ GitHubWorkflow .LINK - https://psmodule.io/GitHub/Functions/Actions/Workflows/Disable-GitHubWorkflow/ + https://psmodule.io/GitHub/Functions/Workflows/Disable-GitHubWorkflow/ - .LINK + .NOTES [Disable a workflow](https://docs.github.com/rest/actions/workflows#disable-a-workflow) #> [CmdletBinding(SupportsShouldProcess)] diff --git a/src/functions/public/Workflows/Enable-GitHubWorkflow.ps1 b/src/functions/public/Workflows/Enable-GitHubWorkflow.ps1 index 75018632f..dfd1b7768 100644 --- a/src/functions/public/Workflows/Enable-GitHubWorkflow.ps1 +++ b/src/functions/public/Workflows/Enable-GitHubWorkflow.ps1 @@ -10,9 +10,9 @@ GitHubWorkflow .LINK - https://psmodule.io/GitHub/Functions/Actions/Workflows/Enable-GitHubWorkflow/ + https://psmodule.io/GitHub/Functions/Workflows/Enable-GitHubWorkflow/ - .LINK + .NOTES [Enable a workflow](https://docs.github.com/rest/actions/workflows#enable-a-workflow) #> [CmdletBinding(SupportsShouldProcess)] diff --git a/src/functions/public/Workflows/Get-GitHubWorkflow.ps1 b/src/functions/public/Workflows/Get-GitHubWorkflow.ps1 index 017aa5769..dd4fbbff5 100644 --- a/src/functions/public/Workflows/Get-GitHubWorkflow.ps1 +++ b/src/functions/public/Workflows/Get-GitHubWorkflow.ps1 @@ -22,9 +22,9 @@ GitHubWorkflow .LINK - https://psmodule.io/GitHub/Functions/Actions/Workflows/Get-GitHubWorkflow/ + https://psmodule.io/GitHub/Functions/Workflows/Get-GitHubWorkflow/ - .LINK + .NOTES [List repository workflows](https://docs.github.com/rest/actions/workflows#list-repository-workflows) #> [OutputType([GitHubWorkflow])] diff --git a/src/functions/public/Workflows/Runs/Get-GitHubWorkflowRun.ps1 b/src/functions/public/Workflows/Runs/Get-GitHubWorkflowRun.ps1 index 67a212816..1892d1075 100644 --- a/src/functions/public/Workflows/Runs/Get-GitHubWorkflowRun.ps1 +++ b/src/functions/public/Workflows/Runs/Get-GitHubWorkflowRun.ps1 @@ -39,12 +39,10 @@ GitHubWorkflowRun .LINK - https://psmodule.io/GitHub/Functions/Actions/Workflows/Runs/Get-GitHubWorkflowRun/ + https://psmodule.io/GitHub/Functions/Workflows/Runs/Get-GitHubWorkflowRun/ - .LINK + .NOTES [List workflow runs for a workflow](https://docs.github.com/rest/actions/workflow-runs#list-workflow-runs-for-a-workflow) - - .LINK [List workflow runs for a repository](https://docs.github.com/rest/actions/workflow-runs#list-workflow-runs-for-a-repository) #> [OutputType([GitHubWorkflowRun])] diff --git a/src/functions/public/Workflows/Runs/Remove-GitHubWorkflowRun.ps1 b/src/functions/public/Workflows/Runs/Remove-GitHubWorkflowRun.ps1 index 33ada5bcc..949ca5a50 100644 --- a/src/functions/public/Workflows/Runs/Remove-GitHubWorkflowRun.ps1 +++ b/src/functions/public/Workflows/Runs/Remove-GitHubWorkflowRun.ps1 @@ -17,9 +17,9 @@ GitHubWorkflowRun .LINK - https://psmodule.io/GitHub/Functions/Actions/Workflows/Runs/Remove-GitHubWorkflowRun/ + https://psmodule.io/GitHub/Functions/Workflows/Runs/Remove-GitHubWorkflowRun/ - .LINK + .NOTES [Delete a workflow run](https://docs.github.com/rest/actions/workflow-runs#delete-a-workflow-run) #> [CmdletBinding(SupportsShouldProcess)] diff --git a/src/functions/public/Workflows/Runs/Restart-GitHubWorkflowRun.ps1 b/src/functions/public/Workflows/Runs/Restart-GitHubWorkflowRun.ps1 index 0b5fb0fff..b36c81400 100644 --- a/src/functions/public/Workflows/Runs/Restart-GitHubWorkflowRun.ps1 +++ b/src/functions/public/Workflows/Runs/Restart-GitHubWorkflowRun.ps1 @@ -13,9 +13,9 @@ GitHubWorkflowRun .LINK - https://psmodule.io/GitHub/Functions/Actions/Workflows/Runs/Restart-GitHubWorkflowRun/ + https://psmodule.io/GitHub/Functions/Workflows/Runs/Restart-GitHubWorkflowRun/ - .LINK + .NOTES [Re-run a workflow](https://docs.github.com/rest/actions/workflow-runs#re-run-a-workflow) #> [CmdletBinding(SupportsShouldProcess)] diff --git a/src/functions/public/Workflows/Runs/Stop-GitHubWorkflowRun.ps1 b/src/functions/public/Workflows/Runs/Stop-GitHubWorkflowRun.ps1 index 0045ed5f5..a1422096f 100644 --- a/src/functions/public/Workflows/Runs/Stop-GitHubWorkflowRun.ps1 +++ b/src/functions/public/Workflows/Runs/Stop-GitHubWorkflowRun.ps1 @@ -15,9 +15,9 @@ GitHubWorkflowRun .LINK - https://psmodule.io/GitHub/Functions/Actions/Workflows/Runs/Stop-GitHubWorkflowRun/ + https://psmodule.io/GitHub/Functions/Workflows/Runs/Stop-GitHubWorkflowRun/ - .LINK + .NOTES [Cancel a workflow run](https://docs.github.com/rest/actions/workflow-runs#cancel-a-workflow-run) #> [CmdletBinding(SupportsShouldProcess)] diff --git a/src/functions/public/Workflows/Start-GitHubWorkflow.ps1 b/src/functions/public/Workflows/Start-GitHubWorkflow.ps1 index 3abd9c5ec..f89866165 100644 --- a/src/functions/public/Workflows/Start-GitHubWorkflow.ps1 +++ b/src/functions/public/Workflows/Start-GitHubWorkflow.ps1 @@ -15,9 +15,9 @@ } .LINK - https://psmodule.io/GitHub/Functions/Actions/Workflows/Start-GitHubWorkflow/ + https://psmodule.io/GitHub/Functions/Workflows/Start-GitHubWorkflow/ - .LINK + .NOTES [Create a workflow dispatch event](https://docs.github.com/rest/actions/workflows#create-a-workflow-dispatch-event) #> [CmdletBinding(SupportsShouldProcess)] @@ -79,9 +79,7 @@ } if ($PSCmdlet.ShouldProcess("$Owner/$Repository/$ID", 'Start workflow')) { - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } + $null = Invoke-GitHubAPI @inputObject } } diff --git a/src/types/GitHubTeam.Types.ps1xml b/src/types/GitHubTeam.Types.ps1xml new file mode 100644 index 000000000..38abc2cc2 --- /dev/null +++ b/src/types/GitHubTeam.Types.ps1xml @@ -0,0 +1,12 @@ + + + + GitHubTeam + + + Team + $this.Slug + + + + diff --git a/tests copy/Artifacts.Tests.ps1 b/tests/Artifacts.Tests.ps1 similarity index 100% rename from tests copy/Artifacts.Tests.ps1 rename to tests/Artifacts.Tests.ps1 diff --git a/tests copy/Environments.Tests.ps1 b/tests/Environments.Tests.ps1 similarity index 96% rename from tests copy/Environments.Tests.ps1 rename to tests/Environments.Tests.ps1 index 4007f92b6..024be230b 100644 --- a/tests copy/Environments.Tests.ps1 +++ b/tests/Environments.Tests.ps1 @@ -21,7 +21,6 @@ param() BeforeAll { $testName = 'EnvironmentsTests' - $environmentName = 'production' $os = $env:RUNNER_OS $guid = [guid]::NewGuid().ToString() } @@ -41,14 +40,16 @@ Describe 'Environments' { Write-Host ($context | Format-List | Out-String) } } - $repoPrefix = "$testName-$os-$TokenType" - $repoName = "$repoPrefix-$guid" + $repoPrefix = "$testName-$os-$TokenType-$guid" + $repoName = $repoPrefix + $environmentName = "$testName-$os-$TokenType-$guid" + switch ($OwnerType) { 'user' { - New-GitHubRepository -Name $repoName -AllowSquashMerge -Debug -Confirm:$false + New-GitHubRepository -Name $repoName -AllowSquashMerge -Confirm:$false } 'organization' { - New-GitHubRepository -Organization $owner -Name $repoName -AllowSquashMerge -Debug -Confirm:$false + New-GitHubRepository -Organization $owner -Name $repoName -AllowSquashMerge -Confirm:$false } } } diff --git a/tests copy/GitHub.Tests.ps1 b/tests/GitHub.Tests.ps1 similarity index 96% rename from tests copy/GitHub.Tests.ps1 rename to tests/GitHub.Tests.ps1 index 267dfa765..2c6daf84e 100644 --- a/tests copy/GitHub.Tests.ps1 +++ b/tests/GitHub.Tests.ps1 @@ -124,7 +124,7 @@ Describe 'GitHub' { Context 'Config' { It 'Get-GitHubConfig - Gets the module configuration' { $config = Get-GitHubConfig - Write-Verbose ($config | Format-Table | Out-String) -Verbose + Write-Host ($config | Format-Table | Out-String) $config | Should -Not -BeNullOrEmpty } It 'Get-GitHubConfig - Gets a configuration item by name' { @@ -152,12 +152,12 @@ Describe 'GitHub' { Context 'Actions' { It 'Get-GitHubEventData - Gets data about the event that triggered the workflow' { $workflow = Get-GitHubEventData - Write-Verbose ($workflow | Format-List | Out-String) -Verbose + Write-Host ($workflow | Format-List | Out-String) $workflow | Should -Not -BeNullOrEmpty } It 'Get-GitHubRunnerData - Gets data about the runner that is running the workflow' { $workflow = Get-GitHubRunnerData - Write-Verbose ($workflow | Format-List | Out-String) -Verbose + Write-Host ($workflow | Format-List | Out-String) $workflow | Should -Not -BeNullOrEmpty } } @@ -287,7 +287,7 @@ string { Get-GitHubOutput } | Should -Not -Throw - Write-Verbose (Get-GitHubOutput | Format-List | Out-String) -Verbose + Write-Host (Get-GitHubOutput | Format-List | Out-String) } It 'Set-GitHubEnvironmentVariable - Should not throw' { { @@ -310,15 +310,15 @@ string Context 'IssueParser' { BeforeAll { $issueTestFilePath = Join-Path -Path $PSScriptRoot -ChildPath 'Data/IssueForm.md' - Write-Verbose "Reading from $issueTestFilePath" -Verbose + Write-Host "Reading from $issueTestFilePath" $content = Get-Content -Path $issueTestFilePath -Raw - Write-Verbose ($content | Out-String) -Verbose - $dataObject = $content | ConvertFrom-IssueForm -Verbose - Write-Verbose 'As PSCustomObject' -Verbose - Write-Verbose ($dataObject | Format-List | Out-String) -Verbose - $dataHashtable = $content | ConvertFrom-IssueForm -AsHashtable -Verbose - Write-Verbose 'As Hashtable' -Verbose - Write-Verbose ($dataHashtable | Out-String) -Verbose + Write-Host ($content | Out-String) + $dataObject = $content | ConvertFrom-IssueForm + Write-Host 'As PSCustomObject' + Write-Host ($dataObject | Format-List | Out-String) + $dataHashtable = $content | ConvertFrom-IssueForm -AsHashtable + Write-Host 'As Hashtable' + Write-Host ($dataHashtable | Out-String) } It 'ConvertFrom-IssueForm - Should return a PSCustomObject' { @@ -330,13 +330,13 @@ string } It "'Type with spaces' should contain 'Action'" { - Write-Verbose ($dataHashtable['Type with spaces'] | Out-String) -Verbose + Write-Host ($dataHashtable['Type with spaces'] | Out-String) $dataHashtable.Keys | Should -Contain 'Type with spaces' $dataHashtable['Type with spaces'] | Should -Be 'Action' } It "'Multiline' should contain a multiline string with 3 lines" { - Write-Verbose ($dataHashtable['Multiline'] | Out-String) -Verbose + Write-Host ($dataHashtable['Multiline'] | Out-String) $dataHashtable.Keys | Should -Contain 'Multiline' $dataHashtable['Multiline'] | Should -Be @' test @@ -346,7 +346,7 @@ line } It "'OS' should contain a hashtable with 3 items" { - Write-Verbose ($dataHashtable['OS'] | Out-String) -Verbose + Write-Host ($dataHashtable['OS'] | Out-String) $dataHashtable.Keys | Should -Contain 'OS' $dataHashtable['OS'].Windows | Should -BeTrue $dataHashtable['OS'].Linux | Should -BeTrue diff --git a/tests copy/Organizations.Tests.ps1 b/tests/Organizations.Tests.ps1 similarity index 100% rename from tests copy/Organizations.Tests.ps1 rename to tests/Organizations.Tests.ps1 diff --git a/tests copy/README.md b/tests/README.md similarity index 100% rename from tests copy/README.md rename to tests/README.md diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 deleted file mode 100644 index 9507edce8..000000000 --- a/tests/Releases.Tests.ps1 +++ /dev/null @@ -1,84 +0,0 @@ -#Requires -Modules @{ ModuleName = 'Pester'; RequiredVersion = '5.7.1' } - -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSUseDeclaredVarsMoreThanAssignments', '', - Justification = 'Pester grouping syntax: known issue.' -)] -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSAvoidUsingConvertToSecureStringWithPlainText', '', - Justification = 'Used to create a secure string for testing.' -)] -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSAvoidUsingWriteHost', '', - Justification = 'Log outputs to GitHub Actions logs.' -)] -[Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSAvoidLongLines', '', - Justification = 'Long test descriptions and skip switches' -)] -[CmdletBinding()] -param() - -BeforeAll { - $testName = 'ReleasesTests' - $os = $env:RUNNER_OS - $guid = [guid]::NewGuid().ToString() -} - -Describe 'Releases' { - $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" - - Context 'As using on ' -ForEach $authCases { - BeforeAll { - $context = Connect-GitHubAccount @connectParams -PassThru -Silent - LogGroup 'Context' { - Write-Host ($context | Format-Table | Out-String) - } - if ($AuthType -eq 'APP') { - LogGroup 'Context - Installation' { - $context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent - Write-Host ($context | Format-Table | Out-String) - } - } - $repoPrefix = "$testName-$os-$TokenType" - $repoName = "$repoPrefix-$guid" - $variablePrefix = ("$testName`_$os`_$TokenType" -replace '-', '_').ToUpper() - $varName = ("$variablePrefix`_$guid" -replace '-', '_').ToUpper() - $environmentName = "$testName-$os-$TokenType-$guid" - - switch ($OwnerType) { - 'user' { - $repo = New-GitHubRepository -Name $repoName -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio - } - 'organization' { - $repo = New-GitHubRepository -Organization $owner -Name $repoName -AllowSquashMerge - } - } - LogGroup "Repository - [$repoName]" { - Write-Host ($repo | Format-Table | Out-String) - } - } - - AfterAll { - switch ($OwnerType) { - 'user' { - Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false - } - 'organization' { - Get-GitHubRepository -Owner $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false - } - } - Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent - } - - Context 'Releases' { - It 'New-GitHubRelease - Creates a new release' { - $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest - LogGroup 'Release' { - Write-Host ($item | Format-Table | Out-String) - } - $item | Should -Not -BeNullOrEmpty - } - } - } -} diff --git a/tests copy/Repositories.Tests.ps1 b/tests/Repositories.Tests.ps1 similarity index 100% rename from tests copy/Repositories.Tests.ps1 rename to tests/Repositories.Tests.ps1 diff --git a/tests copy/Secrets.Tests.ps1 b/tests/Secrets.Tests.ps1 similarity index 89% rename from tests copy/Secrets.Tests.ps1 rename to tests/Secrets.Tests.ps1 index e9c003f58..6d909b181 100644 --- a/tests copy/Secrets.Tests.ps1 +++ b/tests/Secrets.Tests.ps1 @@ -36,37 +36,36 @@ Describe 'Secrets' { Write-Host ($context | Format-List | Out-String) } } - $repoPrefix = "$testName-$os-$TokenType" - $repoName = "$repoPrefix-$guid" + $repoPrefix = "$testName-$os-$TokenType-$guid" $secretPrefix = ("$testName`_$os`_$TokenType`_$guid" -replace '-', '_').ToUpper() + $orgSecretName = "$secretPrefix`ORG" $environmentName = "$testName-$os-$TokenType-$guid" switch ($OwnerType) { 'user' { - $repo = New-GitHubRepository -Name $repoName -AllowSquashMerge - $repo2 = New-GitHubRepository -Name "$repoName-2" -AllowSquashMerge - $repo3 = New-GitHubRepository -Name "$repoName-3" -AllowSquashMerge + $repo = New-GitHubRepository -Name "$repoPrefix-1" -AllowSquashMerge + $repo2 = New-GitHubRepository -Name "$repoPrefix-2" -AllowSquashMerge + $repo3 = New-GitHubRepository -Name "$repoPrefix-3" -AllowSquashMerge } 'organization' { - $repo = New-GitHubRepository -Organization $owner -Name $repoName -AllowSquashMerge - $repo2 = New-GitHubRepository -Organization $owner -Name "$repoName-2" -AllowSquashMerge - $repo3 = New-GitHubRepository -Organization $owner -Name "$repoName-3" -AllowSquashMerge + $repo = New-GitHubRepository -Organization $owner -Name "$repoPrefix-1" -AllowSquashMerge + $repo2 = New-GitHubRepository -Organization $owner -Name "$repoPrefix-2" -AllowSquashMerge + $repo3 = New-GitHubRepository -Organization $owner -Name "$repoPrefix-3" -AllowSquashMerge LogGroup "Org secret - [$secretPrefix]" { $params = @{ Owner = $owner + Name = $orgSecretName Value = 'organization' Visibility = 'selected' SelectedRepositories = $repo.id } - $result = @() - $result += Set-GitHubSecret @params -Name "$secretPrefix" - $result += Set-GitHubSecret @params -Name "$secretPrefix`_2" - $result += Set-GitHubSecret @params -Name "$secretPrefix`_3" - Write-Host ($result | Select-Object * | Format-Table | Out-String) + + $orgSecret += Set-GitHubSecret @params + Write-Host ($orgSecret | Select-Object * | Format-Table | Out-String) } } } - LogGroup "Repository - [$repoName]" { + LogGroup "Repository - [$repoPrefix]" { Write-Host ($repo | Format-List | Out-String) Write-Host ($repo2 | Format-List | Out-String) Write-Host ($repo3 | Format-List | Out-String) @@ -79,11 +78,11 @@ Describe 'Secrets' { Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false } 'organization' { - $orgSecrets = Get-GitHubSecret -Owner $owner | Where-Object { $_.Name -like "$secretPrefix*" } LogGroup 'Secrets to remove' { + $orgSecrets = Get-GitHubSecret -Owner $owner | Where-Object { $_.Name -like "$secretPrefix*" } Write-Host "$($orgSecrets | Format-List | Out-String)" + $orgSecrets | Remove-GitHubSecret } - $orgSecrets | Remove-GitHubSecret LogGroup 'Repos to remove' { $reposToRemove = Get-GitHubRepository -Organization $Owner | Where-Object { $_.Name -like "$repoPrefix*" } Write-Host "$($reposToRemove | Format-List | Out-String)" @@ -228,8 +227,8 @@ Describe 'Secrets' { Context 'SelectedRepository' { It 'Get-GitHubSecretSelectedRepository - gets a list of selected repositories' { - LogGroup "SelectedRepositories - [$secretPrefix]" { - $result = Get-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix + LogGroup "SelectedRepositories - [$orgSecretName]" { + $result = Get-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName Write-Host "$($result | Select-Object * | Format-Table | Out-String)" } $result | Should -Not -BeNullOrEmpty @@ -237,20 +236,20 @@ Describe 'Secrets' { $result | Should -HaveCount 1 } It 'Add-GitHubSecretSelectedRepository - adds a repository to the list of selected repositories' { - { Add-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix -RepositoryID $repo2.id } | Should -Not -Throw + { Add-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName -RepositoryID $repo2.id } | Should -Not -Throw } It 'Add-GitHubSecretSelectedRepository - adds a repository to the list of selected repositories - idempotency test' { - { Add-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix -RepositoryID $repo2.id } | Should -Not -Throw + { Add-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName -RepositoryID $repo2.id } | Should -Not -Throw } It 'Add-GitHubSecretSelectedRepository - adds a repository to the list of selected repositories using pipeline' { LogGroup 'Repo3' { Write-Host "$($repo3 | Format-List | Out-String)" } - { $repo3 | Add-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix } | Should -Not -Throw + { $repo3 | Add-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName } | Should -Not -Throw } It 'Get-GitHubSecretSelectedRepository - gets 3 repositories' { - LogGroup "SelectedRepositories - [$secretPrefix]" { - $result = Get-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix + LogGroup "SelectedRepositories - [$orgSecretName]" { + $result = Get-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName Write-Host "$($result | Select-Object * | Format-Table | Out-String)" } $result | Should -Not -BeNullOrEmpty @@ -258,20 +257,20 @@ Describe 'Secrets' { $result | Should -HaveCount 3 } It 'Remove-GitHubSecretSelectedRepository - removes a repository from the list of selected repositories' { - { Remove-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix -RepositoryID $repo2.id } | Should -Not -Throw + { Remove-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName -RepositoryID $repo2.id } | Should -Not -Throw } It 'Remove-GitHubSecretSelectedRepository - removes a repository from the list of selected repositories - idempotency test' { - { Remove-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix -RepositoryID $repo2.id } | Should -Not -Throw + { Remove-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName -RepositoryID $repo2.id } | Should -Not -Throw } It 'Remove-GitHubSecretSelectedRepository - removes a repository from the list of selected repositories using pipeline' { LogGroup 'Repo3' { Write-Host "$($repo3 | Format-List | Out-String)" } - { $repo3 | Remove-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix } | Should -Not -Throw + { $repo3 | Remove-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName } | Should -Not -Throw } It 'Get-GitHubSecretSelectedRepository - gets 1 repository' { - LogGroup "SelectedRepositories - [$secretPrefix]" { - $result = Get-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix + LogGroup "SelectedRepositories - [$orgSecretName]" { + $result = Get-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName Write-Host "$($result | Select-Object * | Format-Table | Out-String)" } $result | Should -Not -BeNullOrEmpty @@ -279,16 +278,16 @@ Describe 'Secrets' { $result | Should -HaveCount 1 } It 'Set-GitHubSecretSelectedRepository - should set the selected repositories for the secret' { - { Set-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix -RepositoryID $repo.id, $repo2.id, $repo3.id } | + { Set-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName -RepositoryID $repo.id, $repo2.id, $repo3.id } | Should -Not -Throw } It 'Set-GitHubSecretSelectedRepository - should set the selected repositories for the secret - idempotency test' { - { Set-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix -RepositoryID $repo.id, $repo2.id, $repo3.id } | + { Set-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName -RepositoryID $repo.id, $repo2.id, $repo3.id } | Should -Not -Throw } It 'Get-GitHubSecretSelectedRepository - gets 3 repository' { - $result = Get-GitHubSecretSelectedRepository -Owner $owner -Name $secretPrefix - LogGroup "SelectedRepositories - [$secretPrefix]" { + $result = Get-GitHubSecretSelectedRepository -Owner $owner -Name $orgSecretName + LogGroup "SelectedRepositories - [$orgSecretName]" { Write-Host "$($result | Select-Object * | Format-Table | Out-String)" } $result | Should -Not -BeNullOrEmpty @@ -302,9 +301,9 @@ Describe 'Secrets' { BeforeAll { $scope = @{ Owner = $owner - Repository = $repoName + Repository = $repo } - Set-GitHubSecret @scope -Name $secretPrefix -Value 'repository' + Set-GitHubSecret @scope -Name $orgSecretName -Value 'repository' } Context 'PublicKey' { @@ -415,16 +414,16 @@ Describe 'Secrets' { BeforeAll { $scope = @{ Owner = $owner - Repository = $repoName + Repository = $repo } - Set-GitHubSecret @scope -Name $secretPrefix -Value 'repository' + Set-GitHubSecret @scope -Name $orgSecretName -Value 'repository' $scope = @{ Owner = $owner - Repository = $repoName + Repository = $repo Environment = $environmentName } - Set-GitHubEnvironment -Owner $owner -Repository $repoName -Name $environmentName - Set-GitHubSecret @scope -Name $secretPrefix -Value 'environment' + Set-GitHubEnvironment -Owner $owner -Repository $repo -Name $environmentName + Set-GitHubSecret @scope -Name $orgSecretName -Value 'environment' } Context 'PublicKey' { diff --git a/tests copy/TEMPLATE.ps1 b/tests/TEMPLATE.ps1 similarity index 100% rename from tests copy/TEMPLATE.ps1 rename to tests/TEMPLATE.ps1 diff --git a/tests/Teams.Tests.ps1 b/tests/Teams.Tests.ps1 new file mode 100644 index 000000000..8587be108 --- /dev/null +++ b/tests/Teams.Tests.ps1 @@ -0,0 +1,136 @@ +#Requires -Modules @{ ModuleName = 'Pester'; RequiredVersion = '5.7.1' } + +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', '', + Justification = 'Pester grouping syntax: known issue.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidUsingConvertToSecureStringWithPlainText', '', + Justification = 'Used to create a secure string for testing.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidUsingWriteHost', '', + Justification = 'Log outputs to GitHub Actions logs.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidLongLines', '', + Justification = 'Long test descriptions and skip switches' +)] +[CmdletBinding()] +param() + +BeforeAll { + $testName = 'TeamsTests' + $os = $env:RUNNER_OS + $guid = [guid]::NewGuid().ToString() +} + +Describe 'Teams' { + $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" + + Context 'As using on ' -ForEach $authCases { + BeforeAll { + $context = Connect-GitHubAccount @connectParams -PassThru -Silent + LogGroup 'Context' { + Write-Host ($context | Format-List | Out-String) + } + if ($AuthType -eq 'APP') { + LogGroup 'Context - Installation' { + $context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent + Write-Host ($context | Format-List | Out-String) + } + } + $teamPrefix = ("$testName`_$os`_$TokenType`_$guid" -replace '-', '_').ToUpper() + } + + AfterAll { + switch ($OwnerType) { + 'organization' { + $teamsToRemove = Get-GitHubTeam -Organization $owner | Where-Object { $_.Name -like "$teamPrefix*" } + LogGroup 'Teams to remove' { + Write-Host "$($teamsToRemove | Format-List | Out-String)" + } + $teamsToRemove | Remove-GitHubTeam -Confirm:$false + } + } + Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent + } + + Context 'Organization' -Skip:($OwnerType -ne 'organization') { + BeforeAll { + $scope = @{ + Organization = $owner + } + } + + It 'New-GitHubTeam - Creates a new team' { + $teamName = "$teamPrefix`_NewTeam" + $teamDescription = 'This is a test team.' + $team = New-GitHubTeam @scope -Name $teamName -Description $teamDescription + LogGroup 'New Team' { + Write-Host ($team | Format-List | Out-String) + } + $team | Should -Not -BeNullOrEmpty + $team.Name | Should -Be $teamName + $team.Description | Should -Be $teamDescription + } + + It 'Get-GitHubTeam - Gets a team' { + $teamName = "$teamPrefix`_NewTeam" + $team = Get-GitHubTeam -Organization $owner -Slug $teamName + LogGroup 'Get Team' { + Write-Host ($team | Format-List | Out-String) + } + $team | Should -Not -BeNullOrEmpty + $team.Name | Should -Be $teamName + } + + It 'New-GitHubTeam - Creates 5 new teams' { + 1..5 | ForEach-Object { + $teamName = "$teamPrefix`_NewTeam_$_" + $teamDescription = 'This is a test team.' + $team = New-GitHubTeam @scope -Name $teamName -Description $teamDescription + LogGroup 'New Team' { + Write-Host ($team | Format-List | Out-String) + } + $team | Should -Not -BeNullOrEmpty + $team.Name | Should -Be $teamName + $team.Description | Should -Be $teamDescription + } + } + + It 'Get-GitHubTeam - Gets all teams' { + $teams = Get-GitHubTeam -Organization $owner + LogGroup 'Get All Teams' { + Write-Host ($teams | Format-List | Out-String) + } + $teams | Should -Not -BeNullOrEmpty + $teams.Count | Should -BeGreaterThan 0 + } + + It 'Update-GitHubTeam - Updates a team' { + $teamName = "$teamPrefix`_NewTeam" + $newTeamName = "$teamPrefix`_UpdatedTeam" + $teamDescription = 'This is an updated test team.' + $team = Update-GitHubTeam @scope -Slug $teamName -NewName $newTeamName -Description $teamDescription + LogGroup 'Update Team' { + Write-Host ($team | Format-List | Out-String) + } + $team | Should -Not -BeNullOrEmpty + $team.Name | Should -Be $newTeamName + $team.Description | Should -Be $teamDescription + } + + It 'Remove-GitHubTeam - Removes a team' { + $teamName = "$teamPrefix`_UpdatedTeam" + $team = Get-GitHubTeam -Organization $owner -Slug $teamName + LogGroup 'Remove Team' { + Write-Host ($team | Format-List | Out-String) + } + $team | Should -Not -BeNullOrEmpty + $team.Name | Should -Be $teamName + Remove-GitHubTeam @scope -Slug $teamName -Confirm:$false + } + } + } +} diff --git a/tests copy/Users.Tests.ps1 b/tests/Users.Tests.ps1 similarity index 95% rename from tests copy/Users.Tests.ps1 rename to tests/Users.Tests.ps1 index b0e4080e9..c5107d110 100644 --- a/tests copy/Users.Tests.ps1 +++ b/tests/Users.Tests.ps1 @@ -57,7 +57,6 @@ Describe 'Users' { { Update-GitHubUser -Company 'PSModule' } | Should -Not -Throw { Update-GitHubUser -Location 'USA' } | Should -Not -Throw { Update-GitHubUser -Bio 'I love programming' } | Should -Not -Throw - { Update-GitHubUser -Hireable $true } | Should -Not -Throw $tmpUser = Get-GitHubUser $tmpUser.DisplayName | Should -Be 'Octocat' $tmpUser.Blog | Should -Be 'https://psmodule.io' @@ -65,7 +64,10 @@ Describe 'Users' { $tmpUser.Company | Should -Be 'PSModule' $tmpUser.Location | Should -Be 'USA' $tmpUser.Bio | Should -Be 'I love programming' - $tmpUser.Hireable | Should -Be $true + + # Flaky tests + # { Update-GitHubUser -Hireable $true } | Should -Not -Throw + # $tmpUser.Hireable | Should -Be $true } Context 'Email' { It 'Get-GitHubUserEmail - Gets all email addresses for the authenticated user' { diff --git a/tests copy/Variables.Tests.ps1 b/tests/Variables.Tests.ps1 similarity index 91% rename from tests copy/Variables.Tests.ps1 rename to tests/Variables.Tests.ps1 index 1fcb1ad10..edaef1add 100644 --- a/tests copy/Variables.Tests.ps1 +++ b/tests/Variables.Tests.ps1 @@ -36,35 +36,35 @@ Describe 'Variables' { Write-Host ($context | Format-List | Out-String) } } - $repoPrefix = "$testName-$os-$TokenType" - $repoName = "$repoPrefix-$guid" + $repoPrefix = "$testName-$os-$TokenType-$guid" $variablePrefix = ("$testName`_$os`_$TokenType`_$guid" -replace '-', '_').ToUpper() + $orgVariableName = "$variablePrefix`ORG" $environmentName = "$testName-$os-$TokenType-$guid" switch ($OwnerType) { 'user' { - $repo = New-GitHubRepository -Name $repoName -AllowSquashMerge - $repo2 = New-GitHubRepository -Name "$repoName-2" -AllowSquashMerge - $repo3 = New-GitHubRepository -Name "$repoName-3" -AllowSquashMerge + $repo = New-GitHubRepository -Name "$repoPrefix-1" -AllowSquashMerge + $repo2 = New-GitHubRepository -Name "$repoPrefix-2" -AllowSquashMerge + $repo3 = New-GitHubRepository -Name "$repoPrefix-3" -AllowSquashMerge } 'organization' { - $repo = New-GitHubRepository -Organization $owner -Name $repoName -AllowSquashMerge - $repo2 = New-GitHubRepository -Organization $owner -Name "$repoName-2" -AllowSquashMerge - $repo3 = New-GitHubRepository -Organization $owner -Name "$repoName-3" -AllowSquashMerge + $repo = New-GitHubRepository -Organization $owner -Name "$repoPrefix-1" -AllowSquashMerge + $repo2 = New-GitHubRepository -Organization $owner -Name "$repoPrefix-2" -AllowSquashMerge + $repo3 = New-GitHubRepository -Organization $owner -Name "$repoPrefix-3" -AllowSquashMerge LogGroup "Org variable - [$variablePrefix]" { $params = @{ Owner = $owner - Name = $variablePrefix + Name = $orgVariableName Value = 'organization' Visibility = 'selected' SelectedRepositories = $repo.id } - $result = Set-GitHubVariable @params - Write-Host ($result | Select-Object * | Format-Table | Out-String) + $orgVariable = Set-GitHubVariable @params + Write-Host ($orgVariable | Select-Object * | Format-Table | Out-String) } } } - LogGroup "Repository - [$repoName]" { + LogGroup "Repository - [$repoPrefix]" { Write-Host ($repo | Format-Table | Out-String) Write-Host ($repo2 | Format-Table | Out-String) Write-Host ($repo3 | Format-Table | Out-String) @@ -242,8 +242,8 @@ Describe 'Variables' { Context 'SelectedRepository' -Tag 'Flaky' { It 'Get-GitHubVariableSelectedRepository - gets a list of selected repositories' { - LogGroup "SelectedRepositories - [$variablePrefix]" { - $result = Get-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix + LogGroup "SelectedRepositories - [$orgVariableName]" { + $result = Get-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName Write-Host "$($result | Select-Object * | Format-Table | Out-String)" } $result | Should -Not -BeNullOrEmpty @@ -251,20 +251,20 @@ Describe 'Variables' { $result | Should -HaveCount 1 } It 'Add-GitHubVariableSelectedRepository - adds a repository to the list of selected repositories' { - { Add-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix -RepositoryID $repo2.id } | Should -Not -Throw + { Add-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName -RepositoryID $repo2.id } | Should -Not -Throw } It 'Add-GitHubVariableSelectedRepository - adds a repository to the list of selected repositories - idempotency test' { - { Add-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix -RepositoryID $repo2.id } | Should -Not -Throw + { Add-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName -RepositoryID $repo2.id } | Should -Not -Throw } It 'Add-GitHubVariableSelectedRepository - adds a repository to the list of selected repositories using pipeline' { LogGroup 'Repo3' { Write-Host "$($repo3 | Format-List | Out-String)" } - { $repo3 | Add-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix } | Should -Not -Throw + { $repo3 | Add-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName } | Should -Not -Throw } It 'Get-GitHubVariableSelectedRepository - gets 3 repositories' { - LogGroup "SelectedRepositories - [$variablePrefix]" { - $result = Get-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix + LogGroup "SelectedRepositories - [$orgVariableName]" { + $result = Get-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName Write-Host "$($result | Select-Object * | Format-Table | Out-String)" } $result | Should -Not -BeNullOrEmpty @@ -272,20 +272,20 @@ Describe 'Variables' { $result | Should -HaveCount 3 } It 'Remove-GitHubVariableSelectedRepository - removes a repository from the list of selected repositories' { - { Remove-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix -RepositoryID $repo2.id } | Should -Not -Throw + { Remove-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName -RepositoryID $repo2.id } | Should -Not -Throw } It 'Remove-GitHubVariableSelectedRepository - removes a repository from the list of selected repositories - idempotency test' { - { Remove-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix -RepositoryID $repo2.id } | Should -Not -Throw + { Remove-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName -RepositoryID $repo2.id } | Should -Not -Throw } It 'Remove-GitHubVariableSelectedRepository - removes a repository from the list of selected repositories using pipeline' { LogGroup 'Repo3' { Write-Host "$($repo3 | Format-List | Out-String)" } - { $repo3 | Remove-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix } | Should -Not -Throw + { $repo3 | Remove-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName } | Should -Not -Throw } It 'Get-GitHubVariableSelectedRepository - gets 1 repository' { - LogGroup "SelectedRepositories - [$variablePrefix]" { - $result = Get-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix + LogGroup "SelectedRepositories - [$orgVariableName]" { + $result = Get-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName Write-Host "$($result | Select-Object * | Format-Table | Out-String)" } $result | Should -Not -BeNullOrEmpty @@ -293,16 +293,16 @@ Describe 'Variables' { $result | Should -HaveCount 1 } It 'Set-GitHubVariableSelectedRepository - should set the selected repositories for the variable' { - { Set-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix -RepositoryID $repo.id, $repo2.id, $repo3.id } | + { Set-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName -RepositoryID $repo.id, $repo2.id, $repo3.id } | Should -Not -Throw } It 'Set-GitHubVariableSelectedRepository - should set the selected repositories for the variable - idempotency test' { - { Set-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix -RepositoryID $repo.id, $repo2.id, $repo3.id } | + { Set-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName -RepositoryID $repo.id, $repo2.id, $repo3.id } | Should -Not -Throw } It 'Get-GitHubVariableSelectedRepository - gets 3 repository' { - $result = Get-GitHubVariableSelectedRepository -Owner $owner -Name $variablePrefix - LogGroup "SelectedRepositories - [$variablePrefix]" { + $result = Get-GitHubVariableSelectedRepository -Owner $owner -Name $orgVariableName + LogGroup "SelectedRepositories - [$orgVariableName]" { Write-Host "$($result | Select-Object * | Format-Table | Out-String)" } $result | Should -Not -BeNullOrEmpty @@ -316,9 +316,9 @@ Describe 'Variables' { BeforeAll { $scope = @{ Owner = $owner - Repository = $repoName + Repository = $repo } - Set-GitHubVariable @scope -Name $variablePrefix -Value 'repository' + Set-GitHubVariable @scope -Name $orgVariableName -Value 'repository' } It 'Set-GitHubVariable' { $name = "$variablePrefix`TestVariable" @@ -435,16 +435,16 @@ Describe 'Variables' { BeforeAll { $scope = @{ Owner = $owner - Repository = $repoName + Repository = $repo } - Set-GitHubVariable @scope -Name $variablePrefix -Value 'repository' + Set-GitHubVariable @scope -Name $orgVariableName -Value 'repository' $scope = @{ Owner = $owner - Repository = $repoName + Repository = $repo Environment = $environmentName } - Set-GitHubEnvironment -Owner $owner -Repository $repoName -Name $environmentName - Set-GitHubVariable @scope -Name $variablePrefix -Value 'environment' + Set-GitHubEnvironment -Owner $owner -Repository $repo -Name $environmentName + Set-GitHubVariable @scope -Name $orgVariableName -Value 'environment' } It 'Set-GitHubVariable' { $name = "$variablePrefix`TestVariable" diff --git a/tools/dev/Get-GitHubReleaseQL.ps1 b/tools/dev/Get-GitHubReleaseQL.ps1 deleted file mode 100644 index 64dcb4a92..000000000 --- a/tools/dev/Get-GitHubReleaseQL.ps1 +++ /dev/null @@ -1,124 +0,0 @@ -function Get-GitHubReleaseQL { - <# - .SYNOPSIS - Get all releases with nested pagination for assets - - .DESCRIPTION - Gets all releases with their complete asset lists using nested pagination through both releases and their assets. - - .EXAMPLE - Get-GitHubRelease -Owner 'github' -Repository 'my-repo' -PerPage 10 -Context $context - #> - [OutputType([GitHubRelease])] - [CmdletBinding()] - param( - [Parameter(Mandatory)] - [string] $Owner, - - [Parameter(Mandatory)] - [string] $Repository, - - [ValidateRange(1, 100)] - [int] $PerPage, - - [Parameter()] - [object] $Context = (Get-GitHubContext) - ) - - begin { - $stackPath = Get-PSCallStackPath - Write-Debug "[$stackPath] - Start" - Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - - $releaseCursor = $null - $releaseQuery = @' -query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: Int!) { - repository(owner: $owner, name: $repository) { - releases(first: $perPage, after: $releaseCursor, orderBy: {field: CREATED_AT, direction: DESC}) { - nodes { - id - databaseId - name - tagName - description - isDraft - isPrerelease - isLatest - createdAt - publishedAt - updatedAt - tag { - name - id - } - tagCommit { - oid - } - url - author { - login - id - databaseId - } - releaseAssets(first: $perPage) { - nodes { - name - downloadCount - downloadUrl - contentType - createdAt - updatedAt - uploadedBy { - login - name - id - databaseId - } - size - url - id - } - } - } - pageInfo { - hasNextPage - endCursor - } - } - } -} -'@ - - $PerPage = $PSBoundParameters.ContainsKey('PerPage') ? $PerPage : $Context.PerPage - } - - process { - do { - $releaseVariables = @{ - owner = $Owner - repository = $Repository - releaseCursor = $releaseCursor - perPage = $PerPage - } - - $result = Invoke-GitHubGraphQLQuery -Query $releaseQuery -Variables $releaseVariables -Context $Context - if (-not $result) { break } - - $repositoryData = $result.repository - if (-not $repositoryData) { break } - - $releases = $repositoryData.releases - if (-not $releases) { break } - - $releases.nodes | ForEach-Object { - # [GitHubRelease]::new($_) - } - - $releaseCursor = $releases.pageInfo.endCursor - } while ($releases.pageInfo.hasNextPage) - } - - end { - Write-Debug "[$stackPath] - End" - } -} diff --git a/tools/utilities/GitHubAPI.ps1 b/tools/utilities/GitHubAPI.ps1 index 6032a9a1b..d6c41d97c 100644 --- a/tools/utilities/GitHubAPI.ps1 +++ b/tools/utilities/GitHubAPI.ps1 @@ -22,8 +22,8 @@ $response = Invoke-RestMethod -Uri $APIDocURI -Method Get # @{n = 'PUT'; e = { (($_.value.psobject.Properties.Name) -contains 'PUT') } }, ` # @{n = 'PATCH'; e = { (($_.value.psobject.Properties.Name) -contains 'PATCH') } } | Format-Table -$path = '/repos/{owner}/{repo}/releases/generate-notes' -$method = 'post' +$path = '/repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}' +$method = 'delete' $response.paths.$path.$method $response.paths.$path.$method.tags | clip # -> Namespace/foldername $response.paths.$path.$method.operationId | clip # -> FunctionName From 458fda731407348dadba6a64f4bf147e85c1cec4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 11:37:44 +0200 Subject: [PATCH 126/224] Add initial test scripts for GitHub API functionalities - Created TEMPLATE.ps1 for Pester testing framework setup. - Added Teams.Tests.ps1 to test GitHub Teams API interactions. - Implemented Users.Tests.ps1 for user-related API tests. - Developed Variables.Tests.ps1 to validate GitHub variable management. - Introduced Releases.Tests.ps1 for testing release creation and management. - Added Get-GitHubReleaseQL.ps1 to retrieve releases with nested pagination for assets. --- .github/PSModule.yml | 17 +- examples/Releases/Releases.ps1 | 60 +++++++ src/classes/public/Releases/GitHubRelease.ps1 | 146 +++++++++++++++ src/formats/GitHubRelease.Format.ps1xml | 119 +++++++++++++ .../{Releases => }/Get-GitHubReleaseAll.ps1 | 31 ++-- .../{Releases => }/Get-GitHubReleaseByID.ps1 | 22 ++- .../Get-GitHubReleaseByTagName.ps1 | 22 ++- .../Get-GitHubReleaseLatest.ps1 | 18 +- .../Assets/Get-GitHubReleaseAsset.ps1 | 31 ++-- .../{Releases => }/Get-GitHubRelease.ps1 | 72 ++++---- .../{Releases => }/New-GitHubRelease.ps1 | 71 ++++---- .../{Releases => }/New-GitHubReleaseNote.ps1 | 75 ++++---- .../Releases/Releases/Set-GitHubRelease.ps1 | 124 ------------- .../{Releases => }/Remove-GitHubRelease.ps1 | 27 ++- .../public/Releases/Set-GitHubRelease.ps1 | 127 +++++++++++++ .../public/Releases/Update-GitHubRelease.ps1 | 168 ++++++++++++++++++ {tests => tests copy}/Artifacts.Tests.ps1 | 0 tests copy/Data/AuthCases.ps1 | 83 +++++++++ tests copy/Data/IssueForm.md | 19 ++ {tests => tests copy}/Environments.Tests.ps1 | 0 {tests => tests copy}/GitHub.Tests.ps1 | 0 {tests => tests copy}/Organizations.Tests.ps1 | 0 {tests => tests copy}/README.md | 0 {tests => tests copy}/Repositories.Tests.ps1 | 0 {tests => tests copy}/Secrets.Tests.ps1 | 0 {tests => tests copy}/TEMPLATE.ps1 | 0 {tests => tests copy}/Teams.Tests.ps1 | 0 {tests => tests copy}/Users.Tests.ps1 | 0 {tests => tests copy}/Variables.Tests.ps1 | 0 tests/Releases.Tests.ps1 | 84 +++++++++ tools/dev/Get-GitHubReleaseQL.ps1 | 124 +++++++++++++ 31 files changed, 1157 insertions(+), 283 deletions(-) create mode 100644 examples/Releases/Releases.ps1 create mode 100644 src/classes/public/Releases/GitHubRelease.ps1 create mode 100644 src/formats/GitHubRelease.Format.ps1xml rename src/functions/private/Releases/{Releases => }/Get-GitHubReleaseAll.ps1 (71%) rename src/functions/private/Releases/{Releases => }/Get-GitHubReleaseByID.ps1 (73%) rename src/functions/private/Releases/{Releases => }/Get-GitHubReleaseByTagName.ps1 (71%) rename src/functions/private/Releases/{Releases => }/Get-GitHubReleaseLatest.ps1 (78%) rename src/functions/public/Releases/{Releases => }/Get-GitHubRelease.ps1 (63%) rename src/functions/public/Releases/{Releases => }/New-GitHubRelease.ps1 (67%) rename src/functions/public/Releases/{Releases => }/New-GitHubReleaseNote.ps1 (68%) delete mode 100644 src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 rename src/functions/public/Releases/{Releases => }/Remove-GitHubRelease.ps1 (79%) create mode 100644 src/functions/public/Releases/Set-GitHubRelease.ps1 create mode 100644 src/functions/public/Releases/Update-GitHubRelease.ps1 rename {tests => tests copy}/Artifacts.Tests.ps1 (100%) create mode 100644 tests copy/Data/AuthCases.ps1 create mode 100644 tests copy/Data/IssueForm.md rename {tests => tests copy}/Environments.Tests.ps1 (100%) rename {tests => tests copy}/GitHub.Tests.ps1 (100%) rename {tests => tests copy}/Organizations.Tests.ps1 (100%) rename {tests => tests copy}/README.md (100%) rename {tests => tests copy}/Repositories.Tests.ps1 (100%) rename {tests => tests copy}/Secrets.Tests.ps1 (100%) rename {tests => tests copy}/TEMPLATE.ps1 (100%) rename {tests => tests copy}/Teams.Tests.ps1 (100%) rename {tests => tests copy}/Users.Tests.ps1 (100%) rename {tests => tests copy}/Variables.Tests.ps1 (100%) create mode 100644 tests/Releases.Tests.ps1 create mode 100644 tools/dev/Get-GitHubReleaseQL.ps1 diff --git a/.github/PSModule.yml b/.github/PSModule.yml index ed2d635e9..80afa1153 100644 --- a/.github/PSModule.yml +++ b/.github/PSModule.yml @@ -1,3 +1,18 @@ Test: + SourceCode: + Skip: true + PSModule: + Skip: true + Module: + Windows: + Skip: true + MacOS: + Skip: true CodeCoverage: - PercentTarget: 40 + Skip: true + PercentTarget: 50 + TestResults: + Skip: true +Build: + Docs: + Skip: true diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 new file mode 100644 index 000000000..e853fb744 --- /dev/null +++ b/examples/Releases/Releases.ps1 @@ -0,0 +1,60 @@ +# Get all the releases for a specific repository +Get-GitHubRelease -Owner PSModule -Repository GitHub + +# Get the latest release for a specific repository +Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest + +# Get all the releases for all repos in the organization +'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease + +# Get the latest releases for all repos in the organization +'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | ForEach-Object -ThrottleLimit ([Environment]::ProcessorCount) -Parallel { + do { + Import-Module -Name GitHub + } until ($? -eq $true) + $_ | Get-GitHubRelease -Latest +} + +'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease -Latest +Get-GitHubUser | Get-GitHubRepository | Get-GitHubRelease -Latest + +# Create a new release for a specific repository +$repoName = 'mytest' + +$repo = Get-GitHubUser | Get-GitHubRepository -Name $repoName +$repo | Get-GitHubRelease +$repo | New-GitHubRelease -Tag 'v1.0' -Latest +$repo | New-GitHubRelease -Tag 'v1.1' -Latest -Name 'test' +$repo | New-GitHubRelease -Tag 'v1.2' -Latest -Name 'test' -Notes 'Release notes' +$repo | New-GitHubRelease -Tag 'v1.3' -Latest -Name 'test' -GenerateReleaseNotes +$repo | Get-GitHubRelease -Tag 'v1.3' | Format-List +$repo | Get-GitHubRelease -Tag 'v1.3' | Update-GithubRelease -Notes 'Release notes1' +$repo | Update-GitHubRelease -Tag 'v1.3' -Name 'test123' -Debug + +$repo | New-GitHubRelease -Tag 'v1.3.2' -Latest -GenerateReleaseNotes -Debug +$repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List +$repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Debug +$repo | Set-GitHubRelease -Tag 'v1.3.1' -Latest -GenerateReleaseNotes -Notes 'Release notes' +$repo | Get-GitHubRelease -Tag 'v1.3.1' | Format-List +Get-GitHubReleaseAsset -Owner MariusStorhaug -Repository mytest -ReleaseID + +$repo | Set-GitHubRelease -Tag 'v1.5' -Latest -Name 'test' -Notes 'Release notes' | Select-Object * +$repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Draft -Prerelease | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Prerelease | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' -Latest | Select-Object Tag, Name, Latest, Prerelease, Draft +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' | Select-Object Tag, Name, Latest, Prerelease, Draft + +$repo | Get-GitHubRelease -Tag 'v1.4' | Select-Object * + +$repo | Set-GitHubRelease -Tag 'v1.4' -Name 'test2' + + +New-GitHubReleaseNote -Owner PSModule -Repository GitHub -Tag 'v0.22.0' -Target 'main' -PreviousTag 'v0.20.0' | Format-List + +$repo | Get-GitHubRelease | Remove-GitHubRelease + + +$repo | Remove-GitHubRepository -Confirm:$false diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 new file mode 100644 index 000000000..dc2bcab87 --- /dev/null +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -0,0 +1,146 @@ +class GitHubReleaseAsset : GitHubNode { + # Description: URL for downloading the asset + # Example: "https://github.com/PSModule/GitHub/releases/download/v0.22.1/asset.zip" + [string] $Url + + # Description: The file name of the asset + # Example: "Team Environment" + [string] $Name + + # Description: Label for the asset, can be null + # Example: null + [string] $Label + + # Description: State of the release asset (e.g., uploaded, open) + # Example: "uploaded" + [string] $State + + # Description: MIME type of the asset + # Example: "application/zip" + [string] $ContentType + + # Description: Size of the asset in bytes + # Example: 1024 + [int] $Size + + # Description: Number of times the asset was downloaded + # Example: 100 + [int] $Downloads + + # Description: Timestamp when the asset was created + # Example: "2025-04-11T09:03:38Z" + [datetime] $CreatedAt + + # Description: Timestamp when the asset was last updated + # Example: "2025-04-11T09:03:38Z" + [datetime] $UpdatedAt + + # Description: User who uploaded the asset, can be null + # Example: GitHubUser object or null + [GitHubUser] $Uploader + + GitHubReleaseAsset() {} + + GitHubReleaseAsset([PSCustomObject]$Object) { + $this.Url = $Object.url + $this.Name = $Object.name + $this.Label = $Object.label + $this.State = $Object.state + $this.ContentType = $Object.content_type + $this.Size = $Object.size + $this.Downloads = $Object.downloads + $this.CreatedAt = [datetime]::Parse($Object.created_at) + $this.UpdatedAt = [datetime]::Parse($Object.updated_at) + $this.Uploader = [GitHubUser]::new($Object.uploader) + } +} + +class GitHubRelease : GitHubNode { + # Name of the release, can be null + # Example: "v0.22.1" + [string] $Name + + # The repository where the environment is. + [string] $Repository + + # The owner of the environment. + [string] $Owner + + # The name of the tag + # Example: "v0.22.1" + [string] $Tag + + # Release notes or changelog, can be null + # Example: "## What's Changed\n### Other Changes\n* Fix: Enhance repository deletion feedback and fix typo..." + [string] $Notes + + # Specifies the commitish value that determines where the Git tag is created from + # Example: "main" + [string] $Target + + # True if the release is the latest release on the repo. + # Example: true + [bool] $Latest + + # True to create a draft (unpublished) release, false to create a published one + # Example: false + [bool] $Draft + + # Whether to identify the release as a prerelease or a full release + # Example: false + [bool] $Prerelease + + # GitHub URL for the release + # Example: "https://github.com/PSModule/GitHub/releases/tag/v0.22.1" + [string] $Url + + # User who authored the release + [GitHubUser] $Author + + # Timestamp when the release was created + # Example: "2025-04-11T09:03:38Z" + [System.Nullable[datetime]] $CreatedAt + + # Timestamp when the release was published, can be null + # Example: "2025-04-11T13:41:34Z" + [System.Nullable[datetime]] $PublishedAt + + # URL for the release tarball, can be null + # Example: "https://api.github.com/repos/PSModule/GitHub/tarball/v0.22.1" + [string] $TarballUrl + + # URL for the release zipball, can be null + # Example: "https://api.github.com/repos/PSModule/GitHub/zipball/v0.22.1" + [string] $ZipballUrl + + # Assets that are uploaded to the release. + [GitHubReleaseAsset[]] $Assets + + # Number of mentions in the release notes + # Example: 1 + [int] $Mentions + + GitHubRelease() {} + + GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository, [bool] $Latest) { + # From GitHubNode + $this.ID = $Object.id + $this.NodeID = $Object.node_id + + # From GitHubRelease + $this.Name = $Object.name + $this.Repository = $Repository + $this.Owner = $Owner + $this.Notes = $Object.body + $this.Url = $Object.html_url + $this.Author = [GitHubUser]::new($Object.author) + $this.Tag = $Object.tag_name + $this.Target = $Object.target_commitish + $this.Latest = $Latest + $this.Draft = $Object.draft + $this.Prerelease = $Object.prerelease + $this.CreatedAt = $Object.created_at + $this.PublishedAt = $Object.published_at + $this.Assets = $Object.assets | ForEach-Object { [GitHubReleaseAsset]::new($_) } + } +} diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml new file mode 100644 index 000000000..fcdceb8ad --- /dev/null +++ b/src/formats/GitHubRelease.Format.ps1xml @@ -0,0 +1,119 @@ + + + + + GitHubReleaseTable + + GitHubRelease + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tag + + + Owner + + + Repository + + + Url + + + Latest + + + Prerelease + + + Draft + + + + + + + + GitHubReleaseList + + GitHubRelease + + + + + + + Tag + + + Owner + + + Repository + + + Url + + + Author + + + Target + + + Latest + + + Draft + + + Prerelease + + + CreatedAt + + + PublishedAt + + + Assets + + + Name + + + Notes + + + + + + + + diff --git a/src/functions/private/Releases/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 similarity index 71% rename from src/functions/private/Releases/Releases/Get-GitHubReleaseAll.ps1 rename to src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index bd5c52614..00ed59b3f 100644 --- a/src/functions/private/Releases/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -13,11 +13,17 @@ Gets all the releases for the repository 'hello-world' owned by 'octocat'. - .NOTES - https://docs.github.com/rest/releases/releases#list-releases + .INPUTS + GitHubRepository + .OUTPUTS + GitHubRelease + + .LINK + [List releases](https://docs.github.com/rest/releases/releases#list-releases) #> - [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] + [OutputType([GitHubRelease])] + [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] @@ -28,7 +34,7 @@ [string] $Repository, # The number of results per page (max 100). - [Parameter(ParameterSetName = 'AllUsers')] + [Parameter()] [ValidateRange(0, 100)] [int] $PerPage, @@ -45,21 +51,26 @@ } process { - $body = @{ - per_page = $PerPage - } + $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases" Body = $body + PerPage = $PerPage Context = $Context } - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } + try { + Invoke-GitHubAPI @inputObject | ForEach-Object { + $_.Response | ForEach-Object { + $isLatest = $_.id -eq $latest.id + [GitHubRelease]::new($_, $Owner, $Repository, $isLatest) + } + } + } catch { return } } + end { Write-Debug "[$stackPath] - End" } diff --git a/src/functions/private/Releases/Releases/Get-GitHubReleaseByID.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 similarity index 73% rename from src/functions/private/Releases/Releases/Get-GitHubReleaseByID.ps1 rename to src/functions/private/Releases/Get-GitHubReleaseByID.ps1 index dc0c5c030..350bed5f1 100644 --- a/src/functions/private/Releases/Releases/Get-GitHubReleaseByID.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByID.ps1 @@ -12,10 +12,16 @@ Gets the release with the ID '1234567' for the repository 'hello-world' owned by 'octocat'. - .NOTES - https://docs.github.com/rest/releases/releases#get-a-release + .INPUTS + GitHubRepository + .OUTPUTS + GitHubRelease + + .LINK + [Get a release](https://docs.github.com/rest/releases/releases#get-a-release) #> + [OutputType([GitHubRelease])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -28,7 +34,6 @@ # The unique identifier of the release. [Parameter(Mandatory)] - [Alias('release_id')] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -44,15 +49,20 @@ } process { + $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context + $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" Context = $Context } - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } + try { + Invoke-GitHubAPI @inputObject | ForEach-Object { + $isLatest = $_.Response.id -eq $latest.id + [GitHubRelease]::new($_.Response, $Owner, $Repository, $isLatest) + } + } catch { return } } end { diff --git a/src/functions/private/Releases/Releases/Get-GitHubReleaseByTagName.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 similarity index 71% rename from src/functions/private/Releases/Releases/Get-GitHubReleaseByTagName.ps1 rename to src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 index 519cf54f4..3854a5ec1 100644 --- a/src/functions/private/Releases/Releases/Get-GitHubReleaseByTagName.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 @@ -11,10 +11,16 @@ Gets the release with the tag 'v1.0.0' for the repository 'hello-world' owned by 'octocat'. - .NOTES - https://docs.github.com/rest/releases/releases#get-a-release-by-tag-name + .INPUTS + GitHubRepository + .OUTPUTS + GitHubRelease + + .LINK + [Get a release by tag name](https://docs.github.com/rest/releases/releases#get-a-release-by-tag-name) #> + [OutputType([GitHubRelease])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -27,7 +33,6 @@ # The name of the tag to get a release from. [Parameter(Mandatory)] - [Alias('tag_name')] [string] $Tag, # The context to run the command in. Used to get the details for the API call. @@ -43,15 +48,20 @@ } process { + $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context + $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repository/releases/tags/$Tag" Context = $Context } - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } + try { + Invoke-GitHubAPI @inputObject | ForEach-Object { + $isLatest = $_.Response.id -eq $latest.id + [GitHubRelease]::new($_.Response, $Owner, $Repository, $isLatest) + } + } catch { return } } end { diff --git a/src/functions/private/Releases/Releases/Get-GitHubReleaseLatest.ps1 b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 similarity index 78% rename from src/functions/private/Releases/Releases/Get-GitHubReleaseLatest.ps1 rename to src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 index 80f7a6936..c699e2589 100644 --- a/src/functions/private/Releases/Releases/Get-GitHubReleaseLatest.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 @@ -13,10 +13,16 @@ Gets the latest releases for the repository 'hello-world' owned by 'octocat'. - .NOTES - https://docs.github.com/rest/releases/releases#get-the-latest-release + .INPUTS + GitHubRepository + .OUTPUTS + GitHubRelease + + .LINK + [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) #> + [OutputType([GitHubRelease])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -46,9 +52,11 @@ Context = $Context } - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } + try { + Invoke-GitHubAPI @inputObject | ForEach-Object { + [GitHubRelease]::new($_.Response, $Owner, $Repository, $true) + } + } catch { return } } end { diff --git a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 index 5106d462b..795146394 100644 --- a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 @@ -17,35 +17,32 @@ Gets the release assets for the release with the ID '7654321' for the repository 'octocat/hello-world'. - .NOTES - [Get a release asset](https://docs.github.com/rest/releases/assets#get-a-release-asset) + .INPUTS + GitHubRelease + + .OUTPUTS + GitHubReleaseAsset + + .LINK + https://psmodule.io/GitHub/Functions/Releases/Assets/Get-GitHubReleaseAsset #> - [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] + [OutputType([GitHubReleaseAsset])] + [CmdletBinding(DefaultParameterSetName = 'List assets from a release')] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The unique identifier of the asset. - [Parameter( - Mandatory, - ParameterSetName = 'ID' - )] - [Alias('asset_id')] + [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by ID')] [string] $ID, # The unique identifier of the release. - [Parameter( - Mandatory, - ParameterSetName = 'ReleaseID' - )] - [Alias('release_id')] + [Parameter(Mandatory, ParameterSetName = 'List assets from a release', ValueFromPipelineByPropertyName)] [string] $ReleaseID, # The context to run the command in. Used to get the details for the API call. diff --git a/src/functions/public/Releases/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 similarity index 63% rename from src/functions/public/Releases/Releases/Get-GitHubRelease.ps1 rename to src/functions/public/Releases/Get-GitHubRelease.ps1 index ede7522d6..76d6e81a0 100644 --- a/src/functions/public/Releases/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -1,7 +1,7 @@ filter Get-GitHubRelease { <# .SYNOPSIS - List releases + List releases. .DESCRIPTION This returns a list of releases, which does not include regular Git tags that have not been associated with a release. @@ -14,9 +14,9 @@ Gets the releases for the repository 'hello-world' owned by 'octocat'. .EXAMPLE - Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Latest + Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -All - Gets the latest releases for the repository 'hello-world' owned by 'octocat'. + Gets all releases for the repository 'hello-world' owned by 'octocat'. .EXAMPLE Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' @@ -28,21 +28,28 @@ Gets the release with the ID '1234567' for the repository 'hello-world' owned by 'octocat'. - .NOTES - [List releases](https://docs.github.com/rest/releases/releases#list-releases) - [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) + .INPUTS + GitHubRepository + + .OUTPUTS + GitHubRelease + + .LINK + https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSReviewUnusedParameter', 'Latest', + Justification = 'Using the ParameterSetName to determine the context of the command.' + )] + [OutputType([GitHubRelease])] [CmdletBinding(DefaultParameterSetName = 'All')] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Latest', Justification = 'Required for parameter set')] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The number of results per page (max 100). @@ -50,27 +57,16 @@ [ValidateRange(0, 100)] [int] $PerPage, - # Get the latest release only - [Parameter( - Mandatory, - ParameterSetName = 'Latest' - )] + # Get the latest release. + [Parameter(Mandatory, ParameterSetName = 'Latest')] [switch] $Latest, # The name of the tag to get a release from. - [Parameter( - Mandatory, - ParameterSetName = 'Tag' - )] - [Alias('tag_name')] + [Parameter(Mandatory, ParameterSetName = 'Tag')] [string] $Tag, # The unique identifier of the release. - [Parameter( - Mandatory, - ParameterSetName = 'ID' - )] - [Alias('release_id')] + [Parameter(Mandatory, ParameterSetName = 'ID')] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -87,21 +83,31 @@ } process { + $params = @{ + Owner = $Owner + Repository = $Repository + Context = $Context + } + Write-Debug "ParameterSet: $($PSCmdlet.ParameterSetName)" switch ($PSCmdlet.ParameterSetName) { 'All' { - Get-GitHubReleaseAll -Owner $Owner -Repository $Repository -PerPage $PerPage -Context $Context - } - 'Latest' { - Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context + Get-GitHubReleaseAll @params -PerPage $PerPage } 'Tag' { - Get-GitHubReleaseByTagName -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + $release = Get-GitHubReleaseByTagName @params -Tag $Tag + if ($release) { + $release + } else { + Get-GithubReleaseAll @params -PerPage $PerPage | Where-Object { $_.Tag -eq $Tag } + } } 'ID' { - Get-GitHubReleaseByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context + Get-GitHubReleaseByID @params -ID $ID + } + 'Latest' { + Get-GitHubReleaseLatest @params } } - } end { diff --git a/src/functions/public/Releases/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 similarity index 67% rename from src/functions/public/Releases/Releases/New-GitHubRelease.ps1 rename to src/functions/public/Releases/New-GitHubRelease.ps1 index 021a3900a..0c7904c65 100644 --- a/src/functions/public/Releases/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -11,38 +11,43 @@ and "[Dealing with secondary rate limits](https://docs.github.com/rest/guides/best-practices-for-integrators#dealing-with-secondary-rate-limits)" for details. .EXAMPLE - New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -TagName 'v1.0.0' -TargetCommitish 'main' -Body 'Release notes' + New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Target 'main' -Notes 'Release notes' - Creates a release for the repository 'octocat/hello-world' with the tag 'v1.0.0' and the target commitish 'main'. + Creates a release for the repository 'octocat/hello-world' on the 'main' branch with the tag 'v1.0.0'. - .NOTES + .INPUTS + GitHubRepository + + .OUTPUTS + GitHubRelease + + .LINK + https://psmodule.io/GitHub/Functions/Releases/New-GitHubRelease/ + + .LINK [Create a release](https://docs.github.com/rest/releases/releases#create-a-release) #> - [OutputType([pscustomobject])] + [OutputType([GitHubRelease])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] - [CmdletBinding(SupportsShouldProcess)] + [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The name of the tag. [Parameter(Mandatory)] - [Alias('tag_name')] - [string] $TagName, + [string] $Tag, - # Specifies the commitish value that determines where the Git tag is created from. + # Specifies the reference value that determines where the Git tag is created from. # Can be any branch or commit SHA. Unused if the Git tag already exists. # API Default: the repository's default branch. [Parameter()] - [Alias('target_commitish')] - [string] $TargetCommitish = 'main', + [string] $Target = 'main', # The name of the release. [Parameter()] @@ -50,33 +55,33 @@ # Text describing the contents of the tag. [Parameter()] - [string] $Body, + [string] $Notes, # Whether the release is a draft. - [Parameter()] + [Parameter(ParameterSetName = 'Not latest')] [switch] $Draft, # Whether to identify the release as a prerelease. - [Parameter()] + [Parameter(ParameterSetName = 'Not latest')] [switch] $Prerelease, # If specified, a discussion of the specified category is created and linked to the release. # The value must be a category that already exists in the repository. # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). [Parameter()] - [Alias('discussion_category_name')] [string] $DiscussionCategoryName, - # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise,a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. + # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, + # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. [Parameter()] - [Alias('generate_release_notes')] [switch] $GenerateReleaseNotes, - # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation date and higher semantic version. - [Parameter()] - [Alias('make_latest')] - [ValidateSet('true', 'false', 'legacy')] - [string] $MakeLatest = 'true', + # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. + # If not specified the latest release is determined based on the release creation date and higher semantic version. + # If set to true, the release will be set as the latest release for the repository. + # If set to false, the release will not be set as the latest release for the repository. + [Parameter(ParameterSetName = 'Set latest')] + [switch] $Latest, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -93,15 +98,15 @@ process { $body = @{ - tag_name = $TagName - target_commitish = $TargetCommitish + tag_name = $Tag + target_commitish = $Target name = $Name - body = $Body + body = $Notes discussion_category_name = $DiscussionCategoryName - make_latest = $MakeLatest - generate_release_notes = $GenerateReleaseNotes - draft = $Draft - prerelease = $Prerelease + generate_release_notes = [bool]$GenerateReleaseNotes + make_latest = ([bool]$Latest).ToString().ToLower() + draft = [bool]$Draft + prerelease = [bool]$Prerelease } $body | Remove-HashtableEntry -NullOrEmptyValues @@ -114,7 +119,7 @@ if ($PSCmdlet.ShouldProcess("$Owner/$Repository", 'Create a release')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubRelease]::new($_.Response , $Owner, $Repository, $Latest) } } } diff --git a/src/functions/public/Releases/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 similarity index 68% rename from src/functions/public/Releases/Releases/New-GitHubReleaseNote.ps1 rename to src/functions/public/Releases/New-GitHubReleaseNote.ps1 index 849b1ed34..6779c8d88 100644 --- a/src/functions/public/Releases/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 @@ -1,19 +1,18 @@ filter New-GitHubReleaseNote { <# .SYNOPSIS - List releases + Generate release notes content for a release. .DESCRIPTION - Generate a name and body describing a [release](https://docs.github.com/rest/releases/releases#get-a-release). - The body content will be Markdown formatted and contain information like - the changes since last release and users who contributed. The generated release notes are not saved anywhere. They are - intended to be generated and used when creating a new release. + Generate a name and body describing a [release](https://docs.github.com/rest/releases/releases#get-a-release). The body content will be + markdown formatted and contain information like the changes since last release and users who contributed. The generated release notes are not + saved anywhere. They are intended to be generated and used when creating a new release. .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - TagName = 'v1.0.0' + Owner = 'octocat' + Repo = 'hello-world' + Tag = 'v1.0.0' } New-GitHubReleaseNote @params @@ -23,10 +22,10 @@ .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - TagName = 'v1.0.0' - TargetCommitish = 'main' + Owner = 'octocat' + Repo = 'hello-world' + Tag = 'v1.0.0' + Target = 'main' } New-GitHubReleaseNote @params @@ -37,9 +36,9 @@ $params = @{ Owner = 'octocat' Repo = 'hello-world' - TagName = 'v1.0.0' - TargetCommitish = 'main' - PreviousTagName = 'v0.9.2' + Tag = 'v1.0.0' + Target = 'main' + PreviousTag = 'v0.9.2' ConfigurationFilePath = '.github/custom_release_config.yml' } New-GitHubReleaseNote @params @@ -48,8 +47,19 @@ The release notes will be based on the changes between the tags 'v0.9.2' and 'v1.0.0' and generated based on the configuration file located in the repository at '.github/custom_release_config.yml'. + .OUTPUTS + pscustomobject + .NOTES - [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#list-releases) + The returned object contains the following properties: + - Name: The name of the release. + - Notes: The body of the release notes. + + .LINK + https://psmodule.io/GitHub/Functions/Releases/New-GitHubReleaseNote/ + + .LINK + [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#generate-release-notes-content-for-a-release) #> [OutputType([pscustomobject])] [Alias('Generate-GitHubReleaseNotes')] @@ -57,39 +67,32 @@ [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The tag name for the release. This can be an existing tag or a new one. - [Parameter(Mandatory)] - [Alias('tag_name')] - [string] $TagName, + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Tag, # Specifies the commitish value that will be the target for the release's tag. # Required if the supplied tag_name does not reference an existing tag. # Ignored if the tag_name already exists. [Parameter()] - [Alias('target_commitish')] - [string] $TargetCommitish, + [string] $Target, # The name of the previous tag to use as the starting point for the release notes. # Use to manually specify the range for the set of changes considered as part this release. [Parameter()] - [Alias('previous_tag_name')] - [string] $PreviousTagName, - + [string] $PreviousTag, # Specifies a path to a file in the repository containing configuration settings used for generating the release notes. # If unspecified, the configuration file located in the repository at '.github/release.yml' or '.github/release.yaml' will be used. # If that is not present, the default configuration will be used. [Parameter()] - [Alias('configuration_file_path')] [string] $ConfigurationFilePath, # The context to run the command in. Used to get the details for the API call. @@ -107,9 +110,9 @@ process { $body = @{ - tag_name = $TagName - target_commitish = $TargetCommitish - previous_tag_name = $PreviousTagName + tag_name = $Tag + target_commitish = $Target + previous_tag_name = $PreviousTag configuration_file_path = $ConfigurationFilePath } $body | Remove-HashtableEntry -NullOrEmptyValues @@ -118,11 +121,15 @@ Method = 'POST' APIEndpoint = "/repos/$Owner/$Repository/releases/generate-notes" Body = $body + Context = $Context } - if ($PSCmdlet.ShouldProcess("$Owner/$Repository", 'Create release notes')) { + if ($PSCmdlet.ShouldProcess("release notes for release on $Owner/$Repository", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [PSCustomObject]@{ + Name = $_.Response.name + Notes = $_.Response.body + } } } } diff --git a/src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 deleted file mode 100644 index 1559ef234..000000000 --- a/src/functions/public/Releases/Releases/Set-GitHubRelease.ps1 +++ /dev/null @@ -1,124 +0,0 @@ -filter Set-GitHubRelease { - <# - .SYNOPSIS - Update a release - - .DESCRIPTION - Users with push access to the repository can edit a release. - - .EXAMPLE - Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Body 'Release notes' - - Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the body 'Release notes'. - - .NOTES - [Update a release](https://docs.github.com/rest/releases/releases#update-a-release) - #> - [OutputType([pscustomobject])] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] - [CmdletBinding(SupportsShouldProcess)] - param( - # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] - [string] $Owner, - - # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] - [string] $Repository, - - # The unique identifier of the release. - [Parameter(Mandatory)] - [Alias('release_id')] - [string] $ID, - - # The name of the tag. - [Parameter()] - [Alias('tag_name')] - [string] $TagName, - - # Specifies the commitish value that determines where the Git tag is created from. - # Can be any branch or commit SHA. Unused if the Git tag already exists. - # API Default: the repository's default branch. - [Parameter()] - [Alias('target_commitish')] - [string] $TargetCommitish, - - # The name of the release. - [Parameter()] - [string] $Name, - - # Text describing the contents of the tag. - [Parameter()] - [string] $Body, - - # Whether the release is a draft. - [Parameter()] - [switch] $Draft, - - # Whether to identify the release as a prerelease. - [Parameter()] - [switch] $Prerelease, - - # If specified, a discussion of the specified category is created and linked to the release. - # The value must be a category that already exists in the repository. - # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). - [Parameter()] - [Alias('discussion_category_name')] - [string] $DiscussionCategoryName, - - # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. - # Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation - # date and higher semantic version. - [Parameter()] - [Alias('make_latest')] - [ValidateSet('true', 'false', 'legacy')] - [string] $MakeLatest = 'true', - - # The context to run the command in. Used to get the details for the API call. - # Can be either a string or a GitHubContext object. - [Parameter()] - [object] $Context = (Get-GitHubContext) - ) - - begin { - $stackPath = Get-PSCallStackPath - Write-Debug "[$stackPath] - Start" - $Context = Resolve-GitHubContext -Context $Context - Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - } - - process { - $body = @{ - tag_name = $TagName - target_commitish = $TargetCommitish - name = $Name - body = $Body - discussion_category_name = $DiscussionCategoryName - make_latest = $MakeLatest - draft = $Draft - prerelease = $Prerelease - } - $body | Remove-HashtableEntry -NullOrEmptyValues - - $inputObject = @{ - Method = 'PATCH' - APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" - Body = $body - Context = $Context - } - - if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } - } - } - - end { - Write-Debug "[$stackPath] - End" - } -} - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Releases/Releases/Remove-GitHubRelease.ps1 b/src/functions/public/Releases/Remove-GitHubRelease.ps1 similarity index 79% rename from src/functions/public/Releases/Releases/Remove-GitHubRelease.ps1 rename to src/functions/public/Releases/Remove-GitHubRelease.ps1 index 1184c427e..fcf93b6a4 100644 --- a/src/functions/public/Releases/Releases/Remove-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Remove-GitHubRelease.ps1 @@ -11,27 +11,28 @@ Deletes the release with the ID '1234567' for the repository 'octocat/hello-world'. - .NOTES + .INPUTS + GitHubRelease + + .LINK + https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ + + .LINK [Delete a release](https://docs.github.com/rest/releases/releases#delete-a-release) #> - [OutputType([pscustomobject])] + [OutputType([void])] [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, # The unique identifier of the release. - [Parameter( - Mandatory - )] - [Alias('release_id')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $ID, # The context to run the command in. Used to get the details for the API call. @@ -54,10 +55,8 @@ Context = $Context } - if ($PSCmdlet.ShouldProcess("Release with ID [$ID] in [$Owner/$Repository]", 'DELETE')) { - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } + if ($PSCmdlet.ShouldProcess("Release with ID [$ID] in [$Owner/$Repository]", 'Delete')) { + $null = Invoke-GitHubAPI @inputObject } } diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 new file mode 100644 index 000000000..5c86cabeb --- /dev/null +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -0,0 +1,127 @@ +filter Set-GitHubRelease { + <# + .SYNOPSIS + Creates or updates a release. + + .DESCRIPTION + + + .EXAMPLE + Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Target 'main' -Notes 'Release notes' + + .INPUTS + GitHubRepository + + .OUTPUTS + GitHubRelease + + .LINK + https://psmodule.io/GitHub/Functions/Releases/Set-GitHubRelease/ + #> + [OutputType([GitHubRelease])] + [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] + param( + # The account owner of the repository. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Repository, + + # The name of the tag. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Tag, + + # Specifies the reference value that determines where the Git tag is created from. + # Can be any branch or commit SHA. Unused if the Git tag already exists. + # API Default: the repository's default branch. + [Parameter()] + [string] $Target = 'main', + + # The name of the release. + [Parameter()] + [string] $Name = '', + + # Text describing the contents of the tag. + [Parameter()] + [string] $Notes = '', + + # Whether the release is a draft. + [Parameter(ParameterSetName = 'Not latest')] + [switch] $Draft, + + # Whether to identify the release as a prerelease. + [Parameter(ParameterSetName = 'Not latest')] + [switch] $Prerelease, + + # If specified, a discussion of the specified category is created and linked to the release. + # The value must be a category that already exists in the repository. + [Parameter()] + [string] $DiscussionCategoryName, + + # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, + # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. + [Parameter()] + [switch] $GenerateReleaseNotes, + + # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting + # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. + [Parameter(Mandatory, ParameterSetName = 'Set latest')] + [switch] $Latest, + + # The context to run the command in. Used to get the details for the API call. + # Can be either a string or a GitHubContext object. + [Parameter()] + [object] $Context = (Get-GitHubContext) + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + $Context = Resolve-GitHubContext -Context $Context + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + } + + process { + $scope = @{ + Owner = $Owner + Repository = $Repository + Context = $Context + } + + $params = @{ + Tag = $Tag + Target = $Target + Name = $Name + Notes = $Notes + GenerateReleaseNotes = [bool]$GenerateReleaseNotes + DiscussionCategoryName = $DiscussionCategoryName + } + + switch ($PSCmdlet.ParameterSetName) { + 'Set latest' { + $params['Latest'] = [bool]$Latest + } + 'Not latest' { + $params['Draft'] = [bool]$Draft + $params['Prerelease'] = [bool]$Prerelease + } + } + + $release = Get-GitHubRelease @scope -Tag $Tag + if ($release) { + $ID = $release.ID + $params['ID'] = $ID + Update-GitHubRelease @scope @params -Declare + } else { + New-GitHubRelease @scope @params + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} + +#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 new file mode 100644 index 000000000..46139888c --- /dev/null +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -0,0 +1,168 @@ +filter Update-GitHubRelease { + <# + .SYNOPSIS + Update a release + + .DESCRIPTION + Users with push access to the repository can edit a release. + + .EXAMPLE + Update-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Notes 'Release notes' + + Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the note 'Release notes'. + + .NOTES + [Update a release](https://docs.github.com/rest/releases/releases#update-a-release) + #> + [OutputType([pscustomobject])] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] + [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] + param( + # The account owner of the repository. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [string] $Repository, + + # The unique identifier of the release. + [Parameter()] + [string] $ID, + + # The name of the tag. + [Parameter()] + [string] $Tag, + + # Specifies the commitish value that determines where the Git tag is created from. + # Can be any branch or commit SHA. Unused if the Git tag already exists. + # API Default: the repository's default branch. + [Parameter()] + [string] $Target, + + # The name of the release. + [Parameter()] + [string] $Name, + + # Text describing the contents of the tag. + [Parameter()] + [string] $Notes, + + # Whether the release is a draft. + [Parameter(ParameterSetName = 'Not latest')] + [switch] $Draft, + + # Whether to identify the release as a prerelease. + [Parameter(ParameterSetName = 'Not latest')] + [switch] $Prerelease, + + # If specified, a discussion of the specified category is created and linked to the release. + # The value must be a category that already exists in the repository. + # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). + [Parameter()] + [string] $DiscussionCategoryName, + + # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, + # a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. + [Parameter()] + [switch] $GenerateReleaseNotes, + + # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting + # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. + [Parameter(Mandatory, ParameterSetName = 'Set latest')] + [switch] $Latest, + + # Takes all parameters and updates the release with the provided _AND_ the default values of the non-provided parameters. + # Used for Set-GitHubRelease. + [Parameter()] + [switch] $Declare, + + # The release to update + [Parameter(ValueFromPipeline)] + [GitHubRelease] $ReleaseObject, + + # The context to run the command in. Used to get the details for the API call. + # Can be either a string or a GitHubContext object. + [Parameter()] + [object] $Context = (Get-GitHubContext) + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + $Context = Resolve-GitHubContext -Context $Context + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + } + + process { + $ID = $ReleaseObject.ID + + if (-not $ID -and -not $Tag) { + throw 'You must specify either the ID or the Tag parameter.' + } + + if ($GenerateReleaseNotes) { + $generated = New-GitHubReleaseNote -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + $Name = -not [string]::IsNullOrEmpty($Name) ? $Name : $generated.Name + $Notes = -not [string]::IsNullOrEmpty($Notes) ? $Notes, $generated.Notes -join "`n" : $generated.Notes + } + + $body = @{ + tag_name = $Tag + target_commitish = $Target + name = $Name + body = $Notes + } + + if ([string]::IsNullOrEmpty($ID) -and -not [string]::IsNullOrEmpty($Tag)) { + $release = if ($ReleaseObject) { + $ReleaseObject + } else { + Get-GitHubRelease -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + } + if (-not $release) { + throw "Release with tag [$Tag] not found in [$Owner/$Repository]." + } + $ID = $release.ID + $body.Remove('tag_name') + } + + $repo = Get-GitHubRepositoryByName -Owner $Owner -Name $Repository -Context $Context + if ($repo.HasDiscussions) { + $body['discussion_category_name'] = $DiscussionCategoryName + } + if (-not $Declare) { + $body | Remove-HashtableEntry -NullOrEmptyValues + } + + if ($Latest) { + $body['make_latest'] = [bool]$Latest.ToString().ToLower() + $body['prerelease'] = $false + $body['draft'] = $false + } + if ($Draft -or $Prerelease) { + $body['make_latest'] = $false + $body['prerelease'] = [bool]$Prerelease + $body['draft'] = [bool]$Draft + } + + $inputObject = @{ + Method = 'PATCH' + APIEndpoint = "/repos/$Owner/$Repository/releases/$ID" + Body = $body + Context = $Context + } + + if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { + Invoke-GitHubAPI @inputObject | ForEach-Object { + [GitHubRelease]::new($_.Response , $Owner, $Repository, $Latest) + } + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} + +#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/tests/Artifacts.Tests.ps1 b/tests copy/Artifacts.Tests.ps1 similarity index 100% rename from tests/Artifacts.Tests.ps1 rename to tests copy/Artifacts.Tests.ps1 diff --git a/tests copy/Data/AuthCases.ps1 b/tests copy/Data/AuthCases.ps1 new file mode 100644 index 000000000..63c7f1438 --- /dev/null +++ b/tests copy/Data/AuthCases.ps1 @@ -0,0 +1,83 @@ +@( + @{ + AuthType = 'PAT' + Type = 'a user' + Case = 'Fine-grained PAT token' + TokenType = 'USER_FG_PAT' + Target = 'it self (user account)' + Owner = 'psmodule-user' + OwnerType = 'user' + ConnectParams = @{ + Token = $env:TEST_USER_USER_FG_PAT + } + } + @{ + AuthType = 'PAT' + Type = 'a user' + Case = 'Fine-grained PAT token' + TokenType = 'ORG_FG_PAT' + Target = 'organization account' + Owner = 'psmodule-test-org2' + OwnerType = 'organization' + ConnectParams = @{ + Token = $env:TEST_USER_ORG_FG_PAT + } + } + @{ + AuthType = 'PAT' + Type = 'a user' + Case = 'Classic PAT token' + TokenType = 'PAT' + Target = 'user account' + Owner = 'psmodule-user' + OwnerType = 'user' + ConnectParams = @{ + Token = $env:TEST_USER_PAT + } + } + @{ + AuthType = 'IAT' + Type = 'GitHub Actions' + Case = 'GITHUB_TOKEN' + TokenType = 'GITHUB_TOKEN' + Target = 'this repository (GitHub)' + Owner = 'PSModule' + Repo = 'GitHub' + OwnerType = 'repository' + ConnectParams = @{ + Token = $env:GITHUB_TOKEN + } + } + @{ + AuthType = 'App' + Type = 'a GitHub App from an Enterprise' + Case = 'PEM + IAT' + TokenType = 'APP_ENT' + Target = 'organization account' + Owner = 'psmodule-test-org3' + OwnerType = 'organization' + ConnectParams = @{ + ClientID = $env:TEST_APP_ENT_CLIENT_ID + PrivateKey = $env:TEST_APP_ENT_PRIVATE_KEY + } + ConnectAppParams = @{ + Organization = 'psmodule-test-org3' + } + } + @{ + AuthType = 'App' + Type = 'a GitHub App from an Organization' + Case = 'PEM + IAT' + TokenType = 'APP_ORG' + Target = 'organization account' + Owner = 'psmodule-test-org' + OwnerType = 'organization' + ConnectParams = @{ + ClientID = $env:TEST_APP_ORG_CLIENT_ID + PrivateKey = $env:TEST_APP_ORG_PRIVATE_KEY + } + ConnectAppParams = @{ + Organization = 'psmodule-test-org' + } + } +) diff --git a/tests copy/Data/IssueForm.md b/tests copy/Data/IssueForm.md new file mode 100644 index 000000000..83b1b3967 --- /dev/null +++ b/tests copy/Data/IssueForm.md @@ -0,0 +1,19 @@ + +### Type with spaces + +Action + +### Multiline + +test +is multi + line + +### OS + +- [x] Windows +- [x] Linux +- [ ] macOS + diff --git a/tests/Environments.Tests.ps1 b/tests copy/Environments.Tests.ps1 similarity index 100% rename from tests/Environments.Tests.ps1 rename to tests copy/Environments.Tests.ps1 diff --git a/tests/GitHub.Tests.ps1 b/tests copy/GitHub.Tests.ps1 similarity index 100% rename from tests/GitHub.Tests.ps1 rename to tests copy/GitHub.Tests.ps1 diff --git a/tests/Organizations.Tests.ps1 b/tests copy/Organizations.Tests.ps1 similarity index 100% rename from tests/Organizations.Tests.ps1 rename to tests copy/Organizations.Tests.ps1 diff --git a/tests/README.md b/tests copy/README.md similarity index 100% rename from tests/README.md rename to tests copy/README.md diff --git a/tests/Repositories.Tests.ps1 b/tests copy/Repositories.Tests.ps1 similarity index 100% rename from tests/Repositories.Tests.ps1 rename to tests copy/Repositories.Tests.ps1 diff --git a/tests/Secrets.Tests.ps1 b/tests copy/Secrets.Tests.ps1 similarity index 100% rename from tests/Secrets.Tests.ps1 rename to tests copy/Secrets.Tests.ps1 diff --git a/tests/TEMPLATE.ps1 b/tests copy/TEMPLATE.ps1 similarity index 100% rename from tests/TEMPLATE.ps1 rename to tests copy/TEMPLATE.ps1 diff --git a/tests/Teams.Tests.ps1 b/tests copy/Teams.Tests.ps1 similarity index 100% rename from tests/Teams.Tests.ps1 rename to tests copy/Teams.Tests.ps1 diff --git a/tests/Users.Tests.ps1 b/tests copy/Users.Tests.ps1 similarity index 100% rename from tests/Users.Tests.ps1 rename to tests copy/Users.Tests.ps1 diff --git a/tests/Variables.Tests.ps1 b/tests copy/Variables.Tests.ps1 similarity index 100% rename from tests/Variables.Tests.ps1 rename to tests copy/Variables.Tests.ps1 diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 new file mode 100644 index 000000000..9507edce8 --- /dev/null +++ b/tests/Releases.Tests.ps1 @@ -0,0 +1,84 @@ +#Requires -Modules @{ ModuleName = 'Pester'; RequiredVersion = '5.7.1' } + +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', '', + Justification = 'Pester grouping syntax: known issue.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidUsingConvertToSecureStringWithPlainText', '', + Justification = 'Used to create a secure string for testing.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidUsingWriteHost', '', + Justification = 'Log outputs to GitHub Actions logs.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidLongLines', '', + Justification = 'Long test descriptions and skip switches' +)] +[CmdletBinding()] +param() + +BeforeAll { + $testName = 'ReleasesTests' + $os = $env:RUNNER_OS + $guid = [guid]::NewGuid().ToString() +} + +Describe 'Releases' { + $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" + + Context 'As using on ' -ForEach $authCases { + BeforeAll { + $context = Connect-GitHubAccount @connectParams -PassThru -Silent + LogGroup 'Context' { + Write-Host ($context | Format-Table | Out-String) + } + if ($AuthType -eq 'APP') { + LogGroup 'Context - Installation' { + $context = Connect-GitHubApp @connectAppParams -PassThru -Default -Silent + Write-Host ($context | Format-Table | Out-String) + } + } + $repoPrefix = "$testName-$os-$TokenType" + $repoName = "$repoPrefix-$guid" + $variablePrefix = ("$testName`_$os`_$TokenType" -replace '-', '_').ToUpper() + $varName = ("$variablePrefix`_$guid" -replace '-', '_').ToUpper() + $environmentName = "$testName-$os-$TokenType-$guid" + + switch ($OwnerType) { + 'user' { + $repo = New-GitHubRepository -Name $repoName -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio + } + 'organization' { + $repo = New-GitHubRepository -Organization $owner -Name $repoName -AllowSquashMerge + } + } + LogGroup "Repository - [$repoName]" { + Write-Host ($repo | Format-Table | Out-String) + } + } + + AfterAll { + switch ($OwnerType) { + 'user' { + Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false + } + 'organization' { + Get-GitHubRepository -Owner $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false + } + } + Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent + } + + Context 'Releases' { + It 'New-GitHubRelease - Creates a new release' { + $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest + LogGroup 'Release' { + Write-Host ($item | Format-Table | Out-String) + } + $item | Should -Not -BeNullOrEmpty + } + } + } +} diff --git a/tools/dev/Get-GitHubReleaseQL.ps1 b/tools/dev/Get-GitHubReleaseQL.ps1 new file mode 100644 index 000000000..64dcb4a92 --- /dev/null +++ b/tools/dev/Get-GitHubReleaseQL.ps1 @@ -0,0 +1,124 @@ +function Get-GitHubReleaseQL { + <# + .SYNOPSIS + Get all releases with nested pagination for assets + + .DESCRIPTION + Gets all releases with their complete asset lists using nested pagination through both releases and their assets. + + .EXAMPLE + Get-GitHubRelease -Owner 'github' -Repository 'my-repo' -PerPage 10 -Context $context + #> + [OutputType([GitHubRelease])] + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [string] $Owner, + + [Parameter(Mandatory)] + [string] $Repository, + + [ValidateRange(1, 100)] + [int] $PerPage, + + [Parameter()] + [object] $Context = (Get-GitHubContext) + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + + $releaseCursor = $null + $releaseQuery = @' +query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: Int!) { + repository(owner: $owner, name: $repository) { + releases(first: $perPage, after: $releaseCursor, orderBy: {field: CREATED_AT, direction: DESC}) { + nodes { + id + databaseId + name + tagName + description + isDraft + isPrerelease + isLatest + createdAt + publishedAt + updatedAt + tag { + name + id + } + tagCommit { + oid + } + url + author { + login + id + databaseId + } + releaseAssets(first: $perPage) { + nodes { + name + downloadCount + downloadUrl + contentType + createdAt + updatedAt + uploadedBy { + login + name + id + databaseId + } + size + url + id + } + } + } + pageInfo { + hasNextPage + endCursor + } + } + } +} +'@ + + $PerPage = $PSBoundParameters.ContainsKey('PerPage') ? $PerPage : $Context.PerPage + } + + process { + do { + $releaseVariables = @{ + owner = $Owner + repository = $Repository + releaseCursor = $releaseCursor + perPage = $PerPage + } + + $result = Invoke-GitHubGraphQLQuery -Query $releaseQuery -Variables $releaseVariables -Context $Context + if (-not $result) { break } + + $repositoryData = $result.repository + if (-not $repositoryData) { break } + + $releases = $repositoryData.releases + if (-not $releases) { break } + + $releases.nodes | ForEach-Object { + # [GitHubRelease]::new($_) + } + + $releaseCursor = $releases.pageInfo.endCursor + } while ($releases.pageInfo.hasNextPage) + } + + end { + Write-Debug "[$stackPath] - End" + } +} From 1ed9d010ca58dad1fc92b9713ee238bcb1db3cc2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 11:58:50 +0200 Subject: [PATCH 127/224] Refactor parameter aliases for GitHub release functions to consolidate 'Organization' and 'User' into a single alias --- .../Assets/Add-GitHubReleaseAsset.ps1 | 4 +--- .../Assets/Get-GitHubReleaseAsset.ps1 | 1 + .../Assets/Remove-GitHubReleaseAsset.ps1 | 4 +--- .../Assets/Set-GitHubReleaseAsset.ps1 | 4 +--- .../public/Releases/Get-GitHubRelease.ps1 | 1 + .../public/Releases/New-GitHubRelease.ps1 | 1 + .../public/Releases/New-GitHubReleaseNote.ps1 | 1 + .../public/Releases/Remove-GitHubRelease.ps1 | 1 + .../public/Releases/Set-GitHubRelease.ps1 | 1 + .../public/Releases/Update-GitHubRelease.ps1 | 1 + src/types/GitHubRelease.Types.ps1xml | 12 ++++++++++++ tests/Releases.Tests.ps1 | 19 ++++++++++++------- 12 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 src/types/GitHubRelease.Types.ps1xml diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index b52da2c5e..bb0c9a613 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -48,8 +48,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. @@ -58,7 +57,6 @@ # The unique identifier of the release. [Parameter(Mandatory)] - [Alias('release_id')] [string] $ID, #The name of the file asset. diff --git a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 index 795146394..5e303537f 100644 --- a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 @@ -31,6 +31,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. diff --git a/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 index b6eaecfe8..7f754684a 100644 --- a/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 @@ -18,8 +18,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. @@ -28,7 +27,6 @@ # The unique identifier of the asset. [Parameter(Mandatory)] - [Alias('asset_id')] [string] $ID, # The context to run the command in. Used to get the details for the API call. diff --git a/src/functions/public/Releases/Assets/Set-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Set-GitHubReleaseAsset.ps1 index a5def48de..534ff02d8 100644 --- a/src/functions/public/Releases/Assets/Set-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Set-GitHubReleaseAsset.ps1 @@ -19,8 +19,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] - [Alias('Organization')] - [Alias('User')] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. @@ -29,7 +28,6 @@ # The unique identifier of the asset. [Parameter(Mandatory)] - [Alias('asset_id')] [string] $ID, #The name of the file asset. diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index 76d6e81a0..9a19b411e 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -46,6 +46,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 index 0c7904c65..81d755333 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -33,6 +33,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. diff --git a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 index 6779c8d88..db375f580 100644 --- a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 @@ -68,6 +68,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. diff --git a/src/functions/public/Releases/Remove-GitHubRelease.ps1 b/src/functions/public/Releases/Remove-GitHubRelease.ps1 index fcf93b6a4..738c94ddb 100644 --- a/src/functions/public/Releases/Remove-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Remove-GitHubRelease.ps1 @@ -25,6 +25,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 5c86cabeb..b932e4d94 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -23,6 +23,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 46139888c..38cac59d9 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -20,6 +20,7 @@ param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] + [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. diff --git a/src/types/GitHubRelease.Types.ps1xml b/src/types/GitHubRelease.Types.ps1xml new file mode 100644 index 000000000..1c1acc885 --- /dev/null +++ b/src/types/GitHubRelease.Types.ps1xml @@ -0,0 +1,12 @@ + + + + GitHubRelease + + + Release + $this.ID + + + + diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 9507edce8..eed21fc62 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -42,16 +42,21 @@ Describe 'Releases' { } $repoPrefix = "$testName-$os-$TokenType" $repoName = "$repoPrefix-$guid" - $variablePrefix = ("$testName`_$os`_$TokenType" -replace '-', '_').ToUpper() - $varName = ("$variablePrefix`_$guid" -replace '-', '_').ToUpper() - $environmentName = "$testName-$os-$TokenType-$guid" - + + $params = @{ + Name = $repoName + Context = $context + AllowSquashMerge = $true + AddReadme = $true + License = 'mit' + Gitignore = 'VisualStudio' + } switch ($OwnerType) { 'user' { - $repo = New-GitHubRepository -Name $repoName -AllowSquashMerge -AddReadme -License mit -Gitignore VisualStudio + $repo = New-GitHubRepository @params } 'organization' { - $repo = New-GitHubRepository -Organization $owner -Name $repoName -AllowSquashMerge + $repo = New-GitHubRepository @params -Organization $owner } } LogGroup "Repository - [$repoName]" { @@ -65,7 +70,7 @@ Describe 'Releases' { Get-GitHubRepository | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false } 'organization' { - Get-GitHubRepository -Owner $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false + Get-GitHubRepository -Organization $Owner | Where-Object { $_.Name -like "$repoPrefix*" } | Remove-GitHubRepository -Confirm:$false } } Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent From a30eb5f030248de3f8a2eb1e838d4fa7f735c69d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 12:19:06 +0200 Subject: [PATCH 128/224] Fix formatting and adjust context skip condition in Releases tests --- tests/Releases.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index eed21fc62..6123b50c7 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -42,7 +42,7 @@ Describe 'Releases' { } $repoPrefix = "$testName-$os-$TokenType" $repoName = "$repoPrefix-$guid" - + $params = @{ Name = $repoName Context = $context @@ -76,7 +76,7 @@ Describe 'Releases' { Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent } - Context 'Releases' { + Context 'Releases' -Skip:($OwnerType -eq 'repository') { It 'New-GitHubRelease - Creates a new release' { $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest LogGroup 'Release' { From 21540971fc944d23372121ff591f6dbc6325d9f9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 12:27:36 +0200 Subject: [PATCH 129/224] Add tests for New-GitHubRelease function to validate release creation scenarios --- .../public/Releases/New-GitHubRelease.ps1 | 2 -- tests/Releases.Tests.ps1 | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 index 81d755333..cbbead9a3 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -129,5 +129,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 6123b50c7..df39c5e74 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -84,6 +84,34 @@ Describe 'Releases' { } $item | Should -Not -BeNullOrEmpty } + + It 'New-GitHubRelease - Throws when tag already exists' { + { New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest } | Should -Throw + } + + It 'New-GitHubRelease - Creates a new release with a draft' { + $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.2' -Draft + LogGroup 'Release' { + Write-Host ($item | Format-Table | Out-String) + } + $item | Should -Not -BeNullOrEmpty + } + + It 'New-GitHubRelease - Creates a new release with a pre-release' { + $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.1' -PreRelease + LogGroup 'Release' { + Write-Host ($item | Format-Table | Out-String) + } + $item | Should -Not -BeNullOrEmpty + } + + It 'New-GitHubRelease - Creates a new release with a name' { + $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Test Release' -GenerateReleaseNotes + LogGroup 'Release' { + Write-Host ($item | Format-Table | Out-String) + } + $item | Should -Not -BeNullOrEmpty + } } } } From 0adb584b5bde750d208c151ae187165ff75f7465 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 12:34:09 +0200 Subject: [PATCH 130/224] Refactor New-GitHubRelease tests to use consistent variable naming and improve output formatting --- tests/Releases.Tests.ps1 | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index df39c5e74..0b4ebdade 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -78,11 +78,11 @@ Describe 'Releases' { Context 'Releases' -Skip:($OwnerType -eq 'repository') { It 'New-GitHubRelease - Creates a new release' { - $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest + $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest LogGroup 'Release' { - Write-Host ($item | Format-Table | Out-String) + Write-Host ($release | Format-List -Property * | Out-String) } - $item | Should -Not -BeNullOrEmpty + $release | Should -Not -BeNullOrEmpty } It 'New-GitHubRelease - Throws when tag already exists' { @@ -90,27 +90,35 @@ Describe 'Releases' { } It 'New-GitHubRelease - Creates a new release with a draft' { - $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.2' -Draft + $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.2' -Draft LogGroup 'Release' { - Write-Host ($item | Format-Table | Out-String) + Write-Host ($release | Format-List -Property * | Out-String) } - $item | Should -Not -BeNullOrEmpty + $release | Should -Not -BeNullOrEmpty } It 'New-GitHubRelease - Creates a new release with a pre-release' { - $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.1' -PreRelease + $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.1' -PreRelease LogGroup 'Release' { - Write-Host ($item | Format-Table | Out-String) + Write-Host ($release | Format-List -Property * | Out-String) } - $item | Should -Not -BeNullOrEmpty + $release | Should -Not -BeNullOrEmpty } It 'New-GitHubRelease - Creates a new release with a name' { - $item = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Test Release' -GenerateReleaseNotes + $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Test Release' -GenerateReleaseNotes LogGroup 'Release' { - Write-Host ($item | Format-Table | Out-String) + Write-Host ($release | Format-List -Property * | Out-String) } - $item | Should -Not -BeNullOrEmpty + $release | Should -Not -BeNullOrEmpty + } + + It 'Get-GitHubRelease - Gets all releases' { + $releases = Get-GitHubRelease -Owner $Owner -Repository $repo + LogGroup 'Releases' { + Write-Host ($releases | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty } } } From 91516931a61b6c6e4b9d10cc88d831d575bc5979 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 12:41:38 +0200 Subject: [PATCH 131/224] Add debug flag to Get-GitHubRelease test for improved output visibility --- tests/Releases.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 0b4ebdade..5242bb461 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -114,7 +114,7 @@ Describe 'Releases' { } It 'Get-GitHubRelease - Gets all releases' { - $releases = Get-GitHubRelease -Owner $Owner -Repository $repo + $releases = Get-GitHubRelease -Owner $Owner -Repository $repo -Debug LogGroup 'Releases' { Write-Host ($releases | Format-List -Property * | Out-String) } From 7fefb5e1dcdc2dc85f08c225ae480c162d1acf3c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 13:01:04 +0200 Subject: [PATCH 132/224] Update Get-GitHubRelease cmdlet to support 'AllVersions' parameter and adjust examples accordingly --- .../public/Releases/Get-GitHubRelease.ps1 | 26 +++++++++---------- tests/Releases.Tests.ps1 | 14 +++++++--- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index 9a19b411e..f95a3fbbe 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -11,10 +11,10 @@ .EXAMPLE Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' - Gets the releases for the repository 'hello-world' owned by 'octocat'. + Gets the latest release for the repository 'hello-world' owned by 'octocat'. .EXAMPLE - Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -All + Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -AllVersions Gets all releases for the repository 'hello-world' owned by 'octocat'. @@ -38,11 +38,11 @@ https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( - 'PSReviewUnusedParameter', 'Latest', + 'PSReviewUnusedParameter', 'AllVersions', Justification = 'Using the ParameterSetName to determine the context of the command.' )] [OutputType([GitHubRelease])] - [CmdletBinding(DefaultParameterSetName = 'All')] + [CmdletBinding(DefaultParameterSetName = 'Latest')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] @@ -53,14 +53,9 @@ [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, - # The number of results per page (max 100). - [Parameter(ParameterSetName = 'All')] - [ValidateRange(0, 100)] - [int] $PerPage, - - # Get the latest release. - [Parameter(Mandatory, ParameterSetName = 'Latest')] - [switch] $Latest, + # Get all releases instead of just the latest. + [Parameter(Mandatory, ParameterSetName = 'AllVersions')] + [switch] $AllVersions, # The name of the tag to get a release from. [Parameter(Mandatory, ParameterSetName = 'Tag')] @@ -70,6 +65,11 @@ [Parameter(Mandatory, ParameterSetName = 'ID')] [string] $ID, + # The number of results per page (max 100). + [Parameter(ParameterSetName = 'AllVersions')] + [ValidateRange(0, 100)] + [int] $PerPage, + # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] @@ -91,7 +91,7 @@ } Write-Debug "ParameterSet: $($PSCmdlet.ParameterSetName)" switch ($PSCmdlet.ParameterSetName) { - 'All' { + 'AllVersions' { Get-GitHubReleaseAll @params -PerPage $PerPage } 'Tag' { diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 5242bb461..faedd54d8 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -113,12 +113,20 @@ Describe 'Releases' { $release | Should -Not -BeNullOrEmpty } + It 'Get-GitHubRelease - Gets latest release' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + LogGroup 'Latest release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + } + It 'Get-GitHubRelease - Gets all releases' { - $releases = Get-GitHubRelease -Owner $Owner -Repository $repo -Debug - LogGroup 'Releases' { + $releases = Get-GitHubRelease -Owner $Owner -Repository $repo -All + LogGroup 'All releases' { Write-Host ($releases | Format-List -Property * | Out-String) } - $release | Should -Not -BeNullOrEmpty + $releases | Should -Not -BeNullOrEmpty } } } From e5d372fb694c5724ca839137d75c6e0f000b540c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 13:10:55 +0200 Subject: [PATCH 133/224] Enhance Releases tests to validate Get-GitHubRelease functionality and add Update-GitHubRelease test case --- tests/Releases.Tests.ps1 | 51 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index faedd54d8..7a46e7806 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -106,7 +106,7 @@ Describe 'Releases' { } It 'New-GitHubRelease - Creates a new release with a name' { - $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Test Release' -GenerateReleaseNotes + $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Test Release' -GenerateReleaseNotes -Latest LogGroup 'Release' { Write-Host ($release | Format-List -Property * | Out-String) } @@ -119,6 +119,9 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release.Count | Should -Be 1 + $release | Should -BeOfType 'GitHubRelease' + $release.Tag | Should -Be 'v1.3' } It 'Get-GitHubRelease - Gets all releases' { @@ -127,6 +130,52 @@ Describe 'Releases' { Write-Host ($releases | Format-List -Property * | Out-String) } $releases | Should -Not -BeNullOrEmpty + $releases.Count | Should -BeGreaterThan 1 + $releases | Should -BeOfType 'GitHubRelease' + } + + It 'Get-GitHubRelease - Gets release by tag' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.2' + LogGroup 'Release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Count | Should -Be 1 + $release | Should -BeOfType 'GitHubRelease' + $release.Tag | Should -Be 'v1.2' + } + + It 'Get-GitHubRelease - Gets release by ID' { + $specificRelease = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.2' + $release = Get-GitHubRelease -Owner $Owner -Repository $repo -ID $specificRelease.ID + LogGroup 'Release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Count | Should -Be 1 + $release | Should -BeOfType 'GitHubRelease' + $release.Tag | Should -Be 'v1.2' + } + + It 'Get-GitHubRelease - Gets release by ID using Pipeline' { + $specificRelease = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.2' + $release = $specificRelease | Get-GitHubRelease + LogGroup 'Release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Count | Should -Be 1 + $release | Should -BeOfType 'GitHubRelease' + $release.Tag | Should -Be 'v1.2' + } + + It 'Update-GitHubRelease - Updates a release' { + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Body 'Updated release body.' + LogGroup 'Updated release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Name | Should -Be 'Updated Release' } } } From 5decbd0ee5a2ce82b136fbc74cfaeaab474a34d6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 13:25:07 +0200 Subject: [PATCH 134/224] Update Get-GitHubRelease documentation and enhance Releases tests for improved clarity and accuracy --- .../public/Releases/Get-GitHubRelease.ps1 | 2 +- tests/Releases.Tests.ps1 | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index f95a3fbbe..e0d26ddec 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -1,7 +1,7 @@ filter Get-GitHubRelease { <# .SYNOPSIS - List releases. + Retrieves GitHub release information for a repository. .DESCRIPTION This returns a list of releases, which does not include regular Git tags that have not been associated with a release. diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 7a46e7806..031d78b32 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -28,7 +28,7 @@ BeforeAll { Describe 'Releases' { $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" - Context 'As using on ' -ForEach $authCases { + Get-Context 'As using on ' -ForEach $authCases { BeforeAll { $context = Connect-GitHubAccount @connectParams -PassThru -Silent LogGroup 'Context' { @@ -76,7 +76,7 @@ Describe 'Releases' { Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent } - Context 'Releases' -Skip:($OwnerType -eq 'repository') { + Get-Context 'Releases' -Skip:($OwnerType -eq 'repository') { It 'New-GitHubRelease - Creates a new release' { $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest LogGroup 'Release' { @@ -98,7 +98,7 @@ Describe 'Releases' { } It 'New-GitHubRelease - Creates a new release with a pre-release' { - $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.1' -PreRelease + $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.1' -Prerelease LogGroup 'Release' { Write-Host ($release | Format-List -Property * | Out-String) } @@ -122,6 +122,7 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.3' + $release.Latest | Should -Be $true } It 'Get-GitHubRelease - Gets all releases' { @@ -143,10 +144,12 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.2' + $release.Latest | Should -Be $false + $release.Draft | Should -Be $true } It 'Get-GitHubRelease - Gets release by ID' { - $specificRelease = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.2' + $specificRelease = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' $release = Get-GitHubRelease -Owner $Owner -Repository $repo -ID $specificRelease.ID LogGroup 'Release' { Write-Host ($release | Format-List -Property * | Out-String) @@ -154,12 +157,15 @@ Describe 'Releases' { $release | Should -Not -BeNullOrEmpty $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' - $release.Tag | Should -Be 'v1.2' + $release.Tag | Should -Be 'v1.0' + $release.Latest | Should -Be $false + $release.Draft | Should -Be $false + $release.Prerelease | Should -Be $false } It 'Get-GitHubRelease - Gets release by ID using Pipeline' { $specificRelease = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.2' - $release = $specificRelease | Get-GitHubRelease + $release = Get-GitHubRelease -Owner $Owner -Repository $repo -ID $specificRelease.ID LogGroup 'Release' { Write-Host ($release | Format-List -Property * | Out-String) } @@ -170,12 +176,17 @@ Describe 'Releases' { } It 'Update-GitHubRelease - Updates a release' { - $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Body 'Updated release body.' + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' LogGroup 'Updated release' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty $release.Name | Should -Be 'Updated Release' + $release.Notes | Should -Be 'Updated release notes' + $release.Tag | Should -Be 'v1.3' + $release.Latest | Should -Be $true + $release.Draft | Should -Be $false + $release.Prerelease | Should -Be $false } } } From 694521723059629a37c81021d2726cf92ae3e86c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 13:31:02 +0200 Subject: [PATCH 135/224] Comment out Update-GitHubRelease test case for future reference --- tests/Releases.Tests.ps1 | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 031d78b32..0ab90de6b 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -175,19 +175,19 @@ Describe 'Releases' { $release.Tag | Should -Be 'v1.2' } - It 'Update-GitHubRelease - Updates a release' { - $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' - LogGroup 'Updated release' { - Write-Host ($release | Format-List -Property * | Out-String) - } - $release | Should -Not -BeNullOrEmpty - $release.Name | Should -Be 'Updated Release' - $release.Notes | Should -Be 'Updated release notes' - $release.Tag | Should -Be 'v1.3' - $release.Latest | Should -Be $true - $release.Draft | Should -Be $false - $release.Prerelease | Should -Be $false - } + # It 'Update-GitHubRelease - Updates a release' { + # $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' + # LogGroup 'Updated release' { + # Write-Host ($release | Format-List -Property * | Out-String) + # } + # $release | Should -Not -BeNullOrEmpty + # $release.Name | Should -Be 'Updated Release' + # $release.Notes | Should -Be 'Updated release notes' + # $release.Tag | Should -Be 'v1.3' + # $release.Latest | Should -Be $true + # $release.Draft | Should -Be $false + # $release.Prerelease | Should -Be $false + # } } } } From 848488f684d9eb0e3fb12623810c1bc41fe612f7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 13:37:21 +0200 Subject: [PATCH 136/224] Refactor Releases tests to correct context usage and restore Update-GitHubRelease test case --- tests/Releases.Tests.ps1 | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 0ab90de6b..a7838bd42 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -28,7 +28,7 @@ BeforeAll { Describe 'Releases' { $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" - Get-Context 'As using on ' -ForEach $authCases { + Context 'As using on ' -ForEach $authCases { BeforeAll { $context = Connect-GitHubAccount @connectParams -PassThru -Silent LogGroup 'Context' { @@ -76,7 +76,7 @@ Describe 'Releases' { Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent } - Get-Context 'Releases' -Skip:($OwnerType -eq 'repository') { + Context 'Releases' -Skip:($OwnerType -eq 'repository') { It 'New-GitHubRelease - Creates a new release' { $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest LogGroup 'Release' { @@ -175,19 +175,19 @@ Describe 'Releases' { $release.Tag | Should -Be 'v1.2' } - # It 'Update-GitHubRelease - Updates a release' { - # $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' - # LogGroup 'Updated release' { - # Write-Host ($release | Format-List -Property * | Out-String) - # } - # $release | Should -Not -BeNullOrEmpty - # $release.Name | Should -Be 'Updated Release' - # $release.Notes | Should -Be 'Updated release notes' - # $release.Tag | Should -Be 'v1.3' - # $release.Latest | Should -Be $true - # $release.Draft | Should -Be $false - # $release.Prerelease | Should -Be $false - # } + It 'Update-GitHubRelease - Updates a release' { + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' + LogGroup 'Updated release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Name | Should -Be 'Updated Release' + $release.Notes | Should -Be 'Updated release notes' + $release.Tag | Should -Be 'v1.3' + $release.Latest | Should -Be $true + $release.Draft | Should -Be $false + $release.Prerelease | Should -Be $false + } } } } From 08ed72ac28c12172ababde2634a49251e39821c8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 16:37:37 +0200 Subject: [PATCH 137/224] Enhance Update-GitHubRelease cmdlet documentation and add debug parameter to test case --- src/functions/public/Releases/Update-GitHubRelease.ps1 | 5 +++-- tests/Releases.Tests.ps1 | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 38cac59d9..bf633bc26 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -11,6 +11,9 @@ Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the note 'Release notes'. + .LINK + https://psmodule.io/github/Functions/Releases/Update-GitHubRelease + .NOTES [Update a release](https://docs.github.com/rest/releases/releases#update-a-release) #> @@ -165,5 +168,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index a7838bd42..21cb50118 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -176,7 +176,7 @@ Describe 'Releases' { } It 'Update-GitHubRelease - Updates a release' { - $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' -Debug LogGroup 'Updated release' { Write-Host ($release | Format-List -Property * | Out-String) } From 4edcfb4a2ea95cae093c18a45f978f51414809f9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 16:52:23 +0200 Subject: [PATCH 138/224] Update Update-GitHubRelease test case to include -Confirm parameter --- tests/Releases.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 21cb50118..fd39ed127 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -176,7 +176,7 @@ Describe 'Releases' { } It 'Update-GitHubRelease - Updates a release' { - $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' -Debug + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' -Debug -Confirm:$false LogGroup 'Updated release' { Write-Host ($release | Format-List -Property * | Out-String) } From de9425dc91a0b4bcf29f3f903a00c5a60bc36359 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 17:08:55 +0200 Subject: [PATCH 139/224] Refactor Update-GitHubRelease parameters to use nullable switches and update test case to remove unnecessary Confirm parameter --- src/functions/public/Releases/Update-GitHubRelease.ps1 | 9 +++++---- tests/Releases.Tests.ps1 | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index bf633bc26..a863c4f09 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -54,11 +54,11 @@ # Whether the release is a draft. [Parameter(ParameterSetName = 'Not latest')] - [switch] $Draft, + [System.Nullable[switch]] $Draft, # Whether to identify the release as a prerelease. [Parameter(ParameterSetName = 'Not latest')] - [switch] $Prerelease, + [System.Nullable[switch]] $Prerelease, # If specified, a discussion of the specified category is created and linked to the release. # The value must be a category that already exists in the repository. @@ -74,7 +74,7 @@ # Specifies whether this release should be set as the latest release for the repository. If the release is a draft or a prerelease, setting # this parameters will promote the release to a release, setting the draft and prerelease parameters to false. [Parameter(Mandatory, ParameterSetName = 'Set latest')] - [switch] $Latest, + [System.Nullable[switch]] $Latest, # Takes all parameters and updates the release with the provided _AND_ the default values of the non-provided parameters. # Used for Set-GitHubRelease. @@ -158,8 +158,9 @@ } if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { + $resultLatest = $PSBoundParameters.ContainsKey('Latest') ? $Latest : $release.Latest Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response , $Owner, $Repository, $Latest) + [GitHubRelease]::new($_.Response , $Owner, $Repository, $resultLatest) } } } diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index fd39ed127..a7838bd42 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -176,7 +176,7 @@ Describe 'Releases' { } It 'Update-GitHubRelease - Updates a release' { - $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' -Debug -Confirm:$false + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' LogGroup 'Updated release' { Write-Host ($release | Format-List -Property * | Out-String) } From 5480e4b68bfa5154cd3749037e3e2eeb677dc8ee Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 17:19:29 +0200 Subject: [PATCH 140/224] Add tests for Update-GitHubRelease to validate updates for releases v1.0 to v1.3 --- tests/Releases.Tests.ps1 | 44 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index a7838bd42..c85b3e917 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -175,7 +175,7 @@ Describe 'Releases' { $release.Tag | Should -Be 'v1.2' } - It 'Update-GitHubRelease - Updates a release' { + It 'Update-GitHubRelease - Update release v1.3' { $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' LogGroup 'Updated release' { Write-Host ($release | Format-List -Property * | Out-String) @@ -188,6 +188,48 @@ Describe 'Releases' { $release.Draft | Should -Be $false $release.Prerelease | Should -Be $false } + + It 'Update-GitHubRelease - Update release v1.0' { + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Name 'Updated Release' -Notes 'Updated release notes' + LogGroup 'Updated release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Name | Should -Be 'Updated Release' + $release.Notes | Should -Be 'Updated release notes' + $release.Tag | Should -Be 'v1.0' + $release.Latest | Should -Be $false + $release.Draft | Should -Be $false + $release.Prerelease | Should -Be $false + } + + It 'Update-GitHubRelease - Update release v1.1' { + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.1' -Name 'Updated Release' -Notes 'Updated release notes' + LogGroup 'Updated release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Name | Should -Be 'Updated Release' + $release.Notes | Should -Be 'Updated release notes' + $release.Tag | Should -Be 'v1.1' + $release.Latest | Should -Be $false + $release.Draft | Should -Be $false + $release.Prerelease | Should -Be $true + } + + It 'Update-GitHubRelease - Update release v1.2' { + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.2' -Name 'Updated Release' -Notes 'Updated release notes' + LogGroup 'Updated release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Name | Should -Be 'Updated Release' + $release.Notes | Should -Be 'Updated release notes' + $release.Tag | Should -Be 'v1.2' + $release.Latest | Should -Be $false + $release.Draft | Should -Be $true + $release.Prerelease | Should -Be $true + } } } } From 79c643ffee2c9d59dbdceae6218186b3176c1d20 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 17:29:59 +0200 Subject: [PATCH 141/224] Remove assertion for release tag in New-GitHubRelease test case --- tests/Releases.Tests.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index c85b3e917..be81331c8 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -225,7 +225,6 @@ Describe 'Releases' { $release | Should -Not -BeNullOrEmpty $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' - $release.Tag | Should -Be 'v1.2' $release.Latest | Should -Be $false $release.Draft | Should -Be $true $release.Prerelease | Should -Be $true From 92033c8eb0676ffe3feff8f1e485f1eae841d764 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 17:40:32 +0200 Subject: [PATCH 142/224] Refactor Update-GitHubRelease tests to improve coverage and add new scenarios for releases v1.3, v1.4, and removal of v1.0 --- tests/Releases.Tests.ps1 | 71 +++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index be81331c8..d82f24916 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -175,20 +175,6 @@ Describe 'Releases' { $release.Tag | Should -Be 'v1.2' } - It 'Update-GitHubRelease - Update release v1.3' { - $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' - LogGroup 'Updated release' { - Write-Host ($release | Format-List -Property * | Out-String) - } - $release | Should -Not -BeNullOrEmpty - $release.Name | Should -Be 'Updated Release' - $release.Notes | Should -Be 'Updated release notes' - $release.Tag | Should -Be 'v1.3' - $release.Latest | Should -Be $true - $release.Draft | Should -Be $false - $release.Prerelease | Should -Be $false - } - It 'Update-GitHubRelease - Update release v1.0' { $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Name 'Updated Release' -Notes 'Updated release notes' LogGroup 'Updated release' { @@ -227,7 +213,62 @@ Describe 'Releases' { $release.Notes | Should -Be 'Updated release notes' $release.Latest | Should -Be $false $release.Draft | Should -Be $true - $release.Prerelease | Should -Be $true + $release.Prerelease | Should -Be $false + } + + It 'Update-GitHubRelease - Update release v1.3' { + $release = Update-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.3' -Name 'Updated Release' -Notes 'Updated release notes' + LogGroup 'Updated release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Name | Should -Be 'Updated Release' + $release.Notes | Should -Be 'Updated release notes' + $release.Tag | Should -Be 'v1.3' + $release.Latest | Should -Be $true + $release.Draft | Should -Be $false + $release.Prerelease | Should -Be $false + } + + It 'Set-GitHubRelease - Sets release v1.0 as latest' { + $release = Set-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest -Name 'Updated Release again' -Notes 'Updated release notes to something else' + LogGroup 'Set release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Tag | Should -Be 'v1.0' + $release.Latest | Should -Be $true + $release.Draft | Should -Be $false + $release.Prerelease | Should -Be $false + $release.Name | Should -Be 'Updated Release again' + $release.Notes | Should -Be 'Updated release notes to something else' + } + + It 'Set-GitHubRelease - Sets a new release as latest - v1.4' { + $release = Set-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.4' -Latest -Name 'New Release' -Notes 'New release notes' + LogGroup 'Set release' { + Write-Host ($release | Format-List -Property * | Out-String) + } + $release | Should -Not -BeNullOrEmpty + $release.Tag | Should -Be 'v1.4' + $release.Latest | Should -Be $true + $release.Draft | Should -Be $false + $release.Prerelease | Should -Be $false + $release.Name | Should -Be 'New Release' + $release.Notes | Should -Be 'New release notes' + } + + It 'Remove-GitHubRelease - Removes release v1.0' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' + $release | Should -Not -BeNullOrEmpty + $release.Count | Should -Be 1 + $release | Should -BeOfType 'GitHubRelease' + $release.Tag | Should -Be 'v1.0' + $release.Latest | Should -Be $true + $release.Draft | Should -Be $false + $release.Prerelease | Should -Be $false + + Remove-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Confirm:$false } } } From f659057ac81a53621e35bda4e1cb043a3e008578 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 17:46:38 +0200 Subject: [PATCH 143/224] Update Get-GitHubRelease test to assert that v1.0 is no longer the latest release and validate removal --- tests/Releases.Tests.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index d82f24916..4bdbc49bd 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -264,11 +264,14 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.0' - $release.Latest | Should -Be $true + $release.Latest | Should -Be $false $release.Draft | Should -Be $false $release.Prerelease | Should -Be $false Remove-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Confirm:$false + + $release = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' + $release | Should -BeNullOrEmpty } } } From a62499565f266deb22913da0cf1e88f960e5068c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 18:20:05 +0200 Subject: [PATCH 144/224] Update Remove-GitHubRelease test to use ID parameter instead of Tag --- src/functions/public/Releases/Get-GitHubRelease.ps1 | 2 -- src/functions/public/Releases/Remove-GitHubRelease.ps1 | 2 -- src/functions/public/Releases/Set-GitHubRelease.ps1 | 2 -- tests/Releases.Tests.ps1 | 2 +- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index e0d26ddec..a52b1a424 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -115,5 +115,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Releases/Remove-GitHubRelease.ps1 b/src/functions/public/Releases/Remove-GitHubRelease.ps1 index 738c94ddb..c6b045dcb 100644 --- a/src/functions/public/Releases/Remove-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Remove-GitHubRelease.ps1 @@ -65,5 +65,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index b932e4d94..98d1a376e 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -124,5 +124,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 4bdbc49bd..410e468a7 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -268,7 +268,7 @@ Describe 'Releases' { $release.Draft | Should -Be $false $release.Prerelease | Should -Be $false - Remove-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Confirm:$false + Remove-GitHubRelease -Owner $Owner -Repository $repo -ID $release.ID -Confirm:$false $release = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' $release | Should -BeNullOrEmpty From c8910ab3df594f2022707edb00f04679e56f6a4c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sun, 27 Apr 2025 23:08:38 +0200 Subject: [PATCH 145/224] Enhance Add-GitHubReleaseAsset to support directory uploads and improve parameter handling --- .../Assets/Add-GitHubReleaseAsset.ps1 | 165 +++++++++++++----- 1 file changed, 123 insertions(+), 42 deletions(-) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index bb0c9a613..321437e3b 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -37,26 +37,41 @@ the old file before you can re-upload the new asset. .EXAMPLE - Add-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -ID '7654321' -FilePath 'C:\Users\octocat\Downloads\hello-world.zip' + Add-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -ID '7654321' -Path 'C:\Users\octocat\Downloads\hello-world.zip' Gets the release assets for the release with the ID '1234567' for the repository 'octocat/hello-world'. + .EXAMPLE + Add-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -ID '7654321' -Path 'C:\Users\octocat\Projects\MyApp' + + Automatically creates a zip file from the contents of the MyApp directory and uploads it as a release asset. + + .INPUTS + GitHubRelease + + .OUTPUTS + GitHubReleaseAsset + .NOTES [Upload a release asset](https://docs.github.com/rest/releases/assets#upload-a-release-asset) #> [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('Organization', 'User')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Repository, + # The name of the tag to get a release from. + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'Tag')] + [string] $Tag, + # The unique identifier of the release. - [Parameter(Mandatory)] + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'ID')] [string] $ID, #The name of the file asset. @@ -67,14 +82,10 @@ [Parameter()] [string] $Label, - # The content type of the asset. - [Parameter()] - [string] $ContentType, - # The path to the asset file. [Parameter(Mandatory)] [alias('FullName')] - [string] $FilePath, + [string] $Path, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -87,52 +98,116 @@ Write-Debug "[$stackPath] - Start" $Context = Resolve-GitHubContext -Context $Context Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + + # Store if we're using a temporary path for cleanup + $TempFilePath = $null } process { - # If name is not provided, use the name of the file - if (!$Name) { - $Name = (Get-Item $FilePath).Name - } + # Check if the path is a directory + $isDirectory = (Test-Path -Path $Path -PathType Container) + + $fileToUpload = $Path + + # If the path is a directory, create a zip file + if ($isDirectory) { + Write-Verbose 'Path is a directory. Zipping contents...' + $dirName = (Get-Item $Path).Name + $TempFilePath = [System.IO.Path]::GetTempFileName() + '.zip' + + Write-Verbose "Creating temporary zip file: $TempFilePath" + + # Create a temporary zip file + try { + Add-Type -AssemblyName System.IO.Compression.FileSystem - # If label is not provided, use the name of the file - if (!$Label) { - $Label = (Get-Item $FilePath).Name + # Delete temp file if it exists (GetTempFileName creates the file) + if (Test-Path $TempFilePath) { + Remove-Item -Path $TempFilePath -Force + } + + # Create the zip archive + [System.IO.Compression.ZipFile]::CreateFromDirectory($Path, $TempFilePath) + + # Use the temp file path for upload + $fileToUpload = $TempFilePath + + # Set the name to folder name + .zip if not specified + if (!$Name) { + $Name = "$dirName.zip" + } + + # Set content type to zip + $ContentType = 'application/zip' + + Write-Verbose 'Directory zipped successfully' + } catch { + if ($TempFilePath -and (Test-Path $TempFilePath)) { + Remove-Item -Path $TempFilePath -Force -ErrorAction SilentlyContinue + } + throw "Failed to create zip file from directory: $_" + } + } else { + # If name is not provided, use the name of the file + if (!$Name) { + $Name = (Get-Item $Path).Name + } + + # If label is not provided, use the name of the file + if (!$Label) { + $Label = (Get-Item $Path).Name + } + + # If content type is not provided, use the file extension + if (!$ContentType) { + $ContentType = switch ((Get-Item $Path).Extension) { + '.zip' { 'application/zip' } + '.tar' { 'application/x-tar' } + '.gz' { 'application/gzip' } + '.bz2' { 'application/x-bzip2' } + '.xz' { 'application/x-xz' } + '.7z' { 'application/x-7z-compressed' } + '.rar' { 'application/vnd.rar' } + '.tar.gz' { 'application/gzip' } + '.tgz' { 'application/gzip' } + '.tar.bz2' { 'application/x-bzip2' } + '.tar.xz' { 'application/x-xz' } + '.tar.7z' { 'application/x-7z-compressed' } + '.tar.rar' { 'application/vnd.rar' } + '.png' { 'image/png' } + '.json' { 'application/json' } + '.txt' { 'text/plain' } + '.md' { 'text/markdown' } + '.html' { 'text/html' } + default { 'application/octet-stream' } + } + } } - # If content type is not provided, use the file extension - if (!$ContentType) { - $ContentType = switch ((Get-Item $FilePath).Extension) { - '.zip' { 'application/zip' } - '.tar' { 'application/x-tar' } - '.gz' { 'application/gzip' } - '.bz2' { 'application/x-bzip2' } - '.xz' { 'application/x-xz' } - '.7z' { 'application/x-7z-compressed' } - '.rar' { 'application/vnd.rar' } - '.tar.gz' { 'application/gzip' } - '.tgz' { 'application/gzip' } - '.tar.bz2' { 'application/x-bzip2' } - '.tar.xz' { 'application/x-xz' } - '.tar.7z' { 'application/x-7z-compressed' } - '.tar.rar' { 'application/vnd.rar' } - '.png' { 'image/png' } - '.json' { 'application/json' } - '.txt' { 'text/plain' } - '.md' { 'text/markdown' } - '.html' { 'text/html' } - default { 'application/octet-stream' } + switch ($PSCmdlet.ParameterSetName) { + 'Tag' { + $release = Get-GitHubReleaseByTagName -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context + } + 'ID' { + $release = Get-GitHubReleaseByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context + } + default { + throw "Invalid parameter set: $($PSCmdlet.ParameterSetName)" } } - $release = Get-GitHubRelease -Owner $Owner -Repository $Repository -ID $ID - $uploadURI = $release.upload_url -replace '{\?name,label}', "?name=$($Name)&label=$($Label)" + $body = @{ + name = $Name + label = $Label + } $inputObject = @{ Method = 'POST' - URI = $uploadURI + ApiEndpoint = "/repos/$Owner/$Repository/releases/$($release.id)/assets" ContentType = $ContentType - UploadFilePath = $FilePath + UploadFilePath = $fileToUpload + Body = $body + Context = $Context } Invoke-GitHubAPI @inputObject | ForEach-Object { @@ -141,6 +216,12 @@ } end { + # Clean up temporary file if created + if ($TempFilePath -and (Test-Path $TempFilePath)) { + Write-Verbose 'Cleaning up temporary zip file' + Remove-Item -Path $TempFilePath -Force -ErrorAction SilentlyContinue + } + Write-Debug "[$stackPath] - End" } } From ef29843122b94ee005c7a1eff682da3328a828f1 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions@users.noreply.github.com> Date: Sun, 27 Apr 2025 21:10:09 +0000 Subject: [PATCH 146/224] Auto-generated changes --- Coverage.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Coverage.md b/Coverage.md index 82f272f63..3412fb4c2 100644 --- a/Coverage.md +++ b/Coverage.md @@ -9,15 +9,15 @@ Covered functions - 221 + 222 Missing functions - 805 + 804 Coverage - 21.54% + 21.64% @@ -542,7 +542,7 @@ | `/repos/{owner}/{repo}/releases/latest` | | :white_check_mark: | | | | | `/repos/{owner}/{repo}/releases/tags/{tag}` | | :white_check_mark: | | | | | `/repos/{owner}/{repo}/releases/{release_id}` | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | -| `/repos/{owner}/{repo}/releases/{release_id}/assets` | | :white_check_mark: | | :x: | | +| `/repos/{owner}/{repo}/releases/{release_id}/assets` | | :white_check_mark: | | :white_check_mark: | | | `/repos/{owner}/{repo}/releases/{release_id}/reactions` | | :x: | | :x: | | | `/repos/{owner}/{repo}/releases/{release_id}/reactions/{reaction_id}` | :x: | | | | | | `/repos/{owner}/{repo}/rules/branches/{branch}` | | :x: | | | | From c78511104f46ca131cc998722a4fb6c25409c0d2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 12:44:47 +0200 Subject: [PATCH 147/224] Add argument completer for Owner parameter in GitHub commands --- src/completers.ps1 | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/completers.ps1 b/src/completers.ps1 index 31f4d4436..e2447002e 100644 --- a/src/completers.ps1 +++ b/src/completers.ps1 @@ -17,3 +17,26 @@ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } + +Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Owner -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) + $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter + + Get-GitHubOwner -Verbose:$false -Context $fakeBoundParameter['Context'] | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } | Where-Object { $_.CompletionText -like "$wordToComplete*" } +} + +# Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Repository -ScriptBlock { +# param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) +# $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter + +# $repos = if ($fakeBoundParameter.ContainsKey('Owner')) { +# Get-GitHubRepository -Verbose:$false -Owner $fakeBoundParameter['Owner'] +# } else { +# Get-GitHubRepository -Verbose:$false +# } +# $repos | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object { +# [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) +# } +# } From 9d95f149172a4b4531174cc9539d3bc9ad667b3e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 12:52:03 +0200 Subject: [PATCH 148/224] Refactor argument completers: remove unused Owner completer and add Get-GitHubOrganization completer --- src/completers.ps1 | 23 ------------------- .../public/Organization/completers.ps1 | 9 ++++++++ .../public/Repositories/completers.ps1 | 14 +++++++++++ 3 files changed, 23 insertions(+), 23 deletions(-) create mode 100644 src/functions/public/Organization/completers.ps1 diff --git a/src/completers.ps1 b/src/completers.ps1 index e2447002e..31f4d4436 100644 --- a/src/completers.ps1 +++ b/src/completers.ps1 @@ -17,26 +17,3 @@ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } - -Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Owner -ScriptBlock { - param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) - $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter - - Get-GitHubOwner -Verbose:$false -Context $fakeBoundParameter['Context'] | ForEach-Object { - [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) - } | Where-Object { $_.CompletionText -like "$wordToComplete*" } -} - -# Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Repository -ScriptBlock { -# param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) -# $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter - -# $repos = if ($fakeBoundParameter.ContainsKey('Owner')) { -# Get-GitHubRepository -Verbose:$false -Owner $fakeBoundParameter['Owner'] -# } else { -# Get-GitHubRepository -Verbose:$false -# } -# $repos | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object { -# [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) -# } -# } diff --git a/src/functions/public/Organization/completers.ps1 b/src/functions/public/Organization/completers.ps1 new file mode 100644 index 000000000..0a8371be4 --- /dev/null +++ b/src/functions/public/Organization/completers.ps1 @@ -0,0 +1,9 @@ +Register-ArgumentCompleter -CommandName Get-GitHubOrganization -ParameterName Name -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) + $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter + + Get-GitHubOrganization -Verbose:$false -Context $fakeBoundParameter.Context | + Where-Object { $_.CompletionText -like "$wordToComplete*" } | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } +} diff --git a/src/functions/public/Repositories/completers.ps1 b/src/functions/public/Repositories/completers.ps1 index bf0c699a9..c27791b97 100644 --- a/src/functions/public/Repositories/completers.ps1 +++ b/src/functions/public/Repositories/completers.ps1 @@ -13,3 +13,17 @@ Register-ArgumentCompleter -CommandName 'New-GitHubRepository' -ParameterName 'L [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } + +# Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Repository -ScriptBlock { +# param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) +# $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter + +# $repos = if ($fakeBoundParameter.ContainsKey('Owner')) { +# Get-GitHubRepository -Verbose:$false -Owner $fakeBoundParameter['Owner'] +# } else { +# Get-GitHubRepository -Verbose:$false +# } +# $repos | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object { +# [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) +# } +# } From 764d2f2eaa164d0518116bedf77b2d32362a7639 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 12:54:48 +0200 Subject: [PATCH 149/224] Refactor Get-GitHubOrganization argument completer to improve context handling --- src/functions/public/Organization/completers.ps1 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/functions/public/Organization/completers.ps1 b/src/functions/public/Organization/completers.ps1 index 0a8371be4..2d324ed53 100644 --- a/src/functions/public/Organization/completers.ps1 +++ b/src/functions/public/Organization/completers.ps1 @@ -2,8 +2,13 @@ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter - Get-GitHubOrganization -Verbose:$false -Context $fakeBoundParameter.Context | - Where-Object { $_.CompletionText -like "$wordToComplete*" } | ForEach-Object { - [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) - } + if ($fakeBoundParameter.ContainsKey('Context')) { + $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context + } else { + $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false + } + + $orgs | Where-Object { $_.CompletionText -like "$wordToComplete*" } | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } } From 333bad369795fe654d2bd8e9021dbc00805a6494 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 13:09:38 +0200 Subject: [PATCH 150/224] Improve completion result formatting in Get-GitHubOrganization argument completer --- src/functions/public/Organization/completers.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/public/Organization/completers.ps1 b/src/functions/public/Organization/completers.ps1 index 2d324ed53..0348c342e 100644 --- a/src/functions/public/Organization/completers.ps1 +++ b/src/functions/public/Organization/completers.ps1 @@ -9,6 +9,6 @@ } $orgs | Where-Object { $_.CompletionText -like "$wordToComplete*" } | ForEach-Object { - [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + [System.Management.Automation.CompletionResult]::new($_, ($_ | Format-Table -HideTableHeaders), 'ParameterValue', $_.Description) } } From 255ff90bd2914f7eced12d263c5bf6d620ad5129 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 14:14:38 +0200 Subject: [PATCH 151/224] Refactor Get-GitHubOrganization: update default parameter set and add argument completer for organization names --- .../Get-GitHubOrganizationNameCompleter.ps1} | 9 ++++++++- .../public/Organization/Get-GitHubOrganization.ps1 | 7 ++++--- 2 files changed, 12 insertions(+), 4 deletions(-) rename src/functions/{public/Organization/completers.ps1 => private/Organization/Get-GitHubOrganizationNameCompleter.ps1} (82%) diff --git a/src/functions/public/Organization/completers.ps1 b/src/functions/private/Organization/Get-GitHubOrganizationNameCompleter.ps1 similarity index 82% rename from src/functions/public/Organization/completers.ps1 rename to src/functions/private/Organization/Get-GitHubOrganizationNameCompleter.ps1 index 0348c342e..b07770514 100644 --- a/src/functions/public/Organization/completers.ps1 +++ b/src/functions/private/Organization/Get-GitHubOrganizationNameCompleter.ps1 @@ -1,4 +1,11 @@ -Register-ArgumentCompleter -CommandName Get-GitHubOrganization -ParameterName Name -ScriptBlock { +function Get-GitHubOrganizationNameCompleter { + <# + .SYNOPSIS + Short description + + .DESCRIPTION + Long description + #> param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter diff --git a/src/functions/public/Organization/Get-GitHubOrganization.ps1 b/src/functions/public/Organization/Get-GitHubOrganization.ps1 index 84afe544a..42e56640a 100644 --- a/src/functions/public/Organization/Get-GitHubOrganization.ps1 +++ b/src/functions/public/Organization/Get-GitHubOrganization.ps1 @@ -36,7 +36,7 @@ https://psmodule.io/GitHub/Functions/Organization/Get-GitHubOrganization #> [OutputType([GitHubOrganization])] - [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] + [CmdletBinding(DefaultParameterSetName = 'List organizations for the authenticated user')] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'All', Justification = 'Required for parameter set')] param( # The organization name. The name is not case sensitive. @@ -46,6 +46,7 @@ ValueFromPipeline, ValueFromPipelineByPropertyName )] + [ArgummentCompleter({ Get-GitHubOrganizationNameCompleter @args })] [string] $Name, # The handle for the GitHub user account. @@ -71,7 +72,7 @@ # The number of results per page (max 100). [Parameter(ParameterSetName = 'AllOrg')] [Parameter(ParameterSetName = 'UserOrg')] - [Parameter(ParameterSetName = '__AllParameterSets')] + [Parameter(ParameterSetName = 'List organizations for the authenticated user')] [ValidateRange(0, 100)] [int] $PerPage, @@ -99,7 +100,7 @@ 'AllOrg' { Get-GitHubAllOrganization -Since $Since -PerPage $PerPage -Context $Context } - default { + 'List organizations for the authenticated user' { Get-GitHubMyOrganization -PerPage $PerPage -Context $Context } } From d165a9ee454c799c3026823f15ce83dd856e2347 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 14:27:52 +0200 Subject: [PATCH 152/224] Refactor argument completers: add Owner parameter completer and improve organization name completion --- .../Organization/Get-GitHubOrganization.ps1 | 1 - .../Organization/completers.ps1} | 9 +----- .../public/Repositories/completers.ps1 | 14 --------- src/functions/public/Users/completers.ps1 | 31 +++++++++++++++++++ 4 files changed, 32 insertions(+), 23 deletions(-) rename src/functions/{private/Organization/Get-GitHubOrganizationNameCompleter.ps1 => public/Organization/completers.ps1} (82%) create mode 100644 src/functions/public/Users/completers.ps1 diff --git a/src/functions/public/Organization/Get-GitHubOrganization.ps1 b/src/functions/public/Organization/Get-GitHubOrganization.ps1 index 42e56640a..999d44558 100644 --- a/src/functions/public/Organization/Get-GitHubOrganization.ps1 +++ b/src/functions/public/Organization/Get-GitHubOrganization.ps1 @@ -46,7 +46,6 @@ ValueFromPipeline, ValueFromPipelineByPropertyName )] - [ArgummentCompleter({ Get-GitHubOrganizationNameCompleter @args })] [string] $Name, # The handle for the GitHub user account. diff --git a/src/functions/private/Organization/Get-GitHubOrganizationNameCompleter.ps1 b/src/functions/public/Organization/completers.ps1 similarity index 82% rename from src/functions/private/Organization/Get-GitHubOrganizationNameCompleter.ps1 rename to src/functions/public/Organization/completers.ps1 index b07770514..43b6a920f 100644 --- a/src/functions/private/Organization/Get-GitHubOrganizationNameCompleter.ps1 +++ b/src/functions/public/Organization/completers.ps1 @@ -1,11 +1,4 @@ -function Get-GitHubOrganizationNameCompleter { - <# - .SYNOPSIS - Short description - - .DESCRIPTION - Long description - #> +Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Name -ScriptBlock { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter diff --git a/src/functions/public/Repositories/completers.ps1 b/src/functions/public/Repositories/completers.ps1 index c27791b97..bf0c699a9 100644 --- a/src/functions/public/Repositories/completers.ps1 +++ b/src/functions/public/Repositories/completers.ps1 @@ -13,17 +13,3 @@ Register-ArgumentCompleter -CommandName 'New-GitHubRepository' -ParameterName 'L [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } - -# Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Repository -ScriptBlock { -# param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) -# $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter - -# $repos = if ($fakeBoundParameter.ContainsKey('Owner')) { -# Get-GitHubRepository -Verbose:$false -Owner $fakeBoundParameter['Owner'] -# } else { -# Get-GitHubRepository -Verbose:$false -# } -# $repos | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object { -# [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) -# } -# } diff --git a/src/functions/public/Users/completers.ps1 b/src/functions/public/Users/completers.ps1 new file mode 100644 index 000000000..a32def765 --- /dev/null +++ b/src/functions/public/Users/completers.ps1 @@ -0,0 +1,31 @@ +Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Owner -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) + $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter + + if ($fakeBoundParameter.ContainsKey('Context')) { + $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context + } else { + $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false + } + $orgs += Get-GitHubMyUser -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context + + $orgs | Where-Object { $_.CompletionText -like "$wordToComplete*" } | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, ($_ | Format-Table -HideTableHeaders), 'ParameterValue', $_.Description) + } +} + +Register-ArgumentCompleter -CommandName Get-GitHubUser -ParameterName Name -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) + $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter + + if ($fakeBoundParameter.ContainsKey('Context')) { + $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context + } else { + $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false + } + $orgs += Get-GitHubMyUser -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context + + $orgs | Where-Object { $_.CompletionText -like "$wordToComplete*" } | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, ($_ | Format-Table -HideTableHeaders), 'ParameterValue', $_.Description) + } +} From ba702bdb1025befaf0615d8e756dfd557f39d3f7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 15:57:28 +0200 Subject: [PATCH 153/224] Refactor Get-GitHubRelease calls to remove unnecessary -Latest parameter and improve error handling in Add-GitHubReleaseAsset --- examples/Releases/Releases.ps1 | 4 +- src/functions/public/API/Invoke-GitHubAPI.ps1 | 1 + .../Assets/Add-GitHubReleaseAsset.ps1 | 122 +++++++----------- 3 files changed, 52 insertions(+), 75 deletions(-) diff --git a/examples/Releases/Releases.ps1 b/examples/Releases/Releases.ps1 index e853fb744..1b38c9adf 100644 --- a/examples/Releases/Releases.ps1 +++ b/examples/Releases/Releases.ps1 @@ -2,7 +2,7 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub # Get the latest release for a specific repository -Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest +Get-GitHubRelease -Owner PSModule -Repository GitHub # Get all the releases for all repos in the organization 'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease @@ -12,7 +12,7 @@ Get-GitHubRelease -Owner PSModule -Repository GitHub -Latest do { Import-Module -Name GitHub } until ($? -eq $true) - $_ | Get-GitHubRelease -Latest + $_ | Get-GitHubRelease } 'PSModule' | Get-GitHubOrganization | Get-GitHubRepository | Get-GitHubRelease -Latest diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 0cf5d8996..90b56dbdd 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -279,6 +279,7 @@ filter Invoke-GitHubAPI { } while ($APICall['Uri']) } catch { $failure = $_ + $failure | Out-String -Stream | ForEach-Object { Write-Debug $_ } $headers = @{} foreach ($item in $failure.Exception.Response.Headers.GetEnumerator()) { $headers[$item.Key] = ($item.Value).Trim() -join ', ' diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index 321437e3b..28f8c4b2a 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -98,89 +98,62 @@ Write-Debug "[$stackPath] - Start" $Context = Resolve-GitHubContext -Context $Context Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - - # Store if we're using a temporary path for cleanup - $TempFilePath = $null } process { # Check if the path is a directory - $isDirectory = (Test-Path -Path $Path -PathType Container) - + try { + $item = Get-Item $Path + $isDirectory = $item.PSIsContainer + } catch { + throw "Error accessing the path: $_" + } $fileToUpload = $Path - # If the path is a directory, create a zip file if ($isDirectory) { Write-Verbose 'Path is a directory. Zipping contents...' - $dirName = (Get-Item $Path).Name - $TempFilePath = [System.IO.Path]::GetTempFileName() + '.zip' + $dirName = $item.Name + $TempFilePath = "$dirName.zip" Write-Verbose "Creating temporary zip file: $TempFilePath" - - # Create a temporary zip file try { - Add-Type -AssemblyName System.IO.Compression.FileSystem - - # Delete temp file if it exists (GetTempFileName creates the file) - if (Test-Path $TempFilePath) { - Remove-Item -Path $TempFilePath -Force - } - - # Create the zip archive - [System.IO.Compression.ZipFile]::CreateFromDirectory($Path, $TempFilePath) - - # Use the temp file path for upload + Get-ChildItem -Path $Path | Compress-Archive -DestinationPath $TempFilePath -ErrorAction Stop -Force $fileToUpload = $TempFilePath - - # Set the name to folder name + .zip if not specified - if (!$Name) { - $Name = "$dirName.zip" - } - - # Set content type to zip - $ContentType = 'application/zip' - - Write-Verbose 'Directory zipped successfully' } catch { - if ($TempFilePath -and (Test-Path $TempFilePath)) { - Remove-Item -Path $TempFilePath -Force -ErrorAction SilentlyContinue - } - throw "Failed to create zip file from directory: $_" + Remove-Item -Path $TempFilePath -Force -ErrorAction SilentlyContinue } - } else { - # If name is not provided, use the name of the file - if (!$Name) { - $Name = (Get-Item $Path).Name - } - - # If label is not provided, use the name of the file - if (!$Label) { - $Label = (Get-Item $Path).Name - } - - # If content type is not provided, use the file extension - if (!$ContentType) { - $ContentType = switch ((Get-Item $Path).Extension) { - '.zip' { 'application/zip' } - '.tar' { 'application/x-tar' } - '.gz' { 'application/gzip' } - '.bz2' { 'application/x-bzip2' } - '.xz' { 'application/x-xz' } - '.7z' { 'application/x-7z-compressed' } - '.rar' { 'application/vnd.rar' } - '.tar.gz' { 'application/gzip' } - '.tgz' { 'application/gzip' } - '.tar.bz2' { 'application/x-bzip2' } - '.tar.xz' { 'application/x-xz' } - '.tar.7z' { 'application/x-7z-compressed' } - '.tar.rar' { 'application/vnd.rar' } - '.png' { 'image/png' } - '.json' { 'application/json' } - '.txt' { 'text/plain' } - '.md' { 'text/markdown' } - '.html' { 'text/html' } - default { 'application/octet-stream' } - } + } + # # If name is not provided, use the name of the file + # if (!$Name) { + # $Name = (Get-Item $Path).Name + # } + + # # If label is not provided, use the name of the file + # if (!$Label) { + # $Label = (Get-Item $Path).Name + # } + + if (!$ContentType) { + $ContentType = switch ((Get-Item $Path).Extension) { + '.zip' { 'application/zip' } + '.tar' { 'application/x-tar' } + '.gz' { 'application/gzip' } + '.bz2' { 'application/x-bzip2' } + '.xz' { 'application/x-xz' } + '.7z' { 'application/x-7z-compressed' } + '.rar' { 'application/vnd.rar' } + '.tar.gz' { 'application/gzip' } + '.tgz' { 'application/gzip' } + '.tar.bz2' { 'application/x-bzip2' } + '.tar.xz' { 'application/x-xz' } + '.tar.7z' { 'application/x-7z-compressed' } + '.tar.rar' { 'application/vnd.rar' } + '.png' { 'image/png' } + '.json' { 'application/json' } + '.txt' { 'text/plain' } + '.md' { 'text/markdown' } + '.html' { 'text/html' } + default { 'application/octet-stream' } } } @@ -200,6 +173,7 @@ name = $Name label = $Label } + $body | Remove-HashtableEntry -NullOrEmptyValues $inputObject = @{ Method = 'POST' @@ -216,13 +190,15 @@ } end { + Write-Debug "[$stackPath] - End" + } + + clean { # Clean up temporary file if created - if ($TempFilePath -and (Test-Path $TempFilePath)) { - Write-Verbose 'Cleaning up temporary zip file' + if ($isDirectory) { + Write-Verbose "Cleaning up temporary zip file: $TempFilePath" Remove-Item -Path $TempFilePath -Force -ErrorAction SilentlyContinue } - - Write-Debug "[$stackPath] - End" } } From 44f0f02c946733d4760bb2aa5c0da300e2bb6b2d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 16:18:01 +0200 Subject: [PATCH 154/224] Refactor Invoke-GitHubAPI: streamline URI construction and improve handling of POST requests with file uploads --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 90b56dbdd..2967876fa 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -177,9 +177,9 @@ filter Invoke-GitHubAPI { if (-not $Body) { $Body = @{} } - $Body['per_page'] = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context - + $APICall.Uri = New-Uri -BaseUri $Uri -Query $Body -AsString + } elseif (($Method -eq 'POST') -and -not [string]::IsNullOrEmpty($UploadFilePath)) { $APICall.Uri = New-Uri -BaseUri $Uri -Query $Body -AsString } elseif ($Body) { if ($Body -is [hashtable]) { From 45cf3d934573fb5842032bf815ee2cf49b83de3c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 16:32:24 +0200 Subject: [PATCH 155/224] Fix variable reference in content type determination for uploaded files in Add-GitHubReleaseAsset --- src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index 28f8c4b2a..4bb4b7a9c 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -134,7 +134,7 @@ # } if (!$ContentType) { - $ContentType = switch ((Get-Item $Path).Extension) { + $ContentType = switch ((Get-Item $fileToUpload).Extension) { '.zip' { 'application/zip' } '.tar' { 'application/x-tar' } '.gz' { 'application/gzip' } From b6246dbd56b5bdf07ff05d29863e18d012444113 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 16:34:53 +0200 Subject: [PATCH 156/224] Add ContentType parameter to Add-GitHubReleaseAsset for payload specification --- .../public/Releases/Assets/Add-GitHubReleaseAsset.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index 4bb4b7a9c..fd467faa3 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -87,6 +87,10 @@ [alias('FullName')] [string] $Path, + # The 'Content-Type' for the payload. + [Parameter()] + [string] $ContentType, + # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] From 90e5e802332271e719d189feae4b7cdf4a3cff9c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 18:25:49 +0200 Subject: [PATCH 157/224] Refactor Get-GitHubReleaseAll to handle response correctly and update Add-GitHubReleaseAsset comments for clarity; add Update-GitHubReleaseAsset function for asset updates --- src/functions/private/Releases/Get-GitHubReleaseAll.ps1 | 2 +- .../public/Releases/Assets/Add-GitHubReleaseAsset.ps1 | 3 +-- ...t-GitHubReleaseAsset.ps1 => Update-GitHubReleaseAsset.ps1} | 4 ++-- src/functions/public/Releases/Get-GitHubRelease.ps1 | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) rename src/functions/public/Releases/Assets/{Set-GitHubReleaseAsset.ps1 => Update-GitHubReleaseAsset.ps1} (93%) diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index 00ed59b3f..d65e6ba7b 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -63,7 +63,7 @@ try { Invoke-GitHubAPI @inputObject | ForEach-Object { - $_.Response | ForEach-Object { + (, $_.Response) | ForEach-Object { $isLatest = $_.id -eq $latest.id [GitHubRelease]::new($_, $Owner, $Repository, $isLatest) } diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index fd467faa3..404eae5ee 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -105,7 +105,6 @@ } process { - # Check if the path is a directory try { $item = Get-Item $Path $isDirectory = $item.PSIsContainer @@ -113,7 +112,7 @@ throw "Error accessing the path: $_" } $fileToUpload = $Path - # If the path is a directory, create a zip file + # If the path is a directory, create a zip file from the contents of the folder if ($isDirectory) { Write-Verbose 'Path is a directory. Zipping contents...' $dirName = $item.Name diff --git a/src/functions/public/Releases/Assets/Set-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 similarity index 93% rename from src/functions/public/Releases/Assets/Set-GitHubReleaseAsset.ps1 rename to src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 index 534ff02d8..39c13f130 100644 --- a/src/functions/public/Releases/Assets/Set-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 @@ -1,4 +1,4 @@ -filter Set-GitHubReleaseAsset { +filter Update-GitHubReleaseAsset { <# .SYNOPSIS Update a release asset @@ -7,7 +7,7 @@ Users with push access to the repository can edit a release asset. .EXAMPLE - Set-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Name 'new_asset_name' -Label 'new_asset_label' + Update-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Name 'new_asset_name' -Label 'new_asset_label' Updates the release asset with the ID '1234567' for the repository 'octocat/hello-world' with the new name 'new_asset_name' and label 'new_asset_label'. diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index a52b1a424..4d11bc75f 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -68,7 +68,7 @@ # The number of results per page (max 100). [Parameter(ParameterSetName = 'AllVersions')] [ValidateRange(0, 100)] - [int] $PerPage, + [System.Nullable[int]] $PerPage, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. From b3ad9964f3b064b9ed668be14ee7e881e47dbde7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 18:35:11 +0200 Subject: [PATCH 158/224] Refactor Get-GitHubReleaseAll to improve readability by replacing a nested pipeline with a foreach loop for processing API response items --- src/functions/private/Releases/Get-GitHubReleaseAll.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index d65e6ba7b..3b02f63b8 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -63,9 +63,9 @@ try { Invoke-GitHubAPI @inputObject | ForEach-Object { - (, $_.Response) | ForEach-Object { - $isLatest = $_.id -eq $latest.id - [GitHubRelease]::new($_, $Owner, $Repository, $isLatest) + foreach ($item in $_.Response) { + $isLatest = $item.id -eq $latest.id + [GitHubRelease]::new($item, $Owner, $Repository, $isLatest) } } } catch { return } From c4b292a5978bafcd8ec83b2faed25070a2af834e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 20:56:56 +0200 Subject: [PATCH 159/224] Add GitHubReleaseAsset class to manage release assets with properties for URL, name, label, state, content type, size, downloads, timestamps, and uploader. --- src/classes/public/Releases/GitHubRelease.ps1 | 139 ++++++------------ .../public/Releases/GitHubReleaseAsset.ps1 | 56 +++++++ src/formats/GitHubRelease.Format.ps1xml | 18 +-- .../private/Releases/Get-GitHubReleaseAll.ps1 | 60 ++++++-- .../Releases/Get-GitHubReleaseByTagName.ps1 | 44 ++++-- .../Releases/Get-GitHubReleaseLatest.ps1 | 40 ++++- tests/Releases.Tests.ps1 | 61 ++++---- 7 files changed, 256 insertions(+), 162 deletions(-) create mode 100644 src/classes/public/Releases/GitHubReleaseAsset.ps1 diff --git a/src/classes/public/Releases/GitHubRelease.ps1 b/src/classes/public/Releases/GitHubRelease.ps1 index dc2bcab87..8ef7adbaf 100644 --- a/src/classes/public/Releases/GitHubRelease.ps1 +++ b/src/classes/public/Releases/GitHubRelease.ps1 @@ -1,61 +1,4 @@ -class GitHubReleaseAsset : GitHubNode { - # Description: URL for downloading the asset - # Example: "https://github.com/PSModule/GitHub/releases/download/v0.22.1/asset.zip" - [string] $Url - - # Description: The file name of the asset - # Example: "Team Environment" - [string] $Name - - # Description: Label for the asset, can be null - # Example: null - [string] $Label - - # Description: State of the release asset (e.g., uploaded, open) - # Example: "uploaded" - [string] $State - - # Description: MIME type of the asset - # Example: "application/zip" - [string] $ContentType - - # Description: Size of the asset in bytes - # Example: 1024 - [int] $Size - - # Description: Number of times the asset was downloaded - # Example: 100 - [int] $Downloads - - # Description: Timestamp when the asset was created - # Example: "2025-04-11T09:03:38Z" - [datetime] $CreatedAt - - # Description: Timestamp when the asset was last updated - # Example: "2025-04-11T09:03:38Z" - [datetime] $UpdatedAt - - # Description: User who uploaded the asset, can be null - # Example: GitHubUser object or null - [GitHubUser] $Uploader - - GitHubReleaseAsset() {} - - GitHubReleaseAsset([PSCustomObject]$Object) { - $this.Url = $Object.url - $this.Name = $Object.name - $this.Label = $Object.label - $this.State = $Object.state - $this.ContentType = $Object.content_type - $this.Size = $Object.size - $this.Downloads = $Object.downloads - $this.CreatedAt = [datetime]::Parse($Object.created_at) - $this.UpdatedAt = [datetime]::Parse($Object.updated_at) - $this.Uploader = [GitHubUser]::new($Object.uploader) - } -} - -class GitHubRelease : GitHubNode { +class GitHubRelease : GitHubNode { # Name of the release, can be null # Example: "v0.22.1" [string] $Name @@ -80,15 +23,15 @@ class GitHubRelease : GitHubNode { # True if the release is the latest release on the repo. # Example: true - [bool] $Latest + [bool] $IsLatest # True to create a draft (unpublished) release, false to create a published one # Example: false - [bool] $Draft + [bool] $IsDraft # Whether to identify the release as a prerelease or a full release # Example: false - [bool] $Prerelease + [bool] $IsPrerelease # GitHub URL for the release # Example: "https://github.com/PSModule/GitHub/releases/tag/v0.22.1" @@ -101,46 +44,50 @@ class GitHubRelease : GitHubNode { # Example: "2025-04-11T09:03:38Z" [System.Nullable[datetime]] $CreatedAt - # Timestamp when the release was published, can be null + # Timestamp when the release was published # Example: "2025-04-11T13:41:34Z" [System.Nullable[datetime]] $PublishedAt - # URL for the release tarball, can be null - # Example: "https://api.github.com/repos/PSModule/GitHub/tarball/v0.22.1" - [string] $TarballUrl - - # URL for the release zipball, can be null - # Example: "https://api.github.com/repos/PSModule/GitHub/zipball/v0.22.1" - [string] $ZipballUrl - - # Assets that are uploaded to the release. - [GitHubReleaseAsset[]] $Assets - - # Number of mentions in the release notes - # Example: 1 - [int] $Mentions + # Timestamp when the release was updated + # Example: "2025-04-11T13:41:34Z" + [System.Nullable[datetime]] $UpdatedAt GitHubRelease() {} - GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository, [bool] $Latest) { - # From GitHubNode - $this.ID = $Object.id - $this.NodeID = $Object.node_id - - # From GitHubRelease - $this.Name = $Object.name - $this.Repository = $Repository - $this.Owner = $Owner - $this.Notes = $Object.body - $this.Url = $Object.html_url - $this.Author = [GitHubUser]::new($Object.author) - $this.Tag = $Object.tag_name - $this.Target = $Object.target_commitish - $this.Latest = $Latest - $this.Draft = $Object.draft - $this.Prerelease = $Object.prerelease - $this.CreatedAt = $Object.created_at - $this.PublishedAt = $Object.published_at - $this.Assets = $Object.assets | ForEach-Object { [GitHubReleaseAsset]::new($_) } + GitHubRelease([PSCustomObject] $Object, [string] $Owner, [string] $Repository, [System.Nullable[bool]] $Latest) { + if ($null -ne $Object.node_id) { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + $this.Tag = $Object.tag_name + $this.Name = $Object.name + $this.Notes = $Object.body + $this.IsLatest = $Latest + $this.IsDraft = $Object.draft + $this.IsPrerelease = $Object.prerelease + $this.Url = $Object.html_url + $this.Owner = $Owner + $this.Repository = $Repository + $this.Target = $Object.target_commitish + $this.CreatedAt = $Object.created_at + $this.PublishedAt = $Object.published_at + $this.Author = [GitHubUser]::new($Object.author) + } else { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + $this.Tag = $Object.tagName + $this.Name = $Object.name + $this.Notes = $Object.description + $this.IsLatest = $Object.isLatest + $this.IsDraft = $Object.isDraft + $this.IsPrerelease = $Object.isPrerelease + $this.Url = $Object.url + $this.Owner = $Owner + $this.Repository = $Repository + # $this.Target = $Object.target_commitish + $this.CreatedAt = $Object.createdAt + $this.PublishedAt = $Object.publishedAt + $this.UpdatedAt = $Object.updatedAt + $this.Author = [GitHubUser]::new($Object.author) + } } } diff --git a/src/classes/public/Releases/GitHubReleaseAsset.ps1 b/src/classes/public/Releases/GitHubReleaseAsset.ps1 new file mode 100644 index 000000000..513f2f211 --- /dev/null +++ b/src/classes/public/Releases/GitHubReleaseAsset.ps1 @@ -0,0 +1,56 @@ +class GitHubReleaseAsset : GitHubNode { + # Description: URL for downloading the asset + # Example: "https://github.com/PSModule/GitHub/releases/download/v0.22.1/asset.zip" + [string] $Url + + # Description: The file name of the asset + # Example: "Team Environment" + [string] $Name + + # Description: Label for the asset, can be null + # Example: null + [string] $Label + + # Description: State of the release asset (e.g., uploaded, open) + # Example: "uploaded" + [string] $State + + # Description: MIME type of the asset + # Example: "application/zip" + [string] $ContentType + + # Description: Size of the asset in bytes + # Example: 1024 + [int] $Size + + # Description: Number of times the asset was downloaded + # Example: 100 + [int] $Downloads + + # Description: Timestamp when the asset was created + # Example: "2025-04-11T09:03:38Z" + [datetime] $CreatedAt + + # Description: Timestamp when the asset was last updated + # Example: "2025-04-11T09:03:38Z" + [datetime] $UpdatedAt + + # Description: User who uploaded the asset, can be null + # Example: GitHubUser object or null + [GitHubUser] $Uploader + + GitHubReleaseAsset() {} + + GitHubReleaseAsset([PSCustomObject]$Object) { + $this.Url = $Object.url + $this.Name = $Object.name + $this.Label = $Object.label + $this.State = $Object.state + $this.ContentType = $Object.content_type + $this.Size = $Object.size + $this.Downloads = $Object.downloads + $this.CreatedAt = [datetime]::Parse($Object.created_at) + $this.UpdatedAt = [datetime]::Parse($Object.updated_at) + $this.Uploader = [GitHubUser]::new($Object.uploader) + } +} diff --git a/src/formats/GitHubRelease.Format.ps1xml b/src/formats/GitHubRelease.Format.ps1xml index fcdceb8ad..223919863 100644 --- a/src/formats/GitHubRelease.Format.ps1xml +++ b/src/formats/GitHubRelease.Format.ps1xml @@ -21,13 +21,13 @@ - + - + - + @@ -46,13 +46,13 @@ Url - Latest + IsLatest - Prerelease + IsPrerelease - Draft + IsDraft @@ -87,13 +87,13 @@ Target - Latest + IsLatest - Draft + IsDraft - Prerelease + IsPrerelease CreatedAt diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index 3b02f63b8..97a33a6f6 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -51,24 +51,58 @@ } process { - $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context + $hasNextPage = $true + $after = $null - $inputObject = @{ - Method = 'GET' - APIEndpoint = "/repos/$Owner/$Repository/releases" - Body = $body - PerPage = $PerPage - Context = $Context + do { + $inputObject = @{ + Query = @' +query($owner: String!, $repository: String!, $perPage: Int, $after: String) { + repository(owner: $owner, name: $repository) { + releases(first: $perPage, after: $after) { + nodes { + id + databaseId + tagName + name + description + isLatest + isDraft + isPrerelease + url + createdAt + publishedAt + updatedAt + author { + login } + } + pageInfo { + endCursor + hasNextPage + } + } + } +} +'@ + Variables = @{ + owner = $Owner + repository = $Repository + perPage = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context + after = $after + } + Context = $Context + } - try { - Invoke-GitHubAPI @inputObject | ForEach-Object { - foreach ($item in $_.Response) { - $isLatest = $item.id -eq $latest.id - [GitHubRelease]::new($item, $Owner, $Repository, $isLatest) + Invoke-GitHubGraphQLQuery @inputObject | ForEach-Object { + foreach ($release in $_.repository.releases.nodes) { + $isLatest = $latest.Id -eq $release.Id + [GitHubRelease]::new($release, $Owner, $Repository, $isLatest) } + $hasNextPage = $_.repository.releases.pageInfo.hasNextPage + $after = $_.repository.releases.pageInfo.endCursor } - } catch { return } + } while ($hasNextPage) } end { diff --git a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 index 3854a5ec1..cad6a7d30 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseByTagName.ps1 @@ -48,20 +48,44 @@ } process { - $latest = Get-GitHubReleaseLatest -Owner $Owner -Repository $Repository -Context $Context - $inputObject = @{ - Method = 'GET' - APIEndpoint = "/repos/$Owner/$Repository/releases/tags/$Tag" - Context = $Context + Query = @' +query($owner: String!, $repository: String!, $tag: String!) { + repository(owner: $owner, name: $repository) { + release(tagName: $tag) { + id + databaseId + tagName + name + description + isLatest + isDraft + isPrerelease + url + createdAt + publishedAt + updatedAt + author { + login + } + } + } +} +'@ + Variables = @{ + owner = $Owner + repository = $Repository + tag = $Tag + } + Context = $Context } - try { - Invoke-GitHubAPI @inputObject | ForEach-Object { - $isLatest = $_.Response.id -eq $latest.id - [GitHubRelease]::new($_.Response, $Owner, $Repository, $isLatest) + Invoke-GitHubGraphQLQuery @inputObject | ForEach-Object { + $release = $_.repository.release + if ($release) { + [GitHubRelease]::new($release, $Owner, $Repository, $null) } - } catch { return } + } } end { diff --git a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 index c699e2589..d4421fd51 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseLatest.ps1 @@ -47,16 +47,42 @@ process { $inputObject = @{ - Method = 'GET' - APIEndpoint = "/repos/$Owner/$Repository/releases/latest" - Context = $Context + Query = @' +query($owner: String!, $repository: String!) { + repository(owner: $owner, name: $repository) { + latestRelease { + id + databaseId + tagName + name + description + isLatest + isDraft + isPrerelease + url + createdAt + publishedAt + updatedAt + author { + login + } + } + } +} +'@ + Variables = @{ + owner = $Owner + repository = $Repository + } + Context = $Context } - try { - Invoke-GitHubAPI @inputObject | ForEach-Object { - [GitHubRelease]::new($_.Response, $Owner, $Repository, $true) + Invoke-GitHubGraphQLQuery @inputObject | ForEach-Object { + $release = $_.repository.latestRelease + if ($release) { + [GitHubRelease]::new($release, $Owner, $Repository, $null) } - } catch { return } + } } end { diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 410e468a7..bb69331ab 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -95,6 +95,9 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release.IsDraft | Should -BeTrue + $release.IsLatest | Should -BeFalse + $release.IsPrerelease | Should -BeFalse } It 'New-GitHubRelease - Creates a new release with a pre-release' { @@ -103,6 +106,10 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release.Tag | Should -Be 'v1.1' + $release.IsDraft | Should -BeFalse + $release.IsLatest | Should -BeFalse + $release.IsPrerelease | Should -BeTrue } It 'New-GitHubRelease - Creates a new release with a name' { @@ -122,7 +129,7 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.3' - $release.Latest | Should -Be $true + $release.IsLatest | Should -Be $true } It 'Get-GitHubRelease - Gets all releases' { @@ -144,8 +151,8 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.2' - $release.Latest | Should -Be $false - $release.Draft | Should -Be $true + $release.IsLatest | Should -Be $false + $release.IsDraft | Should -Be $true } It 'Get-GitHubRelease - Gets release by ID' { @@ -158,9 +165,9 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.0' - $release.Latest | Should -Be $false - $release.Draft | Should -Be $false - $release.Prerelease | Should -Be $false + $release.IsLatest | Should -Be $false + $release.IsDraft | Should -Be $false + $release.IsPrerelease | Should -Be $false } It 'Get-GitHubRelease - Gets release by ID using Pipeline' { @@ -184,9 +191,9 @@ Describe 'Releases' { $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.Tag | Should -Be 'v1.0' - $release.Latest | Should -Be $false - $release.Draft | Should -Be $false - $release.Prerelease | Should -Be $false + $release.IsLatest | Should -Be $false + $release.IsDraft | Should -Be $false + $release.IsPrerelease | Should -Be $false } It 'Update-GitHubRelease - Update release v1.1' { @@ -198,9 +205,9 @@ Describe 'Releases' { $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.Tag | Should -Be 'v1.1' - $release.Latest | Should -Be $false - $release.Draft | Should -Be $false - $release.Prerelease | Should -Be $true + $release.IsLatest | Should -Be $false + $release.IsDraft | Should -Be $false + $release.IsPrerelease | Should -Be $true } It 'Update-GitHubRelease - Update release v1.2' { @@ -211,9 +218,9 @@ Describe 'Releases' { $release | Should -Not -BeNullOrEmpty $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' - $release.Latest | Should -Be $false - $release.Draft | Should -Be $true - $release.Prerelease | Should -Be $false + $release.IsLatest | Should -Be $false + $release.IsDraft | Should -Be $true + $release.IsPrerelease | Should -Be $false } It 'Update-GitHubRelease - Update release v1.3' { @@ -225,9 +232,9 @@ Describe 'Releases' { $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.Tag | Should -Be 'v1.3' - $release.Latest | Should -Be $true - $release.Draft | Should -Be $false - $release.Prerelease | Should -Be $false + $release.IsLatest | Should -Be $true + $release.IsDraft | Should -Be $false + $release.IsPrerelease | Should -Be $false } It 'Set-GitHubRelease - Sets release v1.0 as latest' { @@ -237,9 +244,9 @@ Describe 'Releases' { } $release | Should -Not -BeNullOrEmpty $release.Tag | Should -Be 'v1.0' - $release.Latest | Should -Be $true - $release.Draft | Should -Be $false - $release.Prerelease | Should -Be $false + $release.IsLatest | Should -Be $true + $release.IsDraft | Should -Be $false + $release.IsPrerelease | Should -Be $false $release.Name | Should -Be 'Updated Release again' $release.Notes | Should -Be 'Updated release notes to something else' } @@ -251,9 +258,9 @@ Describe 'Releases' { } $release | Should -Not -BeNullOrEmpty $release.Tag | Should -Be 'v1.4' - $release.Latest | Should -Be $true - $release.Draft | Should -Be $false - $release.Prerelease | Should -Be $false + $release.IsLatest | Should -Be $true + $release.IsDraft | Should -Be $false + $release.IsPrerelease | Should -Be $false $release.Name | Should -Be 'New Release' $release.Notes | Should -Be 'New release notes' } @@ -264,9 +271,9 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.0' - $release.Latest | Should -Be $false - $release.Draft | Should -Be $false - $release.Prerelease | Should -Be $false + $release.IsLatest | Should -Be $false + $release.IsDraft | Should -Be $false + $release.IsPrerelease | Should -Be $false Remove-GitHubRelease -Owner $Owner -Repository $repo -ID $release.ID -Confirm:$false From 4c408afd56576136b25ed648d3e93bcfd029029b Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions@users.noreply.github.com> Date: Mon, 28 Apr 2025 18:58:38 +0000 Subject: [PATCH 160/224] Auto-generated changes --- Coverage.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Coverage.md b/Coverage.md index 3412fb4c2..abc67dd52 100644 --- a/Coverage.md +++ b/Coverage.md @@ -9,15 +9,15 @@ Covered functions - 222 + 220 Missing functions - 804 + 806 Coverage - 21.64% + 21.44% @@ -539,8 +539,8 @@ | `/repos/{owner}/{repo}/releases` | | :white_check_mark: | | :white_check_mark: | | | `/repos/{owner}/{repo}/releases/assets/{asset_id}` | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | | `/repos/{owner}/{repo}/releases/generate-notes` | | | | :white_check_mark: | | -| `/repos/{owner}/{repo}/releases/latest` | | :white_check_mark: | | | | -| `/repos/{owner}/{repo}/releases/tags/{tag}` | | :white_check_mark: | | | | +| `/repos/{owner}/{repo}/releases/latest` | | :x: | | | | +| `/repos/{owner}/{repo}/releases/tags/{tag}` | | :x: | | | | | `/repos/{owner}/{repo}/releases/{release_id}` | :white_check_mark: | :white_check_mark: | :white_check_mark: | | | | `/repos/{owner}/{repo}/releases/{release_id}/assets` | | :white_check_mark: | | :white_check_mark: | | | `/repos/{owner}/{repo}/releases/{release_id}/reactions` | | :x: | | :x: | | From 456b9f4d1358dbd2d9f3b52efcbf9b4478281d54 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 21:07:08 +0200 Subject: [PATCH 161/224] Refactor Get-GitHubReleaseAll to support paging and improve perPage parameter handling --- .../private/Releases/Get-GitHubReleaseAll.ps1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index 97a33a6f6..4b47db017 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -23,7 +23,7 @@ [List releases](https://docs.github.com/rest/releases/releases#list-releases) #> [OutputType([GitHubRelease])] - [CmdletBinding()] + [CmdletBinding(SupportsPaging)] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] @@ -35,8 +35,8 @@ # The number of results per page (max 100). [Parameter()] - [ValidateRange(0, 100)] - [int] $PerPage, + [ValidateRange(1, 100)] + [System.Nullable[int]] $PerPage, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -53,6 +53,7 @@ process { $hasNextPage = $true $after = $null + $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context do { $inputObject = @{ @@ -88,7 +89,7 @@ query($owner: String!, $repository: String!, $perPage: Int, $after: String) { Variables = @{ owner = $Owner repository = $Repository - perPage = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context + perPage = $perPageSetting after = $after } Context = $Context @@ -96,8 +97,7 @@ query($owner: String!, $repository: String!, $perPage: Int, $after: String) { Invoke-GitHubGraphQLQuery @inputObject | ForEach-Object { foreach ($release in $_.repository.releases.nodes) { - $isLatest = $latest.Id -eq $release.Id - [GitHubRelease]::new($release, $Owner, $Repository, $isLatest) + [GitHubRelease]::new($release, $Owner, $Repository, $null) } $hasNextPage = $_.repository.releases.pageInfo.hasNextPage $after = $_.repository.releases.pageInfo.endCursor From 1c52b9599b86903737f78304b9ce8553ba9e972e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 21:21:49 +0200 Subject: [PATCH 162/224] Update PerPage parameter handling to allow zero value and adjust validation range in Get-GitHubRelease and Resolve-GitHubContextSetting functions --- .../private/Auth/Context/Resolve-GitHubContextSetting.ps1 | 4 ++++ src/functions/private/Releases/Get-GitHubReleaseAll.ps1 | 4 ++-- src/functions/public/Releases/Get-GitHubRelease.ps1 | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 index bcfc2f646..b152c6e96 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContextSetting.ps1 @@ -58,6 +58,10 @@ [object] $Context ) + if ($Name -eq 'PerPage' -and $Value -eq 0) { + $Value = $null + } + Write-Debug "Resolving setting [$Name]" [pscustomobject]@{ 'Name' = $Name diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index 4b47db017..b20f6bc04 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -35,8 +35,8 @@ # The number of results per page (max 100). [Parameter()] - [ValidateRange(1, 100)] - [System.Nullable[int]] $PerPage, + [ValidateRange(0, 100)] + [int] $PerPage, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. diff --git a/src/functions/public/Releases/Get-GitHubRelease.ps1 b/src/functions/public/Releases/Get-GitHubRelease.ps1 index 4d11bc75f..a52b1a424 100644 --- a/src/functions/public/Releases/Get-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Get-GitHubRelease.ps1 @@ -68,7 +68,7 @@ # The number of results per page (max 100). [Parameter(ParameterSetName = 'AllVersions')] [ValidateRange(0, 100)] - [System.Nullable[int]] $PerPage, + [int] $PerPage, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. From f3a32a40385ee3a53db2be88b7360865687fad41 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 21:32:16 +0200 Subject: [PATCH 163/224] Fix Update-GitHubRelease to use IsLatest property for determining release status --- src/functions/public/Releases/Update-GitHubRelease.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index a863c4f09..8382b6fa8 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -158,7 +158,7 @@ } if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repository]", 'Update')) { - $resultLatest = $PSBoundParameters.ContainsKey('Latest') ? $Latest : $release.Latest + $resultLatest = $PSBoundParameters.ContainsKey('Latest') ? $Latest : $release.IsLatest Invoke-GitHubAPI @inputObject | ForEach-Object { [GitHubRelease]::new($_.Response , $Owner, $Repository, $resultLatest) } From d699f1eff6e7a1f333ffdccb6b75519a13a728e6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 21:33:52 +0200 Subject: [PATCH 164/224] Update assertions in Releases.Tests.ps1 to use Should -BeTrue and Should -BeFalse for clarity --- tests/Releases.Tests.ps1 | 54 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index bb69331ab..ffc240a1a 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -129,7 +129,7 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.3' - $release.IsLatest | Should -Be $true + $release.IsLatest | Should -BeTrue } It 'Get-GitHubRelease - Gets all releases' { @@ -151,8 +151,8 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.2' - $release.IsLatest | Should -Be $false - $release.IsDraft | Should -Be $true + $release.IsLatest | Should -BeFalse + $release.IsDraft | Should -BeTrue } It 'Get-GitHubRelease - Gets release by ID' { @@ -165,9 +165,9 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.0' - $release.IsLatest | Should -Be $false - $release.IsDraft | Should -Be $false - $release.IsPrerelease | Should -Be $false + $release.IsLatest | Should -BeFalse + $release.IsDraft | Should -BeFalse + $release.IsPrerelease | Should -BeFalse } It 'Get-GitHubRelease - Gets release by ID using Pipeline' { @@ -191,9 +191,9 @@ Describe 'Releases' { $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.Tag | Should -Be 'v1.0' - $release.IsLatest | Should -Be $false - $release.IsDraft | Should -Be $false - $release.IsPrerelease | Should -Be $false + $release.IsLatest | Should -BeFalse + $release.IsDraft | Should -BeFalse + $release.IsPrerelease | Should -BeFalse } It 'Update-GitHubRelease - Update release v1.1' { @@ -205,9 +205,9 @@ Describe 'Releases' { $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.Tag | Should -Be 'v1.1' - $release.IsLatest | Should -Be $false - $release.IsDraft | Should -Be $false - $release.IsPrerelease | Should -Be $true + $release.IsLatest | Should -BeFalse + $release.IsDraft | Should -BeFalse + $release.IsPrerelease | Should -BeTrue } It 'Update-GitHubRelease - Update release v1.2' { @@ -218,9 +218,9 @@ Describe 'Releases' { $release | Should -Not -BeNullOrEmpty $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' - $release.IsLatest | Should -Be $false - $release.IsDraft | Should -Be $true - $release.IsPrerelease | Should -Be $false + $release.IsLatest | Should -BeFalse + $release.IsDraft | Should -BeTrue + $release.IsPrerelease | Should -BeFalse } It 'Update-GitHubRelease - Update release v1.3' { @@ -232,9 +232,9 @@ Describe 'Releases' { $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.Tag | Should -Be 'v1.3' - $release.IsLatest | Should -Be $true - $release.IsDraft | Should -Be $false - $release.IsPrerelease | Should -Be $false + $release.IsLatest | Should -BeTrue + $release.IsDraft | Should -BeFalse + $release.IsPrerelease | Should -BeFalse } It 'Set-GitHubRelease - Sets release v1.0 as latest' { @@ -244,9 +244,9 @@ Describe 'Releases' { } $release | Should -Not -BeNullOrEmpty $release.Tag | Should -Be 'v1.0' - $release.IsLatest | Should -Be $true - $release.IsDraft | Should -Be $false - $release.IsPrerelease | Should -Be $false + $release.IsLatest | Should -BeTrue + $release.IsDraft | Should -BeFalse + $release.IsPrerelease | Should -BeFalse $release.Name | Should -Be 'Updated Release again' $release.Notes | Should -Be 'Updated release notes to something else' } @@ -258,9 +258,9 @@ Describe 'Releases' { } $release | Should -Not -BeNullOrEmpty $release.Tag | Should -Be 'v1.4' - $release.IsLatest | Should -Be $true - $release.IsDraft | Should -Be $false - $release.IsPrerelease | Should -Be $false + $release.IsLatest | Should -BeTrue + $release.IsDraft | Should -BeFalse + $release.IsPrerelease | Should -BeFalse $release.Name | Should -Be 'New Release' $release.Notes | Should -Be 'New release notes' } @@ -271,9 +271,9 @@ Describe 'Releases' { $release.Count | Should -Be 1 $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.0' - $release.IsLatest | Should -Be $false - $release.IsDraft | Should -Be $false - $release.IsPrerelease | Should -Be $false + $release.IsLatest | Should -BeFalse + $release.IsDraft | Should -BeFalse + $release.IsPrerelease | Should -BeFalse Remove-GitHubRelease -Owner $Owner -Repository $repo -ID $release.ID -Confirm:$false From eb667c366b47d8717961916c1e86fe4a55183b86 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 22:04:01 +0200 Subject: [PATCH 165/224] Remove mandatory ID parameter from Add-GitHubReleaseAsset and streamline asset name and label handling --- .../Assets/Add-GitHubReleaseAsset.ps1 | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index 404eae5ee..2e9883658 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -70,10 +70,6 @@ [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'Tag')] [string] $Tag, - # The unique identifier of the release. - [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'ID')] - [string] $ID, - #The name of the file asset. [Parameter()] [string] $Name, @@ -126,15 +122,15 @@ Remove-Item -Path $TempFilePath -Force -ErrorAction SilentlyContinue } } - # # If name is not provided, use the name of the file - # if (!$Name) { - # $Name = (Get-Item $Path).Name - # } + # If name is not provided, use the name of the file + if (!$Name) { + $Name = (Get-Item $Path).Name + } - # # If label is not provided, use the name of the file - # if (!$Label) { - # $Label = (Get-Item $Path).Name - # } + # If label is not provided, use the name of the file + if (!$Label) { + $Label = (Get-Item $Path).Name + } if (!$ContentType) { $ContentType = switch ((Get-Item $fileToUpload).Extension) { @@ -164,9 +160,6 @@ 'Tag' { $release = Get-GitHubReleaseByTagName -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context } - 'ID' { - $release = Get-GitHubReleaseByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context - } default { throw "Invalid parameter set: $($PSCmdlet.ParameterSetName)" } @@ -185,6 +178,7 @@ UploadFilePath = $fileToUpload Body = $body Context = $Context + HttpVersion = '1.1' } Invoke-GitHubAPI @inputObject | ForEach-Object { From 340d0a8d401beae9434bcd168ffde957b0e3a41d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Mon, 28 Apr 2025 22:48:16 +0200 Subject: [PATCH 166/224] Refactor Add-GitHubReleaseAsset to remove mandatory ID parameter and streamline tag handling --- .../Releases/Assets/Add-GitHubReleaseAsset.ps1 | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index 2e9883658..56f3436d0 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -67,7 +67,7 @@ [string] $Repository, # The name of the tag to get a release from. - [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'Tag')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Tag, #The name of the file asset. @@ -156,14 +156,7 @@ } } - switch ($PSCmdlet.ParameterSetName) { - 'Tag' { - $release = Get-GitHubReleaseByTagName -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context - } - default { - throw "Invalid parameter set: $($PSCmdlet.ParameterSetName)" - } - } + $release = Get-GitHubReleaseByTagName -Owner $Owner -Repository $Repository -Tag $Tag -Context $Context $body = @{ name = $Name @@ -171,14 +164,13 @@ } $body | Remove-HashtableEntry -NullOrEmptyValues + $uploadUrl = New-Uri -BaseUri "https://uploads.$($Context.HostName)" -Path "/repos/$Owner/$Repository/releases/$($release.id)/assets" -Query $Body $inputObject = @{ Method = 'POST' - ApiEndpoint = "/repos/$Owner/$Repository/releases/$($release.id)/assets" + Uri = $uploadUrl ContentType = $ContentType UploadFilePath = $fileToUpload - Body = $body Context = $Context - HttpVersion = '1.1' } Invoke-GitHubAPI @inputObject | ForEach-Object { From 51e882d409750c8b525af1afd4304587191f262e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 29 Apr 2025 00:12:40 +0200 Subject: [PATCH 167/224] Enhance GitHubReleaseAsset and related functions: update property types to nullable, rename uploader property, and add Get-GitHubReleaseAssetByName function for asset retrieval by name. --- .../public/Releases/GitHubReleaseAsset.ps1 | 43 +++++++++---- .../Assets/Get-GitHubReleaseAssetByID.ps1 | 1 - .../Assets/Get-GitHubReleaseAssetByName.ps1 | 62 +++++++++++++++++++ .../Get-GitHubReleaseAssetByReleaseID.ps1 | 1 - .../Assets/Add-GitHubReleaseAsset.ps1 | 2 +- 5 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByName.ps1 diff --git a/src/classes/public/Releases/GitHubReleaseAsset.ps1 b/src/classes/public/Releases/GitHubReleaseAsset.ps1 index 513f2f211..1382ae2d4 100644 --- a/src/classes/public/Releases/GitHubReleaseAsset.ps1 +++ b/src/classes/public/Releases/GitHubReleaseAsset.ps1 @@ -29,28 +29,45 @@ # Description: Timestamp when the asset was created # Example: "2025-04-11T09:03:38Z" - [datetime] $CreatedAt + [System.Nullable[datetime]] $CreatedAt # Description: Timestamp when the asset was last updated # Example: "2025-04-11T09:03:38Z" - [datetime] $UpdatedAt + [System.Nullable[datetime]] $UpdatedAt # Description: User who uploaded the asset, can be null # Example: GitHubUser object or null - [GitHubUser] $Uploader + [GitHubUser] $UploadedBy GitHubReleaseAsset() {} GitHubReleaseAsset([PSCustomObject]$Object) { - $this.Url = $Object.url - $this.Name = $Object.name - $this.Label = $Object.label - $this.State = $Object.state - $this.ContentType = $Object.content_type - $this.Size = $Object.size - $this.Downloads = $Object.downloads - $this.CreatedAt = [datetime]::Parse($Object.created_at) - $this.UpdatedAt = [datetime]::Parse($Object.updated_at) - $this.Uploader = [GitHubUser]::new($Object.uploader) + if ($null -ne $Object.node_id) { + $this.ID = $Object.id + $this.NodeID = $Object.node_id + $this.Url = $Object.browser_download_url + $this.Name = $Object.name + $this.Label = $Object.label + $this.State = $Object.state + $this.ContentType = $Object.content_type + $this.Size = $Object.size + $this.Downloads = $Object.download_count + $this.CreatedAt = [datetime]::Parse($Object.created_at) + $this.UpdatedAt = [datetime]::Parse($Object.updated_at) + $this.UploadedBy = [GitHubUser]::new($Object.uploader) + } else { + $this.ID = $Object.databaseId + $this.NodeID = $Object.id + $this.Url = $Object.downloadUrl + $this.Name = $Object.name + $this.Label = $Object.label + $this.State = $Object.state + $this.ContentType = $Object.contentType + $this.Size = $Object.size + $this.Downloads = $Object.downloadCount + $this.CreatedAt = [datetime]::Parse($Object.createdAt) + $this.UpdatedAt = [datetime]::Parse($Object.updatedAt) + $this.UploadedBy = [GitHubUser]::new($Object.uploadedBy) + } } } diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 index e7a739fba..c5bbea92b 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 @@ -30,7 +30,6 @@ # The unique identifier of the asset. [Parameter(Mandatory)] - [Alias('asset_id')] [string] $ID, # The context to run the command in. Used to get the details for the API call. diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByName.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByName.ps1 new file mode 100644 index 000000000..82bd39c96 --- /dev/null +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByName.ps1 @@ -0,0 +1,62 @@ +filter Get-GitHubReleaseAssetByName { + <# + .SYNOPSIS + Get a release asset by name + + .DESCRIPTION + To download the asset's binary content, set the `Accept` header of the request to + [`application/octet-stream`](https://docs.github.com/rest/overview/media-types). + The API will either redirect the client to the location, or stream it directly if + possible. API clients should handle both a `200` or `302` response. + + .EXAMPLE + Get-GitHubReleaseAssetByName -Owner 'octocat' -Repository 'hello-world' -ID '1234567' + + Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'. + + .NOTES + https://docs.github.com/rest/releases/assets#get-a-release-asset + + #> + [CmdletBinding()] + param( + # The account owner of the repository. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Repository, + + # The unique identifier of the asset. + [Parameter(Mandatory)] + [string] $ID, + + # The context to run the command in. Used to get the details for the API call. + # Can be either a string or a GitHubContext object. + [Parameter(Mandatory)] + [object] $Context + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + } + + process { + $inputObject = @{ + Method = 'GET' + APIEndpoint = "/repos/$Owner/$Repository/releases/assets/$ID" + Context = $Context + } + + Invoke-GitHubAPI @inputObject | ForEach-Object { + Write-Output $_.Response + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 index 512f93e4a..0943c3f89 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 @@ -30,7 +30,6 @@ Mandatory, ParameterSetName = 'ID' )] - [Alias('release_id')] [string] $ID, # The number of results per page (max 100). diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index 56f3436d0..da8f88ff7 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -174,7 +174,7 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubReleaseAsset]($_.Response) } } From f7bd454d86777082ff58d2a08333d441d8b5ca29 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 29 Apr 2025 12:28:48 +0200 Subject: [PATCH 168/224] Refactor Get-GitHubReleaseAsset to support asset retrieval by name and tag, enhancing functionality and documentation. --- ...me.ps1 => Get-GitHubReleaseAssetByTag.ps1} | 42 +++++++++++++++---- .../Assets/Get-GitHubReleaseAsset.ps1 | 42 +++++++++++++++++-- 2 files changed, 73 insertions(+), 11 deletions(-) rename src/functions/private/Releases/Assets/{Get-GitHubReleaseAssetByName.ps1 => Get-GitHubReleaseAssetByTag.ps1} (63%) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByName.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 similarity index 63% rename from src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByName.ps1 rename to src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index 82bd39c96..3025c3967 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByName.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -1,4 +1,4 @@ -filter Get-GitHubReleaseAssetByName { +filter Get-GitHubReleaseAssetByTag { <# .SYNOPSIS Get a release asset by name @@ -10,7 +10,7 @@ possible. API clients should handle both a `200` or `302` response. .EXAMPLE - Get-GitHubReleaseAssetByName -Owner 'octocat' -Repository 'hello-world' -ID '1234567' + Get-GitHubReleaseAssetByTag -Owner 'octocat' -Repository 'hello-world' -ID '1234567' Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'. @@ -46,13 +46,41 @@ process { $inputObject = @{ - Method = 'GET' - APIEndpoint = "/repos/$Owner/$Repository/releases/assets/$ID" - Context = $Context + Query = @' +query($owner: String!, $repository: String!) { + repository(owner: $owner, name: $repository) { + latestRelease { + id + databaseId + tagName + name + description + isLatest + isDraft + isPrerelease + url + createdAt + publishedAt + updatedAt + author { + login + } + } + } +} +'@ + Variables = @{ + owner = $Owner + repository = $Repository + } + Context = $Context } - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + Invoke-GitHubGraphQLQuery @inputObject | ForEach-Object { + $release = $_.repository.latestRelease + if ($release) { + [GitHubRelease]::new($release, $Owner, $Repository, $null) + } } } diff --git a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 index 5e303537f..c6950d191 100644 --- a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 @@ -1,11 +1,13 @@ filter Get-GitHubReleaseAsset { <# .SYNOPSIS - List release assets based on a release ID or asset ID + List release assets based on a release ID, asset ID, or asset name .DESCRIPTION If an asset ID is provided, the asset is returned. If a release ID is provided, all assets for the release are returned. + If a release ID and name are provided, the specific named asset from that release is returned. + If a tag and name are provided, the specific named asset from the release with that tag is returned. .EXAMPLE Get-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -ID '1234567' @@ -15,7 +17,17 @@ .EXAMPLE Get-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -ReleaseID '7654321' - Gets the release assets for the release with the ID '7654321' for the repository 'octocat/hello-world'. + Gets all release assets for the release with the ID '7654321' for the repository 'octocat/hello-world'. + + .EXAMPLE + Get-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -ReleaseID '7654321' -Name 'example.zip' + + Gets the release asset named 'example.zip' from the release with ID '7654321' for the repository 'octocat/hello-world'. + + .EXAMPLE + Get-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Name 'example.zip' + + Gets the release asset named 'example.zip' from the release tagged as 'v1.0.0' for the repository 'octocat/hello-world'. .INPUTS GitHubRelease @@ -44,8 +56,18 @@ # The unique identifier of the release. [Parameter(Mandatory, ParameterSetName = 'List assets from a release', ValueFromPipelineByPropertyName)] + [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by name from a release ID', ValueFromPipelineByPropertyName)] [string] $ReleaseID, + # The tag name of the release. + [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by name from a tag')] + [string] $Tag, + + # The name of the asset to find. + [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by name from a release ID')] + [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by name from a tag')] + [string] $Name, + # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] @@ -61,12 +83,24 @@ process { switch ($PSCmdlet.ParameterSetName) { - 'ReleaseID' { + 'List assets from a release' { Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repository $Repository -ReleaseID $ReleaseID -Context $Context } - 'ID' { + 'Get a specific asset by ID' { Get-GitHubReleaseAssetByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context } + 'Get a specific asset by name from a release ID' { + $assets = Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repository $Repository -ReleaseID $ReleaseID -Context $Context + $asset = $assets | Where-Object { $_.Name -eq $Name } + if ($asset) { + $asset + } else { + Write-Warning "Asset with name '$Name' not found in release with ID '$ReleaseID'" + } + } + 'Get a specific asset by name from a tag' { + Get-GitHubReleaseAssetByTag -Owner $Owner -Repository $Repository -Tag $Tag -Name $Name -Context $Context + } } } From 665c18f25482f45422042ebcdff0d2e1ac9af0f6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 29 Apr 2025 12:44:09 +0200 Subject: [PATCH 169/224] Add tests for GitHub release asset management: create, retrieve, update, and remove assets --- tests/Releases.Tests.ps1 | 126 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index ffc240a1a..e893e8889 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -280,6 +280,132 @@ Describe 'Releases' { $release = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' $release | Should -BeNullOrEmpty } + + It 'Add-GitHubReleaseAsset - Creates a new release asset' { + # Create a sample file to upload + $fileName = "testasset.txt" + $tempFilePath = Join-Path -Path $env:TEMP -ChildPath $fileName + Set-Content -Path $tempFilePath -Value "This is a test file for GitHub release asset testing." + + # Get the latest release to attach the asset to + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + + # Upload the asset + $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -FilePath $tempFilePath + LogGroup 'Added asset' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + + $asset | Should -Not -BeNullOrEmpty + $asset.Name | Should -Be $fileName + + # Clean up the temporary file + Remove-Item -Path $tempFilePath -Force + } + + It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { + # Get the latest release to retrieve assets from + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + + # Get all assets for the release + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + LogGroup 'Release assets by release ID' { + Write-Host ($assets | Format-List -Property * | Out-String) + } + + $assets | Should -Not -BeNullOrEmpty + $assets | Should -BeOfType 'GitHubReleaseAsset' + } + + It 'Get-GitHubReleaseAsset - Gets a specific asset by ID' { + # Get the latest release to retrieve assets from + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + + # Get all assets for the release + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + + # Get the first asset by ID + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID + LogGroup 'Release asset by asset ID' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + + $asset | Should -Not -BeNullOrEmpty + $asset | Should -BeOfType 'GitHubReleaseAsset' + $asset.ID | Should -Be $assets[0].ID + } + + It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a release ID' { + # Get the latest release to retrieve assets from + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + + # Get all assets for the release + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + + # Get the first asset by name from the release ID + $assetName = $assets[0].Name + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Name $assetName + LogGroup 'Release asset by name from release ID' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + + $asset | Should -Not -BeNullOrEmpty + $asset | Should -BeOfType 'GitHubReleaseAsset' + $asset.Name | Should -Be $assetName + } + + It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a tag' { + # Get the latest release to retrieve assets from + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + + # Get all assets for the release + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + + # Get the first asset by name from the release tag + $assetName = $assets[0].Name + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName + LogGroup 'Release asset by name from tag' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + + $asset | Should -Not -BeNullOrEmpty + $asset.Name | Should -Be $assetName + } + + It 'Update-GitHubReleaseAsset - Updates a release asset' { + # Get the latest release to retrieve assets from + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + + # Get all assets for the release + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + + # Update the first asset + $newLabel = "Updated test asset" + $asset = Update-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID -Label $newLabel + LogGroup 'Updated asset' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + + $asset | Should -Not -BeNullOrEmpty + $asset.Label | Should -Be $newLabel + } + + It 'Remove-GitHubReleaseAsset - Removes a release asset' { + # Get the latest release to retrieve assets from + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + + # Get all assets for the release + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + + # Remove the first asset + $assetID = $assets[0].ID + Remove-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assetID -Confirm:$false + + # Verify the asset was removed + $updatedAssets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + $remainingAsset = $updatedAssets | Where-Object { $_.ID -eq $assetID } + $remainingAsset | Should -BeNullOrEmpty + } } } } From 71efe235e7c48161a0bba0f5595e43e61f5f1509 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 29 Apr 2025 12:49:31 +0200 Subject: [PATCH 170/224] Refactor asset test cases in Releases.Tests.ps1: standardize string quotes and remove unnecessary blank lines for improved readability. --- tests/Releases.Tests.ps1 | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index e893e8889..7ac6b27c1 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -283,22 +283,22 @@ Describe 'Releases' { It 'Add-GitHubReleaseAsset - Creates a new release asset' { # Create a sample file to upload - $fileName = "testasset.txt" + $fileName = 'testasset.txt' $tempFilePath = Join-Path -Path $env:TEMP -ChildPath $fileName - Set-Content -Path $tempFilePath -Value "This is a test file for GitHub release asset testing." + Set-Content -Path $tempFilePath -Value 'This is a test file for GitHub release asset testing.' # Get the latest release to attach the asset to $release = Get-GitHubRelease -Owner $Owner -Repository $repo - + # Upload the asset $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -FilePath $tempFilePath LogGroup 'Added asset' { Write-Host ($asset | Format-List -Property * | Out-String) } - + $asset | Should -Not -BeNullOrEmpty $asset.Name | Should -Be $fileName - + # Clean up the temporary file Remove-Item -Path $tempFilePath -Force } @@ -306,13 +306,13 @@ Describe 'Releases' { It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { # Get the latest release to retrieve assets from $release = Get-GitHubRelease -Owner $Owner -Repository $repo - + # Get all assets for the release $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID LogGroup 'Release assets by release ID' { Write-Host ($assets | Format-List -Property * | Out-String) } - + $assets | Should -Not -BeNullOrEmpty $assets | Should -BeOfType 'GitHubReleaseAsset' } @@ -320,16 +320,16 @@ Describe 'Releases' { It 'Get-GitHubReleaseAsset - Gets a specific asset by ID' { # Get the latest release to retrieve assets from $release = Get-GitHubRelease -Owner $Owner -Repository $repo - + # Get all assets for the release $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - + # Get the first asset by ID $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID LogGroup 'Release asset by asset ID' { Write-Host ($asset | Format-List -Property * | Out-String) } - + $asset | Should -Not -BeNullOrEmpty $asset | Should -BeOfType 'GitHubReleaseAsset' $asset.ID | Should -Be $assets[0].ID @@ -338,17 +338,17 @@ Describe 'Releases' { It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a release ID' { # Get the latest release to retrieve assets from $release = Get-GitHubRelease -Owner $Owner -Repository $repo - + # Get all assets for the release $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - + # Get the first asset by name from the release ID $assetName = $assets[0].Name $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Name $assetName LogGroup 'Release asset by name from release ID' { Write-Host ($asset | Format-List -Property * | Out-String) } - + $asset | Should -Not -BeNullOrEmpty $asset | Should -BeOfType 'GitHubReleaseAsset' $asset.Name | Should -Be $assetName @@ -357,17 +357,17 @@ Describe 'Releases' { It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a tag' { # Get the latest release to retrieve assets from $release = Get-GitHubRelease -Owner $Owner -Repository $repo - + # Get all assets for the release $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - + # Get the first asset by name from the release tag $assetName = $assets[0].Name $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName LogGroup 'Release asset by name from tag' { Write-Host ($asset | Format-List -Property * | Out-String) } - + $asset | Should -Not -BeNullOrEmpty $asset.Name | Should -Be $assetName } @@ -375,17 +375,17 @@ Describe 'Releases' { It 'Update-GitHubReleaseAsset - Updates a release asset' { # Get the latest release to retrieve assets from $release = Get-GitHubRelease -Owner $Owner -Repository $repo - + # Get all assets for the release $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - + # Update the first asset - $newLabel = "Updated test asset" + $newLabel = 'Updated test asset' $asset = Update-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID -Label $newLabel LogGroup 'Updated asset' { Write-Host ($asset | Format-List -Property * | Out-String) } - + $asset | Should -Not -BeNullOrEmpty $asset.Label | Should -Be $newLabel } @@ -393,14 +393,14 @@ Describe 'Releases' { It 'Remove-GitHubReleaseAsset - Removes a release asset' { # Get the latest release to retrieve assets from $release = Get-GitHubRelease -Owner $Owner -Repository $repo - + # Get all assets for the release $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - + # Remove the first asset $assetID = $assets[0].ID Remove-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assetID -Confirm:$false - + # Verify the asset was removed $updatedAssets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID $remainingAsset = $updatedAssets | Where-Object { $_.ID -eq $assetID } From c760b45fb73b1f49cc8dbf967db178ceb4b7eee2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 29 Apr 2025 13:01:47 +0200 Subject: [PATCH 171/224] Add tests for Add-GitHubReleaseAsset: create asset with custom parameters and upload folder as zipped asset --- tests/Releases.Tests.ps1 | 59 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 7ac6b27c1..ea542a7c7 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -283,9 +283,8 @@ Describe 'Releases' { It 'Add-GitHubReleaseAsset - Creates a new release asset' { # Create a sample file to upload - $fileName = 'testasset.txt' - $tempFilePath = Join-Path -Path $env:TEMP -ChildPath $fileName - Set-Content -Path $tempFilePath -Value 'This is a test file for GitHub release asset testing.' + $fileName = 'AuthCases.ps1' + $tempFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$fileName" # Get the latest release to attach the asset to $release = Get-GitHubRelease -Owner $Owner -Repository $repo @@ -303,6 +302,60 @@ Describe 'Releases' { Remove-Item -Path $tempFilePath -Force } + It 'Add-GitHubReleaseAsset - Creates a release asset with custom parameters' { + # Use an existing markdown file from the Data folder + $mdFileName = 'IssueForm.md' + $mdFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$mdFileName" + + # Get a release to attach the asset to + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + + # Custom parameters for the asset + $customName = 'CustomIssueTemplate.md' + $contentType = 'text/markdown' + $label = 'Issue Template Documentation' + + # Upload the asset with custom parameters + $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -FilePath $mdFilePath -Name $customName -ContentType $contentType -Label $label + + LogGroup 'Added markdown asset' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + + $asset | Should -Not -BeNullOrEmpty + $asset.Name | Should -Be $customName + $asset.ContentType | Should -Be $contentType + $asset.Label | Should -Be $label + $asset.Size | Should -BeGreaterThan 0 + } + + It 'Add-GitHubReleaseAsset - Adds a folder as a zipped asset to a release' { + # Get the latest release to attach the asset to + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + + # Create a temporary zip file from the Data folder + $path = Join-Path -Path $PSScriptRoot -ChildPath "Data" + $label = "Test Data Files" + + # Upload the zip file as an asset + $asset = $release | Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -Label $label -Path $path + + LogGroup 'Added zip asset' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + + # Verify the asset was created correctly + $asset | Should -Not -BeNullOrEmpty + $asset.Name | Should -Be $zipAssetName + $asset.Label | Should -Be $label + $asset.Size | Should -BeGreaterThan 0 + + # Clean up the temporary zip file + if (Test-Path $tempZipPath) { + Remove-Item -Path $tempZipPath -Force + } + } + It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { # Get the latest release to retrieve assets from $release = Get-GitHubRelease -Owner $Owner -Repository $repo From a77bbef31450d7add085bfe72bef86d3d525d5d4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 29 Apr 2025 13:25:55 +0200 Subject: [PATCH 172/224] Refactor Add-GitHubReleaseAsset calls in tests: replace -FilePath with -Path for consistency and clarity. --- tests/Releases.Tests.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index ea542a7c7..6a0a1c251 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -290,7 +290,7 @@ Describe 'Releases' { $release = Get-GitHubRelease -Owner $Owner -Repository $repo # Upload the asset - $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -FilePath $tempFilePath + $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Path $tempFilePath LogGroup 'Added asset' { Write-Host ($asset | Format-List -Property * | Out-String) } @@ -316,7 +316,7 @@ Describe 'Releases' { $label = 'Issue Template Documentation' # Upload the asset with custom parameters - $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -FilePath $mdFilePath -Name $customName -ContentType $contentType -Label $label + $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Path $mdFilePath -Name $customName -ContentType $contentType -Label $label LogGroup 'Added markdown asset' { Write-Host ($asset | Format-List -Property * | Out-String) @@ -334,8 +334,8 @@ Describe 'Releases' { $release = Get-GitHubRelease -Owner $Owner -Repository $repo # Create a temporary zip file from the Data folder - $path = Join-Path -Path $PSScriptRoot -ChildPath "Data" - $label = "Test Data Files" + $path = Join-Path -Path $PSScriptRoot -ChildPath 'Data' + $label = 'Test Data Files' # Upload the zip file as an asset $asset = $release | Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -Label $label -Path $path From 5659507b332005a96859cbd1a33ea0288c5d31b0 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 17:36:18 +0200 Subject: [PATCH 173/224] Refactor Add-GitHubReleaseAsset and Remove-GitHubReleaseAsset: streamline parameter handling and enhance documentation with .LINK entries. --- .../Assets/Add-GitHubReleaseAsset.ps1 | 11 +- .../Assets/Remove-GitHubReleaseAsset.ps1 | 3 + .../Assets/Update-GitHubReleaseAsset.ps1 | 3 + tests/Releases.Tests.ps1 | 270 +++++++----------- 4 files changed, 117 insertions(+), 170 deletions(-) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index da8f88ff7..cdf97b05e 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -122,12 +122,9 @@ Remove-Item -Path $TempFilePath -Force -ErrorAction SilentlyContinue } } - # If name is not provided, use the name of the file if (!$Name) { $Name = (Get-Item $Path).Name } - - # If label is not provided, use the name of the file if (!$Label) { $Label = (Get-Item $Path).Name } @@ -164,7 +161,13 @@ } $body | Remove-HashtableEntry -NullOrEmptyValues - $uploadUrl = New-Uri -BaseUri "https://uploads.$($Context.HostName)" -Path "/repos/$Owner/$Repository/releases/$($release.id)/assets" -Query $Body + $urlParams = @{ + BaseUri = "https://uploads.$($Context.HostName)" + Path = "/repos/$Owner/$Repository/releases/$($release.id)/assets" + Query = $body + } + $uploadUrl = New-Uri @urlParams + $inputObject = @{ Method = 'POST' Uri = $uploadUrl diff --git a/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 index 7f754684a..a9a589ebb 100644 --- a/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 @@ -11,6 +11,9 @@ Deletes the release asset with the ID '1234567' for the repository 'octocat/hello-world'. + .LINK + https://psmodule.io/GitHub/Functions/Releases/Assets/Remove-GitHubReleaseAsset + .NOTES [Delete a release asset](https://docs.github.com/rest/releases/assets#delete-a-release-asset) #> diff --git a/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 index 39c13f130..2988f4371 100644 --- a/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 @@ -12,6 +12,9 @@ Updates the release asset with the ID '1234567' for the repository 'octocat/hello-world' with the new name 'new_asset_name' and label 'new_asset_label'. + .LINK + https://psmodule.io/GitHub/Functions/Releases/Assets/Update-GitHubReleaseAsset + .NOTES [Update a release asset](https://docs.github.com/rest/releases/assets#update-a-release-asset) #> diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 6a0a1c251..31e9de5f9 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -282,183 +282,121 @@ Describe 'Releases' { } It 'Add-GitHubReleaseAsset - Creates a new release asset' { - # Create a sample file to upload $fileName = 'AuthCases.ps1' $tempFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$fileName" - - # Get the latest release to attach the asset to $release = Get-GitHubRelease -Owner $Owner -Repository $repo - - # Upload the asset - $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Path $tempFilePath + $asset = $release | Add-GitHubReleaseAsset -Path $tempFilePath LogGroup 'Added asset' { Write-Host ($asset | Format-List -Property * | Out-String) } - $asset | Should -Not -BeNullOrEmpty $asset.Name | Should -Be $fileName - - # Clean up the temporary file Remove-Item -Path $tempFilePath -Force } - It 'Add-GitHubReleaseAsset - Creates a release asset with custom parameters' { - # Use an existing markdown file from the Data folder - $mdFileName = 'IssueForm.md' - $mdFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$mdFileName" - - # Get a release to attach the asset to - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - - # Custom parameters for the asset - $customName = 'CustomIssueTemplate.md' - $contentType = 'text/markdown' - $label = 'Issue Template Documentation' - - # Upload the asset with custom parameters - $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Path $mdFilePath -Name $customName -ContentType $contentType -Label $label - - LogGroup 'Added markdown asset' { - Write-Host ($asset | Format-List -Property * | Out-String) - } - - $asset | Should -Not -BeNullOrEmpty - $asset.Name | Should -Be $customName - $asset.ContentType | Should -Be $contentType - $asset.Label | Should -Be $label - $asset.Size | Should -BeGreaterThan 0 - } - - It 'Add-GitHubReleaseAsset - Adds a folder as a zipped asset to a release' { - # Get the latest release to attach the asset to - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - - # Create a temporary zip file from the Data folder - $path = Join-Path -Path $PSScriptRoot -ChildPath 'Data' - $label = 'Test Data Files' - - # Upload the zip file as an asset - $asset = $release | Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -Label $label -Path $path - - LogGroup 'Added zip asset' { - Write-Host ($asset | Format-List -Property * | Out-String) - } - - # Verify the asset was created correctly - $asset | Should -Not -BeNullOrEmpty - $asset.Name | Should -Be $zipAssetName - $asset.Label | Should -Be $label - $asset.Size | Should -BeGreaterThan 0 - - # Clean up the temporary zip file - if (Test-Path $tempZipPath) { - Remove-Item -Path $tempZipPath -Force - } - } - - It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { - # Get the latest release to retrieve assets from - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - - # Get all assets for the release - $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - LogGroup 'Release assets by release ID' { - Write-Host ($assets | Format-List -Property * | Out-String) - } - - $assets | Should -Not -BeNullOrEmpty - $assets | Should -BeOfType 'GitHubReleaseAsset' - } - - It 'Get-GitHubReleaseAsset - Gets a specific asset by ID' { - # Get the latest release to retrieve assets from - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - - # Get all assets for the release - $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - - # Get the first asset by ID - $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID - LogGroup 'Release asset by asset ID' { - Write-Host ($asset | Format-List -Property * | Out-String) - } - - $asset | Should -Not -BeNullOrEmpty - $asset | Should -BeOfType 'GitHubReleaseAsset' - $asset.ID | Should -Be $assets[0].ID - } - - It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a release ID' { - # Get the latest release to retrieve assets from - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - - # Get all assets for the release - $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - - # Get the first asset by name from the release ID - $assetName = $assets[0].Name - $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Name $assetName - LogGroup 'Release asset by name from release ID' { - Write-Host ($asset | Format-List -Property * | Out-String) - } - - $asset | Should -Not -BeNullOrEmpty - $asset | Should -BeOfType 'GitHubReleaseAsset' - $asset.Name | Should -Be $assetName - } - - It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a tag' { - # Get the latest release to retrieve assets from - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - - # Get all assets for the release - $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - - # Get the first asset by name from the release tag - $assetName = $assets[0].Name - $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName - LogGroup 'Release asset by name from tag' { - Write-Host ($asset | Format-List -Property * | Out-String) - } - - $asset | Should -Not -BeNullOrEmpty - $asset.Name | Should -Be $assetName - } - - It 'Update-GitHubReleaseAsset - Updates a release asset' { - # Get the latest release to retrieve assets from - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - - # Get all assets for the release - $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - - # Update the first asset - $newLabel = 'Updated test asset' - $asset = Update-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID -Label $newLabel - LogGroup 'Updated asset' { - Write-Host ($asset | Format-List -Property * | Out-String) - } - - $asset | Should -Not -BeNullOrEmpty - $asset.Label | Should -Be $newLabel - } - - It 'Remove-GitHubReleaseAsset - Removes a release asset' { - # Get the latest release to retrieve assets from - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - - # Get all assets for the release - $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - - # Remove the first asset - $assetID = $assets[0].ID - Remove-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assetID -Confirm:$false - - # Verify the asset was removed - $updatedAssets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - $remainingAsset = $updatedAssets | Where-Object { $_.ID -eq $assetID } - $remainingAsset | Should -BeNullOrEmpty - } + # It 'Add-GitHubReleaseAsset - Creates a release asset with custom parameters' { + # $mdFileName = 'IssueForm.md' + # $mdFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$mdFileName" + # $release = Get-GitHubRelease -Owner $Owner -Repository $repo + # $customName = 'CustomIssueTemplate.md' + # $contentType = 'text/markdown' + # $label = 'Issue Template Documentation' + # $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Path $mdFilePath -Name $customName -ContentType $contentType -Label $label + # LogGroup 'Added markdown asset' { + # Write-Host ($asset | Format-List -Property * | Out-String) + # } + # $asset | Should -Not -BeNullOrEmpty + # $asset.Name | Should -Be $customName + # $asset.ContentType | Should -Be $contentType + # $asset.Label | Should -Be $label + # $asset.Size | Should -BeGreaterThan 0 + # } + + # It 'Add-GitHubReleaseAsset - Adds a folder as a zipped asset to a release' { + # $release = Get-GitHubRelease -Owner $Owner -Repository $repo + # $path = Join-Path -Path $PSScriptRoot -ChildPath 'Data' + # $label = 'Test Data Files' + # $asset = $release | Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -Label $label -Path $path + # LogGroup 'Added zip asset' { + # Write-Host ($asset | Format-List -Property * | Out-String) + # } + # $asset | Should -Not -BeNullOrEmpty + # $asset.Name | Should -Be $zipAssetName + # $asset.Label | Should -Be $label + # $asset.Size | Should -BeGreaterThan 0 + # if (Test-Path $tempZipPath) { + # Remove-Item -Path $tempZipPath -Force + # } + # } + + # It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { + # $release = Get-GitHubRelease -Owner $Owner -Repository $repo + # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + # LogGroup 'Release assets by release ID' { + # Write-Host ($assets | Format-List -Property * | Out-String) + # } + # $assets | Should -Not -BeNullOrEmpty + # $assets | Should -BeOfType 'GitHubReleaseAsset' + # } + + # It 'Get-GitHubReleaseAsset - Gets a specific asset by ID' { + # $release = Get-GitHubRelease -Owner $Owner -Repository $repo + # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + # $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID + # LogGroup 'Release asset by asset ID' { + # Write-Host ($asset | Format-List -Property * | Out-String) + # } + # $asset | Should -Not -BeNullOrEmpty + # $asset | Should -BeOfType 'GitHubReleaseAsset' + # $asset.ID | Should -Be $assets[0].ID + # } + + # It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a release ID' { + # $release = Get-GitHubRelease -Owner $Owner -Repository $repo + # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + # $assetName = $assets[0].Name + # $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Name $assetName + # LogGroup 'Release asset by name from release ID' { + # Write-Host ($asset | Format-List -Property * | Out-String) + # } + # $asset | Should -Not -BeNullOrEmpty + # $asset | Should -BeOfType 'GitHubReleaseAsset' + # $asset.Name | Should -Be $assetName + # } + + # It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a tag' { + # $release = Get-GitHubRelease -Owner $Owner -Repository $repo + # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + # $assetName = $assets[0].Name + # $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName + # LogGroup 'Release asset by name from tag' { + # Write-Host ($asset | Format-List -Property * | Out-String) + # } + # $asset | Should -Not -BeNullOrEmpty + # $asset.Name | Should -Be $assetName + # } + + # It 'Update-GitHubReleaseAsset - Updates a release asset' { + # $release = Get-GitHubRelease -Owner $Owner -Repository $repo + # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + # $newLabel = 'Updated test asset' + # $asset = Update-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID -Label $newLabel + # LogGroup 'Updated asset' { + # Write-Host ($asset | Format-List -Property * | Out-String) + # } + # $asset | Should -Not -BeNullOrEmpty + # $asset.Label | Should -Be $newLabel + # } + + # It 'Remove-GitHubReleaseAsset - Removes a release asset' { + # $release = Get-GitHubRelease -Owner $Owner -Repository $repo + # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + # $assetID = $assets[0].ID + # Remove-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assetID -Confirm:$false + # $updatedAssets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + # $remainingAsset = $updatedAssets | Where-Object { $_.ID -eq $assetID } + # $remainingAsset | Should -BeNullOrEmpty + # } } } } From 8928a16bc1dadfb86087c4c36e0fa6dfafb4112f Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions@users.noreply.github.com> Date: Wed, 30 Apr 2025 15:38:05 +0000 Subject: [PATCH 174/224] Auto-generated changes --- Coverage.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Coverage.md b/Coverage.md index abc67dd52..0c13d6fca 100644 --- a/Coverage.md +++ b/Coverage.md @@ -5,7 +5,7 @@ - + @@ -13,11 +13,11 @@ - + - +
Available functions10261027
Covered functions
Missing functions806807
Coverage21.44%21.42%
@@ -51,6 +51,7 @@ | `/classrooms/{classroom_id}/assignments` | | :x: | | | | | `/codes_of_conduct` | | :x: | | | | | `/codes_of_conduct/{key}` | | :x: | | | | +| `/credentials/revoke` | | | | :x: | | | `/emojis` | | :white_check_mark: | | | | | `/enterprises/{enterprise}/code-security/configurations` | | :x: | | :x: | | | `/enterprises/{enterprise}/code-security/configurations/defaults` | | :x: | | | | From 7c03a3d34bcec26aa5bd57fc920906656b9aa3ca Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 17:48:33 +0200 Subject: [PATCH 175/224] Update test for Add-GitHubReleaseAsset: change asset file path to use Test.txt and create file with test content. --- tests/Releases.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 31e9de5f9..ac27c5f6b 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -282,8 +282,8 @@ Describe 'Releases' { } It 'Add-GitHubReleaseAsset - Creates a new release asset' { - $fileName = 'AuthCases.ps1' - $tempFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$fileName" + $tempFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/Test.txt" + $file = Set-Content -Path $tempFilePath -Value 'Test content' $release = Get-GitHubRelease -Owner $Owner -Repository $repo $asset = $release | Add-GitHubReleaseAsset -Path $tempFilePath LogGroup 'Added asset' { From 11cbeb0a99c386436bc71cd0cbb7bfd629fa0115 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 17:54:55 +0200 Subject: [PATCH 176/224] Update test for asset name validation: change expected asset name to use temporary file path. --- tests/Releases.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index ac27c5f6b..160ca26bd 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -290,7 +290,7 @@ Describe 'Releases' { Write-Host ($asset | Format-List -Property * | Out-String) } $asset | Should -Not -BeNullOrEmpty - $asset.Name | Should -Be $fileName + $asset.Name | Should -Be $tempFilePath Remove-Item -Path $tempFilePath -Force } From 214244092a1527b3421f5f350feb639fa571a834 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 18:02:44 +0200 Subject: [PATCH 177/224] Update Add-GitHubReleaseAsset test: use variable for file name and validate asset properties --- tests/Releases.Tests.ps1 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 160ca26bd..c05a8c8ce 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -282,7 +282,8 @@ Describe 'Releases' { } It 'Add-GitHubReleaseAsset - Creates a new release asset' { - $tempFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/Test.txt" + $fileName = 'Test.txt' + $tempFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$fileName" $file = Set-Content -Path $tempFilePath -Value 'Test content' $release = Get-GitHubRelease -Owner $Owner -Repository $repo $asset = $release | Add-GitHubReleaseAsset -Path $tempFilePath @@ -290,7 +291,11 @@ Describe 'Releases' { Write-Host ($asset | Format-List -Property * | Out-String) } $asset | Should -Not -BeNullOrEmpty - $asset.Name | Should -Be $tempFilePath + $asset | Should -BeOfType 'GitHubReleaseAsset' + $asset.Name | Should -Be $fileName + $asset.Label | Should -Be $fileName + $asset.Size | Should -BeGreaterThan 0 + Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$fileName" Remove-Item -Path $tempFilePath -Force } From 4988567453a8477fbde5ad31758f1a92a278e953 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 18:10:34 +0200 Subject: [PATCH 178/224] Update Add-GitHubReleaseAsset test: validate asset properties and reintroduce custom parameters test --- tests/Releases.Tests.ps1 | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index c05a8c8ce..7798685c3 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -296,26 +296,27 @@ Describe 'Releases' { $asset.Label | Should -Be $fileName $asset.Size | Should -BeGreaterThan 0 Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$fileName" + Get-Content -Path "$PSScriptRoot/../$fileName" | Should -Be 'Test content' Remove-Item -Path $tempFilePath -Force } - # It 'Add-GitHubReleaseAsset - Creates a release asset with custom parameters' { - # $mdFileName = 'IssueForm.md' - # $mdFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$mdFileName" - # $release = Get-GitHubRelease -Owner $Owner -Repository $repo - # $customName = 'CustomIssueTemplate.md' - # $contentType = 'text/markdown' - # $label = 'Issue Template Documentation' - # $asset = Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Path $mdFilePath -Name $customName -ContentType $contentType -Label $label - # LogGroup 'Added markdown asset' { - # Write-Host ($asset | Format-List -Property * | Out-String) - # } - # $asset | Should -Not -BeNullOrEmpty - # $asset.Name | Should -Be $customName - # $asset.ContentType | Should -Be $contentType - # $asset.Label | Should -Be $label - # $asset.Size | Should -BeGreaterThan 0 - # } + It 'Add-GitHubReleaseAsset - Creates a release asset with custom parameters' { + $mdFileName = 'IssueForm.md' + $mdFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$mdFileName" + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $customName = 'CustomIssueTemplate.md' + $contentType = 'text/markdown' + $label = 'Issue Template Documentation' + $asset = $release | Add-GitHubReleaseAsset -Path $mdFilePath -Name $customName -ContentType $contentType -Label $label + LogGroup 'Added markdown asset' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + $asset | Should -Not -BeNullOrEmpty + $asset.Name | Should -Be $customName + $asset.ContentType | Should -Be $contentType + $asset.Label | Should -Be $label + $asset.Size | Should -BeGreaterThan 0 + } # It 'Add-GitHubReleaseAsset - Adds a folder as a zipped asset to a release' { # $release = Get-GitHubRelease -Owner $Owner -Repository $repo From f5437fed2533dcf1f3f07881442f144eb8d70edd Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 18:23:24 +0200 Subject: [PATCH 179/224] Update Add-GitHubReleaseAsset tests: validate asset content type and add zip asset handling --- tests/Releases.Tests.ps1 | 48 ++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 7798685c3..5d7ae1ccc 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -295,6 +295,7 @@ Describe 'Releases' { $asset.Name | Should -Be $fileName $asset.Label | Should -Be $fileName $asset.Size | Should -BeGreaterThan 0 + $asset.ContentType | Should -Be 'text/plain' Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$fileName" Get-Content -Path "$PSScriptRoot/../$fileName" | Should -Be 'Test content' Remove-Item -Path $tempFilePath -Force @@ -305,35 +306,44 @@ Describe 'Releases' { $mdFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$mdFileName" $release = Get-GitHubRelease -Owner $Owner -Repository $repo $customName = 'CustomIssueTemplate.md' - $contentType = 'text/markdown' $label = 'Issue Template Documentation' - $asset = $release | Add-GitHubReleaseAsset -Path $mdFilePath -Name $customName -ContentType $contentType -Label $label + $asset = $release | Add-GitHubReleaseAsset -Path $mdFilePath -Name $customName -Label $label LogGroup 'Added markdown asset' { Write-Host ($asset | Format-List -Property * | Out-String) } $asset | Should -Not -BeNullOrEmpty + $asset | Should -BeOfType 'GitHubReleaseAsset' $asset.Name | Should -Be $customName - $asset.ContentType | Should -Be $contentType + $asset.ContentType | Should -Be 'text/markdown' $asset.Label | Should -Be $label $asset.Size | Should -BeGreaterThan 0 + Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$customName" + Get-Content -Path "$PSScriptRoot/../$customName" | Should -Be 'Test content' + Remove-Item -Path $mdFilePath -Force } - # It 'Add-GitHubReleaseAsset - Adds a folder as a zipped asset to a release' { - # $release = Get-GitHubRelease -Owner $Owner -Repository $repo - # $path = Join-Path -Path $PSScriptRoot -ChildPath 'Data' - # $label = 'Test Data Files' - # $asset = $release | Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -Label $label -Path $path - # LogGroup 'Added zip asset' { - # Write-Host ($asset | Format-List -Property * | Out-String) - # } - # $asset | Should -Not -BeNullOrEmpty - # $asset.Name | Should -Be $zipAssetName - # $asset.Label | Should -Be $label - # $asset.Size | Should -BeGreaterThan 0 - # if (Test-Path $tempZipPath) { - # Remove-Item -Path $tempZipPath -Force - # } - # } + It 'Add-GitHubReleaseAsset - Adds a folder as a zipped asset to a release' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $path = Join-Path -Path $PSScriptRoot -ChildPath 'Data' + $label = 'Test Data Files' + $folderName = Split-Path -Path $path -Leaf + $zipAssetName = "$folderName.zip" + $tempZipPath = Join-Path -Path $env:TEMP -ChildPath $zipAssetName + Remove-Item -Path $tempZipPath -Force + Compress-Archive -Path "$path\*" -DestinationPath $tempZipPath -Force + $asset = $release | Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -Label $label -Path $tempZipPath + LogGroup 'Added zip asset' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + $asset | Should -Not -BeNullOrEmpty + $asset.Name | Should -Be $zipAssetName + $asset.Label | Should -Be $label + $asset.ContentType | Should -Be 'application/zip' + $asset.Size | Should -BeGreaterThan 0 + Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$zipAssetName" + Get-Content -Path "$PSScriptRoot/../$zipAssetName" | Should -Be 'Test content' + Remove-Item -Path $tempZipPath -Force + } # It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { # $release = Get-GitHubRelease -Owner $Owner -Repository $repo From 9e59c242c15df00c02c309c7f64c7929c6240159 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 18:36:09 +0200 Subject: [PATCH 180/224] Update Releases.Tests: modify asset content validation and adjust temporary zip path --- tests/Releases.Tests.ps1 | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 5d7ae1ccc..f49ea8962 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -318,7 +318,7 @@ Describe 'Releases' { $asset.Label | Should -Be $label $asset.Size | Should -BeGreaterThan 0 Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$customName" - Get-Content -Path "$PSScriptRoot/../$customName" | Should -Be 'Test content' + Get-Content -Path "$PSScriptRoot/../$customName" | Select-Object -First 1 | Should -Be '' Remove-Item -Path $mdFilePath -Force } @@ -328,7 +328,7 @@ Describe 'Releases' { $label = 'Test Data Files' $folderName = Split-Path -Path $path -Leaf $zipAssetName = "$folderName.zip" - $tempZipPath = Join-Path -Path $env:TEMP -ChildPath $zipAssetName + $tempZipPath = Join-Path -Path $PSScriptRoot -ChildPath $zipAssetName Remove-Item -Path $tempZipPath -Force Compress-Archive -Path "$path\*" -DestinationPath $tempZipPath -Force $asset = $release | Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -Label $label -Path $tempZipPath @@ -341,19 +341,20 @@ Describe 'Releases' { $asset.ContentType | Should -Be 'application/zip' $asset.Size | Should -BeGreaterThan 0 Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$zipAssetName" - Get-Content -Path "$PSScriptRoot/../$zipAssetName" | Should -Be 'Test content' + Get-Content -Path "$PSScriptRoot/../$zipAssetName" | Select-Object -First 1 | Should -Be '' Remove-Item -Path $tempZipPath -Force } - # It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { - # $release = Get-GitHubRelease -Owner $Owner -Repository $repo - # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - # LogGroup 'Release assets by release ID' { - # Write-Host ($assets | Format-List -Property * | Out-String) - # } - # $assets | Should -Not -BeNullOrEmpty - # $assets | Should -BeOfType 'GitHubReleaseAsset' - # } + It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + LogGroup 'Release assets by release ID' { + Write-Host ($assets | Format-List -Property * | Out-String) + } + $assets | Should -Not -BeNullOrEmpty + $assets.Count | Should -Be 3 + $assets | Should -BeOfType 'GitHubReleaseAsset' + } # It 'Get-GitHubReleaseAsset - Gets a specific asset by ID' { # $release = Get-GitHubRelease -Owner $Owner -Repository $repo From 7c8f597e21fcb08a1f6645615e78dcb9374db3e9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 18:56:33 +0200 Subject: [PATCH 181/224] Update Releases.Tests: refactor asset handling to use temporary directory for file operations --- tests/Releases.Tests.ps1 | 48 +++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index f49ea8962..1127c71a1 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -283,7 +283,7 @@ Describe 'Releases' { It 'Add-GitHubReleaseAsset - Creates a new release asset' { $fileName = 'Test.txt' - $tempFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$fileName" + $tempFilePath = Join-Path -Path $env:TEMP -ChildPath $fileName $file = Set-Content -Path $tempFilePath -Value 'Test content' $release = Get-GitHubRelease -Owner $Owner -Repository $repo $asset = $release | Add-GitHubReleaseAsset -Path $tempFilePath @@ -296,17 +296,18 @@ Describe 'Releases' { $asset.Label | Should -Be $fileName $asset.Size | Should -BeGreaterThan 0 $asset.ContentType | Should -Be 'text/plain' - Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$fileName" - Get-Content -Path "$PSScriptRoot/../$fileName" | Should -Be 'Test content' + Invoke-WebRequest -Uri $asset.Url -OutFile "$env:TEMP/$fileName" + Get-Content -Path "$env:TEMP/$fileName" | Should -Be 'Test content' Remove-Item -Path $tempFilePath -Force } It 'Add-GitHubReleaseAsset - Creates a release asset with custom parameters' { - $mdFileName = 'IssueForm.md' - $mdFilePath = Join-Path -Path $PSScriptRoot -ChildPath "Data/$mdFileName" + $mdFileName = 'TestMarkdown.md' + $mdFilePath = Join-Path -Path $env:TEMP -ChildPath $mdFileName + Set-Content -Path $mdFilePath -Value "# Test Markdown File`nTest content" $release = Get-GitHubRelease -Owner $Owner -Repository $repo - $customName = 'CustomIssueTemplate.md' - $label = 'Issue Template Documentation' + $customName = 'CustomMarkdownFile.md' + $label = 'Test Markdown Documentation' $asset = $release | Add-GitHubReleaseAsset -Path $mdFilePath -Name $customName -Label $label LogGroup 'Added markdown asset' { Write-Host ($asset | Format-List -Property * | Out-String) @@ -317,21 +318,29 @@ Describe 'Releases' { $asset.ContentType | Should -Be 'text/markdown' $asset.Label | Should -Be $label $asset.Size | Should -BeGreaterThan 0 - Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$customName" - Get-Content -Path "$PSScriptRoot/../$customName" | Select-Object -First 1 | Should -Be '' + $downloadPath = Join-Path -Path $env:TEMP -ChildPath $customName + Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath + Get-Content -Path $downloadPath | Select-Object -First 1 | Should -Be '# Test Markdown File' Remove-Item -Path $mdFilePath -Force + Remove-Item -Path $downloadPath -Force } It 'Add-GitHubReleaseAsset - Adds a folder as a zipped asset to a release' { $release = Get-GitHubRelease -Owner $Owner -Repository $repo - $path = Join-Path -Path $PSScriptRoot -ChildPath 'Data' - $label = 'Test Data Files' - $folderName = Split-Path -Path $path -Leaf - $zipAssetName = "$folderName.zip" - $tempZipPath = Join-Path -Path $PSScriptRoot -ChildPath $zipAssetName + $tempFolderName = "TestFolder-$([Guid]::NewGuid().ToString())" + $tempFolderPath = Join-Path -Path $env:TEMP -ChildPath $tempFolderName + New-Item -Path $tempFolderPath -ItemType Directory -Force + 1..3 | ForEach-Object { + $testFileName = "TestFile$_.txt" + $testFilePath = Join-Path -Path $tempFolderPath -ChildPath $testFileName + Set-Content -Path $testFilePath -Value "Test content for file $_" + } + $label = 'Test Files Collection' + $zipAssetName = "$tempFolderName.zip" + $tempZipPath = Join-Path -Path $env:TEMP -ChildPath $zipAssetName Remove-Item -Path $tempZipPath -Force - Compress-Archive -Path "$path\*" -DestinationPath $tempZipPath -Force - $asset = $release | Add-GitHubReleaseAsset -Owner $Owner -Repository $repo -Label $label -Path $tempZipPath + Compress-Archive -Path "$tempFolderPath\*" -DestinationPath $tempZipPath -Force + $asset = $release | Add-GitHubReleaseAsset -Label $label -Path $tempZipPath LogGroup 'Added zip asset' { Write-Host ($asset | Format-List -Property * | Out-String) } @@ -340,9 +349,12 @@ Describe 'Releases' { $asset.Label | Should -Be $label $asset.ContentType | Should -Be 'application/zip' $asset.Size | Should -BeGreaterThan 0 - Invoke-WebRequest -Uri $asset.Url -OutFile "$PSScriptRoot/../$zipAssetName" - Get-Content -Path "$PSScriptRoot/../$zipAssetName" | Select-Object -First 1 | Should -Be '' + $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$zipAssetName" + Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath + Test-Path -Path $downloadPath | Should -BeTrue + Remove-Item -Path $tempFolderPath -Recurse -Force Remove-Item -Path $tempZipPath -Force + Remove-Item -Path $downloadPath -Force } It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { From b71a92b0ccf1eeb927b0676ec34dd9b00d0002d5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 19:13:14 +0200 Subject: [PATCH 182/224] Update Releases.Tests: enhance release asset tests with structured test files and zip asset handling --- tests/Releases.Tests.ps1 | 159 ++++++++++++++++++++++++++++----------- 1 file changed, 117 insertions(+), 42 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 1127c71a1..4f009f406 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -280,81 +280,156 @@ Describe 'Releases' { $release = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' $release | Should -BeNullOrEmpty } + } + Context 'Release Assets' -Skip:($OwnerType -eq 'repository') { + BeforeAll { + $testFolderGuid = [Guid]::NewGuid().ToString().Substring(0, 8) + $testFolderName = "GHAssetTest-$testFolderGuid" + $testFolderPath = Join-Path -Path $env:TEMP -ChildPath $testFolderName + New-Item -Path $testFolderPath -ItemType Directory -Force + $testFiles = @{ + TextFile = @{ + Name = 'TextFile.txt' + Path = Join-Path -Path $testFolderPath -ChildPath 'TextFile.txt' + Content = @' +This is a simple text file for testing GitHub release assets +'@ + ContentType = 'text/plain' + } + MarkdownFile = @{ + Name = 'Documentation.md' + Path = Join-Path -Path $testFolderPath -ChildPath 'Documentation.md' + Content = @' +# Test Documentation +## Introduction +This is a markdown file used for testing GitHub release assets +'@ + ContentType = 'text/markdown' + } + JsonFile = @{ + Name = 'Config.json' + Path = Join-Path -Path $testFolderPath -ChildPath 'Config.json' + Content = @' +{ + "name": "GitHub Release Asset Test", + "version": "1.0.0", + "description": "Test file for GitHub release assets" +} +'@ + ContentType = 'application/json' + } + XmlFile = @{ + Name = 'Data.xml' + Path = Join-Path -Path $testFolderPath -ChildPath 'Data.xml' + Content = @' + + + Test Item + 100 + + +'@ + ContentType = 'application/xml' + } + CsvFile = @{ + Name = 'Records.csv' + Path = Join-Path -Path $testFolderPath -ChildPath 'Records.csv' + Content = @' +ID,Name,Value +1,Item1,100 +2,Item2,200 +3,Item3,300 +'@ + ContentType = 'text/csv' + } + } + foreach ($file in $testFiles.Values) { + Set-Content -Path $file.Path -Value $file.Content + } - It 'Add-GitHubReleaseAsset - Creates a new release asset' { - $fileName = 'Test.txt' - $tempFilePath = Join-Path -Path $env:TEMP -ChildPath $fileName - $file = Set-Content -Path $tempFilePath -Value 'Test content' + # Create a zip file of all test files + $zipFileName = "$testFolderName.zip" + $zipFilePath = Join-Path -Path $env:TEMP -ChildPath $zipFileName + Compress-Archive -Path "$testFolderPath\*" -DestinationPath $zipFilePath -Force + + # Add the zip file to the test files collection + $testFiles['ZipFile'] = @{ + Name = $zipFileName + Path = $zipFilePath + ContentType = 'application/zip' + } + + # Get the latest release to use for tests $release = Get-GitHubRelease -Owner $Owner -Repository $repo - $asset = $release | Add-GitHubReleaseAsset -Path $tempFilePath + } + + AfterAll { + if (Test-Path $testFolderPath) { + Remove-Item -Path $testFolderPath -Recurse -Force + } + if (Test-Path $testFiles.ZipFile.Path) { + Remove-Item -Path $testFiles.ZipFile.Path -Force + } + + foreach ($file in $testFiles.Values) { + $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$($file.Name)" + if (Test-Path $downloadPath) { + Remove-Item -Path $downloadPath -Force + } + } + } + + It 'Add-GitHubReleaseAsset - Creates a new release asset' { + $asset = $release | Add-GitHubReleaseAsset -Path $testFiles.TextFile.Path LogGroup 'Added asset' { Write-Host ($asset | Format-List -Property * | Out-String) } $asset | Should -Not -BeNullOrEmpty $asset | Should -BeOfType 'GitHubReleaseAsset' - $asset.Name | Should -Be $fileName - $asset.Label | Should -Be $fileName + $asset.Name | Should -Be $testFiles.TextFile.Name + $asset.Label | Should -Be $testFiles.TextFile.Name $asset.Size | Should -BeGreaterThan 0 - $asset.ContentType | Should -Be 'text/plain' - Invoke-WebRequest -Uri $asset.Url -OutFile "$env:TEMP/$fileName" - Get-Content -Path "$env:TEMP/$fileName" | Should -Be 'Test content' - Remove-Item -Path $tempFilePath -Force + $asset.ContentType | Should -Be $testFiles.TextFile.ContentType + + $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$($testFiles.TextFile.Name)" + Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath + Get-Content -Path $downloadPath | Should -Be $testFiles.TextFile.Content } It 'Add-GitHubReleaseAsset - Creates a release asset with custom parameters' { - $mdFileName = 'TestMarkdown.md' - $mdFilePath = Join-Path -Path $env:TEMP -ChildPath $mdFileName - Set-Content -Path $mdFilePath -Value "# Test Markdown File`nTest content" - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - $customName = 'CustomMarkdownFile.md' + $customName = "Custom-$($testFiles.MarkdownFile.Name)" $label = 'Test Markdown Documentation' - $asset = $release | Add-GitHubReleaseAsset -Path $mdFilePath -Name $customName -Label $label + $asset = $release | Add-GitHubReleaseAsset -Path $testFiles.MarkdownFile.Path -Name $customName -Label $label LogGroup 'Added markdown asset' { Write-Host ($asset | Format-List -Property * | Out-String) } $asset | Should -Not -BeNullOrEmpty $asset | Should -BeOfType 'GitHubReleaseAsset' $asset.Name | Should -Be $customName - $asset.ContentType | Should -Be 'text/markdown' + $asset.ContentType | Should -Be $testFiles.MarkdownFile.ContentType $asset.Label | Should -Be $label $asset.Size | Should -BeGreaterThan 0 - $downloadPath = Join-Path -Path $env:TEMP -ChildPath $customName + + $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$customName" Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath - Get-Content -Path $downloadPath | Select-Object -First 1 | Should -Be '# Test Markdown File' - Remove-Item -Path $mdFilePath -Force - Remove-Item -Path $downloadPath -Force + (Get-Content -Path $downloadPath -Raw) | Should -Match '# Test Documentation' } It 'Add-GitHubReleaseAsset - Adds a folder as a zipped asset to a release' { - $release = Get-GitHubRelease -Owner $Owner -Repository $repo - $tempFolderName = "TestFolder-$([Guid]::NewGuid().ToString())" - $tempFolderPath = Join-Path -Path $env:TEMP -ChildPath $tempFolderName - New-Item -Path $tempFolderPath -ItemType Directory -Force - 1..3 | ForEach-Object { - $testFileName = "TestFile$_.txt" - $testFilePath = Join-Path -Path $tempFolderPath -ChildPath $testFileName - Set-Content -Path $testFilePath -Value "Test content for file $_" - } $label = 'Test Files Collection' - $zipAssetName = "$tempFolderName.zip" - $tempZipPath = Join-Path -Path $env:TEMP -ChildPath $zipAssetName - Remove-Item -Path $tempZipPath -Force - Compress-Archive -Path "$tempFolderPath\*" -DestinationPath $tempZipPath -Force - $asset = $release | Add-GitHubReleaseAsset -Label $label -Path $tempZipPath + $asset = $release | Add-GitHubReleaseAsset -Label $label -Path $testFiles.ZipFile.Path LogGroup 'Added zip asset' { Write-Host ($asset | Format-List -Property * | Out-String) } $asset | Should -Not -BeNullOrEmpty - $asset.Name | Should -Be $zipAssetName + $asset.Name | Should -Be $testFiles.ZipFile.Name $asset.Label | Should -Be $label - $asset.ContentType | Should -Be 'application/zip' + $asset.ContentType | Should -Be $testFiles.ZipFile.ContentType $asset.Size | Should -BeGreaterThan 0 - $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$zipAssetName" + + $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$($testFiles.ZipFile.Name)" Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath Test-Path -Path $downloadPath | Should -BeTrue - Remove-Item -Path $tempFolderPath -Recurse -Force - Remove-Item -Path $tempZipPath -Force - Remove-Item -Path $downloadPath -Force } It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { From 462549a48c07be86554da4cc12d44635938cd085 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 19:35:04 +0200 Subject: [PATCH 183/224] Update Releases.Tests: change test folder path to use script root instead of TEMP directory --- tests/Releases.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 4f009f406..3feb42356 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -285,7 +285,7 @@ Describe 'Releases' { BeforeAll { $testFolderGuid = [Guid]::NewGuid().ToString().Substring(0, 8) $testFolderName = "GHAssetTest-$testFolderGuid" - $testFolderPath = Join-Path -Path $env:TEMP -ChildPath $testFolderName + $testFolderPath = Join-Path -Path $PSScriptRoot -ChildPath $testFolderName New-Item -Path $testFolderPath -ItemType Directory -Force $testFiles = @{ TextFile = @{ From 929cf1a1546bccc55e778a3eda6dba946e3908c6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 20:06:39 +0200 Subject: [PATCH 184/224] Update Releases.Tests: remove redundant cleanup logic from AfterAll block --- tests/Releases.Tests.ps1 | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 3feb42356..9c8f26387 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -363,22 +363,6 @@ ID,Name,Value $release = Get-GitHubRelease -Owner $Owner -Repository $repo } - AfterAll { - if (Test-Path $testFolderPath) { - Remove-Item -Path $testFolderPath -Recurse -Force - } - if (Test-Path $testFiles.ZipFile.Path) { - Remove-Item -Path $testFiles.ZipFile.Path -Force - } - - foreach ($file in $testFiles.Values) { - $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$($file.Name)" - if (Test-Path $downloadPath) { - Remove-Item -Path $downloadPath -Force - } - } - } - It 'Add-GitHubReleaseAsset - Creates a new release asset' { $asset = $release | Add-GitHubReleaseAsset -Path $testFiles.TextFile.Path LogGroup 'Added asset' { From 7d39d684ab8542680f15f40192547eedce53b07c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 20:10:48 +0200 Subject: [PATCH 185/224] Update Releases.Tests: change zip file path to use script root instead of TEMP directory --- tests/Releases.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 9c8f26387..3a2a58bde 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -349,7 +349,7 @@ ID,Name,Value # Create a zip file of all test files $zipFileName = "$testFolderName.zip" - $zipFilePath = Join-Path -Path $env:TEMP -ChildPath $zipFileName + $zipFilePath = Join-Path -Path $PSScriptRoot -ChildPath $zipFileName Compress-Archive -Path "$testFolderPath\*" -DestinationPath $zipFilePath -Force # Add the zip file to the test files collection From 623214f882a41f1650dc0b8dd62b35e86b879cc1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 20:16:19 +0200 Subject: [PATCH 186/224] Update Releases.Tests: change download path to use script root instead of TEMP directory --- tests/Releases.Tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 3a2a58bde..cb06fd447 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -375,7 +375,7 @@ ID,Name,Value $asset.Size | Should -BeGreaterThan 0 $asset.ContentType | Should -Be $testFiles.TextFile.ContentType - $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$($testFiles.TextFile.Name)" + $downloadPath = Join-Path -Path $PSScriptRoot -ChildPath "Downloaded-$($testFiles.TextFile.Name)" Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath Get-Content -Path $downloadPath | Should -Be $testFiles.TextFile.Content } @@ -394,7 +394,7 @@ ID,Name,Value $asset.Label | Should -Be $label $asset.Size | Should -BeGreaterThan 0 - $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$customName" + $downloadPath = Join-Path -Path $PSScriptRoot -ChildPath "Downloaded-$customName" Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath (Get-Content -Path $downloadPath -Raw) | Should -Match '# Test Documentation' } @@ -411,7 +411,7 @@ ID,Name,Value $asset.ContentType | Should -Be $testFiles.ZipFile.ContentType $asset.Size | Should -BeGreaterThan 0 - $downloadPath = Join-Path -Path $env:TEMP -ChildPath "Downloaded-$($testFiles.ZipFile.Name)" + $downloadPath = Join-Path -Path $PSScriptRoot -ChildPath "Downloaded-$($testFiles.ZipFile.Name)" Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath Test-Path -Path $downloadPath | Should -BeTrue } From ff2011b2a06f87248730b4d9ce5c5b775f27b57c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 20:31:59 +0200 Subject: [PATCH 187/224] Update Get-GitHubReleaseAsset: change parameter usage from ReleaseID to ID for asset retrieval --- .../public/Releases/Assets/Get-GitHubReleaseAsset.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 index c6950d191..b44d70c91 100644 --- a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 @@ -84,13 +84,13 @@ process { switch ($PSCmdlet.ParameterSetName) { 'List assets from a release' { - Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repository $Repository -ReleaseID $ReleaseID -Context $Context + Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repository $Repository -ID $ReleaseID -Context $Context } 'Get a specific asset by ID' { Get-GitHubReleaseAssetByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context } 'Get a specific asset by name from a release ID' { - $assets = Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repository $Repository -ReleaseID $ReleaseID -Context $Context + $assets = Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repository $Repository -ID $ReleaseID -Context $Context $asset = $assets | Where-Object { $_.Name -eq $Name } if ($asset) { $asset From 80434d49e3f313194cb0007f749135ae1d7cbcfe Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 20:51:04 +0200 Subject: [PATCH 188/224] Update Releases.Tests: add retry logic to Invoke-WebRequest for asset downloads --- tests/Releases.Tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index cb06fd447..1dec4fa04 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -376,7 +376,7 @@ ID,Name,Value $asset.ContentType | Should -Be $testFiles.TextFile.ContentType $downloadPath = Join-Path -Path $PSScriptRoot -ChildPath "Downloaded-$($testFiles.TextFile.Name)" - Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath + Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath -RetryIntervalSec 5 -MaximumRetryCount 5 Get-Content -Path $downloadPath | Should -Be $testFiles.TextFile.Content } @@ -395,7 +395,7 @@ ID,Name,Value $asset.Size | Should -BeGreaterThan 0 $downloadPath = Join-Path -Path $PSScriptRoot -ChildPath "Downloaded-$customName" - Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath + Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath -RetryIntervalSec 5 -MaximumRetryCount 5 (Get-Content -Path $downloadPath -Raw) | Should -Match '# Test Documentation' } @@ -412,7 +412,7 @@ ID,Name,Value $asset.Size | Should -BeGreaterThan 0 $downloadPath = Join-Path -Path $PSScriptRoot -ChildPath "Downloaded-$($testFiles.ZipFile.Name)" - Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath + Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath -RetryIntervalSec 5 -MaximumRetryCount 5 Test-Path -Path $downloadPath | Should -BeTrue } From c3190e90462110924e8ee0c9a0b41f1658977fb4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 22:53:26 +0200 Subject: [PATCH 189/224] Update asset retrieval functions: enhance output type handling and improve pagination for tag-based asset retrieval --- .../Assets/Get-GitHubReleaseAssetByID.ps1 | 7 +- .../Get-GitHubReleaseAssetByReleaseID.ps1 | 4 +- .../Assets/Get-GitHubReleaseAssetByTag.ps1 | 103 +++++++++++------- 3 files changed, 71 insertions(+), 43 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 index c5bbea92b..464d7df2f 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 @@ -14,10 +14,13 @@ Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'. + .OUTPUTS + GitHubReleaseAsset + .NOTES https://docs.github.com/rest/releases/assets#get-a-release-asset - #> + [OutputType([GitHubReleaseAsset])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -52,7 +55,7 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubReleaseAsset]($_.Response) } } diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 index 0943c3f89..69e22f23a 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 @@ -62,7 +62,9 @@ } Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + foreach ($asset in $_.Response) { + [GitHubReleaseAsset]($asset) + } } } end { diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index 3025c3967..2a7649382 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -1,23 +1,21 @@ filter Get-GitHubReleaseAssetByTag { <# .SYNOPSIS - Get a release asset by name + Get release assets by tag name .DESCRIPTION - To download the asset's binary content, set the `Accept` header of the request to - [`application/octet-stream`](https://docs.github.com/rest/overview/media-types). - The API will either redirect the client to the location, or stream it directly if - possible. API clients should handle both a `200` or `302` response. + Gets all assets from a release identified by its tag name. + Uses pagination to retrieve all assets even if there are more than the maximum per page. .EXAMPLE - Get-GitHubReleaseAssetByTag -Owner 'octocat' -Repository 'hello-world' -ID '1234567' + Get-GitHubReleaseAssetByTag -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' - Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'. - - .NOTES - https://docs.github.com/rest/releases/assets#get-a-release-asset + Gets all release assets for the release with the tag 'v1.0.0' for the repository 'octocat/hello-world'. + .OUTPUTS + GitHubReleaseAsset #> + [OutputType([GitHubReleaseAsset])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. @@ -28,9 +26,14 @@ [Parameter(Mandatory)] [string] $Repository, - # The unique identifier of the asset. + # The name of the tag to get a release from. [Parameter(Mandatory)] - [string] $ID, + [string] $Tag, + + # The number of results per page (max 100). + [Parameter()] + [ValidateRange(0, 100)] + [int] $PerPage, # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. @@ -45,43 +48,63 @@ } process { - $inputObject = @{ - Query = @' -query($owner: String!, $repository: String!) { + $hasNextPage = $true + $after = $null + $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context + + do { + $inputObject = @{ + Query = @' +query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $after: String) { repository(owner: $owner, name: $repository) { - latestRelease { - id - databaseId - tagName - name - description - isLatest - isDraft - isPrerelease - url - createdAt - publishedAt - updatedAt - author { - login + release(tagName: $tag) { + releaseAssets(first: $perPage, after: $after) { + nodes { + id + databaseId + name + label + state + contentType + size + downloadCount + downloadUrl + url + createdAt + updatedAt + uploadedBy { + login + } + } + pageInfo { + endCursor + hasNextPage + } } } } } '@ - Variables = @{ - owner = $Owner - repository = $Repository + Variables = @{ + owner = $Owner + repository = $Repository + tag = $Tag + perPage = $perPageSetting + after = $after + } + Context = $Context } - Context = $Context - } - Invoke-GitHubGraphQLQuery @inputObject | ForEach-Object { - $release = $_.repository.latestRelease - if ($release) { - [GitHubRelease]::new($release, $Owner, $Repository, $null) + Invoke-GitHubGraphQLQuery @inputObject | ForEach-Object { + $release = $_.repository.release + $assets = $release.releaseAssets + foreach ($asset in $assets.nodes) { + [GitHubReleaseAsset]::new($asset) + } + $hasNextPage = $assets.pageInfo.hasNextPage + $after = $assets.pageInfo.endCursor } - } + } while ($hasNextPage) } end { From 5bdd741d498b55ff26d7d9d21e14f315bb2eb4f4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 30 Apr 2025 23:55:18 +0200 Subject: [PATCH 190/224] Update Get-GitHubReleaseAsset: enhance parameter handling and add support for retrieving assets from the latest release --- .../Get-GitHubReleaseAssetFromLatest.ps1 | 112 ++++++++++++++++++ .../Assets/Get-GitHubReleaseAsset.ps1 | 26 +++- tests/Releases.Tests.ps1 | 9 ++ 3 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 new file mode 100644 index 000000000..fc2205836 --- /dev/null +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -0,0 +1,112 @@ +filter Get-GitHubReleaseAssetFromLatest { + <# + .SYNOPSIS + Get the assets of the latest release + + .DESCRIPTION + Gets all assets for the latest published full release for the repository. + The latest release is the most recent non-prerelease, non-draft release, sorted by the `created_at` attribute. + The `created_at` attribute is the date of the commit used for the release, and not the date when the release was drafted or published. + + .EXAMPLE + Get-GitHubReleaseAssetFromLatest -Owner 'octocat' -Repository 'hello-world' + + Gets the assets for the latest release of the repository 'hello-world' owned by 'octocat'. + + .INPUTS + GitHubRepository + + .OUTPUTS + GitHubReleaseAsset + #> + [OutputType([GitHubReleaseAsset])] + [CmdletBinding()] + param( + # The account owner of the repository. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory)] + [string] $Repository, + + # The number of results per page (max 100). + [Parameter()] + [ValidateRange(0, 100)] + [int] $PerPage, + + # The context to run the command in. Used to get the details for the API call. + # Can be either a string or a GitHubContext object. + [Parameter(Mandatory)] + [object] $Context + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + } + + process { + $hasNextPage = $true + $after = $null + $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context + + do { + $inputObject = @{ + Query = @' +query($owner: String!, $repository: String!, $perPage: Int, $after: String) { + repository(owner: $owner, name: $repository) { + latestRelease { + releaseAssets(first: $perPage, after: $after) { + nodes { + id + databaseId + name + label + state + contentType + size + downloadCount + downloadUrl + url + createdAt + updatedAt + uploadedBy { + login + } + } + pageInfo { + endCursor + hasNextPage + } + } + } + } +} +'@ + Variables = @{ + owner = $Owner + repository = $Repository + perPage = $perPageSetting + after = $after + } + Context = $Context + } + + Invoke-GitHubGraphQLQuery @inputObject | ForEach-Object { + $release = $_.repository.latestRelease + $assets = $release.releaseAssets + foreach ($asset in $assets.nodes) { + [GitHubReleaseAsset]::new($asset) + } + $hasNextPage = $assets.pageInfo.hasNextPage + $after = $assets.pageInfo.endCursor + } + } while ($hasNextPage) + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 index b44d70c91..4d1693a09 100644 --- a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 @@ -39,7 +39,7 @@ https://psmodule.io/GitHub/Functions/Releases/Assets/Get-GitHubReleaseAsset #> [OutputType([GitHubReleaseAsset])] - [CmdletBinding(DefaultParameterSetName = 'List assets from a release')] + [CmdletBinding(DefaultParameterSetName = 'List assets from the latest release')] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] @@ -68,6 +68,11 @@ [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by name from a tag')] [string] $Name, + # The number of results per page (max 100). + [Parameter()] + [ValidateRange(0, 100)] + [int] $PerPage, + # The context to run the command in. Used to get the details for the API call. # Can be either a string or a GitHubContext object. [Parameter()] @@ -82,15 +87,26 @@ } process { + $params = @{ + Owner = $Owner + Repository = $Repository + PerPage = $PerPage + Context = $Context + } + $params | Remove-HashtableEntry -NullOrEmptyValues + switch ($PSCmdlet.ParameterSetName) { + 'List assets from the latest release' { + Get-GitHubReleaseAssetFromLatest @params + } 'List assets from a release' { - Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repository $Repository -ID $ReleaseID -Context $Context + Get-GitHubReleaseAssetByReleaseID @params -ID $ReleaseID } 'Get a specific asset by ID' { - Get-GitHubReleaseAssetByID -Owner $Owner -Repository $Repository -ID $ID -Context $Context + Get-GitHubReleaseAssetByID @params -ID $ID } 'Get a specific asset by name from a release ID' { - $assets = Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repository $Repository -ID $ReleaseID -Context $Context + $assets = Get-GitHubReleaseAssetByReleaseID @params -ID $ReleaseID $asset = $assets | Where-Object { $_.Name -eq $Name } if ($asset) { $asset @@ -99,7 +115,7 @@ } } 'Get a specific asset by name from a tag' { - Get-GitHubReleaseAssetByTag -Owner $Owner -Repository $Repository -Tag $Tag -Name $Name -Context $Context + Get-GitHubReleaseAssetByTag @params -Tag $Tag -Name $Name } } } diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 1dec4fa04..6643675db 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -427,6 +427,15 @@ ID,Name,Value $assets | Should -BeOfType 'GitHubReleaseAsset' } + It 'Get-GitHubReleaseAsset - Gets all assets from the latest release' { + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo + LogGroup 'Release assets from latest release' { + Write-Host ($assets | Format-List -Property * | Out-String) + } + $assets | Should -Not -BeNullOrEmpty + $assets | Should -BeOfType 'GitHubReleaseAsset' + } + # It 'Get-GitHubReleaseAsset - Gets a specific asset by ID' { # $release = Get-GitHubRelease -Owner $Owner -Repository $repo # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID From fe547b8f230c347a735e3ce8185313bc927b34b1 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 09:30:09 +0200 Subject: [PATCH 191/224] Refactor GitHubReleaseAsset queries: remove unused properties (databaseId, label, state) from asset retrieval --- src/classes/public/Releases/GitHubReleaseAsset.ps1 | 3 --- .../private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 | 3 --- .../Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 3 --- 3 files changed, 9 deletions(-) diff --git a/src/classes/public/Releases/GitHubReleaseAsset.ps1 b/src/classes/public/Releases/GitHubReleaseAsset.ps1 index 1382ae2d4..c0ae6d74b 100644 --- a/src/classes/public/Releases/GitHubReleaseAsset.ps1 +++ b/src/classes/public/Releases/GitHubReleaseAsset.ps1 @@ -56,12 +56,9 @@ $this.UpdatedAt = [datetime]::Parse($Object.updated_at) $this.UploadedBy = [GitHubUser]::new($Object.uploader) } else { - $this.ID = $Object.databaseId $this.NodeID = $Object.id $this.Url = $Object.downloadUrl $this.Name = $Object.name - $this.Label = $Object.label - $this.State = $Object.state $this.ContentType = $Object.contentType $this.Size = $Object.size $this.Downloads = $Object.downloadCount diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index 2a7649382..eaa29297e 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -61,10 +61,7 @@ query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $afte releaseAssets(first: $perPage, after: $after) { nodes { id - databaseId name - label - state contentType size downloadCount diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index fc2205836..c1a7fbd40 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -61,10 +61,7 @@ query($owner: String!, $repository: String!, $perPage: Int, $after: String) { releaseAssets(first: $perPage, after: $after) { nodes { id - databaseId name - label - state contentType size downloadCount From 23f57f3765c66c63c5a5d6a61f37f7b18fb73456 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 09:47:37 +0200 Subject: [PATCH 192/224] Update Releases.Tests: re-enable and enhance tests for GitHubReleaseAsset retrieval and management --- tests/Releases.Tests.ps1 | 122 +++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 64 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 6643675db..2ecfbc19e 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -346,20 +346,14 @@ ID,Name,Value foreach ($file in $testFiles.Values) { Set-Content -Path $file.Path -Value $file.Content } - - # Create a zip file of all test files $zipFileName = "$testFolderName.zip" $zipFilePath = Join-Path -Path $PSScriptRoot -ChildPath $zipFileName Compress-Archive -Path "$testFolderPath\*" -DestinationPath $zipFilePath -Force - - # Add the zip file to the test files collection $testFiles['ZipFile'] = @{ Name = $zipFileName Path = $zipFilePath ContentType = 'application/zip' } - - # Get the latest release to use for tests $release = Get-GitHubRelease -Owner $Owner -Repository $repo } @@ -436,64 +430,64 @@ ID,Name,Value $assets | Should -BeOfType 'GitHubReleaseAsset' } - # It 'Get-GitHubReleaseAsset - Gets a specific asset by ID' { - # $release = Get-GitHubRelease -Owner $Owner -Repository $repo - # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - # $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID - # LogGroup 'Release asset by asset ID' { - # Write-Host ($asset | Format-List -Property * | Out-String) - # } - # $asset | Should -Not -BeNullOrEmpty - # $asset | Should -BeOfType 'GitHubReleaseAsset' - # $asset.ID | Should -Be $assets[0].ID - # } - - # It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a release ID' { - # $release = Get-GitHubRelease -Owner $Owner -Repository $repo - # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - # $assetName = $assets[0].Name - # $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Name $assetName - # LogGroup 'Release asset by name from release ID' { - # Write-Host ($asset | Format-List -Property * | Out-String) - # } - # $asset | Should -Not -BeNullOrEmpty - # $asset | Should -BeOfType 'GitHubReleaseAsset' - # $asset.Name | Should -Be $assetName - # } - - # It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a tag' { - # $release = Get-GitHubRelease -Owner $Owner -Repository $repo - # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - # $assetName = $assets[0].Name - # $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName - # LogGroup 'Release asset by name from tag' { - # Write-Host ($asset | Format-List -Property * | Out-String) - # } - # $asset | Should -Not -BeNullOrEmpty - # $asset.Name | Should -Be $assetName - # } - - # It 'Update-GitHubReleaseAsset - Updates a release asset' { - # $release = Get-GitHubRelease -Owner $Owner -Repository $repo - # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - # $newLabel = 'Updated test asset' - # $asset = Update-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID -Label $newLabel - # LogGroup 'Updated asset' { - # Write-Host ($asset | Format-List -Property * | Out-String) - # } - # $asset | Should -Not -BeNullOrEmpty - # $asset.Label | Should -Be $newLabel - # } - - # It 'Remove-GitHubReleaseAsset - Removes a release asset' { - # $release = Get-GitHubRelease -Owner $Owner -Repository $repo - # $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - # $assetID = $assets[0].ID - # Remove-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assetID -Confirm:$false - # $updatedAssets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID - # $remainingAsset = $updatedAssets | Where-Object { $_.ID -eq $assetID } - # $remainingAsset | Should -BeNullOrEmpty - # } + It 'Get-GitHubReleaseAsset - Gets a specific asset by ID' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID + LogGroup 'Release asset by asset ID' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + $asset | Should -Not -BeNullOrEmpty + $asset | Should -BeOfType 'GitHubReleaseAsset' + $asset.ID | Should -Be $assets[0].ID + } + + It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a release ID' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + $assetName = $assets[0].Name + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID -Name $assetName + LogGroup 'Release asset by name from release ID' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + $asset | Should -Not -BeNullOrEmpty + $asset | Should -BeOfType 'GitHubReleaseAsset' + $asset.Name | Should -Be $assetName + } + + It 'Get-GitHubReleaseAsset - Gets a specific asset by name from a tag' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + $assetName = $assets[0].Name + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName + LogGroup 'Release asset by name from tag' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + $asset | Should -Not -BeNullOrEmpty + $asset.Name | Should -Be $assetName + } + + It 'Update-GitHubReleaseAsset - Updates a release asset' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + $newLabel = 'Updated test asset' + $asset = Update-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID -Label $newLabel + LogGroup 'Updated asset' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + $asset | Should -Not -BeNullOrEmpty + $asset.Label | Should -Be $newLabel + } + + It 'Remove-GitHubReleaseAsset - Removes a release asset' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + $assetID = $assets[0].ID + Remove-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assetID -Confirm:$false + $updatedAssets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + $remainingAsset = $updatedAssets | Where-Object { $_.ID -eq $assetID } + $remainingAsset | Should -BeNullOrEmpty + } } } } From d6833541090ab4d57f3992097c3353d372b75867 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 09:59:40 +0200 Subject: [PATCH 193/224] Update Get-GitHubReleaseAsset: refine parameter sets and enhance asset retrieval logic --- .../Assets/Get-GitHubReleaseAsset.ps1 | 39 ++++++------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 index 4d1693a09..5e89c5a0e 100644 --- a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 @@ -55,21 +55,18 @@ [string] $ID, # The unique identifier of the release. - [Parameter(Mandatory, ParameterSetName = 'List assets from a release', ValueFromPipelineByPropertyName)] - [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by name from a release ID', ValueFromPipelineByPropertyName)] + [Parameter(Mandatory, ParameterSetName = 'List assets from a release by ID', ValueFromPipelineByPropertyName)] + [Alias('Release')] [string] $ReleaseID, # The tag name of the release. - [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by name from a tag')] + [Parameter(Mandatory, ParameterSetName = 'List assets from a release by tag')] [string] $Tag, - # The name of the asset to find. - [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by name from a release ID')] - [Parameter(Mandatory, ParameterSetName = 'Get a specific asset by name from a tag')] - [string] $Name, - # The number of results per page (max 100). - [Parameter()] + [Parameter(ParameterSetName = 'List assets from the latest release')] + [Parameter(ParameterSetName = 'List assets from a release by ID')] + [Parameter(ParameterSetName = 'List assets from a release by tag')] [ValidateRange(0, 100)] [int] $PerPage, @@ -90,33 +87,23 @@ $params = @{ Owner = $Owner Repository = $Repository - PerPage = $PerPage Context = $Context } $params | Remove-HashtableEntry -NullOrEmptyValues switch ($PSCmdlet.ParameterSetName) { 'List assets from the latest release' { - Get-GitHubReleaseAssetFromLatest @params + Get-GitHubReleaseAssetFromLatest @params -PerPage $PerPage + } + 'List assets from a release by ID' { + Get-GitHubReleaseAssetByReleaseID @params -ID $ReleaseID -PerPage $PerPage } - 'List assets from a release' { - Get-GitHubReleaseAssetByReleaseID @params -ID $ReleaseID + 'List assets from a release by tag' { + Get-GitHubReleaseAssetByTag @params -Tag $Tag -PerPage $PerPage } 'Get a specific asset by ID' { Get-GitHubReleaseAssetByID @params -ID $ID } - 'Get a specific asset by name from a release ID' { - $assets = Get-GitHubReleaseAssetByReleaseID @params -ID $ReleaseID - $asset = $assets | Where-Object { $_.Name -eq $Name } - if ($asset) { - $asset - } else { - Write-Warning "Asset with name '$Name' not found in release with ID '$ReleaseID'" - } - } - 'Get a specific asset by name from a tag' { - Get-GitHubReleaseAssetByTag @params -Tag $Tag -Name $Name - } } } @@ -124,5 +111,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR From fdbd7a97079568e4eceff450541048ed22ff44d7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 10:14:45 +0200 Subject: [PATCH 194/224] Update asset retrieval functions: add support for filtering by asset name in Get-GitHubReleaseAssetByTag, Get-GitHubReleaseAssetFromLatest, and Get-GitHubReleaseAsset --- .../Assets/Get-GitHubReleaseAssetByTag.ps1 | 14 ++++++++++++-- .../Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 14 ++++++++++++-- .../Releases/Assets/Get-GitHubReleaseAsset.ps1 | 5 +++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index eaa29297e..17374eea2 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -12,6 +12,11 @@ Gets all release assets for the release with the tag 'v1.0.0' for the repository 'octocat/hello-world'. + .EXAMPLE + Get-GitHubReleaseAssetByTag -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Name 'app.zip' + + Gets a specific release asset named 'app.zip' from the release with the tag 'v1.0.0' for the repository 'octocat/hello-world'. + .OUTPUTS GitHubReleaseAsset #> @@ -30,6 +35,10 @@ [Parameter(Mandatory)] [string] $Tag, + # The name of the asset to get. If specified, only assets with this name will be returned. + [Parameter()] + [string] $Name, + # The number of results per page (max 100). [Parameter()] [ValidateRange(0, 100)] @@ -55,10 +64,10 @@ do { $inputObject = @{ Query = @' -query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $after: String) { +query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $after: String, $name: String) { repository(owner: $owner, name: $repository) { release(tagName: $tag) { - releaseAssets(first: $perPage, after: $after) { + releaseAssets(first: $perPage, after: $after, name: $name) { nodes { id name @@ -85,6 +94,7 @@ query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $afte Variables = @{ owner = $Owner repository = $Repository + name = $Name tag = $Tag perPage = $perPageSetting after = $after diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index c1a7fbd40..5aad967d6 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -13,6 +13,11 @@ Gets the assets for the latest release of the repository 'hello-world' owned by 'octocat'. + .EXAMPLE + Get-GitHubReleaseAssetFromLatest -Owner 'octocat' -Repository 'hello-world' -Name 'asset-name' + + Gets the assets for the latest release of the repository 'hello-world' owned by 'octocat'. + .INPUTS GitHubRepository @@ -30,6 +35,10 @@ [Parameter(Mandatory)] [string] $Repository, + # The name of the asset to get. If specified, only assets with this name will be returned. + [Parameter()] + [string] $Name, + # The number of results per page (max 100). [Parameter()] [ValidateRange(0, 100)] @@ -55,10 +64,10 @@ do { $inputObject = @{ Query = @' -query($owner: String!, $repository: String!, $perPage: Int, $after: String) { +query($owner: String!, $repository: String!, $perPage: Int, $after: String, $name: String) { repository(owner: $owner, name: $repository) { latestRelease { - releaseAssets(first: $perPage, after: $after) { + releaseAssets(first: $perPage, after: $after, name: $name) { nodes { id name @@ -85,6 +94,7 @@ query($owner: String!, $repository: String!, $perPage: Int, $after: String) { Variables = @{ owner = $Owner repository = $Repository + name = $Name perPage = $perPageSetting after = $after } diff --git a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 index 5e89c5a0e..4de85f700 100644 --- a/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Get-GitHubReleaseAsset.ps1 @@ -63,6 +63,10 @@ [Parameter(Mandatory, ParameterSetName = 'List assets from a release by tag')] [string] $Tag, + # The name of the asset to get. If specified, only assets with this name will be returned. + [Parameter()] + [string] $Name, + # The number of results per page (max 100). [Parameter(ParameterSetName = 'List assets from the latest release')] [Parameter(ParameterSetName = 'List assets from a release by ID')] @@ -88,6 +92,7 @@ Owner = $Owner Repository = $Repository Context = $Context + Name = $Name } $params | Remove-HashtableEntry -NullOrEmptyValues From 6435f9fe92beb5f7c51132cb13d6527663845466 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 10:27:49 +0200 Subject: [PATCH 195/224] Update Get-GitHubReleaseAssetByID and Get-GitHubReleaseAssetByReleaseID: enhance documentation and add asset name filtering support --- .../Assets/Get-GitHubReleaseAssetByID.ps1 | 2 +- .../Get-GitHubReleaseAssetByReleaseID.ps1 | 25 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 index 464d7df2f..d2a53b506 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1 @@ -1,7 +1,7 @@ filter Get-GitHubReleaseAssetByID { <# .SYNOPSIS - Get a release asset + Get a release asset by ID .DESCRIPTION To download the asset's binary content, set the `Accept` header of the request to diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 index 69e22f23a..e1d7f6a56 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1 @@ -11,11 +11,16 @@ Gets the release assets for the release with the ID '1234567' for the repository 'octocat/hello-world'. + .EXAMPLE + Get-GitHubReleaseAssetByReleaseID -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Name 'example.zip' + + Gets only the release asset named 'example.zip' for the release with the ID '1234567'. + .NOTES https://docs.github.com/rest/releases/assets#list-release-assets #> - [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] + [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] @@ -26,12 +31,13 @@ [string] $Repository, # The unique identifier of the release. - [Parameter( - Mandatory, - ParameterSetName = 'ID' - )] + [Parameter(Mandatory)] [string] $ID, + # The name of a specific asset to return. If provided, only the asset with this name will be returned. + [Parameter()] + [string] $Name, + # The number of results per page (max 100). [Parameter()] [ValidateRange(0, 100)] @@ -63,7 +69,14 @@ Invoke-GitHubAPI @inputObject | ForEach-Object { foreach ($asset in $_.Response) { - [GitHubReleaseAsset]($asset) + if ($PSBoundParameters.ContainsKey('Name')) { + if ($asset.name -eq $Name) { + [GitHubReleaseAsset]($asset) + break + } + } else { + [GitHubReleaseAsset]($asset) + } } } } From e5924b28221fd58c4ccdffd6675d8ef38fc6e1f6 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 10:41:11 +0200 Subject: [PATCH 196/224] Update Get-GitHubReleaseAssetByTag and Get-GitHubReleaseAssetFromLatest: fix asset retrieval query to correctly handle pagination and asset name filtering --- .../private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 | 4 ++-- .../Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index 17374eea2..55911aa6f 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -67,7 +67,7 @@ query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $after: String, $name: String) { repository(owner: $owner, name: $repository) { release(tagName: $tag) { - releaseAssets(first: $perPage, after: $after, name: $name) { + releaseAssets(first: $perPage, after: $after{0}) { nodes { id name @@ -90,7 +90,7 @@ query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $afte } } } -'@ +'@ -f (if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' }) Variables = @{ owner = $Owner repository = $Repository diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index 5aad967d6..8ea0c3718 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -67,7 +67,7 @@ query($owner: String!, $repository: String!, $perPage: Int, $after: String, $name: String) { repository(owner: $owner, name: $repository) { latestRelease { - releaseAssets(first: $perPage, after: $after, name: $name) { + releaseAssets(first: $perPage, after: $after{0}) { nodes { id name @@ -90,7 +90,7 @@ query($owner: String!, $repository: String!, $perPage: Int, $after: String, $nam } } } -'@ +'@ -f (if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' }) Variables = @{ owner = $Owner repository = $Repository From 09a64420be32ea50c75444aa50add3a401685210 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 10:51:12 +0200 Subject: [PATCH 197/224] Fix string interpolation syntax in Get-GitHubReleaseAssetFromLatest for asset name filtering --- .../private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 | 2 +- .../Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index 55911aa6f..1290bbc02 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -90,7 +90,7 @@ query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $afte } } } -'@ -f (if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' }) +'@ -f $(if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' }) Variables = @{ owner = $Owner repository = $Repository diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index 8ea0c3718..46a4237ff 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -90,7 +90,7 @@ query($owner: String!, $repository: String!, $perPage: Int, $after: String, $nam } } } -'@ -f (if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' }) +'@ -f $(if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' }) Variables = @{ owner = $Owner repository = $Repository From 2c1dd973ac8b65d985d519803cc82284338cd94a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 11:04:47 +0200 Subject: [PATCH 198/224] Fix string interpolation in asset queries to handle optional name parameter --- .../private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 | 2 +- .../Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index 1290bbc02..d62d89c91 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -90,7 +90,7 @@ query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $afte } } } -'@ -f $(if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' }) +'@ -f $(if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' } else { '' }) Variables = @{ owner = $Owner repository = $Repository diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index 46a4237ff..c46372f55 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -90,7 +90,7 @@ query($owner: String!, $repository: String!, $perPage: Int, $after: String, $nam } } } -'@ -f $(if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' }) +'@ -f $(if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' } else { '' }) Variables = @{ owner = $Owner repository = $Repository From 9f6028f9ffdbd5dc0ee0cf5dcd0a5540edeb6aab Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 11:19:37 +0200 Subject: [PATCH 199/224] Enhance asset retrieval functions: add support for optional asset name filtering in Get-GitHubReleaseAssetByTag and Get-GitHubReleaseAssetFromLatest --- .../Assets/Get-GitHubReleaseAssetByTag.ps1 | 14 +++++++------- .../Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index d62d89c91..a1a166ddf 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -59,15 +59,16 @@ process { $hasNextPage = $true $after = $null + $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: $Name" : '' $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context do { $inputObject = @{ - Query = @' -query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $after: String, $name: String) { - repository(owner: $owner, name: $repository) { - release(tagName: $tag) { - releaseAssets(first: $perPage, after: $after{0}) { + Query = @" +query(`$owner: String!, `$repository: String!, `$tag: String!, `$perPage: Int, `$after: String, `$name: String) { + repository(owner: `$owner, name: `$repository) { + release(tagName: `$tag) { + releaseAssets(first: `$perPage, after: `$after$nameParam) { nodes { id name @@ -90,11 +91,10 @@ query($owner: String!, $repository: String!, $tag: String!, $perPage: Int, $afte } } } -'@ -f $(if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' } else { '' }) +"@ Variables = @{ owner = $Owner repository = $Repository - name = $Name tag = $Tag perPage = $perPageSetting after = $after diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index c46372f55..780165380 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -59,15 +59,16 @@ process { $hasNextPage = $true $after = $null + $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: $Name" : '' $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context do { $inputObject = @{ - Query = @' -query($owner: String!, $repository: String!, $perPage: Int, $after: String, $name: String) { - repository(owner: $owner, name: $repository) { + Query = @" +query(`$owner: String!, `$repository: String!, `$perPage: Int, `$after: String, `$name: String) { + repository(owner: `$owner, name: `$repository) { latestRelease { - releaseAssets(first: $perPage, after: $after{0}) { + releaseAssets(first: `$perPage, after: `$after$nameParam) { nodes { id name @@ -90,11 +91,10 @@ query($owner: String!, $repository: String!, $perPage: Int, $after: String, $nam } } } -'@ -f $(if ($PSBoundParameters.ContainsKey('Name')) { ', name: $name' } else { '' }) +"@ Variables = @{ owner = $Owner repository = $Repository - name = $Name perPage = $perPageSetting after = $after } From f0df4ea2dd7bcdaf2f9a710ed930ba4f27b1cf8c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 11:23:21 +0200 Subject: [PATCH 200/224] Remove unused asset name parameter from GraphQL queries in Get-GitHubReleaseAssetByTag and Get-GitHubReleaseAssetFromLatest --- .../private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 | 2 +- .../Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index a1a166ddf..2695ee7e4 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -65,7 +65,7 @@ do { $inputObject = @{ Query = @" -query(`$owner: String!, `$repository: String!, `$tag: String!, `$perPage: Int, `$after: String, `$name: String) { +query(`$owner: String!, `$repository: String!, `$tag: String!, `$perPage: Int, `$after: String) { repository(owner: `$owner, name: `$repository) { release(tagName: `$tag) { releaseAssets(first: `$perPage, after: `$after$nameParam) { diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index 780165380..9a587119d 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -65,7 +65,7 @@ do { $inputObject = @{ Query = @" -query(`$owner: String!, `$repository: String!, `$perPage: Int, `$after: String, `$name: String) { +query(`$owner: String!, `$repository: String!, `$perPage: Int, `$after: String) { repository(owner: `$owner, name: `$repository) { latestRelease { releaseAssets(first: `$perPage, after: `$after$nameParam) { From 732c582c974ea7a9a3a02fee350187926004a8c9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 11:40:33 +0200 Subject: [PATCH 201/224] Refactor repository name generation in test scripts for consistency and clarity --- tests copy/Environments.Tests.ps1 | 4 ++-- tests copy/Secrets.Tests.ps1 | 17 +++++++++-------- tests copy/Variables.Tests.ps1 | 17 +++++++++-------- tests/Releases.Tests.ps1 | 2 +- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/tests copy/Environments.Tests.ps1 b/tests copy/Environments.Tests.ps1 index 024be230b..67756b571 100644 --- a/tests copy/Environments.Tests.ps1 +++ b/tests copy/Environments.Tests.ps1 @@ -40,8 +40,8 @@ Describe 'Environments' { Write-Host ($context | Format-List | Out-String) } } - $repoPrefix = "$testName-$os-$TokenType-$guid" - $repoName = $repoPrefix + $repoPrefix = "$testName-$os-$TokenType" + $repoName = "$repoPrefix-$guid" $environmentName = "$testName-$os-$TokenType-$guid" switch ($OwnerType) { diff --git a/tests copy/Secrets.Tests.ps1 b/tests copy/Secrets.Tests.ps1 index 6d909b181..1735e8942 100644 --- a/tests copy/Secrets.Tests.ps1 +++ b/tests copy/Secrets.Tests.ps1 @@ -36,21 +36,22 @@ Describe 'Secrets' { Write-Host ($context | Format-List | Out-String) } } - $repoPrefix = "$testName-$os-$TokenType-$guid" + $repoPrefix = "$testName-$os-$TokenType" + $repoName = "$repoPrefix-$guid" $secretPrefix = ("$testName`_$os`_$TokenType`_$guid" -replace '-', '_').ToUpper() $orgSecretName = "$secretPrefix`ORG" $environmentName = "$testName-$os-$TokenType-$guid" switch ($OwnerType) { 'user' { - $repo = New-GitHubRepository -Name "$repoPrefix-1" -AllowSquashMerge - $repo2 = New-GitHubRepository -Name "$repoPrefix-2" -AllowSquashMerge - $repo3 = New-GitHubRepository -Name "$repoPrefix-3" -AllowSquashMerge + $repo = New-GitHubRepository -Name "$repoName-1" -AllowSquashMerge + $repo2 = New-GitHubRepository -Name "$repoName-2" -AllowSquashMerge + $repo3 = New-GitHubRepository -Name "$repoName-3" -AllowSquashMerge } 'organization' { - $repo = New-GitHubRepository -Organization $owner -Name "$repoPrefix-1" -AllowSquashMerge - $repo2 = New-GitHubRepository -Organization $owner -Name "$repoPrefix-2" -AllowSquashMerge - $repo3 = New-GitHubRepository -Organization $owner -Name "$repoPrefix-3" -AllowSquashMerge + $repo = New-GitHubRepository -Organization $owner -Name "$repoName-1" -AllowSquashMerge + $repo2 = New-GitHubRepository -Organization $owner -Name "$repoName-2" -AllowSquashMerge + $repo3 = New-GitHubRepository -Organization $owner -Name "$repoName-3" -AllowSquashMerge LogGroup "Org secret - [$secretPrefix]" { $params = @{ Owner = $owner @@ -65,7 +66,7 @@ Describe 'Secrets' { } } } - LogGroup "Repository - [$repoPrefix]" { + LogGroup "Repository - [$repoName]" { Write-Host ($repo | Format-List | Out-String) Write-Host ($repo2 | Format-List | Out-String) Write-Host ($repo3 | Format-List | Out-String) diff --git a/tests copy/Variables.Tests.ps1 b/tests copy/Variables.Tests.ps1 index edaef1add..2d3112860 100644 --- a/tests copy/Variables.Tests.ps1 +++ b/tests copy/Variables.Tests.ps1 @@ -36,21 +36,22 @@ Describe 'Variables' { Write-Host ($context | Format-List | Out-String) } } - $repoPrefix = "$testName-$os-$TokenType-$guid" + $repoPrefix = "$testName-$os-$TokenType" + $repoName = "$repoPrefix-$guid" $variablePrefix = ("$testName`_$os`_$TokenType`_$guid" -replace '-', '_').ToUpper() $orgVariableName = "$variablePrefix`ORG" $environmentName = "$testName-$os-$TokenType-$guid" switch ($OwnerType) { 'user' { - $repo = New-GitHubRepository -Name "$repoPrefix-1" -AllowSquashMerge - $repo2 = New-GitHubRepository -Name "$repoPrefix-2" -AllowSquashMerge - $repo3 = New-GitHubRepository -Name "$repoPrefix-3" -AllowSquashMerge + $repo = New-GitHubRepository -Name "$repoName-1" -AllowSquashMerge + $repo2 = New-GitHubRepository -Name "$repoName-2" -AllowSquashMerge + $repo3 = New-GitHubRepository -Name "$repoName-3" -AllowSquashMerge } 'organization' { - $repo = New-GitHubRepository -Organization $owner -Name "$repoPrefix-1" -AllowSquashMerge - $repo2 = New-GitHubRepository -Organization $owner -Name "$repoPrefix-2" -AllowSquashMerge - $repo3 = New-GitHubRepository -Organization $owner -Name "$repoPrefix-3" -AllowSquashMerge + $repo = New-GitHubRepository -Organization $owner -Name "$repoName-1" -AllowSquashMerge + $repo2 = New-GitHubRepository -Organization $owner -Name "$repoName-2" -AllowSquashMerge + $repo3 = New-GitHubRepository -Organization $owner -Name "$repoName-3" -AllowSquashMerge LogGroup "Org variable - [$variablePrefix]" { $params = @{ Owner = $owner @@ -64,7 +65,7 @@ Describe 'Variables' { } } } - LogGroup "Repository - [$repoPrefix]" { + LogGroup "Repository - [$repoName]" { Write-Host ($repo | Format-Table | Out-String) Write-Host ($repo2 | Format-Table | Out-String) Write-Host ($repo3 | Format-Table | Out-String) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 2ecfbc19e..b50c3b5bf 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -459,7 +459,7 @@ ID,Name,Value $release = Get-GitHubRelease -Owner $Owner -Repository $repo $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID $assetName = $assets[0].Name - $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName -Debug LogGroup 'Release asset by name from tag' { Write-Host ($asset | Format-List -Property * | Out-String) } From e6d804c280e667e4e958b71e295a325cdc1402ea Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 11:47:37 +0200 Subject: [PATCH 202/224] Fix string interpolation for asset name parameter in Get-GitHubReleaseAssetByTag and Get-GitHubReleaseAssetFromLatest --- .../private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 | 2 +- .../Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index 2695ee7e4..b25e2380b 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -59,7 +59,7 @@ process { $hasNextPage = $true $after = $null - $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: $Name" : '' + $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: '$Name'" : '' $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context do { diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index 9a587119d..3c1ad09b7 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -59,7 +59,7 @@ process { $hasNextPage = $true $after = $null - $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: $Name" : '' + $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: '$Name'" : '' $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context do { From 115ec351021587a9f4f766822844ea479ed69ca4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 11:52:06 +0200 Subject: [PATCH 203/224] Fix string interpolation for asset name parameter in Get-GitHubReleaseAssetFromLatest --- .../Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index 3c1ad09b7..6b006a9e2 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -59,7 +59,7 @@ process { $hasNextPage = $true $after = $null - $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: '$Name'" : '' + $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: ""$Name""" : '' $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context do { From f7cee1d574cfb7458ea22b32217c794b58ca2958 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 11:52:29 +0200 Subject: [PATCH 204/224] Fix string interpolation for asset name parameter in Get-GitHubReleaseAssetByTag and Get-GitHubReleaseAssetFromLatest --- .../private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 | 2 +- .../Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index b25e2380b..7dfda1fd4 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -59,7 +59,7 @@ process { $hasNextPage = $true $after = $null - $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: '$Name'" : '' + $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: ""$Name""" : '' $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context do { diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index 6b006a9e2..60e48d879 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -59,7 +59,7 @@ process { $hasNextPage = $true $after = $null - $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: ""$Name""" : '' + $nameParam = $PSBoundParameters.ContainsKey('Name') ? ", name: x$Name""" : '' $perPageSetting = Resolve-GitHubContextSetting -Name 'PerPage' -Value $PerPage -Context $Context do { From bfb8b0f51809e0fafc9406edfc769ac96b37f985 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 12:28:55 +0200 Subject: [PATCH 205/224] Remove commented-out skip test notes and enhance release notes tests for clarity and validation --- .../Assets/Add-GitHubReleaseAsset.ps1 | 3 --- .../Assets/Remove-GitHubReleaseAsset.ps1 | 2 -- .../Assets/Update-GitHubReleaseAsset.ps1 | 2 -- tests/Releases.Tests.ps1 | 24 +++++++++++++++++++ 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index cdf97b05e..e5edf6caf 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -186,12 +186,9 @@ } clean { - # Clean up temporary file if created if ($isDirectory) { Write-Verbose "Cleaning up temporary zip file: $TempFilePath" Remove-Item -Path $TempFilePath -Force -ErrorAction SilentlyContinue } } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 index a9a589ebb..eedd80609 100644 --- a/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 @@ -63,5 +63,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 index 2988f4371..86b920857 100644 --- a/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 @@ -85,5 +85,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index b50c3b5bf..81d4d2748 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -280,6 +280,29 @@ Describe 'Releases' { $release = Get-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' $release | Should -BeNullOrEmpty } + + It 'New-GitHubReleaseNote - Generates release notes' { + $notes = New-GitHubReleaseNote -Owner $Owner -Repository $repo -Tag 'v1.4' + LogGroup 'Generated release notes' { + Write-Host ($notes | Format-List -Property * | Out-String) + } + $notes | Should -Not -BeNullOrEmpty + $notes.Name | Should -Not -BeNullOrEmpty + $notes.Notes | Should -Not -BeNullOrEmpty + } + + It 'New-GitHubReleaseNote - Generates release notes with custom parameters' { + $releaseTag = 'v1.4' + $previousTag = 'v1.3' + $notes = New-GitHubReleaseNote -Owner $Owner -Repository $repo -Tag $releaseTag -PreviousTag $previousTag -Target 'main' + LogGroup 'Generated release notes with parameters' { + Write-Host ($notes | Format-List -Property * | Out-String) + } + $notes | Should -Not -BeNullOrEmpty + $notes.Name | Should -Not -BeNullOrEmpty + $notes.Notes | Should -Not -BeNullOrEmpty + $notes.Notes | Should -Match $releaseTag + } } Context 'Release Assets' -Skip:($OwnerType -eq 'repository') { BeforeAll { @@ -400,6 +423,7 @@ ID,Name,Value Write-Host ($asset | Format-List -Property * | Out-String) } $asset | Should -Not -BeNullOrEmpty + $asset | Should -BeOfType 'GitHubReleaseAsset' $asset.Name | Should -Be $testFiles.ZipFile.Name $asset.Label | Should -Be $label $asset.ContentType | Should -Be $testFiles.ZipFile.ContentType From 1d0634b555da1e5ffbf9c9cbb9ae8493a879c2da Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 13:52:51 +0200 Subject: [PATCH 206/224] Enhance documentation for release management functions with additional examples and links --- .../Assets/Add-GitHubReleaseAsset.ps1 | 3 ++ .../public/Releases/New-GitHubRelease.ps1 | 23 +++++++++- .../public/Releases/New-GitHubReleaseNote.ps1 | 28 ++++++------- .../public/Releases/Remove-GitHubRelease.ps1 | 3 ++ .../public/Releases/Set-GitHubRelease.ps1 | 42 +++++++++++++++++++ .../public/Releases/Update-GitHubRelease.ps1 | 21 +++++++++- 6 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index e5edf6caf..58361870c 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -52,6 +52,9 @@ .OUTPUTS GitHubReleaseAsset + .LINK + https://psmodule.io/GitHub/Functions/Releases/Assets/Add-GitHubReleaseAsset/ + .NOTES [Upload a release asset](https://docs.github.com/rest/releases/assets#upload-a-release-asset) #> diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 index cbbead9a3..4e4a0fa9a 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -15,6 +15,27 @@ Creates a release for the repository 'octocat/hello-world' on the 'main' branch with the tag 'v1.0.0'. + .EXAMPLE + New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v0.9.0' -Name 'Beta Release' -Draft -Prerelease + + Creates a draft prerelease for the repository 'octocat/hello-world' with the tag 'v0.9.0' using the default target branch ('main'). + + .EXAMPLE + New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v2.0.0' -Latest + + Creates a release for the repository 'octocat/hello-world' with the tag 'v2.0.0' and marks it as the latest release. + Note that when using -Latest, you cannot use -Draft or -Prerelease as they are mutually exclusive. + + .EXAMPLE + New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.1.0' -GenerateReleaseNotes + + Creates a release for the repository 'octocat/hello-world' with the tag 'v1.1.0' and automatically generates release notes based on commits since the previous release. + + .EXAMPLE + New-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.2.0' -DiscussionCategoryName 'Announcements' -Notes 'Major update with new features' + + Creates a release for the repository 'octocat/hello-world' with the tag 'v1.2.0' and creates a discussion in the 'Announcements' category linked to this release. + .INPUTS GitHubRepository @@ -24,7 +45,7 @@ .LINK https://psmodule.io/GitHub/Functions/Releases/New-GitHubRelease/ - .LINK + .NOTES [Create a release](https://docs.github.com/rest/releases/releases#create-a-release) #> [OutputType([GitHubRelease])] diff --git a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 index db375f580..8349137e0 100644 --- a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 @@ -4,15 +4,15 @@ Generate release notes content for a release. .DESCRIPTION - Generate a name and body describing a [release](https://docs.github.com/rest/releases/releases#get-a-release). The body content will be - markdown formatted and contain information like the changes since last release and users who contributed. The generated release notes are not - saved anywhere. They are intended to be generated and used when creating a new release. + Generate a name and body describing a [release](https://docs.github.com/rest/releases/releases#generate-release-notes-content-for-a-release). + The body content will be markdown formatted and contain information like the changes since last release and users who contributed. + The generated release notes are not saved anywhere. They are intended to be generated and used when creating a new release. .EXAMPLE $params = @{ Owner = 'octocat' - Repo = 'hello-world' - Tag = 'v1.0.0' + Repository = 'hello-world' + Tag = 'v1.0.0' } New-GitHubReleaseNote @params @@ -22,9 +22,9 @@ .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - Tag = 'v1.0.0' + Owner = 'octocat' + Repository = 'hello-world' + Tag = 'v1.0.0' Target = 'main' } New-GitHubReleaseNote @params @@ -34,11 +34,11 @@ .EXAMPLE $params = @{ - Owner = 'octocat' - Repo = 'hello-world' - Tag = 'v1.0.0' - Target = 'main' - PreviousTag = 'v0.9.2' + Owner = 'octocat' + Repository = 'hello-world' + Tag = 'v1.0.0' + Target = 'main' + PreviousTag = 'v0.9.2' ConfigurationFilePath = '.github/custom_release_config.yml' } New-GitHubReleaseNote @params @@ -139,5 +139,3 @@ Write-Debug "[$stackPath] - End" } } - -#SkipTest:FunctionTest:Will add a test for this function in a future PR diff --git a/src/functions/public/Releases/Remove-GitHubRelease.ps1 b/src/functions/public/Releases/Remove-GitHubRelease.ps1 index c6b045dcb..8ed3b1024 100644 --- a/src/functions/public/Releases/Remove-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Remove-GitHubRelease.ps1 @@ -14,6 +14,9 @@ .INPUTS GitHubRelease + .OUTPUTS + None. This cmdlet returns no output. + .LINK https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 98d1a376e..206553ca9 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -4,11 +4,53 @@ Creates or updates a release. .DESCRIPTION + The Set-GitHubRelease cmdlet creates a new GitHub release or updates an existing one for a specified tag. + This function first checks if a release with the specified tag already exists: + - If the release exists, it will update the existing release with the provided parameters + - If the release doesn't exist, it will create a new release + + You can specify whether the release is a draft or prerelease, generate release notes automatically, + link a discussion to the release, and set a release as the latest for the repository. + + When using the 'Latest' parameter, the release will be promoted from draft/prerelease status to a full release. .EXAMPLE Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Target 'main' -Notes 'Release notes' + Creates a new release with tag 'v1.0.0' targeting the 'main' branch. + + .EXAMPLE + Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Notes 'Updated release notes' + + Updates an existing release with tag 'v1.0.0' to have new release notes. + + .EXAMPLE + Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Draft + + Creates or updates a release as a draft release. + + .EXAMPLE + Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Prerelease + + Creates or updates a release as a prerelease. + + .EXAMPLE + Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -Latest + + Sets the release with tag 'v1.0.0' as the latest release for the repository. If the release was a draft or prerelease, + it will be promoted to a full release. + + .EXAMPLE + Set-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0.0' -GenerateReleaseNotes + + Creates or updates a release with automatically generated release notes based on pull requests and commits. + + .EXAMPLE + Get-GitHubRepository -Owner 'octocat' -Repository 'hello-world' | Set-GitHubRelease -Tag 'v1.0.0' -Notes 'Release notes' + + Creates or updates a release using pipeline input for the repository. + .INPUTS GitHubRepository diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 8382b6fa8..6636848b7 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -6,13 +6,32 @@ .DESCRIPTION Users with push access to the repository can edit a release. + You must specify either the ID or Tag parameter to identify the release to update. + The function also accepts GitHubRelease objects through the pipeline. + .EXAMPLE Update-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -ID '1234567' -Notes 'Release notes' Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the note 'Release notes'. + .EXAMPLE + Update-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0' -Name 'Release v1.0' -Notes 'Stable release' + + Updates the release with the tag 'v1.0' for the repository 'octocat/hello-world' with a new name and notes. + + .EXAMPLE + Get-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0' | + Update-GitHubRelease -Draft:$false -Prerelease + + Gets a release by tag and updates it to be a prerelease (not a draft). + + .EXAMPLE + Update-GitHubRelease -Owner 'octocat' -Repository 'hello-world' -Tag 'v1.0' -Latest -GenerateReleaseNotes + + Updates the release with tag 'v1.0' to be the latest release and automatically generates release notes. + .LINK - https://psmodule.io/github/Functions/Releases/Update-GitHubRelease + https://psmodule.io/GitHub/Functions/Releases/Update-GitHubRelease .NOTES [Update a release](https://docs.github.com/rest/releases/releases#update-a-release) From e4ae67e43af9e41586e2a410e53fafead49e2e12 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 14:08:48 +0200 Subject: [PATCH 207/224] Refactor test context usage in Releases.Tests.ps1 for improved clarity and consistency --- tests/Releases.Tests.ps1 | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 81d4d2748..59c093c94 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -28,7 +28,7 @@ BeforeAll { Describe 'Releases' { $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" - Context 'As using on ' -ForEach $authCases { + Get-Context 'As using on ' -ForEach $authCases { BeforeAll { $context = Connect-GitHubAccount @connectParams -PassThru -Silent LogGroup 'Context' { @@ -76,13 +76,14 @@ Describe 'Releases' { Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent } - Context 'Releases' -Skip:($OwnerType -eq 'repository') { + Get-Context 'Releases' -Skip:($OwnerType -eq 'repository') { It 'New-GitHubRelease - Creates a new release' { $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest LogGroup 'Release' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' } It 'New-GitHubRelease - Throws when tag already exists' { @@ -95,6 +96,7 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' $release.IsDraft | Should -BeTrue $release.IsLatest | Should -BeFalse $release.IsPrerelease | Should -BeFalse @@ -106,6 +108,7 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.1' $release.IsDraft | Should -BeFalse $release.IsLatest | Should -BeFalse @@ -118,6 +121,7 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' } It 'Get-GitHubRelease - Gets latest release' { @@ -188,6 +192,7 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.Tag | Should -Be 'v1.0' @@ -202,6 +207,7 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.Tag | Should -Be 'v1.1' @@ -216,6 +222,7 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.IsLatest | Should -BeFalse @@ -229,6 +236,7 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' $release.Name | Should -Be 'Updated Release' $release.Notes | Should -Be 'Updated release notes' $release.Tag | Should -Be 'v1.3' @@ -243,6 +251,7 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.0' $release.IsLatest | Should -BeTrue $release.IsDraft | Should -BeFalse @@ -257,6 +266,7 @@ Describe 'Releases' { Write-Host ($release | Format-List -Property * | Out-String) } $release | Should -Not -BeNullOrEmpty + $release | Should -BeOfType 'GitHubRelease' $release.Tag | Should -Be 'v1.4' $release.IsLatest | Should -BeTrue $release.IsDraft | Should -BeFalse @@ -304,7 +314,7 @@ Describe 'Releases' { $notes.Notes | Should -Match $releaseTag } } - Context 'Release Assets' -Skip:($OwnerType -eq 'repository') { + Get-Context 'Release Assets' -Skip:($OwnerType -eq 'repository') { BeforeAll { $testFolderGuid = [Guid]::NewGuid().ToString().Substring(0, 8) $testFolderName = "GHAssetTest-$testFolderGuid" @@ -483,11 +493,12 @@ ID,Name,Value $release = Get-GitHubRelease -Owner $Owner -Repository $repo $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID $assetName = $assets[0].Name - $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName -Debug + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName LogGroup 'Release asset by name from tag' { Write-Host ($asset | Format-List -Property * | Out-String) } $asset | Should -Not -BeNullOrEmpty + $asset | Should -BeOfType 'GitHubReleaseAsset' $asset.Name | Should -Be $assetName } @@ -500,6 +511,7 @@ ID,Name,Value Write-Host ($asset | Format-List -Property * | Out-String) } $asset | Should -Not -BeNullOrEmpty + $asset | Should -BeOfType 'GitHubReleaseAsset' $asset.Label | Should -Be $newLabel } From 0e4f5ad0303e1d70646eccdbbce585b4d009e0b4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 14:14:03 +0200 Subject: [PATCH 208/224] Refactor context usage in Releases.Tests.ps1 for consistency and clarity --- tests/Releases.Tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 59c093c94..c4cc46737 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -28,7 +28,7 @@ BeforeAll { Describe 'Releases' { $authCases = . "$PSScriptRoot/Data/AuthCases.ps1" - Get-Context 'As using on ' -ForEach $authCases { + Context 'As using on ' -ForEach $authCases { BeforeAll { $context = Connect-GitHubAccount @connectParams -PassThru -Silent LogGroup 'Context' { @@ -76,7 +76,7 @@ Describe 'Releases' { Get-GitHubContext -ListAvailable | Disconnect-GitHubAccount -Silent } - Get-Context 'Releases' -Skip:($OwnerType -eq 'repository') { + Context 'Releases' -Skip:($OwnerType -eq 'repository') { It 'New-GitHubRelease - Creates a new release' { $release = New-GitHubRelease -Owner $Owner -Repository $repo -Tag 'v1.0' -Latest LogGroup 'Release' { @@ -314,7 +314,7 @@ Describe 'Releases' { $notes.Notes | Should -Match $releaseTag } } - Get-Context 'Release Assets' -Skip:($OwnerType -eq 'repository') { + Context 'Release Assets' -Skip:($OwnerType -eq 'repository') { BeforeAll { $testFolderGuid = [Guid]::NewGuid().ToString().Substring(0, 8) $testFolderName = "GHAssetTest-$testFolderGuid" From 40e43cb29c1a62dc32456fdab8865d2d536b7dbc Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 14:26:07 +0200 Subject: [PATCH 209/224] Enhance documentation for release asset functions with INPUTS and OUTPUTS sections --- .../public/Releases/Assets/Add-GitHubReleaseAsset.ps1 | 1 + .../public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 | 7 ++++--- .../public/Releases/Assets/Update-GitHubReleaseAsset.ps1 | 9 ++++++++- src/functions/public/Releases/Remove-GitHubRelease.ps1 | 2 +- src/functions/public/Releases/Set-GitHubRelease.ps1 | 4 ++-- src/functions/public/Releases/Update-GitHubRelease.ps1 | 8 +++++++- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index 58361870c..16a4e2243 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -58,6 +58,7 @@ .NOTES [Upload a release asset](https://docs.github.com/rest/releases/assets#upload-a-release-asset) #> + [OutputType([GitHubReleaseAsset])] [CmdletBinding()] param( # The account owner of the repository. The name is not case sensitive. diff --git a/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 index eedd80609..1ebe7ab5b 100644 --- a/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Remove-GitHubReleaseAsset.ps1 @@ -11,6 +11,9 @@ Deletes the release asset with the ID '1234567' for the repository 'octocat/hello-world'. + .INPUTS + GitHubReleaseAsset + .LINK https://psmodule.io/GitHub/Functions/Releases/Assets/Remove-GitHubReleaseAsset @@ -53,9 +56,7 @@ } if ($PSCmdlet.ShouldProcess("Asset with ID [$ID] in [$Owner/$Repository]", 'DELETE')) { - Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response - } + $null = Invoke-GitHubAPI @inputObject } } diff --git a/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 index 86b920857..2bfd9f554 100644 --- a/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Update-GitHubReleaseAsset.ps1 @@ -12,12 +12,19 @@ Updates the release asset with the ID '1234567' for the repository 'octocat/hello-world' with the new name 'new_asset_name' and label 'new_asset_label'. + .INPUTS + GitHubReleaseAsset + + .OUTPUTS + GitHubReleaseAsset + .LINK https://psmodule.io/GitHub/Functions/Releases/Assets/Update-GitHubReleaseAsset .NOTES [Update a release asset](https://docs.github.com/rest/releases/assets#update-a-release-asset) #> + [OutputType([GitHubReleaseAsset])] [CmdletBinding(SupportsShouldProcess)] param( # The account owner of the repository. The name is not case sensitive. @@ -76,7 +83,7 @@ if ($PSCmdlet.ShouldProcess("assets for release with ID [$ID] in [$Owner/$Repository]", 'Set')) { Invoke-GitHubAPI @inputObject | ForEach-Object { - Write-Output $_.Response + [GitHubReleaseAsset]($_.Response) } } } diff --git a/src/functions/public/Releases/Remove-GitHubRelease.ps1 b/src/functions/public/Releases/Remove-GitHubRelease.ps1 index 8ed3b1024..991aa2c53 100644 --- a/src/functions/public/Releases/Remove-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Remove-GitHubRelease.ps1 @@ -15,7 +15,7 @@ GitHubRelease .OUTPUTS - None. This cmdlet returns no output. + None .LINK https://psmodule.io/GitHub/Functions/Releases/Get-GitHubRelease/ diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 206553ca9..8cd782680 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -84,11 +84,11 @@ # The name of the release. [Parameter()] - [string] $Name = '', + [string] $Name, # Text describing the contents of the tag. [Parameter()] - [string] $Notes = '', + [string] $Notes, # Whether the release is a draft. [Parameter(ParameterSetName = 'Not latest')] diff --git a/src/functions/public/Releases/Update-GitHubRelease.ps1 b/src/functions/public/Releases/Update-GitHubRelease.ps1 index 6636848b7..6a9bec95d 100644 --- a/src/functions/public/Releases/Update-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Update-GitHubRelease.ps1 @@ -33,10 +33,16 @@ .LINK https://psmodule.io/GitHub/Functions/Releases/Update-GitHubRelease + .INPUTS + GitHubRelease + + .OUTPUTS + GitHubRelease + .NOTES [Update a release](https://docs.github.com/rest/releases/releases#update-a-release) #> - [OutputType([pscustomobject])] + [OutputType([GitHubRelease])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] param( From 2746cacf32d9e686220a2956488130106c898152 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 14:40:16 +0200 Subject: [PATCH 210/224] Add test for Add-GitHubReleaseAsset to upload multiple files from a folder --- tests/Releases.Tests.ps1 | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index c4cc46737..3c6824a9e 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -444,6 +444,49 @@ ID,Name,Value Test-Path -Path $downloadPath | Should -BeTrue } + It 'Add-GitHubReleaseAsset - Adds multiple files from a folder to a release' { + $folderName = "FolderAssetTest-$testFolderGuid" + $folderPath = Join-Path -Path $PSScriptRoot -ChildPath $folderName + New-Item -Path $folderPath -ItemType Directory -Force + + $fileContents = @{ + 'config.json' = '{"name": "Test Config", "version": "1.0.0"}' + 'readme.md' = '# Test Folder\nThis is a test folder for uploading to a GitHub release.' + 'data.txt' = 'This is some test data' + } + + foreach ($file in $fileContents.GetEnumerator()) { + $filePath = Join-Path -Path $folderPath -ChildPath $file.Key + Set-Content -Path $filePath -Value $file.Value + } + + $asset = $release | Add-GitHubReleaseAsset -Path $folderPath -Label 'Folder Asset Test' + + LogGroup 'Added folder asset' { + Write-Host ($asset | Format-List -Property * | Out-String) + } + + $asset | Should -Not -BeNullOrEmpty + $asset | Should -BeOfType 'GitHubReleaseAsset' + $asset.Name | Should -Be "$folderName.zip" + $asset.Label | Should -Be 'Folder Asset Test' + $asset.ContentType | Should -Be 'application/zip' + $asset.Size | Should -BeGreaterThan 0 + + $downloadPath = Join-Path -Path $PSScriptRoot -ChildPath "Downloaded-$folderName.zip" + Invoke-WebRequest -Uri $asset.Url -OutFile $downloadPath -RetryIntervalSec 5 -MaximumRetryCount 5 + + $extractPath = Join-Path -Path $PSScriptRoot -ChildPath "Extract-$folderName" + New-Item -Path $extractPath -ItemType Directory -Force + Expand-Archive -Path $downloadPath -DestinationPath $extractPath -Force + + foreach ($file in $fileContents.GetEnumerator()) { + $extractedFilePath = Join-Path -Path $extractPath -ChildPath $file.Key + Test-Path -Path $extractedFilePath | Should -BeTrue + Get-Content -Path $extractedFilePath -Raw | Should -Be $file.Value + } + } + It 'Get-GitHubReleaseAsset - Gets all assets from a release ID' { $release = Get-GitHubRelease -Owner $Owner -Repository $repo $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID From a560d91794a70be66557c6d0dd03da4deae8b8ba Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 15:17:34 +0200 Subject: [PATCH 211/224] Update asset name assertion and count check in release tests --- tests/Releases.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 3c6824a9e..cfb1d7c9f 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -468,7 +468,7 @@ ID,Name,Value $asset | Should -Not -BeNullOrEmpty $asset | Should -BeOfType 'GitHubReleaseAsset' - $asset.Name | Should -Be "$folderName.zip" + $asset.Name | Should -Be $folderName $asset.Label | Should -Be 'Folder Asset Test' $asset.ContentType | Should -Be 'application/zip' $asset.Size | Should -BeGreaterThan 0 @@ -494,7 +494,7 @@ ID,Name,Value Write-Host ($assets | Format-List -Property * | Out-String) } $assets | Should -Not -BeNullOrEmpty - $assets.Count | Should -Be 3 + $assets.Count | Should -Be 4 $assets | Should -BeOfType 'GitHubReleaseAsset' } From c7d99a47ccbb819a3a37670c64013e8548cd8d5d Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 19:09:42 +0200 Subject: [PATCH 212/224] Fix content retrieval in asset extraction test by removing Raw flag from Get-Content --- tests/Releases.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index cfb1d7c9f..30ac6a730 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -483,7 +483,7 @@ ID,Name,Value foreach ($file in $fileContents.GetEnumerator()) { $extractedFilePath = Join-Path -Path $extractPath -ChildPath $file.Key Test-Path -Path $extractedFilePath | Should -BeTrue - Get-Content -Path $extractedFilePath -Raw | Should -Be $file.Value + Get-Content -Path $extractedFilePath | Should -Be $file.Value } } From 692eebbcc9ce095ab9fbead8f73f0398f7af396e Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions@users.noreply.github.com> Date: Thu, 1 May 2025 17:11:24 +0000 Subject: [PATCH 213/224] Auto-generated changes --- Coverage.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Coverage.md b/Coverage.md index 0c13d6fca..f39f6188a 100644 --- a/Coverage.md +++ b/Coverage.md @@ -5,7 +5,7 @@ - + @@ -13,11 +13,11 @@ - + - +
Available functions10271028
Covered functions
Missing functions807808
Coverage21.42%21.4%
@@ -699,6 +699,7 @@ | `/users/{username}/settings/billing/actions` | | :x: | | | | | `/users/{username}/settings/billing/packages` | | :x: | | | | | `/users/{username}/settings/billing/shared-storage` | | :x: | | | | +| `/users/{username}/settings/billing/usage` | | :x: | | | | | `/users/{username}/social_accounts` | | :white_check_mark: | | | | | `/users/{username}/ssh_signing_keys` | | :white_check_mark: | | | | | `/users/{username}/starred` | | :x: | | | | From 73b441ada110a01c514440088f2d209d25375f2a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 19:22:21 +0200 Subject: [PATCH 214/224] Add initial Pester tests for GitHub API interactions - Created TEMPLATE.ps1 for test structure and setup. - Implemented Teams.Tests.ps1 to test GitHub Teams API functionalities including team creation, retrieval, updating, and deletion. - Added Users.Tests.ps1 to validate user-related API calls such as user retrieval and updates. - Developed Variables.Tests.ps1 to cover GitHub variable management, including setting, updating, and removing variables across different scopes (organization, repository, environment). --- tests copy/Data/AuthCases.ps1 | 83 ------------------- tests copy/Data/IssueForm.md | 19 ----- {tests copy => tests}/Artifacts.Tests.ps1 | 0 {tests copy => tests}/Environments.Tests.ps1 | 0 {tests copy => tests}/GitHub.Tests.ps1 | 0 {tests copy => tests}/Organizations.Tests.ps1 | 0 {tests copy => tests}/README.md | 0 {tests copy => tests}/Repositories.Tests.ps1 | 0 {tests copy => tests}/Secrets.Tests.ps1 | 0 {tests copy => tests}/TEMPLATE.ps1 | 0 {tests copy => tests}/Teams.Tests.ps1 | 0 {tests copy => tests}/Users.Tests.ps1 | 0 {tests copy => tests}/Variables.Tests.ps1 | 0 13 files changed, 102 deletions(-) delete mode 100644 tests copy/Data/AuthCases.ps1 delete mode 100644 tests copy/Data/IssueForm.md rename {tests copy => tests}/Artifacts.Tests.ps1 (100%) rename {tests copy => tests}/Environments.Tests.ps1 (100%) rename {tests copy => tests}/GitHub.Tests.ps1 (100%) rename {tests copy => tests}/Organizations.Tests.ps1 (100%) rename {tests copy => tests}/README.md (100%) rename {tests copy => tests}/Repositories.Tests.ps1 (100%) rename {tests copy => tests}/Secrets.Tests.ps1 (100%) rename {tests copy => tests}/TEMPLATE.ps1 (100%) rename {tests copy => tests}/Teams.Tests.ps1 (100%) rename {tests copy => tests}/Users.Tests.ps1 (100%) rename {tests copy => tests}/Variables.Tests.ps1 (100%) diff --git a/tests copy/Data/AuthCases.ps1 b/tests copy/Data/AuthCases.ps1 deleted file mode 100644 index 63c7f1438..000000000 --- a/tests copy/Data/AuthCases.ps1 +++ /dev/null @@ -1,83 +0,0 @@ -@( - @{ - AuthType = 'PAT' - Type = 'a user' - Case = 'Fine-grained PAT token' - TokenType = 'USER_FG_PAT' - Target = 'it self (user account)' - Owner = 'psmodule-user' - OwnerType = 'user' - ConnectParams = @{ - Token = $env:TEST_USER_USER_FG_PAT - } - } - @{ - AuthType = 'PAT' - Type = 'a user' - Case = 'Fine-grained PAT token' - TokenType = 'ORG_FG_PAT' - Target = 'organization account' - Owner = 'psmodule-test-org2' - OwnerType = 'organization' - ConnectParams = @{ - Token = $env:TEST_USER_ORG_FG_PAT - } - } - @{ - AuthType = 'PAT' - Type = 'a user' - Case = 'Classic PAT token' - TokenType = 'PAT' - Target = 'user account' - Owner = 'psmodule-user' - OwnerType = 'user' - ConnectParams = @{ - Token = $env:TEST_USER_PAT - } - } - @{ - AuthType = 'IAT' - Type = 'GitHub Actions' - Case = 'GITHUB_TOKEN' - TokenType = 'GITHUB_TOKEN' - Target = 'this repository (GitHub)' - Owner = 'PSModule' - Repo = 'GitHub' - OwnerType = 'repository' - ConnectParams = @{ - Token = $env:GITHUB_TOKEN - } - } - @{ - AuthType = 'App' - Type = 'a GitHub App from an Enterprise' - Case = 'PEM + IAT' - TokenType = 'APP_ENT' - Target = 'organization account' - Owner = 'psmodule-test-org3' - OwnerType = 'organization' - ConnectParams = @{ - ClientID = $env:TEST_APP_ENT_CLIENT_ID - PrivateKey = $env:TEST_APP_ENT_PRIVATE_KEY - } - ConnectAppParams = @{ - Organization = 'psmodule-test-org3' - } - } - @{ - AuthType = 'App' - Type = 'a GitHub App from an Organization' - Case = 'PEM + IAT' - TokenType = 'APP_ORG' - Target = 'organization account' - Owner = 'psmodule-test-org' - OwnerType = 'organization' - ConnectParams = @{ - ClientID = $env:TEST_APP_ORG_CLIENT_ID - PrivateKey = $env:TEST_APP_ORG_PRIVATE_KEY - } - ConnectAppParams = @{ - Organization = 'psmodule-test-org' - } - } -) diff --git a/tests copy/Data/IssueForm.md b/tests copy/Data/IssueForm.md deleted file mode 100644 index 83b1b3967..000000000 --- a/tests copy/Data/IssueForm.md +++ /dev/null @@ -1,19 +0,0 @@ - -### Type with spaces - -Action - -### Multiline - -test -is multi - line - -### OS - -- [x] Windows -- [x] Linux -- [ ] macOS - diff --git a/tests copy/Artifacts.Tests.ps1 b/tests/Artifacts.Tests.ps1 similarity index 100% rename from tests copy/Artifacts.Tests.ps1 rename to tests/Artifacts.Tests.ps1 diff --git a/tests copy/Environments.Tests.ps1 b/tests/Environments.Tests.ps1 similarity index 100% rename from tests copy/Environments.Tests.ps1 rename to tests/Environments.Tests.ps1 diff --git a/tests copy/GitHub.Tests.ps1 b/tests/GitHub.Tests.ps1 similarity index 100% rename from tests copy/GitHub.Tests.ps1 rename to tests/GitHub.Tests.ps1 diff --git a/tests copy/Organizations.Tests.ps1 b/tests/Organizations.Tests.ps1 similarity index 100% rename from tests copy/Organizations.Tests.ps1 rename to tests/Organizations.Tests.ps1 diff --git a/tests copy/README.md b/tests/README.md similarity index 100% rename from tests copy/README.md rename to tests/README.md diff --git a/tests copy/Repositories.Tests.ps1 b/tests/Repositories.Tests.ps1 similarity index 100% rename from tests copy/Repositories.Tests.ps1 rename to tests/Repositories.Tests.ps1 diff --git a/tests copy/Secrets.Tests.ps1 b/tests/Secrets.Tests.ps1 similarity index 100% rename from tests copy/Secrets.Tests.ps1 rename to tests/Secrets.Tests.ps1 diff --git a/tests copy/TEMPLATE.ps1 b/tests/TEMPLATE.ps1 similarity index 100% rename from tests copy/TEMPLATE.ps1 rename to tests/TEMPLATE.ps1 diff --git a/tests copy/Teams.Tests.ps1 b/tests/Teams.Tests.ps1 similarity index 100% rename from tests copy/Teams.Tests.ps1 rename to tests/Teams.Tests.ps1 diff --git a/tests copy/Users.Tests.ps1 b/tests/Users.Tests.ps1 similarity index 100% rename from tests copy/Users.Tests.ps1 rename to tests/Users.Tests.ps1 diff --git a/tests copy/Variables.Tests.ps1 b/tests/Variables.Tests.ps1 similarity index 100% rename from tests copy/Variables.Tests.ps1 rename to tests/Variables.Tests.ps1 From 300c8939ca5a18942751cea964a464b121a734dc Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 20:10:40 +0200 Subject: [PATCH 215/224] Add suppress message attributes for variable scoping issues in release functions --- .../Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 | 8 ++++++++ .../Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 | 8 ++++++++ src/functions/private/Releases/Get-GitHubReleaseAll.ps1 | 8 ++++++++ src/functions/public/Releases/Set-GitHubRelease.ps1 | 4 ++++ 4 files changed, 28 insertions(+) diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 index 7dfda1fd4..8902da267 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetByTag.ps1 @@ -20,6 +20,14 @@ .OUTPUTS GitHubReleaseAsset #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', 'hasNextPage', Scope = 'Function', + Justification = 'Unknown issue with var scoping in blocks.' + )] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', 'after', Scope = 'Function', + Justification = 'Unknown issue with var scoping in blocks.' + )] [OutputType([GitHubReleaseAsset])] [CmdletBinding()] param( diff --git a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 index 60e48d879..95d40d520 100644 --- a/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 +++ b/src/functions/private/Releases/Assets/Get-GitHubReleaseAssetFromLatest.ps1 @@ -24,6 +24,14 @@ .OUTPUTS GitHubReleaseAsset #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', 'hasNextPage', Scope = 'Function', + Justification = 'Unknown issue with var scoping in blocks.' + )] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', 'after', Scope = 'Function', + Justification = 'Unknown issue with var scoping in blocks.' + )] [OutputType([GitHubReleaseAsset])] [CmdletBinding()] param( diff --git a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 index b20f6bc04..f065ae156 100644 --- a/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 +++ b/src/functions/private/Releases/Get-GitHubReleaseAll.ps1 @@ -22,6 +22,14 @@ .LINK [List releases](https://docs.github.com/rest/releases/releases#list-releases) #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', 'hasNextPage', Scope = 'Function', + Justification = 'Unknown issue with var scoping in blocks.' + )] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseDeclaredVarsMoreThanAssignments', 'after', Scope = 'Function', + Justification = 'Unknown issue with var scoping in blocks.' + )] [OutputType([GitHubRelease])] [CmdletBinding(SupportsPaging)] param( diff --git a/src/functions/public/Releases/Set-GitHubRelease.ps1 b/src/functions/public/Releases/Set-GitHubRelease.ps1 index 8cd782680..e0df36825 100644 --- a/src/functions/public/Releases/Set-GitHubRelease.ps1 +++ b/src/functions/public/Releases/Set-GitHubRelease.ps1 @@ -60,6 +60,10 @@ .LINK https://psmodule.io/GitHub/Functions/Releases/Set-GitHubRelease/ #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSShouldProcess', '', Scope = 'Function', + Justification = 'This check is performed in the private functions.' + )] [OutputType([GitHubRelease])] [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Not latest')] param( From d53f6c6fde768e5728ab7990e7a343a06c0f4314 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 20:49:35 +0200 Subject: [PATCH 216/224] Remove unnecessary skip attributes from PSModule.yml test configuration --- .github/PSModule.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/PSModule.yml b/.github/PSModule.yml index 80afa1153..6d578178e 100644 --- a/.github/PSModule.yml +++ b/.github/PSModule.yml @@ -1,18 +1,3 @@ Test: - SourceCode: - Skip: true - PSModule: - Skip: true - Module: - Windows: - Skip: true - MacOS: - Skip: true CodeCoverage: - Skip: true PercentTarget: 50 - TestResults: - Skip: true -Build: - Docs: - Skip: true From 179fc8db5a6e976bccce45dd68bff756275244af Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 21:27:12 +0200 Subject: [PATCH 217/224] Add comprehensive Pester tests for GitHub API interactions - Created a template test file for GitHub authentication scenarios. - Implemented tests for GitHub Teams management, including team creation, retrieval, updating, and deletion. - Developed user-related tests for GitHub user management, covering user retrieval and updates. - Added extensive variable management tests, including setting, updating, and removing GitHub variables across different scopes (organization, repository, environment). - Ensured all tests utilize proper logging and context management for better traceability in CI/CD environments. --- .github/PSModule.yml | 15 ++ .../Organization/Get-GitHubOrganization.ps1 | 6 +- .../public/Organization/completers.ps1 | 14 -- .../Assets/Add-GitHubReleaseAsset.ps1 | 2 +- .../Assets/Save-GitHubReleaseAsset.ps1 | 193 ++++++++++++++++++ .../public/Releases/New-GitHubReleaseNote.ps1 | 2 +- src/functions/public/Users/completers.ps1 | 31 --- {tests => tests copy}/Artifacts.Tests.ps1 | 0 {tests => tests copy}/Environments.Tests.ps1 | 0 {tests => tests copy}/GitHub.Tests.ps1 | 0 {tests => tests copy}/Organizations.Tests.ps1 | 0 {tests => tests copy}/README.md | 0 {tests => tests copy}/Repositories.Tests.ps1 | 0 {tests => tests copy}/Secrets.Tests.ps1 | 0 {tests => tests copy}/TEMPLATE.ps1 | 0 {tests => tests copy}/Teams.Tests.ps1 | 0 {tests => tests copy}/Users.Tests.ps1 | 0 {tests => tests copy}/Variables.Tests.ps1 | 0 tests/Releases.Tests.ps1 | 78 +++++++ tools/dev/Get-GitHubReleaseQL.ps1 | 124 ----------- 20 files changed, 291 insertions(+), 174 deletions(-) delete mode 100644 src/functions/public/Organization/completers.ps1 create mode 100644 src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 delete mode 100644 src/functions/public/Users/completers.ps1 rename {tests => tests copy}/Artifacts.Tests.ps1 (100%) rename {tests => tests copy}/Environments.Tests.ps1 (100%) rename {tests => tests copy}/GitHub.Tests.ps1 (100%) rename {tests => tests copy}/Organizations.Tests.ps1 (100%) rename {tests => tests copy}/README.md (100%) rename {tests => tests copy}/Repositories.Tests.ps1 (100%) rename {tests => tests copy}/Secrets.Tests.ps1 (100%) rename {tests => tests copy}/TEMPLATE.ps1 (100%) rename {tests => tests copy}/Teams.Tests.ps1 (100%) rename {tests => tests copy}/Users.Tests.ps1 (100%) rename {tests => tests copy}/Variables.Tests.ps1 (100%) delete mode 100644 tools/dev/Get-GitHubReleaseQL.ps1 diff --git a/.github/PSModule.yml b/.github/PSModule.yml index 6d578178e..80afa1153 100644 --- a/.github/PSModule.yml +++ b/.github/PSModule.yml @@ -1,3 +1,18 @@ Test: + SourceCode: + Skip: true + PSModule: + Skip: true + Module: + Windows: + Skip: true + MacOS: + Skip: true CodeCoverage: + Skip: true PercentTarget: 50 + TestResults: + Skip: true +Build: + Docs: + Skip: true diff --git a/src/functions/public/Organization/Get-GitHubOrganization.ps1 b/src/functions/public/Organization/Get-GitHubOrganization.ps1 index 999d44558..84afe544a 100644 --- a/src/functions/public/Organization/Get-GitHubOrganization.ps1 +++ b/src/functions/public/Organization/Get-GitHubOrganization.ps1 @@ -36,7 +36,7 @@ https://psmodule.io/GitHub/Functions/Organization/Get-GitHubOrganization #> [OutputType([GitHubOrganization])] - [CmdletBinding(DefaultParameterSetName = 'List organizations for the authenticated user')] + [CmdletBinding(DefaultParameterSetName = '__AllParameterSets')] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'All', Justification = 'Required for parameter set')] param( # The organization name. The name is not case sensitive. @@ -71,7 +71,7 @@ # The number of results per page (max 100). [Parameter(ParameterSetName = 'AllOrg')] [Parameter(ParameterSetName = 'UserOrg')] - [Parameter(ParameterSetName = 'List organizations for the authenticated user')] + [Parameter(ParameterSetName = '__AllParameterSets')] [ValidateRange(0, 100)] [int] $PerPage, @@ -99,7 +99,7 @@ 'AllOrg' { Get-GitHubAllOrganization -Since $Since -PerPage $PerPage -Context $Context } - 'List organizations for the authenticated user' { + default { Get-GitHubMyOrganization -PerPage $PerPage -Context $Context } } diff --git a/src/functions/public/Organization/completers.ps1 b/src/functions/public/Organization/completers.ps1 deleted file mode 100644 index 43b6a920f..000000000 --- a/src/functions/public/Organization/completers.ps1 +++ /dev/null @@ -1,14 +0,0 @@ -Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Name -ScriptBlock { - param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) - $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter - - if ($fakeBoundParameter.ContainsKey('Context')) { - $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context - } else { - $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false - } - - $orgs | Where-Object { $_.CompletionText -like "$wordToComplete*" } | ForEach-Object { - [System.Management.Automation.CompletionResult]::new($_, ($_ | Format-Table -HideTableHeaders), 'ParameterValue', $_.Description) - } -} diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index 16a4e2243..ad61034dd 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -44,7 +44,7 @@ .EXAMPLE Add-GitHubReleaseAsset -Owner 'octocat' -Repository 'hello-world' -ID '7654321' -Path 'C:\Users\octocat\Projects\MyApp' - Automatically creates a zip file from the contents of the MyApp directory and uploads it as a release asset. + Automatically creates a ZIP file from the contents of the MyApp directory and uploads it as a release asset. .INPUTS GitHubRelease diff --git a/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 new file mode 100644 index 000000000..f585dfd8f --- /dev/null +++ b/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 @@ -0,0 +1,193 @@ +function Save-GitHubReleaseAsset { + <# + .SYNOPSIS + Downloads a GitHub Release asset. + + .DESCRIPTION + Downloads an asset from a repository release. The asset is downloaded as a file to the specified path + or the current directory by default. Users must have read access to the repository. For private repositories, + personal access tokens (classic) or OAuth tokens with the `repo` scope are required. + + .EXAMPLE + Save-GitHubReleaseAsset -Owner 'octocat' -Repository 'Hello-World' -ID '123456' -Path 'C:\Assets' + + Output: + ```powershell + Directory: C:\Assets + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 03/31/2025 12:00 4194304 asset-123456.zip + ``` + + Downloads release asset ID '123456' from the 'Hello-World' repository owned by 'octocat' to the specified path. + + .EXAMPLE + Save-GitHubReleaseAsset -Owner 'octocat' -Repository 'Hello-World' -Tag 'v1.0.0' -Name 'binary.zip' -Path 'C:\Assets\app' -Expand -Force + + Output: + ```powershell + Directory: C:\Assets\app + + Mode LastWriteTime Length Name + ---- ------------- ------ ---- + -a---- 03/31/2025 12:00 5120 config.json + -a---- 03/31/2025 12:00 4194304 application.exe + ``` + + Downloads asset named 'binary.zip' from the release tagged as 'v1.0.0' in the 'Hello-World' repository owned by 'octocat' + to the specified path, overwriting existing files during download and extraction. + + .EXAMPLE + Get-GitHubReleaseAsset -Owner 'octocat' -Repository 'Hello-World' -Tag 'v1.0.0' -Name 'binary.zip' | Save-GitHubReleaseAsset -Path 'C:\Assets' -Expand + + Pipes a release asset object directly to the Save-GitHubReleaseAsset function, which downloads and extracts it. + + .INPUTS + GitHubReleaseAsset + + .OUTPUTS + System.IO.FileSystemInfo[] + + .NOTES + Contains the extracted file or folder information from the downloaded asset. + This output can include directories or files depending on the asset content. + + .LINK + https://psmodule.io/GitHub/Functions/Releases/Assets/Save-GitHubReleaseAsset/ + #> + [OutputType([System.IO.FileSystemInfo[]])] + [CmdletBinding(DefaultParameterSetName = 'By Asset ID')] + param( + # The account owner of the repository. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'By Asset ID')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'By Release ID and Asset Name')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'By Tag and Asset Name')] + [string] $Owner, + + # The name of the repository without the .git extension. The name is not case sensitive. + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'By Asset ID')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'By Release ID and Asset Name')] + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'By Tag and Asset Name')] + [string] $Repository, + + # The unique identifier of the asset. + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'By Asset ID')] + [string] $ID, + + # The unique identifier of the release. + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'By Release ID and Asset Name')] + [string] $ReleaseID, + + # The tag name of the release. + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'By Tag and Asset Name')] + [string] $Tag, + + # The name of the asset to download. + [Parameter(Mandatory, ParameterSetName = 'By Release ID and Asset Name')] + [Parameter(Mandatory, ParameterSetName = 'By Tag and Asset Name')] + [string] $Name, + + # The GitHubReleaseAsset object containing the information about the asset to download. + [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'By Asset Object')] + [GitHubReleaseAsset] $ReleaseAssetObject, + + # Path to the file or folder for the download. Accepts relative or absolute paths. + [Parameter()] + [string] $Path = $PWD.Path, + + # When specified, the ZIP file is extracted to the same directory it was downloaded to. + [Parameter()] + [Alias('Extract')] + [switch] $Expand, + + # When specified, overwrites existing files during download and extraction. + [Parameter()] + [switch] $Force, + + # When specified, the downloaded file or the folder where the ZIP file was extracted to is returned. + [Parameter()] + [switch] $PassThru, + + # The context to run the command in. Used to get the details for the API call. + # Can be either a string or a GitHubContext object. + [Parameter()] + [object] $Context = (Get-GitHubContext) + ) + + begin { + $stackPath = Get-PSCallStackPath + Write-Debug "[$stackPath] - Start" + $Context = Resolve-GitHubContext -Context $Context + Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT + } + + process { + $asset = $null + + switch ($PSCmdlet.ParameterSetName) { + 'By Asset ID' { + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $Repository -ID $ID -Context $Context + } + 'By Release ID and Asset Name' { + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $Repository -ReleaseID $ReleaseID -Name $Name -Context $Context + } + 'By Tag and Asset Name' { + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $Repository -Tag $Tag -Name $Name -Context $Context + } + 'By Asset Object' { + $asset = $ReleaseAssetObject + } + } + + if (-not $asset) { + throw 'Release asset not found. Please verify the parameters provided.' + } + + # Now download the asset + $inputObject = @{ + Method = 'GET' + Uri = $asset.Url + Accept = 'application/octet-stream' + Context = $Context + } + + Invoke-GitHubAPI @inputObject | ForEach-Object { + $itemType = $Path.EndsWith('.zip') ? 'File' : 'Directory' + $isAbsolute = [System.IO.Path]::IsPathRooted($Path) + $filename = $asset.Name + + Write-Debug "Path: [$Path]" + Write-Debug "Type: [$itemType]" + Write-Debug "Is absolute: [$isAbsolute]" + Write-Debug "Filename: [$filename]" + + if ($itemType -eq 'Directory') { + $Path = Join-Path -Path $Path -ChildPath $filename + } + + $folderPath = [System.IO.Path]::GetDirectoryName($Path) + $folder = New-Item -Path $folderPath -ItemType Directory -Force + Write-Debug "Resolved final download path: [$Path]" + [System.IO.File]::WriteAllBytes($Path, $_.Response) + + # Check if we need to expand the downloaded file + if ($Expand -and $filename -match '\.(zip|tar|gz|bz2|xz|7z|rar)$') { + Write-Debug "Expanding asset to [$folder]" + Expand-Archive -LiteralPath $Path -DestinationPath $folder -Force:$Force + Write-Debug "Removing ZIP file [$Path]" + Remove-Item -LiteralPath $Path -Force + if ($PassThru) { + return $folder + } + } + if ($PassThru) { + return Get-Item -Path $Path + } + } + } + + end { + Write-Debug "[$stackPath] - End" + } +} diff --git a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 index 8349137e0..299a185b0 100644 --- a/src/functions/public/Releases/New-GitHubReleaseNote.ps1 +++ b/src/functions/public/Releases/New-GitHubReleaseNote.ps1 @@ -5,7 +5,7 @@ .DESCRIPTION Generate a name and body describing a [release](https://docs.github.com/rest/releases/releases#generate-release-notes-content-for-a-release). - The body content will be markdown formatted and contain information like the changes since last release and users who contributed. + The body content will be Markdown formatted and contain information like the changes since last release and users who contributed. The generated release notes are not saved anywhere. They are intended to be generated and used when creating a new release. .EXAMPLE diff --git a/src/functions/public/Users/completers.ps1 b/src/functions/public/Users/completers.ps1 deleted file mode 100644 index a32def765..000000000 --- a/src/functions/public/Users/completers.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport) -ParameterName Owner -ScriptBlock { - param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) - $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter - - if ($fakeBoundParameter.ContainsKey('Context')) { - $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context - } else { - $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false - } - $orgs += Get-GitHubMyUser -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context - - $orgs | Where-Object { $_.CompletionText -like "$wordToComplete*" } | ForEach-Object { - [System.Management.Automation.CompletionResult]::new($_, ($_ | Format-Table -HideTableHeaders), 'ParameterValue', $_.Description) - } -} - -Register-ArgumentCompleter -CommandName Get-GitHubUser -ParameterName Name -ScriptBlock { - param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) - $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter - - if ($fakeBoundParameter.ContainsKey('Context')) { - $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context - } else { - $orgs = Get-GitHubOrganization -Verbose:$false -Debug:$false - } - $orgs += Get-GitHubMyUser -Verbose:$false -Debug:$false -Context $fakeBoundParameter.Context - - $orgs | Where-Object { $_.CompletionText -like "$wordToComplete*" } | ForEach-Object { - [System.Management.Automation.CompletionResult]::new($_, ($_ | Format-Table -HideTableHeaders), 'ParameterValue', $_.Description) - } -} diff --git a/tests/Artifacts.Tests.ps1 b/tests copy/Artifacts.Tests.ps1 similarity index 100% rename from tests/Artifacts.Tests.ps1 rename to tests copy/Artifacts.Tests.ps1 diff --git a/tests/Environments.Tests.ps1 b/tests copy/Environments.Tests.ps1 similarity index 100% rename from tests/Environments.Tests.ps1 rename to tests copy/Environments.Tests.ps1 diff --git a/tests/GitHub.Tests.ps1 b/tests copy/GitHub.Tests.ps1 similarity index 100% rename from tests/GitHub.Tests.ps1 rename to tests copy/GitHub.Tests.ps1 diff --git a/tests/Organizations.Tests.ps1 b/tests copy/Organizations.Tests.ps1 similarity index 100% rename from tests/Organizations.Tests.ps1 rename to tests copy/Organizations.Tests.ps1 diff --git a/tests/README.md b/tests copy/README.md similarity index 100% rename from tests/README.md rename to tests copy/README.md diff --git a/tests/Repositories.Tests.ps1 b/tests copy/Repositories.Tests.ps1 similarity index 100% rename from tests/Repositories.Tests.ps1 rename to tests copy/Repositories.Tests.ps1 diff --git a/tests/Secrets.Tests.ps1 b/tests copy/Secrets.Tests.ps1 similarity index 100% rename from tests/Secrets.Tests.ps1 rename to tests copy/Secrets.Tests.ps1 diff --git a/tests/TEMPLATE.ps1 b/tests copy/TEMPLATE.ps1 similarity index 100% rename from tests/TEMPLATE.ps1 rename to tests copy/TEMPLATE.ps1 diff --git a/tests/Teams.Tests.ps1 b/tests copy/Teams.Tests.ps1 similarity index 100% rename from tests/Teams.Tests.ps1 rename to tests copy/Teams.Tests.ps1 diff --git a/tests/Users.Tests.ps1 b/tests copy/Users.Tests.ps1 similarity index 100% rename from tests/Users.Tests.ps1 rename to tests copy/Users.Tests.ps1 diff --git a/tests/Variables.Tests.ps1 b/tests copy/Variables.Tests.ps1 similarity index 100% rename from tests/Variables.Tests.ps1 rename to tests copy/Variables.Tests.ps1 diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 30ac6a730..7ffd5b021 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -567,6 +567,84 @@ ID,Name,Value $remainingAsset = $updatedAssets | Where-Object { $_.ID -eq $assetID } $remainingAsset | Should -BeNullOrEmpty } + + It 'Save-GitHubReleaseAsset - Downloads a release asset by ID' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + $downloadPath = Join-Path -Path $PSScriptRoot -ChildPath "DownloadTest-$testFolderGuid" + New-Item -Path $downloadPath -ItemType Directory -Force | Out-Null + + $downloadedFile = Save-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $assets[0].ID -Path $downloadPath -PassThru + LogGroup 'Downloaded Asset' { + Write-Host ($downloadedFile | Format-List | Out-String) + } + + $downloadedFile | Should -Not -BeNullOrEmpty + Test-Path -Path $downloadedFile.FullName | Should -BeTrue + $downloadedFile.Name | Should -Be $assets[0].Name + } + + It 'Save-GitHubReleaseAsset - Downloads a release asset by name from a tag' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $assets = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID + $assetName = $assets[1].Name + $downloadPath = Join-Path -Path $PSScriptRoot -ChildPath "DownloadByName-$testFolderGuid" + New-Item -Path $downloadPath -ItemType Directory -Force | Out-Null + + $downloadedFile = Save-GitHubReleaseAsset -Owner $Owner -Repository $repo -Tag $release.Tag -Name $assetName -Path $downloadPath -PassThru + LogGroup 'Downloaded Asset by Name' { + Write-Host ($downloadedFile | Format-List | Out-String) + } + + $downloadedFile | Should -Not -BeNullOrEmpty + Test-Path -Path $downloadedFile.FullName | Should -BeTrue + $downloadedFile.Name | Should -Be $assetName + } + + It 'Save-GitHubReleaseAsset - Downloads and extracts a ZIP release asset' { + # Find the ZIP asset + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $zipAsset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID | + Where-Object { $_.Name -like '*.zip' } | + Select-Object -First 1 + + if ($zipAsset) { + $extractPath = Join-Path -Path $PSScriptRoot -ChildPath "ExtractTest-$testFolderGuid" + New-Item -Path $extractPath -ItemType Directory -Force | Out-Null + + $extractedItems = Save-GitHubReleaseAsset -Owner $Owner -Repository $repo -ID $zipAsset.ID -Path $extractPath -Expand -PassThru + LogGroup 'Extracted ZIP Asset' { + Write-Host ($extractedItems | Format-Table | Out-String) + } + + $extractedItems | Should -Not -BeNullOrEmpty + Test-Path -Path $extractPath | Should -BeTrue + # Verify we don't have the zip file in the directory anymore + Test-Path -Path (Join-Path -Path $extractPath -ChildPath $zipAsset.Name) | Should -BeFalse + # Verify we have extracted content + (Get-ChildItem -Path $extractPath -Recurse).Count | Should -BeGreaterThan 0 + } else { + Set-ItResult -Inconclusive -Because 'No ZIP asset found for testing extraction' + } + } + + It 'Save-GitHubReleaseAsset - Uses pipeline input from Get-GitHubReleaseAsset' { + $release = Get-GitHubRelease -Owner $Owner -Repository $repo + $asset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID | + Select-Object -First 1 + + $pipelinePath = Join-Path -Path $PSScriptRoot -ChildPath "PipelineTest-$testFolderGuid" + New-Item -Path $pipelinePath -ItemType Directory -Force | Out-Null + + $downloadedFile = $asset | Save-GitHubReleaseAsset -Path $pipelinePath -PassThru + LogGroup 'Downloaded Asset via Pipeline' { + Write-Host ($downloadedFile | Format-List | Out-String) + } + + $downloadedFile | Should -Not -BeNullOrEmpty + Test-Path -Path $downloadedFile.FullName | Should -BeTrue + $downloadedFile.Name | Should -Be $asset.Name + } } } } diff --git a/tools/dev/Get-GitHubReleaseQL.ps1 b/tools/dev/Get-GitHubReleaseQL.ps1 deleted file mode 100644 index 64dcb4a92..000000000 --- a/tools/dev/Get-GitHubReleaseQL.ps1 +++ /dev/null @@ -1,124 +0,0 @@ -function Get-GitHubReleaseQL { - <# - .SYNOPSIS - Get all releases with nested pagination for assets - - .DESCRIPTION - Gets all releases with their complete asset lists using nested pagination through both releases and their assets. - - .EXAMPLE - Get-GitHubRelease -Owner 'github' -Repository 'my-repo' -PerPage 10 -Context $context - #> - [OutputType([GitHubRelease])] - [CmdletBinding()] - param( - [Parameter(Mandatory)] - [string] $Owner, - - [Parameter(Mandatory)] - [string] $Repository, - - [ValidateRange(1, 100)] - [int] $PerPage, - - [Parameter()] - [object] $Context = (Get-GitHubContext) - ) - - begin { - $stackPath = Get-PSCallStackPath - Write-Debug "[$stackPath] - Start" - Assert-GitHubContext -Context $Context -AuthType IAT, PAT, UAT - - $releaseCursor = $null - $releaseQuery = @' -query($owner: String!, $repository: String!, $releaseCursor: String, $perPage: Int!) { - repository(owner: $owner, name: $repository) { - releases(first: $perPage, after: $releaseCursor, orderBy: {field: CREATED_AT, direction: DESC}) { - nodes { - id - databaseId - name - tagName - description - isDraft - isPrerelease - isLatest - createdAt - publishedAt - updatedAt - tag { - name - id - } - tagCommit { - oid - } - url - author { - login - id - databaseId - } - releaseAssets(first: $perPage) { - nodes { - name - downloadCount - downloadUrl - contentType - createdAt - updatedAt - uploadedBy { - login - name - id - databaseId - } - size - url - id - } - } - } - pageInfo { - hasNextPage - endCursor - } - } - } -} -'@ - - $PerPage = $PSBoundParameters.ContainsKey('PerPage') ? $PerPage : $Context.PerPage - } - - process { - do { - $releaseVariables = @{ - owner = $Owner - repository = $Repository - releaseCursor = $releaseCursor - perPage = $PerPage - } - - $result = Invoke-GitHubGraphQLQuery -Query $releaseQuery -Variables $releaseVariables -Context $Context - if (-not $result) { break } - - $repositoryData = $result.repository - if (-not $repositoryData) { break } - - $releases = $repositoryData.releases - if (-not $releases) { break } - - $releases.nodes | ForEach-Object { - # [GitHubRelease]::new($_) - } - - $releaseCursor = $releases.pageInfo.endCursor - } while ($releases.pageInfo.hasNextPage) - } - - end { - Write-Debug "[$stackPath] - End" - } -} From bde6629e40350d92f503a1856a282adae4d0cef3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 21:43:50 +0200 Subject: [PATCH 218/224] Refactor example usage in Save-GitHubReleaseAsset and clean up test for ZIP asset extraction --- .../public/Releases/Assets/Save-GitHubReleaseAsset.ps1 | 9 ++++++++- tests/Releases.Tests.ps1 | 3 --- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 index f585dfd8f..b2b7c4906 100644 --- a/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 @@ -39,7 +39,14 @@ to the specified path, overwriting existing files during download and extraction. .EXAMPLE - Get-GitHubReleaseAsset -Owner 'octocat' -Repository 'Hello-World' -Tag 'v1.0.0' -Name 'binary.zip' | Save-GitHubReleaseAsset -Path 'C:\Assets' -Expand + $params = @{ + Owner = 'octocat' + Repository = 'Hello-World' + ID = '123456' + Tag = 'v1.0.0' + Name = 'binary.zip' + } + Get-GitHubReleaseAsset @params | Save-GitHubReleaseAsset -Path 'C:\Assets' -Expand -Force Pipes a release asset object directly to the Save-GitHubReleaseAsset function, which downloads and extracts it. diff --git a/tests/Releases.Tests.ps1 b/tests/Releases.Tests.ps1 index 7ffd5b021..210173643 100644 --- a/tests/Releases.Tests.ps1 +++ b/tests/Releases.Tests.ps1 @@ -602,7 +602,6 @@ ID,Name,Value } It 'Save-GitHubReleaseAsset - Downloads and extracts a ZIP release asset' { - # Find the ZIP asset $release = Get-GitHubRelease -Owner $Owner -Repository $repo $zipAsset = Get-GitHubReleaseAsset -Owner $Owner -Repository $repo -ReleaseID $release.ID | Where-Object { $_.Name -like '*.zip' } | @@ -619,9 +618,7 @@ ID,Name,Value $extractedItems | Should -Not -BeNullOrEmpty Test-Path -Path $extractPath | Should -BeTrue - # Verify we don't have the zip file in the directory anymore Test-Path -Path (Join-Path -Path $extractPath -ChildPath $zipAsset.Name) | Should -BeFalse - # Verify we have extracted content (Get-ChildItem -Path $extractPath -Recurse).Count | Should -BeGreaterThan 0 } else { Set-ItResult -Inconclusive -Because 'No ZIP asset found for testing extraction' From 892df96a6443c6c7368c144dfe0a78c87327c4c3 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 22:14:55 +0200 Subject: [PATCH 219/224] Fix variable assignment for Name and Label in Add-GitHubReleaseAsset function --- .../public/Releases/Assets/Add-GitHubReleaseAsset.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 index ad61034dd..92123b57f 100644 --- a/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Add-GitHubReleaseAsset.ps1 @@ -127,10 +127,10 @@ } } if (!$Name) { - $Name = (Get-Item $Path).Name + $Name = $item.Name } if (!$Label) { - $Label = (Get-Item $Path).Name + $Label = $item.Name } if (!$ContentType) { From 72f78a3a33c91f6c81b815f889793980f0c35db8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 22:26:14 +0200 Subject: [PATCH 220/224] Remove Accept header from HTTP request in Save-GitHubReleaseAsset function and make Target parameter mandatory in New-GitHubRelease function --- .../public/Releases/Assets/Save-GitHubReleaseAsset.ps1 | 1 - src/functions/public/Releases/New-GitHubRelease.ps1 | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 b/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 index b2b7c4906..88321e97a 100644 --- a/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 +++ b/src/functions/public/Releases/Assets/Save-GitHubReleaseAsset.ps1 @@ -155,7 +155,6 @@ $inputObject = @{ Method = 'GET' Uri = $asset.Url - Accept = 'application/octet-stream' Context = $Context } diff --git a/src/functions/public/Releases/New-GitHubRelease.ps1 b/src/functions/public/Releases/New-GitHubRelease.ps1 index 4e4a0fa9a..488560be0 100644 --- a/src/functions/public/Releases/New-GitHubRelease.ps1 +++ b/src/functions/public/Releases/New-GitHubRelease.ps1 @@ -69,7 +69,7 @@ # Can be any branch or commit SHA. Unused if the Git tag already exists. # API Default: the repository's default branch. [Parameter()] - [string] $Target = 'main', + [string] $Target, # The name of the release. [Parameter()] From 6adb82c21b3bf648ba41edeb398f3135c9775c35 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 22:50:09 +0200 Subject: [PATCH 221/224] Remove handling for 'text/plain' and 'text/html' content types in Invoke-GitHubAPI and add warning for unknown content types --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 2967876fa..11be85559 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -244,12 +244,6 @@ filter Invoke-GitHubAPI { 'application/.*json' { $results = $response.Content | ConvertFrom-Json } - 'text/plain' { - $results = $response.Content - } - 'text/html' { - $results = $response.Content - } 'application/octocat-stream' { [byte[]]$byteArray = $response.Content $results = [System.Text.Encoding]::UTF8.GetString($byteArray) @@ -260,10 +254,10 @@ filter Invoke-GitHubAPI { default { if (-not $response.Content) { $results = $null + Write-Warning "Unknown content type: $($headers.'Content-Type')" + Write-Warning 'Please report this issue!' break } - Write-Warning "Unknown content type: $($headers.'Content-Type')" - Write-Warning 'Please report this issue!' $results = $response.Content } } From 0b85fb0f8ff1ba5e0468a325f026d7ddc46e672c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 23:14:00 +0200 Subject: [PATCH 222/224] Remove handling for 'zip' content type in Invoke-GitHubAPI and streamline warning for unknown content types --- src/functions/public/API/Invoke-GitHubAPI.ps1 | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/functions/public/API/Invoke-GitHubAPI.ps1 b/src/functions/public/API/Invoke-GitHubAPI.ps1 index 11be85559..b18d5af1b 100644 --- a/src/functions/public/API/Invoke-GitHubAPI.ps1 +++ b/src/functions/public/API/Invoke-GitHubAPI.ps1 @@ -248,16 +248,7 @@ filter Invoke-GitHubAPI { [byte[]]$byteArray = $response.Content $results = [System.Text.Encoding]::UTF8.GetString($byteArray) } - 'zip' { - $results = $response.Content - } default { - if (-not $response.Content) { - $results = $null - Write-Warning "Unknown content type: $($headers.'Content-Type')" - Write-Warning 'Please report this issue!' - break - } $results = $response.Content } } From a9a634fc8c24788ad11bb3a0103aa71f395c365e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 23:37:31 +0200 Subject: [PATCH 223/224] Remove unnecessary skip configurations from PSModule.yml --- .github/PSModule.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/PSModule.yml b/.github/PSModule.yml index 80afa1153..6d578178e 100644 --- a/.github/PSModule.yml +++ b/.github/PSModule.yml @@ -1,18 +1,3 @@ Test: - SourceCode: - Skip: true - PSModule: - Skip: true - Module: - Windows: - Skip: true - MacOS: - Skip: true CodeCoverage: - Skip: true PercentTarget: 50 - TestResults: - Skip: true -Build: - Docs: - Skip: true From 0d76fc7ae0f1a2f06b97ad0844fc63512e2f1124 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Thu, 1 May 2025 23:37:52 +0200 Subject: [PATCH 224/224] Add initial test scripts for GitHub API interactions - Created TEMPLATE.ps1 for Pester testing framework setup. - Added Teams.Tests.ps1 to test GitHub Teams API functionalities including team creation, retrieval, updating, and deletion. - Implemented Users.Tests.ps1 to validate user-related API calls such as user retrieval and updates. - Developed Variables.Tests.ps1 to test GitHub variable management across different scopes (organization, repository, environment). - Each test script includes setup and teardown procedures to manage test context and cleanup. --- {tests copy => tests}/Artifacts.Tests.ps1 | 0 {tests copy => tests}/Environments.Tests.ps1 | 0 {tests copy => tests}/GitHub.Tests.ps1 | 0 {tests copy => tests}/Organizations.Tests.ps1 | 0 {tests copy => tests}/README.md | 0 {tests copy => tests}/Repositories.Tests.ps1 | 0 {tests copy => tests}/Secrets.Tests.ps1 | 0 {tests copy => tests}/TEMPLATE.ps1 | 0 {tests copy => tests}/Teams.Tests.ps1 | 0 {tests copy => tests}/Users.Tests.ps1 | 0 {tests copy => tests}/Variables.Tests.ps1 | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename {tests copy => tests}/Artifacts.Tests.ps1 (100%) rename {tests copy => tests}/Environments.Tests.ps1 (100%) rename {tests copy => tests}/GitHub.Tests.ps1 (100%) rename {tests copy => tests}/Organizations.Tests.ps1 (100%) rename {tests copy => tests}/README.md (100%) rename {tests copy => tests}/Repositories.Tests.ps1 (100%) rename {tests copy => tests}/Secrets.Tests.ps1 (100%) rename {tests copy => tests}/TEMPLATE.ps1 (100%) rename {tests copy => tests}/Teams.Tests.ps1 (100%) rename {tests copy => tests}/Users.Tests.ps1 (100%) rename {tests copy => tests}/Variables.Tests.ps1 (100%) diff --git a/tests copy/Artifacts.Tests.ps1 b/tests/Artifacts.Tests.ps1 similarity index 100% rename from tests copy/Artifacts.Tests.ps1 rename to tests/Artifacts.Tests.ps1 diff --git a/tests copy/Environments.Tests.ps1 b/tests/Environments.Tests.ps1 similarity index 100% rename from tests copy/Environments.Tests.ps1 rename to tests/Environments.Tests.ps1 diff --git a/tests copy/GitHub.Tests.ps1 b/tests/GitHub.Tests.ps1 similarity index 100% rename from tests copy/GitHub.Tests.ps1 rename to tests/GitHub.Tests.ps1 diff --git a/tests copy/Organizations.Tests.ps1 b/tests/Organizations.Tests.ps1 similarity index 100% rename from tests copy/Organizations.Tests.ps1 rename to tests/Organizations.Tests.ps1 diff --git a/tests copy/README.md b/tests/README.md similarity index 100% rename from tests copy/README.md rename to tests/README.md diff --git a/tests copy/Repositories.Tests.ps1 b/tests/Repositories.Tests.ps1 similarity index 100% rename from tests copy/Repositories.Tests.ps1 rename to tests/Repositories.Tests.ps1 diff --git a/tests copy/Secrets.Tests.ps1 b/tests/Secrets.Tests.ps1 similarity index 100% rename from tests copy/Secrets.Tests.ps1 rename to tests/Secrets.Tests.ps1 diff --git a/tests copy/TEMPLATE.ps1 b/tests/TEMPLATE.ps1 similarity index 100% rename from tests copy/TEMPLATE.ps1 rename to tests/TEMPLATE.ps1 diff --git a/tests copy/Teams.Tests.ps1 b/tests/Teams.Tests.ps1 similarity index 100% rename from tests copy/Teams.Tests.ps1 rename to tests/Teams.Tests.ps1 diff --git a/tests copy/Users.Tests.ps1 b/tests/Users.Tests.ps1 similarity index 100% rename from tests copy/Users.Tests.ps1 rename to tests/Users.Tests.ps1 diff --git a/tests copy/Variables.Tests.ps1 b/tests/Variables.Tests.ps1 similarity index 100% rename from tests copy/Variables.Tests.ps1 rename to tests/Variables.Tests.ps1