diff --git a/.devops/workflows/Test_Devops_Build.yml b/.devops/workflows/Test_Devops_Build.yml index 6ffed4c0..bd6ab2fc 100644 --- a/.devops/workflows/Test_Devops_Build.yml +++ b/.devops/workflows/Test_Devops_Build.yml @@ -214,7 +214,7 @@ jobs: targetPath: "$(Build.BinariesDirectory)/DecSm.Atom.Tool.Tests" - - job: PushToNuget + - job: PushToNugetDevops dependsOn: [ TestProjects, PackProjects, PackTool, SetupBuildInfo ] pool: vmImage: ubuntu-latest @@ -307,8 +307,26 @@ jobs: artifact: DecSm.Atom.Tool-macos-latest path: "$(Build.ArtifactStagingDirectory)/DecSm.Atom.Tool" - - script: dotnet run --project _atom/_atom.csproj PushToNuget --skip --headless - name: PushToNuget + - task: DownloadPipelineArtifact@2 + displayName: DecSm.Atom.Tool + inputs: + artifact: DecSm.Atom.Tool-windows-latest + path: "$(Build.ArtifactStagingDirectory)/DecSm.Atom.Tool" + + - task: DownloadPipelineArtifact@2 + displayName: DecSm.Atom.Tool + inputs: + artifact: DecSm.Atom.Tool-ubuntu-latest + path: "$(Build.ArtifactStagingDirectory)/DecSm.Atom.Tool" + + - task: DownloadPipelineArtifact@2 + displayName: DecSm.Atom.Tool + inputs: + artifact: DecSm.Atom.Tool-macos-latest + path: "$(Build.ArtifactStagingDirectory)/DecSm.Atom.Tool" + + - script: dotnet run --project _atom/_atom.csproj PushToNugetDevops --skip --headless + name: PushToNugetDevops env: build-id: $(build-id) azure-vault-app-secret: $(AZURE_VAULT_APP_SECRET) diff --git a/.github/workflows/Dependabot - Auto Approve.yml b/.github/workflows/Dependabot - Auto Approve.yml new file mode 100644 index 00000000..2bf3b9f7 --- /dev/null +++ b/.github/workflows/Dependabot - Auto Approve.yml @@ -0,0 +1,36 @@ +name: Dependabot - Auto Approve + +permissions: { } +on: + workflow_dispatch: + pull_request: + branches: + - 'main' + +jobs: + + ApproveDependabotPr: + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + permissions: + id-token: write + pull-requests: write + steps: + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '10.0.x' + + - name: ApproveDependabotPr + id: ApproveDependabotPr + run: dotnet run --project _atom/_atom.csproj ApproveDependabotPr --skip --headless + env: + azure-vault-app-secret: ${{ secrets.AZURE_VAULT_APP_SECRET }} + azure-vault-address: ${{ vars.AZURE_VAULT_ADDRESS }} + azure-vault-tenant-id: ${{ vars.AZURE_VAULT_TENANT_ID }} + azure-vault-app-id: ${{ vars.AZURE_VAULT_APP_ID }} + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/DecSm.Atom.Module.AzureKeyVault/AzureKeySecretsProvider.cs b/DecSm.Atom.Module.AzureKeyVault/AzureKeySecretsProvider.cs index b5f2f94b..dba62402 100644 --- a/DecSm.Atom.Module.AzureKeyVault/AzureKeySecretsProvider.cs +++ b/DecSm.Atom.Module.AzureKeyVault/AzureKeySecretsProvider.cs @@ -191,7 +191,8 @@ private TokenCredential GetCredential(IAzureKeyVault definition) { string portString => int.TryParse(portString, out var parsedPort) ? parsedPort - : throw new InvalidOperationException($"Invalid port value for AzureVaultAuthPort: '{portString}'. Please provide a valid integer."), + : throw new InvalidOperationException( + $"Invalid port value for AzureVaultAuthPort: '{portString}'. Please provide a valid integer."), int portInt => portInt, _ => 0, }; diff --git a/DecSm.Atom.Module.AzureStorage/IAzureArtifactStorage.cs b/DecSm.Atom.Module.AzureStorage/IAzureArtifactStorage.cs index 59cfeed6..bdc1a8f9 100644 --- a/DecSm.Atom.Module.AzureStorage/IAzureArtifactStorage.cs +++ b/DecSm.Atom.Module.AzureStorage/IAzureArtifactStorage.cs @@ -8,7 +8,6 @@ /// enabling the build to both upload and download artifacts from Azure Blob Storage. /// [ConfigureHostBuilder] - public partial interface IAzureArtifactStorage : IStoreArtifact, IRetrieveArtifact { /// diff --git a/DecSm.Atom.Module.AzureStorage/_usings.cs b/DecSm.Atom.Module.AzureStorage/_usings.cs index 3bcaf96e..82dc00cf 100644 --- a/DecSm.Atom.Module.AzureStorage/_usings.cs +++ b/DecSm.Atom.Module.AzureStorage/_usings.cs @@ -2,7 +2,6 @@ global using Azure.Storage.Blobs; global using Azure.Storage.Blobs.Models; global using DecSm.Atom.Artifacts; -global using DecSm.Atom.Build.Definition; global using DecSm.Atom.BuildInfo; global using DecSm.Atom.Hosting; global using DecSm.Atom.Params; diff --git a/DecSm.Atom.Module.DevopsWorkflows.Tests/Workflows/DuplicateDependencyBuild.cs b/DecSm.Atom.Module.DevopsWorkflows.Tests/Workflows/DuplicateDependencyBuild.cs index 76fcfd6c..4745f604 100644 --- a/DecSm.Atom.Module.DevopsWorkflows.Tests/Workflows/DuplicateDependencyBuild.cs +++ b/DecSm.Atom.Module.DevopsWorkflows.Tests/Workflows/DuplicateDependencyBuild.cs @@ -16,7 +16,6 @@ public partial class DuplicateDependencyBuild : MinimalBuildDefinition, IDevopsW ]; } - [ConfigureHostBuilder] public partial interface IDuplicateDependencyTarget : IStoreArtifact, IRetrieveArtifact { diff --git a/DecSm.Atom.Module.GitVersion/GitVersionBuildVersionProvider.cs b/DecSm.Atom.Module.GitVersion/GitVersionBuildVersionProvider.cs index cf53cda0..f2f40c02 100644 --- a/DecSm.Atom.Module.GitVersion/GitVersionBuildVersionProvider.cs +++ b/DecSm.Atom.Module.GitVersion/GitVersionBuildVersionProvider.cs @@ -28,8 +28,6 @@ ILogger logger /// /// Thrown if the version information cannot be determined from GitVersion's output. /// - [field: AllowNull] - [field: MaybeNull] public SemVer Version { get diff --git a/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/DuplicateDependencyBuild.cs b/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/DuplicateDependencyBuild.cs index 54f95743..4ebd7354 100644 --- a/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/DuplicateDependencyBuild.cs +++ b/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/DuplicateDependencyBuild.cs @@ -16,7 +16,6 @@ public partial class DuplicateDependencyBuild : MinimalBuildDefinition, IGithubW ]; } - [ConfigureHostBuilder] public partial interface IDuplicateDependencyTarget : IStoreArtifact, IRetrieveArtifact { diff --git a/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/SnapshotImageBuild.cs b/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/SnapshotImageBuild.cs index 155d1ed7..3fc7ff0b 100644 --- a/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/SnapshotImageBuild.cs +++ b/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/SnapshotImageBuild.cs @@ -1,7 +1,7 @@ namespace DecSm.Atom.Module.GithubWorkflows.Tests.Workflows; [BuildDefinition] -public partial class SnapshotImageBuild : MinimalBuildDefinition, IGithubWorkflows, ICheckoutOptionTarget +public partial class SnapshotImageBuild : MinimalBuildDefinition, IGithubWorkflows, ISnapshotImageTarget { public override IReadOnlyList Workflows => [ @@ -10,7 +10,7 @@ public partial class SnapshotImageBuild : MinimalBuildDefinition, IGithubWorkflo Triggers = [ManualTrigger.Empty], Targets = [ - WorkflowTargets.CheckoutOptionTarget.WithOptions( + WorkflowTargets.SnapshotImageTarget.WithOptions( GithubSnapshotImageOption.Create(new("snapshot-image-test", "1.*.*"))), ], WorkflowTypes = [new GithubWorkflowType()], diff --git a/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/WorkflowTests.SnapshotImageBuild_GeneratesWorkflow.verified.txt b/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/WorkflowTests.SnapshotImageBuild_GeneratesWorkflow.verified.txt index aaf2502f..3867d92a 100644 --- a/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/WorkflowTests.SnapshotImageBuild_GeneratesWorkflow.verified.txt +++ b/DecSm.Atom.Module.GithubWorkflows.Tests/Workflows/WorkflowTests.SnapshotImageBuild_GeneratesWorkflow.verified.txt @@ -5,7 +5,7 @@ on: jobs: - CheckoutOptionTarget: + SnapshotImageTarget: runs-on: ubuntu-latest snapshot: image-name: snapshot-image-test @@ -17,6 +17,6 @@ jobs: with: fetch-depth: 0 - - name: CheckoutOptionTarget - id: CheckoutOptionTarget - run: dotnet run --project AtomTest/AtomTest.csproj CheckoutOptionTarget --skip --headless + - name: SnapshotImageTarget + id: SnapshotImageTarget + run: dotnet run --project AtomTest/AtomTest.csproj SnapshotImageTarget --skip --headless diff --git a/DecSm.Atom.Module.GithubWorkflows/Generation/GithubWorkflowWriter.cs b/DecSm.Atom.Module.GithubWorkflows/Generation/GithubWorkflowWriter.cs index 789d2bbc..fd6812bc 100644 --- a/DecSm.Atom.Module.GithubWorkflows/Generation/GithubWorkflowWriter.cs +++ b/DecSm.Atom.Module.GithubWorkflows/Generation/GithubWorkflowWriter.cs @@ -502,7 +502,9 @@ private void WriteStep(WorkflowModel workflow, WorkflowStepModel step, WorkflowJ ?.InformationalVersion ?? "", out var semVer)) - toolVersion = semVer; + toolVersion = + SemVer.Parse( + $"{semVer.Prefix}{(semVer.IsPreRelease ? $"-{semVer.PreRelease}" : string.Empty)}"); else throw new InvalidOperationException( "Failed to parse DecSm.Atom.Host assembly version as SemVer for syncing atom tool version"); @@ -518,12 +520,9 @@ private void WriteStep(WorkflowModel workflow, WorkflowStepModel step, WorkflowJ using (WriteSection("run: |")) { foreach (var feedToAdd in feedsToAdd) - if (syncAtomToolVersionToLibraryVersion) - WriteLine( - $"dotnet tool exec decsm.atom.tool@{toolVersion} -y -- nuget-add --name \"{feedToAdd.FeedName}\" --url \"{feedToAdd.FeedUrl}\""); - else - WriteLine( - $"dotnet tool exec decsm.atom.tool -y -- nuget-add --name \"{feedToAdd.FeedName}\" --url \"{feedToAdd.FeedUrl}\""); + WriteLine(syncAtomToolVersionToLibraryVersion + ? $"dotnet tool exec decsm.atom.tool@{toolVersion} -y -- nuget-add --name \"{feedToAdd.FeedName}\" --url \"{feedToAdd.FeedUrl}\"" + : $"dotnet tool exec decsm.atom.tool -y -- nuget-add --name \"{feedToAdd.FeedName}\" --url \"{feedToAdd.FeedUrl}\""); } WriteLine("shell: bash"); diff --git a/DecSm.Atom.Module.GithubWorkflows/Generation/Options/GithubTokenPermissionsOption.cs b/DecSm.Atom.Module.GithubWorkflows/Generation/Options/GithubTokenPermissionsOption.cs index 4ded9f07..08ceae25 100644 --- a/DecSm.Atom.Module.GithubWorkflows/Generation/Options/GithubTokenPermissionsOption.cs +++ b/DecSm.Atom.Module.GithubWorkflows/Generation/Options/GithubTokenPermissionsOption.cs @@ -101,7 +101,7 @@ public sealed record GithubTokenPermissionsOption : IWorkflowOption .Select(x => (x.Item1, x.Item2!)) .ToList(); - private string? GetTokenPermissionString(GithubTokenPermission? permission) => + private static string? GetTokenPermissionString(GithubTokenPermission? permission) => permission switch { GithubTokenPermission.None => "none", diff --git a/DecSm.Atom.Module.GithubWorkflows/Generation/Options/IGithubCustomStepOption.cs b/DecSm.Atom.Module.GithubWorkflows/Generation/Options/IGithubCustomStepOption.cs index a897c74b..86c403e6 100644 --- a/DecSm.Atom.Module.GithubWorkflows/Generation/Options/IGithubCustomStepOption.cs +++ b/DecSm.Atom.Module.GithubWorkflows/Generation/Options/IGithubCustomStepOption.cs @@ -3,11 +3,11 @@ namespace DecSm.Atom.Module.GithubWorkflows.Generation.Options; [PublicAPI] public interface IGithubCustomStepOption : IWorkflowOption { - bool IWorkflowOption.AllowMultiple => true; - GithubCustomStepOrder Order { get; } int Priority { get; } + bool IWorkflowOption.AllowMultiple => true; + void WriteStep(GithubStepWriter writer); } diff --git a/DecSm.Atom.SourceGenerators/Symbols.cs b/DecSm.Atom.SourceGenerators/Symbols.cs index 87333261..5e178b18 100644 --- a/DecSm.Atom.SourceGenerators/Symbols.cs +++ b/DecSm.Atom.SourceGenerators/Symbols.cs @@ -4,9 +4,6 @@ public static class Symbols { public const string BuildDefinitionAttribute = "DecSm.Atom.Build.Definition.BuildDefinitionAttribute"; - public const string GeneratedBuildDefinitionAttribute = - "DecSm.Atom.Build.Definition.GeneratedBuildDefinitionAttribute"; - public const string GenerateEntryPointAttribute = "DecSm.Atom.Hosting.GenerateEntryPointAttribute"; public const string GenerateInterfaceMembersAttribute = diff --git a/DecSm.Atom.Tests/ApiSurfaceTests/PublicApiSurfaceTests.VerifyPublicApiSurface.verified.txt b/DecSm.Atom.Tests/ApiSurfaceTests/PublicApiSurfaceTests.VerifyPublicApiSurface.verified.txt new file mode 100644 index 00000000..cf33c2db --- /dev/null +++ b/DecSm.Atom.Tests/ApiSurfaceTests/PublicApiSurfaceTests.VerifyPublicApiSurface.verified.txt @@ -0,0 +1,2832 @@ +[ + { + Name: DecSm.Atom.Args.CommandArg, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Name + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Args.CommandLineArgs, + Members: [ + { + Name: $ + }, + { + Name: Args + }, + { + Name: Commands + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: HasGen + }, + { + Name: HasHeadless + }, + { + Name: HasHelp + }, + { + Name: HasInteractive + }, + { + Name: HasProject + }, + { + Name: HasSkip + }, + { + Name: HasVerbose + }, + { + Name: IsValid + }, + { + Name: Params + }, + { + Name: ProjectName + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Args.GenArg, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Args.HeadlessArg, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Args.HelpArg, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Args.IArg + }, + { + Name: DecSm.Atom.Args.InteractiveArg, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Args.ParamArg, + Members: [ + { + Name: $ + }, + { + Name: ArgName + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ParamName + }, + { + Name: ParamValue + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Args.ProjectArg, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ProjectName + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Args.SkipArg, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Args.VerboseArg, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Artifacts.IArtifactProvider, + Members: [ + { + Name: Cleanup + }, + { + Name: GetStoredRunIdentifiers + }, + { + Name: RequiredParams + }, + { + Name: RetrieveArtifacts + }, + { + Name: StoreArtifacts + } + ] + }, + { + Name: DecSm.Atom.Artifacts.IAtomArtifactsParam, + Members: [ + { + Name: AtomArtifacts + } + ] + }, + { + Name: DecSm.Atom.Artifacts.IRetrieveArtifact, + Members: [ + { + Name: RetrieveArtifact + } + ] + }, + { + Name: DecSm.Atom.Artifacts.IStoreArtifact, + Members: [ + { + Name: StoreArtifact + } + ] + }, + { + Name: DecSm.Atom.Artifacts.UseCustomArtifactProvider, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Build.Definition.BuildDefinition + }, + { + Name: DecSm.Atom.Build.Definition.BuildDefinitionAttribute + }, + { + Name: DecSm.Atom.Build.Definition.DefinedParam, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Param + }, + { + Name: Required + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Build.Definition.GenerateInterfaceMembersAttribute + }, + { + Name: DecSm.Atom.Build.Definition.GenerateSolutionModelAttribute + }, + { + Name: DecSm.Atom.Build.Definition.IBuildDefinition, + Members: [ + { + Name: AccessParam + }, + { + Name: GlobalWorkflowOptions + }, + { + Name: ParamDefinitions + }, + { + Name: TargetDefinitions + }, + { + Name: Workflows + } + ] + }, + { + Name: DecSm.Atom.Build.Definition.MinimalBuildDefinition, + Members: [ + { + Name: AccessParam + }, + { + Name: GlobalWorkflowOptions + }, + { + Name: ParamDefinitions + }, + { + Name: Services + }, + { + Name: TargetDefinitions + }, + { + Name: Workflows + } + ] + }, + { + Name: DecSm.Atom.Build.Definition.Target, + Members: [ + { + Name: BeginInvoke + }, + { + Name: EndInvoke + }, + { + Name: Invoke + } + ] + }, + { + Name: DecSm.Atom.Build.Definition.TargetDefinition, + Members: [ + { + Name: ConsumedArtifacts + }, + { + Name: ConsumedVariables + }, + { + Name: ConsumesArtifact + }, + { + Name: ConsumesArtifact + }, + { + Name: ConsumesArtifacts + }, + { + Name: ConsumesArtifacts + }, + { + Name: ConsumesNoArtifacts + }, + { + Name: ConsumesNoVariables + }, + { + Name: ConsumesVariable + }, + { + Name: Dependencies + }, + { + Name: DependsOn + }, + { + Name: DependsOn + }, + { + Name: DependsOn + }, + { + Name: DescribedAs + }, + { + Name: Description + }, + { + Name: Executes + }, + { + Name: Executes + }, + { + Name: Executes + }, + { + Name: Extends + }, + { + Name: Hidden + }, + { + Name: IsHidden + }, + { + Name: Name + }, + { + Name: Params + }, + { + Name: ProducedArtifacts + }, + { + Name: ProducedVariables + }, + { + Name: ProducesArtifact + }, + { + Name: ProducesArtifacts + }, + { + Name: ProducesNoArtifacts + }, + { + Name: ProducesNoVariables + }, + { + Name: ProducesVariable + }, + { + Name: RequiresParam + }, + { + Name: Tasks + }, + { + Name: UsesParam + } + ] + }, + { + Name: DecSm.Atom.Build.Definition.TargetDefinitionExtensions, + Members: [ + { + Name: DependsOn + }, + { + Name: DependsOn + }, + { + Name: DependsOn + }, + { + Name: DependsOn + } + ] + }, + { + Name: DecSm.Atom.Build.IBuildAccessor, + Members: [ + { + Name: Services + } + ] + }, + { + Name: DecSm.Atom.Build.Model.BuildModel, + Members: [ + { + Name: $ + }, + { + Name: CurrentTarget + }, + { + Name: DeclaringAssembly + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: GetTarget + }, + { + Name: Targets + }, + { + Name: TargetStates + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Build.Model.ConsumedArtifact, + Members: [ + { + Name: $ + }, + { + Name: ArtifactName + }, + { + Name: BuildSlice + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: TargetName + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Build.Model.ConsumedVariable, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: TargetName + }, + { + Name: ToString + }, + { + Name: VariableName + } + ] + }, + { + Name: DecSm.Atom.Build.Model.ProducedArtifact, + Members: [ + { + Name: $ + }, + { + Name: ArtifactName + }, + { + Name: BuildSlice + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Build.Model.TargetModel, + Members: [ + { + Name: $ + }, + { + Name: ConsumedArtifacts + }, + { + Name: ConsumedVariables + }, + { + Name: DeclaringAssembly + }, + { + Name: Deconstruct + }, + { + Name: Dependencies + }, + { + Name: Description + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: IsHidden + }, + { + Name: Name + }, + { + Name: Params + }, + { + Name: ProducedArtifacts + }, + { + Name: ProducedVariables + }, + { + Name: Tasks + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Build.Model.TargetRunState, + Members: [ + { + Name: Failed + }, + { + Name: NotRun + }, + { + Name: PendingRun + }, + { + Name: Running + }, + { + Name: Skipped + }, + { + Name: Succeeded + }, + { + Name: Uninitialized + }, + { + Name: value__ + } + ] + }, + { + Name: DecSm.Atom.Build.Model.TargetState, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Name + }, + { + Name: RunDuration + }, + { + Name: Status + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Build.Model.UsedParam, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Param + }, + { + Name: Required + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.BuildInfo.IBuildIdProvider, + Members: [ + { + Name: BuildId + }, + { + Name: GetBuildIdGroup + } + ] + }, + { + Name: DecSm.Atom.BuildInfo.IBuildInfo, + Members: [ + { + Name: BuildId + }, + { + Name: BuildName + }, + { + Name: BuildSlice + }, + { + Name: BuildTimestamp + }, + { + Name: BuildVersion + } + ] + }, + { + Name: DecSm.Atom.BuildInfo.IBuildTimestampProvider, + Members: [ + { + Name: Timestamp + } + ] + }, + { + Name: DecSm.Atom.BuildInfo.IBuildVersionProvider, + Members: [ + { + Name: Version + } + ] + }, + { + Name: DecSm.Atom.Help.IHelpService, + Members: [ + { + Name: ShowHelp + } + ] + }, + { + Name: DecSm.Atom.Hosting.AtomHost, + Members: [ + { + Name: CreateAtomBuilder + }, + { + Name: Run + } + ] + }, + { + Name: DecSm.Atom.Hosting.ConfigureHostAttribute + }, + { + Name: DecSm.Atom.Hosting.ConfigureHostBuilderAttribute + }, + { + Name: DecSm.Atom.Hosting.GenerateEntryPointAttribute + }, + { + Name: DecSm.Atom.Hosting.HostExtensions, + Members: [ + { + Name: AddAtom + }, + { + Name: UseAtom + } + ] + }, + { + Name: DecSm.Atom.Hosting.IConfigureHost, + Members: [ + { + Name: ConfigureBuildHost + }, + { + Name: ConfigureBuildHostBuilder + } + ] + }, + { + Name: DecSm.Atom.ISetupBuildInfo, + Members: [ + { + Name: SetupBuildInfo + } + ] + }, + { + Name: DecSm.Atom.IValidateBuild, + Members: [ + { + Name: ValidateBuild + } + ] + }, + { + Name: DecSm.Atom.Logging.LogOptions, + Members: [ + { + Name: IsVerboseEnabled + } + ] + }, + { + Name: DecSm.Atom.Nuget.AddNugetFeedsStep, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: FeedsToAdd + }, + { + Name: GetEnvVarNameForFeed + }, + { + Name: GetHashCode + }, + { + Name: SyncAtomToolVersionToLibraryVersion + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Nuget.NugetFeedOptions, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: FeedName + }, + { + Name: FeedUrl + }, + { + Name: GetHashCode + }, + { + Name: SecretName + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Params.IParamService, + Members: [ + { + Name: CreateDefaultValuesOnlyScope + }, + { + Name: CreateNoCacheScope + }, + { + Name: CreateOverrideSourcesScope + }, + { + Name: GetParam + }, + { + Name: GetParam + }, + { + Name: GetParam + }, + { + Name: MaskMatchingSecrets + } + ] + }, + { + Name: DecSm.Atom.Params.ParamDefinition, + Members: [ + { + Name: $ + }, + { + Name: ArgName + }, + { + Name: ChainedParams + }, + { + Name: Deconstruct + }, + { + Name: Description + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: IsSecret + }, + { + Name: Name + }, + { + Name: Sources + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Params.ParamDefinitionAttribute, + Members: [ + { + Name: ArgName + }, + { + Name: ChainedParams + }, + { + Name: Description + }, + { + Name: IsSecret + }, + { + Name: Sources + } + ] + }, + { + Name: DecSm.Atom.Params.ParamModel, + Members: [ + { + Name: $ + }, + { + Name: ArgName + }, + { + Name: ChainedParams + }, + { + Name: Deconstruct + }, + { + Name: DefaultValue + }, + { + Name: Description + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: IsSecret + }, + { + Name: Name + }, + { + Name: Sources + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Params.ParamSource, + Members: [ + { + Name: All + }, + { + Name: Cache + }, + { + Name: CommandLineArgs + }, + { + Name: Configuration + }, + { + Name: EnvironmentVariables + }, + { + Name: None + }, + { + Name: Secrets + }, + { + Name: value__ + } + ] + }, + { + Name: DecSm.Atom.Params.SecretDefinitionAttribute + }, + { + Name: DecSm.Atom.Paths.AtomPaths, + Members: [ + { + Name: Artifacts + }, + { + Name: ProvidePath + }, + { + Name: ProvidePath + }, + { + Name: Publish + }, + { + Name: Root + }, + { + Name: Temp + } + ] + }, + { + Name: DecSm.Atom.Paths.FunctionPathProvider, + Members: [ + { + Name: GetPath + }, + { + Name: Priority + }, + { + Name: Resolver + } + ] + }, + { + Name: DecSm.Atom.Paths.IAtomFileSystem, + Members: [ + { + Name: AtomArtifactsDirectory + }, + { + Name: AtomPublishDirectory + }, + { + Name: AtomRootDirectory + }, + { + Name: AtomTempDirectory + }, + { + Name: CreateRootedPath + }, + { + Name: CurrentDirectory + }, + { + Name: FileSystem + }, + { + Name: GetPath + }, + { + Name: GetPath + }, + { + Name: IsFileBasedApp + }, + { + Name: ProjectName + } + ] + }, + { + Name: DecSm.Atom.Paths.IPathLocator, + Members: [ + { + Name: Path + } + ] + }, + { + Name: DecSm.Atom.Paths.IPathProvider, + Members: [ + { + Name: GetPath + }, + { + Name: Priority + } + ] + }, + { + Name: DecSm.Atom.Paths.RootedPath, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: DirectoryExists + }, + { + Name: DirectoryName + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: FileExists + }, + { + Name: FileName + }, + { + Name: FileNameWithoutExtension + }, + { + Name: FileSystem + }, + { + Name: GetHashCode + }, + { + Name: Parent + }, + { + Name: Path + }, + { + Name: PathExists + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Paths.TransformFileScope, + Members: [ + { + Name: Add + }, + { + Name: AddAsync + }, + { + Name: CancelRestore + }, + { + Name: Create + }, + { + Name: CreateAsync + }, + { + Name: Dispose + }, + { + Name: DisposeAsync + } + ] + }, + { + Name: DecSm.Atom.Paths.TransformFileScopeExtensions, + Members: [ + { + Name: AddAsync + }, + { + Name: AddAsync + } + ] + }, + { + Name: DecSm.Atom.Paths.TransformMultiFileScope, + Members: [ + { + Name: Add + }, + { + Name: AddAsync + }, + { + Name: CancelRestore + }, + { + Name: Create + }, + { + Name: CreateAsync + }, + { + Name: Dispose + }, + { + Name: DisposeAsync + } + ] + }, + { + Name: DecSm.Atom.Process.IProcessRunner, + Members: [ + { + Name: Run + }, + { + Name: RunAsync + } + ] + }, + { + Name: DecSm.Atom.Process.ProcessRunner, + Members: [ + { + Name: Run + }, + { + Name: RunAsync + } + ] + }, + { + Name: DecSm.Atom.Process.ProcessRunOptions, + Members: [ + { + Name: $ + }, + { + Name: AllowFailedResult + }, + { + Name: Args + }, + { + Name: Deconstruct + }, + { + Name: EnvironmentVariables + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: ErrorLogLevel + }, + { + Name: GetHashCode + }, + { + Name: InvocationLogLevel + }, + { + Name: Name + }, + { + Name: OutputLogLevel + }, + { + Name: ToString + }, + { + Name: TransformError + }, + { + Name: TransformOutput + }, + { + Name: WorkingDirectory + } + ] + }, + { + Name: DecSm.Atom.Process.ProcessRunResult, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Error + }, + { + Name: ExitCode + }, + { + Name: GetHashCode + }, + { + Name: Output + }, + { + Name: RunOptions + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Reports.ArtifactReportData, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Name + }, + { + Name: Path + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Reports.ColumnAlignment, + Members: [ + { + Name: Center + }, + { + Name: Left + }, + { + Name: Right + }, + { + Name: value__ + } + ] + }, + { + Name: DecSm.Atom.Reports.ICustomReportData, + Members: [ + { + Name: BeforeStandardData + } + ] + }, + { + Name: DecSm.Atom.Reports.IOutcomeReportWriter, + Members: [ + { + Name: ReportRunOutcome + } + ] + }, + { + Name: DecSm.Atom.Reports.IReportData + }, + { + Name: DecSm.Atom.Reports.IReportsHelper, + Members: [ + { + Name: AddReportData + } + ] + }, + { + Name: DecSm.Atom.Reports.ListReportData, + Members: [ + { + Name: $ + }, + { + Name: BeforeStandardData + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Items + }, + { + Name: Prefix + }, + { + Name: Title + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Reports.LogReportData, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Exception + }, + { + Name: GetHashCode + }, + { + Name: Level + }, + { + Name: Message + }, + { + Name: Timestamp + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Reports.ReportDataMarkdownFormatter, + Members: [ + { + Name: Write + } + ] + }, + { + Name: DecSm.Atom.Reports.ReportService, + Members: [ + { + Name: AddReportData + }, + { + Name: GetReportData + } + ] + }, + { + Name: DecSm.Atom.Reports.TableReportData, + Members: [ + { + Name: $ + }, + { + Name: BeforeStandardData + }, + { + Name: ColumnAlignments + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Header + }, + { + Name: Rows + }, + { + Name: Title + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Reports.TextReportData, + Members: [ + { + Name: $ + }, + { + Name: BeforeStandardData + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Text + }, + { + Name: Title + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Secrets.IDotnetUserSecrets + }, + { + Name: DecSm.Atom.Secrets.ISecretsProvider, + Members: [ + { + Name: GetSecret + } + ] + }, + { + Name: DecSm.Atom.SemVer, + Members: [ + { + Name: BuildNumberFromMetadata + }, + { + Name: BuildNumberFromPreRelease + }, + { + Name: CompareTo + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: ExtractBuildNumber + }, + { + Name: FromSystemVersion + }, + { + Name: GetHashCode + }, + { + Name: IsBetween + }, + { + Name: IsPreRelease + }, + { + Name: Major + }, + { + Name: Metadata + }, + { + Name: Minor + }, + { + Name: One + }, + { + Name: Parse + }, + { + Name: Parse + }, + { + Name: Parse + }, + { + Name: Patch + }, + { + Name: Prefix + }, + { + Name: PreRelease + }, + { + Name: ToString + }, + { + Name: ToSystemVersion + }, + { + Name: TryParse + }, + { + Name: TryParse + }, + { + Name: TryParse + }, + { + Name: TryParse + } + ] + }, + { + Name: DecSm.Atom.StepFailedException, + Members: [ + { + Name: ReportData + } + ] + }, + { + Name: DecSm.Atom.Util.BuildCache`1, + Members: [ + { + Name: Clear + }, + { + Name: Set + }, + { + Name: TryGetValue + } + ] + }, + { + Name: DecSm.Atom.Util.Scope.ActionScope, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Dispose + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: OnDispose + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Util.Scope.NullScope, + Members: [ + { + Name: Dispose + }, + { + Name: Instance + } + ] + }, + { + Name: DecSm.Atom.Util.Scope.TaskScope, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: DisposeAsync + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: OnDispose + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Util.ServiceStaticAccessor`1, + Members: [ + { + Name: Service + } + ] + }, + { + Name: DecSm.Atom.Util.StringUtil, + Members: [ + { + Name: GetLevenshteinDistance + }, + { + Name: SanitizeForLogging + } + ] + }, + { + Name: DecSm.Atom.Util.TaskExtensions, + Members: [ + { + Name: WithRetry + }, + { + Name: WithRetry + }, + { + Name: WithRetry + }, + { + Name: WithRetry + } + ] + }, + { + Name: DecSm.Atom.Util.TypeUtil, + Members: [ + { + Name: Convert + } + ] + }, + { + Name: DecSm.Atom.Variables.IVariablesHelper, + Members: [ + { + Name: WriteVariable + } + ] + }, + { + Name: DecSm.Atom.Variables.IWorkflowVariableProvider, + Members: [ + { + Name: ReadVariable + }, + { + Name: WriteVariable + } + ] + }, + { + Name: DecSm.Atom.Variables.IWorkflowVariableService, + Members: [ + { + Name: ReadVariable + }, + { + Name: WriteVariable + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.IWorkflowType, + Members: [ + { + Name: IsRunning + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.MatrixDimension, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Name + }, + { + Name: ToString + }, + { + Name: Values + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Options.IWorkflowOption, + Members: [ + { + Name: AllowMultiple + }, + { + Name: GetOptionsForCurrentTarget + }, + { + Name: Merge + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Options.ToggleWorkflowOption`1, + Members: [ + { + Name: $ + }, + { + Name: Disabled + }, + { + Name: Enabled + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: IsEnabled + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Options.WorkflowEnvironmentInjection, + Members: [ + { + Name: $ + }, + { + Name: AllowMultiple + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Options.WorkflowOption`2, + Members: [ + { + Name: $ + }, + { + Name: AllowMultiple + }, + { + Name: Create + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + }, + { + Name: Value + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Options.WorkflowParamInjection, + Members: [ + { + Name: $ + }, + { + Name: AllowMultiple + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: MergeWith + }, + { + Name: Name + }, + { + Name: ToString + }, + { + Name: Value + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Options.WorkflowSecretInjection, + Members: [ + { + Name: $ + }, + { + Name: AllowMultiple + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Options.WorkflowSecretsEnvironmentInjection, + Members: [ + { + Name: $ + }, + { + Name: AllowMultiple + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Options.WorkflowSecretsSecretInjection, + Members: [ + { + Name: $ + }, + { + Name: AllowMultiple + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Triggers.GithubScheduleTrigger, + Members: [ + { + Name: $ + }, + { + Name: CronExpression + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Triggers.GitPullRequestTrigger, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: ExcludedBranches + }, + { + Name: ExcludedPaths + }, + { + Name: GetHashCode + }, + { + Name: IncludedBranches + }, + { + Name: IncludedPaths + }, + { + Name: IntoMain + }, + { + Name: ToString + }, + { + Name: Types + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Triggers.GitPushTrigger, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: ExcludedBranches + }, + { + Name: ExcludedPaths + }, + { + Name: ExcludedTags + }, + { + Name: GetHashCode + }, + { + Name: IncludedBranches + }, + { + Name: IncludedPaths + }, + { + Name: IncludedTags + }, + { + Name: ToMain + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Triggers.IWorkflowTrigger + }, + { + Name: DecSm.Atom.Workflows.Definition.Triggers.ManualBoolInput, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: DefaultValue + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: ForParam + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Triggers.ManualChoiceInput, + Members: [ + { + Name: $ + }, + { + Name: Choices + }, + { + Name: Deconstruct + }, + { + Name: DefaultValue + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: ForParam + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Triggers.ManualInput, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Description + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Name + }, + { + Name: Required + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Triggers.ManualStringInput, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: DefaultValue + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: ForParam + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.Triggers.ManualTrigger, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Empty + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Inputs + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.WorkflowDefinition, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Name + }, + { + Name: Options + }, + { + Name: Targets + }, + { + Name: ToString + }, + { + Name: Triggers + }, + { + Name: WorkflowTypes + } + ] + }, + { + Name: DecSm.Atom.Workflows.Definition.WorkflowTargetDefinition, + Members: [ + { + Name: $ + }, + { + Name: CreateModel + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: MatrixDimensions + }, + { + Name: Name + }, + { + Name: Options + }, + { + Name: SuppressArtifactPublishing + }, + { + Name: ToString + }, + { + Name: WithMatrixDimensions + }, + { + Name: WithOptions + }, + { + Name: WithSuppressedArtifactPublishing + } + ] + }, + { + Name: DecSm.Atom.Workflows.IWorkflowOptionProvider, + Members: [ + { + Name: WorkflowOptions + } + ] + }, + { + Name: DecSm.Atom.Workflows.Model.WorkflowJobModel, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: JobDependencies + }, + { + Name: MatrixDimensions + }, + { + Name: Name + }, + { + Name: Options + }, + { + Name: Steps + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Model.WorkflowModel, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Jobs + }, + { + Name: Name + }, + { + Name: Options + }, + { + Name: ToString + }, + { + Name: Triggers + } + ] + }, + { + Name: DecSm.Atom.Workflows.Model.WorkflowStepModel, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: MatrixDimensions + }, + { + Name: Name + }, + { + Name: Options + }, + { + Name: SuppressArtifactPublishing + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Options.CustomStep, + Members: [ + { + Name: $ + }, + { + Name: AllowMultiple + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Name + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Options.DeployToEnvironment, + Members: [ + { + Name: $ + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Options.IJobRunsOn, + Members: [ + { + Name: JobRunsOn + }, + { + Name: MacOsLatestTag + }, + { + Name: UbuntuLatestTag + }, + { + Name: WindowsLatestTag + } + ] + }, + { + Name: DecSm.Atom.Workflows.Options.SetupDotnetStep, + Members: [ + { + Name: $ + }, + { + Name: Deconstruct + }, + { + Name: DotnetVersion + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: Equals + }, + { + Name: GetHashCode + }, + { + Name: Quality + }, + { + Name: ToString + } + ] + }, + { + Name: DecSm.Atom.Workflows.Writer.IWorkflowWriter, + Members: [ + { + Name: CheckForDirtyWorkflow + }, + { + Name: Generate + }, + { + Name: WorkflowType + } + ] + }, + { + Name: DecSm.Atom.Workflows.Writer.IWorkflowWriter`1 + }, + { + Name: DecSm.Atom.Workflows.Writer.WorkflowFileWriter`1, + Members: [ + { + Name: CheckForDirtyWorkflow + }, + { + Name: Generate + } + ] + } +] \ No newline at end of file diff --git a/DecSm.Atom.Tests/ApiSurfaceTests/PublicApiSurfaceTests.cs b/DecSm.Atom.Tests/ApiSurfaceTests/PublicApiSurfaceTests.cs new file mode 100644 index 00000000..1883c623 --- /dev/null +++ b/DecSm.Atom.Tests/ApiSurfaceTests/PublicApiSurfaceTests.cs @@ -0,0 +1,79 @@ +namespace DecSm.Atom.Tests.ApiSurfaceTests; + +[TestFixture] +public class PublicApiSurfaceTests +{ + [Test] + public async Task VerifyPublicApiSurface() + { + // Get all types in DecSm.Atom assembly that are annotated with [PublicAPI] attribute + var publicApiSurface = typeof(BuildDefinition) + .Assembly + .GetTypes() + .Where(static t => t is { IsPublic: true }) + .Select(static t => new Type(t.FullName!, + t + .GetMembers(BindingFlags.Instance | + BindingFlags.Static | + BindingFlags.Public | + BindingFlags.DeclaredOnly) + .Select(static m => GetMember(m)) + .Where(static m => m is not null) + .Select(x => x!) + .OrderBy(static m => m.Name) + .ToList())) + .OrderBy(static t => t.Name) + .ToList(); + + var jsonRepresentation = JsonSerializer.Serialize(publicApiSurface); + + await VerifyJson(jsonRepresentation); + } + + private static IMember? GetMember(MemberInfo arg) => + arg switch + { + FieldInfo fieldInfo => new Field(fieldInfo.Name, fieldInfo.FieldType.FullName!), + PropertyInfo propertyInfo => new Property(propertyInfo.Name, propertyInfo.PropertyType.FullName!), + MethodInfo { IsSpecialName: false } methodInfo => new Method(methodInfo.Name, + methodInfo.ReturnType.FullName!, + methodInfo + .GetParameters() + .Select(p => new Parameter(p.Name!, p.ParameterType.FullName!)) + .ToList()), + _ => null, + }; +} + +public sealed record Type(string Name, IReadOnlyList Members); + +public interface IMember +{ + string ToString(); + + string Name { get; } +} + +public sealed record Field(string Name, string Type) : IMember +{ + public override string ToString() => + $"{Type} {Name}"; +} + +public sealed record Property(string Name, string Type) : IMember +{ + public override string ToString() => + $"{Type} {Name}"; +} + +public sealed record Method(string Name, string ReturnType, IReadOnlyList Parameters) : IMember +{ + public override string ToString() => + $"{ReturnType} {Name}({string.Join(", ", Parameters)})"; +} + +public sealed record Parameter(string Name, string Type) +{ + public override string ToString() => + $"{Type} {Name}"; +} diff --git a/DecSm.Atom.Tests/BuildTests/Core/TestTargetAtomBuild.cs b/DecSm.Atom.Tests/BuildTests/Core/TestTargetAtomBuild.cs index da6a2166..6a289fa8 100644 --- a/DecSm.Atom.Tests/BuildTests/Core/TestTargetAtomBuild.cs +++ b/DecSm.Atom.Tests/BuildTests/Core/TestTargetAtomBuild.cs @@ -10,7 +10,7 @@ public partial class TestTargetAtomBuild : MinimalBuildDefinition, ITestTarget public interface ITestTarget { - string Description { get; set; } + string Description { get; } Func Execute { get; set; } diff --git a/DecSm.Atom.Tests/BuildTests/Params/OptionalParamBuild.cs b/DecSm.Atom.Tests/BuildTests/Params/OptionalParamBuild.cs index bf877219..ba34c714 100644 --- a/DecSm.Atom.Tests/BuildTests/Params/OptionalParamBuild.cs +++ b/DecSm.Atom.Tests/BuildTests/Params/OptionalParamBuild.cs @@ -16,9 +16,9 @@ public interface IOptionalParamTarget1 : IBuildAccessor [ParamDefinition("param-2", "Param 2")] string? Param2 => GetParam(() => Param2); - string? ExecuteValue1 { get; set; } + string? ExecuteValue1 { set; } - string? ExecuteValue2 { get; set; } + string? ExecuteValue2 { set; } Target OptionalParamTarget1 => t => t diff --git a/DecSm.Atom.Tests/BuildTests/Params/ParamBuild.cs b/DecSm.Atom.Tests/BuildTests/Params/ParamBuild.cs index 7fdf47a6..e6872520 100644 --- a/DecSm.Atom.Tests/BuildTests/Params/ParamBuild.cs +++ b/DecSm.Atom.Tests/BuildTests/Params/ParamBuild.cs @@ -11,7 +11,7 @@ public interface IParamTarget1 : IBuildAccessor [ParamDefinition("param-1", "Param 1")] string Param1 => GetParam(() => Param1, "DefaultValue"); - string? ExecuteValue { get; set; } + string? ExecuteValue { set; } Target ParamTarget1 => t => t.Executes(() => @@ -27,7 +27,7 @@ public interface IParamTarget2 : IBuildAccessor [ParamDefinition("param-2", "Param 2")] string Param2 => GetParam(() => Param2)!; - string? ExecuteValue { get; set; } + string? ExecuteValue { set; } Target ParamTarget2 => t => t diff --git a/DecSm.Atom.Tests/BuildTests/Secrets/UserSecretsBuild.cs b/DecSm.Atom.Tests/BuildTests/Secrets/UserSecretsBuild.cs index 93269c43..fa692e04 100644 --- a/DecSm.Atom.Tests/BuildTests/Secrets/UserSecretsBuild.cs +++ b/DecSm.Atom.Tests/BuildTests/Secrets/UserSecretsBuild.cs @@ -11,7 +11,7 @@ public interface IUserSecretsTarget : IBuildAccessor [SecretDefinition("secret-1", "Secret 1")] string? Secret1 => GetParam(() => Secret1); - string? ExecutionValue { get; set; } + string? ExecutionValue { set; } Target UserSecretsTarget => t => t diff --git a/DecSm.Atom.Tests/BuildTests/Targets/CircularTargetDependencyBuild.cs b/DecSm.Atom.Tests/BuildTests/Targets/CircularTargetDependencyBuild.cs index 1fe725f8..0edca991 100644 --- a/DecSm.Atom.Tests/BuildTests/Targets/CircularTargetDependencyBuild.cs +++ b/DecSm.Atom.Tests/BuildTests/Targets/CircularTargetDependencyBuild.cs @@ -10,7 +10,7 @@ public partial class CircularTargetDependencyBuild : MinimalBuildDefinition, ICi public interface ICircularTarget1 { - bool CircularTarget1Executed { get; set; } + bool CircularTarget1Executed { set; } Target CircularTarget1 => t => t @@ -25,7 +25,7 @@ public interface ICircularTarget1 public interface ICircularTarget2 { - bool CircularTarget2Executed { get; set; } + bool CircularTarget2Executed { set; } Target CircularTarget2 => t => t @@ -53,7 +53,7 @@ public partial class CircularTargetDependencyBuild2 : MinimalBuildDefinition, public interface ITestCircularTarget3 { - bool CircularTarget3Executed { get; set; } + bool CircularTarget3Executed { set; } Target TestCircularTarget3 => t => t @@ -68,7 +68,7 @@ public interface ITestCircularTarget3 public interface ITestCircularTarget4 { - bool CircularTarget4Executed { get; set; } + bool CircularTarget4Executed { set; } Target TestCircularTarget4 => t => t @@ -83,7 +83,7 @@ public interface ITestCircularTarget4 public interface ITestCircularTarget5 { - bool CircularTarget5Executed { get; set; } + bool CircularTarget5Executed { set; } Target TestCircularTarget5 => t => t diff --git a/DecSm.Atom.Tests/BuildTests/Targets/DependencyTargetBuild.cs b/DecSm.Atom.Tests/BuildTests/Targets/DependencyTargetBuild.cs index cdbc9ff9..862a3ecb 100644 --- a/DecSm.Atom.Tests/BuildTests/Targets/DependencyTargetBuild.cs +++ b/DecSm.Atom.Tests/BuildTests/Targets/DependencyTargetBuild.cs @@ -18,7 +18,7 @@ public partial class DependencyTargetBuild : MinimalBuildDefinition, public interface IDependencyTarget1 { - bool DependencyTarget1Executed { get; set; } + bool DependencyTarget1Executed { set; } Target DependencyTarget1 => t => t.Executes(() => @@ -31,7 +31,7 @@ public interface IDependencyTarget1 public interface IDependencyTarget2 { - bool DependencyTarget2Executed { get; set; } + bool DependencyTarget2Executed { set; } Target DependencyTarget2 => t => t @@ -46,7 +46,7 @@ public interface IDependencyTarget2 public interface IDependencyFailTarget1 { - bool DependencyFailTarget1Executed { get; set; } + bool DependencyFailTarget1Executed { set; } Target DependencyFailTarget1 => t => t.Executes(() => @@ -59,7 +59,7 @@ public interface IDependencyFailTarget1 public interface IDependencyFailTarget2 { - bool DependencyFailTarget2Executed { get; set; } + bool DependencyFailTarget2Executed { set; } Target DependencyFailTarget2 => t => t diff --git a/DecSm.Atom.Tests/BuildTests/Targets/ExtensionTargetBuild.cs b/DecSm.Atom.Tests/BuildTests/Targets/ExtensionTargetBuild.cs index afa9e705..b3e8ab0e 100644 --- a/DecSm.Atom.Tests/BuildTests/Targets/ExtensionTargetBuild.cs +++ b/DecSm.Atom.Tests/BuildTests/Targets/ExtensionTargetBuild.cs @@ -10,7 +10,7 @@ public partial class ExtensionTargetBuild : MinimalBuildDefinition, IBaseExtensi public interface IBaseExtensionTarget { - bool BaseExtensionTargetExecuted { get; set; } + bool BaseExtensionTargetExecuted { set; } Target BaseExtensionTarget => t => t.Executes(() => @@ -23,7 +23,7 @@ public interface IBaseExtensionTarget public interface IExtendedExtensionTarget { - bool ExtendedExtensionTargetExecuted { get; set; } + bool ExtendedExtensionTargetExecuted { set; } Target ExtendedExtensionTarget => t => t diff --git a/DecSm.Atom.Tests/BuildTests/Targets/TargetOverrideBuild.cs b/DecSm.Atom.Tests/BuildTests/Targets/TargetOverrideBuild.cs index b9bd9194..b8ae38a1 100644 --- a/DecSm.Atom.Tests/BuildTests/Targets/TargetOverrideBuild.cs +++ b/DecSm.Atom.Tests/BuildTests/Targets/TargetOverrideBuild.cs @@ -10,7 +10,7 @@ public partial class TargetOverrideBuild : MinimalBuildDefinition, IOverrideTarg public interface IBaseOverrideTarget { - bool BaseOverrideTargetExecuted { get; set; } + bool BaseOverrideTargetExecuted { set; } Target OverrideTarget => t => t.Executes(() => @@ -23,7 +23,7 @@ public interface IBaseOverrideTarget public interface IOverrideTarget : IBaseOverrideTarget { - bool OverrideOverrideTargetExecuted { get; set; } + bool OverrideOverrideTargetExecuted { set; } new Target OverrideTarget => t => t.Executes(() => diff --git a/DecSm.Atom.Tests/ClassTests/Build/DefaultBuildVersionProviderTests.cs b/DecSm.Atom.Tests/ClassTests/Build/DefaultBuildVersionProviderTests.cs index a34244dc..4f1edfcf 100644 --- a/DecSm.Atom.Tests/ClassTests/Build/DefaultBuildVersionProviderTests.cs +++ b/DecSm.Atom.Tests/ClassTests/Build/DefaultBuildVersionProviderTests.cs @@ -47,8 +47,9 @@ public void Version_Returns_VersionInfo() var version = provider.Version; // Assert - version.ShouldSatisfyAllConditions(x => x.ShouldNotBeNull(), - x => x + version + .ShouldNotBeNull() + .ShouldSatisfyAllConditions(x => x .ToString() .ShouldBe("1.2.3")); } diff --git a/DecSm.Atom.Tests/ClassTests/SemVerBuildNumberExtractionTests.cs b/DecSm.Atom.Tests/ClassTests/SemVerBuildNumberExtractionTests.cs deleted file mode 100644 index 1b4b3985..00000000 --- a/DecSm.Atom.Tests/ClassTests/SemVerBuildNumberExtractionTests.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace DecSm.Atom.Tests.ClassTests; - -[TestFixture] -internal sealed class SemVerBuildNumberExtractionTests -{ - [TestCase("alpha.beta.1", 1)] - [TestCase("alpha.1", 1)] - [TestCase("alpha3.valid", 3)] - [TestCase("alpha.4valid", 4)] - [TestCase("rc.1", 1)] - [TestCase("alpha.1227", 1227)] - [TestCase("7A.is.legal", 7)] - [TestCase("SNAPSHOT-123", 123)] - [TestCase("---RC-SNAPSHOT.12--N-A", 12)] - [TestCase("prerelease", 0)] - [TestCase("alpha", 0)] - [TestCase("beta", 0)] - [TestCase("alpha.beta", 0)] - [TestCase("alpha-a.b-c-somethinglong", 0)] - [TestCase("beta", 0)] - [TestCase("DEV-SNAPSHOT", 0)] - [TestCase("alpha", 0)] - [TestCase("alpha3.4valid", 0)] - [TestCase("3alpha.4valid.1", 0)] - [TestCase("---RC-SNAPSHOT.12.9.1--.12", 0)] - [TestCase("---R-S.12.9.1--.12", 0)] - [TestCase("---RC-SNAPSHOT.12.9.1--.12", 0)] - public void DefaultBuildNumberExtractionStrategy_ExtractsBuildNumber(string preRelease, int expected) - { - var actual = SemVer.ExtractBuildNumber(preRelease); - - actual.ShouldBe(expected); - } -} diff --git a/DecSm.Atom.Tests/ClassTests/SemVerTests.cs b/DecSm.Atom.Tests/ClassTests/SemVerTests.cs index 9859ead5..d0d1cd94 100644 --- a/DecSm.Atom.Tests/ClassTests/SemVerTests.cs +++ b/DecSm.Atom.Tests/ClassTests/SemVerTests.cs @@ -271,10 +271,39 @@ public void Serialize_Deserialize_Json(string versionString, string expectedStri var semVer = SemVer.Parse(versionString); var json = JsonSerializer.Serialize(semVer, JsonSerializerOptions.Default); - var actual = JsonSerializer.Deserialize(json, JsonSerializerOptions.Default)!; + var actual = JsonSerializer.Deserialize(json, JsonSerializerOptions.Default); actual - .ToString() + ?.ToString() .ShouldBe(expectedString); } + + [TestCase("alpha.beta.1", 1)] + [TestCase("alpha.1", 1)] + [TestCase("alpha3.valid", 3)] + [TestCase("alpha.4valid", 4)] + [TestCase("rc.1", 1)] + [TestCase("alpha.1227", 1227)] + [TestCase("7A.is.legal", 7)] + [TestCase("SNAPSHOT-123", 123)] + [TestCase("---RC-SNAPSHOT.12--N-A", 12)] + [TestCase("prerelease", 0)] + [TestCase("alpha", 0)] + [TestCase("beta", 0)] + [TestCase("alpha.beta", 0)] + [TestCase("alpha-a.b-c-somethinglong", 0)] + [TestCase("beta", 0)] + [TestCase("DEV-SNAPSHOT", 0)] + [TestCase("alpha", 0)] + [TestCase("alpha3.4valid", 0)] + [TestCase("3alpha.4valid.1", 0)] + [TestCase("---RC-SNAPSHOT.12.9.1--.12", 0)] + [TestCase("---R-S.12.9.1--.12", 0)] + [TestCase("---RC-SNAPSHOT.12.9.1--.12", 0)] + public void DefaultBuildNumberExtractionStrategy_ExtractsBuildNumber(string preRelease, int expected) + { + var actual = SemVer.ExtractBuildNumber(preRelease); + + actual.ShouldBe(expected); + } } diff --git a/DecSm.Atom.Tool.Tests/RunCommandTests.cs b/DecSm.Atom.Tool.Tests/RunCommandTests.cs index c17f69ba..c2b08b6b 100644 --- a/DecSm.Atom.Tool.Tests/RunCommandTests.cs +++ b/DecSm.Atom.Tool.Tests/RunCommandTests.cs @@ -3,8 +3,6 @@ [TestFixture] public class RunCommandTests { - private MockFileSystem _fs = null!; - [SetUp] public void SetUp() { @@ -13,7 +11,9 @@ public void SetUp() RunCommand.MockDotnetCli = true; } - private string GetRoot() => + private MockFileSystem _fs = null!; + + private static string GetRoot() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\" : "/"; diff --git a/DecSm.Atom.Tool.Tests/_usings.cs b/DecSm.Atom.Tool.Tests/_usings.cs index 876bca80..81e7008e 100644 --- a/DecSm.Atom.Tool.Tests/_usings.cs +++ b/DecSm.Atom.Tool.Tests/_usings.cs @@ -1,6 +1,4 @@ -global using System.Diagnostics.CodeAnalysis; -global using System.IO.Abstractions; -global using System.IO.Abstractions.TestingHelpers; +global using System.IO.Abstractions.TestingHelpers; global using System.Runtime.InteropServices; global using DecSm.Atom.Tool.Commands; global using Shouldly; diff --git a/DecSm.Atom.Tool/Commands/RunCommand.cs b/DecSm.Atom.Tool/Commands/RunCommand.cs index f8f6151a..3b13b468 100644 --- a/DecSm.Atom.Tool/Commands/RunCommand.cs +++ b/DecSm.Atom.Tool/Commands/RunCommand.cs @@ -176,15 +176,10 @@ private static async Task Execute( "run", }; - if (isCsFile) - { - args.Add(path.FullName); - } - else - { + if (!isCsFile) args.Add("--project"); - args.Add(path.FullName); - } + + args.Add(path.FullName); args.Add("--"); args.AddRange(sanitizedArgs); diff --git a/DecSm.Atom.Tool/RunArgsFilter.cs b/DecSm.Atom.Tool/RunArgsFilter.cs index 9b31b552..d15aac27 100644 --- a/DecSm.Atom.Tool/RunArgsFilter.cs +++ b/DecSm.Atom.Tool/RunArgsFilter.cs @@ -38,7 +38,7 @@ await Next.InvokeAsync(new(context.CommandName, context.State, null, context.CommandDepth, - (context.Arguments[0] is "-p" or "--project" or "-f" or "--file") && context.Arguments.Length >= 2 + context.Arguments[0] is "-p" or "--project" or "-f" or "--file" && context.Arguments.Length >= 2 ? 2 // Skip "-p" or "--project" or "-f" or "--file" and the project/file name : 0), // All arguments are for the Atom project cancellationToken); diff --git a/DecSm.Atom/Build/Definition/IBuildDefinition.cs b/DecSm.Atom/Build/Definition/IBuildDefinition.cs index 28db899c..49be17ae 100644 --- a/DecSm.Atom/Build/Definition/IBuildDefinition.cs +++ b/DecSm.Atom/Build/Definition/IBuildDefinition.cs @@ -25,7 +25,7 @@ public interface IBuildDefinition /// /// /// Targets represent individual units of work. This collection is populated by source generation - /// based on properties in interfaces that inherit + /// based on properties in interfaces that inherit /// IReadOnlyDictionary TargetDefinitions { get; } diff --git a/DecSm.Atom/DecSm.Atom.csproj b/DecSm.Atom/DecSm.Atom.csproj index 456a27e7..2131759b 100644 --- a/DecSm.Atom/DecSm.Atom.csproj +++ b/DecSm.Atom/DecSm.Atom.csproj @@ -5,7 +5,7 @@ - + diff --git a/DecSm.Atom/IValidateBuild.cs b/DecSm.Atom/IValidateBuild.cs index 439b4f20..9703afbc 100644 --- a/DecSm.Atom/IValidateBuild.cs +++ b/DecSm.Atom/IValidateBuild.cs @@ -9,6 +9,7 @@ /// of Atom build scripts by catching common configuration mistakes early in the process. /// /// +[PublicAPI] public interface IValidateBuild : IReportsHelper { /// diff --git a/DecSm.Atom/Params/ParamService.cs b/DecSm.Atom/Params/ParamService.cs index dc718447..935a1482 100644 --- a/DecSm.Atom/Params/ParamService.cs +++ b/DecSm.Atom/Params/ParamService.cs @@ -123,24 +123,26 @@ IEnumerable secretsProviders ) : IParamService { private readonly Dictionary _cache = []; - private readonly List _knownSecrets = []; - private readonly ISecretsProvider[] _secretsProviders = secretsProviders.ToArray(); /// - /// Gets or sets a value indicating whether parameter caching is disabled. + /// Gets or sets a value indicating whether parameter resolution is currently suppressed. /// - private readonly AsyncLocal _noCache = new(); + private readonly AsyncLocal _defaultValuesOnly = new(); + + private readonly List _knownSecrets = []; /// - /// Gets or sets a value indicating whether parameter resolution is currently suppressed. + /// Gets or sets a value indicating whether parameter caching is disabled. /// - private readonly AsyncLocal _defaultValuesOnly = new(); + private readonly AsyncLocal _noCache = new(); /// /// Gets or sets an optional override for parameter sources to use when resolving parameters. /// private readonly AsyncLocal _overrideSources = new(); + private readonly ISecretsProvider[] _secretsProviders = secretsProviders.ToArray(); + /// public IDisposable CreateNoCacheScope() => new NoCacheScope(this); @@ -473,6 +475,6 @@ public OverrideSourcesScope(ParamService paramService, ParamSource sources) } public void Dispose() => - _paramService._overrideSources.Value = null; + _paramService._overrideSources.Value = _sources; } } diff --git a/DecSm.Atom/Paths/AtomFileSystem.cs b/DecSm.Atom/Paths/AtomFileSystem.cs index 0d0c188d..9733cf52 100644 --- a/DecSm.Atom/Paths/AtomFileSystem.cs +++ b/DecSm.Atom/Paths/AtomFileSystem.cs @@ -105,6 +105,7 @@ RootedPath CreateRootedPath(string path) => /// The logger for diagnostics. internal sealed class AtomFileSystem(ILogger logger) : IAtomFileSystem { + private readonly AsyncLocal _getPathDepth = new(); private readonly Dictionary _pathCache = []; public required IReadOnlyList PathLocators { private get; init; } @@ -116,8 +117,6 @@ internal sealed class AtomFileSystem(ILogger logger) : IAtomFile public required IFileSystem FileSystem { get; init; } - private readonly AsyncLocal _getPathDepth = new(); - /// public RootedPath GetPath(string key) { diff --git a/DecSm.Atom/Paths/AtomPaths.cs b/DecSm.Atom/Paths/AtomPaths.cs index a60052d9..24abbb35 100644 --- a/DecSm.Atom/Paths/AtomPaths.cs +++ b/DecSm.Atom/Paths/AtomPaths.cs @@ -30,35 +30,32 @@ public static class AtomPaths /// public const string Temp = "Temp"; - /// - /// Registers a custom path provider with the dependency injection container. - /// - /// The service collection to add the provider to. - /// A function that resolves a based on a key. - /// The priority of the provider. Higher values take precedence. - public static void ProvidePath( - this IServiceCollection services, - Func locate, - int priority = 1) => - services.AddSingleton(new FunctionPathProvider - { - Priority = priority, - Resolver = locate, - }); + extension(IServiceCollection services) + { + /// + /// Registers a custom path provider with the dependency injection container. + /// + /// A function that resolves a based on a key. + /// The priority of the provider. Higher values take precedence. + [PublicAPI] + public void ProvidePath(Func locate, int priority = 1) => + services.AddSingleton(new FunctionPathProvider + { + Priority = priority, + Resolver = locate, + }); - /// - /// Registers a custom path provider with the dependency injection container. - /// - /// The service collection to add the provider to. - /// A function that resolves a based on a key. - /// The priority of the provider. Higher values take precedence. - public static void ProvidePath( - this IServiceCollection services, - Func locate, - int priority = 1) => - services.AddSingleton(provider => new FunctionPathProvider - { - Priority = priority, - Resolver = key => locate(key, provider.GetRequiredService()), - }); + /// + /// Registers a custom path provider with the dependency injection container. + /// + /// A function that resolves a based on a key. + /// The priority of the provider. Higher values take precedence. + [PublicAPI] + public void ProvidePath(Func locate, int priority = 1) => + services.AddSingleton(provider => new FunctionPathProvider + { + Priority = priority, + Resolver = key => locate(key, provider.GetRequiredService()), + }); + } } diff --git a/_atom/Build.cs b/_atom/Build.cs index 9bb762a2..32730cdb 100644 --- a/_atom/Build.cs +++ b/_atom/Build.cs @@ -10,7 +10,8 @@ internal partial class Build : BuildDefinition, IGitVersion, IBuildTargets, ITestTargets, - IDeployTargets + IDeployTargets, + IApproveDependabotPr { public static readonly string[] PlatformNames = [ @@ -95,6 +96,24 @@ internal partial class Build : BuildDefinition, WorkflowTypes = [Github.WorkflowType], Options = [GithubTokenPermissionsOption.NoneAll], }, + new("Dependabot - Auto Approve") + { + Triggers = [ManualTrigger.Empty, GitPullRequestTrigger.IntoMain], + Targets = + [ + WorkflowTargets.ApproveDependabotPr.WithGithubTokenInjection(new() + { + IdToken = GithubTokenPermission.Write, + PullRequests = GithubTokenPermission.Write, + }), + ], + WorkflowTypes = [Github.WorkflowType], + Options = + [ + GithubTokenPermissionsOption.NoneAll, + GithubIf.Create(new EqualExpression("github.actor", new StringExpression("dependabot[bot]"))), + ], + }, // Test workflows new("Test_Devops_Build") @@ -110,7 +129,7 @@ internal partial class Build : BuildDefinition, .WithDevopsPoolMatrix(DevopsPlatformNames) .WithMatrixDimensions(TestFrameworkMatrix) .WithOptions(new SetupDotnetStep("8.0.x"), new SetupDotnetStep("9.0.x")), - WorkflowTargets.PushToNuget, + WorkflowTargets.PushToNugetDevops, ], WorkflowTypes = [Devops.WorkflowType], Options = [new WorkflowParamInjection(Params.NugetDryRun, "true"), new DevopsVariableGroup("Atom")], diff --git a/_atom/Targets/IApproveDependabotPr.cs b/_atom/Targets/IApproveDependabotPr.cs new file mode 100644 index 00000000..a2a2e811 --- /dev/null +++ b/_atom/Targets/IApproveDependabotPr.cs @@ -0,0 +1,62 @@ +using Octokit.GraphQL; +using Octokit.GraphQL.Internal; +using Octokit.GraphQL.Model; +using Environment = System.Environment; + +namespace Atom.Targets; + +public interface IApproveDependabotPr : IGithubHelper +{ + Target ApproveDependabotPr => + t => t + .RequiresParam(nameof(GithubToken)) + .Executes(async cancellationToken => + { + if (Github.Variables.Actor != "dependabot[bot]") + throw new StepFailedException("Only pull requests from Dependabot can be auto-approved."); + + var pullRequestNumberVariable = Environment.GetEnvironmentVariable("GITHUB_EVENT_NUMBER"); + + if (pullRequestNumberVariable is not { Length: > 0 } || + !int.TryParse(pullRequestNumberVariable, out var prNumber)) + throw new StepFailedException("Could not determine pull request number from environment."); + + const string owner = "DecSmith42"; + const string repo = "atom"; + + var clientMutationId = + $"atom-{Environment.MachineName.ToLowerInvariant().Replace(" ", "-")}-{Environment.ProcessId}"; + + var productHeader = new ProductHeaderValue("Atom"); + var connection = new Connection(productHeader, new InMemoryCredentialStore(new(GithubToken))); + + var prQuery = new Query() + .Repository(repo, owner) + .PullRequest(prNumber) + .Select(p => new + { + p.Id, + p.HeadRefOid, + }) + .Compile(); + + var prQueryResult = await connection.Run(prQuery, cancellationToken: cancellationToken); + + if (prQueryResult.Id.Value is null) + throw new StepFailedException("Could not find pull request."); + + var enableAutoMergeMutation = new Mutation().EnablePullRequestAutoMerge( + new EnablePullRequestAutoMergeInput + { + ClientMutationId = clientMutationId, + PullRequestId = prQueryResult.Id, + AuthorEmail = "dependabot[bot]@users.noreply.github.com", + ExpectedHeadOid = prQueryResult.HeadRefOid, + }); + + var enableAutoMergeResult = await connection.Run(enableAutoMergeMutation, cancellationToken); + + if (enableAutoMergeResult is null) + throw new StepFailedException("Could not enable auto merge."); + }); +} diff --git a/_atom/_atom.csproj b/_atom/_atom.csproj index 43f32847..007dd62b 100644 --- a/_atom/_atom.csproj +++ b/_atom/_atom.csproj @@ -11,6 +11,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive