Skip to content

Commit

Permalink
Ability to upload to Generic Packages Repository
Browse files Browse the repository at this point in the history
  • Loading branch information
gep13 committed Sep 11, 2023
1 parent a6333c1 commit e356b33
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 2 deletions.
2 changes: 2 additions & 0 deletions NGitLab.Mock/Clients/GitLabClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public GitLabClient(ClientContext context)

public IGroupsClient Groups => new GroupClient(Context);

public IPackageClient Packages => new PackageClient(Context);

public IUserClient Users => new UserClient(Context);

public IProjectClient Projects => new ProjectClient(Context);
Expand Down
17 changes: 17 additions & 0 deletions NGitLab.Mock/Clients/PackageClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using NGitLab.Models;

namespace NGitLab.Mock.Clients
{
internal sealed class PackageClient : ClientBase, IPackageClient
{
public PackageClient(ClientContext context)
: base(context)
{
}

public Package Publish(PackagePublish packagePublish)
{
throw new System.NotImplementedException();
}
}
}
33 changes: 33 additions & 0 deletions NGitLab.Tests/PackageTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Threading.Tasks;
using NGitLab.Models;
using NGitLab.Tests.Docker;
using NUnit.Framework;

namespace NGitLab.Tests
{
public class PackageTests
{
[Test]
[NGitLabRetry]
public async Task Test_publish_package()
{
using var context = await GitLabTestContext.CreateAsync();
var project = context.CreateProject();
var packagesClient = context.Client.Packages;

var packagePublish = new PackagePublish
{
ProjectId = project.Id,
FileName = "../../../../README.md",
PackageName = "Packages",
PackageVersion = "1.0.0",
Status = "default",
};

var package1 = packagesClient.Publish(packagePublish);

// TODO: What assertions should be put here?
Assert.True(true);
}
}
}
3 changes: 3 additions & 0 deletions NGitLab/GitLabClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public class GitLabClient : IGitLabClient
{
private readonly API _api;

public IPackageClient Packages { get; }

public IUserClient Users { get; }

public IProjectClient Projects { get; }
Expand Down Expand Up @@ -73,6 +75,7 @@ public GitLabClient(string hostUrl, string userName, string password, RequestOpt
private GitLabClient(GitLabCredentials credentials, RequestOptions options)
{
_api = new API(credentials, options);
Packages = new PackageClient(_api);
Users = new UserClient(_api);
Projects = new ProjectClient(_api);
MergeRequests = new MergeRequestClient(_api);
Expand Down
2 changes: 2 additions & 0 deletions NGitLab/IGitLabClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
{
public interface IGitLabClient
{
IPackageClient Packages { get; }

IUserClient Users { get; }

IProjectClient Projects { get; }
Expand Down
14 changes: 14 additions & 0 deletions NGitLab/IPackageClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using NGitLab.Models;

namespace NGitLab
{
public interface IPackageClient
{
/// <summary>
/// Add a package file with the proposed information to the GitLab Generic Package Repository for the selected Project Id.
/// </summary>
/// <param name="packagePublish">The information about the package file to publish.</param>
/// <returns>The package if it was created. Null if not.</returns>
Package Publish(PackagePublish packagePublish);
}
}
19 changes: 17 additions & 2 deletions NGitLab/Impl/HttpRequestor.GitLabRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ private sealed class GitLabRequest

public string JsonData { get; }

public FileContent FileContent { get; }

public FormDataContent FormData { get; }

private MethodType Method { get; }
Expand Down Expand Up @@ -60,7 +62,11 @@ public GitLabRequest(Uri url, MethodType method, object data, string apiToken, R
Headers.Add("User-Agent", options.UserAgent);
}

if (data is FormDataContent formData)
if (data is FileContent fileContent)
{
FileContent = fileContent;
}
else if (data is FormDataContent formData)
{
FormData = formData;
}
Expand Down Expand Up @@ -165,7 +171,11 @@ private HttpWebRequest CreateRequest(RequestOptions options)

if (HasOutput)
{
if (FormData != null)
if (FileContent != null)
{
AddFileContent(request, options);
}
else if (FormData != null)
{
AddFileData(request, options);
}
Expand All @@ -182,6 +192,11 @@ private HttpWebRequest CreateRequest(RequestOptions options)
return request;
}

private void AddFileContent(HttpWebRequest request, RequestOptions options)
{
FileContent.Stream.CopyTo(options.GetRequestStream(request));
}

private void AddJsonData(HttpWebRequest request, RequestOptions options)
{
request.ContentType = "application/json";
Expand Down
36 changes: 36 additions & 0 deletions NGitLab/Impl/PackageClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Globalization;
using System.IO;
using NGitLab.Models;

namespace NGitLab.Impl
{
public class PackageClient : IPackageClient
{
private const string PublishPackageUrl = "/projects/{0}/packages/generic/{1}/{2}/{3}?status={4}&select=package_file";

private readonly API _api;

public PackageClient(API api)
{
_api = api;
}

public Package Publish(PackagePublish packagePublish)
{
var fullFilePath = Path.GetFullPath(packagePublish.FileName);

if (!File.Exists(fullFilePath))
{
throw new InvalidOperationException("Can't find file!");
}

var formData = new FileContent(File.OpenRead(fullFilePath));
var packageFile = new FileInfo(fullFilePath);

return _api.Put().With(formData).To<Package>(string.Format(CultureInfo.InvariantCulture,
PublishPackageUrl, packagePublish.ProjectId, packagePublish.PackageName, packagePublish.PackageVersion,
packageFile.Name, packagePublish.Status));
}
}
}
17 changes: 17 additions & 0 deletions NGitLab/Models/FileContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.IO;

namespace NGitLab.Models
{
public sealed class FileContent
{
public FileContent(Stream stream)
{
Stream = stream;
}

/// <summary>
/// The stream to be uploaded.
/// </summary>
public Stream Stream { get; }
}
}
76 changes: 76 additions & 0 deletions NGitLab/Models/Package.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.ComponentModel;
using System.Text.Json.Serialization;
using NGitLab.Impl.Json;

namespace NGitLab.Models
{
public class Package
{
[EditorBrowsable(EditorBrowsableState.Never)]
[JsonIgnore]
public int Id;

[JsonPropertyName("package_id")]
public int PackageId;

[JsonPropertyName("created_at")]
[JsonConverter(typeof(DateOnlyConverter))]
public DateTime CreatedAt;

[JsonPropertyName("updated_at")]
[JsonConverter(typeof(DateOnlyConverter))]
public DateTime? UpdatedAt;

[JsonPropertyName("size")]
public int Size;

[JsonPropertyName("file_store")]
public int FileStore;

[JsonPropertyName("file_md5")]
public string FileMD5;

[JsonPropertyName("file_sha1")]
public string FileSHA1;

[JsonPropertyName("file_sha256")]
public string FileSHA256;

[JsonPropertyName("file_name")]
public string FileName;

[JsonPropertyName("verification_retry_at")]
[JsonConverter(typeof(DateOnlyConverter))]
public DateTime? VerificationRetryAt;

[JsonPropertyName("verified_at")]
[JsonConverter(typeof(DateOnlyConverter))]
public DateTime? VerifiedAt;

[JsonPropertyName("verification_failure")]
public string VerificationFailure;

[JsonPropertyName("verification_retry_count")]
public string VerificationRetryCount;

[JsonPropertyName("verification_checksum")]
public string VerificationChecksum;

[JsonPropertyName("verification_state")]
public int VerificationState;

[JsonPropertyName("verification_started_at")]
[JsonConverter(typeof(DateOnlyConverter))]
public DateTime? VerificationStartedAt;

[JsonPropertyName("new_file_path")]
public string NewFilePath;

[JsonPropertyName("status")]
public string Status;

[JsonPropertyName("file")]
public PackageFile File;
}
}
10 changes: 10 additions & 0 deletions NGitLab/Models/PackageFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Text.Json.Serialization;

namespace NGitLab.Models
{
public class PackageFile
{
[JsonPropertyName("url")]
public string Url;
}
}
30 changes: 30 additions & 0 deletions NGitLab/Models/PackagePublish.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;

namespace NGitLab.Models
{
public class PackagePublish
{
[Required]
[JsonPropertyName("id")]
public int ProjectId;

[Required]
[JsonPropertyName("package_name")]
public string PackageName;

[Required]
[JsonPropertyName("package_version")]
public string PackageVersion;

[Required]
[JsonPropertyName("file_name")]
public string FileName;

[JsonPropertyName("status")]
public string Status;

[JsonPropertyName("select")]
public string Select;
}
}

0 comments on commit e356b33

Please sign in to comment.