Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Action takes Project URL, pipeline name and a [Personal Access Token (PAT)](http
azure-pipeline-name: 'pipeline-name' # name of the Azure pipeline to be triggered
azure-devops-token: '${{ secrets.AZURE_DEVOPS_TOKEN }}'
azure-pipeline-variables: '{"variable1": "value1", "variable2": "value2"}' # optional stringified json
azure-pipeline-parameters: '{"param1": "value1", "param2": "value2"}' # optional stringified json
```

# Contributing
Expand Down
343 changes: 159 additions & 184 deletions __tests__/main.test.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ inputs:
azure-devops-token:
description: 'Paste personal access token of the user as value of secret variable:AZURE_DEVOPS_TOKEN'
required: true
azure-pipeline-parameters:
description: 'Pipeline parameters to trigger the pipeline with'
required: false
runs:
using: 'node16'
main: 'dist/index.js'
41,139 changes: 27,440 additions & 13,699 deletions dist/index.js

Large diffs are not rendered by default.

19 changes: 12 additions & 7 deletions dist/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "azure-devops-node-api",
"description": "Node client for Azure DevOps and TFS REST APIs",
"version": "11.0.1",
"version": "15.1.1",
"main": "./WebApi.js",
"types": "./WebApi.d.ts",
"scripts": {
Expand All @@ -23,17 +23,22 @@
"Teddy Ward <t-edward@microsoft.com>"
],
"license": "MIT",
"engines": {
"node": ">= 16.0.0"
},
"dependencies": {
"tunnel": "0.0.6",
"typed-rest-client": "^1.8.4"
"typed-rest-client": "2.1.0"
},
"devDependencies": {
"@types/glob": "5.0.35",
"@types/minimatch": "3.0.3",
"@types/mocha": "^2.2.44",
"@types/shelljs": "0.7.8",
"mocha": "^3.5.3",
"@types/node": "16.11.7",
"@types/shelljs": "0.8.5",
"mocha": "^10.4.0",
"nock": "9.6.1",
"shelljs": "0.7.8",
"typescript": "3.1.5",
"@types/node": "8.9.2"
"shelljs": "^0.8.5",
"typescript": "4.0.2"
}
}
96 changes: 47 additions & 49 deletions lib/pipeline.runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const azdev = __importStar(require("azure-devops-node-api"));
const task_parameters_1 = require("./task.parameters");
const pipeline_error_1 = require("./pipeline.error");
const ReleaseInterfaces = __importStar(require("azure-devops-node-api/interfaces/ReleaseInterfaces"));
const BuildInterfaces = __importStar(require("azure-devops-node-api/interfaces/BuildInterfaces"));
const pipeline_helper_1 = require("./util/pipeline.helper");
const logger_1 = require("./util/logger");
const url_parser_1 = require("./util/url.parser");
Expand Down Expand Up @@ -80,59 +79,58 @@ class PipelineRunner {
return __awaiter(this, void 0, void 0, function* () {
let projectName = url_parser_1.UrlParser.GetProjectName(this.taskParameters.azureDevopsProjectUrl);
let pipelineName = this.taskParameters.azurePipelineName;
let buildApi = yield webApi.getBuildApi();
// Get matching build definitions for the given project and pipeline name
const buildDefinitions = yield buildApi.getDefinitions(projectName, pipelineName);
pipeline_helper_1.PipelineHelper.EnsureValidPipeline(projectName, pipelineName, buildDefinitions);
// Extract Id from build definition
let buildDefinitionReference = buildDefinitions[0];
let buildDefinitionId = buildDefinitionReference.id;
// Get build definition for the matching definition Id
let buildDefinition = yield buildApi.getDefinition(projectName, buildDefinitionId);
logger_1.Logger.LogPipelineObject(buildDefinition);
// Fetch repository details from build definition
let repositoryId = buildDefinition.repository.id.trim();
let repositoryType = buildDefinition.repository.type.trim();
let sourceBranch = null;
let sourceVersion = null;
// If definition is linked to existing github repo, pass github source branch and source version to build
if (pipeline_helper_1.PipelineHelper.equals(repositoryId, this.repository) && pipeline_helper_1.PipelineHelper.equals(repositoryType, this.githubRepo)) {
core.debug("pipeline is linked to same Github repo");
sourceBranch = this.branch,
sourceVersion = this.commitId;
let pipelinesApi = yield webApi.getPipelinesApi();
// Get all pipelines for the project
const pipelines = yield pipelinesApi.listPipelines(projectName);
// Find the pipeline by name
const pipeline = pipelines.find((x) => x.name === pipelineName);
if (!pipeline) {
throw new pipeline_error_1.PipelineNotFoundError(`Pipeline "${pipelineName}" not found in project "${projectName}"`);
}
else {
core.debug("pipeline is not linked to same Github repo");
}
let build = {
definition: {
id: buildDefinition.id
},
project: {
id: buildDefinition.project.id
},
sourceBranch: sourceBranch,
sourceVersion: sourceVersion,
reason: BuildInterfaces.BuildReason.Triggered,
parameters: this.taskParameters.azurePipelineVariables
pipeline_helper_1.PipelineHelper.EnsureValidPipeline(projectName, pipelineName, [pipeline]);
logger_1.Logger.LogPipelineObject(pipeline);
// Prepare run parameters
let runParameters = {
variables: undefined,
resources: {
repositories: {
self: {
refName: this.branch,
version: this.commitId
}
}
}
};
logger_1.Logger.LogPipelineTriggerInput(build);
// Queue build
let buildQueueResult = yield buildApi.queueBuild(build, build.project.id, true);
if (buildQueueResult != null) {
logger_1.Logger.LogPipelineTriggerOutput(buildQueueResult);
// If build result contains validation errors set result to FAILED
if (buildQueueResult.validationResults != null && buildQueueResult.validationResults.length > 0) {
let errorAndWarningMessage = pipeline_helper_1.PipelineHelper.getErrorAndWarningMessageFromBuildResult(buildQueueResult.validationResults);
core.setFailed("Errors: " + errorAndWarningMessage.errorMessage + " Warnings: " + errorAndWarningMessage.warningMessage);
// Set variables if provided
if (this.taskParameters.azurePipelineVariables) {
try {
const varsJson = JSON.parse(this.taskParameters.azurePipelineVariables);
// Convert to Pipeline API format: {key: {value: string, isSecret?: boolean}}
runParameters.variables = {};
Object.keys(varsJson).forEach(key => {
runParameters.variables[key] = { value: varsJson[key] };
});
}
else {
logger_1.Logger.LogPipelineTriggered(pipelineName, projectName);
if (buildQueueResult._links != null) {
logger_1.Logger.LogOutputUrl(buildQueueResult._links.web.href);
}
catch (e) {
core.warning("Failed to parse pipeline variables: " + e.message);
}
}
if (this.taskParameters.azurePipelineParameters) {
try {
runParameters.templateParameters = JSON.parse(this.taskParameters.azurePipelineParameters);
}
catch (e) {
core.warning("Failed to parse pipeline template parameters: " + e.message);
}
}
logger_1.Logger.LogPipelineTriggerInput(runParameters);
// Run pipeline
const runResult = yield pipelinesApi.runPipeline(runParameters, projectName, pipeline.id);
logger_1.Logger.LogPipelineTriggered(pipelineName, projectName);
logger_1.Logger.LogPipelineTriggerOutput(runResult);
if (runResult._links && runResult._links.web) {
logger_1.Logger.LogOutputUrl(runResult._links.web.href);
}
});
}
RunDesignerPipeline(webApi) {
Expand Down
4 changes: 4 additions & 0 deletions lib/task.parameters.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class TaskParameters {
this._azureDevopsProjectUrl = core.getInput('azure-devops-project-url', { required: true });
this._azurePipelineName = core.getInput('azure-pipeline-name', { required: true });
this._azureDevopsToken = core.getInput('azure-devops-token', { required: true });
this._azurePipelineParameters = core.getInput('azure-pipeline-parameters', { required: false });
this._azurePipelineVariables = core.getInput('azure-pipeline-variables', { required: false });
}
static getTaskParams() {
Expand All @@ -46,5 +47,8 @@ class TaskParameters {
get azurePipelineVariables() {
return this._azurePipelineVariables;
}
get azurePipelineParameters() {
return this._azurePipelineParameters;
}
}
exports.TaskParameters = TaskParameters;
Loading