Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[feat]: SDKs for ActionsArtifacts APIs #2782

Merged
merged 16 commits into from
Sep 25, 2023
44 changes: 43 additions & 1 deletion Octokit.Reactive/Clients/IObservableActionsArtifactsClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
namespace Octokit.Reactive
using System;
using System.IO;
using System.Reactive;

namespace Octokit.Reactive
{
/// <summary>
/// A client for GitHub's Actions Artifacts API.
Expand All @@ -8,5 +12,43 @@
/// </remarks>
public interface IObservableActionsArtifactsClient
{
IObservable<ListArtifactsResponse> ListArtifacts(string owner, string repository, ListArtifactsRequest listArtifactsRequest = null);

/// <summary>
/// Gets the specified artifact
/// </summary>
/// <param name="owner"></param>
/// <param name="repository"></param>
/// <param name="artifactId"></param>
/// <returns></returns>
IObservable<Artifact> GetArtifact(string owner, string repository, long artifactId);

/// <summary>
/// Deletes the specified artifact
/// </summary>
/// <param name="owner"></param>
/// <param name="repository"></param>
/// <param name="artifactId"></param>
/// <returns></returns>
IObservable<Unit> DeleteArtifact(string owner, string repository, long artifactId);

/// <summary>
/// Downloads the specified artifact's contents
/// </summary>
/// <param name="owner"></param>
/// <param name="repository"></param>
/// <param name="artifactId"></param>
/// <param name="archiveFormat"></param>
/// <returns></returns>
IObservable<Stream> DownloadArtifact(string owner, string repository, long artifactId, string archiveFormat);

/// <summary>
/// Lists the artifacts for a specific workflow run
/// </summary>
/// <param name="owner"></param>
/// <param name="repository"></param>
/// <param name="runId"></param>
/// <returns></returns>
IObservable<ListArtifactsResponse> ListWorkflowArtifacts(string owner, string repository, long runId, ListArtifactsRequest listArtifactsRequest = null);
}
}
37 changes: 36 additions & 1 deletion Octokit.Reactive/Clients/ObservableActionsArtifactsClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
namespace Octokit.Reactive
using System;
using System.IO;
using System.Reactive;
using System.Reactive.Threading.Tasks;

namespace Octokit.Reactive
{
public class ObservableActionsArtifactsClient : IObservableActionsArtifactsClient
{
Expand All @@ -14,5 +19,35 @@ public ObservableActionsArtifactsClient(IGitHubClient client)

_client = client.Actions.Artifacts;
}

/// <inheritdoc/>
public IObservable<ListArtifactsResponse> ListArtifacts(string owner, string repository, ListArtifactsRequest listArtifactsRequest = null)
{
return _client.ListArtifacts(owner, repository, listArtifactsRequest).ToObservable();
}

/// <inheritdoc/>
public IObservable<Artifact> GetArtifact(string owner, string repository, long artifactId)
{
return _client.GetArtifact(owner, repository, artifactId).ToObservable();
}

/// <inheritdoc/>
public IObservable<Unit> DeleteArtifact(string owner, string repository, long artifactId)
{
return _client.DeleteArtifact(owner, repository, artifactId).ToObservable();
}

/// <inheritdoc/>
public IObservable<Stream> DownloadArtifact(string owner, string repository, long artifactId, string archiveFormat)
{
return _client.DownloadArtifact(owner, repository, artifactId, archiveFormat).ToObservable();
}

/// <inheritdoc/>
public IObservable<ListArtifactsResponse> ListWorkflowArtifacts(string owner, string repository, long runId, ListArtifactsRequest listArtifactsRequest = null)
{
return _client.ListWorkflowArtifacts(owner, repository, runId, listArtifactsRequest).ToObservable();
}
}
}
8 changes: 5 additions & 3 deletions Octokit.Tests/Http/HttpClientAdapterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,9 @@ public async Task BuildsResponseFromResponseMessage(HttpStatusCode httpStatusCod
Assert.Equal(httpStatusCode, response.StatusCode);
Assert.Null(response.ContentType);
}

[Fact]
public async Task BuildsByteArrayResponseFromResponseMessage()
public async Task BuildsStreamResponseFromResponseMessage()
{
var responseMessage = new HttpResponseMessage
{
Expand All @@ -157,7 +157,9 @@ public async Task BuildsByteArrayResponseFromResponseMessage()

var response = await tester.BuildResponseTester(responseMessage);

Assert.Equal(new byte[] { 0, 1, 1, 0, 1 }, response.Body);
var memoryStream = Assert.IsType<MemoryStream>(response.Body);

Assert.Equal(new byte[] { 0, 1, 1, 0, 1 }, memoryStream.ToArray());
Assert.Equal("image/png", response.ContentType);
}

Expand Down
98 changes: 98 additions & 0 deletions Octokit.Tests/Models/ArtifactsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using Octokit.Internal;
using Xunit;

namespace Octokit.Tests.Models
{
public class ArtifactsTests
{
[Fact]
public void CanBeDeserialized()
{
var json = @"{
""total_count"": 2,
""artifacts"": [
{
""id"": 11,
""node_id"": ""MDg6QXJ0aWZhY3QxMQ=="",
""name"": ""Rails"",
""size_in_bytes"": 556,
""url"": ""https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/11"",
""archive_download_url"": ""https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/11/zip"",
""expired"": false,
""created_at"": ""2020-01-10T14:59:22Z"",
""expires_at"": ""2020-03-21T14:59:22Z"",
""updated_at"": ""2020-02-21T14:59:22Z"",
""workflow_run"": {
""id"": 2332938,
""repository_id"": 1296269,
""head_repository_id"": 1296269,
""head_branch"": ""main"",
""head_sha"": ""328faa0536e6fef19753d9d91dc96a9931694ce3""
}
},
{
""id"": 13,
""node_id"": ""MDg6QXJ0aWZhY3QxMw=="",
""name"": ""Test output"",
""size_in_bytes"": 453,
""url"": ""https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/13"",
""archive_download_url"": ""https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/13/zip"",
""expired"": false,
""created_at"": ""2020-01-10T14:59:22Z"",
""expires_at"": ""2020-03-21T14:59:22Z"",
""updated_at"": ""2020-02-21T14:59:22Z"",
""workflow_run"": {
""id"": 2332942,
""repository_id"": 1296269,
""head_repository_id"": 1296269,
""head_branch"": ""main"",
""head_sha"": ""178f4f6090b3fccad4a65b3e83d076a622d59652""
}
}
]
}";

var serializer = new SimpleJsonSerializer();

var payload = serializer.Deserialize<ListArtifactsResponse>(json);

Assert.NotNull(payload);

Assert.Equal(2, payload.TotalCount);
Assert.Equal(2, payload.Artifacts.Count);

Assert.Equal(11, payload.Artifacts[0].Id);
Assert.Equal("MDg6QXJ0aWZhY3QxMQ==", payload.Artifacts[0].NodeId);
Assert.Equal("Rails", payload.Artifacts[0].Name);
Assert.Equal(556, payload.Artifacts[0].SizeInBytes);
Assert.Equal("https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/11", payload.Artifacts[0].Url);
Assert.Equal("https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/11/zip", payload.Artifacts[0].ArchiveDownloadUrl);
Assert.False(payload.Artifacts[0].Expired);
Assert.Equal(new DateTime(2020, 1, 10, 14, 59, 22, DateTimeKind.Utc), payload.Artifacts[0].CreatedAt);
Assert.Equal(new DateTime(2020, 3, 21, 14, 59, 22, DateTimeKind.Utc), payload.Artifacts[0].ExpiresAt);
Assert.Equal(new DateTime(2020, 2, 21, 14, 59, 22, DateTimeKind.Utc), payload.Artifacts[0].UpdatedAt);
Assert.Equal(2332938, payload.Artifacts[0].WorkflowRun.Id);
Assert.Equal(1296269, payload.Artifacts[0].WorkflowRun.RepositoryId);
Assert.Equal(1296269, payload.Artifacts[0].WorkflowRun.HeadRepositoryId);
Assert.Equal("main", payload.Artifacts[0].WorkflowRun.HeadBranch);
Assert.Equal("328faa0536e6fef19753d9d91dc96a9931694ce3", payload.Artifacts[0].WorkflowRun.HeadSha);

Assert.Equal(13, payload.Artifacts[1].Id);
Assert.Equal("MDg6QXJ0aWZhY3QxMw==", payload.Artifacts[1].NodeId);
Assert.Equal("Test output", payload.Artifacts[1].Name);
Assert.Equal(453, payload.Artifacts[1].SizeInBytes);
Assert.Equal("https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/13", payload.Artifacts[1].Url);
Assert.Equal("https://api.github.com/repos/octo-org/octo-docs/actions/artifacts/13/zip", payload.Artifacts[1].ArchiveDownloadUrl);
Assert.False(payload.Artifacts[1].Expired);
Assert.Equal(new DateTime(2020, 1, 10, 14, 59, 22, DateTimeKind.Utc), payload.Artifacts[1].CreatedAt);
Assert.Equal(new DateTime(2020, 3, 21, 14, 59, 22, DateTimeKind.Utc), payload.Artifacts[1].ExpiresAt);
Assert.Equal(new DateTime(2020, 2, 21, 14, 59, 22, DateTimeKind.Utc), payload.Artifacts[1].UpdatedAt);
Assert.Equal(2332942, payload.Artifacts[1].WorkflowRun.Id);
Assert.Equal(1296269, payload.Artifacts[1].WorkflowRun.RepositoryId);
Assert.Equal(1296269, payload.Artifacts[1].WorkflowRun.HeadRepositoryId);
Assert.Equal("main", payload.Artifacts[1].WorkflowRun.HeadBranch);
Assert.Equal("178f4f6090b3fccad4a65b3e83d076a622d59652", payload.Artifacts[1].WorkflowRun.HeadSha);
}
}
}
4 changes: 1 addition & 3 deletions Octokit/Caching/CachedResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ public V1(object body, IReadOnlyDictionary<string, string> headers, ApiInfo apiI
ContentType = contentType;
}

/// <summary>
/// Raw response body. Typically a string, but when requesting images, it will be a byte array.
/// </summary>
/// <inheritdoc/>
public object Body { get; private set; }
/// <summary>
/// Information about the API.
Expand Down
60 changes: 59 additions & 1 deletion Octokit/Clients/ActionsArtifactsClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
namespace Octokit
using System.IO;
using System.Threading.Tasks;

namespace Octokit
{
/// <summary>
/// A client for GitHub's Actions Artifacts API.
Expand All @@ -15,5 +18,60 @@ public class ActionsArtifactsClient : ApiClient, IActionsArtifactsClient
public ActionsArtifactsClient(IApiConnection apiConnection) : base(apiConnection)
{
}

/// <inheritdoc/>
[ManualRoute("GET", "/repos/{owner}/{repository}/actions/artifacts")]
public Task<ListArtifactsResponse> ListArtifacts(string owner, string repository, ListArtifactsRequest listArtifactsRequest = null)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(repository, nameof(repository));

return ApiConnection.Get<ListArtifactsResponse>(ApiUrls.ListArtifacts(owner, repository), listArtifactsRequest?.ToParametersDictionary());
}

/// <inheritdoc/>
[ManualRoute("GET", "/repos/{owner}/{repository}/actions/artifacts/{artifact_id}")]
public Task<Artifact> GetArtifact(string owner, string repository, long artifactId)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(repository, nameof(repository));
Ensure.ArgumentNotNullOrDefault(artifactId, nameof(artifactId));

return ApiConnection.Get<Artifact>(ApiUrls.Artifact(owner, repository, artifactId), null);
}

/// <inheritdoc/>
[ManualRoute("DELETE", "/repos/{owner}/{repository}/actions/artifacts/{artifact_id}")]
public Task DeleteArtifact(string owner, string repository, long artifactId)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(repository, nameof(repository));
Ensure.ArgumentNotNullOrDefault(artifactId, nameof(artifactId));

return ApiConnection.Delete(ApiUrls.Artifact(owner, repository, artifactId), null);
}

/// <inheritdoc/>
[ManualRoute("GET", "/repos/{owner}/{repository}/actions/artifacts/{artifact_id}/{archive_format}")]
public Task<Stream> DownloadArtifact(string owner, string repository, long artifactId, string archiveFormat)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(repository, nameof(repository));
Ensure.ArgumentNotNullOrDefault(artifactId, nameof(artifactId));
Ensure.ArgumentNotNullOrEmptyString(repository, nameof(archiveFormat));

return ApiConnection.GetRawStream(ApiUrls.DownloadArtifact(owner, repository, artifactId, archiveFormat), null);
}

/// <inheritdoc/>
[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/artifacts")]
public Task<ListArtifactsResponse> ListWorkflowArtifacts(string owner, string repository, long runId, ListArtifactsRequest listArtifactsRequest = null)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(repository, nameof(repository));
Ensure.ArgumentNotNullOrDefault(runId, nameof(runId));

return ApiConnection.Get<ListArtifactsResponse>(ApiUrls.ListWorkflowArtifacts(owner, repository, runId), listArtifactsRequest?.ToParametersDictionary());
}
}
}
46 changes: 45 additions & 1 deletion Octokit/Clients/IActionsArtifactsClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace Octokit
Expand All @@ -11,5 +11,49 @@
/// </remarks>
public interface IActionsArtifactsClient
{
/// <summary>
/// Lists artifacts for a repository
/// </summary>
/// <param name="owner"></param>
/// <param name="repository"></param>
/// <returns></returns>
Task<ListArtifactsResponse> ListArtifacts(string owner, string repository, ListArtifactsRequest listArtifactsRequest = null);

Check warning on line 20 in Octokit/Clients/IActionsArtifactsClient.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Parameter 'listArtifactsRequest' has no matching param tag in the XML comment for 'IActionsArtifactsClient.ListArtifacts(string, string, ListArtifactsRequest)' (but other parameters do)

Check warning on line 20 in Octokit/Clients/IActionsArtifactsClient.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

Parameter 'listArtifactsRequest' has no matching param tag in the XML comment for 'IActionsArtifactsClient.ListArtifacts(string, string, ListArtifactsRequest)' (but other parameters do)

Check warning on line 20 in Octokit/Clients/IActionsArtifactsClient.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Parameter 'listArtifactsRequest' has no matching param tag in the XML comment for 'IActionsArtifactsClient.ListArtifacts(string, string, ListArtifactsRequest)' (but other parameters do)

/// <summary>
/// Gets the specified artifact
/// </summary>
/// <param name="owner"></param>
/// <param name="repository"></param>
/// <param name="artifactId"></param>
/// <returns></returns>
Task<Artifact> GetArtifact(string owner, string repository, long artifactId);

/// <summary>
/// Deletes the specified artifact
/// </summary>
/// <param name="owner"></param>
/// <param name="repository"></param>
/// <param name="artifactId"></param>
/// <returns></returns>
Task DeleteArtifact(string owner, string repository, long artifactId);

/// <summary>
/// Downloads the specified artifact's contents
/// </summary>
/// <param name="owner"></param>
/// <param name="repository"></param>
/// <param name="artifactId"></param>
/// <param name="archiveFormat"></param>
/// <returns></returns>
Task<Stream> DownloadArtifact(string owner, string repository, long artifactId, string archiveFormat);

/// <summary>
/// Lists the artifacts for a specific workflow run
/// </summary>
/// <param name="owner"></param>
/// <param name="repository"></param>
/// <param name="runId"></param>
/// <returns></returns>
Task<ListArtifactsResponse> ListWorkflowArtifacts(string owner, string repository, long runId, ListArtifactsRequest listArtifactsRequest = null);

Check warning on line 57 in Octokit/Clients/IActionsArtifactsClient.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Parameter 'listArtifactsRequest' has no matching param tag in the XML comment for 'IActionsArtifactsClient.ListWorkflowArtifacts(string, string, long, ListArtifactsRequest)' (but other parameters do)

Check warning on line 57 in Octokit/Clients/IActionsArtifactsClient.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

Parameter 'listArtifactsRequest' has no matching param tag in the XML comment for 'IActionsArtifactsClient.ListWorkflowArtifacts(string, string, long, ListArtifactsRequest)' (but other parameters do)

Check warning on line 57 in Octokit/Clients/IActionsArtifactsClient.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Parameter 'listArtifactsRequest' has no matching param tag in the XML comment for 'IActionsArtifactsClient.ListWorkflowArtifacts(string, string, long, ListArtifactsRequest)' (but other parameters do)
}
}
Loading
Loading