Skip to content
This repository was archived by the owner on Oct 30, 2020. It is now read-only.

Commit d23946e

Browse files
author
Paulo Baima
committed
Refactoring main class
1 parent 0fa1259 commit d23946e

File tree

12 files changed

+224
-136
lines changed

12 files changed

+224
-136
lines changed

unify-release-build-task/.taskkey

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
672bb41c-8652-4bb0-83ac-f0e1e4b1a9a1
1+
2bd4c206-0962-4558-98ac-6fcfffb36e28
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1-
import * as azdev from "azure-devops-node-api";
2-
import { IBuildApi } from "azure-devops-node-api/BuildApi";
3-
import { BuildReason, BuildStatus, BuildResult, BuildQueryOrder, QueryDeletedOption, Build } from "azure-devops-node-api/interfaces/BuildInterfaces"
4-
import { injectable, inject } from "tsyringe";
5-
6-
@injectable()
7-
export default class AzureDevOpsWrapper {
8-
constructor() { }
9-
10-
async getBuildApi(organizationUrl: string, token: string): Promise<IBuildApi> {
11-
let authHandler = azdev.getPersonalAccessTokenHandler(token);
12-
let connection = new azdev.WebApi(organizationUrl, authHandler);
13-
return await connection.getBuildApi();
14-
}
15-
16-
async getBuild(organizationUrl: string, token: string, project: string, buildId: number) {
17-
let buildApi = await this.getBuildApi(organizationUrl, token);
18-
return buildApi.getBuild(project, buildId);
19-
}
20-
21-
async getBuilds(organizationUrl: string, token: string, project: string, definitions?: number[], queues?: number[], buildNumber?: string, minTime?: Date, maxTime?: Date, requestedFor?: string, reasonFilter?: BuildReason, statusFilter?: BuildStatus, resultFilter?: BuildResult, tagFilters?: string[], properties?: string[], top?: number, continuationToken?: string, maxBuildsPerDefinition?: number, deletedFilter?: QueryDeletedOption, queryOrder?: BuildQueryOrder, branchName?: string, buildIds?: number[], repositoryId?: string, repositoryType?: string): Promise<Build[]> {
22-
let buildApi = await this.getBuildApi(organizationUrl, token);
23-
return buildApi.getBuilds(project, definitions, queues, buildNumber, minTime, maxTime, requestedFor, reasonFilter, statusFilter, resultFilter, tagFilters, properties, top, continuationToken, maxBuildsPerDefinition, deletedFilter, queryOrder, branchName, buildIds, repositoryId, repositoryType);
24-
}
25-
26-
async addBuildTag(organizationUrl: string, token: string, project: string, buildId: number, tag: string) {
27-
let buildApi = await this.getBuildApi(organizationUrl, token);
28-
return buildApi.addBuildTag(project, buildId, tag)
29-
}
1+
import * as azdev from "azure-devops-node-api";
2+
import { IBuildApi } from "azure-devops-node-api/BuildApi";
3+
import { BuildReason, BuildStatus, BuildResult, BuildQueryOrder, QueryDeletedOption, Build } from "azure-devops-node-api/interfaces/BuildInterfaces"
4+
import { injectable, inject } from "tsyringe";
5+
6+
@injectable()
7+
export default class AzureDevOpsWrapper {
8+
constructor() { }
9+
10+
async getBuildApi(organizationUrl: string, token: string): Promise<IBuildApi> {
11+
let authHandler = azdev.getPersonalAccessTokenHandler(token);
12+
let connection = new azdev.WebApi(organizationUrl, authHandler);
13+
return await connection.getBuildApi();
14+
}
15+
16+
async getBuild(organizationUrl: string, token: string, project: string, buildId: number) {
17+
let buildApi = await this.getBuildApi(organizationUrl, token);
18+
return buildApi.getBuild(project, buildId);
19+
}
20+
21+
async getBuilds(organizationUrl: string, token: string, project: string, definitions?: number[], queues?: number[], buildNumber?: string, minTime?: Date, maxTime?: Date, requestedFor?: string, reasonFilter?: BuildReason, statusFilter?: BuildStatus, resultFilter?: BuildResult, tagFilters?: string[], properties?: string[], top?: number, continuationToken?: string, maxBuildsPerDefinition?: number, deletedFilter?: QueryDeletedOption, queryOrder?: BuildQueryOrder, branchName?: string, buildIds?: number[], repositoryId?: string, repositoryType?: string): Promise<Build[]> {
22+
let buildApi = await this.getBuildApi(organizationUrl, token);
23+
return buildApi.getBuilds(project, definitions, queues, buildNumber, minTime, maxTime, requestedFor, reasonFilter, statusFilter, resultFilter, tagFilters, properties, top, continuationToken, maxBuildsPerDefinition, deletedFilter, queryOrder, branchName, buildIds, repositoryId, repositoryType);
24+
}
25+
26+
async addBuildTag(organizationUrl: string, token: string, project: string, buildId: number, tag: string) {
27+
let buildApi = await this.getBuildApi(organizationUrl, token);
28+
return buildApi.addBuildTag(project, buildId, tag)
29+
}
3030
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import "reflect-metadata";
2-
import { container } from "tsyringe";
3-
import * as TaskLib from "azure-pipelines-task-lib/task";
4-
1+
import "reflect-metadata";
2+
import { container } from "tsyringe";
3+
import * as TaskLib from "azure-pipelines-task-lib/task";
4+
55
container.register("TaskLib", {useValue: TaskLib});
Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
1-
import { resolve } from "path"
2-
import { config } from "dotenv"
3-
import { injectable, inject } from "tsyringe";
4-
5-
config({ path: resolve(__dirname, "../.env") })
6-
@injectable()
7-
export default class VariableManager {
8-
9-
constructor(@inject("TaskLib") private taskLib: any) {
10-
}
11-
12-
getInput(key: string, required: boolean): string | undefined {
13-
if (process.env.NODE_ENV == "development") {
14-
if (required && !process.env[key]) {
15-
throw new Error(`Required Parameter ${key} not supplied.`)
16-
}
17-
return process.env[key];
18-
} else {
19-
return this.taskLib.getInput(key, required)!;
20-
}
21-
}
22-
23-
getBooleanInput(key: string, required: boolean): boolean | undefined {
24-
let value = this.getInput(key, required);
25-
return value == "true" ? true : false;
26-
}
27-
28-
getVariable(key: string): string | undefined {
29-
if (process.env.NODE_ENV == "development") {
30-
return process.env[key];
31-
} else {
32-
return this.taskLib.getVariable(key)!;
33-
}
34-
}
1+
import { resolve } from "path"
2+
import { config } from "dotenv"
3+
import { injectable, inject } from "tsyringe";
4+
5+
config({ path: resolve(__dirname, "../.env") })
6+
@injectable()
7+
export default class VariableManager {
8+
9+
constructor(@inject("TaskLib") private taskLib: any) {
10+
}
11+
12+
getInput(key: string, required: boolean): string | undefined {
13+
if (process.env.NODE_ENV == "development") {
14+
if (required && !process.env[key]) {
15+
throw new Error(`Required Parameter ${key} not supplied.`)
16+
}
17+
return process.env[key];
18+
} else {
19+
return this.taskLib.getInput(key, required)!;
20+
}
21+
}
22+
23+
getBooleanInput(key: string, required: boolean): boolean | undefined {
24+
let value = this.getInput(key, required);
25+
return value == "true" ? true : false;
26+
}
27+
28+
getVariable(key: string): string | undefined {
29+
if (process.env.NODE_ENV == "development") {
30+
return process.env[key];
31+
} else {
32+
return this.taskLib.getVariable(key)!;
33+
}
34+
}
3535
}

unify-release-build-task/src/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import "./dependency-injection";
1+
import "./helpers/dependency-injection";
22
import tl = require('azure-pipelines-task-lib/task');
3-
import VariableManager from "./variableManager";
4-
import AzureDevOpsClient from "./buildService";
5-
import { BuildResult, BuildStatus } from 'azure-devops-node-api/interfaces/BuildInterfaces';
3+
import AzureDevOpsClient from "./services/buildService";
64
import { container } from "tsyringe";
75
import AzureDevopsConfiguration from "./models/AzureDevOpsConfiguration"
86
async function run() {

unify-release-build-task/src/models/AzureDevOpsConfiguration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import "reflect-metadata";
22
import { injectable, inject } from "tsyringe";
3-
import VariableManager from "../variableManager";
3+
import VariableManager from "../helpers/variableManager";
44

55
@injectable()
66
export default class AzureDevOpsConfiguration {
Lines changed: 56 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,57 @@
1-
import * as azdev from "azure-devops-node-api";
2-
import * as ba from "azure-devops-node-api/BuildApi";
3-
import { Build, BuildStatus, BuildResult } from "azure-devops-node-api/interfaces/BuildInterfaces";
4-
import { stringify } from "querystring";
5-
import { IBuildApi } from "azure-devops-node-api/BuildApi";
6-
import AzureDevOpsClientWrapper from "./azureDevOpsClientWrapper";
7-
import { injectable, inject } from "tsyringe";
8-
9-
@injectable()
10-
export default class AzureDevOpsClient {
11-
12-
private orgUrl: string;
13-
private token: string;
14-
15-
constructor(@inject(AzureDevOpsClientWrapper) private azureDevOpsClient: AzureDevOpsClientWrapper) {
16-
17-
}
18-
19-
public async getBuildInfo(organizationUrl: string, token: string, project: string, buildId: number): Promise<Build> {
20-
return await this.azureDevOpsClient.getBuild(organizationUrl, token, project, buildId);
21-
}
22-
23-
public async listRelatedBuilds(organizationUrl: string, token: string, project: string, sourceVersion: string, waitForAllBuilds: Boolean = true, definitionFilters?: string[]): Promise<Map<string, Build>> {
24-
let allBuilds = await this.azureDevOpsClient.getBuilds(organizationUrl, token, project, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
25-
26-
var relatedBuilds = this.getBuildsFromSameSourceVersion(allBuilds, sourceVersion);
27-
relatedBuilds = this.sortBuildsByQueueTimeDescending(relatedBuilds);
28-
29-
if (!waitForAllBuilds) {
30-
relatedBuilds = this.filterBuildsByDefinition(relatedBuilds, definitionFilters);
31-
}
32-
33-
// Only the last Build Run for each definition is considered
34-
let lastBuildsFromRelatedDefinitions = new Map<string, Build>();
35-
for (var relatedBuild of relatedBuilds) {
36-
if (lastBuildsFromRelatedDefinitions.has(relatedBuild.definition.id.toString())) {
37-
continue;
38-
}
39-
lastBuildsFromRelatedDefinitions.set(relatedBuild.definition.id.toString(), relatedBuild);
40-
}
41-
42-
return lastBuildsFromRelatedDefinitions;
43-
}
44-
45-
private filterBuildsByDefinition(builds: Build[], definitions?: string[]) {
46-
return builds.filter(x => definitions.some(definition => definition == x.definition.id.toString()));
47-
}
48-
49-
private getBuildsFromSameSourceVersion(builds: Build[], sourceVersion: string): Build[] {
50-
return builds.filter(build => build.sourceVersion == sourceVersion);
51-
}
52-
53-
private sortBuildsByQueueTimeDescending(builds: Build[]): Build[] {
54-
return builds.sort((a, b) => b.queueTime.getDate() - a.queueTime.getDate());
55-
}
56-
57-
public async addBuildTag(organizationUrl: string, token: string, project: string, buildId: number, tag: string) {
58-
return await await this.azureDevOpsClient.addBuildTag(organizationUrl, token, project, buildId, tag);
59-
}
1+
import * as azdev from "azure-devops-node-api";
2+
import * as ba from "azure-devops-node-api/BuildApi";
3+
import { Build, BuildStatus, BuildResult } from "azure-devops-node-api/interfaces/BuildInterfaces";
4+
import { stringify } from "querystring";
5+
import { IBuildApi } from "azure-devops-node-api/BuildApi";
6+
import AzureDevOpsClientWrapper from "../helpers/azureDevOpsClientWrapper";
7+
import { injectable, inject } from "tsyringe";
8+
9+
@injectable()
10+
export default class AzureDevOpsClient {
11+
12+
constructor(@inject(AzureDevOpsClientWrapper) private azureDevOpsClient: AzureDevOpsClientWrapper) {
13+
14+
}
15+
16+
public async getBuildInfo(organizationUrl: string, token: string, project: string, buildId: number): Promise<Build> {
17+
return await this.azureDevOpsClient.getBuild(organizationUrl, token, project, buildId);
18+
}
19+
20+
public async listRelatedBuilds(organizationUrl: string, token: string, project: string, sourceVersion: string, waitForAllBuilds: Boolean = true, definitionFilters?: string[]): Promise<Map<string, Build>> {
21+
let allBuilds = await this.azureDevOpsClient.getBuilds(organizationUrl, token, project, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
22+
23+
var relatedBuilds = this.filterBuildsFromSameSourceVersion(allBuilds, sourceVersion);
24+
relatedBuilds = this.sortBuildsByQueueTimeDescending(relatedBuilds);
25+
26+
if (!waitForAllBuilds) {
27+
relatedBuilds = this.filterBuildsByDefinition(relatedBuilds, definitionFilters);
28+
}
29+
30+
// Only the last Build Run for each definition is considered
31+
let lastBuildsFromRelatedDefinitions = new Map<string, Build>();
32+
for (var relatedBuild of relatedBuilds) {
33+
if (lastBuildsFromRelatedDefinitions.has(relatedBuild.definition.id.toString())) {
34+
continue;
35+
}
36+
lastBuildsFromRelatedDefinitions.set(relatedBuild.definition.id.toString(), relatedBuild);
37+
}
38+
39+
return lastBuildsFromRelatedDefinitions;
40+
}
41+
42+
private filterBuildsByDefinition(builds: Build[], definitions?: string[]) {
43+
return builds.filter(x => definitions.some(definition => definition == x.definition.id.toString()));
44+
}
45+
46+
private filterBuildsFromSameSourceVersion(builds: Build[], sourceVersion: string): Build[] {
47+
return builds.filter(build => build.sourceVersion == sourceVersion);
48+
}
49+
50+
private sortBuildsByQueueTimeDescending(builds: Build[]): Build[] {
51+
return builds.sort((a, b) => b.queueTime.getDate() - a.queueTime.getDate());
52+
}
53+
54+
public async addBuildTag(organizationUrl: string, token: string, project: string, buildId: number, tag: string) {
55+
return await await this.azureDevOpsClient.addBuildTag(organizationUrl, token, project, buildId, tag);
56+
}
6057
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { inject } from "tsyringe";
2+
import BuildService from "../services/buildService";
3+
import AzureDevopsConfiguration from "../models/AzureDevOpsConfiguration";
4+
5+
export default class UnifyReleaseService {
6+
7+
constructor(@inject(BuildService) private buildService: BuildService, @inject(AzureDevopsConfiguration) private configuration: AzureDevopsConfiguration) {
8+
9+
}
10+
11+
async unifyRelease() {
12+
var buildDetails = await this.buildService.getBuildInfo(this.configuration.teamFoundationCollectionUri, this.configuration.accessToken, this.configuration.teamFoundationProject, this.configuration.currentBuildId);
13+
14+
console.log(`Processing Build ${buildDetails.id} (${buildDetails.definition.name}) from Source Version ${buildDetails.sourceVersion}`);
15+
console.log(`Task Parameters:
16+
ReleaseTag: ${this.configuration.releaseTag},
17+
ReleaseOnCancel: ${this.configuration.releaseOnCancel},
18+
ReleaseOnError ${this.configuration.releaseOnError}
19+
WaitForAllDefinitions: ${this.configuration.waitForAllTriggeredBuilds}`);
20+
21+
22+
}
23+
24+
}

unify-release-build-task/tests/helpers/variableManagerTests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import "reflect-metadata";
22
import { expect } from 'chai';
33
import 'mocha';
44
import { stubObject } from "ts-sinon";
5-
import VariableManager from "../../src/variableManager";
5+
import VariableManager from "../../src/helpers/variableManager";
66
import * as TaskLib from "azure-pipelines-task-lib/task";
77

88
describe('Variable Manager', () => {

unify-release-build-task/tests/models/azureDevOpsConfigurationTests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import 'mocha';
55
import { stubObject as Stub, StubbedInstance, stubInterface, stubObject } from "ts-sinon";
66

77
//# Imports
8-
import VariableManager from "../../src/variableManager";
8+
import VariableManager from "../../src/helpers/variableManager";
99
import AzureDevOpsConfiguration from "../../src/models/AzureDevOpsConfiguration";
1010

1111
//# Tests

0 commit comments

Comments
 (0)