Merge pull request #909 from apache/dependabot/github_actions/dot-git… #47
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
| # | |
| # Licensed to the Apache Software Foundation (ASF) under one | |
| # or more contributor license agreements. See the NOTICE file | |
| # distributed with this work for additional information | |
| # regarding copyright ownership. The ASF licenses this file | |
| # to you under the Apache License, Version 2.0 (the | |
| # "License"); you may not use this file except in compliance | |
| # with the License. You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, | |
| # software distributed under the License is distributed on an | |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| # KIND, either express or implied. See the License for the | |
| # specific language governing permissions and limitations | |
| # under the License. | |
| # | |
| # Keeps the allowlist trio in sync: `actions.yml` (source of truth), | |
| # `.github/actions/for-dependabot-triggered-reviews/action.yml` (the | |
| # composite Dependabot watches), and `approved_patterns.yml` (the | |
| # org-wide allow list). A single concurrency group serialises edits so | |
| # neither direction's change is lost when both files move in overlapping | |
| # pushes (see #866 for the race this prevents). | |
| # | |
| # Also enforces the 800/1000-entry cap on `approved_patterns.yml` inline | |
| # (see the "Check approved actions count" step) — running after | |
| # regeneration and before commit/push, so an over-cap state never lands | |
| # on `main`. The commit-and-push step uses the `ALLOWLIST_WORKFLOW_TOKEN` | |
| # PAT because `main` is a protected branch; see the comment on the | |
| # `token:` input below for the full rationale. | |
| name: Update Allowlist and Composite Action | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - "actions.yml" | |
| - ".github/actions/for-dependabot-triggered-reviews/action.yml" | |
| pull_request: | |
| paths: | |
| - ".github/workflows/update.yml" | |
| - ".github/actions/for-dependabot-triggered-reviews/action.yml" | |
| - "actions.yml" | |
| - "gateway/*" | |
| permissions: | |
| contents: read | |
| # Single group across both inputs so no two updates touch the allowlist | |
| # files in parallel. Don't cancel — every queued run must finish so we | |
| # don't drop a dependabot bump or a manual actions.yml edit. | |
| concurrency: | |
| group: "${{ github.ref }}-update" | |
| cancel-in-progress: false | |
| jobs: | |
| update: | |
| runs-on: ubuntu-latest | |
| # `contents: write` is required on push/dispatch so the commit step | |
| # can push the regenerated files back to `main`. The workflow also | |
| # runs on `pull_request`, where GitHub automatically downgrades the | |
| # GITHUB_TOKEN to read-only regardless of what's declared here, so | |
| # PRs from forks can't acquire write access via this workflow. | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: true | |
| # The PAT is required because `main` is a protected branch and | |
| # the default `GITHUB_TOKEN` cannot push to it — every push from | |
| # a `GITHUB_TOKEN`-authenticated commit step fails with | |
| # `GH006: Protected branch update failed`. The | |
| # `ALLOWLIST_WORKFLOW_TOKEN` secret is configured with bypass | |
| # rights for this workflow's commit so the regenerated | |
| # `actions.yml`, composite, and `approved_patterns.yml` can | |
| # land. Fallback to `github.token` is only useful for PR/fork | |
| # runs, where the commit step is skipped anyway. | |
| token: ${{ secrets.ALLOWLIST_WORKFLOW_TOKEN || github.token }} # zizmor: ignore[secrets-outside-env] | |
| # On push/dispatch, check out the current tip of main rather | |
| # than the trigger SHA. A queued run that started on an older | |
| # SHA would otherwise regenerate from stale inputs and either | |
| # undo the prior run's commit or fail to push. | |
| ref: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && 'main' || '' }} | |
| - run: pipx install uv | |
| - name: Sync composite action, actions.yml, and approved_patterns.yml | |
| run: | | |
| uv run python << 'PYEOF' | |
| import sys | |
| sys.path.append("./gateway/") | |
| import gateway as g | |
| composite = ".github/actions/for-dependabot-triggered-reviews/action.yml" | |
| actions = "actions.yml" | |
| patterns = "approved_patterns.yml" | |
| # Run both directions every time, regardless of which file | |
| # triggered us — the outcome is the same either way. | |
| # | |
| # 1. Pull any new refs from the composite (e.g. dependabot | |
| # bumps) into actions.yml. Additive: existing entries stay | |
| # and get their expiry refreshed. | |
| g.update_actions(composite, actions) | |
| # 2. Regenerate the composite from the (now-merged) | |
| # actions.yml so a manual actions.yml edit is reflected. | |
| g.update_workflow(composite, actions) | |
| # 3. Regenerate the approved patterns from actions.yml. | |
| g.update_patterns(patterns, actions) | |
| PYEOF | |
| - name: Check approved actions count | |
| # The org-wide approved_patterns list has a hard limit of 1000 | |
| # entries; we fail at 800 to give maintainers room to act before | |
| # hitting the wall. Runs after regeneration and before | |
| # commit/push, so an over-cap state never lands on main. See | |
| # https://github.com/apache/infrastructure-actions/issues/602 | |
| run: | | |
| LIMIT=800 | |
| COUNT=$(grep -c '^- ' approved_patterns.yml) | |
| echo "Approved actions count: $COUNT / 1000 (warning threshold: $LIMIT)" | |
| if [ "$COUNT" -ge "$LIMIT" ]; then | |
| echo "::error::Approved actions count ($COUNT) has reached the warning threshold of $LIMIT. The org-wide limit is 1000. Time to clean up unused actions or explore workarounds. See https://github.com/apache/infrastructure-actions/issues/602" | |
| exit 1 | |
| fi | |
| - name: Commit and push changes | |
| if: ${{ github.event_name != 'pull_request' }} | |
| env: | |
| # Same PAT as the checkout step above — `main` is a protected | |
| # branch and only the `ALLOWLIST_WORKFLOW_TOKEN` PAT has bypass | |
| # rights for this workflow's automated push. Without it, the | |
| # push fails with `GH006: Protected branch update failed` and | |
| # the regenerated files never land. | |
| GH_TOKEN: ${{ secrets.ALLOWLIST_WORKFLOW_TOKEN || github.token }} # zizmor: ignore[secrets-outside-env] | |
| run: | | |
| AUTHOR_NAME=$(gh api /user --jq '.login' 2>/dev/null || echo "asfgit") | |
| AUTHOR_EMAIL=$(gh api /user --jq '.email // "\(.login)@users.noreply.github.com"' 2>/dev/null || echo "asfgit@users.noreply.github.com") | |
| git config --local user.name "${AUTHOR_NAME}" | |
| git config --local user.email "${AUTHOR_EMAIL}" | |
| composite=".github/actions/for-dependabot-triggered-reviews/action.yml" | |
| if git diff --quiet -- actions.yml approved_patterns.yml "${composite}"; then | |
| echo "No changes" | |
| exit 0 | |
| fi | |
| git add -f actions.yml approved_patterns.yml "${composite}" | |
| git commit \ | |
| -m "Sync actions.yml, composite action, and approved_patterns.yml" \ | |
| -m "Generated by .github/workflows/update.yml" | |
| # If a concurrent push (e.g. remove_expired.yml) advanced main | |
| # while we were computing, rebase and retry. The sync script is | |
| # idempotent so re-running on the rebased tree is safe. | |
| for attempt in 1 2 3; do | |
| if git push origin HEAD:main; then | |
| exit 0 | |
| fi | |
| echo "Push rejected on attempt ${attempt}; rebasing and re-running sync" | |
| git fetch origin main | |
| git reset --hard origin/main | |
| uv run python << 'PYEOF' | |
| import sys | |
| sys.path.append("./gateway/") | |
| import gateway as g | |
| composite = ".github/actions/for-dependabot-triggered-reviews/action.yml" | |
| actions = "actions.yml" | |
| patterns = "approved_patterns.yml" | |
| g.update_actions(composite, actions) | |
| g.update_workflow(composite, actions) | |
| g.update_patterns(patterns, actions) | |
| PYEOF | |
| if git diff --quiet -- actions.yml approved_patterns.yml "${composite}"; then | |
| echo "Already in sync after rebase; nothing to push" | |
| exit 0 | |
| fi | |
| git add -f actions.yml approved_patterns.yml "${composite}" | |
| git commit \ | |
| -m "Sync actions.yml, composite action, and approved_patterns.yml" \ | |
| -m "Generated by .github/workflows/update.yml" | |
| done | |
| echo "Failed to push after 3 attempts" | |
| exit 1 |