n8n-nodes-azuredevops-advanced 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +244 -244
- package/dist/nodes/AzureDevOpsAdvanced/AzureDevOpsAdvanced.node.js +38 -21
- package/dist/nodes/AzureDevOpsAdvanced/GenericFunctions.js +1 -1
- package/dist/nodes/AzureDevOpsAdvanced/descriptions/GitDescription.js +30 -0
- package/dist/nodes/AzureDevOpsAdvanced/descriptions/PipelineDescription.js +1 -1
- package/nodes/AzureDevOpsAdvanced/AzureDevOpsAdvanced.node.ts +38 -17
- package/nodes/AzureDevOpsAdvanced/GenericFunctions.ts +1 -1
- package/nodes/AzureDevOpsAdvanced/descriptions/GitDescription.ts +30 -0
- package/nodes/AzureDevOpsAdvanced/descriptions/PipelineDescription.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
[](https://docs.n8n.io/integrations/community-nodes/)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
A comprehensive n8n community node package for Azure DevOps integration. Manage Git, Pipelines, Work Items, Pull Requests, Test Plans, Boards, Wiki, Service Hooks, TFVC, and Artifacts — all from a single node.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Table of Contents
|
|
13
13
|
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
14
|
+
- [Features](#features)
|
|
15
|
+
- [Installation](#installation)
|
|
16
|
+
- [Credential Configuration](#credential-configuration)
|
|
17
|
+
- [Resources & Operations](#resources--operations)
|
|
18
18
|
- [Git Repositories](#1-git-repositories)
|
|
19
19
|
- [Pipeline (CI/CD)](#2-pipeline-cicd)
|
|
20
20
|
- [Work Items](#3-work-items)
|
|
@@ -25,57 +25,57 @@ Azure DevOps için kapsamlı bir n8n community node paketi. Git, Pipeline, Work
|
|
|
25
25
|
- [Service Hooks](#8-service-hooks)
|
|
26
26
|
- [TFVC](#9-tfvc)
|
|
27
27
|
- [Artifacts](#10-artifacts)
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
31
|
-
- [
|
|
28
|
+
- [Usage Examples](#usage-examples)
|
|
29
|
+
- [Requirements](#requirements)
|
|
30
|
+
- [Contributing](#contributing)
|
|
31
|
+
- [License](#license)
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
-
##
|
|
36
|
-
|
|
37
|
-
- **10
|
|
38
|
-
- **40+
|
|
39
|
-
- Azure DevOps REST API **v7.1**
|
|
40
|
-
- Personal Access Token (PAT)
|
|
41
|
-
- n8n
|
|
42
|
-
- TypeScript
|
|
43
|
-
|
|
44
|
-
###
|
|
45
|
-
|
|
46
|
-
|
|
|
47
|
-
|
|
48
|
-
| Git Repositories | 4 |
|
|
49
|
-
| Pipeline (CI/CD) | 4 |
|
|
50
|
-
| Work Items | 6 |
|
|
51
|
-
| Pull Requests | 5 |
|
|
52
|
-
| Test Plans | 4 |
|
|
53
|
-
| Boards | 3 |
|
|
54
|
-
| Wiki | 4 |
|
|
55
|
-
| Service Hooks | 2 |
|
|
56
|
-
| TFVC | 2 | TFVC
|
|
57
|
-
| Artifacts | 2 |
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **10 Azure DevOps resources** managed through a single node
|
|
38
|
+
- **40+ operations** for comprehensive automation
|
|
39
|
+
- Azure DevOps REST API **v7.1** support
|
|
40
|
+
- Secure authentication via Personal Access Token (PAT)
|
|
41
|
+
- Full support for n8n error handling and **continueOnFail**
|
|
42
|
+
- Built with TypeScript for complete type safety
|
|
43
|
+
|
|
44
|
+
### Supported Resources
|
|
45
|
+
|
|
46
|
+
| Resource | Operations | Description |
|
|
47
|
+
|----------|-----------|-------------|
|
|
48
|
+
| Git Repositories | 4 | List repos, read files, create branches, push commits |
|
|
49
|
+
| Pipeline (CI/CD) | 4 | List, run, get logs, cancel pipelines |
|
|
50
|
+
| Work Items | 6 | Create, update, list work items; manage users and tags |
|
|
51
|
+
| Pull Requests | 5 | Create, update, list PRs, read comments |
|
|
52
|
+
| Test Plans | 4 | List test plans, suites, cases, and runs |
|
|
53
|
+
| Boards | 3 | List boards, columns, and iterations (sprints) |
|
|
54
|
+
| Wiki | 4 | Read, create, and update wiki pages |
|
|
55
|
+
| Service Hooks | 2 | List and create webhook subscriptions |
|
|
56
|
+
| TFVC | 2 | List TFVC branches and read files |
|
|
57
|
+
| Artifacts | 2 | List feeds and packages |
|
|
58
58
|
|
|
59
59
|
---
|
|
60
60
|
|
|
61
|
-
##
|
|
61
|
+
## Installation
|
|
62
62
|
|
|
63
|
-
### n8n
|
|
63
|
+
### Via n8n UI (Recommended)
|
|
64
64
|
|
|
65
|
-
1. n8n
|
|
66
|
-
2. **Install**
|
|
67
|
-
3.
|
|
68
|
-
4. **Install**
|
|
65
|
+
1. In n8n, go to **Settings → Community Nodes**
|
|
66
|
+
2. Click **Install**
|
|
67
|
+
3. Enter the package name: `n8n-nodes-azuredevops-advanced`
|
|
68
|
+
4. Click **Install** and confirm the restart
|
|
69
69
|
|
|
70
|
-
###
|
|
70
|
+
### Manual Installation via npm
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
For self-hosted n8n environments:
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
75
|
npm install n8n-nodes-azuredevops-advanced
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
Docker
|
|
78
|
+
If you're running Docker, add it to the `n8n-custom-extensions` folder or build a custom Docker image:
|
|
79
79
|
|
|
80
80
|
```dockerfile
|
|
81
81
|
FROM n8nio/n8n
|
|
@@ -84,19 +84,19 @@ RUN cd /usr/local/lib/node_modules/n8n && npm install n8n-nodes-azuredevops-adva
|
|
|
84
84
|
|
|
85
85
|
---
|
|
86
86
|
|
|
87
|
-
##
|
|
87
|
+
## Credential Configuration
|
|
88
88
|
|
|
89
|
-
### Azure DevOps Personal Access Token (PAT)
|
|
89
|
+
### Creating an Azure DevOps Personal Access Token (PAT)
|
|
90
90
|
|
|
91
|
-
1. [dev.azure.com](https://dev.azure.com)
|
|
92
|
-
2.
|
|
93
|
-
3. **New Token**
|
|
94
|
-
4.
|
|
95
|
-
5. **Expiration**
|
|
96
|
-
6. **Scopes
|
|
91
|
+
1. Go to [dev.azure.com](https://dev.azure.com) and sign in
|
|
92
|
+
2. Click your user icon in the top right → **Personal access tokens**
|
|
93
|
+
3. Click **New Token**
|
|
94
|
+
4. Give the token a name (e.g. `n8n-integration`)
|
|
95
|
+
5. Set an **Expiration** date
|
|
96
|
+
6. Under **Scopes**, select the permissions you need:
|
|
97
97
|
|
|
98
|
-
|
|
|
99
|
-
|
|
98
|
+
| Scope | Permission | Used For |
|
|
99
|
+
|-------|-----------|----------|
|
|
100
100
|
| Code | Read & Write | Git, Pull Requests |
|
|
101
101
|
| Build | Read & Execute | Pipeline |
|
|
102
102
|
| Work Items | Read & Write | Work Items, Boards |
|
|
@@ -105,41 +105,41 @@ RUN cd /usr/local/lib/node_modules/n8n && npm install n8n-nodes-azuredevops-adva
|
|
|
105
105
|
| Service Hooks | Read, Write & Manage | Service Hooks |
|
|
106
106
|
| Packaging | Read | Artifacts |
|
|
107
107
|
|
|
108
|
-
7. **Create**
|
|
108
|
+
7. Click **Create** and copy the token (it won't be shown again!)
|
|
109
109
|
|
|
110
|
-
###
|
|
110
|
+
### Creating a Credential in n8n
|
|
111
111
|
|
|
112
|
-
1. n8n
|
|
113
|
-
2. **Azure DevOps Advanced API**
|
|
114
|
-
3.
|
|
112
|
+
1. In n8n, go to **Credentials → Add Credential**
|
|
113
|
+
2. Select **Azure DevOps Advanced API**
|
|
114
|
+
3. Fill in the following fields:
|
|
115
115
|
|
|
116
|
-
|
|
|
117
|
-
|
|
118
|
-
| Organization | Azure DevOps
|
|
119
|
-
| Personal Access Token |
|
|
116
|
+
| Field | Description | Example |
|
|
117
|
+
|-------|-------------|---------|
|
|
118
|
+
| Organization | Your Azure DevOps organization name | `mycompany` |
|
|
119
|
+
| Personal Access Token | The PAT you created above | `xxxxxxxxxxxxxxxxxxxx` |
|
|
120
120
|
|
|
121
|
-
4. **Save**
|
|
121
|
+
4. Click **Save**
|
|
122
122
|
|
|
123
|
-
> **
|
|
123
|
+
> **Note:** You can find your organization name in the URL: `dev.azure.com/{organization}`
|
|
124
124
|
|
|
125
125
|
---
|
|
126
126
|
|
|
127
|
-
##
|
|
127
|
+
## Resources & Operations
|
|
128
128
|
|
|
129
129
|
### 1. Git Repositories
|
|
130
130
|
|
|
131
|
-
Azure DevOps Git
|
|
131
|
+
Manage Azure DevOps Git repositories.
|
|
132
132
|
|
|
133
|
-
####
|
|
133
|
+
#### Operations
|
|
134
134
|
|
|
135
|
-
|
|
|
136
|
-
|
|
137
|
-
| **List Repositories** |
|
|
138
|
-
| **Get File Content** |
|
|
139
|
-
| **Create Branch** |
|
|
140
|
-
| **Push Commit** |
|
|
135
|
+
| Operation | Description | Required Parameters |
|
|
136
|
+
|-----------|-------------|-------------------|
|
|
137
|
+
| **List Repositories** | List all Git repos in a project | Project |
|
|
138
|
+
| **Get File Content** | Retrieve the content of a file | Project, Repository ID, File Path |
|
|
139
|
+
| **Create Branch** | Create a new branch (from main) | Project, Repository ID, Branch Name |
|
|
140
|
+
| **Push Commit** | Commit a file change | Project, Repository ID, Branch Name, Commit Message |
|
|
141
141
|
|
|
142
|
-
####
|
|
142
|
+
#### Example: Get File Content
|
|
143
143
|
|
|
144
144
|
```
|
|
145
145
|
Resource: Git Repositories
|
|
@@ -149,7 +149,7 @@ Repository ID: my-repo
|
|
|
149
149
|
File Path: /src/app.ts
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
-
####
|
|
152
|
+
#### Example: Create Branch
|
|
153
153
|
|
|
154
154
|
```
|
|
155
155
|
Resource: Git Repositories
|
|
@@ -163,18 +163,18 @@ Branch Name: refs/heads/feature/new-feature
|
|
|
163
163
|
|
|
164
164
|
### 2. Pipeline (CI/CD)
|
|
165
165
|
|
|
166
|
-
Azure DevOps build
|
|
166
|
+
Automate Azure DevOps build and release pipelines.
|
|
167
167
|
|
|
168
|
-
####
|
|
168
|
+
#### Operations
|
|
169
169
|
|
|
170
|
-
|
|
|
171
|
-
|
|
172
|
-
| **List Pipelines** |
|
|
173
|
-
| **Run Pipeline** |
|
|
174
|
-
| **Get Build Logs** |
|
|
175
|
-
| **Cancel Run** |
|
|
170
|
+
| Operation | Description | Required Parameters |
|
|
171
|
+
|-----------|-------------|-------------------|
|
|
172
|
+
| **List Pipelines** | List all pipelines | Project |
|
|
173
|
+
| **Run Pipeline** | Trigger a pipeline | Project, Pipeline ID |
|
|
174
|
+
| **Get Build Logs** | Retrieve logs for a specific run | Project, Pipeline ID, Run ID |
|
|
175
|
+
| **Cancel Run** | Cancel an active pipeline run | Project, Pipeline ID, Run ID |
|
|
176
176
|
|
|
177
|
-
####
|
|
177
|
+
#### Example: Trigger a Pipeline
|
|
178
178
|
|
|
179
179
|
```
|
|
180
180
|
Resource: Pipeline
|
|
@@ -183,7 +183,7 @@ Project: MyProject
|
|
|
183
183
|
Pipeline ID: 42
|
|
184
184
|
```
|
|
185
185
|
|
|
186
|
-
####
|
|
186
|
+
#### Example: Get Build Logs
|
|
187
187
|
|
|
188
188
|
```
|
|
189
189
|
Resource: Pipeline
|
|
@@ -197,20 +197,20 @@ Run ID: 1234
|
|
|
197
197
|
|
|
198
198
|
### 3. Work Items
|
|
199
199
|
|
|
200
|
-
Azure DevOps
|
|
200
|
+
Manage Azure DevOps work items (Task, Bug, Epic, Feature, User Story).
|
|
201
201
|
|
|
202
|
-
####
|
|
202
|
+
#### Operations
|
|
203
203
|
|
|
204
|
-
|
|
|
205
|
-
|
|
206
|
-
| **Get Work Item** |
|
|
207
|
-
| **List All Work Items** |
|
|
208
|
-
| **Create Work Item** |
|
|
209
|
-
| **Update Work Item** |
|
|
210
|
-
| **List Users** |
|
|
211
|
-
| **List Tags** |
|
|
204
|
+
| Operation | Description | Required Parameters |
|
|
205
|
+
|-----------|-------------|-------------------|
|
|
206
|
+
| **Get Work Item** | Fetch a single work item | Project, Work Item ID |
|
|
207
|
+
| **List All Work Items** | List all work items via WIQL query | Project |
|
|
208
|
+
| **Create Work Item** | Create a new work item | Project, Work Item Type, Title |
|
|
209
|
+
| **Update Work Item** | Update an existing work item | Project, Work Item ID |
|
|
210
|
+
| **List Users** | List organization users | — |
|
|
211
|
+
| **List Tags** | List all tags in a project | Project |
|
|
212
212
|
|
|
213
|
-
####
|
|
213
|
+
#### Supported Work Item Types
|
|
214
214
|
|
|
215
215
|
- Task
|
|
216
216
|
- Bug
|
|
@@ -220,7 +220,7 @@ Azure DevOps iş öğelerini (Task, Bug, Epic, Feature, User Story) yönetin.
|
|
|
220
220
|
- Issue
|
|
221
221
|
- Test Case
|
|
222
222
|
|
|
223
|
-
####
|
|
223
|
+
#### Supported Work Item States
|
|
224
224
|
|
|
225
225
|
- New / To Do
|
|
226
226
|
- Active / Doing
|
|
@@ -228,20 +228,20 @@ Azure DevOps iş öğelerini (Task, Bug, Epic, Feature, User Story) yönetin.
|
|
|
228
228
|
- Closed / Done
|
|
229
229
|
- Removed
|
|
230
230
|
|
|
231
|
-
####
|
|
231
|
+
#### Additional Fields (Optional)
|
|
232
232
|
|
|
233
|
-
|
|
233
|
+
Extra fields available when creating or updating a work item:
|
|
234
234
|
|
|
235
|
-
|
|
|
236
|
-
|
|
237
|
-
| `System.Description` |
|
|
238
|
-
| `System.AssignedTo` |
|
|
239
|
-
| `System.State` |
|
|
240
|
-
| `Microsoft.VSTS.Common.Priority` |
|
|
241
|
-
| `System.Tags` |
|
|
242
|
-
| `Custom.FieldName` |
|
|
235
|
+
| Field Name | Description |
|
|
236
|
+
|-----------|-------------|
|
|
237
|
+
| `System.Description` | Work item description (HTML supported) |
|
|
238
|
+
| `System.AssignedTo` | Assigned user name or email |
|
|
239
|
+
| `System.State` | State (New, Active, Resolved, Closed) |
|
|
240
|
+
| `Microsoft.VSTS.Common.Priority` | Priority (1=Highest, 4=Lowest) |
|
|
241
|
+
| `System.Tags` | Tags (semicolon-separated) |
|
|
242
|
+
| `Custom.FieldName` | Any custom field |
|
|
243
243
|
|
|
244
|
-
####
|
|
244
|
+
#### Example: Create a Bug
|
|
245
245
|
|
|
246
246
|
```
|
|
247
247
|
Resource: Work Items
|
|
@@ -259,39 +259,39 @@ Additional Fields:
|
|
|
259
259
|
|
|
260
260
|
### 4. Pull Requests
|
|
261
261
|
|
|
262
|
-
Git pull request
|
|
262
|
+
Automate Git pull request workflows.
|
|
263
263
|
|
|
264
|
-
####
|
|
264
|
+
#### Operations
|
|
265
265
|
|
|
266
|
-
|
|
|
267
|
-
|
|
268
|
-
| **Get Pull Request** |
|
|
269
|
-
| **List Pull Requests** |
|
|
270
|
-
| **Create Pull Request** |
|
|
271
|
-
| **Update Pull Request** |
|
|
272
|
-
| **Get Comments** | PR
|
|
266
|
+
| Operation | Description | Required Parameters |
|
|
267
|
+
|-----------|-------------|-------------------|
|
|
268
|
+
| **Get Pull Request** | Fetch a single PR | Project, Repository ID, PR ID |
|
|
269
|
+
| **List Pull Requests** | List PRs with filters | Project, Repository ID |
|
|
270
|
+
| **Create Pull Request** | Open a new PR | Project, Repository ID, Source Branch, Target Branch, Title |
|
|
271
|
+
| **Update Pull Request** | Update or merge a PR | Project, Repository ID, PR ID |
|
|
272
|
+
| **Get Comments** | Fetch PR review threads | Project, Repository ID, PR ID |
|
|
273
273
|
|
|
274
|
-
#### PR
|
|
274
|
+
#### PR Listing Filters
|
|
275
275
|
|
|
276
|
-
|
|
|
277
|
-
|
|
276
|
+
| Filter | Options |
|
|
277
|
+
|--------|---------|
|
|
278
278
|
| Status | active, abandoned, completed, all |
|
|
279
|
-
| Source Branch |
|
|
280
|
-
| Target Branch |
|
|
281
|
-
| Limit |
|
|
279
|
+
| Source Branch | Source branch name |
|
|
280
|
+
| Target Branch | Target branch name |
|
|
281
|
+
| Limit | Maximum number of results |
|
|
282
282
|
|
|
283
|
-
#### Merge
|
|
283
|
+
#### Merge Strategies
|
|
284
284
|
|
|
285
|
-
|
|
285
|
+
Merge strategies available when completing a PR:
|
|
286
286
|
|
|
287
|
-
|
|
|
288
|
-
|
|
289
|
-
| `noFastForward` |
|
|
290
|
-
| `rebase` |
|
|
291
|
-
| `rebaseMerge` | Rebase
|
|
292
|
-
| `squash` |
|
|
287
|
+
| Strategy | Description |
|
|
288
|
+
|----------|-------------|
|
|
289
|
+
| `noFastForward` | Create a merge commit |
|
|
290
|
+
| `rebase` | Rebase onto target branch |
|
|
291
|
+
| `rebaseMerge` | Rebase and create a merge commit |
|
|
292
|
+
| `squash` | Squash all commits into one |
|
|
293
293
|
|
|
294
|
-
####
|
|
294
|
+
#### Example: Create a Pull Request
|
|
295
295
|
|
|
296
296
|
```
|
|
297
297
|
Resource: Pull Requests
|
|
@@ -311,18 +311,18 @@ Additional Fields:
|
|
|
311
311
|
|
|
312
312
|
### 5. Test Plans
|
|
313
313
|
|
|
314
|
-
Azure DevOps test
|
|
314
|
+
Automate Azure DevOps test management.
|
|
315
315
|
|
|
316
|
-
####
|
|
316
|
+
#### Operations
|
|
317
317
|
|
|
318
|
-
|
|
|
319
|
-
|
|
320
|
-
| **List Test Plans** |
|
|
321
|
-
| **List Test Suites** |
|
|
322
|
-
| **List Test Cases** |
|
|
323
|
-
| **List Test Runs** |
|
|
318
|
+
| Operation | Description | Required Parameters |
|
|
319
|
+
|-----------|-------------|-------------------|
|
|
320
|
+
| **List Test Plans** | List all test plans | Project |
|
|
321
|
+
| **List Test Suites** | List suites within a plan | Project, Plan ID |
|
|
322
|
+
| **List Test Cases** | List test cases within a suite | Project, Plan ID, Suite ID |
|
|
323
|
+
| **List Test Runs** | List all test runs | Project |
|
|
324
324
|
|
|
325
|
-
####
|
|
325
|
+
#### Example: List Test Cases
|
|
326
326
|
|
|
327
327
|
```
|
|
328
328
|
Resource: Test Plans
|
|
@@ -336,17 +336,17 @@ Suite ID: 25
|
|
|
336
336
|
|
|
337
337
|
### 6. Boards
|
|
338
338
|
|
|
339
|
-
Agile board
|
|
339
|
+
Agile board and sprint management.
|
|
340
340
|
|
|
341
|
-
####
|
|
341
|
+
#### Operations
|
|
342
342
|
|
|
343
|
-
|
|
|
344
|
-
|
|
345
|
-
| **List Boards** |
|
|
346
|
-
| **List Board Columns** |
|
|
347
|
-
| **List Iterations** |
|
|
343
|
+
| Operation | Description | Required Parameters |
|
|
344
|
+
|-----------|-------------|-------------------|
|
|
345
|
+
| **List Boards** | List team boards | Project, Team |
|
|
346
|
+
| **List Board Columns** | List columns in a board | Project, Team, Board ID |
|
|
347
|
+
| **List Iterations** | Get sprint/iteration list | Project, Team |
|
|
348
348
|
|
|
349
|
-
####
|
|
349
|
+
#### Example: Get Sprint List
|
|
350
350
|
|
|
351
351
|
```
|
|
352
352
|
Resource: Boards
|
|
@@ -355,7 +355,7 @@ Project: MyProject
|
|
|
355
355
|
Team: MyProject Team
|
|
356
356
|
```
|
|
357
357
|
|
|
358
|
-
####
|
|
358
|
+
#### Common Board IDs
|
|
359
359
|
|
|
360
360
|
- `Epics`
|
|
361
361
|
- `Features`
|
|
@@ -366,18 +366,18 @@ Team: MyProject Team
|
|
|
366
366
|
|
|
367
367
|
### 7. Wiki
|
|
368
368
|
|
|
369
|
-
Azure DevOps wiki
|
|
369
|
+
Manage Azure DevOps wiki pages.
|
|
370
370
|
|
|
371
|
-
####
|
|
371
|
+
#### Operations
|
|
372
372
|
|
|
373
|
-
|
|
|
374
|
-
|
|
375
|
-
| **List Wikis** |
|
|
376
|
-
| **Get Page** |
|
|
377
|
-
| **Create Page** |
|
|
378
|
-
| **Update Page** |
|
|
373
|
+
| Operation | Description | Required Parameters |
|
|
374
|
+
|-----------|-------------|-------------------|
|
|
375
|
+
| **List Wikis** | List all wikis in a project | Project |
|
|
376
|
+
| **Get Page** | Fetch a wiki page | Project, Wiki Identifier, Page Path |
|
|
377
|
+
| **Create Page** | Create a new wiki page | Project, Wiki Identifier, Page Path, Content |
|
|
378
|
+
| **Update Page** | Update an existing wiki page | Project, Wiki Identifier, Page Path, Content |
|
|
379
379
|
|
|
380
|
-
####
|
|
380
|
+
#### Example: Create a Wiki Page
|
|
381
381
|
|
|
382
382
|
```
|
|
383
383
|
Resource: Wiki
|
|
@@ -385,37 +385,37 @@ Operation: Create Page
|
|
|
385
385
|
Project: MyProject
|
|
386
386
|
Wiki Identifier: MyProject.wiki
|
|
387
387
|
Page Path: /Documentation/API-Guide
|
|
388
|
-
Content: # API Guide\n\
|
|
388
|
+
Content: # API Guide\n\nThis page contains the API reference...
|
|
389
389
|
```
|
|
390
390
|
|
|
391
|
-
> **
|
|
391
|
+
> **Note:** The Content field supports Markdown format.
|
|
392
392
|
|
|
393
393
|
---
|
|
394
394
|
|
|
395
395
|
### 8. Service Hooks
|
|
396
396
|
|
|
397
|
-
|
|
397
|
+
Manage webhook subscriptions for Azure DevOps events.
|
|
398
398
|
|
|
399
|
-
####
|
|
399
|
+
#### Operations
|
|
400
400
|
|
|
401
|
-
|
|
|
402
|
-
|
|
403
|
-
| **List Subscriptions** |
|
|
404
|
-
| **Create Subscription** |
|
|
401
|
+
| Operation | Description | Required Parameters |
|
|
402
|
+
|-----------|-------------|-------------------|
|
|
403
|
+
| **List Subscriptions** | List all webhook subscriptions | — |
|
|
404
|
+
| **Create Subscription** | Create a new webhook subscription | Project, Event Type, Consumer URL |
|
|
405
405
|
|
|
406
|
-
####
|
|
406
|
+
#### Supported Event Types
|
|
407
407
|
|
|
408
|
-
| Event
|
|
409
|
-
|
|
410
|
-
| `build.complete` | Build
|
|
411
|
-
| `git.push` |
|
|
412
|
-
| `git.pullrequest.created` | Pull
|
|
413
|
-
| `git.pullrequest.merged` | Pull
|
|
414
|
-
| `workitem.created` |
|
|
415
|
-
| `workitem.updated` |
|
|
416
|
-
| `ms.vss-release.release-created-event` | Release
|
|
408
|
+
| Event Type | Description |
|
|
409
|
+
|-----------|-------------|
|
|
410
|
+
| `build.complete` | Build completed |
|
|
411
|
+
| `git.push` | Code pushed |
|
|
412
|
+
| `git.pullrequest.created` | Pull request created |
|
|
413
|
+
| `git.pullrequest.merged` | Pull request merged |
|
|
414
|
+
| `workitem.created` | Work item created |
|
|
415
|
+
| `workitem.updated` | Work item updated |
|
|
416
|
+
| `ms.vss-release.release-created-event` | Release created |
|
|
417
417
|
|
|
418
|
-
####
|
|
418
|
+
#### Example: Create a Webhook Subscription
|
|
419
419
|
|
|
420
420
|
```
|
|
421
421
|
Resource: Service Hooks
|
|
@@ -425,22 +425,22 @@ Event Type: git.push
|
|
|
425
425
|
Consumer URL: https://your-n8n-instance.com/webhook/xyz
|
|
426
426
|
```
|
|
427
427
|
|
|
428
|
-
>
|
|
428
|
+
> **Tip:** Use your n8n Webhook node's URL as the Consumer URL to connect Azure DevOps events directly to n8n workflows.
|
|
429
429
|
|
|
430
430
|
---
|
|
431
431
|
|
|
432
432
|
### 9. TFVC
|
|
433
433
|
|
|
434
|
-
Team Foundation Version Control (
|
|
434
|
+
Support for Team Foundation Version Control (legacy source control).
|
|
435
435
|
|
|
436
|
-
####
|
|
436
|
+
#### Operations
|
|
437
437
|
|
|
438
|
-
|
|
|
439
|
-
|
|
440
|
-
| **List Branches** | TFVC
|
|
441
|
-
| **Get File Content** |
|
|
438
|
+
| Operation | Description | Required Parameters |
|
|
439
|
+
|-----------|-------------|-------------------|
|
|
440
|
+
| **List Branches** | List TFVC branches and folders | Project |
|
|
441
|
+
| **Get File Content** | Read a file from TFVC | Project, File Path |
|
|
442
442
|
|
|
443
|
-
####
|
|
443
|
+
#### Example: Read a TFVC File
|
|
444
444
|
|
|
445
445
|
```
|
|
446
446
|
Resource: TFVC
|
|
@@ -449,22 +449,22 @@ Project: MyProject
|
|
|
449
449
|
File Path: $/MyProject/src/main.cs
|
|
450
450
|
```
|
|
451
451
|
|
|
452
|
-
> **
|
|
452
|
+
> **Note:** TFVC paths start with `$/`.
|
|
453
453
|
|
|
454
454
|
---
|
|
455
455
|
|
|
456
456
|
### 10. Artifacts
|
|
457
457
|
|
|
458
|
-
Azure Artifacts
|
|
458
|
+
Azure Artifacts package feed management.
|
|
459
459
|
|
|
460
|
-
####
|
|
460
|
+
#### Operations
|
|
461
461
|
|
|
462
|
-
|
|
|
463
|
-
|
|
464
|
-
| **List Feeds** |
|
|
465
|
-
| **List Packages** |
|
|
462
|
+
| Operation | Description | Required Parameters |
|
|
463
|
+
|-----------|-------------|-------------------|
|
|
464
|
+
| **List Feeds** | List all artifact feeds | Project |
|
|
465
|
+
| **List Packages** | List packages in a feed | Project, Feed ID |
|
|
466
466
|
|
|
467
|
-
####
|
|
467
|
+
#### Example: List Packages
|
|
468
468
|
|
|
469
469
|
```
|
|
470
470
|
Resource: Artifacts
|
|
@@ -475,76 +475,76 @@ Feed ID: my-nuget-feed
|
|
|
475
475
|
|
|
476
476
|
---
|
|
477
477
|
|
|
478
|
-
##
|
|
478
|
+
## Usage Examples
|
|
479
479
|
|
|
480
|
-
###
|
|
480
|
+
### Example 1: Automated PR Creation Workflow
|
|
481
481
|
|
|
482
|
-
|
|
482
|
+
This workflow automatically creates a PR in Azure DevOps in response to an external event:
|
|
483
483
|
|
|
484
|
-
1. **Webhook Trigger** → GitHub push event
|
|
485
|
-
2. **Azure DevOps Advanced** (Git: Create Branch) →
|
|
486
|
-
3. **Azure DevOps Advanced** (Pull Requests: Create) → PR
|
|
487
|
-
4. **Slack** →
|
|
484
|
+
1. **Webhook Trigger** → Receives a GitHub push event
|
|
485
|
+
2. **Azure DevOps Advanced** (Git: Create Branch) → Creates a new branch
|
|
486
|
+
3. **Azure DevOps Advanced** (Pull Requests: Create) → Opens a PR
|
|
487
|
+
4. **Slack** → Sends a notification to the team
|
|
488
488
|
|
|
489
|
-
###
|
|
489
|
+
### Example 2: Work Item Automation
|
|
490
490
|
|
|
491
|
-
Jira
|
|
491
|
+
Synchronize issues from Jira to Azure DevOps:
|
|
492
492
|
|
|
493
|
-
1. **Schedule Trigger** →
|
|
494
|
-
2. **Jira** →
|
|
495
|
-
3. **IF** →
|
|
496
|
-
4. **Azure DevOps Advanced** (Work Items: Create) → Task
|
|
497
|
-
5. **Jira** →
|
|
493
|
+
1. **Schedule Trigger** → Runs every hour
|
|
494
|
+
2. **Jira** → Lists new issues
|
|
495
|
+
3. **IF** → Filters out items already in Azure DevOps
|
|
496
|
+
4. **Azure DevOps Advanced** (Work Items: Create) → Creates a Task
|
|
497
|
+
5. **Jira** → Updates the original issue
|
|
498
498
|
|
|
499
|
-
###
|
|
499
|
+
### Example 3: Build Monitoring
|
|
500
500
|
|
|
501
|
-
|
|
501
|
+
Send an alert when a pipeline fails:
|
|
502
502
|
|
|
503
|
-
1. **Azure DevOps Advanced** (Service Hooks: Create Subscription) →
|
|
504
|
-
2. **Webhook** →
|
|
505
|
-
3. **IF** →
|
|
506
|
-
4. **Azure DevOps Advanced** (Pipeline: Get Build Logs) →
|
|
507
|
-
5. **Email / Slack** →
|
|
503
|
+
1. **Azure DevOps Advanced** (Service Hooks: Create Subscription) → Subscribes to build events
|
|
504
|
+
2. **Webhook** → Receives the build complete event
|
|
505
|
+
3. **IF** → Checks whether the build failed
|
|
506
|
+
4. **Azure DevOps Advanced** (Pipeline: Get Build Logs) → Fetches error logs
|
|
507
|
+
5. **Email / Slack** → Sends a detailed failure notification
|
|
508
508
|
|
|
509
509
|
---
|
|
510
510
|
|
|
511
|
-
##
|
|
511
|
+
## Requirements
|
|
512
512
|
|
|
513
513
|
- **n8n** >= 1.0.0
|
|
514
514
|
- **Node.js** >= 18.x
|
|
515
|
-
- Azure DevOps
|
|
516
|
-
-
|
|
515
|
+
- An Azure DevOps account and organization
|
|
516
|
+
- A Personal Access Token (PAT) with sufficient permissions
|
|
517
517
|
|
|
518
518
|
---
|
|
519
519
|
|
|
520
|
-
##
|
|
520
|
+
## Development
|
|
521
521
|
|
|
522
|
-
|
|
522
|
+
To run the project locally:
|
|
523
523
|
|
|
524
524
|
```bash
|
|
525
|
-
#
|
|
525
|
+
# Clone the repository
|
|
526
526
|
git clone https://github.com/ertekinozturgut/n8n-nodes-azuredevops-advanced.git
|
|
527
527
|
cd n8n-nodes-azuredevops-advanced
|
|
528
528
|
|
|
529
|
-
#
|
|
529
|
+
# Install dependencies
|
|
530
530
|
npm install
|
|
531
531
|
|
|
532
|
-
# TypeScript
|
|
532
|
+
# TypeScript compilation (watch mode)
|
|
533
533
|
npm run dev
|
|
534
534
|
|
|
535
|
-
#
|
|
535
|
+
# Production build
|
|
536
536
|
npm run build
|
|
537
537
|
```
|
|
538
538
|
|
|
539
|
-
###
|
|
539
|
+
### Project Structure
|
|
540
540
|
|
|
541
541
|
```
|
|
542
542
|
n8n-nodes-azuredevops-advanced/
|
|
543
543
|
├── nodes/
|
|
544
544
|
│ └── AzureDevOpsAdvanced/
|
|
545
|
-
│ ├── AzureDevOpsAdvanced.node.ts #
|
|
546
|
-
│ ├── GenericFunctions.ts # API
|
|
547
|
-
│ ├── azureDevOps.svg # Node
|
|
545
|
+
│ ├── AzureDevOpsAdvanced.node.ts # Main node implementation
|
|
546
|
+
│ ├── GenericFunctions.ts # API request helper
|
|
547
|
+
│ ├── azureDevOps.svg # Node icon
|
|
548
548
|
│ └── descriptions/
|
|
549
549
|
│ ├── GitDescription.ts
|
|
550
550
|
│ ├── PipelineDescription.ts
|
|
@@ -558,38 +558,38 @@ n8n-nodes-azuredevops-advanced/
|
|
|
558
558
|
│ └── ArtifactsDescription.ts
|
|
559
559
|
├── credentials/
|
|
560
560
|
│ └── AzureDevOpsAdvancedApi.credentials.ts
|
|
561
|
-
├── dist/ #
|
|
561
|
+
├── dist/ # Compiled JavaScript
|
|
562
562
|
├── package.json
|
|
563
563
|
└── tsconfig.json
|
|
564
564
|
```
|
|
565
565
|
|
|
566
566
|
---
|
|
567
567
|
|
|
568
|
-
##
|
|
568
|
+
## Contributing
|
|
569
569
|
|
|
570
|
-
|
|
570
|
+
Contributions are welcome! Please follow these steps:
|
|
571
571
|
|
|
572
|
-
1.
|
|
573
|
-
2.
|
|
574
|
-
3.
|
|
575
|
-
4.
|
|
576
|
-
5. Pull Request
|
|
572
|
+
1. Fork the repository
|
|
573
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
574
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
575
|
+
4. Push the branch (`git push origin feature/amazing-feature`)
|
|
576
|
+
5. Open a Pull Request
|
|
577
577
|
|
|
578
|
-
### Bug
|
|
578
|
+
### Bug Reports
|
|
579
579
|
|
|
580
|
-
[GitHub Issues](https://github.com/ertekinozturgut/n8n-nodes-azuredevops-advanced/issues)
|
|
580
|
+
You can report bugs or request features via [GitHub Issues](https://github.com/ertekinozturgut/n8n-nodes-azuredevops-advanced/issues).
|
|
581
581
|
|
|
582
582
|
---
|
|
583
583
|
|
|
584
|
-
##
|
|
584
|
+
## License
|
|
585
585
|
|
|
586
|
-
|
|
586
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
587
587
|
|
|
588
588
|
---
|
|
589
589
|
|
|
590
|
-
##
|
|
590
|
+
## Links
|
|
591
591
|
|
|
592
|
-
- [npm
|
|
593
|
-
- [GitHub
|
|
594
|
-
- [Azure DevOps REST API
|
|
595
|
-
- [n8n Community Nodes
|
|
592
|
+
- [npm Package](https://www.npmjs.com/package/n8n-nodes-azuredevops-advanced)
|
|
593
|
+
- [GitHub Repository](https://github.com/ertekinozturgut/n8n-nodes-azuredevops-advanced)
|
|
594
|
+
- [Azure DevOps REST API Documentation](https://docs.microsoft.com/en-us/rest/api/azure/devops/)
|
|
595
|
+
- [n8n Community Nodes Guide](https://docs.n8n.io/integrations/community-nodes/)
|
|
@@ -21,7 +21,7 @@ class AzureDevOpsAdvanced {
|
|
|
21
21
|
group: ['transform'],
|
|
22
22
|
version: 1,
|
|
23
23
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
24
|
-
description: '
|
|
24
|
+
description: 'Comprehensive Azure DevOps integration node',
|
|
25
25
|
defaults: { name: 'Azure DevOps Advanced' },
|
|
26
26
|
inputs: ['main'],
|
|
27
27
|
outputs: ['main'],
|
|
@@ -70,7 +70,7 @@ class AzureDevOpsAdvanced {
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
async execute() {
|
|
73
|
-
var _a, _b, _c, _d;
|
|
73
|
+
var _a, _b, _c, _d, _e, _f;
|
|
74
74
|
const items = this.getInputData();
|
|
75
75
|
const returnData = [];
|
|
76
76
|
const resource = this.getNodeParameter('resource', 0);
|
|
@@ -95,25 +95,45 @@ class AzureDevOpsAdvanced {
|
|
|
95
95
|
else if (operation === 'createBranch') {
|
|
96
96
|
const repoId = this.getNodeParameter('repositoryId', i);
|
|
97
97
|
const branchName = this.getNodeParameter('branchName', i);
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
// Try main first, fall back to master
|
|
99
|
+
let oldObjectId = '0000000000000000000000000000000000000000';
|
|
100
|
+
for (const baseBranch of ['main', 'master']) {
|
|
101
|
+
const refResponse = await GenericFunctions_1.azureApiRequest.call(this, 'GET', `${project}/_apis/git/repositories/${repoId}/refs?filter=heads/${baseBranch}&api-version=7.1`);
|
|
102
|
+
if ((_b = (_a = refResponse === null || refResponse === void 0 ? void 0 : refResponse.value) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.objectId) {
|
|
103
|
+
oldObjectId = refResponse.value[0].objectId;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
103
107
|
const createEndpoint = `${project}/_apis/git/repositories/${repoId}/refs?api-version=7.1`;
|
|
104
|
-
const body = [{ name: branchName, newObjectId: oldObjectId, oldObjectId:
|
|
108
|
+
const body = [{ name: branchName, newObjectId: oldObjectId, oldObjectId: '0000000000000000000000000000000000000000' }];
|
|
105
109
|
responseData = await GenericFunctions_1.azureApiRequest.call(this, 'POST', createEndpoint, body);
|
|
110
|
+
responseData = (responseData === null || responseData === void 0 ? void 0 : responseData.value) || responseData;
|
|
106
111
|
}
|
|
107
112
|
else if (operation === 'pushCommit') {
|
|
108
113
|
const repoId = this.getNodeParameter('repositoryId', i);
|
|
109
114
|
const branchName = this.getNodeParameter('branchName', i);
|
|
110
115
|
const commitMessage = this.getNodeParameter('commitMessage', i);
|
|
111
|
-
|
|
112
|
-
|
|
116
|
+
const pushFilePath = this.getNodeParameter('pushFilePath', i);
|
|
117
|
+
const fileContent = this.getNodeParameter('fileContent', i);
|
|
118
|
+
const changeType = this.getNodeParameter('changeType', i);
|
|
119
|
+
// Get current branch HEAD to use as oldObjectId
|
|
120
|
+
const branchFilter = branchName.replace('refs/heads/', '');
|
|
121
|
+
const refResponse = await GenericFunctions_1.azureApiRequest.call(this, 'GET', `${project}/_apis/git/repositories/${repoId}/refs?filter=heads/${branchFilter}&api-version=7.1`);
|
|
122
|
+
const oldObjectId = ((_d = (_c = refResponse === null || refResponse === void 0 ? void 0 : refResponse.value) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.objectId) || '0000000000000000000000000000000000000000';
|
|
113
123
|
const endpoint = `${project}/_apis/git/repositories/${repoId}/pushes?api-version=7.1`;
|
|
114
124
|
const body = {
|
|
115
|
-
refUpdates: [{ name: branchName, oldObjectId
|
|
116
|
-
commits: [{
|
|
125
|
+
refUpdates: [{ name: branchName, oldObjectId }],
|
|
126
|
+
commits: [{
|
|
127
|
+
comment: commitMessage,
|
|
128
|
+
changes: [{
|
|
129
|
+
changeType,
|
|
130
|
+
item: { path: pushFilePath.startsWith('/') ? pushFilePath : `/${pushFilePath}` },
|
|
131
|
+
newContent: {
|
|
132
|
+
content: Buffer.from(fileContent).toString('base64'),
|
|
133
|
+
contentType: 'base64Encoded',
|
|
134
|
+
},
|
|
135
|
+
}],
|
|
136
|
+
}],
|
|
117
137
|
};
|
|
118
138
|
responseData = await GenericFunctions_1.azureApiRequest.call(this, 'POST', endpoint, body);
|
|
119
139
|
}
|
|
@@ -169,7 +189,7 @@ class AzureDevOpsAdvanced {
|
|
|
169
189
|
const endpoint = `${project}/_apis/wit/wiql?api-version=7.1`;
|
|
170
190
|
const wiqlQuery = { query: `Select [System.Id], [System.Title], [System.State] From WorkItems Where [System.TeamProject] = '${project}'` };
|
|
171
191
|
const idsResponse = await GenericFunctions_1.azureApiRequest.call(this, 'POST', endpoint, wiqlQuery);
|
|
172
|
-
const idsArray = (
|
|
192
|
+
const idsArray = (_e = idsResponse === null || idsResponse === void 0 ? void 0 : idsResponse.workItems) === null || _e === void 0 ? void 0 : _e.map((wi) => wi.id);
|
|
173
193
|
if (idsArray && idsArray.length > 0) {
|
|
174
194
|
const workItemIds = idsArray.join(',');
|
|
175
195
|
const bulkEndpoint = `${project}/_apis/wit/workitems?ids=${workItemIds}&api-version=7.1`;
|
|
@@ -195,14 +215,14 @@ class AzureDevOpsAdvanced {
|
|
|
195
215
|
if (!isUpdate) {
|
|
196
216
|
mapPropertyToPatch('System.Title', this.getNodeParameter('title', i));
|
|
197
217
|
}
|
|
198
|
-
const additionalFields = this.getNodeParameter('additionalFields', i);
|
|
199
|
-
if (Object.keys(additionalFields).length) {
|
|
218
|
+
const additionalFields = this.getNodeParameter('additionalFields', i, {});
|
|
219
|
+
if (additionalFields && Object.keys(additionalFields).length) {
|
|
200
220
|
mapPropertyToPatch('System.Description', additionalFields.description);
|
|
201
221
|
mapPropertyToPatch('System.AssignedTo', additionalFields.assignedTo);
|
|
202
222
|
mapPropertyToPatch('System.State', additionalFields.state);
|
|
203
223
|
mapPropertyToPatch('Microsoft.VSTS.Common.Priority', additionalFields.priority);
|
|
204
224
|
mapPropertyToPatch('System.Tags', additionalFields.tags);
|
|
205
|
-
if ((
|
|
225
|
+
if ((_f = additionalFields.customFieldsUi) === null || _f === void 0 ? void 0 : _f.customFieldsValues) {
|
|
206
226
|
for (const customField of additionalFields.customFieldsUi.customFieldsValues) {
|
|
207
227
|
mapPropertyToPatch(customField.fieldId, customField.fieldValue);
|
|
208
228
|
}
|
|
@@ -256,7 +276,7 @@ class AzureDevOpsAdvanced {
|
|
|
256
276
|
}
|
|
257
277
|
else if (operation === 'getComments') {
|
|
258
278
|
const pullRequestId = this.getNodeParameter('pullRequestId', i);
|
|
259
|
-
const endpoint = `${project}/_apis/git/repositories/${repositoryId}/
|
|
279
|
+
const endpoint = `${project}/_apis/git/repositories/${repositoryId}/pullrequests/${pullRequestId}/threads?api-version=7.1`;
|
|
260
280
|
responseData = await GenericFunctions_1.azureApiRequest.call(this, 'GET', endpoint);
|
|
261
281
|
responseData = (responseData === null || responseData === void 0 ? void 0 : responseData.value) || responseData;
|
|
262
282
|
}
|
|
@@ -264,12 +284,9 @@ class AzureDevOpsAdvanced {
|
|
|
264
284
|
const listOptions = this.getNodeParameter('listOptions', i);
|
|
265
285
|
let endpoint = `${project}/_apis/git/repositories/${repositoryId}/pullrequests?api-version=7.1`;
|
|
266
286
|
if (listOptions) {
|
|
267
|
-
if (listOptions.status
|
|
287
|
+
if (listOptions.status) {
|
|
268
288
|
endpoint += `&searchCriteria.status=${listOptions.status}`;
|
|
269
289
|
}
|
|
270
|
-
else if (listOptions.status === 'all') {
|
|
271
|
-
endpoint += `&searchCriteria.status=all`;
|
|
272
|
-
}
|
|
273
290
|
if (listOptions.creatorId)
|
|
274
291
|
endpoint += `&searchCriteria.creatorId=${listOptions.creatorId}`;
|
|
275
292
|
if (listOptions.reviewerId)
|
|
@@ -19,7 +19,7 @@ async function azureApiRequest(method, endpoint, body = {}, query = {}) {
|
|
|
19
19
|
},
|
|
20
20
|
json: true,
|
|
21
21
|
};
|
|
22
|
-
if (Object.keys(body).length === 0) {
|
|
22
|
+
if (!Array.isArray(body) && Object.keys(body).length === 0) {
|
|
23
23
|
delete options.body;
|
|
24
24
|
}
|
|
25
25
|
return this.helpers.request(options);
|
|
@@ -90,6 +90,36 @@ exports.gitFields = [
|
|
|
90
90
|
},
|
|
91
91
|
},
|
|
92
92
|
},
|
|
93
|
+
{
|
|
94
|
+
displayName: 'File Path',
|
|
95
|
+
name: 'pushFilePath',
|
|
96
|
+
type: 'string',
|
|
97
|
+
default: '',
|
|
98
|
+
required: true,
|
|
99
|
+
displayOptions: {
|
|
100
|
+
show: {
|
|
101
|
+
resource: ['git'],
|
|
102
|
+
operation: ['pushCommit'],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
description: 'Path of the file to create or update (e.g. /src/app.ts)',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
displayName: 'Change Type',
|
|
109
|
+
name: 'changeType',
|
|
110
|
+
type: 'options',
|
|
111
|
+
options: [
|
|
112
|
+
{ name: 'Edit (update existing file)', value: 'edit' },
|
|
113
|
+
{ name: 'Add (create new file)', value: 'add' },
|
|
114
|
+
],
|
|
115
|
+
default: 'edit',
|
|
116
|
+
displayOptions: {
|
|
117
|
+
show: {
|
|
118
|
+
resource: ['git'],
|
|
119
|
+
operation: ['pushCommit'],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
93
123
|
{
|
|
94
124
|
displayName: 'File Content',
|
|
95
125
|
name: 'fileContent',
|
|
@@ -19,7 +19,7 @@ export class AzureDevOpsAdvanced implements INodeType {
|
|
|
19
19
|
group: ['transform'],
|
|
20
20
|
version: 1,
|
|
21
21
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
22
|
-
description: '
|
|
22
|
+
description: 'Comprehensive Azure DevOps integration node',
|
|
23
23
|
defaults: { name: 'Azure DevOps Advanced' },
|
|
24
24
|
inputs: ['main'],
|
|
25
25
|
outputs: ['main'],
|
|
@@ -94,26 +94,49 @@ export class AzureDevOpsAdvanced implements INodeType {
|
|
|
94
94
|
else if (operation === 'createBranch') {
|
|
95
95
|
const repoId = this.getNodeParameter('repositoryId', i) as string;
|
|
96
96
|
const branchName = this.getNodeParameter('branchName', i) as string;
|
|
97
|
-
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
97
|
+
|
|
98
|
+
// Try main first, fall back to master
|
|
99
|
+
let oldObjectId = '0000000000000000000000000000000000000000';
|
|
100
|
+
for (const baseBranch of ['main', 'master']) {
|
|
101
|
+
const refResponse = await azureApiRequest.call(this, 'GET', `${project}/_apis/git/repositories/${repoId}/refs?filter=heads/${baseBranch}&api-version=7.1`);
|
|
102
|
+
if (refResponse?.value?.[0]?.objectId) {
|
|
103
|
+
oldObjectId = refResponse.value[0].objectId;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
102
107
|
|
|
103
108
|
const createEndpoint = `${project}/_apis/git/repositories/${repoId}/refs?api-version=7.1`;
|
|
104
|
-
const body = [{ name: branchName, newObjectId: oldObjectId, oldObjectId:
|
|
109
|
+
const body = [{ name: branchName, newObjectId: oldObjectId, oldObjectId: '0000000000000000000000000000000000000000' }];
|
|
105
110
|
responseData = await azureApiRequest.call(this, 'POST', createEndpoint, body);
|
|
111
|
+
responseData = responseData?.value || responseData;
|
|
106
112
|
}
|
|
107
113
|
else if (operation === 'pushCommit') {
|
|
108
114
|
const repoId = this.getNodeParameter('repositoryId', i) as string;
|
|
109
115
|
const branchName = this.getNodeParameter('branchName', i) as string;
|
|
110
116
|
const commitMessage = this.getNodeParameter('commitMessage', i) as string;
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
const pushFilePath = this.getNodeParameter('pushFilePath', i) as string;
|
|
118
|
+
const fileContent = this.getNodeParameter('fileContent', i) as string;
|
|
119
|
+
const changeType = this.getNodeParameter('changeType', i) as string;
|
|
120
|
+
|
|
121
|
+
// Get current branch HEAD to use as oldObjectId
|
|
122
|
+
const branchFilter = branchName.replace('refs/heads/', '');
|
|
123
|
+
const refResponse = await azureApiRequest.call(this, 'GET', `${project}/_apis/git/repositories/${repoId}/refs?filter=heads/${branchFilter}&api-version=7.1`);
|
|
124
|
+
const oldObjectId = refResponse?.value?.[0]?.objectId || '0000000000000000000000000000000000000000';
|
|
125
|
+
|
|
113
126
|
const endpoint = `${project}/_apis/git/repositories/${repoId}/pushes?api-version=7.1`;
|
|
114
127
|
const body = {
|
|
115
|
-
refUpdates: [{ name: branchName, oldObjectId
|
|
116
|
-
commits: [{
|
|
128
|
+
refUpdates: [{ name: branchName, oldObjectId }],
|
|
129
|
+
commits: [{
|
|
130
|
+
comment: commitMessage,
|
|
131
|
+
changes: [{
|
|
132
|
+
changeType,
|
|
133
|
+
item: { path: pushFilePath.startsWith('/') ? pushFilePath : `/${pushFilePath}` },
|
|
134
|
+
newContent: {
|
|
135
|
+
content: Buffer.from(fileContent).toString('base64'),
|
|
136
|
+
contentType: 'base64Encoded',
|
|
137
|
+
},
|
|
138
|
+
}],
|
|
139
|
+
}],
|
|
117
140
|
};
|
|
118
141
|
responseData = await azureApiRequest.call(this, 'POST', endpoint, body);
|
|
119
142
|
}
|
|
@@ -203,8 +226,8 @@ export class AzureDevOpsAdvanced implements INodeType {
|
|
|
203
226
|
mapPropertyToPatch('System.Title', this.getNodeParameter('title', i));
|
|
204
227
|
}
|
|
205
228
|
|
|
206
|
-
const additionalFields = this.getNodeParameter('additionalFields', i) as any;
|
|
207
|
-
if (Object.keys(additionalFields).length) {
|
|
229
|
+
const additionalFields = this.getNodeParameter('additionalFields', i, {}) as any;
|
|
230
|
+
if (additionalFields && Object.keys(additionalFields).length) {
|
|
208
231
|
mapPropertyToPatch('System.Description', additionalFields.description);
|
|
209
232
|
mapPropertyToPatch('System.AssignedTo', additionalFields.assignedTo);
|
|
210
233
|
mapPropertyToPatch('System.State', additionalFields.state);
|
|
@@ -270,7 +293,7 @@ export class AzureDevOpsAdvanced implements INodeType {
|
|
|
270
293
|
}
|
|
271
294
|
else if (operation === 'getComments') {
|
|
272
295
|
const pullRequestId = this.getNodeParameter('pullRequestId', i) as number;
|
|
273
|
-
const endpoint = `${project}/_apis/git/repositories/${repositoryId}/
|
|
296
|
+
const endpoint = `${project}/_apis/git/repositories/${repositoryId}/pullrequests/${pullRequestId}/threads?api-version=7.1`;
|
|
274
297
|
responseData = await azureApiRequest.call(this, 'GET', endpoint);
|
|
275
298
|
responseData = responseData?.value || responseData;
|
|
276
299
|
}
|
|
@@ -279,10 +302,8 @@ export class AzureDevOpsAdvanced implements INodeType {
|
|
|
279
302
|
let endpoint = `${project}/_apis/git/repositories/${repositoryId}/pullrequests?api-version=7.1`;
|
|
280
303
|
|
|
281
304
|
if (listOptions) {
|
|
282
|
-
if (listOptions.status
|
|
305
|
+
if (listOptions.status) {
|
|
283
306
|
endpoint += `&searchCriteria.status=${listOptions.status}`;
|
|
284
|
-
} else if (listOptions.status === 'all') {
|
|
285
|
-
endpoint += `&searchCriteria.status=all`;
|
|
286
307
|
}
|
|
287
308
|
if (listOptions.creatorId) endpoint += `&searchCriteria.creatorId=${listOptions.creatorId}`;
|
|
288
309
|
if (listOptions.reviewerId) endpoint += `&searchCriteria.reviewerId=${listOptions.reviewerId}`;
|
|
@@ -91,6 +91,36 @@ export const gitFields: INodeProperties[] = [
|
|
|
91
91
|
},
|
|
92
92
|
},
|
|
93
93
|
},
|
|
94
|
+
{
|
|
95
|
+
displayName: 'File Path',
|
|
96
|
+
name: 'pushFilePath',
|
|
97
|
+
type: 'string',
|
|
98
|
+
default: '',
|
|
99
|
+
required: true,
|
|
100
|
+
displayOptions: {
|
|
101
|
+
show: {
|
|
102
|
+
resource: ['git'],
|
|
103
|
+
operation: ['pushCommit'],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
description: 'Path of the file to create or update (e.g. /src/app.ts)',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
displayName: 'Change Type',
|
|
110
|
+
name: 'changeType',
|
|
111
|
+
type: 'options',
|
|
112
|
+
options: [
|
|
113
|
+
{ name: 'Edit (update existing file)', value: 'edit' },
|
|
114
|
+
{ name: 'Add (create new file)', value: 'add' },
|
|
115
|
+
],
|
|
116
|
+
default: 'edit',
|
|
117
|
+
displayOptions: {
|
|
118
|
+
show: {
|
|
119
|
+
resource: ['git'],
|
|
120
|
+
operation: ['pushCommit'],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
94
124
|
{
|
|
95
125
|
displayName: 'File Content',
|
|
96
126
|
name: 'fileContent',
|
package/package.json
CHANGED