示例#1
0
 internal Boolean TryAddKnownName(
     String value,
     out String error)
 {
     if (!NameValidation.IsValid(value, allowHyphens: true) && value.Length < PipelineConstants.MaxNodeNameLength)
     {
         error = $"The identifier '{value}' is invalid. IDs may only contain alphanumeric characters, '_', and '-'. IDs must start with a letter or '_' and and must be less than {PipelineConstants.MaxNodeNameLength} characters.";
         return(false);
     }
     else if (!m_distinctNames.Add(value))
     {
         error = $"The identifier '{value}' may not be used more than once within the same scope.";
         return(false);
     }
     else
     {
         error = null;
         return(true);
     }
 }
示例#2
0
        private static ActionStep ConvertToStep(
            TemplateContext context,
            TemplateToken stepsItem)
        {
            var step            = stepsItem.AssertMapping($"{PipelineTemplateConstants.Steps} item");
            var continueOnError = default(ScalarToken);
            var env             = default(TemplateToken);
            var id             = default(StringToken);
            var ifCondition    = default(String);
            var ifToken        = default(ScalarToken);
            var name           = default(ScalarToken);
            var run            = default(ScalarToken);
            var scope          = default(StringToken);
            var timeoutMinutes = default(ScalarToken);
            var uses           = default(StringToken);
            var with           = default(TemplateToken);
            var workingDir     = default(ScalarToken);
            var path           = default(ScalarToken);
            var clean          = default(ScalarToken);
            var fetchDepth     = default(ScalarToken);
            var lfs            = default(ScalarToken);
            var submodules     = default(ScalarToken);
            var shell          = default(ScalarToken);

            foreach (var stepProperty in step)
            {
                var propertyName = stepProperty.Key.AssertString($"{PipelineTemplateConstants.Steps} item key");

                switch (propertyName.Value)
                {
                case PipelineTemplateConstants.Clean:
                    clean = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Clean}");
                    break;

                case PipelineTemplateConstants.ContinueOnError:
                    ConvertToStepContinueOnError(context, stepProperty.Value, allowExpressions: true);     // Validate early if possible
                    continueOnError = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} {PipelineTemplateConstants.ContinueOnError}");
                    break;

                case PipelineTemplateConstants.Env:
                    ConvertToStepEnvironment(context, stepProperty.Value, StringComparer.Ordinal, allowExpressions: true);     // Validate early if possible
                    env = stepProperty.Value;
                    break;

                case PipelineTemplateConstants.FetchDepth:
                    fetchDepth = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.FetchDepth}");
                    break;

                case PipelineTemplateConstants.Id:
                    id = stepProperty.Value.AssertString($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Id}");
                    if (!NameValidation.IsValid(id.Value, true))
                    {
                        context.Error(id, $"Step id {id.Value} is invalid. Ids must start with a letter or '_' and contain only alphanumeric characters, '-', or '_'");
                    }
                    break;

                case PipelineTemplateConstants.If:
                    ifToken = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.If}");
                    break;

                case PipelineTemplateConstants.Lfs:
                    lfs = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Lfs}");
                    break;

                case PipelineTemplateConstants.Name:
                    name = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Name}");
                    break;

                case PipelineTemplateConstants.Path:
                    path = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Path}");
                    break;

                case PipelineTemplateConstants.Run:
                    run = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Run}");
                    break;

                case PipelineTemplateConstants.Shell:
                    shell = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Shell}");
                    break;

                case PipelineTemplateConstants.Scope:
                    scope = stepProperty.Value.AssertString($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Scope}");
                    break;

                case PipelineTemplateConstants.Submodules:
                    submodules = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Submodules}");
                    break;

                case PipelineTemplateConstants.TimeoutMinutes:
                    ConvertToStepTimeout(context, stepProperty.Value, allowExpressions: true);     // Validate early if possible
                    timeoutMinutes = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.TimeoutMinutes}");
                    break;

                case PipelineTemplateConstants.Uses:
                    uses = stepProperty.Value.AssertString($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Uses}");
                    break;

                case PipelineTemplateConstants.With:
                    ConvertToStepInputs(context, stepProperty.Value, allowExpressions: true);     // Validate early if possible
                    with = stepProperty.Value;
                    break;

                case PipelineTemplateConstants.WorkingDirectory:
                    workingDir = stepProperty.Value.AssertScalar($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.WorkingDirectory}");
                    break;

                default:
                    propertyName.AssertUnexpectedValue($"{PipelineTemplateConstants.Steps} item key");     // throws
                    break;
                }
            }

            // Fixup the if-condition
            var isDefaultScope = String.IsNullOrEmpty(scope?.Value);

            ifCondition = ConvertToIfCondition(context, ifToken, false, isDefaultScope);

            if (run != null)
            {
                var result = new ActionStep
                {
                    ScopeName        = scope?.Value,
                    ContextName      = id?.Value,
                    ContinueOnError  = continueOnError,
                    DisplayNameToken = name,
                    Condition        = ifCondition,
                    TimeoutInMinutes = timeoutMinutes,
                    Environment      = env,
                    Reference        = new ScriptReference(),
                };

                var inputs = new MappingToken(null, null, null);
                inputs.Add(new StringToken(null, null, null, PipelineConstants.ScriptStepInputs.Script), run);

                if (workingDir != null)
                {
                    inputs.Add(new StringToken(null, null, null, PipelineConstants.ScriptStepInputs.WorkingDirectory), workingDir);
                }

                if (shell != null)
                {
                    inputs.Add(new StringToken(null, null, null, PipelineConstants.ScriptStepInputs.Shell), shell);
                }

                result.Inputs = inputs;

                return(result);
            }
            else
            {
                uses.AssertString($"{PipelineTemplateConstants.Steps} item {PipelineTemplateConstants.Uses}");
                var result = new ActionStep
                {
                    ScopeName        = scope?.Value,
                    ContextName      = id?.Value,
                    ContinueOnError  = continueOnError,
                    DisplayNameToken = name,
                    Condition        = ifCondition,
                    TimeoutInMinutes = timeoutMinutes,
                    Inputs           = with,
                    Environment      = env,
                };

                if (uses.Value.StartsWith("docker://", StringComparison.Ordinal))
                {
                    var image = uses.Value.Substring("docker://".Length);
                    result.Reference = new ContainerRegistryReference {
                        Image = image
                    };
                }
                else if (uses.Value.StartsWith("./") || uses.Value.StartsWith(".\\"))
                {
                    result.Reference = new RepositoryPathReference
                    {
                        RepositoryType = PipelineConstants.SelfAlias,
                        Path           = uses.Value
                    };
                }
                else
                {
                    var usesSegments = uses.Value.Split('@');
                    var pathSegments = usesSegments[0].Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
                    var gitRef       = usesSegments.Length == 2 ? usesSegments[1] : String.Empty;

                    if (usesSegments.Length != 2 ||
                        pathSegments.Length < 2 ||
                        String.IsNullOrEmpty(pathSegments[0]) ||
                        String.IsNullOrEmpty(pathSegments[1]) ||
                        String.IsNullOrEmpty(gitRef))
                    {
                        // todo: loc
                        context.Error(uses, $"Expected format {{org}}/{{repo}}[/path]@ref. Actual '{uses.Value}'");
                    }
                    else
                    {
                        var repositoryName = $"{pathSegments[0]}/{pathSegments[1]}";
                        var directoryPath  = pathSegments.Length > 2 ? String.Join("/", pathSegments.Skip(2)) : String.Empty;

                        result.Reference = new RepositoryPathReference
                        {
                            RepositoryType = RepositoryTypes.GitHub,
                            Name           = repositoryName,
                            Ref            = gitRef,
                            Path           = directoryPath,
                        };
                    }
                }

                return(result);
            }
        }