-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathazure-pipelines.yml
More file actions
223 lines (182 loc) · 8.15 KB
/
Copy pathazure-pipelines.yml
File metadata and controls
223 lines (182 loc) · 8.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
trigger: none
pr:
branches:
include:
- main
- develop
- feature/*
pool:
vmImage: ubuntu-latest
variables:
- group: "GitHub Copilot CLI"
- name: MODEL
value: claude-opus-4.5
- name: COPILOT_VERSION
value: "latest"
- name: ANALYSIS_DIR
value: "$(Build.ArtifactStagingDirectory)/pr-analysis"
- name: DIFF_FILE
value: "$(Build.ArtifactStagingDirectory)/pr-diff.json"
steps:
- bash: |
echo "🔍 Validating PR context..."
if [ -z "$(System.PullRequest.PullRequestId)" ]; then
echo "##vso[task.logissue type=error]This pipeline must run in a Pull Request context."
echo "❌ Error: No Pull Request ID found."
echo " This pipeline is designed to run only on PR triggers."
exit 1
fi
if [ -z "$(System.PullRequest.SourceBranch)" ] || [ -z "$(System.PullRequest.TargetBranch)" ]; then
echo "##vso[task.logissue type=error]Missing source or target branch information."
echo "❌ Error: Branch information is incomplete."
exit 1
fi
echo "✅ PR context validated successfully"
echo " PR #$(System.PullRequest.PullRequestId): $(System.PullRequest.SourceBranch) → $(System.PullRequest.TargetBranch)"
displayName: ✅ Validate PR Context
- bash: |
echo "📋 Pull Request Information:"
echo " - Repository URI: $(System.PullRequest.SourceRepositoryUri)"
echo " - PR #: $(System.PullRequest.PullRequestId)"
echo " - Source Branch: $(System.PullRequest.SourceBranch)"
echo " - Target Branch: $(System.PullRequest.TargetBranch)"
echo " - Source Commit: $(System.PullRequest.SourceCommitId)"
echo " - Build Repository: $(Build.Repository.Uri)"
echo " - Build Commit: $(Build.SourceVersion)"
echo ""
echo "📁 Working directories:"
echo " - Analysis Dir: $(ANALYSIS_DIR)"
echo " - Diff File: $(DIFF_FILE)"
echo " - Comment File: $(COMMENT_FILE)"
displayName: 📋 Show PR Information
- task: NodeTool@0
inputs:
versionSource: "spec"
versionSpec: "22.x"
displayName: ⚙️ Setup Node.js 22.x
- bash: |
NPM_PREFIX=$(npm config get prefix)
echo "##vso[task.setvariable variable=NPM_GLOBAL_PATH]${NPM_PREFIX}/lib/node_modules"
echo "NPM global path: ${NPM_PREFIX}/lib/node_modules"
displayName: 🔍 Detect NPM Global Path
- task: Cache@2
inputs:
key: 'npm-global | "$(Agent.OS)" | "copilot" | "$(COPILOT_VERSION)"'
path: $(NPM_GLOBAL_PATH)
restoreKeys: |
npm-global | "$(Agent.OS)" | "copilot"
displayName: 📦 Cache Global NPM Packages
- bash: |
if ! command -v copilot &> /dev/null; then
echo "Installing @github/copilot@$(COPILOT_VERSION)..."
npm install -g @github/copilot@$(COPILOT_VERSION)
else
echo "✅ @github/copilot already installed (from cache)"
copilot --version
fi
displayName: 🐙 Install Copilot CLI
- template: templates/run-script.yml
parameters:
script: install-copilot-agents.sh
args: '"$(System.DefaultWorkingDirectory)"'
displayName: 🤖 Install Custom Agents
- template: templates/run-script.yml
parameters:
script: get-pr-diff.sh
args: '"$(System.PullRequest.SourceRepositoryUri)" "$(System.PullRequest.SourceBranch)" "$(System.PullRequest.TargetBranch)" "$(AZURE_DEVOPS_EXT_PAT)" "$(DIFF_FILE)"'
displayName: 🔍 Get PR Differences
- template: templates/run-script.yml
parameters:
script: download-pr-files.sh
args: '"$(DIFF_FILE)" "$(System.PullRequest.SourceRepositoryUri)" "$(System.PullRequest.SourceBranch)" "$(System.PullRequest.TargetBranch)" "$(AZURE_DEVOPS_EXT_PAT)" "$(ANALYSIS_DIR)"'
displayName: 📁 Download Modified Files
- template: templates/run-script.yml
parameters:
script: analyze-with-copilot.sh
args: '"$(ANALYSIS_DIR)/source"'
displayName: 🤖 Analyze with GitHub Copilot CLI
workingDirectory: $(System.DefaultWorkingDirectory)
- bash: |
# Extract repository information
REPO_URI="$(System.PullRequest.SourceRepositoryUri)"
ORG=$(echo "$REPO_URI" | sed 's|https://[^@]*@||' | awk -F'/' '{print $2}')
PROJECT=$(echo "$REPO_URI" | sed 's|https://[^@]*@||' | awk -F'/' '{print $3}' | sed 's/%20/ /g' | sed 's/ /%20/g')
REPO=$(echo "$REPO_URI" | sed 's|https://[^@]*@||' | awk -F'/' '{print $5}')
PR_ID="$(System.PullRequest.PullRequestId)"
echo "🔍 Repository information:"
echo " - Organization: $ORG"
echo " - Project: $PROJECT"
echo " - Repository: $REPO"
echo " - PR ID: $PR_ID"
echo "##vso[task.setvariable variable=PR_ORG]$ORG"
echo "##vso[task.setvariable variable=PR_PROJECT]$PROJECT"
echo "##vso[task.setvariable variable=PR_REPO]$REPO"
echo "##vso[task.setvariable variable=PR_NUM]$PR_ID"
displayName: 📋 Extract PR Info
- template: templates/run-script.yml
parameters:
script: post-pr-comment.sh
args: '"$(ANALYSIS_DIR)/source/pr-comments" "$(PR_ORG)" "$(PR_PROJECT)" "$(PR_REPO)" "$(PR_NUM)" "$(AZURE_DEVOPS_EXT_PAT)"'
displayName: 💬 Publish Comment on PR
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: "$(Build.ArtifactStagingDirectory)"
ArtifactName: "pr-analysis-complete"
publishLocation: "Container"
displayName: 📦 Publish Complete Analysis as Artifact
- bash: |
echo "🔴 Pipeline failed! Analyzing the error with GitHub Copilot CLI..."
echo ""
# Get the agent diagnostic logs directory
DIAG_DIR="$(Agent.WorkFolder)/_diag"
# Find the most recent worker log (contains task execution details)
WORKER_LOG=$(ls -t "$DIAG_DIR"/Worker_*.log 2>/dev/null | head -1)
# Extract error messages from the logs
ERROR_LOG="/tmp/pipeline_errors.txt"
echo "📋 Extracting error information from pipeline logs..."
if [ -f "$WORKER_LOG" ]; then
# Extract lines containing errors, warnings, and failed tasks (last 200 lines for context)
tail -200 "$WORKER_LOG" | grep -iE "(error|failed|exception|fatal|##vso\[task\.logissue|##vso\[task\.complete result=Failed)" > "$ERROR_LOG" 2>/dev/null || true
fi
# Also check for any .log files in the current build directory
BUILD_LOGS_DIR="$(Agent.WorkFolder)/_temp"
if [ -d "$BUILD_LOGS_DIR" ]; then
find "$BUILD_LOGS_DIR" -name "*.log" -type f -exec tail -50 {} \; 2>/dev/null | grep -iE "(error|failed|exception)" >> "$ERROR_LOG" 2>/dev/null || true
fi
# Add any stderr output that might have been captured
if [ -f "$(Agent.TempDirectory)/stderr.txt" ]; then
cat "$(Agent.TempDirectory)/stderr.txt" >> "$ERROR_LOG" 2>/dev/null || true
fi
# Build the error context for Copilot
if [ -s "$ERROR_LOG" ]; then
ERROR_CONTENT=$(cat "$ERROR_LOG" | head -100)
else
ERROR_CONTENT="No specific error logs found. The pipeline failed but detailed error messages could not be extracted from the agent logs."
fi
echo "📝 Error content extracted:"
echo "---"
echo "$ERROR_CONTENT"
echo "---"
echo ""
echo "🤖 Asking GitHub Copilot to analyze the failure..."
echo ""
# Use Copilot CLI to analyze the actual error
copilot -p "Eres un experto en DevOps analizando un fallo de pipeline de Azure DevOps.
## Información del Pipeline
- Pipeline: $(Build.DefinitionName)
- Build ID: $(Build.BuildId)
- Repository: $(Build.Repository.Name)
- Branch: $(Build.SourceBranch)
## Mensajes de Error del Pipeline
$ERROR_CONTENT
## Tu tarea
1. Analiza el error y explica qué ha fallado exactamente
2. Identifica la causa raíz más probable
3. Proporciona una solución concreta y pasos para solucionarlo
4. Si es relevante, sugiere cómo prevenir este error en el futuro
Responde de forma clara y concisa."
displayName: 🔴 Analyze Pipeline Failure with Copilot
condition: failed()
env:
GITHUB_TOKEN: $(GITHUB_TOKEN)
XDG_CONFIG_HOME: $(XDG_CONFIG_HOME)