Skip to content

Commit ef855b1

Browse files
authored
Update GitHub Actions workflow for version checks (#32)
Updated permissions for GitHub Actions workflow and added functionality to apply action updates, configure SSH signing, and create a branch for commits. Enhanced issue and PR management based on action updates. Signed-off-by: nerdalytics <97166791+nerdalytics@users.noreply.github.com>
1 parent 74441d8 commit ef855b1

1 file changed

Lines changed: 142 additions & 3 deletions

File tree

.github/workflows/check-action-versions.yml

Lines changed: 142 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
name: Check Action Versions
22
permissions:
3-
contents: read
3+
contents: write
44
issues: write
5+
pull-requests: write
56

67
on:
78
schedule:
@@ -13,6 +14,8 @@ jobs:
1314
runs-on: ubuntu-latest
1415
steps:
1516
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
17+
with:
18+
token: ${{ secrets.ACTION_UPDATER_PAT }}
1619

1720
- name: Check for outdated actions
1821
id: check
@@ -150,6 +153,11 @@ jobs:
150153
151154
echo "Report generated:"
152155
cat outdated-actions-report.md
156+
157+
# Export action data for file modification step
158+
for action in "${!ACTIONS_SHA[@]}"; do
159+
echo "${action}|${ACTIONS_CURRENT[$action]}|${ACTIONS_LATEST[$action]}|${ACTIONS_SHA[$action]}"
160+
done > outdated-actions-data.txt
153161
else
154162
echo "All actions are up to date!"
155163
fi
@@ -179,18 +187,149 @@ jobs:
179187
echo "Created new issue"
180188
fi
181189
182-
- name: Close issue if all actions up to date
190+
- name: Apply action updates
191+
if: steps.check.outputs.has_outdated == 'true'
192+
id: apply
193+
run: |
194+
set -euo pipefail
195+
196+
CHANGES_MADE=0
197+
198+
while IFS='|' read -r action current latest sha; do
199+
echo "Updating $action: $current -> $sha # $latest"
200+
201+
for workflow in .github/workflows/*.yml; do
202+
# Escape special characters for sed
203+
action_escaped=$(echo "$action" | sed 's/[\/&]/\\&/g')
204+
sha_escaped=$(echo "$sha" | sed 's/[\/&]/\\&/g')
205+
latest_escaped=$(echo "$latest" | sed 's/[\/&]/\\&/g')
206+
207+
# Replace: uses: owner/repo@anything -> uses: owner/repo@sha # version
208+
if grep -q "uses:[[:space:]]*${action}@" "$workflow"; then
209+
sed -i "s|\(uses:[[:space:]]*${action_escaped}@\)[^[:space:]#]*\(.*\)|\1${sha_escaped} # ${latest_escaped}|" "$workflow"
210+
CHANGES_MADE=1
211+
fi
212+
done
213+
done < outdated-actions-data.txt
214+
215+
echo "changes_made=$CHANGES_MADE" >> "$GITHUB_OUTPUT"
216+
217+
- name: Configure SSH signing
218+
if: steps.apply.outputs.changes_made == '1'
219+
env:
220+
SSH_SIGNING_KEY: ${{ secrets.SSH_SIGNING_KEY }}
221+
SSH_PASSPHRASE: ${{ secrets.SSH_SIGNING_KEY_PASSPHRASE }}
222+
run: |
223+
mkdir -p ~/.ssh
224+
printf '%s\n' "$SSH_SIGNING_KEY" > ~/.ssh/signing_key
225+
chmod 600 ~/.ssh/signing_key
226+
ssh-keygen -p -P "$SSH_PASSPHRASE" -N "" -f ~/.ssh/signing_key
227+
git config user.name "nerdalytics"
228+
git config user.email "97166791+nerdalytics@users.noreply.github.com"
229+
git config gpg.format ssh
230+
git config user.signingkey ~/.ssh/signing_key
231+
git config commit.gpgsign true
232+
233+
- name: Create branch and commit
234+
if: steps.apply.outputs.changes_made == '1'
235+
id: commit
236+
run: |
237+
set -euo pipefail
238+
239+
BRANCH_NAME="automation/update-github-actions"
240+
241+
git checkout -B "$BRANCH_NAME"
242+
git add .github/workflows/*.yml
243+
244+
if git diff --cached --quiet; then
245+
echo "No changes to commit"
246+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
247+
exit 0
248+
fi
249+
250+
OUTDATED_COUNT=$(wc -l < outdated-actions-data.txt)
251+
git commit -m "chore(deps): update $OUTDATED_COUNT GitHub Action(s) to latest versions
252+
253+
Updates actions to SHA-pinned versions for security.
254+
See workflow file changes for details."
255+
256+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
257+
echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT"
258+
259+
- name: Push and create PR
260+
if: steps.commit.outputs.has_changes == 'true'
261+
env:
262+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
263+
GH_REPO: ${{ github.repository }}
264+
run: |
265+
set -euo pipefail
266+
267+
BRANCH_NAME="${{ steps.commit.outputs.branch_name }}"
268+
ISSUE_TITLE="Security: Outdated GitHub Actions detected"
269+
PR_TITLE="chore(deps): Update GitHub Actions to latest versions"
270+
271+
# Find issue number for linking
272+
ISSUE_NUMBER=$(gh issue list --state open --search "in:title $ISSUE_TITLE" --json number --jq '.[0].number' 2>/dev/null || echo "")
273+
274+
# Generate PR body
275+
PR_BODY="## Summary
276+
277+
Automatically updates GitHub Actions to their latest SHA-pinned versions.
278+
279+
$(cat outdated-actions-report.md)
280+
281+
---
282+
${ISSUE_NUMBER:+Fixes #$ISSUE_NUMBER}
283+
284+
*This PR was automatically generated by the [Check Action Versions](.github/workflows/check-action-versions.yml) workflow.*"
285+
286+
# Close existing PR and delete branch if they exist (avoids force-push)
287+
EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number' 2>/dev/null || echo "")
288+
if [[ -n "$EXISTING_PR" ]]; then
289+
echo "Closing existing PR #$EXISTING_PR to replace with updated version"
290+
gh pr close "$EXISTING_PR" --comment "Superseded by a new PR with updated changes." --delete-branch || true
291+
fi
292+
293+
# Delete remote branch if it still exists (e.g., PR was already closed/merged)
294+
if git ls-remote --exit-code --heads origin "$BRANCH_NAME" > /dev/null 2>&1; then
295+
echo "Deleting existing remote branch"
296+
git push origin --delete "$BRANCH_NAME" || true
297+
fi
298+
299+
# Push branch and create new PR
300+
git push -u origin "$BRANCH_NAME"
301+
302+
echo "Creating new PR"
303+
gh pr create \
304+
--title "$PR_TITLE" \
305+
--body "$PR_BODY" \
306+
--label "security,dependencies" \
307+
--base main \
308+
--head "$BRANCH_NAME"
309+
310+
- name: Close issue and PR if all actions up to date
183311
if: steps.check.outputs.has_outdated == 'false'
184312
env:
185313
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
186314
GH_REPO: ${{ github.repository }}
187315
run: |
188316
ISSUE_TITLE="Security: Outdated GitHub Actions detected"
189-
EXISTING_ISSUE=$(gh issue list --state open --search "in:title $ISSUE_TITLE" --json number --jq '.[0].number' 2>/dev/null || echo "")
317+
BRANCH_NAME="automation/update-github-actions"
190318
319+
# Close existing issue
320+
EXISTING_ISSUE=$(gh issue list --state open --search "in:title $ISSUE_TITLE" --json number --jq '.[0].number' 2>/dev/null || echo "")
191321
if [[ -n "$EXISTING_ISSUE" ]]; then
192322
gh issue close "$EXISTING_ISSUE" --comment "All GitHub Actions are now up to date."
193323
echo "Closed issue #$EXISTING_ISSUE"
194324
else
195325
echo "No existing issue to close"
196326
fi
327+
328+
# Close existing PR
329+
EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number' 2>/dev/null || echo "")
330+
if [[ -n "$EXISTING_PR" ]]; then
331+
gh pr close "$EXISTING_PR" --comment "All GitHub Actions are now up to date. Closing this automated PR."
332+
echo "Closed PR #$EXISTING_PR"
333+
else
334+
echo "No existing PR to close"
335+
fi

0 commit comments

Comments
 (0)