diff --git a/.github/workflows/auto-merge-windows-version-definitions.yml b/.github/workflows/auto-merge-windows-version-definitions.yml new file mode 100644 index 0000000..dbd7530 --- /dev/null +++ b/.github/workflows/auto-merge-windows-version-definitions.yml @@ -0,0 +1,70 @@ +name: Auto-merge Windows Version Definition Updates + +on: + workflow_run: + workflows: ["PR-tests"] + types: [completed] + +permissions: + contents: write + pull-requests: write + +jobs: + auto-merge: + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + steps: + - name: Resolve matching pull request + id: pr + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }} + HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} + EXPECTED_TITLE: "chore(winpeas): update windows version vulnerability definitions" + run: | + pr_number="$PR_NUMBER" + if [ -z "$pr_number" ] && [ -n "$HEAD_BRANCH" ]; then + pr_number="$(gh pr list --state open --head "$HEAD_BRANCH" --json number --jq '.[0].number')" + fi + if [ -z "$pr_number" ]; then + echo "No pull request found for this workflow_run; skipping." + echo "should_merge=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + title="$(gh pr view "$pr_number" --json title --jq .title)" + base_ref="$(gh pr view "$pr_number" --json baseRefName --jq .baseRefName)" + head_ref="$(gh pr view "$pr_number" --json headRefName --jq .headRefName)" + author="$(gh pr view "$pr_number" --json author --jq .author.login)" + + if [ "$title" != "$EXPECTED_TITLE" ]; then + echo "PR #$pr_number title does not match; skipping." + echo "should_merge=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + if [ "$base_ref" != "master" ] || [ "$head_ref" != "bot/update-windows-version-definitions" ]; then + echo "PR #$pr_number is not the expected branch pair; skipping." + echo "should_merge=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + if [ "$author" != "github-actions" ] && [ "$author" != "github-actions[bot]" ]; then + echo "PR #$pr_number author is $author; skipping." + echo "should_merge=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + echo "should_merge=true" >> "$GITHUB_OUTPUT" + echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT" + + - name: Merge matching pull request + if: ${{ steps.pr.outputs.should_merge == 'true' }} + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ steps.pr.outputs.pr_number }} + run: | + gh api \ + -X PUT \ + -H "Accept: application/vnd.github+json" \ + /repos/${{ github.repository }}/pulls/${PR_NUMBER}/merge \ + -f merge_method=squash \ + -f commit_title="chore(winpeas): update windows version vulnerability definitions" diff --git a/.github/workflows/update_windows_version_definitions.yml b/.github/workflows/update_windows_version_definitions.yml index 4b3ffc7..30622b0 100644 --- a/.github/workflows/update_windows_version_definitions.yml +++ b/.github/workflows/update_windows_version_definitions.yml @@ -7,6 +7,7 @@ on: permissions: contents: write + pull-requests: write jobs: update-definitions: @@ -34,16 +35,34 @@ jobs: - name: Validate windows version definitions run: python3 build_lists/validate_windows_version_defs.py - - name: Commit and push changes + - name: Create update pull request + env: + GH_TOKEN: ${{ github.token }} run: | - if git diff --quiet -- build_lists/windows_version_exploits.json build_lists/validate_windows_version_defs.py; then + title="chore(winpeas): update windows version vulnerability definitions" + branch="bot/update-windows-version-definitions" + + if git diff --quiet -- build_lists/windows_version_exploits.json; then echo "No windows version definition updates detected." exit 0 fi git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add build_lists/windows_version_exploits.json build_lists/validate_windows_version_defs.py - git commit -m "chore(winpeas): update windows version vulnerability definitions" - git pull --rebase origin master - git push origin HEAD:master + git checkout -B "$branch" + git add build_lists/windows_version_exploits.json + git commit -m "$title" + git push --force-with-lease origin "$branch" + + pr_number="$(gh pr list --state open --head "$branch" --base master --json number --jq '.[0].number')" + if [ -z "$pr_number" ]; then + gh pr create \ + --base master \ + --head "$branch" \ + --title "$title" \ + --body "Automated update of \`build_lists/windows_version_exploits.json\`. The generated JSON passed \`build_lists/validate_windows_version_defs.py\` before this PR was created." + else + gh pr edit "$pr_number" \ + --title "$title" \ + --body "Automated update of \`build_lists/windows_version_exploits.json\`. The generated JSON passed \`build_lists/validate_windows_version_defs.py\` before this PR was updated." + fi