Backport PR #1499
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: Backport PR | |
| on: | |
| # SECURITY: This workflow uses workflow_run to create pull requests and write commits. | |
| # | |
| # - The artifact only contains the PR number (integer) | |
| # - The default branch is checked out, not PR code | |
| # - The backport tool uses PR number to fetch commits via API, not execute code | |
| # - PR state and labels are verified via API before processing | |
| # | |
| # zizmor: ignore[dangerous-triggers] see above | |
| workflow_run: | |
| workflows: ["Backport PR - Trigger"] | |
| types: [completed] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| id-token: write | |
| jobs: | |
| backport: | |
| # Only run if the trigger workflow succeeded. | |
| if: > | |
| github.repository == 'grafana/alloy' && | |
| github.event.workflow_run.conclusion == 'success' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Get GitHub app secrets 🔐 | |
| id: get-secrets | |
| uses: grafana/shared-workflows/actions/get-vault-secrets@a37de51f3d713a30a9e4b21bcdfbd38170020593 # get-vault-secrets/v1.3.0 | |
| with: | |
| export_env: false | |
| repo_secrets: | | |
| ALLOYBOT_APP_ID=alloybot:app_id | |
| ALLOYBOT_PRIVATE_KEY=alloybot:private_key | |
| - name: Generate token 🔐 | |
| uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 | |
| id: app-token | |
| with: | |
| app-id: ${{ fromJSON(steps.get-secrets.outputs.secrets).ALLOYBOT_APP_ID }} | |
| private-key: ${{ fromJSON(steps.get-secrets.outputs.secrets).ALLOYBOT_PRIVATE_KEY }} | |
| owner: grafana | |
| repositories: alloy | |
| - name: Download PR info artifact 🛬 | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: backport-info | |
| path: backport-info | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ steps.app-token.outputs.token }} | |
| - name: Read PR number 📖 | |
| id: pr-number | |
| run: | | |
| PR_NUMBER=$(cat backport-info/pr_number) | |
| echo "pr_number=${PR_NUMBER}" >> "$GITHUB_OUTPUT" | |
| echo "PR number: ${PR_NUMBER}" | |
| - name: Verify PR is merged and get backport labels 🏷️ | |
| id: pr-info | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| env: | |
| PR_NUMBER: ${{ steps.pr-number.outputs.pr_number }} | |
| with: | |
| github-token: ${{ steps.app-token.outputs.token }} | |
| script: | | |
| const prNumber = parseInt(process.env.PR_NUMBER, 10); | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: prNumber, | |
| }); | |
| if (!pr.merged) { | |
| core.setFailed(`PR #${prNumber} is not merged`); | |
| return; | |
| } | |
| console.log(`PR #${prNumber} is merged`); | |
| const backportLabels = pr.labels | |
| .map(l => l.name) | |
| .filter(name => name.startsWith('backport/')); | |
| if (backportLabels.length === 0) { | |
| core.setFailed(`PR #${prNumber} has no backport labels`); | |
| return; | |
| } | |
| console.log(`Backport labels: ${backportLabels.join(', ')}`); | |
| core.setOutput('labels', JSON.stringify(backportLabels)); | |
| - name: Checkout repository 🛎️ | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| ref: ${{ github.event.repository.default_branch }} | |
| fetch-depth: 0 | |
| persist-credentials: true # Needed for subsequent git operations | |
| - name: Set up Go 🏗️ | |
| uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 | |
| with: | |
| go-version-file: tools/go.mod | |
| cache-dependency-path: tools/go.sum | |
| - name: Run backport tool 🍒 | |
| env: | |
| GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} | |
| APP_SLUG: ${{ steps.app-token.outputs.app-slug }} | |
| LABELS: ${{ steps.pr-info.outputs.labels }} | |
| PR_NUMBER: ${{ steps.pr-number.outputs.pr_number }} | |
| run: | | |
| cd tools | |
| # Use while-read loop to safely handle labels with special characters | |
| echo "${LABELS}" | jq -r '.[]' | while IFS= read -r label; do | |
| echo "🍒 Processing backport for label: $label" | |
| go run ./release/backport \ | |
| --pr "${PR_NUMBER}" \ | |
| --label "$label" || echo "⚠️ Backport for $label failed, moving to next..." | |
| done |