public void CreateEnvironment(string project, string release, Guid environmentId, JObject jsonVariables) { ReleaseDefinition releaseDefinition = GetRelease(project, release); ReleaseDefinitionEnvironmentTemplate environmentTemplate = GetEnvironmentTemplate(project, environmentId); ReleaseDefinitionEnvironment environment = environmentTemplate.Environment; int maxRank = releaseDefinition.Environments.Max(x => x.Rank); environment.Rank = maxRank + 1; environment.Name = Guid.NewGuid().ToString(); List <string> variables = environment.Variables.Keys.ToList(); foreach (var variable in variables) { environment.Variables[variable] = new ConfigurationVariableValue() { Value = "" }; } if (jsonVariables != null) { foreach (var variable in jsonVariables) { environment.Variables[variable.Key] = new ConfigurationVariableValue() { Value = variable.Value.ToString() }; } } releaseDefinition.Environments.Add(environment); Task <ReleaseDefinition> result = releaseClient.UpdateReleaseDefinitionAsync(releaseDefinition, project); ReleaseDefinition update = result.Result; }
private ReleaseDefinitionEnvironment BuildEnvironment(CreateReleaseDefinitionQuery message, Model.Environment environment, string buildDefinitionName) { List <WorkflowTask> workflowTasks = GetWorkflowTasks(message, environment); var releaseDefinitionEnvironment = new ReleaseDefinitionEnvironment() { Name = environment.EnvironmentName, Variables = new Dictionary <string, ConfigurationVariableValue>(), RetentionPolicy = new EnvironmentRetentionPolicy { DaysToKeep = 30, ReleasesToKeep = 1 }, PreDeployApprovals = new ReleaseDefinitionApprovals() { Approvals = new List <ReleaseDefinitionApprovalStep>() { new ReleaseDefinitionApprovalStep() { Rank = 1, IsAutomated = true } } }, PostDeployApprovals = new ReleaseDefinitionApprovals() { Approvals = new List <ReleaseDefinitionApprovalStep> { new ReleaseDefinitionApprovalStep() { Rank = 1, IsAutomated = true } } }, DeployPhases = new List <DeployPhase>() { new AgentBasedDeployPhase() { Name = "Run on agent", Rank = 1, DeploymentInput = new AgentDeploymentInput() { QueueId = 7 //linux //todo }, WorkflowTasks = workflowTasks } }, Conditions = new List <Condition>() { new Condition("ReleaseStarted", ConditionType.Event, string.Empty) } }; AddEnvironmentVariables(message, environment, buildDefinitionName, releaseDefinitionEnvironment.Variables); return(releaseDefinitionEnvironment); }
/// <summary> /// deep clone using <see cref="DataContractSerializer"/> /// </summary> /// <param name="original">original instance</param> /// <returns>new instance (deep clone)</returns> public static ReleaseDefinitionEnvironment DeepClone(this ReleaseDefinitionEnvironment original) { using (var stream = new MemoryStream()) { var dcs = new DataContractSerializer(typeof(ReleaseDefinitionEnvironment)); //all the structures are wcf data contracts dcs.WriteObject(stream, original); stream.Position = 0; return((ReleaseDefinitionEnvironment)dcs.ReadObject(stream)); } }
public bool CloneReleaseEnvironment(string SourceEnvName, string TargetEnvName, int DeployGroupId) { bool success = false; //This call is to get the project GUID var project = projclient.GetProject(TfsEnvInfo.ProjectName).Result; //This returns everything in a definition including properties such as Owner in an Environment var def = relclient.GetReleaseDefinitionAsync(project.Id, TfsEnvInfo.ReleaseDefinitionID).Result; var envcount = def.Environments.Count; var source = def.Environments.Where(e => e.Name == SourceEnvName).First(); var newrank = def.Environments.Select(e => e.Rank).ToList().Max() + 1; //Environment must have a minimum RetentionPolicy, Rank, Owner, //PreDeployApprovals, PostDeployApprovals and DeployPhases var target = new ReleaseDefinitionEnvironment() { Name = TargetEnvName + " - Clone from " + SourceEnvName, RetentionPolicy = source.RetentionPolicy, Rank = newrank, Owner = source.Owner, PreDeployApprovals = source.PreDeployApprovals, PostDeployApprovals = source.PostDeployApprovals }; //Clone phases and tasks var newphases = source.DeployPhases.ToList(); //Update deployment group name in phases foreach (var p in newphases) { if (p.PhaseType == DeployPhaseTypes.MachineGroupBasedDeployment) { var m = ((MachineGroupBasedDeployPhase)p); var inputs = m.GetDeploymentInput(); var newinputs = (MachineGroupDeploymentInput)inputs.Clone(); newinputs.QueueId = DeployGroupId; m.DeploymentInput = newinputs; } } target.DeployPhases = newphases; def.Environments.Add(target); var newdef = relclient.UpdateReleaseDefinitionAsync(def, project.Id).Result; //Basic detection if environment was added if (newdef.Environments.Count > envcount) { success = true; } return(success); }
public bool CloneReleaseEnvironment(string SourceEnvName, string TargetEnvName) { bool success = false; var definitions = relclient.GetReleaseDefinitionsAsync(TfsEnvInfo.ProjectName, TfsEnvInfo.ReleaseDefinitionName, ReleaseDefinitionExpands.Environments, isExactNameMatch: true).Result; //This call is to get the project GUID var project = projclient.GetProject(TfsEnvInfo.ProjectName).Result; //This returns everything in a definition including properties such as Owner in an Environment var def = relclient.GetReleaseDefinitionAsync(project.Id, definitions.First().Id).Result; var envcount = def.Environments.Count; var source = def.Environments.Where(e => e.Name == SourceEnvName).First(); //Environment must have a minimum RetentionPolicy, Rank, Owner, //PreDeployApprovals, PostDeployApprovals and DeployPhases var target = new ReleaseDefinitionEnvironment() { Name = TargetEnvName, RetentionPolicy = source.RetentionPolicy, Rank = source.Rank++, Owner = source.Owner, PreDeployApprovals = source.PreDeployApprovals, PostDeployApprovals = source.PostDeployApprovals, DeployPhases = source.DeployPhases }; def.Environments.Add(target); var newdef = relclient.UpdateReleaseDefinitionAsync(def, project.Id).Result; //Basic detection if environment was added if (newdef.Environments.Count > envcount) { success = true; } return(success); }
public async Task <List <DisplayEnvironment> > GetEnvironmentsAsync() { var client = VssClientHelper.GetClient <ReleaseHttpClient>( Settings.GlobalSettings.Current.AccountUrl, Settings.GlobalSettings.Current.ApiKey, Settings.GlobalSettings.Current.UseSsl); var environments = new List <DisplayEnvironment>(); List <ReleaseDefinition> definitions = await client.GetReleaseDefinitionsAsync(Settings.GlobalSettings.Current.Project, expand : ReleaseDefinitionExpands.Environments); string[] environmentNames = definitions.SelectMany(d => d.Environments).Select(e => e.Name).Distinct().ToArray(); List <Release> releases = await client.GetReleasesAsync( Settings.GlobalSettings.Current.Project, expand : ReleaseExpands.Environments, // Reduce number of releases to load faster minCreatedTime : DateTime.Today.AddMonths(-6)); foreach (string environmentName in environmentNames) { var environment = new DisplayEnvironment { Name = environmentName }; foreach (ReleaseDefinition definition in definitions) { ReleaseDefinitionEnvironment definitionEnvironment = definition.Environments.FirstOrDefault(e => e.Name == environmentName); if (definitionEnvironment == null) { continue; } Release[] definitionReleases = releases .Where(r => r.ReleaseDefinitionReference.Id == definition.Id && r.Environments.Any(e => e.Name == environmentName)) .OrderBy(r => r.CreatedOn) .ToArray(); Release lastSuccess = definitionReleases.LastOrDefault(r => r.Environments.First(e => e.Name == environmentName).Status == EnvironmentStatus.Succeeded); Release last = definitionReleases.LastOrDefault(); ReleaseEnvironment releaseEnvironment = last?.Environments.First(e => e.Name == environmentName); environment.Releases.Add(new DisplayRelease { Id = last?.Id ?? 0, DefinitionId = definition.Id, EnvironmentId = releaseEnvironment?.Id, Name = definition.Name, AvailableVersion = last != null ? Regex.Match(last.Name, Settings.GlobalSettings.Current.ReleaseNameExtractVersionRegex).Value : null, AvailableVersionLink = (last?.Links.Links["web"] as ReferenceLink)?.Href, LastDeployedVersion = lastSuccess != null ? Regex.Match(lastSuccess.Name, Settings.GlobalSettings.Current.ReleaseNameExtractVersionRegex).Value : String.Empty, LastDeployedVersionLink = (lastSuccess?.Links.Links["web"] as ReferenceLink)?.Href, Status = (DisplayReleaseStatus?)releaseEnvironment?.Status }); } environments.Add(environment); } return(environments); }
public string CloneReleaseEnvironment(string SourceEnvName, string TargetEnvName, int DeployGroupId) { string result = ""; var definitions = relclient.GetReleaseDefinitionsAsync(TfsEnvInfo.ProjectName, TfsEnvInfo.ReleaseDefinitionName, ReleaseDefinitionExpands.Environments, isExactNameMatch: true).Result; if (definitions.Count() > 0) { //This call is to get the project GUID var project = projclient.GetProject(TfsEnvInfo.ProjectName).Result; //This returns everything in a definition including properties such as Owner in an Environment var def = relclient.GetReleaseDefinitionAsync(project.Id, definitions.First().Id).Result; var envcount = def.Environments.Count; var defenvlist = def.Environments.Where(e => e.Name == SourceEnvName); if (defenvlist.Count() > 0) { var source = defenvlist.First(); var newrank = def.Environments.Select(e => e.Rank).ToList().Max() + 1; if (def.Environments.Where(e => e.Name == TargetEnvName).Count() == 0) { //Environment must have a minimum RetentionPolicy, Rank, Owner, //PreDeployApprovals, PostDeployApprovals and DeployPhases var target = new ReleaseDefinitionEnvironment() { Name = TargetEnvName + " - Clone from " + SourceEnvName, RetentionPolicy = source.RetentionPolicy, Rank = newrank, Owner = source.Owner, PreDeployApprovals = source.PreDeployApprovals, PostDeployApprovals = source.PostDeployApprovals }; //Clone phases and tasks var newphases = source.DeployPhases.ToList(); //Update deployment group name in phases foreach (var p in newphases) { if (p.PhaseType == DeployPhaseTypes.MachineGroupBasedDeployment) { var m = ((MachineGroupBasedDeployPhase)p); var inputs = m.GetDeploymentInput(); var newinputs = (MachineGroupDeploymentInput)inputs.Clone(); newinputs.QueueId = DeployGroupId; m.DeploymentInput = newinputs; } } target.DeployPhases = newphases; def.Environments.Add(target); var newdef = relclient.UpdateReleaseDefinitionAsync(def, project.Id).Result; var envinfo = new TfsCloneReleaseEnvInfo() { ReleaseName = newdef.Name, EnvironmentName = target.Name, CloneFrom = SourceEnvName, RetentionPolicy = target.RetentionPolicy.ToString(), Rank = target.Rank, Owner = target.Owner.DisplayName, PreDeployApprovals = target.PreDeployApprovals.Approvals.Where(e => e.Approver != null).OrderBy(e => e.Approver.DisplayName).Select(e => e.Approver.DisplayName).ToArray(), PostDeployApprovals = target.PostDeployApprovals.Approvals.Where(e => e.Approver != null).OrderBy(e => e.Approver.DisplayName).Select(e => e.Approver.DisplayName).ToArray(), DeployPhases = target.DeployPhases.OrderBy(e => e.Name).Select(e => e.Name).ToArray(), success = (newdef.Environments.Count > envcount) ? true : false //Basic detection if environment was added }; result = JsonConvert.SerializeObject(envinfo, Formatting.Indented); } else { result = $"**Warning** An Env with name \"{TargetEnvName}\" already exists"; } } else { result = $"**Warning** Failed to find Env with name \"{SourceEnvName}\""; } } else { result = $"**Warning** Failed to find Release Definition with name \"{TfsEnvInfo.ReleaseDefinitionName}\""; } return(result); }
private async Task CustomizeNonRingPipeline(VstsReleaseDefinition model, ReleaseDefinition pipeline) { //load sf endpoints var connectionEndpoints = await _taskAgentHttpClient.GetServiceEndpointsAsync(_vstsConfiguration.VstsTargetProjectId); //set up source trigger var sourceTrigger = (ArtifactSourceTrigger)pipeline.Triggers.First(); sourceTrigger.ArtifactAlias = model.BuildDefinition.ToString(); var clonedEnvStages = new List <ReleaseDefinitionEnvironment>(); var rank = 1; //relink to target build definition foreach (var e in pipeline.Environments) { if (!Enum.TryParse(e.Name, true, out DeploymentEnvironment sierraEnvironment)) { throw new Exception($"Release template #{pipeline.Id} contains unrecognized environment - {e.Name}"); } if (model.SkipEnvironments != null && model.SkipEnvironments.Contains(sierraEnvironment)) { continue; } ReleaseDefinitionEnvironment predecessor = null; foreach (var r in EswDevOpsSdk.GetRegionSequence(sierraEnvironment, default)) { var regionEnv = e.DeepClone(); var phase = regionEnv.DeployPhases.First(); var envInput = (AgentDeploymentInput)phase.GetDeploymentInput(); envInput.ArtifactsDownloadInput.DownloadInputs.First().Alias = model.BuildDefinition.ToString(); regionEnv.Name = $"{e.Name} - {r}"; regionEnv.Rank = rank++; regionEnv.Id = regionEnv.Rank; //link condition to predecessor (region) if (predecessor != null) { regionEnv.Conditions = new List <Condition>(new[] { new Condition(predecessor.Name, ConditionType.EnvironmentState, "4" /*find the documentation for this value*/) }); } //re-point to correct SF instance var sfDeployStep = phase.WorkflowTasks.FirstOrDefault(t => t.TaskId == Guid.Parse(VstsSfDeployTaskId)); if (sfDeployStep == null) { throw new Exception( $"Release template #{pipeline.Id} does not contain expected Task {VstsSfDeployTaskId} for {e.Name} environment"); } var expectedConnectionName = $"esw-{r.ToRegionCode().ToLowerInvariant()}-fabric-{e.Name.ToLowerInvariant()}"; var sfConnection = connectionEndpoints.FirstOrDefault(c => c.Name == expectedConnectionName); if (sfConnection == null) { throw new Exception( $"SF Endpoint {expectedConnectionName} not found in VSTS project {_vstsConfiguration.VstsTargetProjectId}"); } sfDeployStep.Inputs[VstsSfDeployTaskConnectionNameInput] = sfConnection.Id.ToString(); //set region in manifest var sfUpdaterStep = phase.WorkflowTasks.FirstOrDefault(t => t.TaskId == Guid.Parse(VstsSfUpdateTaskId)); if (sfUpdaterStep == null) { throw new Exception( $"Release template {pipeline.Name} does not contain expected Task {VstsSfUpdateTaskId} for {e.Name} environment"); } sfUpdaterStep.Inputs[VstsSfUpdateTaskRegionInput] = r.ToRegionName(); clonedEnvStages.Add(regionEnv); predecessor = regionEnv; } } pipeline.Environments = clonedEnvStages; //set tenant specific variables pipeline.Variables["TenantCode"].Value = model.TenantCode; pipeline.Variables["PortNumber"].Value = "11111"; //TODO: link to port management }
List <Variable> GenVariables(VariableType type, ReleaseDefinitionEnvironment environment = null) { List <Variable> variables; if (type == VariableType.Build) { variables = new List <Variable>(_build.VariableGroups.Count + _build.Variables.Count); foreach (var vg in _build.VariableGroups) { variables.Add(new Variable { group = vg.Name }); } foreach (var kvp in _build.Variables) { variables.Add(new Variable { name = kvp.Key, value = kvp.Value.Value }); } } else { if (environment is object) { variables = new List <Variable>(environment.VariableGroups.Count + environment.Variables.Count); foreach (var id in environment.VariableGroups) { if (_variableGroupMap.TryGetValue(id, out var vg)) { variables.Add(new Variable { group = vg.Name }); } } foreach (var variable in environment.Variables) { variables.Add(new Variable { name = variable.Key, value = variable.Value.Value }); } } else { variables = new List <Variable>(); if (!_release.VariableGroups.IsNullOrEmpty()) { foreach (var id in _release.VariableGroups) { if (_variableGroupMap.TryGetValue(id, out var vg)) { variables.Add(new Variable { group = vg.Name }); } } } foreach (var variable in _release.Variables) { variables.Add(new Variable { name = variable.Key, value = variable.Value.Value }); } } } return(variables); }