Skip to content

Commit

Permalink
Nullability and code coverage... we'll see how it goes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaben committed Aug 13, 2024
1 parent 5efff31 commit 3e87bb2
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 30 deletions.
54 changes: 53 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,59 @@ jobs:
useConfigFile: true

- name: Run Tests
run: dotnet test
run: dotnet test --logger trx --collect:"XPlat Code Coverage"

- name: Combine Coverage Reports # This is because one report is produced per project, and we want one result for all of them.
uses: danielpalme/[email protected]
with:
reports: "**/*.cobertura.xml" # REQUIRED # The coverage reports that should be parsed (separated by semicolon). Globbing is supported.
targetdir: "${{ github.workspace }}" # REQUIRED # The directory where the generated report should be saved.
reporttypes: "Cobertura" # The output formats and scope (separated by semicolon) Values: Badges, Clover, Cobertura, CsvSummary, Html, Html_Dark, Html_Light, Html_BlueRed, HtmlChart, HtmlInline, HtmlInline_AzurePipelines, HtmlInline_AzurePipelines_Dark, HtmlInline_AzurePipelines_Light, HtmlSummary, JsonSummary, Latex, LatexSummary, lcov, MarkdownSummary, MarkdownSummaryGithub, MarkdownDeltaSummary, MHtml, PngChart, SonarQube, TeamCitySummary, TextSummary, TextDeltaSummary, Xml, XmlSummary
verbosity: "Info" # The verbosity level of the log messages. Values: Verbose, Info, Warning, Error, Off
title: "Code Coverage" # Optional title.
tag: "${{ github.run_number }}_${{ github.run_id }}" # Optional tag or build version.
customSettings: "" # Optional custom settings (separated by semicolon). See: https://github.com/danielpalme/ReportGenerator/wiki/Settings.
toolpath: "reportgeneratortool" # Default directory for installing the dotnet tool.

- name: Upload Combined Coverage XML
uses: actions/upload-artifact@v4
with:
name: coverage
path: ${{ github.workspace }}/Cobertura.xml
retention-days: 5

- name: Publish Code Coverage Report
uses: irongut/[email protected]
with:
filename: "Cobertura.xml"
badge: true
fail_below_min: false # just informative for now
format: markdown
hide_branch_rate: false
hide_complexity: false
indicators: true
output: both
thresholds: "10 30"

- name: Add Coverage PR Comment
uses: marocchino/sticky-pull-request-comment@v2
if: github.event_name == 'pull_request'
with:
recreate: true
path: code-coverage-results.md

- name: Upload Test Result Files
uses: actions/upload-artifact@v4
with:
name: test-results
path: ${{ github.workspace }}/**/TestResults/**/*
retention-days: 5

- name: Publish Test Results
uses: EnricoMi/[email protected]
if: always()
with:
trx_files: "${{ github.workspace }}/**/*.trx"

- name: Pack
run: dotnet pack src/Docker.Registry.DotNet -c Release -p:PackageVersion=${{ steps.gitversion.outputs.nuGetVersion }} -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public override async Task Authenticate(
bearerBits.Service,
bearerBits.Scope);

if (token?.Token == null)
{
throw new ArgumentNullException(nameof(token.Token), "Authorization token cannot be null");
}

//Set the header
request.Headers.Authorization = new AuthenticationHeaderValue(Schema, token.Token);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Docker.Registry.DotNet.Application.Authentication;

internal static class AuthenticateParser
{
public static IDictionary<string, string> Parse(string value)
public static IDictionary<string, string?> Parse(string value)
{
//https://stackoverflow.com/questions/45516717/extracting-and-parsing-the-www-authenticate-header-from-httpresponsemessage-in/45516809#45516809
return SplitWWWAuthenticateHeader(value).ToDictionary(GetKey, GetValue);

Check warning on line 23 in src/Docker.Registry.DotNet/Application/Authentication/AuthenticateParser.cs

View workflow job for this annotation

GitHub Actions / build (8.x)

Nullability of reference types in value of type 'Dictionary<string, string>' doesn't match target type 'IDictionary<string, string?>'.

Check warning on line 23 in src/Docker.Registry.DotNet/Application/Authentication/AuthenticateParser.cs

View workflow job for this annotation

GitHub Actions / build (8.x)

Nullability of reference types in value of type 'Dictionary<string, string>' doesn't match target type 'IDictionary<string, string?>'.
Expand All @@ -27,9 +27,9 @@ private static IEnumerable<string> SplitWWWAuthenticateHeader(string value)
{
var builder = new StringBuilder();
var inQuotes = false;
for (var i = 0; i < value.Length; i++)

foreach (var charI in value)
{
var charI = value[i];
switch (charI)
{
case '\"':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@

namespace Docker.Registry.DotNet.Application.Authentication;

internal class ParsedAuthentication(string realm, string service, string scope)
internal class ParsedAuthentication(string? realm, string? service, string? scope)
{
public string Realm { get; } = realm;
public string? Realm { get; } = realm;

public string Service { get; } = service;
public string? Service { get; } = service;

public string Scope { get; } = scope;
public string? Scope { get; } = scope;
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public override async Task Authenticate(
scope,
username,
password);

if (token?.AccessToken == null)
{
throw new ArgumentNullException(nameof(token.AccessToken), "Authorization token cannot be null");
}

//Set the header
request.Headers.Authorization =
Expand Down
14 changes: 7 additions & 7 deletions src/Docker.Registry.DotNet/Application/OAuth/OAuthClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal class OAuthClient
private static readonly HttpClient _client = new();

private async Task<OAuthToken?> GetTokenInner(
string realm,
string? realm,
string? service,
string? scope,
string? username,
Expand Down Expand Up @@ -52,7 +52,7 @@ internal class OAuthClient
request = new HttpRequestMessage(HttpMethod.Post, realm)
{
Content = new FormUrlEncodedContent(
new Dictionary<string, string>
new Dictionary<string, string?>
{
{ "client_id", "Docker.Registry.DotNet" },
{ "grant_type", "password" },
Expand Down Expand Up @@ -94,17 +94,17 @@ internal class OAuthClient
}

public Task<OAuthToken?> GetToken(
string realm,
string service,
string scope,
string? realm,
string? service,
string? scope,
CancellationToken cancellationToken = default)
{
return this.GetTokenInner(realm, service, scope, null, null, cancellationToken);
}

public Task<OAuthToken?> GetToken(
string realm,
string service,
string? realm,
string? service,
string? scope,
string username,
string password,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ public class GetImageManifestResult
{
internal GetImageManifestResult(string mediaType, ImageManifest manifest, string content)
{
this.Manifest = manifest;
this.Content = content;
this.MediaType = mediaType;
}
this.Manifest = manifest;
this.Content = content;
this.MediaType = mediaType;
}

public string DockerContentDigest { get; internal set; }
public string? DockerContentDigest { get; internal set; }

public string Etag { get; internal set; }
public string? Etag { get; internal set; }

public string MediaType { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ internal RegistryApiException(RegistryApiResponse<TBody> response)
Body = response.Body;
}

public TBody Body { get; }
public TBody? Body { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ public class ListRepositoryTagsResponse
public int Count { get; set; }

[JsonProperty("next")]
public string Next { get; set; }
public string? Next { get; set; }

[JsonProperty("previous")]
public string Previous { get; set; }
public string? Previous { get; set; }

[JsonProperty("results")]
public List<RepositoryTag> Tags { get; set; }
public List<RepositoryTag>? Tags { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,10 @@ public static string GetQueryString(this IDictionary<string, string[]> values)
v => $"{Uri.EscapeUriString(pair.Key)}={Uri.EscapeDataString(v)}"))));
}

public static TValue GetValueOrDefault<TKey, TValue>(
public static TValue? GetValueOrDefault<TKey, TValue>(
this IDictionary<TKey, TValue> dict,
TKey key)
{
if (dict.TryGetValue(key, out var value))
return value;

return default;
return dict.TryGetValue(key, out var value) ? value : default;
}
}

0 comments on commit 3e87bb2

Please sign in to comment.