Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 35 additions & 56 deletions .github/examples/workflow-consumption-wordpress-plugin.yml
Original file line number Diff line number Diff line change
@@ -1,81 +1,60 @@
# Example: Using LightSpeed reusable workflows in a WordPress block plugin
# Example: CI for a WordPress block plugin
#
# Place this in: .github/workflows/ci.yml (in your wordpress-block-plugin repo)
# Place this in: .github/workflows/ci.yml (in your plugin repo, e.g. one
# generated from lightspeedwp/block-plugin-scaffold).
#
# This example shows how to consume reusable workflows from lightspeedwp/.github
# - Every action is pinned to a full commit SHA with its version as a
# comment; let Dependabot (github-actions ecosystem) keep the pins current.
# - `npm ci` and the npm cache need a committed `package-lock.json`. The
# scaffold's .gitignore excludes it: remove that line, run `npm install`
# and commit the lockfile before enabling this workflow.
# - Organisation reusable workflows from lightspeedwp/.github are not
# available yet (tracked in #3480). Once they are, call them with
# `uses: lightspeedwp/.github/.github/workflows/<file>.yml@<sha>`.

name: Plugin CI/CD
name: Plugin CI

on:
push:
branches: [main, develop]
paths:
- '**.js'
- '**.php'
- 'package.json'
- 'composer.json'
pull_request:
branches: [main, develop]
workflow_dispatch:

jobs:
# Run AI feedback validation on PRs
ai-feedback:
if: github.event_name == 'pull_request'
uses: lightspeedwp/.github/workflows/ai-feedback-validation@main
with:
context: wordpress-plugin
severity: warning
secrets:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Run integration tests using PR creation agent
integration-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
permissions:
contents: read

# Use the reusable workflow if it supports your test setup
- name: Run integration tests
uses: lightspeedwp/.github/workflows/pr-creation-agent-integration-tests@main
secrets:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

# PHP linting
jobs:
php-lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
php-version: '8.1'
- run: composer install
persist-credentials: false
- uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
with:
# Use a PHP release in active support that your plugin supports.
php-version: '8.4'
tools: composer
- run: composer install --no-interaction --no-progress
- run: composer run lint

# JavaScript linting
js-lint:
js-lint-and-test:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- run: npm ci --ignore-scripts --no-audit --no-fund
- run: npm run lint

# Phase progression (on main branch pushes)
update-phase:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: lightspeedwp/.github/workflows/orchestrate-phase-progression@main
with:
repo-context: wordpress-plugin
secrets:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: npm test
76 changes: 34 additions & 42 deletions .github/examples/workflow-consumption-wordpress-theme.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# Example: Using LightSpeed reusable workflows in a WordPress block theme
# Example: CI for a WordPress block theme
#
# Place this in: .github/workflows/ci.yml (in your wordpress-block-theme repo)
# Place this in: .github/workflows/ci.yml (in your theme repo, e.g. one
# generated from lightspeedwp/block-theme-scaffold).
#
# This example shows how to consume reusable workflows from lightspeedwp/.github
# - Every action is pinned to a full commit SHA with its version as a
# comment; let Dependabot (github-actions ecosystem) keep the pins current.
# - `npm ci` and the npm cache need a committed `package-lock.json`. The
# scaffold's .gitignore excludes it: remove that line, run `npm install`
# and commit the lockfile before enabling this workflow.
# - Organisation reusable workflows from lightspeedwp/.github are not
# available yet (tracked in #3480). Once they are, call them with
# `uses: lightspeedwp/.github/.github/workflows/<file>.yml@<sha>`.

name: CI/CD Pipeline
name: Theme CI

on:
push:
Expand All @@ -13,50 +21,34 @@ on:
branches: [main, develop]
workflow_dispatch:

jobs:
# Validate issue labels (if this is a PR)
validate-labels:
if: github.event_name == 'pull_request'
uses: lightspeedwp/.github/workflows/validate-issue-labels@main
# Note: workflow must be public or you must have access to lightspeedwp/.github

# Collect AI feedback on PR changes
ai-feedback:
if: github.event_name == 'pull_request'
uses: lightspeedwp/.github/workflows/ai-feedback-validation@main
with:
context: wordpress-theme
secrets:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
permissions:
contents: read

# Run orchestrated phase progression (if applicable to your project)
phase-progression:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: lightspeedwp/.github/workflows/orchestrate-phase-progression@main
with:
repo-context: wordpress-theme
secrets:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

# Your custom jobs below
lint:
jobs:
lint-and-test:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- run: npm run lint

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
cache: npm
- run: npm ci
# The scaffold's `npm run lint` and `npm test` also run `composer run
# lint` (phpcs) and `composer run test` (phpunit), so PHP and the
# Composer dependencies must be installed first.
- uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
with:
# Use a PHP release in active support that your theme supports.
php-version: '8.4'
tools: composer
- run: composer install --no-interaction --no-progress
- run: npm ci --ignore-scripts --no-audit --no-fund
Comment thread
eleshar marked this conversation as resolved.
Resolved
- run: npm run lint
Comment thread
eleshar marked this conversation as resolved.
Resolved
- run: npm test
12 changes: 6 additions & 6 deletions .github/workflows/branch-name-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
id: extract-branch
run: |
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT"

# Branch names can contain shell metacharacters ($, parentheses), so
# every value derived from them is passed through env, never inlined.
Expand Down Expand Up @@ -78,16 +78,16 @@ jobs:
ERRORS=$(echo "$OUTPUT" | jq -r '.errors | join(", ")')
SUGGESTED=$(echo "$OUTPUT" | jq -r '.suggested_name // empty')

echo "valid=$VALID" >> $GITHUB_OUTPUT
[ -n "$ERRORS" ] && echo "errors=$ERRORS" >> $GITHUB_OUTPUT
[ -n "$SUGGESTED" ] && echo "suggested_name=$SUGGESTED" >> $GITHUB_OUTPUT
echo "valid=$VALID" >> "$GITHUB_OUTPUT"
[ -n "$ERRORS" ] && echo "errors=$ERRORS" >> "$GITHUB_OUTPUT"
[ -n "$SUGGESTED" ] && echo "suggested_name=$SUGGESTED" >> "$GITHUB_OUTPUT"
else
# Fallback: simple string matching
echo "Using fallback parsing"
if echo "$OUTPUT" | grep -q '"valid": true'; then
echo "valid=true" >> $GITHUB_OUTPUT
echo "valid=true" >> "$GITHUB_OUTPUT"
else
echo "valid=false" >> $GITHUB_OUTPUT
echo "valid=false" >> "$GITHUB_OUTPUT"
fi
fi

Expand Down
18 changes: 16 additions & 2 deletions .github/workflows/branch-validation-metrics-aggregator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,24 @@ jobs:
- name: Prune old metrics artifacts
shell: bash
run: |
set -euo pipefail
keep=30
mapfile -t stale < <(find metrics-artifacts -maxdepth 1 -type f -name '*.json' -printf '%T@\t%p\n' 2>/dev/null | sort -rn -k1,1 -k2,2 | tail -n +$((keep + 1)) | cut -f2- || true)
if [ ! -d metrics-artifacts ]; then
echo "No metrics-artifacts directory; nothing to prune."
exit 0
fi
# Newest first by filename: names start with a UTC timestamp
# (YYYYMMDD-HHMMSS-<run id>.json). mtime is useless here because
# checkout gives every file the same one. The pipeline runs
# synchronously into a NUL-delimited file so a failure fails this
# step (process substitution would hide it).
list=$(mktemp)
find metrics-artifacts -maxdepth 1 -type f -name '*.json' -print0 \
| sort -z -r | tail -z -n +$((keep + 1)) > "$list"
mapfile -d '' -t stale < "$list"
rm -f -- "$list"
if [ "${#stale[@]}" -gt 0 ]; then
printf '%s\n' "${stale[@]}" | xargs rm -f --
rm -f -- "${stale[@]}"
echo "Pruned ${#stale[@]} artifact(s), kept latest $keep."
else
echo "Nothing to prune (≤ $keep artifacts present)."
Expand Down
42 changes: 24 additions & 18 deletions .github/workflows/changelog-unified.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,14 @@ jobs:
cd .github/validation/changelog

if [ "$CHANGELOG_CHANGED" == "false" ]; then
echo "passed=0" >> $GITHUB_OUTPUT
echo "failed=0" >> $GITHUB_OUTPUT
echo "warnings=0" >> $GITHUB_OUTPUT
echo "new_failed=0" >> $GITHUB_OUTPUT
echo "base_failed=0" >> $GITHUB_OUTPUT
echo "result=No changelog files modified in this PR" >> $GITHUB_OUTPUT
{
echo "passed=0"
echo "failed=0"
echo "warnings=0"
echo "new_failed=0"
echo "base_failed=0"
echo "result=No changelog files modified in this PR"
} >> "$GITHUB_OUTPUT"
exit 0
fi

Expand All @@ -245,21 +247,25 @@ jobs:
RESULT=$(jq -r '.recommendation' validation-report.json)
GATE_RESULT=$(jq -r '.ci_gate_result' validation-report.json)

echo "passed=$PASSED" >> $GITHUB_OUTPUT
echo "failed=$FAILED" >> $GITHUB_OUTPUT
echo "warnings=0" >> $GITHUB_OUTPUT
echo "result=$RESULT" >> $GITHUB_OUTPUT
echo "gate_result=$GATE_RESULT" >> $GITHUB_OUTPUT
{
echo "passed=$PASSED"
echo "failed=$FAILED"
echo "warnings=0"
echo "result=$RESULT"
echo "gate_result=$GATE_RESULT"
} >> "$GITHUB_OUTPUT"

cp validation-report.json ../../../.github/reports/validation-audits/latest-report.json 2>/dev/null || true
else
echo "❌ Validation report missing or malformed; failing closed"
[ -f validation-stderr.log ] && cat validation-stderr.log
echo "passed=0" >> $GITHUB_OUTPUT
echo "failed=1" >> $GITHUB_OUTPUT
echo "warnings=0" >> $GITHUB_OUTPUT
echo "result=ERROR" >> $GITHUB_OUTPUT
echo "gate_result=fail" >> $GITHUB_OUTPUT
{
echo "passed=0"
echo "failed=1"
echo "warnings=0"
echo "result=ERROR"
echo "gate_result=fail"
} >> "$GITHUB_OUTPUT"
FAILED=1
GATE_RESULT=fail
fi
Expand All @@ -286,8 +292,8 @@ jobs:
NEW_FAILED=$((FAILED - BASE_FAILED))
if [ "$NEW_FAILED" -lt 0 ]; then NEW_FAILED=0; fi

echo "base_failed=$BASE_FAILED" >> $GITHUB_OUTPUT
echo "new_failed=$NEW_FAILED" >> $GITHUB_OUTPUT
echo "base_failed=$BASE_FAILED" >> "$GITHUB_OUTPUT"
echo "new_failed=$NEW_FAILED" >> "$GITHUB_OUTPUT"
echo "PR failures: $FAILED, base failures: $BASE_FAILED, new: $NEW_FAILED"

# Gate on new failures only; pre-existing Unreleased debt never blocks.
Expand Down
21 changes: 14 additions & 7 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ jobs:
if: contains(fromJson('["all", "staleness"]'), env.AUDIT_SCOPE)
run: |
echo "Checking for stale README files (>6 months old)..."
find . -name "README.md" -type f | while read file; do
find . -name "README.md" -type f | while read -r file; do
echo "Checking staleness for $file..."
done

Expand Down Expand Up @@ -465,10 +465,17 @@ jobs:

- name: Maintenance summary
if: always()
env:
JOB_STATUS: ${{ job.status }}
HAS_CHANGES: ${{ steps.changes.outputs.has_changes }}
run: |
echo "## Documentation Maintenance Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Status**: ${{ job.status }}" >> $GITHUB_STEP_SUMMARY
echo "**Scope**: ${{ env.AUDIT_SCOPE }}" >> $GITHUB_STEP_SUMMARY
echo "**Dry Run**: ${{ env.DRY_RUN }}" >> $GITHUB_STEP_SUMMARY
echo "**Changes Made**: ${{ steps.changes.outputs.has_changes }}" >> $GITHUB_STEP_SUMMARY
# AUDIT_SCOPE and DRY_RUN are already job env; read them as shell
# variables rather than inlining expressions into the script.
{
echo "## Documentation Maintenance Summary"
echo ""
echo "**Status**: $JOB_STATUS"
echo "**Scope**: $AUDIT_SCOPE"
echo "**Dry Run**: $DRY_RUN"
echo "**Changes Made**: $HAS_CHANGES"
} >> "$GITHUB_STEP_SUMMARY"
Loading
Loading