diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29c0952..b9fce76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,6 @@ name: CI -# Structural checks for this repo's own moving parts: the workflow YAML and -# the profile-refresh script. Also the gate that dependabot-auto-merge.yml -# waits on before enabling auto-merge. +# dependabot-auto-merge.yml waits on this workflow. on: pull_request: @@ -18,16 +16,30 @@ permissions: jobs: actionlint: runs-on: ubuntu-latest + timeout-minutes: 60 steps: - uses: actions/checkout@v7 + with: + persist-credentials: false + + # Dependabot can't see this pin; bump by hand. - name: Install actionlint - run: bash <(curl -fsSL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) + env: + ACTIONLINT_VERSION: 1.7.12 + run: | + bash <(curl -fsSL "https://raw.githubusercontent.com/rhysd/actionlint/v${ACTIONLINT_VERSION}/scripts/download-actionlint.bash") "$ACTIONLINT_VERSION" - run: ./actionlint -color + zizmor: + uses: drumandbytes/reusable-actions/.github/workflows/zizmor.yml@v1 + scripts: runs-on: ubuntu-latest + timeout-minutes: 60 steps: - uses: actions/checkout@v7 + with: + persist-credentials: false - uses: actions/setup-python@v7 with: python-version: "3.12" @@ -47,13 +59,13 @@ jobs: print("ok", f) PY - # Single stable name for the org's required-status-check ruleset to point - # at, regardless of how the real jobs above are split or renamed. + # Stable name for the org ruleset's required check. required-checks-passed: name: Required checks passed runs-on: ubuntu-latest - needs: [actionlint, scripts] + timeout-minutes: 60 + needs: [actionlint, zizmor, scripts] if: always() steps: - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') - run: exit 1 + run: exit 1 \ No newline at end of file diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index eb69d25..88fad99 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -1,13 +1,7 @@ name: Dependabot auto-merge -# Enables auto-merge on a Dependabot PR once CI has passed. Uses the org's -# shared definition in reusable-actions, the same way nordvpn and the action -# repos do. -# -# Triggered from `workflow_run` rather than `pull_request` on purpose: -# Dependabot-triggered `pull_request` runs get a read-only GITHUB_TOKEN and no -# secrets, so they cannot merge. A `workflow_run` job runs in the base repo's -# context with full permissions. See reusable-actions/.github/workflows/auto-merge.yml. +# workflow_run, not pull_request: Dependabot's pull_request runs get a +# read-only token and no secrets, so they can't merge. on: workflow_run: @@ -16,15 +10,13 @@ on: jobs: auto-merge: - # The reusable workflow cannot grant itself more than the caller has, and - # the org default for GITHUB_TOKEN is read-only — so declare it here. + # The org default token is read-only, and a reusable workflow can't + # raise the caller's permissions. permissions: contents: write pull-requests: write - # Every other actor's CI completion used to match this too, spinning up - # the reusable workflow (and its PR lookup) just to no-op - narrowing the - # trigger itself to the only actor that can ever be eligible below. + # Only Dependabot's runs are eligible; skip the rest before the call. if: >- github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.actor.login == 'dependabot[bot]' - uses: drumandbytes/reusable-actions/.github/workflows/auto-merge.yml@v1 + uses: drumandbytes/reusable-actions/.github/workflows/auto-merge.yml@v1 \ No newline at end of file diff --git a/.github/workflows/update-profile.yml b/.github/workflows/update-profile.yml index 3e1797d..ac84617 100644 --- a/.github/workflows/update-profile.yml +++ b/.github/workflows/update-profile.yml @@ -1,17 +1,12 @@ name: Update profile -# Refreshes the "Latest from the blog" block in profile/README.md from the -# drumandbytes.com RSS feed and commits the result straight to the default -# branch. -# -# The push is attributed to the dnb-robot GitHub App (app id 4773076), the -# one bypass actor on the org's `protecting-main` ruleset — a plain -# GITHUB_TOKEN push is rejected by "changes must be made through a pull -# request". See drumandbytes/dnb-tf's rulesets.tf for the full story. +# Refreshes the blog block in profile/README.md from the drumandbytes.com +# RSS feed. Pushes as dnb-robot, the only bypass actor on the org's +# protecting-main ruleset (see dnb-tf's rulesets.tf). on: schedule: - - cron: "17 6 * * *" # daily, 06:17 UTC + - cron: "17 6 * * *" workflow_dispatch: permissions: @@ -24,16 +19,18 @@ concurrency: jobs: update: runs-on: ubuntu-latest + timeout-minutes: 60 steps: - name: Generate dnb-robot app token id: app_token - # pinned to v3.2.0 - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: - app-id: 4773076 + client-id: ${{ secrets.DNB_ROBOT_CLIENT_ID }} private-key: ${{ secrets.AUTOMATION_APP_PRIVATE_KEY }} + permission-contents: write - - name: Checkout + # Keeps the token: the last step pushes with it. + - name: Checkout # zizmor: ignore[artipacked] uses: actions/checkout@v7 with: token: ${{ steps.app_token.outputs.token }} @@ -51,4 +48,4 @@ jobs: git config user.email "4773076+dnb-robot[bot]@users.noreply.github.com" git add profile/README.md git commit -m "chore: refresh latest blog posts on profile" - git push + git push \ No newline at end of file diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000..60efc8a --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,13 @@ +rules: + unpinned-uses: + config: + policies: + # GitHub's and our own actions on tags; third-party SHA-pinned. + "actions/*": ref-pin + "drumandbytes/*": ref-pin + "*": hash-pin + + dangerous-triggers: + ignore: + # Needed for Dependabot merges; never checks out PR code. + - dependabot-auto-merge.yml \ No newline at end of file