private static IDictionary <string, string> GetBuildProperties(NukeBuild build) { var startTimeString = EnvironmentInfo.Variables.GetValueOrDefault(Constants.GlobalToolStartTimeEnvironmentKey); var compileTime = startTimeString != null ? DateTime.Now.Subtract(DateTime.Parse(startTimeString)) : default(TimeSpan?); return(new Dictionary <string, string> { ["compile_time"] = compileTime?.TotalSeconds.ToString("F0"), ["target_framework"] = EnvironmentInfo.Framework.ToString(), ["host"] = GetTypeName(NukeBuild.Host), ["build_type"] = NukeBuild.BuildProjectFile != null ? "Project" : "Global Tool", ["num_targets"] = build.ExecutableTargets.Count.ToString(), ["num_custom_extensions"] = build.BuildExtensions.Select(x => x.GetType()).Count(IsCustomType).ToString(), ["num_custom_components"] = build.GetType().GetInterfaces().Count(IsCustomType).ToString(), ["num_partitioned_targets"] = build.ExecutableTargets.Count(x => x.PartitionSize.HasValue).ToString(), ["num_secrets"] = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: true) .Count(x => x.HasCustomAttribute <SecretAttribute>()).ToString(), ["config_generators"] = build.GetType().GetCustomAttributes <ConfigurationAttributeBase>() .Select(GetTypeName).Distinct().OrderBy(x => x).JoinCommaSpace(), ["build_components"] = build.GetType().GetInterfaces().Where(x => IsCommonType(x) && x != typeof(INukeBuild)) .Select(GetTypeName).Distinct().OrderBy(x => x).JoinCommaSpace() }); }
public static void SetValue(NukeBuild build, string memberName, object value) { var member = build.GetType().GetMember(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .SingleOrDefault() .NotNull($"Could not find member '{memberName}' on type '{build.GetType()}'."); SetValue(build, member, value); }
public override ConfigurationEntity GetConfiguration( NukeBuild build, IReadOnlyCollection <ExecutableTarget> relevantTargets ) { var paramList = new List <AzurePipelinesParameter>(); var parameters = build.GetType() .GetInterfaces() .SelectMany(x => x.GetMembers()) .Concat( build.GetType() .GetMembers( BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy ) ) .Where(x => x.GetCustomAttribute <ParameterAttribute>() != null); foreach (var parameter in parameters) { if (Parameters.Any( z => z.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase) || z.Equals( parameter.GetCustomAttribute <ParameterAttribute>()?.Name, StringComparison.OrdinalIgnoreCase ) )) { var value = parameter.GetValue(build); if (value is AbsolutePath) { value = null; } paramList.Add( new AzurePipelinesParameter { Name = parameter.GetCustomAttribute <ParameterAttribute>()?.Name ?? parameter.Name, Default = value?.ToString() ?? "", } ); } } var lookupTable = new LookupTable <ExecutableTarget, AzurePipelinesStep>(); var steps = relevantTargets .Select(x => (ExecutableTarget: x, Job: GetStep(x, relevantTargets, lookupTable))) .ForEachLazy(x => lookupTable.Add(x.ExecutableTarget, x.Job)) .Select(x => x.Job).ToArray(); return(new AzurePipelinesSteps { Parameters = paramList.ToArray(), Steps = steps }); }
protected virtual IEnumerable <GithubActionsNukeParameter> GetParameters(NukeBuild build) { var parameters = build.GetType().GetMembers( BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy ) .Where(x => x.GetCustomAttribute <ParameterAttribute>() != null); foreach (var parameter in parameters) { if (Parameters.Any( z => z.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase) || z.Equals( parameter.GetCustomAttribute <ParameterAttribute>().Name, StringComparison.OrdinalIgnoreCase ) )) { var value = parameter.GetValue(build); if (value is AbsolutePath) { value = null; } yield return(new GithubActionsNukeParameter() { Name = parameter.GetCustomAttribute <ParameterAttribute>().Name ?? parameter.Name, Default = value?.ToString() ?? "", }); } } }
public static void ValidateRequirements(NukeBuild build, IReadOnlyCollection <ExecutableTarget> executingTargets) { foreach (var target in executingTargets) { foreach (var requirement in target.Requirements) { if (requirement is Expression <Func <bool> > boolExpression) { // TODO: same as HasSkippingCondition.GetSkipReason ControlFlow.Assert(boolExpression.Compile().Invoke(), $"Target '{target.Name}' requires '{requirement.Body}'."); } else if (IsMemberNull(requirement.GetMemberInfo(), build, target)) { ControlFlow.Fail($"Target '{target.Name}' requires member '{requirement.GetMemberInfo().Name}' to be not null."); } } } var requiredMembers = ValueInjectionUtility.GetInjectionMembers(build.GetType()) .Select(x => x.Member) .Where(x => x.HasCustomAttribute <RequiredAttribute>()); foreach (var member in requiredMembers) { if (IsMemberNull(member, build)) { ControlFlow.Fail($"Member '{member.Name}' is required to be not null."); } } }
public void OnBeforeLogo( NukeBuild build, IReadOnlyCollection <ExecutableTarget> executableTargets) { var completionItems = new SortedDictionary <string, string[]>(); var targetNames = build.ExecutableTargets.Select(x => x.Name).OrderBy(x => x).ToList(); completionItems[Constants.InvokedTargetsParameterName] = targetNames.ToArray(); completionItems[Constants.SkippedTargetsParameterName] = targetNames.ToArray(); var parameters = InjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false); foreach (var parameter in parameters) { var parameterName = ParameterService.GetParameterMemberName(parameter); if (completionItems.ContainsKey(parameterName)) { continue; } var subItems = ParameterService.GetParameterValueSet(parameter, build)?.Select(x => x.Text); completionItems[parameterName] = subItems?.ToArray(); } SerializationTasks.YamlSerializeToFile(completionItems, Constants.GetCompletionFile(NukeBuild.RootDirectory)); if (EnvironmentInfo.GetParameter <bool>(Constants.CompletionParameterName)) { Environment.Exit(exitCode: 0); } }
public static void ValidateRequirements(NukeBuild build) { foreach (var target in build.ExecutionPlan) { foreach (var requirement in target.Requirements) { if (requirement is Expression <Func <bool> > boolExpression) { ControlFlow.Assert(boolExpression.Compile().Invoke(), $"Target '{target.Name}' requires '{requirement.Body}'."); } else if (IsMemberNull(requirement.GetMemberInfo(), build, target)) { ControlFlow.Fail($"Target '{target.Name}' requires member '{requirement.GetMemberInfo().Name}' to be not null."); } } } var requiredMembers = InjectionUtility.GetParameterMembers(build.GetType()).Where(x => x.HasCustomAttribute <RequiredAttribute>()); foreach (var member in requiredMembers) { if (IsMemberNull(member, build)) { ControlFlow.Fail($"Member '{member.Name}' is required to be not null."); } } }
private static void WriteCompletionFile(NukeBuild build) { var completionItems = new SortedDictionary <string, string[]>(); var targets = build.ExecutableTargets.OrderBy(x => x.Name).ToList(); completionItems[InvokedTargetsParameterName] = targets.Where(x => x.Listed).Select(x => x.Name).ToArray(); completionItems[SkippedTargetsParameterName] = targets.Select(x => x.Name).ToArray(); var parameters = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false); foreach (var parameter in parameters) { var parameterName = ParameterService.GetParameterMemberName(parameter); if (completionItems.ContainsKey(parameterName)) { continue; } var subItems = ParameterService.GetParameterValueSet(parameter, build)?.Select(x => x.Text); completionItems[parameterName] = subItems?.ToArray(); } SerializationTasks.YamlSerializeToFile(completionItems, GetCompletionFile(NukeBuild.RootDirectory)); }
public static void InjectValues(NukeBuild build) { var injectionMembers = build.GetType() .GetMembers(c_bindingFlags) .Where(x => x.GetCustomAttributes <InjectionAttributeBase>().Any()).ToList(); foreach (var member in injectionMembers) { var attributes = member.GetCustomAttributes().OfType <InjectionAttributeBase>().ToList(); if (attributes.Count == 0) { continue; } ControlFlow.Assert(attributes.Count == 1, $"Member '{member.Name}' has multiple injection attributes applied."); var attribute = attributes.Single(); var memberType = (member as FieldInfo)?.FieldType ?? ((PropertyInfo)member).PropertyType; var value = attribute.GetValue(member.Name, memberType); if (value == null) { continue; } var valueType = value.GetType(); ControlFlow.Assert(memberType.IsAssignableFrom(valueType), $"Field '{member.Name}' must be of type '{valueType.Name}' to get its valued injected from '{attribute.GetType().Name}'."); SetValue(build, member, value); } }
protected virtual IEnumerable <TeamCityParameter> GetGlobalParameters(NukeBuild build, IReadOnlyCollection <ExecutableTarget> relevantTargets) { return(ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false) .Except(relevantTargets.SelectMany(x => x.Requirements .Where(y => !(y is Expression <Func <bool> >)) .Select(y => y.GetMemberInfo()))) .Where(x => x.DeclaringType != typeof(NukeBuild) || x.Name == nameof(NukeBuild.Verbosity)) .Select(x => GetParameter(x, build, required: false))); }
private static bool IsMemberNull(MemberInfo member, NukeBuild build, ExecutableTarget target = null) { member = member.DeclaringType != build.GetType() ? build.GetType().GetMember(member.Name).SingleOrDefault() ?? member : member; var from = target != null ? $"from target '{target.Name}' " : string.Empty; ControlFlow.Assert(member.HasCustomAttribute <ValueInjectionAttributeBase>(), $"Member '{member.Name}' is required {from}but not marked with an injection attribute."); if (NukeBuild.Host == HostType.Console) { TryInjectValueInteractive(member, build); } return(member.GetValue(build) == null); }
public static IReadOnlyCollection <MemberInfo> GetInjectionMembers(this NukeBuild build) { var members = build.GetType() .GetMembers(ReflectionService.All) .Where(x => x.GetCustomAttributes <InjectionAttributeBase>().Any()).ToList(); var transitiveMembers = members .SelectMany(x => x.GetCustomAttributes <InjectionAttributeBase>()) .SelectMany(x => x.GetType().GetMembers(ReflectionService.All)) .Where(x => x.GetCustomAttributes <InjectionAttributeBase>().Any()).ToList(); return(members.Concat(transitiveMembers).ToList()); }
protected virtual IEnumerable <TeamCityParameter> GetGlobalParameters(NukeBuild build, IReadOnlyCollection <ExecutableTarget> relevantTargets) { return(ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false) // TODO: except build.ExecutableTargets ? .Except(relevantTargets.SelectMany(x => x.Requirements .Where(y => y is not Expression <Func <bool> >) .Select(y => y.GetMemberInfo()))) .Where(x => !x.HasCustomAttribute <SecretAttribute>()) .Where(x => x.DeclaringType != typeof(NukeBuild) || x.Name == nameof(NukeBuild.Verbosity)) .Select(x => GetParameter(x, build, required: false)) .Concat(GetSecretParameters(build)) .Concat(GetDefaultParameters())); }
internal virtual void WriteSummary(NukeBuild build) { if (SevereMessages.Count > 0) { WriteNormal(); WriteSevereMessages(); } WriteNormal(); WriteSummaryTable(build); WriteNormal(); if (build.IsSuccessful) { WriteSuccessfulBuild(); } else { WriteFailedBuild(); } bool HasHighUsage() => // global tool build.GetType().GetInterfaces().Length > 1 || // configuration generation build.GetType().GetCustomAttributes <ConfigurationAttributeBase>().Any() || // interface implementations NukeBuild.BuildProjectFile == null; T TryGetValue <T>(Func <T> func) { try { return(func.Invoke()); } catch { return(default);
public static string GetParametersText(NukeBuild build) { var defaultTarget = build.ExecutableTargets.Single(x => x.IsDefault); var builder = new StringBuilder(); var parameters = InjectionUtility.GetParameterMembers(build.GetType()) .Where(x => !x.HasCustomAttribute <UnlistedAttribute>()) .OrderBy(x => x.Name).ToList(); var padRightParameter = Math.Max(parameters.Max(x => x.Name.Length), val2: 16); void PrintParameter(MemberInfo parameter) { var description = SplitLines( // TODO: remove ParameterService.Instance.GetParameterDescription(parameter) ?.Replace("{default_target}", defaultTarget.Name).Append(".") ?? "<no description>"); var parameterName = ParameterService.Instance.GetParameterName(parameter).SplitCamelHumpsWithSeparator("-"); builder.AppendLine($" --{parameterName.PadRight(padRightParameter)} {description.First()}"); foreach (var line in description.Skip(count: 1)) { builder.AppendLine($"{new string(c: ' ', count: padRightParameter + 6)}{line}"); } } builder.AppendLine("Parameters:"); var customParameters = parameters.Where(x => x.DeclaringType != typeof(NukeBuild)).ToList(); if (customParameters.Count > 0) { builder.AppendLine(); } foreach (var parameter in customParameters) { PrintParameter(parameter); } builder.AppendLine(); var inheritedParameters = parameters.Where(x => x.DeclaringType == typeof(NukeBuild)); foreach (var parameter in inheritedParameters) { PrintParameter(parameter); } return(builder.ToString()); }
protected virtual IEnumerable <TeamCityParameter> GetSecretParameters(NukeBuild build) { var guids = build.GetType().GetCustomAttributes <TeamCityTokenAttribute>() .ToDictionary(x => x.Name, x => $"credentialsJSON:{Guid.Parse(x.Guid):D}"); return(ImportSecrets.Select(x => new TeamCityConfigurationParameter { Type = TeamCityParameterType.Password, Name = x, DefaultValue = guids.GetValueOrDefault(x), Display = TeamCityParameterDisplay.Hidden })); }
public void OnBuildCreated(NukeBuild build, IReadOnlyCollection <ExecutableTarget> executableTargets) { // TODO: probably remove if (!Directory.Exists(Constants.GetNukeDirectory(NukeBuild.RootDirectory))) { return; } var parameterMembers = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: true); var passwords = new Dictionary <string, string>(); IEnumerable <string> ConvertToArguments(string profile, string name, string[] values) { var member = parameterMembers.SingleOrDefault(x => ParameterService.GetParameterMemberName(x).EqualsOrdinalIgnoreCase(name)); var scalarType = member?.GetMemberType().GetScalarType(); var mustDecrypt = (member?.HasCustomAttribute <SecretAttribute>() ?? false) && !BuildServerConfigurationGeneration.IsActive; var decryptedValues = values.Select(x => mustDecrypt ? DecryptValue(profile, name, x) : x); var convertedValues = decryptedValues.Select(x => ConvertValue(scalarType, x)).ToList(); Log.Verbose("Passing value for {Member} ({Value})", member?.GetDisplayName() ?? "<unresolved>", !mustDecrypt ? convertedValues.JoinComma() : "secret"); return(new[] { $"--{ParameterService.GetParameterDashedName(name)}" }.Concat(convertedValues)); } string DecryptValue(string profile, string name, string value) => EncryptionUtility.Decrypt( value, passwords[profile] = passwords.GetValueOrDefault(profile) ?? EncryptionUtility.GetPassword(profile), name); // TODO: Abstract AbsolutePath/Solution/Project etc. string ConvertValue(Type scalarType, string value) => scalarType == typeof(AbsolutePath) || typeof(Solution).IsAssignableFrom(scalarType) || scalarType == typeof(Project) ? EnvironmentInfo.WorkingDirectory.GetUnixRelativePathTo(NukeBuild.RootDirectory / value) : value; var arguments = GetParameters().SelectMany(x => ConvertToArguments(x.Profile, x.Name, x.Values)).ToArray(); ParameterService.Instance.ArgumentsFromFilesService = new ParameterService(() => arguments, () => throw new NotSupportedException()); }
public void OnBuildCreated(NukeBuild build, IReadOnlyCollection <ExecutableTarget> executableTargets) { // TODO: probably remove if (!Directory.Exists(Constants.GetNukeDirectory(NukeBuild.RootDirectory))) { return; } var parameterMembers = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: true); var passwords = new Dictionary <string, byte[]>(); IEnumerable <string> ConvertToArguments(string profile, string name, string[] values) { var member = parameterMembers.SingleOrDefault(x => x.Name.EqualsOrdinalIgnoreCase(name)); var scalarType = member?.GetMemberType().GetScalarType(); var mustDecrypt = (member?.HasCustomAttribute <SecretAttribute>() ?? false) && !GenerationMode; var decryptedValues = values.Select(x => mustDecrypt ? DecryptValue(profile, name, x) : x); var convertedValues = decryptedValues.Select(x => ConvertValue(scalarType, x)); Logger.Trace($"Passing argument for '{name}'{(member != null ? $" on '{member.DeclaringType.NotNull().Name}'" : string.Empty)}."); return(new[] { $"--{ParameterService.GetParameterDashedName(name)}" }.Concat(convertedValues)); } string DecryptValue(string profile, string name, string value) => EncryptionUtility.Decrypt( value, passwords[profile] = passwords.GetValueOrDefault(profile) ?? Encoding.UTF8.GetBytes(EncryptionUtility.GetPassword(profile)), name); // TODO: Abstract AbsolutePath/Solution/Project etc. string ConvertValue(Type scalarType, string value) => scalarType == typeof(AbsolutePath) || typeof(Solution).IsAssignableFrom(scalarType) || scalarType == typeof(Project) ? EnvironmentInfo.WorkingDirectory.GetUnixRelativePathTo(NukeBuild.RootDirectory / value) : value; var arguments = GetParameters().SelectMany(x => ConvertToArguments(x.Profile, x.Name, x.Values)).ToArray(); ParameterService.Instance.ArgumentsFromFilesService = new ParameterService(() => arguments, () => throw new NotSupportedException()); }
public void Execute(NukeBuild build) { var completionItems = new SortedDictionary <string, string[]>(); var targetNames = build.ExecutableTargets.Select(x => x.Name).OrderBy(x => x).ToList(); completionItems[Constants.InvokedTargetsParameterName] = targetNames.ToArray(); completionItems[Constants.SkippedTargetsParameterName] = targetNames.ToArray(); string[] GetSubItems(Type type) { if (type.IsEnum) { return(type.GetEnumNames()); } if (type.IsSubclassOf(typeof(Enumeration))) { return(type.GetFields(ReflectionService.Static).Select(x => x.Name).ToArray()); } return(null); } foreach (var parameter in InjectionUtility.GetParameterMembers(build.GetType())) { var parameterName = ParameterService.Instance.GetParameterName(parameter); if (completionItems.ContainsKey(parameterName)) { continue; } completionItems[parameterName] = GetSubItems(parameter.GetFieldOrPropertyType())?.OrderBy(x => x).ToArray(); } SerializationTasks.YamlSerializeToFile(completionItems, Constants.GetCompletionFile(NukeBuild.RootDirectory)); if (EnvironmentInfo.ParameterSwitch(Constants.CompletionParameterName)) { Environment.Exit(exitCode: 0); } }
public static void SetValue(NukeBuild build, MemberInfo member, object value) { if (member is FieldInfo field) { field.SetValue(build, value); } else if (member is PropertyInfo property) { var backingField = build.GetType().DescendantsAndSelf(x => x.GetTypeInfo().BaseType) .SelectMany(x => x.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) .SingleOrDefault(x => x.Name.StartsWith($"<{member.Name}>")); if (backingField != null) { backingField.SetValue(build, value); } else { ControlFlow.Assert(property.SetMethod != null, $"Property '{member.Name}' is not settable."); property.SetValue(build, value); } } }
private Dictionary <string, string> GetSecrets(NukeBuild build) { return(build.GetType().GetCustomAttributes <AppVeyorSecretAttribute>() .Where(x => Secrets == null || Secrets.Contains(x.Parameter)) .ToDictionary(x => x.Parameter, x => x.Value)); }
// ReSharper disable once CognitiveComplexity public static JObject GetBuildSchema(NukeBuild build) { var parameters = ValueInjectionUtility .GetParameterMembers(build.GetType(), includeUnlisted: true) // .Where(x => x.DeclaringType != typeof(NukeBuild)) .Select(x => new { Name = ParameterService.GetParameterMemberName(x), Description = ParameterService.GetParameterDescription(x), MemberType = x.GetMemberType(), ScalarType = x.GetMemberType().GetScalarType(), EnumValues = ParameterService.GetParameterValueSet(x, build)?.Select(x => x.Text), IsRequired = x.HasCustomAttribute <RequiredAttribute>(), IsSecret = x.HasCustomAttribute <SecretAttribute>() }).ToList(); string GetJsonType(Type type) => type.IsCollectionLike() ? "array" : type.GetScalarType() == typeof(int) ? "integer" : type.GetScalarType() == typeof(bool) ? "boolean" : "string"; var schema = JObject.Parse(@" { ""$schema"": ""http://json-schema.org/draft-04/schema#"", ""title"": ""Build Schema"", ""$ref"": ""#/definitions/build"", ""definitions"": { ""build"": { ""type"": ""object"", ""properties"": { } } } } "); var properties = schema["definitions"].NotNull()["build"].NotNull()["properties"].NotNull(); foreach (var parameter in parameters) { var property = properties[parameter.Name] = new JObject(); property["type"] = GetJsonType(parameter.MemberType); if (parameter.Description != null) { property["description"] = parameter.Description; } if (parameter.IsSecret) { property["default"] = "Secrets must be entered via 'nuke :secrets [profile]'"; } if (parameter.EnumValues != null && !parameter.MemberType.IsCollectionLike()) { property["enum"] = new JArray(parameter.EnumValues); } if (parameter.MemberType.IsCollectionLike()) { property["items"] = new JObject(); property["items"].NotNull()["type"] = GetJsonType(parameter.ScalarType); if (parameter.EnumValues != null) { property["items"].NotNull()["enum"] = new JArray(parameter.EnumValues); } } } return(schema); }
public static string GetParametersText(NukeBuild build) { var defaultTargets = build.ExecutableTargets.Where(x => x.IsDefault).Select(x => x.Name).ToList(); var builder = new StringBuilder(); var parameters = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false); var padRightParameter = Math.Max(parameters.Max(x => ParameterService.GetParameterDashedName(x).Length), val2: 16); List <string> SplitLines(string text) { var words = new Queue <string>(text.Split(' ').ToList()); var lines = new List <string> { string.Empty }; foreach (var word in words) { var nextLength = padRightParameter + 6 + lines.Last().Length + word.Length; if (nextLength >= Console.BufferWidth || nextLength > 90) { lines.Add(string.Empty); } lines[lines.Count - 1] = $"{lines.Last()} {word}"; } return(lines); } void PrintParameter(MemberInfo parameter) { var description = SplitLines( // TODO: remove ParameterService.GetParameterDescription(parameter) ?.Replace("{default_target}", defaultTargets.Count > 0 ? defaultTargets.JoinCommaSpace() : "<none>") .TrimEnd(".").Append(".") ?? "<no description>"); var parameterName = ParameterService.GetParameterDashedName(parameter); builder.AppendLine($" --{parameterName.PadRight(padRightParameter)} {description.First()}"); foreach (var line in description.Skip(count: 1)) { builder.AppendLine($"{new string(c: ' ', count: padRightParameter + 6)}{line}"); } } builder.AppendLine("Parameters:"); var customParameters = parameters.Where(x => x.DeclaringType != typeof(NukeBuild)).ToList(); if (customParameters.Count > 0) { builder.AppendLine(); } foreach (var parameter in customParameters) { PrintParameter(parameter); } builder.AppendLine(); var inheritedParameters = parameters.Where(x => x.DeclaringType == typeof(NukeBuild)); foreach (var parameter in inheritedParameters) { PrintParameter(parameter); } return(builder.ToString()); }
public override ConfigurationEntity GetConfiguration( NukeBuild build, IReadOnlyCollection <ExecutableTarget> relevantTargets ) { var steps = new List <GitHubActionsStep> { new CheckoutStep("Checkout"), // new SetupDotNetStep("Install .NET Core Sdk"), }; var globalToolStep = new RunStep("Install Nuke Global Tool") { Run = "dotnet tool install -g Nuke.GlobalTool" }; var dotnetTools = Path.Combine(NukeBuild.RootDirectory, ".config/dotnet-tools.json"); var localTool = false; if (File.Exists(dotnetTools)) { steps.Add(new RunStep("dotnet tool restore") { Run = "dotnet tool restore" }); if (!File.ReadAllText(dotnetTools).Contains("\"nuke.globaltool\": {")) { steps.Add(globalToolStep); } else { localTool = true; } } else { steps.Add(globalToolStep); } var stepParameters = GetParameters(build).Select(z => $"--{z.Name.ToLowerInvariant()} '${{{{ env.{z.Name.ToUpperInvariant()} }}}}'") .ToArray() .JoinSpace(); var lookupTable = new LookupTable <ExecutableTarget, ExecutableTarget[]>(); foreach (var(execute, targets) in relevantTargets .Select(x => (ExecutableTarget: x, Targets: GetInvokedTargets(x, relevantTargets).ToArray())) .ForEachLazy(x => lookupTable.Add(x.ExecutableTarget, x.Targets.ToArray())) ) { steps.Add(new RunStep(execute.Name.Humanize(LetterCasing.Title)) { Run = $"{( localTool ? "dotnet nuke" : "nuke" )} {targets.Select(z => z.Name).JoinSpace()} --skip {stepParameters}".TrimEnd() }); } var config = new RocketSurgeonGitHubActionsConfiguration() { Name = _name, DetailedTriggers = GetTriggers().ToList(), Jobs = new List <RocketSurgeonsGithubActionsJob> { new RocketSurgeonsGithubActionsJob("Build") { Steps = steps, Images = _images, } } }; if (Enhancements?.Any() == true) { foreach (var method in Enhancements.Join(build.GetType().GetMethods(), z => z, z => z.Name, (_, e) => e)) { config = method.IsStatic ? method.Invoke(null, new object[] { config }) as RocketSurgeonGitHubActionsConfiguration ?? config : method.Invoke(build, new object[] { config }) as RocketSurgeonGitHubActionsConfiguration ?? config; } } return(config); }
protected static IEnumerable <IConfigurationGenerator> GetGenerators(NukeBuild build) { return(build.GetType().GetCustomAttributes <ConfigurationAttributeBase>()); }