/// <summary> /// This method is used to get latest release result of given release definition Id and branch name with descending order. /// Reference: https://docs.microsoft.com/en-us/rest/api/azure/devops/release/releases/list?view=azure-devops-rest-5.1 /// </summary> /// <param name="definitionId">release definition Ids</param> /// <param name="branchName">github repository branch name</param> /// <returns>List of IoT Edge releases</returns> public async Task <List <IoTEdgeRelease> > GetReleasesAsync(ReleaseDefinitionId definitionId, string branchName, int top = 5) { ValidationUtil.ThrowIfNullOrWhiteSpace(branchName, nameof(branchName)); ValidationUtil.ThrowIfNonPositive(top, nameof(top)); // TODO: need to think about how to handle unexpected exception during REST API call string requestPath = string.Format(ReleasePathSegmentFormat, this.accessSetting.Organization, this.accessSetting.Project); IFlurlRequest latestBuildRequest = DevOpsAccessSetting.ReleaseManagementBaseUrl .AppendPathSegment(requestPath) .SetQueryParam("definitionId", definitionId.IdString()) .SetQueryParam("queryOrder", "descending") .SetQueryParam("$expand", "environments") .SetQueryParam("$top", top) .SetQueryParam("api-version", "5.1") .SetQueryParam("sourceBranchFilter", branchName) .WithBasicAuth(string.Empty, this.accessSetting.PersonalAccessToken); string resultJson = await latestBuildRequest.GetStringAsync().ConfigureAwait(false); JObject result = JObject.Parse(resultJson); if (!result.ContainsKey("count") || (int)result["count"] <= 0) { return(new List <IoTEdgeRelease>()); } VstsRelease[] releases = JsonConvert.DeserializeObject <VstsRelease[]>(result["value"].ToString()); return(releases.Select(r => IoTEdgeRelease.Create(r, branchName)).ToList()); }
public static string DisplayName(this ReleaseDefinitionId releaseDefinitionId) { var definitionIdToDisplayNameMapping = new Dictionary <ReleaseDefinitionId, string> { { ReleaseDefinitionId.E2ETest, "Old E2E Test" }, }; return(definitionIdToDisplayNameMapping.ContainsKey(releaseDefinitionId) ? definitionIdToDisplayNameMapping[releaseDefinitionId] : releaseDefinitionId.ToString()); }
/// <summary> /// This method is used to get latest release result of given release definition Id and branch name with descending order. /// Reference: https://docs.microsoft.com/en-us/rest/api/azure/devops/release/releases/list?view=azure-devops-rest-5.1 /// </summary> /// <param name="definitionId">release definition Ids</param> /// <param name="branchName">github repository branch name</param> /// <returns>List of IoT Edge releases</returns> public async Task <List <IoTEdgeRelease> > GetReleasesAsync(ReleaseDefinitionId definitionId, string branchName, int top = 200) { ValidationUtil.ThrowIfNullOrWhiteSpace(branchName, nameof(branchName)); ValidationUtil.ThrowIfNonPositive(top, nameof(top)); // TODO: need to think about how to handle unexpected exception during REST API call string requestPath = string.Format(ReleasePathSegmentFormat, this.accessSetting.Organization, this.accessSetting.Project); IFlurlRequest listReleasesRequest = DevOpsAccessSetting.ReleaseManagementBaseUrl .AppendPathSegment(requestPath) .SetQueryParam("definitionId", definitionId.IdString()) .SetQueryParam("queryOrder", "descending") .SetQueryParam("$top", top) .SetQueryParam("api-version", "5.1") .SetQueryParam("sourceBranchFilter", branchName) .WithBasicAuth(string.Empty, this.accessSetting.PersonalAccessToken); string releasesJson = await listReleasesRequest.GetStringAsync().ConfigureAwait(false); JObject releasesJObject = JObject.Parse(releasesJson); if (!releasesJObject.ContainsKey("count") || (int)releasesJObject["count"] <= 0) { return(new List <IoTEdgeRelease>()); } VstsRelease[] vstsReleases = JsonConvert.DeserializeObject <VstsRelease[]>(releasesJObject["value"].ToString()); var iotEdgeReleases = new List <IoTEdgeRelease>(); foreach (VstsRelease vstsRelease in vstsReleases) { IFlurlRequest getReleaseRequest = DevOpsAccessSetting.ReleaseManagementBaseUrl .AppendPathSegment(requestPath) .SetQueryParam("api-version", "5.1") .SetQueryParam("releaseId", vstsRelease.Id) .WithBasicAuth(string.Empty, this.accessSetting.PersonalAccessToken); string releaseJson = await getReleaseRequest.GetStringAsync().ConfigureAwait(false); try { VstsRelease releaseWithDetails = JsonConvert.DeserializeObject <VstsRelease>(releaseJson); iotEdgeReleases.Add(IoTEdgeRelease.Create(releaseWithDetails, branchName)); } catch (System.Exception ex) { // TODO: log exception Console.WriteLine(ex.ToString()); } } return(iotEdgeReleases); }
public IoTEdgeRelease( int id, ReleaseDefinitionId definitionId, string name, string sourceBranch, VstsReleaseStatus status, Uri webUri, HashSet <IoTEdgeReleaseEnvironment> environments) { ValidationUtil.ThrowIfNonPositive(id, nameof(id)); ValidationUtil.ThrowIfNullOrWhiteSpace(name, nameof(name)); ValidationUtil.ThrowIfNullOrWhiteSpace(sourceBranch, nameof(sourceBranch)); ValidationUtil.ThrowIfNull(webUri, nameof(webUri)); ValidationUtil.ThrowIfNull(environments, nameof(environments)); this.id = id; this.definitionId = definitionId; this.name = name; this.sourceBranch = sourceBranch; this.status = status; this.webUri = webUri; this.environments = environments; }
async Task ImportVstsReleasesDataAsync(ReleaseManagement releaseManagement, string branch, ReleaseDefinitionId releaseDefinitionId) { SqlConnection sqlConnection = null; try { sqlConnection = new SqlConnection(this.dbConnectionString); sqlConnection.Open(); List <IoTEdgeRelease> releaseResults = await releaseManagement.GetReleasesAsync(releaseDefinitionId, branch, 200); Console.WriteLine($"Query VSTS for branch [{branch}] and release definition [{releaseDefinitionId.ToString()}]: result count={releaseResults.Count}"); foreach (IoTEdgeRelease release in releaseResults.Where(r => r.HasResult())) { UpsertVstsReleaseToDb(sqlConnection, release); foreach (KeyValuePair <int, string> kvp in ReleaseEnvironment.DefinitionIdToDisplayNameMapping) { IoTEdgeReleaseEnvironment releaseEnvironment = release.GetEnvironment(kvp.Key); if (releaseEnvironment.HasResult()) { UpsertVstsReleaseEnvironmentToDb(sqlConnection, release.Id, releaseEnvironment, kvp.Value); } } } } catch (Exception) { throw; } finally { sqlConnection?.Close(); } }
async Task ImportVstsReleasesDataAsync(ReleaseManagement releaseManagement, string branch, ReleaseDefinitionId releaseDefinitionId) { Console.WriteLine($"Import VSTS releases from branch [{branch}] started at {DateTime.UtcNow}."); SqlConnection sqlConnection = null; try { sqlConnection = new SqlConnection(this.dbConnectionString); sqlConnection.Open(); List <IoTEdgeRelease> releaseResults = await releaseManagement.GetReleasesAsync(releaseDefinitionId, branch, 200); Console.WriteLine($"Query VSTS releases for branch [{branch}] and release definition [{releaseDefinitionId.ToString()}]: result count={releaseResults.Count} at {DateTime.UtcNow}."); int releaseCount = 0; foreach (IoTEdgeRelease release in releaseResults.Where(r => r.HasResult())) { UpsertVstsReleaseToDb(sqlConnection, release); foreach (KeyValuePair <int, string> kvp in ReleaseEnvironment.DefinitionIdToDisplayNameMapping) { IoTEdgeReleaseEnvironment releaseEnvironment = release.GetEnvironment(kvp.Key); if (releaseEnvironment.HasResult()) { UpsertVstsReleaseEnvironmentToDb(sqlConnection, release.Id, releaseEnvironment, kvp.Value); foreach (IoTEdgeReleaseDeployment deployment in releaseEnvironment.Deployments) { UpsertVstsReleaseDeploymentToDb(sqlConnection, releaseEnvironment.Id, deployment); const string testTaskPrefix = "Test:"; foreach (IoTEdgePipelineTask pipelineTask in deployment.Tasks.Where(x => IsTestTask(x, testTaskPrefix))) { UpsertVstsReleaseTaskToDb(sqlConnection, deployment.Id, pipelineTask, testTaskPrefix); } } } } releaseCount++; if (releaseCount % 10 == 0) { Console.WriteLine($"Query VSTS releases for branch [{branch}] and release definition [{releaseDefinitionId.ToString()}]: release count={releaseCount} at {DateTime.UtcNow}."); } } } catch (Exception) { throw; } finally { sqlConnection?.Close(); } }
public static string IdString(this ReleaseDefinitionId buildDefinitionId) => ((int)buildDefinitionId).ToString();