mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
✨ Add Jenkins Node (#2345)
* feat: initial jenkins setup * feat: trigger job functionality * feat: copy a job * feat: basic Jenkins instance operations * feat: create job from xml * feat: trigger with params * feat: basic build list * feat: list build with params * feat: basic credentials test * chore: linting fixes * feat: use baseUrl from credentials * chore: naming fixes * feat: filters collection for getall buils * fix: better ui and credentials * chore: alphabetize params and fix typos * ⚡ Small changes * ⚡ Improvements * ⚡ Improvements * ⚡ Improvements * ⚡ Improvements * ⚡ Improvements * ⚡ Improvements * ⚡ Some improvements Co-authored-by: ricardo <ricardoespinoza105@gmail.com> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
30
packages/nodes-base/credentials/JenkinsApi.credentials.ts
Normal file
30
packages/nodes-base/credentials/JenkinsApi.credentials.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import {
|
||||||
|
ICredentialType,
|
||||||
|
INodeProperties,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export class JenkinsApi implements ICredentialType {
|
||||||
|
name = 'jenkinsApi';
|
||||||
|
displayName = 'Jenkins API';
|
||||||
|
documentationUrl = 'jenkins';
|
||||||
|
properties: INodeProperties[] = [
|
||||||
|
{
|
||||||
|
displayName: 'Jenking Username',
|
||||||
|
name: 'username',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Personal API Token',
|
||||||
|
name: 'apiKey',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Jenkins Instance URL',
|
||||||
|
name: 'baseUrl',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
45
packages/nodes-base/nodes/Jenkins/GenericFunctions.ts
Normal file
45
packages/nodes-base/nodes/Jenkins/GenericFunctions.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import {
|
||||||
|
OptionsWithUri,
|
||||||
|
} from 'request';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
IExecuteSingleFunctions,
|
||||||
|
IHookFunctions,
|
||||||
|
ILoadOptionsFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IDataObject,
|
||||||
|
NodeApiError,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
export async function jenkinsApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, uri: string, qs: IDataObject = {}, body: any = '', option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||||
|
const credentials = await this.getCredentials('jenkinsApi') as IDataObject;
|
||||||
|
let options: OptionsWithUri = {
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
},
|
||||||
|
method,
|
||||||
|
auth: {
|
||||||
|
username: credentials.username as string,
|
||||||
|
password: credentials.apiKey as string,
|
||||||
|
},
|
||||||
|
uri: `${tolerateTrailingSlash(credentials.baseUrl as string)}${uri}`,
|
||||||
|
json: true,
|
||||||
|
qs,
|
||||||
|
body,
|
||||||
|
};
|
||||||
|
options = Object.assign({}, options, option);
|
||||||
|
try {
|
||||||
|
return await this.helpers.request!(options);
|
||||||
|
} catch (error) {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tolerateTrailingSlash(baseUrl: string) {
|
||||||
|
return baseUrl.endsWith('/')
|
||||||
|
? baseUrl.substr(0, baseUrl.length - 1)
|
||||||
|
: baseUrl;
|
||||||
|
}
|
||||||
20
packages/nodes-base/nodes/Jenkins/Jenkins.node.json
Normal file
20
packages/nodes-base/nodes/Jenkins/Jenkins.node.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"node": "n8n-nodes-base.jenkins",
|
||||||
|
"nodeVersion": "1.0",
|
||||||
|
"codexVersion": "1.0",
|
||||||
|
"categories": [
|
||||||
|
"Development"
|
||||||
|
],
|
||||||
|
"resources": {
|
||||||
|
"credentialDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/credentials/jenkins"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/nodes/n8n-nodes-base.jenkins/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
682
packages/nodes-base/nodes/Jenkins/Jenkins.node.ts
Normal file
682
packages/nodes-base/nodes/Jenkins/Jenkins.node.ts
Normal file
@@ -0,0 +1,682 @@
|
|||||||
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ICredentialsDecrypted,
|
||||||
|
ICredentialTestFunctions,
|
||||||
|
IDataObject,
|
||||||
|
ILoadOptionsFunctions,
|
||||||
|
INodeExecutionData,
|
||||||
|
INodePropertyOptions,
|
||||||
|
INodeType,
|
||||||
|
INodeTypeDescription,
|
||||||
|
NodeApiError,
|
||||||
|
NodeCredentialTestResult,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import {
|
||||||
|
jenkinsApiRequest,
|
||||||
|
tolerateTrailingSlash
|
||||||
|
} from './GenericFunctions';
|
||||||
|
|
||||||
|
export type JenkinsApiCredentials = {
|
||||||
|
username: string;
|
||||||
|
apiKey: string;
|
||||||
|
baseUrl: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class Jenkins implements INodeType {
|
||||||
|
description: INodeTypeDescription = {
|
||||||
|
displayName: 'Jenkins',
|
||||||
|
name: 'jenkins',
|
||||||
|
icon: 'file:jenkins.svg',
|
||||||
|
group: ['output'],
|
||||||
|
version: 1,
|
||||||
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||||
|
description: 'Consume Jenkins API',
|
||||||
|
defaults: {
|
||||||
|
name: 'Jenkins',
|
||||||
|
color: '#04AA51',
|
||||||
|
},
|
||||||
|
inputs: ['main'],
|
||||||
|
outputs: ['main'],
|
||||||
|
credentials: [
|
||||||
|
{
|
||||||
|
name: 'jenkinsApi',
|
||||||
|
required: true,
|
||||||
|
testedBy: 'jenkinApiCredentialTest',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
displayName: 'Resource',
|
||||||
|
name: 'resource',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Build',
|
||||||
|
value: 'build',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Instance',
|
||||||
|
value: 'instance',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Job',
|
||||||
|
value: 'job',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'job',
|
||||||
|
noDataExpression: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
// Job Operations
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Copy',
|
||||||
|
value: 'copy',
|
||||||
|
description: 'Copy a specific job',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Create',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create a new job',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Trigger',
|
||||||
|
value: 'trigger',
|
||||||
|
description: 'Trigger a specific job',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Trigger with Parameters',
|
||||||
|
value: 'triggerParams',
|
||||||
|
description: 'Trigger a specific job',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'trigger',
|
||||||
|
description: 'Possible operations',
|
||||||
|
noDataExpression: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Make sure the job is setup to support triggering with parameters. <a href="https://wiki.jenkins.io/display/JENKINS/Parameterized+Build" target="_blank">More info</a>',
|
||||||
|
name: 'triggerParamsNotice',
|
||||||
|
type: 'notice',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'triggerParams',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Job Name',
|
||||||
|
name: 'job',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getJobs',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'trigger',
|
||||||
|
'triggerParams',
|
||||||
|
'copy',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the job',
|
||||||
|
},
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
// Trigger a Job
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Parameters',
|
||||||
|
name: 'param',
|
||||||
|
type: 'fixedCollection',
|
||||||
|
placeholder: 'Add Parameter',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'triggerParams',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
typeOptions: {
|
||||||
|
multipleValues: true,
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'params',
|
||||||
|
displayName: 'Parameters',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getJobParameters',
|
||||||
|
loadOptionsDependsOn: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Parameters for Jenkins job',
|
||||||
|
},
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
// Copy or Create a Job
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'New Job Name',
|
||||||
|
name: 'newJob',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'copy',
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the new Jenkins job',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'XML',
|
||||||
|
name: 'xml',
|
||||||
|
type: 'string',
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
description: 'XML of Jenkins config',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'To get the XML of an existing job, add ‘config.xml’ to the end of the job URL',
|
||||||
|
name: 'createNotice',
|
||||||
|
type: 'notice',
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'job',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
// Jenkins operations
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'instance',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Cancel Quiet Down',
|
||||||
|
value: 'cancelQuietDown',
|
||||||
|
description: 'Cancel quiet down state',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Quiet Down',
|
||||||
|
value: 'quietDown',
|
||||||
|
description: 'Put Jenkins in quiet mode, no builds can be started, Jenkins is ready for shutdown',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Restart',
|
||||||
|
value: 'restart',
|
||||||
|
description: 'Restart Jenkins immediately on environments where it is possible',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Safely Restart',
|
||||||
|
value: 'safeRestart',
|
||||||
|
description: 'Restart Jenkins once no jobs are running on environments where it is possible',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Safely Shutdown',
|
||||||
|
value: 'safeExit',
|
||||||
|
description: 'Shutdown once no jobs are running',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Shutdown',
|
||||||
|
value: 'exit',
|
||||||
|
description: 'Shutdown Jenkins immediately',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'safeRestart',
|
||||||
|
description: 'Jenkins instance operations',
|
||||||
|
noDataExpression: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Reason',
|
||||||
|
name: 'reason',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'instance',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'quietDown',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
description: 'Freeform reason for quiet down mode',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Instance operation can shutdown Jenkins instance and make it unresponsive. Some commands may not be available depending on instance implementation.',
|
||||||
|
name: 'instanceNotice',
|
||||||
|
type: 'notice',
|
||||||
|
default: '',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'instance',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
// Builds operations
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'build',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Get All',
|
||||||
|
value: 'getAll',
|
||||||
|
description: 'List Builds',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'getAll',
|
||||||
|
noDataExpression: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Job Name',
|
||||||
|
name: 'job',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getJobs',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'build',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
description: 'Name of the job',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Return All',
|
||||||
|
name: 'returnAll',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'build',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Whether to return all results or only up to a given limit',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Limit',
|
||||||
|
name: 'limit',
|
||||||
|
type: 'number',
|
||||||
|
default: 50,
|
||||||
|
typeOptions: {
|
||||||
|
minValue: 1,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'build',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getAll',
|
||||||
|
],
|
||||||
|
returnAll: [
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'Max number of results to return',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
methods = {
|
||||||
|
credentialTest: {
|
||||||
|
async jenkinApiCredentialTest(
|
||||||
|
this: ICredentialTestFunctions,
|
||||||
|
credential: ICredentialsDecrypted,
|
||||||
|
): Promise<NodeCredentialTestResult> {
|
||||||
|
const { baseUrl, username, apiKey } = credential.data as JenkinsApiCredentials;
|
||||||
|
|
||||||
|
const url = tolerateTrailingSlash(baseUrl);
|
||||||
|
const endpoint = '/api/json';
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
auth: {
|
||||||
|
username: username,
|
||||||
|
password: apiKey,
|
||||||
|
},
|
||||||
|
method: 'GET',
|
||||||
|
body: {},
|
||||||
|
qs: {},
|
||||||
|
uri: `${url}${endpoint}`,
|
||||||
|
json: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.helpers.request(options);
|
||||||
|
return {
|
||||||
|
status: 'OK',
|
||||||
|
message: 'Authentication successful',
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
status: 'Error',
|
||||||
|
message: error.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
loadOptions: {
|
||||||
|
async getJobs(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
const endpoint = `/api/json`;
|
||||||
|
const { jobs } = await jenkinsApiRequest.call(this, 'GET', endpoint);
|
||||||
|
for (const job of jobs) {
|
||||||
|
returnData.push({
|
||||||
|
name: job.name,
|
||||||
|
value: job.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
returnData.sort((a, b) => {
|
||||||
|
if (a.name < b.name) { return -1; }
|
||||||
|
if (a.name > b.name) { return 1; }
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
async getJobParameters(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
|
const job = this.getCurrentNodeParameter('job') as string;
|
||||||
|
const returnData: INodePropertyOptions[] = [];
|
||||||
|
const endpoint = `/job/${job}/api/json?tree=actions[parameterDefinitions[*]]`;
|
||||||
|
const { actions } = await jenkinsApiRequest.call(this, 'GET', endpoint);
|
||||||
|
for (const { _class, parameterDefinitions } of actions) {
|
||||||
|
if (_class?.includes('ParametersDefinitionProperty')) {
|
||||||
|
for (const { name, type } of parameterDefinitions) {
|
||||||
|
returnData.push({
|
||||||
|
name: `${name} - (${type})`,
|
||||||
|
value: name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
returnData.sort((a, b) => {
|
||||||
|
if (a.name < b.name) { return -1; }
|
||||||
|
if (a.name > b.name) { return 1; }
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
|
const items = this.getInputData();
|
||||||
|
const returnData: IDataObject[] = [];
|
||||||
|
const length = items.length as unknown as number;
|
||||||
|
let responseData;
|
||||||
|
const resource = this.getNodeParameter('resource', 0) as string;
|
||||||
|
const operation = this.getNodeParameter('operation', 0) as string;
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
try {
|
||||||
|
if (resource === 'job') {
|
||||||
|
if (operation === 'trigger') {
|
||||||
|
const job = this.getNodeParameter('job', i) as string;
|
||||||
|
const endpoint = `/job/${job}/build`;
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint);
|
||||||
|
responseData = { success: true };
|
||||||
|
}
|
||||||
|
if (operation === 'triggerParams') {
|
||||||
|
const job = this.getNodeParameter('job', i) as string;
|
||||||
|
const params = this.getNodeParameter('param.params', i, []) as [];
|
||||||
|
let body = {};
|
||||||
|
if (params.length) {
|
||||||
|
body = params.reduce((body: IDataObject, param: { name: string; value: string }) => {
|
||||||
|
body[param.name] = param.value;
|
||||||
|
return body;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
const endpoint = `/job/${job}/buildWithParameters`;
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint, {}, {},
|
||||||
|
{
|
||||||
|
form: body,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
responseData = { success: true };
|
||||||
|
}
|
||||||
|
if (operation === 'copy') {
|
||||||
|
const job = this.getNodeParameter('job', i) as string;
|
||||||
|
const name = this.getNodeParameter('newJob', i) as string;
|
||||||
|
const queryParams = {
|
||||||
|
name,
|
||||||
|
mode: 'copy',
|
||||||
|
from: job,
|
||||||
|
};
|
||||||
|
|
||||||
|
const endpoint = `/createItem`;
|
||||||
|
try {
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint, queryParams);
|
||||||
|
responseData = { success: true };
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error.httpCode === '302') {
|
||||||
|
responseData = { success: true };
|
||||||
|
} else {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (operation === 'create') {
|
||||||
|
const name = this.getNodeParameter('newJob', i) as string;
|
||||||
|
const queryParams = {
|
||||||
|
name,
|
||||||
|
};
|
||||||
|
const headers = {
|
||||||
|
'content-type': 'application/xml',
|
||||||
|
};
|
||||||
|
|
||||||
|
const body = this.getNodeParameter('xml', i) as string;
|
||||||
|
|
||||||
|
const endpoint = `/createItem`;
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint, queryParams, body, { headers, json: false });
|
||||||
|
responseData = { success: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource === 'instance') {
|
||||||
|
if (operation === 'quietDown') {
|
||||||
|
const reason = this.getNodeParameter('reason', i) as string;
|
||||||
|
|
||||||
|
let queryParams;
|
||||||
|
if (reason) {
|
||||||
|
queryParams = {
|
||||||
|
reason,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const endpoint = `/quietDown`;
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint, queryParams);
|
||||||
|
responseData = { success: true };
|
||||||
|
}
|
||||||
|
if (operation === 'cancelQuietDown') {
|
||||||
|
const endpoint = `/cancelQuietDown`;
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint);
|
||||||
|
responseData = { success: true };
|
||||||
|
}
|
||||||
|
if (operation === 'restart') {
|
||||||
|
const endpoint = `/restart`;
|
||||||
|
try {
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.httpCode === '503') {
|
||||||
|
responseData = { success: true };
|
||||||
|
} else {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (operation === 'safeRestart') {
|
||||||
|
const endpoint = `/safeRestart`;
|
||||||
|
try {
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.httpCode === '503') {
|
||||||
|
responseData = { success: true };
|
||||||
|
} else {
|
||||||
|
throw new NodeApiError(this.getNode(), error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (operation === 'exit') {
|
||||||
|
const endpoint = `/exit`;
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint);
|
||||||
|
responseData = { success: true };
|
||||||
|
}
|
||||||
|
if (operation === 'safeExit') {
|
||||||
|
const endpoint = `/safeExit`;
|
||||||
|
await jenkinsApiRequest.call(this, 'POST', endpoint);
|
||||||
|
responseData = { success: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource === 'build') {
|
||||||
|
if (operation === 'getAll') {
|
||||||
|
const job = this.getNodeParameter('job', i) as string;
|
||||||
|
let endpoint = `/job/${job}/api/json?tree=builds[*]`;
|
||||||
|
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
|
||||||
|
if (!returnAll) {
|
||||||
|
const limit = this.getNodeParameter('limit', i) as number;
|
||||||
|
endpoint += `{0,${limit}}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
responseData = await jenkinsApiRequest.call(this, 'GET', endpoint);
|
||||||
|
responseData = responseData.builds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(responseData)) {
|
||||||
|
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||||
|
} else {
|
||||||
|
returnData.push(responseData as IDataObject);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (this.continueOnFail()) {
|
||||||
|
returnData.push({ error: error.message });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [this.helpers.returnJsonArray(returnData)];
|
||||||
|
}
|
||||||
|
}
|
||||||
72
packages/nodes-base/nodes/Jenkins/jenkins.svg
Normal file
72
packages/nodes-base/nodes/Jenkins/jenkins.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 47 KiB |
@@ -149,6 +149,7 @@
|
|||||||
"dist/credentials/IntercomApi.credentials.js",
|
"dist/credentials/IntercomApi.credentials.js",
|
||||||
"dist/credentials/InvoiceNinjaApi.credentials.js",
|
"dist/credentials/InvoiceNinjaApi.credentials.js",
|
||||||
"dist/credentials/IterableApi.credentials.js",
|
"dist/credentials/IterableApi.credentials.js",
|
||||||
|
"dist/credentials/JenkinsApi.credentials.js",
|
||||||
"dist/credentials/JiraSoftwareCloudApi.credentials.js",
|
"dist/credentials/JiraSoftwareCloudApi.credentials.js",
|
||||||
"dist/credentials/JiraSoftwareServerApi.credentials.js",
|
"dist/credentials/JiraSoftwareServerApi.credentials.js",
|
||||||
"dist/credentials/JotFormApi.credentials.js",
|
"dist/credentials/JotFormApi.credentials.js",
|
||||||
@@ -472,6 +473,7 @@
|
|||||||
"dist/nodes/InvoiceNinja/InvoiceNinjaTrigger.node.js",
|
"dist/nodes/InvoiceNinja/InvoiceNinjaTrigger.node.js",
|
||||||
"dist/nodes/ItemLists/ItemLists.node.js",
|
"dist/nodes/ItemLists/ItemLists.node.js",
|
||||||
"dist/nodes/Iterable/Iterable.node.js",
|
"dist/nodes/Iterable/Iterable.node.js",
|
||||||
|
"dist/nodes/Jenkins/Jenkins.node.js",
|
||||||
"dist/nodes/Jira/Jira.node.js",
|
"dist/nodes/Jira/Jira.node.js",
|
||||||
"dist/nodes/Jira/JiraTrigger.node.js",
|
"dist/nodes/Jira/JiraTrigger.node.js",
|
||||||
"dist/nodes/JotForm/JotFormTrigger.node.js",
|
"dist/nodes/JotForm/JotFormTrigger.node.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user