Attach OIDC Native to Ingress Resource #1708
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: External PR Handler | |
| on: | |
| issue_comment: | |
| types: [ created ] | |
| permissions: | |
| contents: read | |
| issues: read | |
| pull-requests: read | |
| jobs: | |
| pr-details: | |
| if: > | |
| github.repository == 'nginx/kubernetes-ingress' && ( | |
| github.event.issue.pull_request && | |
| github.event.comment.body == '/approve-pipeline-run' | |
| ) | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| is_fork: ${{ steps.pr-info.outputs.is_fork }} | |
| fork_owner: ${{ steps.pr-info.outputs.fork_owner }} | |
| fork_repo: ${{ steps.pr-info.outputs.fork_repo }} | |
| branch: ${{ steps.pr-info.outputs.branch }} | |
| sha: ${{ steps.pr-info.outputs.sha }} | |
| base_branch: ${{ steps.pr-info.outputs.base_branch }} | |
| title: ${{ steps.pr-info.outputs.title }} | |
| body: ${{ steps.pr-info.outputs.body }} | |
| steps: | |
| - name: Get PR details | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| id: pr-info | |
| with: | |
| script: | | |
| const pr = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.issue.number | |
| }); | |
| core.setOutput('is_fork', pr.data.head.repo.fork.toString()); | |
| core.setOutput('fork_owner', pr.data.head.repo.owner.login); | |
| core.setOutput('fork_repo', pr.data.head.repo.name); | |
| core.setOutput('branch', pr.data.head.ref); | |
| core.setOutput('sha', pr.data.head.sha); | |
| core.setOutput('base_branch', pr.data.base.ref); | |
| core.setOutput('title', pr.data.title); | |
| const body = pr.data.body ?? ''; | |
| core.setOutput('body', body); | |
| create-internal-pr-mirror: | |
| needs: pr-details | |
| permissions: | |
| id-token: write | |
| contents: read | |
| issues: read | |
| pull-requests: read | |
| if: > | |
| github.repository == 'nginx/kubernetes-ingress' && ( | |
| needs.pr-details.outputs.is_fork == 'true' | |
| ) | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Check commenter permissions | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| id: pr | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| username: context.actor | |
| }); | |
| const allowed = ["admin", "write", "maintain"].includes(permission.permission); | |
| if (!allowed) { | |
| core.setFailed("User is not authorized to approve pipeline run."); | |
| } | |
| - name: Azure login | |
| uses: azure/login@f5d393ae46f8fde4be8b75f32e3fc50e654ad0ca # v3.0.1 | |
| with: | |
| client-id: ${{ secrets.AZURE_COMMON_VAULT_CLIENT_ID }} | |
| tenant-id: ${{ secrets.AZURE_COMMON_VAULT_TENANT_ID }} | |
| subscription-id: ${{ secrets.AZURE_COMMON_VAULT_SUBSCRIPTION_ID }} | |
| - name: Get secrets from vault | |
| uses: nginx/ci-self-hosted/.github/actions/get-from-vault@5c3e1f8b51f66a851fdba80f70e19cf966199730 # main @ 2026-05-22 | |
| with: | |
| vault-name: ${{ secrets.COMMON_KEYVAULT_NAME }} | |
| secret-names: "nginx-bot-nic-create-pr-app-client-id, nginx-bot-nic-create-pr-app-private-key" | |
| env-names: "APP_CLIENT_ID, APP_PRIVATE_KEY_B64" | |
| - name: Decode GitHub App private key | |
| id: app_key | |
| run: | | |
| set +x | |
| # Mask the raw base64 value | |
| echo "::add-mask::$APP_PRIVATE_KEY_B64" | |
| private_key=$(printf '%s' "$APP_PRIVATE_KEY_B64" | base64 -d) | |
| # Mask every line of the decoded PEM key individually | |
| while IFS= read -r line; do | |
| if [[ -n "$line" ]]; then | |
| echo "::add-mask::$line" | |
| fi | |
| done <<< "$private_key" | |
| delimiter="GHEOF_$(openssl rand -hex 12)" | |
| { | |
| echo "private_key<<$delimiter" | |
| echo "$private_key" | |
| echo "$delimiter" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Generate GitHub App token | |
| id: app_token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| with: | |
| client-id: ${{ env.APP_CLIENT_ID }} | |
| private-key: ${{ steps.app_key.outputs.private_key }} | |
| owner: ${{ github.repository_owner }} | |
| repositories: ${{ github.event.repository.name }} | |
| - name: Checkout fork branch | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| repository: ${{ needs.pr-details.outputs.fork_owner }}/${{ needs.pr-details.outputs.fork_repo }} | |
| ref: ${{ needs.pr-details.outputs.sha }} | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Create and push branch | |
| id: branch | |
| env: | |
| PR_BRANCH: ${{ needs.pr-details.outputs.branch }} | |
| SHA: ${{ needs.pr-details.outputs.sha }} | |
| APP_TOKEN: ${{ steps.app_token.outputs.token }} | |
| run: | | |
| git config --global credential.helper store | |
| echo "https://x-access-token:${APP_TOKEN}@github.com" > ~/.git-credentials | |
| git remote add upstream https://github.com/${{ github.repository }}.git | |
| git fetch upstream | |
| BRANCH_NAME="$PR_BRANCH" | |
| SHORT_SHA="${SHA:0:8}" | |
| INTERNAL_BRANCH="chore/${BRANCH_NAME}-${SHORT_SHA}-do-not-merge" | |
| git checkout -b "${INTERNAL_BRANCH}" | |
| git push upstream "${INTERNAL_BRANCH}" | |
| echo "Branch updated: ${INTERNAL_BRANCH}" | |
| rm ~/.git-credentials | |
| echo "internal_branch=${INTERNAL_BRANCH}" >> $GITHUB_OUTPUT | |
| - name: Open internal PR | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| env: | |
| BASE_BRANCH: ${{ needs.pr-details.outputs.base_branch }} | |
| HEAD_BRANCH: ${{ steps.branch.outputs.internal_branch }} | |
| PR_TITLE: ${{ needs.pr-details.outputs.title }} | |
| PR_BODY: ${{ needs.pr-details.outputs.body }} | |
| with: | |
| github-token: ${{ steps.app_token.outputs.token }} | |
| script: | | |
| // Check for existing PR | |
| const { data: existingPRs } = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| head: `${context.repo.owner}:${process.env.HEAD_BRANCH}`, | |
| state: 'open' | |
| }); | |
| if (existingPRs.length > 0) { | |
| core.setFailed( | |
| `PR already exists: #${existingPRs[0].number}\n` + | |
| `URL: ${existingPRs[0].html_url}\n` + | |
| `Close existing PR before creating a new one.` | |
| ); | |
| return; | |
| } | |
| // Create new PR | |
| await github.rest.pulls.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| base: process.env.BASE_BRANCH, | |
| head: process.env.HEAD_BRANCH, | |
| title: `DO NOT MERGE ${process.env.PR_TITLE}`, | |
| body: process.env.PR_BODY, | |
| draft: true | |
| }); |