blob: fb06ba82fd77a272efb88ec1ff70466811556205 (
plain) (
blame)
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
223
224
|
name: Manual Gate Control
on:
workflow_dispatch:
inputs:
action:
description: 'Action to perform'
required: true
default: 'open'
type: choice
options:
- open
- close
count_of_runners_to_change_label:
description: 'Optional: Number of runners to change (leave empty for all)'
required: false
type: string
jobs:
manage_gate:
runs-on: ubuntu-latest
name: Manual Gate Control
steps:
- name: Set Gate State
shell: bash
run: |
echo "Performing manual gate ${{ github.event.inputs.action }} operation"
# Set limit count if provided
LIMIT_COUNT="${{ github.event.inputs.count_of_runners_to_change_label }}"
if [[ -n "$LIMIT_COUNT" && "$LIMIT_COUNT" =~ ^[0-9]+$ ]]; then
echo "Will change labels for up to $LIMIT_COUNT runners"
LIMIT_OPTION=true
else
echo "Will change labels for all applicable runners"
LIMIT_OPTION=false
fi
if [[ "${{ github.event.inputs.action }}" == "close" ]]; then
echo "Closing gate for postcommits - removing postcommit labels"
query='.runners[] | select(.labels[].name=="ghrun") | select( any([.labels[].name][]; .=="postcommit")) | .id'
OPERATION="Closing"
LABEL_ACTION="Removing"
else
echo "Opening gate for postcommits - adding postcommit labels"
query='.runners[] | select(.labels[].name=="ghrun") | select( all([.labels[].name][]; .!="postcommit")) | .id'
OPERATION="Opening"
LABEL_ACTION="Adding"
fi
# Function to fetch a page of runners
fetch_runners_page() {
local page=$1
echo "Fetching runners page $page..."
local result=$(curl -Ls -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{secrets.GH_PERSONAL_ACCESS_TOKEN}}" \
-H "X-GitHub-Api-Version: 2022-11-28" -w "%{http_code}\n" \
"https://api.github.com/repos/${{github.repository}}/actions/runners?per_page=100&page=$page")
local http_code=$(echo "$result" | tail -n 1)
if [ "$http_code" != "200" ]; then
echo "HTTP error fetching page $page: $http_code"
echo "$result"
return 1
fi
# Remove status code from the end
echo "$result" | sed '$d'
}
# Get all runners with pagination
echo "Collecting all runners (paginated)..."
page=1
all_runner_ids=()
more_pages=true
while $more_pages; do
runners_data=$(fetch_runners_page $page)
if [ $? -ne 0 ]; then
echo "Failed to fetch runners page $page, exiting"
exit 1
fi
# Extract runner IDs for this page
readarray -t page_ids < <(echo "$runners_data" | jq -r "$query" | grep -v "^$")
# Check if we have runners on this page
count_on_page=${#page_ids[@]}
echo "Found $count_on_page eligible runners on page $page"
# Append to our array
all_runner_ids+=("${page_ids[@]}")
# Check if we have more pages
runners_count=$(echo "$runners_data" | jq '.runners | length')
if [ $runners_count -lt 100 ]; then
more_pages=false
else
page=$((page + 1))
fi
done
# Count total eligible runners
total_runners=${#all_runner_ids[@]}
echo "Total eligible runners found across all pages: $total_runners"
# Limit if needed
if [[ "$LIMIT_OPTION" == "true" && $total_runners -gt $LIMIT_COUNT ]]; then
all_runner_ids=("${all_runner_ids[@]:0:$LIMIT_COUNT}")
echo "Limited to first $LIMIT_COUNT runners"
fi
# Files to store results and details
success_file=$(mktemp)
failed_file=$(mktemp)
details_file=$(mktemp)
# Process runners
changed_count=0
for runner_id in "${all_runner_ids[@]}"; do
changed_count=$((changed_count + 1))
echo "Processing runner $changed_count/${#all_runner_ids[@]}: ID $runner_id"
if [[ "${{ github.event.inputs.action }}" == "close" ]]; then
echo "Removing postcommit label from runner $runner_id"
response=$(curl -s -w "\n%{http_code}" -X DELETE -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{secrets.GH_PERSONAL_ACCESS_TOKEN}}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{github.repository}}/actions/runners/$runner_id/labels/postcommit")
else
echo "Adding postcommit label to runner $runner_id"
response=$(curl -s -w "\n%{http_code}" -X POST -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{secrets.GH_PERSONAL_ACCESS_TOKEN}}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{github.repository}}/actions/runners/$runner_id/labels" \
-d '{"labels":["postcommit"]}')
fi
# Parse response
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')
# Get runner name for better reporting
runner_name=$(curl -s -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{secrets.GH_PERSONAL_ACCESS_TOKEN}}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{github.repository}}/actions/runners/$runner_id" | \
jq -r '.name // "Unknown"')
# Check success (HTTP 2xx)
if [[ $http_code -ge 200 && $http_code -lt 300 ]]; then
echo "1" >> "$success_file"
status_icon="✅"
status_text="Success"
echo "$status_icon Success: Label ${{ github.event.inputs.action == 'close' && 'removed' || 'added' }} for runner $runner_name (ID: $runner_id)"
else
echo "1" >> "$failed_file"
status_icon="❌"
status_text="Failed"
echo "$status_icon Failed: HTTP $http_code for runner $runner_name (ID: $runner_id)"
echo "Error response: $body"
fi
# Add to details for summary
echo "| $runner_name | $runner_id | $status_text | $http_code |" >> "$details_file"
done
# Calculate success/failure counts
success_count=$(wc -l < "$success_file")
failed_count=$(wc -l < "$failed_file")
# Create summary for GitHub Actions
echo "## Gate Control Operation Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Action:** $OPERATION gate ($LABEL_ACTION 'postcommit' label)" >> $GITHUB_STEP_SUMMARY
echo "**Repository:** \`${{github.repository}}\`" >> $GITHUB_STEP_SUMMARY
echo "**Timestamp:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Metric | Count |" >> $GITHUB_STEP_SUMMARY
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Total eligible runners | $total_runners |" >> $GITHUB_STEP_SUMMARY
if [[ "$LIMIT_OPTION" == "true" ]]; then
echo "| Limit applied | $LIMIT_COUNT |" >> $GITHUB_STEP_SUMMARY
fi
echo "| Runners processed | $changed_count |" >> $GITHUB_STEP_SUMMARY
echo "| ✅ Successful operations | $success_count |" >> $GITHUB_STEP_SUMMARY
echo "| ❌ Failed operations | $failed_count |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ $changed_count -gt 0 ]]; then
echo "### Operation Details" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Runner Name | ID | Status | HTTP Code |" >> $GITHUB_STEP_SUMMARY
echo "|-------------|----|---------|----|" >> $GITHUB_STEP_SUMMARY
cat "$details_file" >> $GITHUB_STEP_SUMMARY
else
echo "### No runners were processed" >> $GITHUB_STEP_SUMMARY
fi
# Console summary
echo ""
echo "=== OPERATION SUMMARY ==="
echo "Action: ${{ github.event.inputs.action }} gate"
echo "Total eligible runners: $total_runners"
if [[ "$LIMIT_OPTION" == "true" ]]; then
echo "Limited to: $LIMIT_COUNT"
fi
echo "Runners processed: $changed_count"
echo "Successful operations: $success_count"
echo "Failed operations: $failed_count"
echo "========================="
# Cleanup temp files
rm -f "$success_file" "$failed_file" "$details_file"
# Set exit code based on success
if [[ $failed_count -gt 0 ]]; then
echo "Warning: Some operations failed"
echo "::warning::$failed_count operations failed. See summary for details."
exit 1
fi
echo "Gate ${{ github.event.inputs.action }} operation completed successfully"
|