Workflow drift detection #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Workflow drift detection | |
| on: | |
| schedule: | |
| - cron: '0 8 * * 1' # every Monday 08:00 UTC | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| issues: write | |
| jobs: | |
| drift: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check for unsigned workflow commits since last week | |
| id: check | |
| run: | | |
| set -euo pipefail | |
| SINCE=$(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-7d +%Y-%m-%dT%H:%M:%SZ) | |
| ISSUES="" | |
| while IFS= read -r sha; do | |
| [ -z "$sha" ] && continue | |
| VERIFIED=$(git verify-commit "$sha" 2>/dev/null && echo "yes" || echo "no") | |
| AUTHOR_EMAIL=$(git log -1 --format='%ae' "$sha") | |
| FILES=$(git diff-tree --no-commit-id -r --name-only "$sha" | grep '^\.github/' || true) | |
| if [ -n "$FILES" ] && [ "$VERIFIED" = "no" ]; then | |
| SHORT="${sha:0:7}" | |
| FILES_ONELINE=$(echo "$FILES" | tr '\n' ',' | sed 's/,$//') | |
| ISSUES="${ISSUES}- ${SHORT} (${AUTHOR_EMAIL}): unsigned commit touched ${FILES_ONELINE}"$'\n' | |
| fi | |
| done < <(git log --format='%H' --since="$SINCE" -- .github/) | |
| if [ -n "$ISSUES" ]; then | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| { | |
| echo "details<<DRIFT_EOF" | |
| echo "$ISSUES" | |
| echo "DRIFT_EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| else | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Open issue if drift detected | |
| if: steps.check.outputs.found == 'true' | |
| uses: actions/github-script@v7 | |
| env: | |
| DRIFT_DETAILS: ${{ steps.check.outputs.details }} | |
| with: | |
| script: | | |
| const details = process.env.DRIFT_DETAILS || '(no details available)'; | |
| const body = [ | |
| '## Workflow drift alert', | |
| '', | |
| 'The scheduled drift-detection scan found unsigned commits modifying `.github/` in the past 7 days:', | |
| '', | |
| '```', | |
| details.trim(), | |
| '```', | |
| '', | |
| 'Please review these commits immediately and verify they are legitimate.', | |
| '', | |
| '_This issue was opened automatically by the drift-detection workflow._' | |
| ].join('\n'); | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: 'Workflow drift detected \u2014 unsigned commits touched .github/', | |
| body: body, | |
| labels: ['security'] | |
| }); |