@@ -3,6 +3,7 @@ name: night
33on :
44 schedule :
55 - cron : ' 0 0 * * *'
6+ workflow_dispatch :
67
78env :
89 MAIN_PYTHON_VERSION : ' 3.12'
@@ -103,4 +104,163 @@ jobs:
103104 repository-url : " https://test.pypi.org/legacy/"
104105 print-hash : true
105106 skip-existing : true
106- verbose : true
107+ verbose : true
108+
109+ check-dependabot-coverage :
110+ name : " Check dependabot coverage for third-party actions"
111+ runs-on : ubuntu-latest
112+ permissions :
113+ contents : write # Needed to create PR for when dependabot.yml gets updated
114+ pull-requests : write # Needed to create PR for when dependabot.yml gets updated
115+ steps :
116+ - name : " Checkout repository"
117+ uses : actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
118+ with :
119+ token : ${{ secrets.PYANSYS_CI_BOT_TOKEN }}
120+ fetch-depth : 0 # zizmor: ignore[artipacked] , credentials must be persisted in this case
121+
122+ - name : " Check third-party actions are in dependabot.yml"
123+ id : missing-actions-check
124+ shell : bash
125+ run : |
126+ echo "Checking third-party actions coverage in dependabot.yml"
127+ echo "========================================================"
128+ echo ""
129+
130+ # Get all third-party actions from workflows and composite actions
131+ ACTIONS=$(
132+ (find . -type f -name "action.yml" -not -path "./doc/*" && \
133+ find .github/workflows -type f \( -name "*.yml" -o -name "*.yaml" \) ! -name "dependabot_coverage.yml") | \
134+ xargs grep -h "uses:" | \
135+ sed 's/^[[:space:]]*//' | \
136+ sed 's/^-[[:space:]]*//' | \
137+ sed 's/^uses:[[:space:]]*//' | \
138+ sed 's/@.*//' | \
139+ grep '/' | \
140+ grep -v '\$' | \
141+ grep -v '^unpinned-uses' | \
142+ grep -v '^ansys/actions' | \
143+ sort -u | \
144+ grep -v "^\./"
145+ )
146+
147+ echo "Actions found in workflows/composite actions:"
148+ echo "----------------------------------------------"
149+ echo "$ACTIONS" | while read -r action; do
150+ echo "- $action"
151+ done
152+
153+ echo ""
154+ echo "Missing from dependabot.yml patterns:"
155+ echo "--------------------------------------"
156+
157+ # Check if "actions/*" pattern exists in dependabot.yml
158+ ACTIONS_WILDCARD_EXISTS=$(grep -q "actions/\*" .github/dependabot.yml && echo "true" || echo "false")
159+
160+ # Check each action against dependabot.yml and collect missing ones
161+ MISSING_ACTIONS=""
162+ while read -r action; do
163+ # If action starts with "actions/" and wildcard exists, skip it
164+ if [[ "$action" == actions/* ]] && [[ "$ACTIONS_WILDCARD_EXISTS" == "true" ]]; then
165+ continue
166+ fi
167+
168+ # Otherwise check if the exact action is in dependabot.yml
169+ if ! grep -q "$action" .github/dependabot.yml; then
170+ echo "- $action"
171+ MISSING_ACTIONS="${MISSING_ACTIONS}${action}\n"
172+ fi
173+ done < <(echo "$ACTIONS")
174+
175+ echo ""
176+ echo "========================================================"
177+
178+ # Count missing actions
179+ MISSING_COUNT=$(printf "$MISSING_ACTIONS" | wc -l)
180+
181+ echo "Total missing actions: $MISSING_COUNT"
182+
183+ # Fail if there are missing actions
184+ if [ "$MISSING_COUNT" -gt 0 ]; then
185+ echo ""
186+ echo "ERROR: Some third-party actions are not covered by dependabot.yml"
187+ echo "A pull request will be opened to add the missing actions to .github/dependabot.yml"
188+ echo "MISSING_ACTIONS_FOUND=true" >> ${GITHUB_OUTPUT}
189+ echo "MISSING_ACTIONS=${MISSING_ACTIONS}" >> ${GITHUB_OUTPUT}
190+ else
191+ echo ""
192+ echo "SUCCESS: All third-party actions are covered by dependabot.yml"
193+ echo "MISSING_ACTIONS_FOUND=false" >> ${GITHUB_OUTPUT}
194+ fi
195+
196+ - name : " Update dependabot.yml with missing actions"
197+ if : steps.missing-actions-check.outputs.MISSING_ACTIONS_FOUND == 'true'
198+ shell : bash
199+ env :
200+ MISSING_ACTIONS : ${{ steps.missing-actions-check.outputs.MISSING_ACTIONS }}
201+ run : |
202+ # Update dependabot.yml
203+ echo "Updating .github/dependabot.yml..."
204+
205+ TEMP_FILE=$(mktemp)
206+ awk -v missing="$MISSING_ACTIONS" '
207+ BEGIN {
208+ split(missing, actions, "\n");
209+ for (i in actions) {
210+ if (actions[i] != "") {
211+ # The indentation is 10 spaces, then "- "
212+ print " - " actions[i] "";
213+ }
214+ }
215+ }
216+ ' > "$TEMP_FILE"
217+
218+ # Insert the missing actions into dependabot.yml
219+ awk -v additions_file="$TEMP_FILE" '
220+ /must-be-assigned-actions:/ { in_section=1 }
221+ in_section && /patterns:/ {
222+ print;
223+ while ((getline line < additions_file) > 0) {
224+ print line;
225+ }
226+ next;
227+ }
228+ { print }
229+ ' .github/dependabot.yml > .github/dependabot.yml.tmp && mv .github/dependabot.yml.tmp .github/dependabot.yml
230+
231+ rm "$TEMP_FILE"
232+ echo "SUCCESS: .github/dependabot.yml updated."
233+ cat .github/dependabot.yml
234+
235+ - name : " Create PR into main with the dependabot.yml file changes"
236+ if : steps.missing-actions-check.outputs.MISSING_ACTIONS_FOUND == 'true'
237+ shell : bash
238+ env :
239+ BOT_USER : ${{ secrets.PYANSYS_CI_BOT_USERNAME }}
240+ BOT_EMAIL : ${{ secrets.PYANSYS_CI_BOT_EMAIL }}
241+ GITHUB_TOKEN : ${{ secrets.PYANSYS_CI_BOT_TOKEN }}
242+ run : |
243+ pr_title="ci: updating dependabot.yml with missing actions"
244+
245+ # Create and checkout PR branch
246+ git checkout -b "ci/dependabot-configuration-update"
247+
248+ # Configure git username & email
249+ git config user.name "${BOT_USER}"
250+ git config user.email "${BOT_EMAIL}"
251+
252+ # Add and commit changes
253+ git commit -am "${pr_title}"
254+
255+ # Push branch to remote
256+ git push -u origin "ci/dependabot-configuration-update"
257+
258+ body_msg="Update dependabot.yml with missing actions.
259+
260+ > [!NOTE]
261+ > Before merging this pull request, check if any of the added actions can be moved from "must-be-assigned-actions" group to a more specific group and make the necessary changes"
262+
263+ gh pr create --title "${pr_title}" --body "${body_msg}" --reviewer "ansys/pyansys-core"
264+
265+ # Exit with error
266+ exit 1
0 commit comments