using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.Serialization; namespace GitHub.Actions.WorkflowParser { /// /// Features flags (mostly short-lived) /// [DataContract] public class WorkflowFeatures { /// /// Gets or sets a value indicating whether users may specify permission "id-token". /// Used during parsing only. /// [DataMember(EmitDefaultValue = false)] public bool IdToken { get; set; } // Remove with DistributedTask.AllowGenerateIdToken /// /// Gets or sets a value indicating whether users may specify permission "short-matrix-ids". /// Used during parsing and evaluation. /// [DataMember(EmitDefaultValue = false)] public bool ShortMatrixIds { get; set; } // Remove with DistributedTask.GenerateShortMatrixIds /// /// Gets or sets a value indicating whether users may use the "snapshot" keyword. /// Used during parsing only. /// More information: https://github.com/github/hosted-runners/issues/186 /// [DataMember(EmitDefaultValue = false)] public bool Snapshot { get; set; } /// /// Gets or sets a value indicating whether users may use the "models" permission. /// Used during parsing only. /// [DataMember(EmitDefaultValue = false)] public bool AllowModelsPermission { get; set; } /// /// Gets or sets a value indicating whether the expression function fromJson performs strict JSON parsing. /// Used during evaluation only. /// [DataMember(EmitDefaultValue = false)] public bool StrictJsonParsing { get; set; } /// /// Gets or sets a value indicating whether service containers may specify "entrypoint" and "command". /// Used during parsing and evaluation. /// [DataMember(EmitDefaultValue = false)] public bool AllowServiceContainerCommand { get; set; } /// /// Gets the default workflow features. /// public static WorkflowFeatures GetDefaults() { return new WorkflowFeatures { IdToken = true, // Default to true since this is a long-lived feature flag ShortMatrixIds = true, // Default to true since this is a long-lived feature flag Snapshot = false, // Default to false since this feature is still in an experimental phase StrictJsonParsing = false, // Default to false since this is temporary for telemetry purposes only AllowModelsPermission = false, // Default to false since we want this to be disabled for all non-production environments AllowServiceContainerCommand = false, // Default to false since this feature is gated by actions_service_container_command }; } /// /// Gets the value of the feature flag /// public bool GetFeature(string name) { return (bool)s_properties[name].GetValue(this)!; } /// /// Sets the value of the feature flag /// public void SetFeature(string name, bool value) { s_properties[name].SetValue(this, value); } /// /// Reflection info for accessing the feature flags /// private static readonly Dictionary s_properties = typeof(WorkflowFeatures).GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.PropertyType == typeof(bool)) // Boolean properties only .ToDictionary(x => x.Name, StringComparer.Ordinal); /// /// Names of all feature flags /// public static readonly IReadOnlyList Names = s_properties.Keys.Order().ToList().AsReadOnly(); } }