Skip to content

Commit da0cdc0

Browse files
[Feature] Releases - Release Assets - Manage release assets (#68)
- Fixes #59 - Add-GitHubReleaseAsset - Get-GitHubReleaseAsset - Remove-GitHubReleaseAsset - Set-GitHubReleaseAsset
1 parent 41c7b99 commit da0cdc0

13 files changed

+423
-21
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
filter Get-GitHubReleaseAssetByID {
2+
<#
3+
.SYNOPSIS
4+
Get a release asset
5+
6+
.DESCRIPTION
7+
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).
8+
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.
9+
10+
.EXAMPLE
11+
Get-GitHubReleaseAssetByID -Owner 'octocat' -Repo 'hello-world' -ID '1234567'
12+
13+
Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'.
14+
15+
.NOTES
16+
https://docs.github.com/rest/releases/assets#get-a-release-asset
17+
18+
#>
19+
[CmdletBinding()]
20+
param (
21+
# The account owner of the repository. The name is not case sensitive.
22+
[Parameter()]
23+
[string] $Owner = (Get-GitHubConfig -Name Owner),
24+
25+
# The name of the repository without the .git extension. The name is not case sensitive.
26+
[Parameter()]
27+
[string] $Repo = (Get-GitHubConfig -Name Repo),
28+
29+
# The unique identifier of the asset.
30+
[Parameter(Mandatory)]
31+
[Alias('asset_id')]
32+
[string] $ID
33+
)
34+
35+
$inputObject = @{
36+
APIEndpoint = "/repos/$Owner/$Repo/releases/assets/$ID"
37+
Method = 'GET'
38+
}
39+
40+
(Invoke-GitHubAPI @inputObject).Response
41+
42+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
filter Get-GitHubReleaseAssetByReleaseID {
2+
<#
3+
.SYNOPSIS
4+
List release assets
5+
6+
.DESCRIPTION
7+
List release assets
8+
9+
.EXAMPLE
10+
Get-GitHubReleaseAssetByReleaseID -Owner 'octocat' -Repo 'hello-world' -ID '1234567'
11+
12+
Gets the release assets for the release with the ID '1234567' for the repository 'octocat/hello-world'.
13+
14+
.NOTES
15+
https://docs.github.com/rest/releases/assets#list-release-assets
16+
17+
#>
18+
[CmdletBinding()]
19+
param (
20+
# The account owner of the repository. The name is not case sensitive.
21+
[Parameter()]
22+
[string] $Owner = (Get-GitHubConfig -Name Owner),
23+
24+
# The name of the repository without the .git extension. The name is not case sensitive.
25+
[Parameter()]
26+
[string] $Repo = (Get-GitHubConfig -Name Repo),
27+
28+
# The unique identifier of the release.
29+
[Parameter(
30+
Mandatory,
31+
ParameterSetName = 'ID'
32+
)]
33+
[Alias('release_id')]
34+
[string] $ID,
35+
36+
# The number of results per page (max 100).
37+
[Parameter()]
38+
[int] $PerPage = 30
39+
)
40+
41+
$body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
42+
Remove-HashtableEntries -Hashtable $body -RemoveNames 'Owner', 'Repo', 'ID'
43+
44+
$inputObject = @{
45+
APIEndpoint = "/repos/$Owner/$Repo/releases/$ID/assets"
46+
Method = 'GET'
47+
Body = $body
48+
}
49+
50+
(Invoke-GitHubAPI @inputObject).Response
51+
52+
}

src/GitHub/private/Releases/Releases/Get-GitHubReleaseByTagName.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
[Parameter(
3030
Mandatory
3131
)]
32+
[Alias('tag_name')]
3233
[string] $Tag
3334
)
3435

src/GitHub/public/API/Invoke-GitHubAPI.ps1

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,23 @@
2222
2323
Gets all open pull requests for the specified repository, filtered by the 'state' parameter, and using the specified 'Accept' header.
2424
#>
25-
[CmdletBinding()]
25+
[CmdletBinding(DefaultParameterSetName = 'ApiEndpoint')]
2626
param (
2727
# The HTTP method to be used for the API request. It can be one of the following: GET, POST, PUT, DELETE, or PATCH.
2828
[Parameter()]
2929
[Microsoft.PowerShell.Commands.WebRequestMethod] $Method = 'GET',
3030

3131
# The base URI for the GitHub API. This is usually 'https://api.github.com', but can be adjusted if necessary.
32-
[Parameter()]
32+
[Parameter(
33+
ParameterSetName = 'ApiEndpoint'
34+
)]
3335
[string] $ApiBaseUri = (Get-GitHubConfig -Name ApiBaseUri),
3436

3537
# The specific endpoint for the API call, e.g., '/repos/user/repo/pulls'.
36-
[Parameter(Mandatory)]
38+
[Parameter(
39+
Mandatory,
40+
ParameterSetName = 'ApiEndpoint'
41+
)]
3742
[string] $ApiEndpoint,
3843

3944
# The body of the API request. This can be a hashtable or a string. If a hashtable is provided, it will be converted to JSON.
@@ -52,6 +57,21 @@
5257
[Parameter()]
5358
[bool] $FollowRelLink = $true,
5459

60+
# The file path to be used for the API request. This is used for uploading files.
61+
[Parameter()]
62+
[string] $UploadFilePath,
63+
64+
# The file path to be used for the API response. This is used for downloading files.
65+
[Parameter()]
66+
[string] $DownloadFilePath,
67+
68+
# The full URI for the API request. This is used for custom API calls.
69+
[Parameter(
70+
Mandatory,
71+
ParameterSetName = 'Uri'
72+
)]
73+
[string] $URI,
74+
5575
# The secure token used for authentication in the GitHub API. It should be stored as a SecureString to ensure it's kept safe in memory.
5676
[Parameter()]
5777
[SecureString] $AccessToken = (Get-GitHubConfig -Name AccessToken),
@@ -79,7 +99,9 @@
7999

80100
Remove-HashTableEntries -Hashtable $headers -NullOrEmptyValues
81101

82-
$URI = ("$ApiBaseUri/" -replace '/$', '') + ("/$ApiEndpoint" -replace '^/', '')
102+
if (-not $URI) {
103+
$URI = ("$ApiBaseUri/" -replace '/$', '') + ("/$ApiEndpoint" -replace '^/', '')
104+
}
83105

84106
# $AccessTokenAsPlainText = ConvertFrom-SecureString $AccessToken -AsPlainText
85107
# # Swap out this by using the -Authentication Bearer -Token $AccessToken
@@ -109,20 +131,18 @@
109131
FollowRelLink = $FollowRelLink
110132
StatusCodeVariable = 'APICallStatusCode'
111133
ResponseHeadersVariable = 'APICallResponseHeaders'
134+
InFile = $UploadFilePath
135+
OutFile = $DownloadFilePath
112136
}
113137

114138
$APICall | Remove-HashTableEntries -NullOrEmptyValues
115139

116140
if ($Body) {
117-
118-
# Use body to create the query string for GET requests
141+
# Use body to create the query string for certain situations
119142
if ($Method -eq 'GET') {
120143
$queryString = $Body | ConvertTo-QueryString
121144
$APICall.Uri = $APICall.Uri + $queryString
122-
}
123-
124-
# Use body to create the form data
125-
if ($Body -is [string]) {
145+
} elseif ($Body -is [string]) { # Use body to create the form data
126146
$APICall.Body = $Body
127147
} else {
128148
$APICall.Body = $Body | ConvertTo-Json -Depth 100
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
filter Add-GitHubReleaseAsset {
2+
<#
3+
.SYNOPSIS
4+
Upload a release asset
5+
6+
.DESCRIPTION
7+
This endpoint makes use of [a Hypermedia relation](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in
8+
the response of the [Create a release endpoint](https://docs.github.com/rest/releases/releases#create-a-release) to upload a release asset.
9+
10+
You need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.
11+
12+
Most libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example:
13+
14+
`application/zip`
15+
16+
GitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,
17+
you'll still need to pass your authentication to be able to upload an asset.
18+
19+
When an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.
20+
21+
**Notes:**
22+
* GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The "[List release assets](https://docs.github.com/rest/releases/assets#list-release-assets)"
23+
endpoint lists the renamed filenames. For more information and help, contact [GitHub Support](https://support.github.com/contact?tags=dotcom-rest-api).
24+
* To find the `release_id` query the [`GET /repos/{owner}/{repo}/releases/latest` endpoint](https://docs.github.com/rest/releases/releases#get-the-latest-release).
25+
* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
26+
27+
.EXAMPLE
28+
Add-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '7654321' -FilePath 'C:\Users\octocat\Downloads\hello-world.zip'
29+
30+
Gets the release assets for the release with the ID '1234567' for the repository 'octocat/hello-world'.
31+
32+
.NOTES
33+
https://docs.github.com/rest/releases/assets#upload-a-release-asset
34+
35+
#>
36+
[CmdletBinding()]
37+
param (
38+
# The account owner of the repository. The name is not case sensitive.
39+
[Parameter()]
40+
[string] $Owner = (Get-GitHubConfig -Name Owner),
41+
42+
# The name of the repository without the .git extension. The name is not case sensitive.
43+
[Parameter()]
44+
[string] $Repo = (Get-GitHubConfig -Name Repo),
45+
46+
# The unique identifier of the release.
47+
[Parameter(Mandatory)]
48+
[Alias('release_id')]
49+
[string] $ID,
50+
51+
#The file name of the asset.
52+
[Parameter()]
53+
[string] $Name,
54+
55+
# An alternate short description of the asset. Used in place of the filename.
56+
[Parameter()]
57+
[string] $Label,
58+
59+
# The content type of the asset.
60+
[Parameter()]
61+
[string] $ContentType,
62+
63+
# The path to the asset file.
64+
[Parameter(Mandatory)]
65+
[alias('fullname')]
66+
[string] $FilePath
67+
)
68+
69+
# If name is not provided, use the file name
70+
if (!$Name) {
71+
$Name = (Get-Item $FilePath).Name
72+
}
73+
74+
# If label is not provided, use the file name
75+
if (!$Label) {
76+
$Label = (Get-Item $FilePath).Name
77+
}
78+
79+
# If content type is not provided, use the file extension
80+
if (!$ContentType) {
81+
$ContentType = switch ((Get-Item $FilePath).Extension) {
82+
'.zip' { 'application/zip' }
83+
'.tar' { 'application/x-tar' }
84+
'.gz' { 'application/gzip' }
85+
'.bz2' { 'application/x-bzip2' }
86+
'.xz' { 'application/x-xz' }
87+
'.7z' { 'application/x-7z-compressed' }
88+
'.rar' { 'application/vnd.rar' }
89+
'.tar.gz' { 'application/gzip' }
90+
'.tgz' { 'application/gzip' }
91+
'.tar.bz2' { 'application/x-bzip2' }
92+
'.tar.xz' { 'application/x-xz' }
93+
'.tar.7z' { 'application/x-7z-compressed' }
94+
'.tar.rar' { 'application/vnd.rar' }
95+
'.png' { 'image/png' }
96+
'.json' { 'application/json' }
97+
'.txt' { 'text/plain' }
98+
'.md' { 'text/markdown' }
99+
'.html' { 'text/html' }
100+
default { 'application/octet-stream' }
101+
}
102+
}
103+
104+
$body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
105+
Remove-HashtableEntries -Hashtable $body -RemoveNames 'Owner', 'Repo', 'ID', 'FilePath'
106+
107+
$body['name'] = $Name
108+
$body['label'] = $Label
109+
110+
Remove-HashtableEntries -Hashtable $body -NullOrEmptyValues
111+
112+
$release = Get-GitHubRelease -Owner $Owner -Repo $Repo -ID $ID
113+
$uploadURI = $release.upload_url -replace '{\?name,label}', "?name=$($Name)&label=$($Label)"
114+
115+
$inputObject = @{
116+
URI = $uploadURI
117+
Method = 'POST'
118+
ContentType = $ContentType
119+
UploadFilePath = $FilePath
120+
}
121+
122+
(Invoke-GitHubAPI @inputObject).Response
123+
124+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
filter Get-GitHubReleaseAsset {
2+
<#
3+
.SYNOPSIS
4+
List release assets based on a release ID or asset ID
5+
6+
.DESCRIPTION
7+
If an asset id is provided, the asset is returned.
8+
If a release id is provided, all assets for the release are returned.
9+
10+
.EXAMPLE
11+
Get-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '1234567'
12+
13+
Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'.
14+
15+
.EXAMPLE
16+
Get-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ReleaseID '7654321'
17+
18+
Gets the release assets for the release with the ID '7654321' for the repository 'octocat/hello-world'.
19+
20+
.NOTES
21+
https://docs.github.com/rest/releases/assets#get-a-release-asset
22+
23+
#>
24+
[CmdletBinding()]
25+
param (
26+
# The account owner of the repository. The name is not case sensitive.
27+
[Parameter()]
28+
[string] $Owner = (Get-GitHubConfig -Name Owner),
29+
30+
# The name of the repository without the .git extension. The name is not case sensitive.
31+
[Parameter()]
32+
[string] $Repo = (Get-GitHubConfig -Name Repo),
33+
34+
# The unique identifier of the asset.
35+
[Parameter(Mandatory)]
36+
[Alias('asset_id')]
37+
[string] $ID,
38+
39+
# The unique identifier of the release.
40+
[Parameter(
41+
Mandatory,
42+
ParameterSetName = 'ReleaseID'
43+
)]
44+
[Alias('release_id')]
45+
[string] $ReleaseID
46+
)
47+
48+
if ($ReleaseID) {
49+
Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repo $Repo -ReleaseID $ReleaseID
50+
}
51+
if ($ID) {
52+
Get-GitHubReleaseAssetByID -Owner $Owner -Repo $Repo -ID $ID
53+
}
54+
55+
}

0 commit comments

Comments
 (0)