// Prepare build directory
        // Set all build related variables
        public override void InitializeJobExtension(IExecutionContext executionContext, IList <Pipelines.JobStep> steps, Pipelines.WorkspaceOptions workspace)
        {
            // Validate args.
            Trace.Entering();
            ArgUtil.NotNull(executionContext, nameof(executionContext));

            // This flag can be false for jobs like cleanup artifacts.
            // If syncSources = false, we will not set source related build variable, not create build folder, not sync source.
            bool syncSources = executionContext.Variables.Build_SyncSources ?? true;

            if (!syncSources)
            {
                Trace.Info($"{Constants.Variables.Build.SyncSources} = false, we will not set source related build variable, not create build folder and not sync source");
                return;
            }

            // We set the variables based on the 'self' repository
            if (!TryGetRepositoryInfo(executionContext, out RepositoryInfo repoInfo))
            {
                throw new Exception(StringUtil.Loc("SupportedRepositoryEndpointNotFound"));
            }

            executionContext.Debug($"Primary repository: {repoInfo.Repository.Properties.Get<string>(Pipelines.RepositoryPropertyNames.Name)}. repository type: {repoInfo.Repository.Type}");

            // Set the repo variables.
            if (!string.IsNullOrEmpty(repoInfo.Repository.Id)) // TODO: Move to const after source artifacts PR is merged.
            {
                executionContext.SetVariable(Constants.Variables.Build.RepoId, repoInfo.Repository.Id);
            }

            executionContext.SetVariable(Constants.Variables.Build.RepoName, repoInfo.Repository.Properties.Get <string>(Pipelines.RepositoryPropertyNames.Name));
            executionContext.SetVariable(Constants.Variables.Build.RepoProvider, ConvertToLegacyRepositoryType(repoInfo.Repository.Type));
            executionContext.SetVariable(Constants.Variables.Build.RepoUri, repoInfo.Repository.Url?.AbsoluteUri);

            // Prepare the build directory.
            executionContext.Output(StringUtil.Loc("PrepareBuildDir"));
            var            directoryManager = HostContext.GetService <IBuildDirectoryManager>();
            TrackingConfig trackingConfig   = directoryManager.PrepareDirectory(
                executionContext,
                executionContext.Repositories,
                workspace);

            string _workDirectory             = HostContext.GetDirectory(WellKnownDirectory.Work);
            string pipelineWorkspaceDirectory = Path.Combine(_workDirectory, trackingConfig.BuildDirectory);

            UpdateCheckoutTasksAndVariables(executionContext, steps, repoInfo, pipelineWorkspaceDirectory);

            // Set the directory variables.
            executionContext.Output(StringUtil.Loc("SetBuildVars"));
            executionContext.SetVariable(Constants.Variables.Agent.BuildDirectory, pipelineWorkspaceDirectory, isFilePath: true);
            executionContext.SetVariable(Constants.Variables.System.ArtifactsDirectory, Path.Combine(_workDirectory, trackingConfig.ArtifactsDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.System.DefaultWorkingDirectory, Path.Combine(_workDirectory, trackingConfig.SourcesDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Common.TestResultsDirectory, Path.Combine(_workDirectory, trackingConfig.TestResultsDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.BinariesDirectory, Path.Combine(_workDirectory, trackingConfig.BuildDirectory, Constants.Build.Path.BinariesDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.SourcesDirectory, Path.Combine(_workDirectory, trackingConfig.SourcesDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.StagingDirectory, Path.Combine(_workDirectory, trackingConfig.ArtifactsDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.ArtifactStagingDirectory, Path.Combine(_workDirectory, trackingConfig.ArtifactsDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.RepoLocalPath, Path.Combine(_workDirectory, trackingConfig.SourcesDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Pipeline.Workspace, pipelineWorkspaceDirectory, isFilePath: true);
        }
Example #2
0
 public override void InitializeJobExtension(IExecutionContext context, IList <Pipelines.JobStep> steps, Pipelines.WorkspaceOptions workspace)
 {
     return;
 }
        // Prepare build directory
        // Set all build related variables
        public override void InitializeJobExtension(IExecutionContext executionContext, IList <Pipelines.JobStep> steps, Pipelines.WorkspaceOptions workspace)
        {
            // Validate args.
            Trace.Entering();
            ArgUtil.NotNull(executionContext, nameof(executionContext));

            // This flag can be false for jobs like cleanup artifacts.
            // If syncSources = false, we will not set source related build variable, not create build folder, not sync source.
            bool syncSources = executionContext.Variables.Build_SyncSources ?? true;

            if (!syncSources)
            {
                Trace.Info($"{Constants.Variables.Build.SyncSources} = false, we will not set source related build variable, not create build folder and not sync source");
                return;
            }

            // We set the variables based on the 'self' repository
            if (!TryGetRepositoryInfo(executionContext, out RepositoryInfo repoInfo))
            {
                throw new Exception(StringUtil.Loc("SupportedRepositoryEndpointNotFound"));
            }

            executionContext.Debug($"Primary repository: {repoInfo.Repository.Properties.Get<string>(Pipelines.RepositoryPropertyNames.Name)}. repository type: {repoInfo.Repository.Type}");

            // Set the repo variables.
            if (!string.IsNullOrEmpty(repoInfo.Repository.Id)) // TODO: Move to const after source artifacts PR is merged.
            {
                executionContext.Variables.Set(Constants.Variables.Build.RepoId, repoInfo.Repository.Id);
            }

            executionContext.Variables.Set(Constants.Variables.Build.RepoName, repoInfo.Repository.Properties.Get <string>(Pipelines.RepositoryPropertyNames.Name));
            executionContext.Variables.Set(Constants.Variables.Build.RepoProvider, ConvertToLegacyRepositoryType(repoInfo.Repository.Type));
            executionContext.Variables.Set(Constants.Variables.Build.RepoUri, repoInfo.Repository.Url?.AbsoluteUri);

            // There may be more than one Checkout task, but for back compat we will simply pay attention to the first checkout task here
            var checkoutTask = steps.FirstOrDefault(x => x.IsCheckoutTask()) as Pipelines.TaskStep;

            if (checkoutTask != null)
            {
                if (checkoutTask.Inputs.ContainsKey(Pipelines.PipelineConstants.CheckoutTaskInputs.Submodules))
                {
                    executionContext.Variables.Set(Constants.Variables.Build.RepoGitSubmoduleCheckout, Boolean.TrueString);
                }
                else
                {
                    executionContext.Variables.Set(Constants.Variables.Build.RepoGitSubmoduleCheckout, Boolean.FalseString);
                }

                // overwrite primary repository's clean value if build.repository.clean is sent from server. this is used by tfvc gated check-in
                bool?repoClean = executionContext.Variables.GetBoolean(Constants.Variables.Build.RepoClean);
                if (repoClean != null)
                {
                    checkoutTask.Inputs[Pipelines.PipelineConstants.CheckoutTaskInputs.Clean] = repoClean.Value.ToString();
                }
                else
                {
                    if (checkoutTask.Inputs.ContainsKey(Pipelines.PipelineConstants.CheckoutTaskInputs.Clean))
                    {
                        executionContext.Variables.Set(Constants.Variables.Build.RepoClean, checkoutTask.Inputs[Pipelines.PipelineConstants.CheckoutTaskInputs.Clean]);
                    }
                    else
                    {
                        executionContext.Variables.Set(Constants.Variables.Build.RepoClean, Boolean.FalseString);
                    }
                }
            }


            // Prepare the build directory.
            executionContext.Output(StringUtil.Loc("PrepareBuildDir"));
            var            directoryManager = HostContext.GetService <IBuildDirectoryManager>();
            TrackingConfig trackingConfig   = directoryManager.PrepareDirectory(
                executionContext,
                executionContext.Repositories,
                workspace);

            // Set the directory variables.
            executionContext.Output(StringUtil.Loc("SetBuildVars"));
            string _workDirectory = HostContext.GetDirectory(WellKnownDirectory.Work);

            executionContext.SetVariable(Constants.Variables.Agent.BuildDirectory, Path.Combine(_workDirectory, trackingConfig.BuildDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.System.ArtifactsDirectory, Path.Combine(_workDirectory, trackingConfig.ArtifactsDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.System.DefaultWorkingDirectory, Path.Combine(_workDirectory, trackingConfig.SourcesDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Common.TestResultsDirectory, Path.Combine(_workDirectory, trackingConfig.TestResultsDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.BinariesDirectory, Path.Combine(_workDirectory, trackingConfig.BuildDirectory, Constants.Build.Path.BinariesDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.SourcesDirectory, Path.Combine(_workDirectory, trackingConfig.SourcesDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.StagingDirectory, Path.Combine(_workDirectory, trackingConfig.ArtifactsDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.ArtifactStagingDirectory, Path.Combine(_workDirectory, trackingConfig.ArtifactsDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Build.RepoLocalPath, Path.Combine(_workDirectory, trackingConfig.SourcesDirectory), isFilePath: true);
            executionContext.SetVariable(Constants.Variables.Pipeline.Workspace, Path.Combine(_workDirectory, trackingConfig.BuildDirectory), isFilePath: true);
        }
Example #4
0
 // Anything job extension want to do before building the steps list.
 public abstract void InitializeJobExtension(IExecutionContext context, IList <Pipelines.JobStep> steps, Pipelines.WorkspaceOptions workspace);
        private TestHostContext Setup([CallerMemberName] string name    = "",
                                      bool createWorkDirectory          = true,
                                      CheckoutConfigType checkOutConfig = CheckoutConfigType.SingleCheckoutDefaultPath,
                                      string pathToSelfRepo             = "")
        {
            bool isMulticheckoutScenario = checkOutConfig == CheckoutConfigType.MultiCheckoutCustomPath || checkOutConfig == CheckoutConfigType.MultiCheckoutDefaultPath;
            bool isCustomPathScenario    = checkOutConfig == CheckoutConfigType.SingleCheckoutCustomPath || checkOutConfig == CheckoutConfigType.MultiCheckoutCustomPath;

            TestHostContext hc = new TestHostContext(this, name);

            this.stubWorkFolder = hc.GetDirectory(WellKnownDirectory.Work);
            if (createWorkDirectory)
            {
                Directory.CreateDirectory(this.stubWorkFolder);
            }

            _ec = new Mock <IExecutionContext>();

            _extensionManager      = new Mock <IExtensionManager>();
            _sourceProvider        = new Mock <ISourceProvider>();
            _buildDirectoryManager = new Mock <IBuildDirectoryManager>();
            _workspaceOptions      = new Pipelines.WorkspaceOptions();
            _configurationStore    = new Mock <IConfigurationStore>();
            _configurationStore.Setup(store => store.GetSettings()).Returns(new AgentSettings {
                WorkFolder = this.stubWorkFolder
            });

            steps = new List <Pipelines.JobStep>();
            var selfCheckoutTask = new Pipelines.TaskStep()
            {
                Reference = new Pipelines.TaskStepDefinitionReference()
                {
                    Id      = Guid.Parse("6d15af64-176c-496d-b583-fd2ae21d4df4"),
                    Name    = "Checkout",
                    Version = "1.0.0"
                }
            };

            selfCheckoutTask.Inputs.Add("repository", "self");
            if (isCustomPathScenario)
            {
                selfCheckoutTask.Inputs.Add("path", pathToSelfRepo);
            }
            steps.Add(selfCheckoutTask);

            // Setup second checkout only for multicheckout jobs
            if (isMulticheckoutScenario)
            {
                var anotherCheckoutTask = new Pipelines.TaskStep()
                {
                    Reference = new Pipelines.TaskStepDefinitionReference()
                    {
                        Id      = Guid.Parse("6d15af64-176c-496d-b583-fd2ae21d4df4"),
                        Name    = "Checkout",
                        Version = "1.0.0"
                    }
                };
                anotherCheckoutTask.Inputs.Add("repository", "BuildRepo");
                anotherCheckoutTask.Inputs.Add("path", "s/BuildRepo");
                steps.Add(anotherCheckoutTask);
            }

            hc.SetSingleton(_buildDirectoryManager.Object);
            hc.SetSingleton(_extensionManager.Object);
            hc.SetSingleton(_configurationStore.Object);

            var buildVariables = GetBuildVariables();

            _variables = new Variables(hc, buildVariables, out _);
            _ec.Setup(x => x.Variables).Returns(_variables);

            repositories = new List <Pipelines.RepositoryResource>();
            repositories.Add(GetRepository(hc, "self", "App", "App"));
            repositories.Add(GetRepository(hc, "repo2", "BuildRepo", "BuildRepo"));
            _ec.Setup(x => x.Repositories).Returns(repositories);

            jobSettings = new Dictionary <string, string>();
            jobSettings.Add(WellKnownJobSettings.HasMultipleCheckouts, isMulticheckoutScenario.ToString());
            _ec.Setup(x => x.JobSettings).Returns(jobSettings);

            _ec.Setup(x =>
                      x.SetVariable(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <bool>()))
            .Callback((string varName, string varValue, bool isSecret, bool isOutput, bool isFilePath, bool isReadOnly) => { _variables.Set(varName, varValue, false); });

            _extensionManager.Setup(x => x.GetExtensions <ISourceProvider>())
            .Returns(new List <ISourceProvider> {
                _sourceProvider.Object
            });

            _sourceProvider.Setup(x => x.RepositoryType)
            .Returns(Pipelines.RepositoryTypes.ExternalGit);

            _buildDirectoryManager.Setup(x => x.PrepareDirectory(_ec.Object, repositories, _workspaceOptions))
            .Returns(new TrackingConfig(_ec.Object, repositories, 1));

            buildJobExtension = new BuildJobExtension();
            buildJobExtension.Initialize(hc);
            return(hc);
        }
        // TODO: Updates legacy config.

        private TestHostContext Setup(
            [CallerMemberName] string name        = "",
            BuildCleanOption?cleanOption          = null,
            ExistingConfigKind existingConfigKind = ExistingConfigKind.None)
        {
            // Setup the host context.
            TestHostContext hc = new TestHostContext(this, name);

            // Create a random work path.
            var configStore = new Mock <IConfigurationStore>();

            _workFolder = hc.GetDirectory(WellKnownDirectory.Work);
            var settings = new AgentSettings()
            {
                WorkFolder = _workFolder
            };

            configStore.Setup(x => x.GetSettings()).Returns(settings);
            hc.SetSingleton <IConfigurationStore>(configStore.Object);

            // Setup the execution context.
            _ec = new Mock <IExecutionContext>();
            List <string> warnings;

            _variables = new Variables(hc, new Dictionary <string, VariableValue>(), out warnings);
            _variables.Set(Constants.Variables.System.CollectionId, CollectionId);
            _variables.Set(Constants.Variables.System.DefinitionId, DefinitionId);
            _variables.Set(Constants.Variables.Build.Clean, $"{cleanOption}");
            _ec.Setup(x => x.Variables).Returns(_variables);

            // Store the expected tracking file path.
            _trackingFile = Path.Combine(
                _workFolder,
                Constants.Build.Path.SourceRootMappingDirectory,
                _ec.Object.Variables.System_CollectionId,
                _ec.Object.Variables.System_DefinitionId,
                Constants.Build.Path.TrackingConfigFile);

            // Setup the endpoint.
            _repository = new Pipelines.RepositoryResource()
            {
                Alias = "self",
                Type  = Pipelines.RepositoryTypes.Git,
                Url   = new Uri("http://contoso.visualstudio.com"),
            };
            _repository.Properties.Set <String>(Pipelines.RepositoryPropertyNames.Name, "Some endpoint name");

            _workspaceOptions = new Pipelines.WorkspaceOptions();
            // // Setup the source provider.
            // _sourceProvider = new Mock<ISourceProvider>();
            // _sourceProvider
            //     .Setup(x => x.GetBuildDirectoryHashKey(_ec.Object, _repository))
            //     .Returns(HashKey);
            // hc.SetSingleton<ISourceProvider>(_sourceProvider.Object);

            // Store the existing config object.
            switch (existingConfigKind)
            {
            case ExistingConfigKind.Matching:
                _existingConfig = new TrackingConfig(_ec.Object, _repository, 1, HashKey);
                Assert.Equal("1", _existingConfig.BuildDirectory);
                break;

            case ExistingConfigKind.Nonmatching:
                _existingConfig = new TrackingConfig(_ec.Object, _repository, 2, NonmatchingHashKey);
                Assert.Equal("2", _existingConfig.BuildDirectory);
                break;

            case ExistingConfigKind.None:
                break;

            default:
                throw new NotSupportedException();
            }

            // Store the new config object.
            if (existingConfigKind == ExistingConfigKind.Matching)
            {
                _newConfig = _existingConfig;
            }
            else
            {
                _newConfig = new TrackingConfig(_ec.Object, _repository, 3, HashKey);
                Assert.Equal("3", _newConfig.BuildDirectory);
            }

            // Setup the tracking manager.
            _trackingManager = new Mock <ITrackingManager>();
            _trackingManager
            .Setup(x => x.LoadIfExists(_ec.Object, _trackingFile))
            .Returns(_existingConfig);
            if (existingConfigKind == ExistingConfigKind.None || existingConfigKind == ExistingConfigKind.Nonmatching)
            {
                _trackingManager
                .Setup(x => x.Create(_ec.Object, _repository, HashKey, _trackingFile, false))
                .Returns(_newConfig);
                if (existingConfigKind == ExistingConfigKind.Nonmatching)
                {
                    _trackingManager
                    .Setup(x => x.MarkForGarbageCollection(_ec.Object, _existingConfig));
                }
            }
            else if (existingConfigKind == ExistingConfigKind.Matching)
            {
                _trackingManager
                .Setup(x => x.UpdateJobRunProperties(_ec.Object, _existingConfig, _trackingFile));
            }
            else
            {
                throw new NotSupportedException();
            }

            hc.SetSingleton <ITrackingManager>(_trackingManager.Object);

            // Setup the build directory manager.
            _buildDirectoryManager = new BuildDirectoryManager();
            _buildDirectoryManager.Initialize(hc);
            return(hc);
        }