docs-pr #121
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: Create/Update Docs PR | |
| on: | |
| repository_dispatch: | |
| types: [docs-pr] | |
| workflow_dispatch: | |
| inputs: | |
| repo: | |
| description: 'Repository name (e.g., gardenlinux)' | |
| required: true | |
| type: string | |
| pr_number: | |
| description: 'PR number in source repo' | |
| required: true | |
| type: string | |
| commit_sha: | |
| description: 'Commit SHA from source repo' | |
| required: true | |
| type: string | |
| ref: | |
| description: 'Git ref/branch from source repo' | |
| required: true | |
| type: string | |
| event: | |
| description: 'Event type (pr_success or merged)' | |
| required: true | |
| type: choice | |
| options: | |
| - pr_success | |
| - merged | |
| jobs: | |
| create-pr: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Generate GitHub App token | |
| id: app-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| with: | |
| client-id: ${{ secrets.DOCS_BOT_APP_ID }} | |
| private-key: ${{ secrets.DOCS_BOT_PRIVATE_KEY }} | |
| repositories: docs,${{ github.event.client_payload.repo || inputs.repo }} | |
| - name: Checkout docs | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| fetch-depth: 0 | |
| - name: Configure git | |
| run: | | |
| git config user.name "gardenlinux-docs-bot[bot]" | |
| git config user.email "${{ secrets.DOCS_BOT_APP_ID }}+gardenlinux-docs-bot[bot]@users.noreply.github.com" | |
| - name: Extract payload | |
| id: payload | |
| uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | |
| with: | |
| script: | | |
| let payload; | |
| if (context.eventName === 'workflow_dispatch') { | |
| payload = context.payload.inputs; | |
| } else { | |
| payload = context.payload.client_payload; | |
| } | |
| core.setOutput('repo', payload.repo); | |
| core.setOutput('pr_number', payload.pr_number); | |
| core.setOutput('commit_sha', payload.commit_sha); | |
| core.setOutput('ref', payload.ref); | |
| core.setOutput('event', payload.event); | |
| - name: Create or update branch | |
| run: | | |
| BRANCH="auto/${{ steps.payload.outputs.repo }}/${{ steps.payload.outputs.pr_number }}" | |
| git fetch origin main | |
| git checkout -B "$BRANCH" origin/main | |
| - name: Update repos-config.json | |
| uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const repoName = '${{ steps.payload.outputs.repo }}'; | |
| const commitSha = '${{ steps.payload.outputs.commit_sha }}'; | |
| const ref = '${{ steps.payload.outputs.ref }}'; | |
| const event = '${{ steps.payload.outputs.event }}'; | |
| const config = JSON.parse(fs.readFileSync('repos-config.json', 'utf8')); | |
| let found = false; | |
| for (const repo of config.repos) { | |
| if (repo.name === repoName) { | |
| repo.commit = commitSha; | |
| // Always use the ref from the payload (for merged PRs, this is the base branch) | |
| repo.ref = ref; | |
| found = true; | |
| break; | |
| } | |
| } | |
| if (!found) { | |
| core.setFailed(`Repository '${repoName}' not found in repos-config.json. Available repos: ${config.repos.map(r => r.name).join(', ')}`); | |
| return; | |
| } | |
| fs.writeFileSync('repos-config.json', JSON.stringify(config, null, 2) + '\n'); | |
| core.info(`Updated ${repoName}: ref=${ref}, commit=${commitSha}`); | |
| - name: Commit and push | |
| run: | | |
| git add repos-config.json | |
| git commit -m "docs(${{ steps.payload.outputs.repo }}): update commit lock to ${{ steps.payload.outputs.commit_sha }}" | |
| git push -f origin "auto/${{ steps.payload.outputs.repo }}/${{ steps.payload.outputs.pr_number }}" | |
| - name: Create or update PR | |
| id: docs_pr | |
| uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | |
| with: | |
| github-token: ${{ steps.app-token.outputs.token }} | |
| script: | | |
| const branch = `auto/${{ steps.payload.outputs.repo }}/${{ steps.payload.outputs.pr_number }}`; | |
| const prNumber = '${{ steps.payload.outputs.pr_number }}'; | |
| const repo = '${{ steps.payload.outputs.repo }}'; | |
| const event = '${{ steps.payload.outputs.event }}'; | |
| const commitSha = '${{ steps.payload.outputs.commit_sha }}'; | |
| // Check if PR already exists | |
| const { data: existingPRs } = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| head: `${context.repo.owner}:${branch}`, | |
| state: 'open' | |
| }); | |
| let prUrl; | |
| let docsPrNumber; | |
| if (existingPRs.length > 0) { | |
| const existingPR = existingPRs[0]; | |
| core.info(`PR #${existingPR.number} already exists, updating...`); | |
| const isDraft = event !== 'merged'; | |
| const statusText = isDraft ? 'Draft (waiting for source PR to merge)' : 'Ready for review'; | |
| // Update PR with latest status, draft setting, and body | |
| const updateBody = [ | |
| '## Summary', | |
| '', | |
| `Automated PR to update the commit lock for \`${repo}\` repository.`, | |
| '', | |
| `- **Source PR:** https://github.com/gardenlinux/${repo}/pull/${prNumber}`, | |
| `- **Commit:** \`${commitSha}\``, | |
| `- **Status:** ${statusText}`, | |
| '', | |
| 'This PR was automatically created by the docs-check workflow.' | |
| ].join('\n'); | |
| await github.rest.pulls.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: existingPR.number, | |
| draft: isDraft, | |
| body: updateBody | |
| }); | |
| prUrl = existingPR.html_url; | |
| docsPrNumber = existingPR.number; | |
| } else { | |
| core.info('Creating new draft PR...'); | |
| const isDraft = event !== 'merged'; | |
| const statusText = isDraft ? 'Draft (waiting for source PR to merge)' : 'Ready for review'; | |
| const createBody = [ | |
| '## Summary', | |
| '', | |
| `Automated PR to update the commit lock for \`${repo}\` repository.`, | |
| '', | |
| `- **Source PR:** https://github.com/gardenlinux/${repo}/pull/${prNumber}`, | |
| `- **Commit:** \`${commitSha}\``, | |
| `- **Status:** ${statusText}`, | |
| '', | |
| 'This PR was automatically created by the docs-check workflow.' | |
| ].join('\n'); | |
| const { data: newPR } = await github.rest.pulls.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| head: branch, | |
| base: 'main', | |
| draft: isDraft, | |
| title: `docs(${repo}): Update commit lock from PR #${prNumber}`, | |
| body: createBody | |
| }); | |
| prUrl = newPR.html_url; | |
| docsPrNumber = newPR.number; | |
| } | |
| core.setOutput('pr_url', prUrl); | |
| core.setOutput('docs_pr_number', docsPrNumber); | |
| - name: Comment on source PR | |
| if: steps.payload.outputs.pr_number != '' | |
| uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | |
| with: | |
| github-token: ${{ steps.app-token.outputs.token }} | |
| script: | | |
| const prNumber = parseInt('${{ steps.payload.outputs.pr_number }}'); | |
| const repo = '${{ steps.payload.outputs.repo }}'; | |
| const prUrl = '${{ steps.docs_pr.outputs.pr_url }}'; | |
| const docsPrNumber = '${{ steps.docs_pr.outputs.docs_pr_number }}'; | |
| const commentBody = `📚 **Documentation Preview PR:** ${prUrl} | |
| 😎 **Deploy Preview:** https://deploy-preview-${docsPrNumber}--gardenlinux-docs.netlify.app | |
| A PR has been created/updated to preview the documentation changes from this PR.`; | |
| // Find existing bot comment | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: 'gardenlinux', | |
| repo: repo, | |
| issue_number: prNumber | |
| }); | |
| const botComment = comments.find(comment => | |
| comment.body.includes('📚 **Documentation Preview PR:**') && | |
| comment.user.type === 'Bot' | |
| ); | |
| if (botComment) { | |
| // Update existing comment | |
| await github.rest.issues.updateComment({ | |
| owner: 'gardenlinux', | |
| repo: repo, | |
| comment_id: botComment.id, | |
| body: commentBody | |
| }); | |
| core.info(`Updated existing comment #${botComment.id}`); | |
| } else { | |
| // Create new comment | |
| await github.rest.issues.createComment({ | |
| owner: 'gardenlinux', | |
| repo: repo, | |
| issue_number: prNumber, | |
| body: commentBody | |
| }); | |
| core.info('Created new comment'); | |
| } |