Skip to content

Commit e356b33

Browse files
committed
Ability to upload to Generic Packages Repository
1 parent a6333c1 commit e356b33

12 files changed

+257
-2
lines changed

Diff for: NGitLab.Mock/Clients/GitLabClient.cs

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public GitLabClient(ClientContext context)
1313

1414
public IGroupsClient Groups => new GroupClient(Context);
1515

16+
public IPackageClient Packages => new PackageClient(Context);
17+
1618
public IUserClient Users => new UserClient(Context);
1719

1820
public IProjectClient Projects => new ProjectClient(Context);

Diff for: NGitLab.Mock/Clients/PackageClient.cs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using NGitLab.Models;
2+
3+
namespace NGitLab.Mock.Clients
4+
{
5+
internal sealed class PackageClient : ClientBase, IPackageClient
6+
{
7+
public PackageClient(ClientContext context)
8+
: base(context)
9+
{
10+
}
11+
12+
public Package Publish(PackagePublish packagePublish)
13+
{
14+
throw new System.NotImplementedException();
15+
}
16+
}
17+
}

Diff for: NGitLab.Tests/PackageTests.cs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Threading.Tasks;
2+
using NGitLab.Models;
3+
using NGitLab.Tests.Docker;
4+
using NUnit.Framework;
5+
6+
namespace NGitLab.Tests
7+
{
8+
public class PackageTests
9+
{
10+
[Test]
11+
[NGitLabRetry]
12+
public async Task Test_publish_package()
13+
{
14+
using var context = await GitLabTestContext.CreateAsync();
15+
var project = context.CreateProject();
16+
var packagesClient = context.Client.Packages;
17+
18+
var packagePublish = new PackagePublish
19+
{
20+
ProjectId = project.Id,
21+
FileName = "../../../../README.md",
22+
PackageName = "Packages",
23+
PackageVersion = "1.0.0",
24+
Status = "default",
25+
};
26+
27+
var package1 = packagesClient.Publish(packagePublish);
28+
29+
// TODO: What assertions should be put here?
30+
Assert.True(true);
31+
}
32+
}
33+
}

Diff for: NGitLab/GitLabClient.cs

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ public class GitLabClient : IGitLabClient
88
{
99
private readonly API _api;
1010

11+
public IPackageClient Packages { get; }
12+
1113
public IUserClient Users { get; }
1214

1315
public IProjectClient Projects { get; }
@@ -73,6 +75,7 @@ public GitLabClient(string hostUrl, string userName, string password, RequestOpt
7375
private GitLabClient(GitLabCredentials credentials, RequestOptions options)
7476
{
7577
_api = new API(credentials, options);
78+
Packages = new PackageClient(_api);
7679
Users = new UserClient(_api);
7780
Projects = new ProjectClient(_api);
7881
MergeRequests = new MergeRequestClient(_api);

Diff for: NGitLab/IGitLabClient.cs

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
{
33
public interface IGitLabClient
44
{
5+
IPackageClient Packages { get; }
6+
57
IUserClient Users { get; }
68

79
IProjectClient Projects { get; }

Diff for: NGitLab/IPackageClient.cs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using NGitLab.Models;
2+
3+
namespace NGitLab
4+
{
5+
public interface IPackageClient
6+
{
7+
/// <summary>
8+
/// Add a package file with the proposed information to the GitLab Generic Package Repository for the selected Project Id.
9+
/// </summary>
10+
/// <param name="packagePublish">The information about the package file to publish.</param>
11+
/// <returns>The package if it was created. Null if not.</returns>
12+
Package Publish(PackagePublish packagePublish);
13+
}
14+
}

Diff for: NGitLab/Impl/HttpRequestor.GitLabRequest.cs

+17-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ private sealed class GitLabRequest
2525

2626
public string JsonData { get; }
2727

28+
public FileContent FileContent { get; }
29+
2830
public FormDataContent FormData { get; }
2931

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

63-
if (data is FormDataContent formData)
65+
if (data is FileContent fileContent)
66+
{
67+
FileContent = fileContent;
68+
}
69+
else if (data is FormDataContent formData)
6470
{
6571
FormData = formData;
6672
}
@@ -165,7 +171,11 @@ private HttpWebRequest CreateRequest(RequestOptions options)
165171

166172
if (HasOutput)
167173
{
168-
if (FormData != null)
174+
if (FileContent != null)
175+
{
176+
AddFileContent(request, options);
177+
}
178+
else if (FormData != null)
169179
{
170180
AddFileData(request, options);
171181
}
@@ -182,6 +192,11 @@ private HttpWebRequest CreateRequest(RequestOptions options)
182192
return request;
183193
}
184194

195+
private void AddFileContent(HttpWebRequest request, RequestOptions options)
196+
{
197+
FileContent.Stream.CopyTo(options.GetRequestStream(request));
198+
}
199+
185200
private void AddJsonData(HttpWebRequest request, RequestOptions options)
186201
{
187202
request.ContentType = "application/json";

Diff for: NGitLab/Impl/PackageClient.cs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Globalization;
3+
using System.IO;
4+
using NGitLab.Models;
5+
6+
namespace NGitLab.Impl
7+
{
8+
public class PackageClient : IPackageClient
9+
{
10+
private const string PublishPackageUrl = "/projects/{0}/packages/generic/{1}/{2}/{3}?status={4}&select=package_file";
11+
12+
private readonly API _api;
13+
14+
public PackageClient(API api)
15+
{
16+
_api = api;
17+
}
18+
19+
public Package Publish(PackagePublish packagePublish)
20+
{
21+
var fullFilePath = Path.GetFullPath(packagePublish.FileName);
22+
23+
if (!File.Exists(fullFilePath))
24+
{
25+
throw new InvalidOperationException("Can't find file!");
26+
}
27+
28+
var formData = new FileContent(File.OpenRead(fullFilePath));
29+
var packageFile = new FileInfo(fullFilePath);
30+
31+
return _api.Put().With(formData).To<Package>(string.Format(CultureInfo.InvariantCulture,
32+
PublishPackageUrl, packagePublish.ProjectId, packagePublish.PackageName, packagePublish.PackageVersion,
33+
packageFile.Name, packagePublish.Status));
34+
}
35+
}
36+
}

Diff for: NGitLab/Models/FileContent.cs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.IO;
2+
3+
namespace NGitLab.Models
4+
{
5+
public sealed class FileContent
6+
{
7+
public FileContent(Stream stream)
8+
{
9+
Stream = stream;
10+
}
11+
12+
/// <summary>
13+
/// The stream to be uploaded.
14+
/// </summary>
15+
public Stream Stream { get; }
16+
}
17+
}

Diff for: NGitLab/Models/Package.cs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Text.Json.Serialization;
4+
using NGitLab.Impl.Json;
5+
6+
namespace NGitLab.Models
7+
{
8+
public class Package
9+
{
10+
[EditorBrowsable(EditorBrowsableState.Never)]
11+
[JsonIgnore]
12+
public int Id;
13+
14+
[JsonPropertyName("package_id")]
15+
public int PackageId;
16+
17+
[JsonPropertyName("created_at")]
18+
[JsonConverter(typeof(DateOnlyConverter))]
19+
public DateTime CreatedAt;
20+
21+
[JsonPropertyName("updated_at")]
22+
[JsonConverter(typeof(DateOnlyConverter))]
23+
public DateTime? UpdatedAt;
24+
25+
[JsonPropertyName("size")]
26+
public int Size;
27+
28+
[JsonPropertyName("file_store")]
29+
public int FileStore;
30+
31+
[JsonPropertyName("file_md5")]
32+
public string FileMD5;
33+
34+
[JsonPropertyName("file_sha1")]
35+
public string FileSHA1;
36+
37+
[JsonPropertyName("file_sha256")]
38+
public string FileSHA256;
39+
40+
[JsonPropertyName("file_name")]
41+
public string FileName;
42+
43+
[JsonPropertyName("verification_retry_at")]
44+
[JsonConverter(typeof(DateOnlyConverter))]
45+
public DateTime? VerificationRetryAt;
46+
47+
[JsonPropertyName("verified_at")]
48+
[JsonConverter(typeof(DateOnlyConverter))]
49+
public DateTime? VerifiedAt;
50+
51+
[JsonPropertyName("verification_failure")]
52+
public string VerificationFailure;
53+
54+
[JsonPropertyName("verification_retry_count")]
55+
public string VerificationRetryCount;
56+
57+
[JsonPropertyName("verification_checksum")]
58+
public string VerificationChecksum;
59+
60+
[JsonPropertyName("verification_state")]
61+
public int VerificationState;
62+
63+
[JsonPropertyName("verification_started_at")]
64+
[JsonConverter(typeof(DateOnlyConverter))]
65+
public DateTime? VerificationStartedAt;
66+
67+
[JsonPropertyName("new_file_path")]
68+
public string NewFilePath;
69+
70+
[JsonPropertyName("status")]
71+
public string Status;
72+
73+
[JsonPropertyName("file")]
74+
public PackageFile File;
75+
}
76+
}

Diff for: NGitLab/Models/PackageFile.cs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace NGitLab.Models
4+
{
5+
public class PackageFile
6+
{
7+
[JsonPropertyName("url")]
8+
public string Url;
9+
}
10+
}

Diff for: NGitLab/Models/PackagePublish.cs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.ComponentModel.DataAnnotations;
2+
using System.Text.Json.Serialization;
3+
4+
namespace NGitLab.Models
5+
{
6+
public class PackagePublish
7+
{
8+
[Required]
9+
[JsonPropertyName("id")]
10+
public int ProjectId;
11+
12+
[Required]
13+
[JsonPropertyName("package_name")]
14+
public string PackageName;
15+
16+
[Required]
17+
[JsonPropertyName("package_version")]
18+
public string PackageVersion;
19+
20+
[Required]
21+
[JsonPropertyName("file_name")]
22+
public string FileName;
23+
24+
[JsonPropertyName("status")]
25+
public string Status;
26+
27+
[JsonPropertyName("select")]
28+
public string Select;
29+
}
30+
}

0 commit comments

Comments
 (0)