Skip to content

Commit 8c162de

Browse files
committed
ci: fix pull_request_target, add schedule dependabotbot PR (#2688)
* ci: change pull_request_target to pull_request, don't sync images from fork * ci: move adding PRs from dependabot to scheduled job * fix: cr apply suggested changes (cherry picked from commit 1a4b7e3)
1 parent a053222 commit 8c162de

3 files changed

Lines changed: 272 additions & 116 deletions

File tree

.github/workflows/post-sync-external-images.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,6 @@ on:
55
- main
66
paths:
77
- "external-images.yaml"
8-
pull_request_target:
9-
types: [ opened, edited, synchronize, reopened, ready_for_review ]
10-
branches:
11-
- main
12-
paths:
13-
- "external-images.yaml"
14-
158
permissions:
169
id-token: write # This is required for requesting the JWT token
1710
contents: read # This is required for actions/checkout

.github/workflows/pull-add-bot-prs-to-project.yaml

Lines changed: 0 additions & 109 deletions
This file was deleted.
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
name: Scheduled add Bot PRs to GitHub Project
2+
3+
# Runs to add dependabot PRs to GitHub Project
4+
# This avoids security issues with pull_request_target trigger
5+
6+
permissions:
7+
contents: read
8+
pull-requests: read
9+
10+
on:
11+
schedule:
12+
# run each day
13+
- cron: '0 7 * * *'
14+
workflow_dispatch: # Allow manual trigger
15+
16+
jobs:
17+
add-bot-prs:
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Get project data
22+
id: project_data
23+
env:
24+
GH_TOKEN: ${{ secrets.PROJECT_ACCESS_CLASSIC }}
25+
ORGANIZATION: kyma-project
26+
PROJECT_NUMBER: ${{vars.PROJECT_ID}}
27+
run: |
28+
if ! gh api graphql -f query='
29+
query($org: String!, $number: Int!) {
30+
organization(login: $org){
31+
projectV2(number: $number) {
32+
id
33+
fields(first:20) {
34+
nodes {
35+
... on ProjectV2Field {
36+
id
37+
name
38+
}
39+
... on ProjectV2SingleSelectField {
40+
id
41+
name
42+
options {
43+
id
44+
name
45+
}
46+
}
47+
}
48+
}
49+
}
50+
}
51+
}' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json; then
52+
echo "ERROR: Failed to fetch project data"
53+
exit 1
54+
fi
55+
56+
if ! jq -e '.data.organization.projectV2.id' project_data.json > /dev/null; then
57+
echo "ERROR: Invalid project data received"
58+
cat project_data.json
59+
exit 1
60+
fi
61+
62+
echo 'PROJECT_ID='$(jq -r '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
63+
64+
echo 'READY_ID='$(jq -r '.data.organization.projectV2.fields.nodes[] | select(.name== "Ready") | .id' project_data.json) >> $GITHUB_ENV
65+
echo 'SPRINT_OPTION_ID='$(jq -r '.data.organization.projectV2.fields.nodes[] | select(.name== "Ready") | .options[] | select(.name=="Sprint") |.id' project_data.json) >> $GITHUB_ENV
66+
67+
echo 'STATUS_ID='$(jq -r '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
68+
echo 'REVIEW_OPTION_ID='$(jq -r '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="Review") |.id' project_data.json) >> $GITHUB_ENV
69+
70+
- name: Get existing project items
71+
env:
72+
GH_TOKEN: ${{ secrets.PROJECT_ACCESS_CLASSIC }}
73+
run: |
74+
# Get all items currently in the project (simplified - no pagination for first iteration)
75+
gh api graphql -f query='
76+
query($project: ID!) {
77+
node(id: $project) {
78+
... on ProjectV2 {
79+
items(first: 100) {
80+
nodes {
81+
content {
82+
... on PullRequest {
83+
id
84+
number
85+
}
86+
}
87+
}
88+
}
89+
}
90+
}
91+
}' -f project=$PROJECT_ID | \
92+
jq -r '.data.node.items.nodes[].content.id // empty' | \
93+
sort -u > existing_pr_ids.txt
94+
95+
echo "Found $(wc -l < existing_pr_ids.txt | tr -d ' ') PRs already in project"
96+
97+
- name: Find open bot PRs
98+
env:
99+
GH_TOKEN: ${{ secrets.PROJECT_ACCESS_CLASSIC }}
100+
REPO: ${{ github.repository }}
101+
run: |
102+
# Get dependabot PRs
103+
echo "Fetching dependabot PRs..."
104+
gh pr list \
105+
--repo "$REPO" \
106+
--state open \
107+
--author "app/dependabot" \
108+
--limit 100 \
109+
--json id,number,title,author,url > dependabot_prs.json || echo "[]" > dependabot_prs.json
110+
111+
# Get kyma-goat-bot PRs
112+
echo "Fetching kyma-goat-bot PRs..."
113+
gh pr list \
114+
--repo "$REPO" \
115+
--state open \
116+
--author "kyma-goat-bot" \
117+
--limit 100 \
118+
--json id,number,title,author,url > bot_prs.json || echo "[]" > bot_prs.json
119+
120+
# Combine and deduplicate
121+
jq -s 'add | unique_by(.id)' dependabot_prs.json bot_prs.json > all_bot_prs.json
122+
123+
total_prs=$(jq 'length' all_bot_prs.json)
124+
echo "Found $total_prs bot PRs"
125+
126+
if [ "$total_prs" -eq 0 ]; then
127+
echo "No bot PRs found"
128+
fi
129+
130+
- name: Add PRs to project
131+
id: add_prs
132+
env:
133+
GH_TOKEN: ${{ secrets.PROJECT_ACCESS_CLASSIC }}
134+
run: |
135+
# Read existing PR IDs
136+
if [ -f existing_pr_ids.txt ]; then
137+
existing_ids=$(cat existing_pr_ids.txt | tr '\n' '|')
138+
else
139+
existing_ids=""
140+
fi
141+
142+
added_count=0
143+
skipped_count=0
144+
failed_count=0
145+
146+
# Process each bot PR - use process substitution to avoid subshell
147+
while read pr; do
148+
PR_ID=$(echo "$pr" | jq -r '.id')
149+
PR_NUMBER=$(echo "$pr" | jq -r '.number')
150+
PR_TITLE=$(echo "$pr" | jq -r '.title')
151+
PR_URL=$(echo "$pr" | jq -r '.url')
152+
153+
# Check if PR is already in project
154+
if echo "$existing_ids" | grep -qF "$PR_ID"; then
155+
echo "SKIP: PR #$PR_NUMBER already in project"
156+
skipped_count=$((skipped_count + 1))
157+
continue
158+
fi
159+
160+
echo "ADD: PR #$PR_NUMBER to project: $PR_TITLE"
161+
162+
# Add PR to project
163+
if ! add_result=$(gh api graphql -f query='
164+
mutation($project:ID!, $pr:ID!) {
165+
addProjectV2ItemById(input: {projectId: $project, contentId: $pr}) {
166+
item {
167+
id
168+
}
169+
}
170+
}' -f project=$PROJECT_ID -f pr=$PR_ID 2>&1); then
171+
echo "FAILED: Could not add PR #$PR_NUMBER: $add_result"
172+
failed_count=$((failed_count + 1))
173+
continue
174+
fi
175+
176+
item_id=$(echo "$add_result" | jq -r '.data.addProjectV2ItemById.item.id')
177+
178+
if [ "$item_id" = "null" ] || [ -z "$item_id" ]; then
179+
echo "FAILED: Could not get item ID for PR #$PR_NUMBER"
180+
failed_count=$((failed_count + 1))
181+
continue
182+
fi
183+
184+
echo "SUCCESS: Added with item ID: $item_id"
185+
186+
# Set fields (Status: Review, Ready: Sprint)
187+
if ! gh api graphql -f query='
188+
mutation (
189+
$project: ID!
190+
$item: ID!
191+
$status_field: ID!
192+
$status_value: String!
193+
$ready_field: ID!
194+
$ready_value: String!
195+
) {
196+
set_status: updateProjectV2ItemFieldValue(input: {
197+
projectId: $project
198+
itemId: $item
199+
fieldId: $status_field
200+
value: {
201+
singleSelectOptionId: $status_value
202+
}
203+
}) {
204+
projectV2Item {
205+
id
206+
}
207+
}
208+
set_ready: updateProjectV2ItemFieldValue(input: {
209+
projectId: $project
210+
itemId: $item
211+
fieldId: $ready_field
212+
value: {
213+
singleSelectOptionId: $ready_value
214+
}
215+
}) {
216+
projectV2Item {
217+
id
218+
}
219+
}
220+
}' -f project=$PROJECT_ID \
221+
-f item=$item_id \
222+
-f status_field=$STATUS_ID \
223+
-f status_value=$REVIEW_OPTION_ID \
224+
-f ready_field=$READY_ID \
225+
-f ready_value=$SPRINT_OPTION_ID 2>&1; then
226+
echo "WARNING: Failed to set fields for PR #$PR_NUMBER"
227+
else
228+
echo "SUCCESS: Fields set - Status=Review, Ready=Sprint"
229+
fi
230+
231+
added_count=$((added_count + 1))
232+
echo "---"
233+
done < <(jq -c '.[]' all_bot_prs.json)
234+
235+
# Summary
236+
echo ""
237+
echo "Summary:"
238+
echo " Added: $added_count"
239+
echo " Skipped (already in project): $skipped_count"
240+
echo " Failed: $failed_count"
241+
242+
# Set outputs for job summary
243+
echo "added=$added_count" >> $GITHUB_OUTPUT
244+
echo "skipped=$skipped_count" >> $GITHUB_OUTPUT
245+
echo "failed=$failed_count" >> $GITHUB_OUTPUT
246+
247+
- name: Create job summary
248+
if: always()
249+
run: |
250+
echo "## Bot PRs Added to Project" >> $GITHUB_STEP_SUMMARY
251+
echo "" >> $GITHUB_STEP_SUMMARY
252+
echo "**Run time:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
253+
echo "" >> $GITHUB_STEP_SUMMARY
254+
255+
total_prs=$(jq 'length' all_bot_prs.json 2>/dev/null || echo "0")
256+
echo "**Total bot PRs found:** $total_prs" >> $GITHUB_STEP_SUMMARY
257+
echo "" >> $GITHUB_STEP_SUMMARY
258+
259+
# Show summary counts
260+
echo "### Results:" >> $GITHUB_STEP_SUMMARY
261+
echo "- **Added:** ${{ steps.add_prs.outputs.added }}" >> $GITHUB_STEP_SUMMARY
262+
echo "- **Skipped:** ${{ steps.add_prs.outputs.skipped }}" >> $GITHUB_STEP_SUMMARY
263+
echo "- **Failed:** ${{ steps.add_prs.outputs.failed }}" >> $GITHUB_STEP_SUMMARY
264+
echo "" >> $GITHUB_STEP_SUMMARY
265+
266+
# List the PRs that were processed
267+
if [ "$total_prs" -gt 0 ]; then
268+
echo "### PRs Processed:" >> $GITHUB_STEP_SUMMARY
269+
jq -r '.[] | "- [#\(.number)](\(.url)) - \(.title)"' all_bot_prs.json >> $GITHUB_STEP_SUMMARY
270+
else
271+
echo "_No bot PRs found_" >> $GITHUB_STEP_SUMMARY
272+
fi

0 commit comments

Comments
 (0)