|
| 1 | +name: Landing security bump |
| 2 | + |
| 3 | +on: |
| 4 | + schedule: |
| 5 | + - cron: '23 2 * * 1' |
| 6 | + workflow_dispatch: |
| 7 | + # External signature-verifying relay required; no receiver is installed here. |
| 8 | + repository_dispatch: |
| 9 | + types: [dependabot_alert] |
| 10 | + workflow_run: |
| 11 | + workflows: [Main] |
| 12 | + types: [completed] |
| 13 | + |
| 14 | +permissions: |
| 15 | + contents: write |
| 16 | + issues: write |
| 17 | + pull-requests: write |
| 18 | + actions: write |
| 19 | + vulnerability-alerts: read |
| 20 | + |
| 21 | +jobs: |
| 22 | + check-alerts: |
| 23 | + if: >- |
| 24 | + vars.LANDING_MODEL != '' && |
| 25 | + (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') |
| 26 | + runs-on: ubuntu-latest |
| 27 | + timeout-minutes: 5 |
| 28 | + permissions: |
| 29 | + vulnerability-alerts: read |
| 30 | + outputs: |
| 31 | + count: ${{ steps.alerts.outputs.count }} |
| 32 | + env: |
| 33 | + GH_TOKEN: ${{ secrets.LANDING_GITHUB_TOKEN || github.token }} |
| 34 | + GH_REPO: ${{ github.repository }} |
| 35 | + steps: |
| 36 | + - name: Check open security alerts |
| 37 | + id: alerts |
| 38 | + run: | |
| 39 | + count=$(gh api --method GET "repos/$GH_REPO/dependabot/alerts" -f state=open -f per_page=1 --jq 'length') |
| 40 | + echo "count=$count" >> "$GITHUB_OUTPUT" |
| 41 | + if [ "$count" -eq 0 ]; then |
| 42 | + echo "No open Dependabot alerts." |
| 43 | + fi |
| 44 | +
|
| 45 | + bump: |
| 46 | + needs: [check-alerts] |
| 47 | + if: >- |
| 48 | + always() && !cancelled() && vars.LANDING_MODEL != '' && |
| 49 | + (((github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && |
| 50 | + needs.check-alerts.result == 'success' && needs.check-alerts.outputs.count == '1') || |
| 51 | + github.event_name == 'repository_dispatch' || |
| 52 | + (github.event_name == 'workflow_run' && |
| 53 | + github.event.workflow_run.conclusion == 'failure' && |
| 54 | + github.event.workflow_run.head_repository.full_name == github.repository && |
| 55 | + (github.event.workflow_run.event == 'pull_request' || |
| 56 | + (github.event.workflow_run.event == 'workflow_dispatch' && |
| 57 | + github.event.workflow_run.head_branch != github.event.repository.default_branch)) && |
| 58 | + vars.LANDING_BUMP_ON_FAILURE != 'false')) |
| 59 | + concurrency: |
| 60 | + group: landing-security-bump-${{ github.repository_id }} |
| 61 | + cancel-in-progress: false |
| 62 | + queue: max |
| 63 | + runs-on: ubuntu-latest |
| 64 | + timeout-minutes: 30 |
| 65 | + env: |
| 66 | + GH_ADMISSION_TOKEN: ${{ secrets.LANDING_ADMISSION_TOKEN || github.token }} |
| 67 | + GH_TOKEN: ${{ secrets.LANDING_GITHUB_TOKEN || github.token }} |
| 68 | + GIT_AUTHOR_NAME: ${{ vars.LANDING_GIT_NAME || 'github-actions[bot]' }} |
| 69 | + GIT_AUTHOR_EMAIL: ${{ vars.LANDING_GIT_EMAIL || '41898282+github-actions[bot]@users.noreply.github.com' }} |
| 70 | + GIT_COMMITTER_NAME: ${{ vars.LANDING_GIT_NAME || 'github-actions[bot]' }} |
| 71 | + GIT_COMMITTER_EMAIL: ${{ vars.LANDING_GIT_EMAIL || '41898282+github-actions[bot]@users.noreply.github.com' }} |
| 72 | + steps: |
| 73 | + - name: Check out trusted default branch |
| 74 | + uses: actions/checkout@v7 |
| 75 | + with: |
| 76 | + ref: ${{ github.event.repository.default_branch }} |
| 77 | + fetch-depth: 0 |
| 78 | + persist-credentials: false |
| 79 | + - name: Set up Python dependencies |
| 80 | + uses: ./.github/actions/setup-python-env |
| 81 | + with: |
| 82 | + python-version: '3.12' |
| 83 | + - name: Prepare GitHub Git authentication |
| 84 | + run: gh auth setup-git |
| 85 | + - name: Identify Landing dependency PR publisher |
| 86 | + if: github.event_name == 'workflow_run' && startsWith(github.event.workflow_run.head_branch, 'deps/landing-') |
| 87 | + run: echo "LANDING_PUBLISHING_ACTOR=$(gh api graphql -f query='{viewer{login}}' --jq .data.viewer.login)" >> "$GITHUB_ENV" |
| 88 | + - name: Remediate vulnerable dependencies |
| 89 | + uses: bubbuild/landing@main |
| 90 | + env: |
| 91 | + LANDING_MODEL: ${{ vars.LANDING_MODEL }} |
| 92 | + LANDING_API_KEY: ${{ secrets.LANDING_API_KEY }} |
| 93 | + LANDING_API_BASE: ${{ vars.LANDING_API_BASE }} |
| 94 | + LANDING_COMPLETION_ARGS: ${{ vars.LANDING_COMPLETION_ARGS || '{}' }} |
| 95 | + with: |
| 96 | + command: bump |
| 97 | + upstream-workflow: Main |
| 98 | + bump-on-failure: ${{ vars.LANDING_BUMP_ON_FAILURE || 'true' }} |
| 99 | + dependency-update-actors: | |
| 100 | + dependabot[bot] |
| 101 | + renovate[bot] |
| 102 | + ${{ env.LANDING_PUBLISHING_ACTOR }} |
| 103 | + ${{ vars.LANDING_DEPENDENCY_UPDATE_ACTORS }} |
| 104 | + checked-revision: '' |
| 105 | + checks: | |
| 106 | + make check |
| 107 | + make test |
| 108 | + instruction: >- |
| 109 | + Security remediation only: inspect open Dependabot alerts; skip routine upgrades and stop if alert access fails. Closed alerts only reconcile tracked remediation. |
| 110 | + For failed CI, verify the supplied security dependency PR's current head and failed checks; make only necessary repairs on its existing branch, without force-push. |
| 111 | + Follow AGENTS.md: use uv, preserve dependency constraints and pinning styles, and keep manifest/lock changes scoped to the security fix. |
| 112 | + Reuse matching PRs; publish new candidates as English drafts on deps/landing-* branches with Conventional Commit titles and advisory/version/check evidence. |
| 113 | + After each candidate push, run gh workflow run main.yml --ref <candidate-branch> and verify the run's head_sha matches; report dispatch failures without weakening checks. |
| 114 | + Maintainers decide merges, releases and alert dismissal; do not change the package version or generated protocol bindings. No general review or triage is authorized. |
0 commit comments