mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
Merge branch 'master' of github.com:n8n-io/n8n into N8N-2563-workflow-activation
This commit is contained in:
commit
1de1b1cbe7
|
@ -87,7 +87,7 @@ npm install -g lerna
|
||||||
|
|
||||||
### Actual n8n setup
|
### Actual n8n setup
|
||||||
|
|
||||||
> **IMPORTANT**: All the steps bellow have to get executed at least once to get the development setup up and running!
|
> **IMPORTANT**: All the steps below have to get executed at least once to get the development setup up and running!
|
||||||
|
|
||||||
Now that everything n8n requires to run is installed the actual n8n code can be
|
Now that everything n8n requires to run is installed the actual n8n code can be
|
||||||
checked out and set up:
|
checked out and set up:
|
||||||
|
|
1082
package-lock.json
generated
1082
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,12 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import { Command, flags } from '@oclif/command';
|
import { Command, flags } from '@oclif/command';
|
||||||
import { BinaryDataManager, IBinaryDataConfig, UserSettings } from 'n8n-core';
|
import {
|
||||||
|
BinaryDataManager,
|
||||||
|
IBinaryDataConfig,
|
||||||
|
UserSettings,
|
||||||
|
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
||||||
|
} from 'n8n-core';
|
||||||
import { INode, LoggerProxy } from 'n8n-workflow';
|
import { INode, LoggerProxy } from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -96,8 +101,8 @@ export class Execute extends Command {
|
||||||
console.info(`The file "${flags.file}" does not contain valid workflow data.`);
|
console.info(`The file "${flags.file}" does not contain valid workflow data.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
||||||
workflowId = workflowData.id!.toString();
|
workflowId = workflowData.id ? workflowData.id.toString() : PLACEHOLDER_EMPTY_WORKFLOW_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait till the database is ready
|
// Wait till the database is ready
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "n8n",
|
"name": "n8n",
|
||||||
"version": "0.158.0",
|
"version": "0.159.0",
|
||||||
"description": "n8n Workflow Automation Tool",
|
"description": "n8n Workflow Automation Tool",
|
||||||
"license": "SEE LICENSE IN LICENSE.md",
|
"license": "SEE LICENSE IN LICENSE.md",
|
||||||
"homepage": "https://n8n.io",
|
"homepage": "https://n8n.io",
|
||||||
|
@ -111,10 +111,10 @@
|
||||||
"localtunnel": "^2.0.0",
|
"localtunnel": "^2.0.0",
|
||||||
"lodash.get": "^4.4.2",
|
"lodash.get": "^4.4.2",
|
||||||
"mysql2": "~2.3.0",
|
"mysql2": "~2.3.0",
|
||||||
"n8n-core": "~0.100.0",
|
"n8n-core": "~0.101.0",
|
||||||
"n8n-editor-ui": "~0.125.0",
|
"n8n-editor-ui": "~0.126.0",
|
||||||
"n8n-nodes-base": "~0.156.0",
|
"n8n-nodes-base": "~0.157.0",
|
||||||
"n8n-workflow": "~0.82.0",
|
"n8n-workflow": "~0.83.0",
|
||||||
"oauth-1.0a": "^2.2.6",
|
"oauth-1.0a": "^2.2.6",
|
||||||
"open": "^7.0.0",
|
"open": "^7.0.0",
|
||||||
"pg": "^8.3.0",
|
"pg": "^8.3.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "n8n-core",
|
"name": "n8n-core",
|
||||||
"version": "0.100.0",
|
"version": "0.101.0",
|
||||||
"description": "Core functionality of n8n",
|
"description": "Core functionality of n8n",
|
||||||
"license": "SEE LICENSE IN LICENSE.md",
|
"license": "SEE LICENSE IN LICENSE.md",
|
||||||
"homepage": "https://n8n.io",
|
"homepage": "https://n8n.io",
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"lodash.get": "^4.4.2",
|
"lodash.get": "^4.4.2",
|
||||||
"mime-types": "^2.1.27",
|
"mime-types": "^2.1.27",
|
||||||
"n8n-workflow": "~0.82.0",
|
"n8n-workflow": "~0.83.0",
|
||||||
"oauth-1.0a": "^2.2.6",
|
"oauth-1.0a": "^2.2.6",
|
||||||
"p-cancelable": "^2.0.0",
|
"p-cancelable": "^2.0.0",
|
||||||
"qs": "^6.10.1",
|
"qs": "^6.10.1",
|
||||||
|
|
|
@ -6,5 +6,6 @@ export const USER_FOLDER_ENV_OVERWRITE = 'N8N_USER_FOLDER';
|
||||||
export const USER_SETTINGS_FILE_NAME = 'config';
|
export const USER_SETTINGS_FILE_NAME = 'config';
|
||||||
export const USER_SETTINGS_SUBFOLDER = '.n8n';
|
export const USER_SETTINGS_SUBFOLDER = '.n8n';
|
||||||
export const PLACEHOLDER_EMPTY_EXECUTION_ID = '__UNKOWN__';
|
export const PLACEHOLDER_EMPTY_EXECUTION_ID = '__UNKOWN__';
|
||||||
|
export const PLACEHOLDER_EMPTY_WORKFLOW_ID = '__EMPTY__';
|
||||||
export const TUNNEL_SUBDOMAIN_ENV = 'N8N_TUNNEL_SUBDOMAIN';
|
export const TUNNEL_SUBDOMAIN_ENV = 'N8N_TUNNEL_SUBDOMAIN';
|
||||||
export const WAIT_TIME_UNLIMITED = '3000-01-01T00:00:00.000Z';
|
export const WAIT_TIME_UNLIMITED = '3000-01-01T00:00:00.000Z';
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
"jest"
|
"jest"
|
||||||
],
|
],
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"noImplicitAny": true,
|
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"strictNullChecks": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "n8n-editor-ui",
|
"name": "n8n-editor-ui",
|
||||||
"version": "0.125.0",
|
"version": "0.126.0",
|
||||||
"description": "Workflow Editor UI for n8n",
|
"description": "Workflow Editor UI for n8n",
|
||||||
"license": "SEE LICENSE IN LICENSE.md",
|
"license": "SEE LICENSE IN LICENSE.md",
|
||||||
"homepage": "https://n8n.io",
|
"homepage": "https://n8n.io",
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
"lodash.get": "^4.4.2",
|
"lodash.get": "^4.4.2",
|
||||||
"lodash.set": "^4.3.2",
|
"lodash.set": "^4.3.2",
|
||||||
"n8n-workflow": "~0.82.0",
|
"n8n-workflow": "~0.83.0",
|
||||||
"monaco-editor-webpack-plugin": "^5.0.0",
|
"monaco-editor-webpack-plugin": "^5.0.0",
|
||||||
"normalize-wheel": "^1.0.1",
|
"normalize-wheel": "^1.0.1",
|
||||||
"prismjs": "^1.17.1",
|
"prismjs": "^1.17.1",
|
||||||
|
|
|
@ -180,14 +180,6 @@ export class GithubApi implements ICredentialType {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"server": {...},
|
|
||||||
"user": {...},
|
|
||||||
"accessToken": {...},
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The object for each node credential parameter allows for the keys `displayName`, `description`, and `placeholder`.
|
The object for each node credential parameter allows for the keys `displayName`, `description`, and `placeholder`.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
@ -215,14 +207,7 @@ Only existing parameters are translatable. If a credential parameter does not ha
|
||||||
|
|
||||||
> **Note**: All keys are optional. Missing translations trigger a fallback to the `en` locale strings.
|
> **Note**: All keys are optional. Missing translations trigger a fallback to the `en` locale strings.
|
||||||
|
|
||||||
Each node translation file is an object that allows for two keys, `header` and `nodeView`, which are the _sections_ of each node translation:
|
Each node translation file is an object that allows for two keys, `header` and `nodeView`, which are the _sections_ of each node translation.
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"header": { ... },
|
|
||||||
"nodeView": { ... },
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `header` section points to an object that may contain only two keys, `displayName` and `description`, matching the node's `description.displayName` and `description.description`.
|
The `header` section points to an object that may contain only two keys, `displayName` and `description`, matching the node's `description.displayName` and `description.description`.
|
||||||
|
|
||||||
|
@ -280,7 +265,9 @@ export class Github implements INodeType {
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"nodeView": {
|
"nodeView": {
|
||||||
"resource": {...},
|
"resource": {
|
||||||
|
"displayName": "🇩🇪 Resource",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "esnext",
|
"target": "esnext",
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"noImplicitAny": true,
|
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"strictNullChecks": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "n8n-node-dev",
|
"name": "n8n-node-dev",
|
||||||
"version": "0.39.0",
|
"version": "0.40.0",
|
||||||
"description": "CLI to simplify n8n credentials/node development",
|
"description": "CLI to simplify n8n credentials/node development",
|
||||||
"license": "SEE LICENSE IN LICENSE.md",
|
"license": "SEE LICENSE IN LICENSE.md",
|
||||||
"homepage": "https://n8n.io",
|
"homepage": "https://n8n.io",
|
||||||
|
@ -61,8 +61,8 @@
|
||||||
"change-case": "^4.1.1",
|
"change-case": "^4.1.1",
|
||||||
"copyfiles": "^2.1.1",
|
"copyfiles": "^2.1.1",
|
||||||
"inquirer": "^7.0.1",
|
"inquirer": "^7.0.1",
|
||||||
"n8n-core": "~0.100.0",
|
"n8n-core": "~0.101.0",
|
||||||
"n8n-workflow": "~0.82.0",
|
"n8n-workflow": "~0.83.0",
|
||||||
"oauth-1.0a": "^2.2.6",
|
"oauth-1.0a": "^2.2.6",
|
||||||
"replace-in-file": "^6.0.0",
|
"replace-in-file": "^6.0.0",
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
],
|
],
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"noImplicitAny": true,
|
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"strictNullChecks": true,
|
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"preserveConstEnums": true,
|
"preserveConstEnums": true,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
|
|
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: '',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
|
@ -130,7 +130,7 @@ export class Box implements INodeType {
|
||||||
|
|
||||||
let mimeType: string | undefined;
|
let mimeType: string | undefined;
|
||||||
|
|
||||||
responseData = await boxApiRequest.call(this, 'GET', `/files/${fileId}/content`, {}, {}, undefined, { resolveWithFullResponse: true });
|
responseData = await boxApiRequest.call(this, 'GET', `/files/${fileId}/content`, {}, {}, undefined, { encoding: null, resolveWithFullResponse: true });
|
||||||
|
|
||||||
const newItem: INodeExecutionData = {
|
const newItem: INodeExecutionData = {
|
||||||
json: items[i].json,
|
json: items[i].json,
|
||||||
|
|
|
@ -25,6 +25,28 @@ export class GraphQL implements INodeType {
|
||||||
inputs: ['main'],
|
inputs: ['main'],
|
||||||
outputs: ['main'],
|
outputs: ['main'],
|
||||||
credentials: [
|
credentials: [
|
||||||
|
{
|
||||||
|
name: 'httpBasicAuth',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
authentication: [
|
||||||
|
'basicAuth',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'httpDigestAuth',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
authentication: [
|
||||||
|
'digestAuth',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'httpHeaderAuth',
|
name: 'httpHeaderAuth',
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -36,6 +58,39 @@ export class GraphQL implements INodeType {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'httpQueryAuth',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
authentication: [
|
||||||
|
'queryAuth',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'oAuth1Api',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
authentication: [
|
||||||
|
'oAuth1',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'oAuth2Api',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
authentication: [
|
||||||
|
'oAuth2',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
|
@ -43,10 +98,30 @@ export class GraphQL implements INodeType {
|
||||||
name: 'authentication',
|
name: 'authentication',
|
||||||
type: 'options',
|
type: 'options',
|
||||||
options: [
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Basic Auth',
|
||||||
|
value: 'basicAuth',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Digest Auth',
|
||||||
|
value: 'digestAuth',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Header Auth',
|
name: 'Header Auth',
|
||||||
value: 'headerAuth',
|
value: 'headerAuth',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Query Auth',
|
||||||
|
value: 'queryAuth',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'OAuth1',
|
||||||
|
value: 'oAuth1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'OAuth2',
|
||||||
|
value: 'oAuth2',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'None',
|
name: 'None',
|
||||||
value: 'none',
|
value: 'none',
|
||||||
|
@ -229,7 +304,12 @@ export class GraphQL implements INodeType {
|
||||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
|
|
||||||
const items = this.getInputData();
|
const items = this.getInputData();
|
||||||
|
const httpBasicAuth = await this.getCredentials('httpBasicAuth');
|
||||||
|
const httpDigestAuth = await this.getCredentials('httpDigestAuth');
|
||||||
const httpHeaderAuth = await this.getCredentials('httpHeaderAuth');
|
const httpHeaderAuth = await this.getCredentials('httpHeaderAuth');
|
||||||
|
const httpQueryAuth = await this.getCredentials('httpQueryAuth');
|
||||||
|
const oAuth1Api = await this.getCredentials('oAuth1Api');
|
||||||
|
const oAuth2Api = await this.getCredentials('oAuth2Api');
|
||||||
|
|
||||||
let requestOptions: OptionsWithUri & RequestPromiseOptions;
|
let requestOptions: OptionsWithUri & RequestPromiseOptions;
|
||||||
|
|
||||||
|
@ -260,15 +340,35 @@ export class GraphQL implements INodeType {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add credentials if any are set
|
// Add credentials if any are set
|
||||||
|
if (httpBasicAuth !== undefined) {
|
||||||
|
requestOptions.auth = {
|
||||||
|
user: httpBasicAuth.user as string,
|
||||||
|
pass: httpBasicAuth.password as string,
|
||||||
|
};
|
||||||
|
}
|
||||||
if (httpHeaderAuth !== undefined) {
|
if (httpHeaderAuth !== undefined) {
|
||||||
requestOptions.headers![httpHeaderAuth.name as string] = httpHeaderAuth.value;
|
requestOptions.headers![httpHeaderAuth.name as string] = httpHeaderAuth.value;
|
||||||
}
|
}
|
||||||
|
if (httpQueryAuth !== undefined) {
|
||||||
|
if (!requestOptions.qs) {
|
||||||
|
requestOptions.qs = {};
|
||||||
|
}
|
||||||
|
requestOptions.qs![httpQueryAuth.name as string] = httpQueryAuth.value;
|
||||||
|
}
|
||||||
|
if (httpDigestAuth !== undefined) {
|
||||||
|
requestOptions.auth = {
|
||||||
|
user: httpDigestAuth.user as string,
|
||||||
|
pass: httpDigestAuth.password as string,
|
||||||
|
sendImmediately: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const gqlQuery = this.getNodeParameter('query', itemIndex, '') as string;
|
const gqlQuery = this.getNodeParameter('query', itemIndex, '') as string;
|
||||||
if (requestMethod === 'GET') {
|
if (requestMethod === 'GET') {
|
||||||
requestOptions.qs = {
|
if (!requestOptions.qs) {
|
||||||
query: gqlQuery,
|
requestOptions.qs = {};
|
||||||
};
|
}
|
||||||
|
requestOptions.qs.query = gqlQuery;
|
||||||
} else {
|
} else {
|
||||||
if (requestFormat === 'json') {
|
if (requestFormat === 'json') {
|
||||||
requestOptions.body = {
|
requestOptions.body = {
|
||||||
|
@ -292,7 +392,15 @@ export class GraphQL implements INodeType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await this.helpers.request(requestOptions);
|
let response;
|
||||||
|
// Now that the options are all set make the actual http request
|
||||||
|
if (oAuth1Api !== undefined) {
|
||||||
|
response = await this.helpers.requestOAuth1.call(this, 'oAuth1Api', requestOptions);
|
||||||
|
} else if (oAuth2Api !== undefined) {
|
||||||
|
response = await this.helpers.requestOAuth2.call(this, 'oAuth2Api', requestOptions, { tokenType: 'Bearer' });
|
||||||
|
} else {
|
||||||
|
response = await this.helpers.request(requestOptions);
|
||||||
|
}
|
||||||
if (responseFormat === 'string') {
|
if (responseFormat === 'string') {
|
||||||
const dataPropertyName = this.getNodeParameter('dataPropertyName', 0) as string;
|
const dataPropertyName = this.getNodeParameter('dataPropertyName', 0) as string;
|
||||||
|
|
||||||
|
|
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,
|
||||||
|
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 |
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"node": "n8n-nodes-base.microsoftGraphSecurity",
|
||||||
|
"nodeVersion": "1.0",
|
||||||
|
"codexVersion": "1.0",
|
||||||
|
"categories": [
|
||||||
|
"Development"
|
||||||
|
],
|
||||||
|
"resources": {
|
||||||
|
"credentialDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/credentials/microsoft"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/nodes/n8n-nodes-base.microsoftGraphSecurity/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -191,7 +191,9 @@ export function getQuery(options: IDataObject, sobject: string, returnAll: boole
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getValue(value: any) { // tslint:disable-line:no-any
|
export function getValue(value: any) { // tslint:disable-line:no-any
|
||||||
if (typeof value === 'string') {
|
if (moment(value).isValid()) {
|
||||||
|
return value;
|
||||||
|
} else if (typeof value === 'string') {
|
||||||
return `'${value}'`;
|
return `'${value}'`;
|
||||||
} else {
|
} else {
|
||||||
return value;
|
return value;
|
||||||
|
|
20
packages/nodes-base/nodes/Supabase/Supabase.node.json
Normal file
20
packages/nodes-base/nodes/Supabase/Supabase.node.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"node": "n8n-nodes-base.supabase",
|
||||||
|
"nodeVersion": "1.0",
|
||||||
|
"codexVersion": "1.0",
|
||||||
|
"categories": [
|
||||||
|
"Data & Storage"
|
||||||
|
],
|
||||||
|
"resources": {
|
||||||
|
"credentialDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/credentials/supabase"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/nodes/n8n-nodes-base.supabase/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,8 @@
|
||||||
"Filter",
|
"Filter",
|
||||||
"Condition",
|
"Condition",
|
||||||
"Logic",
|
"Logic",
|
||||||
"Branch"
|
"Branch",
|
||||||
|
"Case"
|
||||||
],
|
],
|
||||||
"subcategories": {
|
"subcategories": {
|
||||||
"Core Nodes": [
|
"Core Nodes": [
|
||||||
|
|
20
packages/nodes-base/nodes/SyncroMSP/SyncroMsp.node.json
Normal file
20
packages/nodes-base/nodes/SyncroMSP/SyncroMsp.node.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"node": "n8n-nodes-base.syncroMsp",
|
||||||
|
"nodeVersion": "1.0",
|
||||||
|
"codexVersion": "1.0",
|
||||||
|
"categories": [
|
||||||
|
"Productivity"
|
||||||
|
],
|
||||||
|
"resources": {
|
||||||
|
"credentialDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/credentials/syncroMsp"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryDocumentation": [
|
||||||
|
{
|
||||||
|
"url": "https://docs.n8n.io/nodes/n8n-nodes-base.syncroMsp/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "n8n-nodes-base",
|
"name": "n8n-nodes-base",
|
||||||
"version": "0.156.0",
|
"version": "0.157.0",
|
||||||
"description": "Base nodes of n8n",
|
"description": "Base nodes of n8n",
|
||||||
"license": "SEE LICENSE IN LICENSE.md",
|
"license": "SEE LICENSE IN LICENSE.md",
|
||||||
"homepage": "https://n8n.io",
|
"homepage": "https://n8n.io",
|
||||||
|
@ -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",
|
||||||
|
@ -689,7 +691,7 @@
|
||||||
"@types/xml2js": "^0.4.3",
|
"@types/xml2js": "^0.4.3",
|
||||||
"gulp": "^4.0.0",
|
"gulp": "^4.0.0",
|
||||||
"jest": "^26.4.2",
|
"jest": "^26.4.2",
|
||||||
"n8n-workflow": "~0.82.0",
|
"n8n-workflow": "~0.83.0",
|
||||||
"nodelinter": "^0.1.9",
|
"nodelinter": "^0.1.9",
|
||||||
"ts-jest": "^26.3.0",
|
"ts-jest": "^26.3.0",
|
||||||
"tslint": "^6.1.2",
|
"tslint": "^6.1.2",
|
||||||
|
@ -731,7 +733,7 @@
|
||||||
"mqtt": "4.2.6",
|
"mqtt": "4.2.6",
|
||||||
"mssql": "^6.2.0",
|
"mssql": "^6.2.0",
|
||||||
"mysql2": "~2.3.0",
|
"mysql2": "~2.3.0",
|
||||||
"n8n-core": "~0.100.0",
|
"n8n-core": "~0.101.0",
|
||||||
"node-ssh": "^12.0.0",
|
"node-ssh": "^12.0.0",
|
||||||
"nodemailer": "^6.5.0",
|
"nodemailer": "^6.5.0",
|
||||||
"pdf-parse": "^1.1.1",
|
"pdf-parse": "^1.1.1",
|
||||||
|
|
|
@ -10,9 +10,7 @@
|
||||||
"jest"
|
"jest"
|
||||||
],
|
],
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"noImplicitAny": true,
|
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"strictNullChecks": true,
|
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"preserveConstEnums": true,
|
"preserveConstEnums": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "n8n-workflow",
|
"name": "n8n-workflow",
|
||||||
"version": "0.82.0",
|
"version": "0.83.0",
|
||||||
"description": "Workflow base code of n8n",
|
"description": "Workflow base code of n8n",
|
||||||
"license": "SEE LICENSE IN LICENSE.md",
|
"license": "SEE LICENSE IN LICENSE.md",
|
||||||
"homepage": "https://n8n.io",
|
"homepage": "https://n8n.io",
|
||||||
|
|
|
@ -9,9 +9,7 @@
|
||||||
"jest"
|
"jest"
|
||||||
],
|
],
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"noImplicitAny": true,
|
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"strictNullChecks": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
|
Loading…
Reference in a new issue