Skip to content

Commit 5dde397

Browse files
author
Danny McCormick
authored
Added lots of samples/caught small bug (#241)
* Added dashboard samples * Added projectAnalysis sample and caught bug with date serialization * Cleaning up * Cleaning up * Fixing error with git sample * Cleaning up * Added WIT samples * Cleaning up * Added test samples * cleaning up * Added work samples * Cleaning up * Added release sample * Added extension management samples * Cleaning up * Undo changes to vsoClient its been updated since * Undo changes (updated since) * Undo weird space * Add good space
1 parent 591f0c6 commit 5dde397

11 files changed

Lines changed: 443 additions & 9 deletions

api/VsoClient.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ export class VsoClient {
190190
}
191191
let queryString: string = '';
192192

193-
if(typeof(queryParams) !== 'string') {
193+
if (typeof(queryParams) !== 'string') {
194194
for (let property in queryParams) {
195195
if (queryParams.hasOwnProperty(property)) {
196196
const prop = queryParams[property];
@@ -200,11 +200,12 @@ export class VsoClient {
200200
}
201201
}
202202

203-
if(queryString === '' && prefix.length > 0){
203+
if (queryString === '' && prefix.length > 0){
204204
// Date.prototype.toString() returns a string that is not valid for the REST API.
205205
// Need to specially call `toUTCString()` instead for such cases
206206
const queryValue = typeof queryParams === 'object' && 'toUTCString' in queryParams ? (queryParams as Date).toUTCString() : queryParams.toString();
207207

208+
208209
// Will always need to chop period off of end of prefix
209210
queryString = prefix.slice(0,-1) + '=' + encodeURIComponent(queryValue) + '&';
210211
}

samples/dashboard.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import * as common from './common';
2+
import * as nodeApi from 'azure-devops-node-api';
3+
4+
import * as DashboardApi from 'azure-devops-node-api/DashboardApi';
5+
import * as CoreApi from 'azure-devops-node-api/CoreApi';
6+
import * as DashboardInterfaces from 'azure-devops-node-api/interfaces/DashboardInterfaces';
7+
import * as CoreInterfaces from 'azure-devops-node-api/interfaces/CoreInterfaces';
8+
9+
export async function run(projectId: string) {
10+
const webApi: nodeApi.WebApi = await common.getWebApi();
11+
const dashboardApiObject: DashboardApi.IDashboardApi = await webApi.getDashboardApi();
12+
const coreApiObject: CoreApi.CoreApi = await webApi.getCoreApi();
13+
const project: CoreInterfaces.TeamProject = await coreApiObject.getProject(projectId);
14+
15+
common.banner('Dashboard Samples');
16+
17+
common.heading('Create a Dashboard');
18+
const teamContext: CoreInterfaces.TeamContext = {project: project.name,
19+
projectId: project.id,
20+
team: project.defaultTeam.name,
21+
teamId: project.defaultTeam.id};
22+
const createDashboardContext: DashboardInterfaces.Dashboard = {_links: null,
23+
description: 'fancy new dashboard',
24+
eTag: '',
25+
id: null,
26+
name: 'dash',
27+
ownerId: null,
28+
position: null,
29+
refreshInterval: 1,
30+
url: null,
31+
widgets: []};
32+
let dashboard: DashboardInterfaces.Dashboard = await dashboardApiObject.createDashboard(createDashboardContext, teamContext);
33+
//Ensure its been created and we can get it.
34+
dashboard = await dashboardApiObject.getDashboard(teamContext, dashboard.id);
35+
console.log('Created dashboard', dashboard.name);
36+
37+
common.heading('Create a widget');
38+
let widget: DashboardInterfaces.Widget = {_links: null,
39+
allowedSizes: null,
40+
artifactId: null,
41+
configurationContributionId: null,
42+
configurationContributionRelativeId: null,
43+
contentUri: null,
44+
contributionId: 'ms.vss-dashboards-web.Microsoft.VisualStudioOnline.Dashboards.OtherLinksWidget',
45+
dashboard: dashboard,
46+
eTag: null,
47+
id: null,
48+
isEnabled: null,
49+
isNameConfigurable: null,
50+
lightboxOptions: null,
51+
loadingImageUrl: null,
52+
name: 'widge',
53+
position: {row: 1, column: 1},
54+
settings: null,
55+
settingsVersion: {major: 1, minor: 0, patch: 0},
56+
size: {rowSpan: 1, columnSpan: 2},
57+
typeId: null,
58+
url: null
59+
};
60+
const widgetMetadata: DashboardInterfaces.WidgetMetadataResponse = await dashboardApiObject.getWidgetMetadata('ms.vss-dashboards-web.Microsoft.VisualStudioOnline.Dashboards.OtherLinksWidget');
61+
console.log('Creating widget with metadata:', widgetMetadata);
62+
widget = await dashboardApiObject.createWidget(widget, teamContext, dashboard.id);
63+
//Ensure its been created and we can get it.
64+
widget = await dashboardApiObject.getWidget(teamContext, dashboard.id, widget.id);
65+
console.log('Created widget', widget.name);
66+
67+
common.heading('Update a widget');
68+
widget.name = 'new name';
69+
widget = await dashboardApiObject.updateWidget(widget, teamContext, dashboard.id, widget.id);
70+
//Ensure its been updated and we can get it.
71+
widget = await dashboardApiObject.getWidget(teamContext, dashboard.id, widget.id);
72+
console.log('Widget name updated to', widget.name);
73+
74+
common.heading('Get Widget data');
75+
const widgetTypes: DashboardInterfaces.WidgetTypesResponse = await dashboardApiObject.getWidgetTypes(DashboardInterfaces.WidgetScope.Project_Team);
76+
console.log('First widget type:', widgetTypes.widgetTypes[0]);
77+
78+
common.heading('Delete a widget');
79+
await dashboardApiObject.deleteWidget(teamContext, dashboard.id, widget.id);
80+
widget = await dashboardApiObject.getWidget(teamContext, dashboard.id, widget.id);
81+
console.log('Widget deleted, trying to get it returns:', widget);
82+
83+
common.heading('Delete dashboard');
84+
//Can't delete last dashboard for a team, will create a new one so we can delete the old one.
85+
createDashboardContext.description = 'this dashboard should survive';
86+
createDashboardContext.name = 'tempDash';
87+
await dashboardApiObject.createDashboard(createDashboardContext, teamContext);
88+
//Will delete old dashboard
89+
await dashboardApiObject.deleteDashboard(teamContext, dashboard.id);
90+
dashboard = await dashboardApiObject.getDashboard(teamContext, dashboard.id);
91+
console.log('Dashboard deleted, trying to get it returns:', dashboard);
92+
}

samples/extensionManagement.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import * as common from './common';
2+
import * as nodeApi from 'azure-devops-node-api';
3+
4+
import * as ExtensionManagementApi from 'azure-devops-node-api/ExtensionManagementApi';
5+
import * as ExtensionManagementInterfaces from 'azure-devops-node-api/interfaces/ExtensionManagementInterfaces';
6+
7+
export async function run() {
8+
const webApi: nodeApi.WebApi = await common.getWebApi();
9+
const extensionManagementApiObject: ExtensionManagementApi.IExtensionManagementApi = await webApi.getExtensionManagementApi();
10+
11+
common.banner('Extension Management Samples');
12+
13+
common.heading('Get state information');
14+
console.log('States:', await extensionManagementApiObject.getStates(true, true, true));
15+
const publisherName = 'ms';
16+
const extensionName = 'vss-releaseartifact';
17+
const version = '0.1.35';
18+
let alreadyInstalled = false;
19+
if (await extensionManagementApiObject.getInstalledExtensionByName(publisherName, extensionName)) {
20+
console.log('Extension has already been installed');
21+
alreadyInstalled = true;
22+
}
23+
else {
24+
common.heading('Install an extension');
25+
await extensionManagementApiObject.installExtensionByName(publisherName, extensionName, version);
26+
}
27+
28+
// Verify extension was actually created
29+
let installedExtension: ExtensionManagementInterfaces.InstalledExtension = await extensionManagementApiObject.getInstalledExtensionByName(publisherName, extensionName);
30+
console.log('The following extension was installed', installedExtension);
31+
32+
if(!alreadyInstalled){
33+
common.heading('Uninstall the extension');
34+
await extensionManagementApiObject.uninstallExtensionByName(publisherName, extensionName);
35+
installedExtension = await extensionManagementApiObject.getInstalledExtensionByName(publisherName, extensionName);
36+
console.log('Extension was uninstalled, looking for it returns', installedExtension);
37+
}
38+
39+
common.heading('Get a token');
40+
console.log('Token:' , await extensionManagementApiObject.getToken())
41+
}

samples/git.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,4 @@ export async function run() {
6666
else {
6767
console.log("Must have an active repository for this part of the sample");
6868
}
69-
}
69+
}

samples/projectAnalysis.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as common from './common';
2+
import * as nodeApi from 'azure-devops-node-api';
3+
4+
import * as CoreApi from 'azure-devops-node-api/CoreApi';
5+
import * as GitApi from 'azure-devops-node-api/GitApi';
6+
import * as ProjectAnalysisApi from 'azure-devops-node-api/ProjectAnalysisApi';
7+
import * as CoreInterfaces from 'azure-devops-node-api/interfaces/CoreInterfaces';
8+
import * as GitInterfaces from 'azure-devops-node-api/interfaces/GitInterfaces';
9+
import * as ProjectAnalysisInterfaces from 'azure-devops-node-api/interfaces/ProjectAnalysisInterfaces';
10+
11+
export async function run() {
12+
const webApi: nodeApi.WebApi = await common.getWebApi();
13+
const projectName: string = common.getProject();
14+
const coreApiObject: CoreApi.CoreApi = await webApi.getCoreApi();
15+
const project: CoreInterfaces.TeamProject = await coreApiObject.getProject(projectName);
16+
const projectAnalysisApiObject: ProjectAnalysisApi.IProjectAnalysisApi = await webApi.getProjectAnalysisApi();
17+
const gitApiObject: GitApi.IGitApi = await webApi.getGitApi();
18+
19+
common.banner('Project Analytics Samples');
20+
21+
common.heading('Get Language Analytics');
22+
console.log(await projectAnalysisApiObject.getProjectLanguageAnalytics(project.id));
23+
24+
const startDate: Date = new Date();
25+
common.heading('Get Activity Metrics since the start of 2018');
26+
console.log(await projectAnalysisApiObject.getProjectActivityMetrics(project.id, startDate, ProjectAnalysisInterfaces.AggregationType.Daily));
27+
28+
common.heading('Get Git Repositories Activity Metrics since the start of 2018');
29+
console.log(await projectAnalysisApiObject.getGitRepositoriesActivityMetrics(project.id, startDate, ProjectAnalysisInterfaces.AggregationType.Daily, 0, 10));
30+
31+
common.heading('Get Repository Activity Metrics since the start of 2018 for a single repo');
32+
const repos: GitInterfaces.GitRepository[] = await gitApiObject.getRepositories(projectName);
33+
if(repos.length > 0) {
34+
console.log(await projectAnalysisApiObject.getRepositoryActivityMetrics(project.id, repos[0].id, startDate, ProjectAnalysisInterfaces.AggregationType.Daily));
35+
}
36+
else {
37+
console.log('No repos to analyze');
38+
}
39+
}

samples/release.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import * as common from './common';
2+
import * as nodeApi from 'azure-devops-node-api';
3+
4+
import * as ReleaseApi from 'azure-devops-node-api/ReleaseApi';
5+
import * as ReleaseInterfaces from 'azure-devops-node-api/interfaces/ReleaseInterfaces';
6+
7+
export async function run() {
8+
const projectId: string = common.getProject();
9+
const webApi: nodeApi.WebApi = await common.getWebApi();
10+
const releaseApiObject: ReleaseApi.IReleaseApi = await webApi.getReleaseApi();
11+
12+
common.banner('Release Samples');
13+
14+
common.heading('Get releases');
15+
const releases: ReleaseInterfaces.Release[] = await releaseApiObject.getReleases(projectId);
16+
console.log('There are', releases.length, 'releases for this project');
17+
18+
if(releases.length > 0) {
19+
const release = releases[0];
20+
console.log('Info for release', release.name);
21+
console.log('Logs for this release:', releaseApiObject.getLogs(projectId, release.id));
22+
const workItemRefs: ReleaseInterfaces.ReleaseWorkItemRef[] = await releaseApiObject.getReleaseWorkItemsRefs(projectId, release.id);
23+
console.log('There are', workItemRefs.length, 'work items associated with this release');
24+
if (workItemRefs.length > 0) {
25+
console.log('Example work item', workItemRefs[0]);
26+
}
27+
}
28+
else {
29+
console.log('Must have at least 1 release to do samples with releases');
30+
}
31+
32+
common.heading('Get metadata');
33+
console.log('Release settings:', await releaseApiObject.getReleaseSettings(projectId));
34+
console.log('Tags:', await releaseApiObject.getTags(projectId));
35+
36+
common.heading('Get Approval information');
37+
const approvals: ReleaseInterfaces.ReleaseApproval[] = await releaseApiObject.getApprovals(projectId);
38+
console.log('There are', approvals.length, 'approvals for this project');
39+
if (approvals.length > 0) {
40+
console.log('Sample approval:', approvals[0]);
41+
}
42+
}

samples/samples.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
"build",
33
"buildArtifact",
44
"creation",
5+
"dashboard",
6+
"extensionManagement",
7+
"filecontainer",
8+
"git",
59
"policy",
610
"profile",
11+
"projectAnalysis",
12+
"release",
713
"task",
8-
"filecontainer",
9-
"git",
10-
"wiki"
14+
"test",
15+
"wiki",
16+
"work",
17+
"workItemTracking"
1118
]

samples/test.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import * as common from './common';
2+
import * as nodeApi from 'azure-devops-node-api';
3+
4+
import * as BuildApi from 'azure-devops-node-api/BuildApi';
5+
import * as CoreApi from 'azure-devops-node-api/CoreApi';
6+
import * as TestApi from 'azure-devops-node-api/TestApi';
7+
import * as BuildInterfaces from 'azure-devops-node-api/interfaces/BuildInterfaces';
8+
import * as CoreInterfaces from 'azure-devops-node-api/interfaces/CoreInterfaces';
9+
import * as TestInterfaces from 'azure-devops-node-api/interfaces/TestInterfaces';
10+
11+
export async function run(createdProjectId: string) {
12+
const projectId: string = common.getProject();
13+
const webApi: nodeApi.WebApi = await common.getWebApi();
14+
const testApiObject: TestApi.ITestApi = await webApi.getTestApi();
15+
const coreApiObject: CoreApi.CoreApi = await webApi.getCoreApi();
16+
const project: CoreInterfaces.TeamProject = await coreApiObject.getProject(projectId);
17+
18+
common.banner('Testing Samples');
19+
20+
common.heading('Get test suite plans');
21+
const plans: TestInterfaces.TestPlan[] = await testApiObject.getPlans(projectId);
22+
console.log('Current Plans:', plans);
23+
24+
common.heading('Get code coverage');
25+
const buildApiObject: BuildApi.IBuildApi = await webApi.getBuildApi();
26+
const defs: BuildInterfaces.DefinitionReference[] = await buildApiObject.getDefinitions(projectId);
27+
console.log('Code coverage for build' + defs[0].id + ':', await testApiObject.getCodeCoverageSummary(projectId, defs[0].id));
28+
29+
common.heading('Create test suite plan');
30+
const testPlanModel: TestInterfaces.PlanUpdateModel = {area: null,
31+
automatedTestEnvironment: null,
32+
automatedTestSettings: null,
33+
build: null,
34+
buildDefinition: null,
35+
configurationIds: null,
36+
description: 'autogenerated, should be deleted',
37+
endDate: null,
38+
iteration: null,
39+
manualTestEnvironment: null,
40+
manualTestSettings: null,
41+
name: 'myPlan',
42+
owner: null,
43+
releaseEnvironmentDefinition: null,
44+
startDate: null,
45+
state: null,
46+
status: null};
47+
const testPlan = await testApiObject.createTestPlan(testPlanModel, createdProjectId);
48+
console.log('Created plan', testPlan.name);
49+
50+
common.heading('Create test suite');
51+
const suiteId = 1;
52+
const testSuiteModel: TestInterfaces.SuiteCreateModel = {name: 'myTestSuite', queryString: 'myTestSuite', requirementIds: [], suiteType: 'StaticTestSuite'};
53+
const testSuite: TestInterfaces.TestSuite[] = await testApiObject.createTestSuite(testSuiteModel, createdProjectId, testPlan.id, suiteId);
54+
console.log('Empty suite created, should be null:', testSuite);
55+
56+
common.heading('Create test variable');
57+
const variableToCreate: TestInterfaces.TestVariable = {description: 'variable for testing',
58+
id: null,
59+
name: 'testVar',
60+
project: null,
61+
revision: null,
62+
url: null,
63+
values: ['values', 'that', 'are', 'allowed']};
64+
const testVariable: TestInterfaces.TestVariable = await testApiObject.createTestVariable(variableToCreate, createdProjectId);
65+
console.log('Variable created:', testVariable);
66+
67+
common.heading('Delete test variable');
68+
await testApiObject.deleteTestVariable(createdProjectId, testVariable.id);
69+
console.log('Trying to get test variable now returns', await testApiObject.getTestVariableById(createdProjectId, testVariable.id));
70+
71+
common.heading('Delete test suite');
72+
await testApiObject.deleteTestSuite(createdProjectId, testPlan.id, suiteId);
73+
console.log('Trying to get suite now returns', await testApiObject.getTestSuiteById(createdProjectId, testPlan.id, suiteId));
74+
75+
common.heading('Delete test suite plan');
76+
await testApiObject.deleteTestPlan(project.id, testPlan.id);
77+
console.log('Trying to get plan now returns', await testApiObject.getPlanById(createdProjectId, testPlan.id));
78+
}

samples/tsconfig.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,18 @@
99
"build.ts",
1010
"buildArtifact.ts",
1111
"creation.ts",
12+
"dashboard.ts",
13+
"extensionManagement.ts",
14+
"filecontainer.ts",
15+
"git.ts",
1216
"policy.ts",
1317
"profile.ts",
18+
"projectAnalysis.ts",
19+
"release.ts",
1420
"task.ts",
15-
"filecontainer.ts",
16-
"git.ts",
17-
"wiki.ts"
21+
"test.ts",
22+
"wiki.ts",
23+
"work.ts",
24+
"workItemTracking.ts"
1825
]
1926
}

0 commit comments

Comments
 (0)