Skip to content
Open
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
File renamed without changes.
2 changes: 1 addition & 1 deletion .github/workflows/build_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ jobs:
with:
dotnet-version: 3.1.301
- name: Build Tool Info
run: dotnet run --project src/DotNetCI/src/DotNetCI.Tool/
run: dotnet run --project src/DotNetCI.Tool/

File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions src/DotNetCI/DotNetCI.sln → DotNetCI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCI.Engine", "src\DotN
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCI.Config", "src\DotNetCI.Config\DotNetCI.Config.csproj", "{11C6B3A4-E3DB-4F79-AF24-728A188519E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCI.Extensions", "src\DotNetCI.Extensions\DotNetCI.Extensions.csproj", "{C4D2280C-F5ED-4D54-AEA5-42D3FDC5382D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -43,6 +45,10 @@ Global
{11C6B3A4-E3DB-4F79-AF24-728A188519E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11C6B3A4-E3DB-4F79-AF24-728A188519E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11C6B3A4-E3DB-4F79-AF24-728A188519E2}.Release|Any CPU.Build.0 = Release|Any CPU
{C4D2280C-F5ED-4D54-AEA5-42D3FDC5382D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4D2280C-F5ED-4D54-AEA5-42D3FDC5382D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4D2280C-F5ED-4D54-AEA5-42D3FDC5382D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4D2280C-F5ED-4D54-AEA5-42D3FDC5382D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -52,6 +58,7 @@ Global
{A9343D80-0366-4BEC-B637-2E6BCD66252F} = {16DED6D7-9309-4A88-B499-39A6C8AE33A6}
{0CE9842E-C869-4AFC-85B8-34C55FDEDD26} = {16DED6D7-9309-4A88-B499-39A6C8AE33A6}
{11C6B3A4-E3DB-4F79-AF24-728A188519E2} = {16DED6D7-9309-4A88-B499-39A6C8AE33A6}
{C4D2280C-F5ED-4D54-AEA5-42D3FDC5382D} = {16DED6D7-9309-4A88-B499-39A6C8AE33A6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0DCA34AB-D2D4-419E-815F-82AAE2B03C45}
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions src/DotNetCI/Packages.props → Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<ItemGroup Label="nupkg Versions">
<PackageReference Update="CliWrap" Version="3.1.0" />
<PackageReference Update="Bullseye" Version="3.4.0" />
<PackageReference Update="SharpYaml" Version="1.6.6" />
<PackageReference Update="System.CommandLine.DragonFruit" Version="0.3.0-alpha.20303.1" />

<PackageReference Update="Nerdbank.GitVersioning" Version="3.2.31" PrivateAssets="All" IncludeAssets="runtime; build; native; contentfiles; analyzers" />
Expand Down
23 changes: 23 additions & 0 deletions dnci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
variables:
- DOTNET_CLI_TELEMETRY_OPTOUT 1
- DOTNET_SVCUTIL_TELEMETRY_OPTOUT 1
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE 1
- DOTNET_NOLOGO 1
- POWERSHELL_TELEMETRY_OPTOUT 1
- POWERSHELL_UPDATECHECK_OPTOUT 1
- DOTNET_CLI_UI_LANGUAGE ru
tasks:
- name: Hello! It's me!
definitions:
- src/DotNetCI/
jobs:
- name: restore
configuration: Release
- name: Hello! It's me2!
definitions:
- src/DotNetCI.Config
- src/DotNetCI.Engine
jobs:
- name: restore
- configuration: Release

File renamed without changes.
11 changes: 11 additions & 0 deletions src/DotNetCI.Config/CIConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Collections.Generic;

namespace DotNetCI.Config
{
internal class CIConfig
{
public IEnumerable<string> Variables { get; set; } = new List<string>();
public RunOptions RunOptions { get; set; } = new RunOptions();
public IEnumerable<CITaskConfig> Tasks { get; set; } = new List<CITaskConfig>();
}
}
124 changes: 124 additions & 0 deletions src/DotNetCI.Config/CIConfigRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Bullseye;
using DotNetCI.Extensions;
using SharpYaml.Serialization;

namespace DotNetCI.Config
{
public class CIConfigRepository
{
private const char SEPARATOR = ' ';

public Dictionary<string, string> Variables { get; }
public IEnumerable<CITaskConfig> Tasks { get; }
public Options Options { get; }

private CIConfigRepository(Dictionary<string, string> envVars, IEnumerable<CITaskConfig> tasks, Options options)
{
Variables = envVars;
Tasks = tasks;
Options = options;
}

public static async Task<CIConfigRepository> CreateAsync(string sourcePath, bool throwsExceptions = true)
{
CIConfig config = await ReadCIConfigFileAsync(sourcePath, throwsExceptions);
Dictionary<string, string> enviroinmentVariables = ParseEnviroinmentVariables(config.Variables, throwsExceptions);
Options options = GetOptions(config.RunOptions);

return new CIConfigRepository(enviroinmentVariables, config.Tasks, options);
}

private static Options GetOptions(RunOptions options)
{
return DefaultConfig
.RunOptions
.MutableClone(x =>
{
x.Clear = options.Clear ?? x.Clear;
x.DryRun = options.DryRun ?? x.DryRun;
x.Host = options.Host ?? x.Host;
x.ListDependencies = options.ListDependencies ?? x.ListDependencies;
x.ListInputs = options.ListInputs ?? x.ListInputs;
x.ListTargets = options.ListTargets ?? x.ListTargets;
x.ListTree = options.ListTree ?? x.ListTree;
x.NoColor = options.NoColor ?? x.NoColor;
x.Parallel = options.Parallel ?? x.Parallel;
x.SkipDependencies = options.SkipDependencies ?? x.SkipDependencies;
x.Verbose = options.Verbose ?? x.Verbose;
}).TransferTo(options =>
{
return new Options
{
#pragma warning disable CS8629 // Тип значения, допускающего NULL, может быть NULL.
Clear = options.Clear.Value,
DryRun = options.DryRun.Value,
Host = options.Host.Value,
ListDependencies = options.ListDependencies.Value,
ListInputs = options.ListInputs.Value,
ListTargets = options.ListTargets.Value,
ListTree = options.ListTree.Value,
NoColor = options.NoColor.Value,
Parallel = options.Parallel.Value,
SkipDependencies = options.SkipDependencies.Value,
Verbose = options.Verbose.Value
#pragma warning restore CS8629 // Тип значения, допускающего NULL, может быть NULL.
};
});
}
private static Dictionary<string, string> ParseEnviroinmentVariables(IEnumerable<string> dataSet, bool throwsExceptions)
{
Dictionary<string, string> result = DefaultConfig
.EnviroinmentVariables
.ToDictionary(x => x.Key, x => x.Value);

foreach (string data in dataSet)
{
string[] dataPair = data.Split(SEPARATOR);

if (dataPair.Count() != 2)
{
if (throwsExceptions)
{
throw new InvalidDataException($"Can't set variable {data}");
}
}
else
{
result[dataPair[0]] = dataPair[1];
}
}

return result;
}

private static async Task<CIConfig> ReadCIConfigFileAsync(string sourcePath, bool throwsExceptions)
{
try
{
string content = string.Empty;
using (StreamReader reader = new StreamReader(sourcePath))
{
content = await reader.ReadToEndAsync();
}
Serializer serializer = new Serializer(new SerializerSettings()
{
NamingConvention = new NameConvention()
});
return serializer.Deserialize<CIConfig>(content);
}
catch
{
if (throwsExceptions)
{
throw;
}

return new CIConfig();
}
}
}
}
19 changes: 19 additions & 0 deletions src/DotNetCI.Config/CIJobConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;

namespace DotNetCI.Config
{
public class CIJobConfig
{
[Required]
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public IEnumerable<string> Filters { get; set; } = new List<string>();
[Required]
public string Configuration { get; set; }
public IEnumerable<string> Depends { get; set; } = new List<string>();
}
}
14 changes: 14 additions & 0 deletions src/DotNetCI.Config/CITaskConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace DotNetCI.Config
{
public class CITaskConfig
{
[Required]
public string? Name { get; set; }
public string? Description { get; set; }
public IEnumerable<string> Definitions { get; set; } = new List<string>();
public IEnumerable<CIJobConfig> Jobs { get; set; } = new List<CIJobConfig>();
}
}
33 changes: 33 additions & 0 deletions src/DotNetCI.Config/DefaultConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections.Generic;
using Bullseye;

namespace DotNetCI.Config
{
internal static class DefaultConfig
{
public static Dictionary<string, string> EnviroinmentVariables => new Dictionary<string, string>
{
{ "DOTNET_CLI_TELEMETRY_OPTOUT", "1" },
{ "DOTNET_SVCUTIL_TELEMETRY_OPTOUT", "1" },
{ "DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "1" },
{ "DOTNET_NOLOGO", "1" },
{ "POWERSHELL_TELEMETRY_OPTOUT", "1" },
{ "POWERSHELL_UPDATECHECK_OPTOUT", "1" },
{ "DOTNET_CLI_UI_LANGUAGE", "ru" },
};
public static RunOptions RunOptions => new RunOptions
{
Host = Host.Unknown,
Verbose = false,
SkipDependencies = false,
Parallel = false,
NoColor = false,
ListTargets = false,
ListInputs = false,
ListDependencies = false,
DryRun = false,
Clear = false,
ListTree = false
};
}
}
14 changes: 14 additions & 0 deletions src/DotNetCI.Config/DotNetCI.Config.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Bullseye" />
<PackageReference Include="SharpYaml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DotNetCI.Extensions\DotNetCI.Extensions.csproj" />
</ItemGroup>

</Project>
22 changes: 22 additions & 0 deletions src/DotNetCI.Config/NameConvention.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Globalization;
using DotNetCI.Extensions;
using SharpYaml.Serialization;

namespace DotNetCI.Config
{
internal class NameConvention : IMemberNamingConvention
{
public StringComparer Comparer { get; }

public NameConvention()
{
Comparer = StringComparer.Ordinal;
}

public string Convert(string name)
{
return name.ToLower();
}
}
}
25 changes: 25 additions & 0 deletions src/DotNetCI.Config/RunOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using Bullseye;

namespace DotNetCI.Config
{
internal class RunOptions : ICloneable
{
public Host? Host { get; set; }
public bool? Verbose { get; set; }
public bool? SkipDependencies { get; set; }
public bool? Parallel { get; set; }
public bool? NoColor { get; set; }
public bool? ListTargets { get; set; }
public bool? ListInputs { get; set; }
public bool? ListDependencies { get; set; }
public bool? DryRun { get; set; }
public bool? Clear { get; set; }
public bool? ListTree { get; set; }

public object Clone()
{
return MemberwiseClone();
}
}
}
59 changes: 59 additions & 0 deletions src/DotNetCI.Engine/DotNetBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Bullseye;

namespace DotNetCI.Engine
{
public class DotNetBuilder
{
private readonly Options _runOptions;
private readonly ICollection<ICiTask> _tasks;

public DotNetBuilder(Options runOptions)
{
_runOptions = runOptions;
_tasks = new List<ICiTask>();
}

public DotNetBuilder AddCiTask<TCiTask>(TCiTask task)
where TCiTask : ICiTask
{
_tasks.Add(task);
return this;
}

public DotNetBuilder AddCiTaskRange<TCiTask>(IEnumerable<TCiTask> tasks)
where TCiTask : ICiTask
{
foreach (TCiTask task in tasks)
{
_ = AddCiTask(task);
}

return this;
}

public async Task ExecuteTargetsAsync()
{
List<ConfiguredTaskAwaitable> runTargetsTasks = new List<ConfiguredTaskAwaitable>();
foreach (ICiTask task in _tasks)
{
Targets targets = new Targets();

foreach (ICiJob job in task.Jobs)
{
targets.Add(job.Name, async () => await job.ExecuteJobAsync());
}

runTargetsTasks.Add(targets.RunWithoutExitingAsync(task.Jobs.Select(x => x.Name), _runOptions).ConfigureAwait(false));
}

foreach (ConfiguredTaskAwaitable runTargetTask in runTargetsTasks)
{
await runTargetTask;
}
}
}
}
Loading