Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
569 changes: 437 additions & 132 deletions .editorconfig

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions .github/workflows/update-dependencies-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ name: Update Dependencies Tests
on:
pull_request:
paths:
- '.editorconfig'
- 'Directory.Build.props'
- 'Microsoft.DotNet.Docker.slnx'
- 'eng/update-dependencies/**'
- 'tests/UpdateDependencies.Tests/**'
- 'eng/shared/**'
- 'tests/**'
- '!tests/Microsoft.DotNet.Docker.Tests/TestAppArtifacts/**'
- '.github/workflows/update-dependencies-tests.yml'

permissions: {}
Expand All @@ -28,13 +33,16 @@ jobs:
- name: Restore dependencies
run: >
dotnet restore
tests/UpdateDependencies.Tests/UpdateDependencies.Tests.csproj
Microsoft.DotNet.Docker.slnx
--verbosity normal

- name: Build tests
- name: Verify formatting
run: dotnet format Microsoft.DotNet.Docker.slnx --no-restore --verify-no-changes

- name: Build solution
run: >
dotnet build
tests/UpdateDependencies.Tests/UpdateDependencies.Tests.csproj
Microsoft.DotNet.Docker.slnx
--no-restore

- name: Run tests
Expand Down
9 changes: 9 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project>
<PropertyGroup>
<AnalysisMode>Recommended</AnalysisMode>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<!-- IDE0005 (remove unnecessary using directives) requires XML documentation processing. -->
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
</Project>
36 changes: 18 additions & 18 deletions README.aspnet.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions eng/pipelines/dotnet-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ extends:
stagesTemplateParameters:
versionsRepoRef: VersionsRepo
sourceBuildPipelineRunId: ${{ parameters.sourceBuildPipelineRunId }}
poolPriority: High
noCache: ${{ parameters.noCache }}
additionalServiceConnections:
- name: $(kusto.serviceConnectionName)
Expand Down
5 changes: 5 additions & 0 deletions eng/pipelines/jobs/update-dependency.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ parameters:
- name: dependencyName
type: string
default: ""
- name: poolPriority
type: string
default: ""
- name: updateSteps
type: stepList
default: []
Expand All @@ -13,6 +16,8 @@ jobs:
name: $(default1ESInternalPoolName)
image: $(default1ESInternalPoolImage)
os: linux
${{ if ne(parameters.poolPriority, '') }}:
demands: Priority -equals ${{ parameters.poolPriority }}
steps:
- checkout: self
fetchDepth: 0
Expand Down
6 changes: 6 additions & 0 deletions eng/pipelines/pipelines/sync-internal-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ parameters:
- name: targetBranch
type: string

- name: poolPriority
type: string
default: ""

extends:
template: /eng/docker-tools/templates/1es.yml@self
parameters:
Expand All @@ -31,6 +35,8 @@ extends:
name: $(default1ESInternalPoolName)
image: $(default1ESInternalPoolImage)
os: linux
${{ if ne(parameters.poolPriority, '') }}:
demands: Priority -equals ${{ parameters.poolPriority }}

steps:
- checkout: self
Expand Down
5 changes: 5 additions & 0 deletions eng/pipelines/pipelines/update-dependencies-internal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ parameters:
type: string
default: ""

- name: poolPriority
type: string
default: ""

extends:
template: /eng/docker-tools/templates/1es.yml@self
parameters:
Expand All @@ -31,6 +35,7 @@ extends:
- template: /eng/pipelines/jobs/update-dependency.yml@self
parameters:
dependencyName: dotnet
poolPriority: ${{ parameters.poolPriority }}
updateSteps:
- ${{ if eq(parameters.stageContainers, '') }}:
- "stageContainers parameter must not be empty.": error
Expand Down
1 change: 1 addition & 0 deletions eng/pipelines/release-promotion-official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ extends:
stagesTemplate: /eng/pipelines/stages/publish.yml@self
stagesTemplateParameters:
versionsRepoRef: VersionsRepo
poolPriority: High
isStandalonePublish: true
# Whenever staged images are published, we need to override the commit SHA since they were
# staged from an earlier, internal commit. We want the image info's commit URLs to point to
Expand Down
1 change: 1 addition & 0 deletions eng/pipelines/release-staging-official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extends:
stagesTemplate: /eng/pipelines/stages/build-and-test.yml@self
stagesTemplateParameters:
isStandaloneBuild: true
poolPriority: High
versionsRepoRef: VersionsRepo
sourceBuildPipelineRunId: ${{ parameters.sourceBuildPipelineRunId }}
noCache: ${{ parameters.noCache }}
Expand Down
5 changes: 5 additions & 0 deletions eng/pipelines/stages/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ parameters:
- name: sourceBuildPipelineRunId
type: string

- name: poolPriority
type: string
default: ""

- name: noCache
type: boolean
default: false
Expand Down Expand Up @@ -47,6 +51,7 @@ stages:
internalProjectName: ${{ parameters.internalProjectName }}
publicProjectName: ${{ parameters.publicProjectName }}
sourceBuildPipelineRunId: ${{ parameters.sourceBuildPipelineRunId }}
poolPriority: ${{ parameters.poolPriority }}
noCache: ${{ parameters.noCache }}
versionsRepoRef: ${{ parameters.versionsRepoRef }}
storageAccountServiceConnection: ${{ parameters.storageAccountServiceConnection }}
Expand Down
6 changes: 6 additions & 0 deletions eng/pipelines/stages/build-test-publish-repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ parameters:
type: boolean
default: false

- name: poolPriority
type: string
default: ""

# Additional service connections needed by this pipeline that are not included
# in the publishConfig.
- name: additionalServiceConnections
Expand All @@ -41,6 +45,7 @@ stages:
versionsRepoRef: ${{ parameters.versionsRepoRef }}
sourceBuildPipelineRunId: ${{ parameters.sourceBuildPipelineRunId }}
noCache: ${{ parameters.noCache }}
poolPriority: ${{ parameters.poolPriority }}

- template: /eng/pipelines/stages/publish.yml@self
parameters:
Expand All @@ -50,3 +55,4 @@ stages:
versionsRepoRef: ${{ parameters.versionsRepoRef }}
sourceBuildPipelineRunId: ${{ parameters.sourceBuildPipelineRunId }}
additionalServiceConnections: ${{ parameters.additionalServiceConnections }}
poolPriority: ${{ parameters.poolPriority }}
4 changes: 4 additions & 0 deletions eng/pipelines/stages/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ parameters:
- name: linuxAmd64Pool
type: string
default: ""
- name: poolPriority
type: string
default: ""
- name: isStandalonePublish
type: boolean
default: false
Expand Down Expand Up @@ -45,6 +48,7 @@ stages:
isStandalonePublish: ${{ parameters.isStandalonePublish }}
additionalServiceConnections: ${{ parameters.additionalServiceConnections }}
pool: ${{ parameters.linuxAmd64Pool }}
poolPriority: ${{ parameters.poolPriority }}
customPublishInitSteps:
- ${{ parameters.customPublishInitSteps }}
- template: /eng/pipelines/steps/set-public-source-branch-var.yml@self
Expand Down
1 change: 1 addition & 0 deletions eng/pipelines/sync-internal-release-official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ extends:
targetBranch: "internal/$(Build.SourceBranch)"
# Service connection used to push new branches and submit pull requests.
serviceConnection: "$(updateDepsInt.serviceConnectionName)"
poolPriority: High
1 change: 1 addition & 0 deletions eng/pipelines/update-dependencies-internal-official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ extends:
stagingStorageAccount: "dotnetstage"
targetBranch: "$(targetBranch)"
gitServiceConnectionName: "$(updateDepsInt.serviceConnectionName)"
poolPriority: High
5 changes: 0 additions & 5 deletions eng/shared/.editorconfig

This file was deleted.

12 changes: 7 additions & 5 deletions eng/shared/DotNetVersion.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Globalization;
using System.Text.RegularExpressions;
using NuGet.Versioning;

#pragma warning disable CA1716 // Avoid language keywords in namespaces: this shared code is consumed only by C# projects.
namespace Microsoft.DotNet.Docker.Shared;
#pragma warning restore CA1716

/// <summary>
/// Represents the version of a .NET build artifact.
Expand All @@ -31,7 +33,7 @@ public sealed partial class DotNetVersion(SemanticVersion version) : SemanticVer
// SemanticVersion only handles full, strict semantic versions.
// If we can parse it as a full semantic version, use that. It resolves
// full build versions correctly including prerelease suffixes (e.g. '-preview.7')
if (SemanticVersion.TryParse(versionString, out var fullSemanticVersion))
if (TryParse(versionString, out SemanticVersion? fullSemanticVersion))
{
return new DotNetVersion(fullSemanticVersion);
}
Expand All @@ -42,9 +44,9 @@ public sealed partial class DotNetVersion(SemanticVersion version) : SemanticVer
// we don't need to account for that in our parsing.
// Don't use System.Version.Parse here, because it defaults unmatched
// minor/patch versions to -1, whereas we want them to default to 0.
var matchGroups = MajorMinorVersionRegex.Match(versionString).Groups;
int major = int.Parse(matchGroups["major"].Value);
int minor = int.TryParse(matchGroups["minor"].Value.TrimStart('.'), out int minorValue) ? minorValue : 0;
GroupCollection matchGroups = MajorMinorVersionRegex.Match(versionString).Groups;
int major = int.Parse(matchGroups["major"].Value, CultureInfo.InvariantCulture);
int minor = int.TryParse(matchGroups["minor"].Value.TrimStart('.'), NumberStyles.Integer, CultureInfo.InvariantCulture, out int minorValue) ? minorValue : 0;
return new DotNetVersion(new SemanticVersion(major, minor, 0));
}

Expand Down
4 changes: 0 additions & 4 deletions eng/shared/Microsoft.DotNet.Docker.Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<RootNamespace>Microsoft.DotNet.Docker.Shared</RootNamespace>

<!-- Enables CS1591, which lets us know when public members aren't documented -->
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
Expand Down
8 changes: 4 additions & 4 deletions eng/update-dependencies/AzdoAuthProvider.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Maestro.Common.AzureDevOpsTokens;
using Microsoft.DotNet.Internal.AzureDevOps.Authentication;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.Services.Common;
Expand Down Expand Up @@ -55,9 +55,9 @@ public string AccessToken
/// </returns>
public VssConnection GetVssConnection(string azdoOrg)
{
var baseUrl = new Uri(azdoOrg);
var credential = new VssBasicCredential(userName: string.Empty, password: AccessToken);
var connection = new VssConnection(baseUrl, credential);
Uri baseUrl = new Uri(azdoOrg);
VssBasicCredential credential = new VssBasicCredential(userName: string.Empty, password: AccessToken);
VssConnection connection = new VssConnection(baseUrl, credential);
return connection;
}
}
Expand Down
2 changes: 1 addition & 1 deletion eng/update-dependencies/AzdoHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ internal class AzdoHttpClient(IAzdoAuthProvider azdoAuthProvider, HttpClient htt
{
public async Task<HttpResponseMessage> GetAsync(string requestUri, CancellationToken ct = default)
{
using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
request.Headers.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(
Expand Down
25 changes: 11 additions & 14 deletions eng/update-dependencies/BuildAssetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,37 @@ public async Task<string> GetAssetTextContentsAsync(Asset asset)
string url = ResolveAssetUrl(asset);
try
{
_logger.LogInformation("Fetching contents from {url}", url);
var response = await _httpClient.GetAsync(url);
_logger.LogInformation("Fetching contents from {Url}", url);
HttpResponseMessage response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
_logger.LogInformation(
"""
Successfully fetched contents from {url}:
{content}
Successfully fetched contents from {Url}:
{Content}
""",
url, content);
// Remove trailing newlines
return content.Trim();
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to fetch contents from {url}", url);
_logger.LogError(ex, "Failed to fetch contents from {Url}", url);
throw;
}
}

private string ResolveAssetUrl(Asset asset)
{
var blobStorageLocations = asset.Locations.Where(l => l.Location.Contains("blob.core.windows.net"));
var azdoLocations = asset.Locations.Where(l => l.Location.Contains("dev.azure.com"));
IEnumerable<AssetLocation> blobStorageLocations = asset.Locations.Where(l => l.Location.Contains("blob.core.windows.net"));
IEnumerable<AssetLocation> azdoLocations = asset.Locations.Where(l => l.Location.Contains("dev.azure.com"));

string allLocations =
string.Join(Environment.NewLine, asset.Locations.Select(l => $"Type: {l.Type}; Url: {l.Location}"));
_logger.LogInformation(
"""
Asset {asset.Name} has {asset.Locations.Count} locations:
{allLocations}
Asset {AssetName} has {LocationCount} locations:
{AllLocations}
""",
asset.Name, asset.Locations.Count, allLocations);

Expand All @@ -63,12 +63,9 @@ private string ResolveAssetUrl(Asset asset)
?? throw new InvalidOperationException(FormatErrorMessage(asset, "does not have any valid locations"));

string url = $"{bestLocation.Location}/{asset.Name}";
_logger.LogInformation("Using location {url}", url);
_logger.LogInformation("Using location {Url}", url);
return url;
}

private static string FormatErrorMessage(Asset asset, string message)
{
return $"Build {asset.BuildId} Asset {asset.Name} (version {asset.Version}) {message}";
}
private static string FormatErrorMessage(Asset asset, string message) => $"Build {asset.BuildId} Asset {asset.Name} (version {asset.Version}) {message}";
}
2 changes: 1 addition & 1 deletion eng/update-dependencies/BuildLabelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ internal sealed class BuildLabelService(TextWriter output) : IBuildLabelService
/// <inheritdoc />
public void AddBuildTags(params IEnumerable<string> tags)
{
foreach (var tag in tags)
foreach (string tag in tags)
{
output.WriteLine($"##vso[build.addbuildtag]{tag}");
}
Expand Down
23 changes: 13 additions & 10 deletions eng/update-dependencies/ChecksumHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;

Expand All @@ -17,18 +21,17 @@ internal static class ChecksumHelper
{
if (response.IsSuccessStatusCode)
{
using (Stream httpStream = await response.Content.ReadAsStreamAsync(cancellationToken))
using (SHA512 hash = SHA512.Create())
{
byte[] hashedInputBytes = hash.ComputeHash(httpStream);
using Stream httpStream = await response.Content.ReadAsStreamAsync(cancellationToken);
using SHA512 hash = SHA512.Create();
byte[] hashedInputBytes = hash.ComputeHash(httpStream);

StringBuilder stringBuilder = new(128);
foreach (byte b in hashedInputBytes)
{
stringBuilder.Append(b.ToString("X2"));
}
sha = stringBuilder.ToString();
StringBuilder stringBuilder = new(128);
foreach (byte b in hashedInputBytes)
{
stringBuilder.Append(b.ToString("X2", CultureInfo.InvariantCulture));
}

sha = stringBuilder.ToString();
}
else
{
Expand Down
Loading
Loading