fix(ci): permissions model — no top-level perms in ci.yml; callers need write
GitHub Actions permission model for reusable workflows: callers must declare at least the permission level that any job in the called workflow requests. Since the phpcs job declares 'permissions: contents: write' (for phpcbf commit-back), all callers must include 'permissions: contents: write' at their workflow level. Changes: - ci.yml: remove top-level permissions block (was: contents: read); phpcs job already has job-level contents: write. Docblock now explains the caller requirement clearly. - ci-self-test.yml: add 'permissions: contents: write' at workflow level. - README.md: adoption snippet now includes the required permissions block. - Remove diagnostic bisect/minimal test workflows (used to identify the root cause of startup_failure; finding: job-level write in reusable workflow requires caller to declare write at workflow level). Confirmed: ci-bisect-caller with permissions: contents: write = SUCCESS. Confirmed: actionlint 1.7.4 + yamllint 1.38.0 both clean. Agent-Session: claude/reusable-ci-20260616
This commit is contained in:
15
.github/workflows/ci-bisect-caller.yml
vendored
15
.github/workflows/ci-bisect-caller.yml
vendored
@@ -1,15 +0,0 @@
|
||||
name: CI Bisect Caller v3
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['claude/**']
|
||||
|
||||
permissions:
|
||||
contents: write # needed for called reusable workflow's phpcs job
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
uses: ./.github/workflows/ci-bisect.yml
|
||||
with:
|
||||
tests: none
|
||||
secrets: inherit
|
||||
27
.github/workflows/ci-bisect.yml
vendored
27
.github/workflows/ci-bisect.yml
vendored
@@ -1,27 +0,0 @@
|
||||
name: CI Bisect Test v3
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
tests:
|
||||
type: string
|
||||
required: false
|
||||
default: stubs
|
||||
|
||||
# No top-level permissions — only job-level where needed
|
||||
|
||||
jobs:
|
||||
phpcs:
|
||||
name: PHPCS
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- run: echo "phpcs with write"
|
||||
|
||||
phpunit:
|
||||
name: PHPUnit
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ inputs.tests != 'none' }}
|
||||
steps:
|
||||
- run: echo "phpunit ${{ inputs.tests }}"
|
||||
12
.github/workflows/ci-minimal-test.yml
vendored
12
.github/workflows/ci-minimal-test.yml
vendored
@@ -1,12 +0,0 @@
|
||||
name: Minimal Reusable Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['claude/**']
|
||||
|
||||
jobs:
|
||||
test:
|
||||
uses: ./.github/workflows/ci-minimal.yml
|
||||
with:
|
||||
test_input: hello
|
||||
secrets: inherit
|
||||
18
.github/workflows/ci-minimal.yml
vendored
18
.github/workflows/ci-minimal.yml
vendored
@@ -1,18 +0,0 @@
|
||||
name: Minimal Reusable
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
test_input:
|
||||
type: string
|
||||
required: false
|
||||
default: world
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
hello:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "Hello ${{ inputs.test_input }}"
|
||||
10
.github/workflows/ci-self-test.yml
vendored
10
.github/workflows/ci-self-test.yml
vendored
@@ -1,8 +1,9 @@
|
||||
# Self-test: exercises the reusable ci.yml on this repo itself.
|
||||
# Uses tests: none (peptide-e2e is a Playwright/Node repo, no PHP suite).
|
||||
# phpcs_autofix: false avoids needing contents: write at the caller level
|
||||
# (the phpcs job in ci.yml has its own job-level write permission for phpcbf).
|
||||
# Purpose: smoke-check that the reusable workflow skeleton runs without errors.
|
||||
# permissions: contents: write is required at the caller level — any caller of
|
||||
# ci.yml must declare this so the phpcs job can commit phpcbf fixes back to the
|
||||
# PR branch. Even with phpcs_autofix: false here, the permission must be declared
|
||||
# for the reusable workflow to pass GH's startup permission-escalation check.
|
||||
|
||||
name: CI Self-Test (reusable ci.yml)
|
||||
|
||||
@@ -12,6 +13,9 @@ on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: write # required: called ci.yml phpcs job declares job-level write for phpcbf
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
uses: ./.github/workflows/ci.yml
|
||||
|
||||
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@@ -50,9 +50,11 @@
|
||||
# and concatenated verbatim — missing slash produces wrong path).
|
||||
# - Every repo calls `composer test` regardless of the `tests` input; the
|
||||
# input only controls environment provisioning, not the command.
|
||||
# - permissions: contents: read at workflow level; the phpcs job sets
|
||||
# contents: write for phpcbf commit-back only. Calling workflows do NOT
|
||||
# need to declare contents: write — job-level override is sufficient.
|
||||
# - permissions: the phpcs job declares `contents: write` at job level for
|
||||
# phpcbf commit-back. GitHub requires the CALLING WORKFLOW to also declare
|
||||
# `permissions: contents: write` at the caller's workflow level — GH enforces
|
||||
# that callers cannot be escalated beyond their declared scope, even by job-level
|
||||
# overrides in the reusable workflow. All caller repos must include this.
|
||||
##
|
||||
|
||||
name: CI — Reusable
|
||||
@@ -100,9 +102,6 @@ on:
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: read # jobs that need write declare it explicitly (phpcs)
|
||||
|
||||
jobs:
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user