Update SSH installer documentation for post-quantum KEX hardening #3
Workflow file for this run
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: Automerge and Approve PRs | |
| # This workflow automatically approves and enables automerge for PRs created by trusted automation | |
| on: | |
| pull_request: | |
| types: [opened, ready_for_review, reopened] | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: 'PR number to enable automerge for' | |
| required: true | |
| type: number | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| automerge: | |
| name: Enable Automerge | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check if PR should be automerged | |
| id: check | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const prNumber = context.payload.pull_request?.number || context.payload.inputs?.pr_number; | |
| if (!prNumber) { | |
| console.log('No PR number found'); | |
| return; | |
| } | |
| // Get PR details | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: prNumber | |
| }); | |
| console.log(`Checking PR #${prNumber}: ${pr.title}`); | |
| console.log(`Author: ${pr.user.login}`); | |
| console.log(`Draft: ${pr.draft}`); | |
| console.log(`Head ref: ${pr.head.ref}`); | |
| // Skip draft PRs | |
| if (pr.draft) { | |
| console.log('PR is a draft, skipping automerge'); | |
| return; | |
| } | |
| // Check if PR is from automation (Claude or github-actions bot) | |
| const isAutomatedPR = pr.user.login === 'Claude' || | |
| pr.user.login === 'github-actions[bot]' || | |
| pr.head.ref.startsWith('automated-update/') || | |
| pr.head.ref.startsWith('claude/'); | |
| if (!isAutomatedPR) { | |
| console.log('PR is not from automation, skipping automerge'); | |
| return; | |
| } | |
| console.log('PR is from automation and eligible for automerge'); | |
| // Check if PR has already been approved | |
| const { data: reviews } = await github.rest.pulls.listReviews({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: prNumber | |
| }); | |
| const hasApproval = reviews.some(review => | |
| review.state === 'APPROVED' && | |
| review.user.login === 'Stensel8' | |
| ); | |
| console.log(`Has approval from Stensel8: ${hasApproval}`); | |
| // Get check runs status | |
| const { data: checkRuns } = await github.rest.checks.listForRef({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| ref: pr.head.sha | |
| }); | |
| const allChecksPassed = checkRuns.check_runs.length === 0 || | |
| checkRuns.check_runs.every(check => | |
| check.status === 'completed' && | |
| check.conclusion === 'success' | |
| ); | |
| console.log(`All checks passed: ${allChecksPassed}`); | |
| // Set outputs for next steps | |
| core.setOutput('should_approve', !hasApproval); | |
| core.setOutput('should_enable_automerge', allChecksPassed); | |
| core.setOutput('pr_number', prNumber); | |
| core.setOutput('pr_node_id', pr.node_id); | |
| - name: Approve PR | |
| if: steps.check.outputs.should_approve == 'true' | |
| uses: actions/github-script@v8 | |
| env: | |
| PR_NUMBER: ${{ steps.check.outputs.pr_number }} | |
| with: | |
| script: | | |
| const prNumber = parseInt(process.env.PR_NUMBER); | |
| console.log(`Approving PR #${prNumber}`); | |
| await github.rest.pulls.createReview({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: prNumber, | |
| event: 'APPROVE', | |
| body: '✅ Automatically approved by automerge workflow.\n\nThis PR was created by trusted automation and has passed all checks.' | |
| }); | |
| console.log(`Successfully approved PR #${prNumber}`); | |
| - name: Enable automerge | |
| if: steps.check.outputs.should_enable_automerge == 'true' | |
| uses: actions/github-script@v8 | |
| env: | |
| PR_NODE_ID: ${{ steps.check.outputs.pr_node_id }} | |
| PR_NUMBER: ${{ steps.check.outputs.pr_number }} | |
| with: | |
| script: | | |
| const prNodeId = process.env.PR_NODE_ID; | |
| const prNumber = process.env.PR_NUMBER; | |
| console.log(`Enabling automerge for PR #${prNumber}`); | |
| try { | |
| // Enable automerge using GraphQL API | |
| const mutation = ` | |
| mutation EnableAutoMerge($pullRequestId: ID!, $mergeMethod: PullRequestMergeMethod!) { | |
| enablePullRequestAutoMerge(input: { | |
| pullRequestId: $pullRequestId, | |
| mergeMethod: $mergeMethod | |
| }) { | |
| pullRequest { | |
| autoMergeRequest { | |
| enabledAt | |
| enabledBy { | |
| login | |
| } | |
| } | |
| } | |
| } | |
| } | |
| `; | |
| const result = await github.graphql(mutation, { | |
| pullRequestId: prNodeId, | |
| mergeMethod: 'SQUASH' // Use squash merge by default | |
| }); | |
| console.log(`Successfully enabled automerge for PR #${prNumber}`); | |
| console.log(JSON.stringify(result, null, 2)); | |
| } catch (error) { | |
| console.error(`Error enabling automerge: ${error.message}`); | |
| // Comment on the PR about the failure | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body: `⚠️ **Automerge Failed**\n\nUnable to enable automerge automatically. Error: ${error.message}\n\nYou may need to enable automerge manually or check repository settings.` | |
| }); | |
| throw error; | |
| } |