From 6adf255deaeb6fd5acbc2a18ce0aac3a714b5081 Mon Sep 17 00:00:00 2001 From: peptiderepo Date: Tue, 16 Jun 2026 12:01:53 +0000 Subject: [PATCH] fix(ci): P2-A injection, P2-B lint-js fallback, P2-C phpcs config detection P2-A: move ${{ inputs.line_limit_paths }} from raw shell into env: block (PATHS) to eliminate template-injection surface on caller-controlled input. P2-B: replace 'npm run lint --if-present' (always exits 0 on missing script, killing the node --check fallback) with explicit node -e detection; fallback now actually runs when no lint npm script is defined. P2-C: both phpcbf and phpcs steps now detect which of phpcs.xml / phpcs.xml.dist / .phpcs.xml.dist is present and pass it to --standard; guard and command now agree for all three config filename variants. Validators: actionlint 1.7.4 clean, yamllint 1.38.0 clean (both files). Version: 1.6.1 Agent-Session: claude/reusable-ci-20260616-p2-fixes --- .github/workflows/ci.yml | 40 ++++++++++++++++++++++++++++++---------- CHANGELOG.md | 16 ++++++++++++++++ 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e899f5..03d5e73 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -175,11 +175,18 @@ jobs: # trigger a new CI run — GitHub prevents loops on bot commits. if: ${{ github.event_name == 'pull_request' && inputs.phpcs_autofix }} run: | - if [ ! -f phpcs.xml ] && [ ! -f phpcs.xml.dist ] && [ ! -f .phpcs.xml.dist ]; then - echo "No phpcs.xml — phpcbf skipped." + # Detect which phpcs config file is present; pass it explicitly to + # --standard so phpcbf and phpcs always agree with the guard check. + PHPCS_CONFIG="" + if [ -f phpcs.xml ]; then PHPCS_CONFIG="phpcs.xml" + elif [ -f phpcs.xml.dist ]; then PHPCS_CONFIG="phpcs.xml.dist" + elif [ -f .phpcs.xml.dist ]; then PHPCS_CONFIG=".phpcs.xml.dist" + fi + if [ -z "$PHPCS_CONFIG" ]; then + echo "No phpcs.xml / phpcs.xml.dist / .phpcs.xml.dist — phpcbf skipped." exit 0 fi - phpcbf --standard=phpcs.xml \ + phpcbf --standard="$PHPCS_CONFIG" \ --extensions=php \ --ignore=vendor/*,tests/*,node_modules/* \ . || true @@ -195,14 +202,20 @@ jobs: # Runs on all events (push AND pull_request). After phpcbf has committed # any auto-fixable issues on PRs, only non-auto-fixable violations land # here. On push events phpcbf is skipped but phpcs is still strict. - # Guard: skip gracefully if no phpcs.xml exists (repo not yet configured). + # Guard: skip gracefully if no phpcs config file exists (repo not yet configured). run: | - if [ ! -f phpcs.xml ] && [ ! -f phpcs.xml.dist ] && [ ! -f .phpcs.xml.dist ]; then + # Detect which phpcs config file is present (mirrors the phpcbf step above). + PHPCS_CONFIG="" + if [ -f phpcs.xml ]; then PHPCS_CONFIG="phpcs.xml" + elif [ -f phpcs.xml.dist ]; then PHPCS_CONFIG="phpcs.xml.dist" + elif [ -f .phpcs.xml.dist ]; then PHPCS_CONFIG=".phpcs.xml.dist" + fi + if [ -z "$PHPCS_CONFIG" ]; then echo "No phpcs.xml / phpcs.xml.dist / .phpcs.xml.dist found — PHPCS skipped." echo "Add a phpcs.xml to enable coding standards enforcement." exit 0 fi - phpcs --standard=phpcs.xml \ + phpcs --standard="$PHPCS_CONFIG" \ --extensions=php \ --ignore=vendor/*,tests/*,node_modules/* \ --warning-severity=0 \ @@ -223,9 +236,11 @@ jobs: # Scans only tracked *.php files under line_limit_paths (not vendor etc.). # Prints every offender with its line count, then fails the job so the # engineer has a clear list to split. + env: + # Use env: block to avoid shell-injection from caller-controlled input. + PATHS: ${{ inputs.line_limit_paths }} run: | set -e - PATHS="${{ inputs.line_limit_paths }}" OFFENDERS="" for DIR in $PATHS; do if [ ! -e "$DIR" ]; then @@ -355,11 +370,16 @@ jobs: - name: Lint JavaScript # Prefer `npm run lint` if the repo defines it (catches ESLint etc.). # Fall back to `node --check` syntax-only scan on all *.js files. + # NOTE: `npm run lint --if-present` exits 0 even when no lint script + # exists (npm 10+ / ubuntu-latest Node 20 behaviour), so the fallback + # branch is dead code under --if-present. Instead, explicitly detect + # whether a lint script is declared and branch on that. run: | - if npm run lint --if-present 2>/dev/null; then - echo "npm run lint executed." + if node -e "process.exit(require('./package.json').scripts?.lint ? 0 : 1)" 2>/dev/null; then + echo "npm run lint script found — running it." + npm run lint else - echo "No 'lint' npm script — falling back to node --check syntax scan." + echo "No 'lint' npm script — running node --check syntax scan." find . -name '*.js' \ -not -path './vendor/*' \ -not -path './node_modules/*' \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 41091c2..0e57d37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to the peptide-e2e smoke suite will be documented here. ## [1.6.0] - 2026-06-16 +## [1.6.1] - 2026-06-16 + +### Fixed +- **P2-A injection** (`ci.yml:239`): `${{ inputs.line_limit_paths }}` moved + from raw shell assignment into an `env:` block (`PATHS`); shell now reads + `$PATHS` — eliminates template-injection surface for caller-supplied input. +- **P2-B lint-js fallback** (`ci.yml:378`): replaced `npm run lint --if-present` + (exits 0 when no lint script exists, killing the fallback branch) with + explicit `node -e "process.exit(…)"` detection; `node --check` scan now + actually runs when no `lint` npm script is defined. +- **P2-C phpcs config mismatch** (`ci.yml:178-199, 206-223`): both phpcbf + and phpcs steps now detect which of `phpcs.xml` / `phpcs.xml.dist` / + `.phpcs.xml.dist` is present and pass that file to `--standard`; guard and + command now agree for all three variants. + + ### Added - **Reusable CI workflow** (`.github/workflows/ci.yml`). `on: workflow_call` entrypoint that every estate repo will adopt as a thin