private Pipelines.AgentJobRequestMessage CreateJobRequestMessage(string jobName) { TaskOrchestrationPlanReference plan = new TaskOrchestrationPlanReference() { PlanId = Guid.NewGuid() }; TimelineReference timeline = null; Dictionary <string, VariableValue> variables = new Dictionary <string, VariableValue>(StringComparer.OrdinalIgnoreCase); variables[Constants.Variables.System.Culture] = "en-US"; Pipelines.JobResources resources = new Pipelines.JobResources(); var serviceEndpoint = new ServiceEndpoint(); serviceEndpoint.Authorization = new EndpointAuthorization(); serviceEndpoint.Authorization.Parameters.Add("nullValue", null); resources.Endpoints.Add(serviceEndpoint); List <Pipelines.ActionStep> actions = new List <Pipelines.ActionStep>(); actions.Add(new Pipelines.ActionStep() { Id = Guid.NewGuid(), Reference = new Pipelines.RepositoryPathReference() { RepositoryType = "GitHub", Name = "actions/test", Ref = "v1" } }); Guid JobId = Guid.NewGuid(); var sidecarContainers = new MappingToken(null, null, null) { { new StringToken(null, null, null, "nginx"), new MappingToken(null, null, null) { { new StringToken(null, null, null, "image"), new StringToken(null, null, null, "nginx") }, } }, }; var context = new Pipelines.ContextData.DictionaryContextData { { "github", new Pipelines.ContextData.DictionaryContextData() }, }; var jobRequest = new Pipelines.AgentJobRequestMessage(plan, timeline, JobId, jobName, jobName, new StringToken(null, null, null, "ubuntu"), sidecarContainers, null, variables, new List <MaskHint>(), resources, context, null, actions, null, null, null); return(jobRequest); }
// Download all required actions. // Make sure all condition inputs are valid. // Build up three list of steps for jobrunner (pre-job, job, post-job). public async Task <List <IStep> > InitializeJob(IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message) { Trace.Entering(); ArgUtil.NotNull(jobContext, nameof(jobContext)); ArgUtil.NotNull(message, nameof(message)); // Create a new timeline record for 'Set up job' IExecutionContext context = jobContext.CreateChild(Guid.NewGuid(), "Set up job", $"{nameof(JobExtension)}_Init", null, null); List <IStep> preJobSteps = new List <IStep>(); List <IStep> jobSteps = new List <IStep>(); using (var register = jobContext.CancellationToken.Register(() => { context.CancelToken(); })) { try { context.Start(); context.Debug($"Starting: Set up job"); context.Output($"Current runner version: '{BuildConstants.RunnerPackage.Version}'"); var repoFullName = context.GetGitHubContext("repository"); ArgUtil.NotNull(repoFullName, nameof(repoFullName)); context.Debug($"Primary repository: {repoFullName}"); // Print proxy setting information for better diagnostic experience if (!string.IsNullOrEmpty(HostContext.WebProxy.HttpProxyAddress)) { context.Output($"Runner is running behind proxy server '{HostContext.WebProxy.HttpProxyAddress}' for all HTTP requests."); } if (!string.IsNullOrEmpty(HostContext.WebProxy.HttpsProxyAddress)) { context.Output($"Runner is running behind proxy server '{HostContext.WebProxy.HttpsProxyAddress}' for all HTTPS requests."); } // Prepare the workflow directory context.Output("Prepare workflow directory"); var directoryManager = HostContext.GetService <IPipelineDirectoryManager>(); TrackingConfig trackingConfig = directoryManager.PrepareDirectory( context, message.Workspace); // Set the directory variables context.Debug("Update context data"); string _workDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); context.SetRunnerContext("workspace", Path.Combine(_workDirectory, trackingConfig.PipelineDirectory)); context.SetGitHubContext("workspace", Path.Combine(_workDirectory, trackingConfig.WorkspaceDirectory)); // Evaluate the job-level environment variables context.Debug("Evaluating job-level environment variables"); var templateEvaluator = context.ToPipelineTemplateEvaluator(); foreach (var token in message.EnvironmentVariables) { var environmentVariables = templateEvaluator.EvaluateStepEnvironment(token, jobContext.ExpressionValues, VarUtil.EnvironmentVariableKeyComparer); foreach (var pair in environmentVariables) { context.EnvironmentVariables[pair.Key] = pair.Value ?? string.Empty; context.SetEnvContext(pair.Key, pair.Value ?? string.Empty); } } // Evaluate the job container context.Debug("Evaluating job container"); var container = templateEvaluator.EvaluateJobContainer(message.JobContainer, jobContext.ExpressionValues); if (container != null) { jobContext.Container = new Container.ContainerInfo(HostContext, container); } // Evaluate the job service containers context.Debug("Evaluating job service containers"); var serviceContainers = templateEvaluator.EvaluateJobServiceContainers(message.JobServiceContainers, jobContext.ExpressionValues); if (serviceContainers?.Count > 0) { foreach (var pair in serviceContainers) { var networkAlias = pair.Key; var serviceContainer = pair.Value; jobContext.ServiceContainers.Add(new Container.ContainerInfo(HostContext, serviceContainer, false, networkAlias)); } } // Build up 2 lists of steps, pre-job, job // Download actions not already in the cache Trace.Info("Downloading actions"); var actionManager = HostContext.GetService <IActionManager>(); var prepareSteps = await actionManager.PrepareActionsAsync(context, message.Steps); preJobSteps.AddRange(prepareSteps); // Add start-container steps, record and stop-container steps if (jobContext.Container != null || jobContext.ServiceContainers.Count > 0) { var containerProvider = HostContext.GetService <IContainerOperationProvider>(); var containers = new List <Container.ContainerInfo>(); if (jobContext.Container != null) { containers.Add(jobContext.Container); } containers.AddRange(jobContext.ServiceContainers); preJobSteps.Add(new JobExtensionRunner(runAsync: containerProvider.StartContainersAsync, condition: $"{PipelineTemplateConstants.Success}()", displayName: "Initialize containers", data: (object)containers)); } // Add action steps foreach (var step in message.Steps) { if (step.Type == Pipelines.StepType.Action) { var action = step as Pipelines.ActionStep; Trace.Info($"Adding {action.DisplayName}."); var actionRunner = HostContext.CreateService <IActionRunner>(); actionRunner.Action = action; actionRunner.Stage = ActionRunStage.Main; actionRunner.Condition = step.Condition; var contextData = new Pipelines.ContextData.DictionaryContextData(); if (message.ContextData?.Count > 0) { foreach (var pair in message.ContextData) { contextData[pair.Key] = pair.Value; } } actionRunner.TryEvaluateDisplayName(contextData, context); jobSteps.Add(actionRunner); } } // Create execution context for pre-job steps foreach (var step in preJobSteps) { if (step is JobExtensionRunner) { JobExtensionRunner extensionStep = step as JobExtensionRunner; ArgUtil.NotNull(extensionStep, extensionStep.DisplayName); Guid stepId = Guid.NewGuid(); extensionStep.ExecutionContext = jobContext.CreateChild(stepId, extensionStep.DisplayName, null, null, stepId.ToString("N")); } } // Create execution context for job steps foreach (var step in jobSteps) { if (step is IActionRunner actionStep) { ArgUtil.NotNull(actionStep, step.DisplayName); actionStep.ExecutionContext = jobContext.CreateChild(actionStep.Action.Id, actionStep.DisplayName, actionStep.Action.Name, actionStep.Action.ScopeName, actionStep.Action.ContextName); } } List <IStep> steps = new List <IStep>(); steps.AddRange(preJobSteps); steps.AddRange(jobSteps); // Prepare for orphan process cleanup _processCleanup = jobContext.Variables.GetBoolean("process.clean") ?? true; if (_processCleanup) { // Set the RUNNER_TRACKING_ID env variable. Environment.SetEnvironmentVariable(Constants.ProcessTrackingId, _processLookupId); context.Debug("Collect running processes for tracking orphan processes."); // Take a snapshot of current running processes Dictionary <int, Process> processes = SnapshotProcesses(); foreach (var proc in processes) { // Pid_ProcessName _existingProcesses.Add($"{proc.Key}_{proc.Value.ProcessName}"); } } return(steps); } catch (OperationCanceledException ex) when(jobContext.CancellationToken.IsCancellationRequested) { // Log the exception and cancel the JobExtension Initialization. Trace.Error($"Caught cancellation exception from JobExtension Initialization: {ex}"); context.Error(ex); context.Result = TaskResult.Canceled; throw; } catch (Exception ex) { // Log the error and fail the JobExtension Initialization. Trace.Error($"Caught exception from JobExtension Initialization: {ex}"); context.Error(ex); context.Result = TaskResult.Failed; throw; } finally { context.Debug("Finishing: Set up job"); context.Complete(); } } }