feat: complete cross-platform CLI portability (Gemini + Codex) #63
Workflow file for this run
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
| name: Validate PR | |
| on: | |
| pull_request: | |
| paths: | |
| - 'plugins/**' | |
| - '.claude-plugin/marketplace.json' | |
| - '.claude/skills/**' | |
| - '.gemini-extensions/**' | |
| - '.codex-marketplace/**' | |
| - 'scripts/**' | |
| - '.version-bump.json' | |
| - 'docs/**' | |
| - '*.md' | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| detect-changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| plugins: ${{ steps.filter.outputs.plugins }} | |
| skills: ${{ steps.filter.outputs.skills }} | |
| research: ${{ steps.filter.outputs.research }} | |
| docs: ${{ steps.filter.outputs.docs }} | |
| shims: ${{ steps.filter.outputs.shims }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Detect changed paths | |
| uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 | |
| id: filter | |
| with: | |
| filters: | | |
| plugins: | |
| - 'plugins/**' | |
| - '.claude-plugin/marketplace.json' | |
| - '.claude/skills/**' | |
| skills: | |
| - 'plugins/**/skills/**' | |
| - '.claude/skills/**' | |
| research: | |
| - 'docs/research/**' | |
| docs: | |
| - 'docs/**' | |
| - 'plugins/**' | |
| - '*.md' | |
| shims: | |
| - 'plugins/**/skills/**' | |
| - 'plugins/**/commands/**' | |
| - 'plugins/**/.claude-plugin/plugin.json' | |
| - 'plugins/**/README.md' | |
| - '.claude-plugin/marketplace.json' | |
| - '.gemini-extensions/**' | |
| - '.codex-marketplace/**' | |
| - 'scripts/build-shims.sh' | |
| - 'scripts/transpile-commands.py' | |
| - 'scripts/generate-codex-agents-md.py' | |
| - 'scripts/update-plugin-readmes.py' | |
| validate-plugins: | |
| name: Plugin Validation | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.plugins == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install PyYAML | |
| run: pip install pyyaml | |
| - name: Run plugin validation | |
| run: | | |
| python3 .claude/skills/plugin-release-checker/scripts/check_release_readiness.py \ | |
| --all --format text | |
| validate-skills-full: | |
| name: Skill Quality (Full) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.skills == 'true' | |
| runs-on: ubuntu-latest | |
| # PHASE: warning-only (remove continue-on-error when skills are clean at warning level) | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install PyYAML | |
| run: pip install pyyaml | |
| - name: Run skill validator (all severities) | |
| run: | | |
| python3 .claude/skills/plugin-release-checker/scripts/check_release_readiness.py \ | |
| --all --skill-severity warning --format text | |
| validate-research-docs: | |
| name: Research Docs | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.research == 'true' | |
| runs-on: ubuntu-latest | |
| # PHASE: warning-only (remove continue-on-error when docs/research/ is clean) | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Full history for git log dates | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install PyYAML | |
| run: pip install pyyaml | |
| - name: Validate research documents | |
| run: | | |
| python3 plugins/doc/skills/research-frontmatter/scripts/validate_research_docs.py \ | |
| --format text | |
| validate-cross-references: | |
| name: Cross-Reference Integrity | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.docs == 'true' | |
| runs-on: ubuntu-latest | |
| # PHASE: warning-only (remove continue-on-error when cross-refs are clean) | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Check markdown link integrity | |
| run: | | |
| python3 .claude/skills/plugin-release-checker/scripts/validate_cross_references.py \ | |
| --format text | |
| validate-staleness: | |
| name: Staleness Detection | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.docs == 'true' | |
| runs-on: ubuntu-latest | |
| # PHASE: warning-only (remove continue-on-error when staleness is addressed) | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Full history for git log dates | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install PyYAML | |
| run: pip install pyyaml | |
| - name: Check research doc staleness | |
| run: | | |
| python3 plugins/doc/skills/research-frontmatter/scripts/validate_research_docs.py \ | |
| --staleness-only --format text | |
| - name: Check reference doc staleness | |
| run: | | |
| python3 .claude/skills/plugin-release-checker/scripts/validate_reference_staleness.py \ | |
| --format text | |
| doc-freshness: | |
| name: Doc Freshness (Action) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.docs == 'true' | |
| runs-on: ubuntu-latest | |
| # PHASE 1: advisory-only (remove continue-on-error once validated) | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Run documentation health checks | |
| uses: joaquimscosta/docs-health-action@v1 | |
| with: | |
| checks: 'links,versions,staleness,claude-md' | |
| fail-on: 'errors' | |
| shim-drift: | |
| name: Shim Drift Check | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.shims == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install jq | |
| run: sudo apt-get update && sudo apt-get install -y jq | |
| - name: Regenerate shims | |
| run: bash scripts/build-shims.sh | |
| - name: Verify shims are in sync | |
| run: | | |
| if ! git diff --exit-code .gemini-extensions/ .codex-marketplace/ plugins/*/README.md; then | |
| echo "::error::Shim drift detected. Run 'bash scripts/build-shims.sh' locally and commit the result." | |
| exit 1 | |
| fi | |
| echo "Shims are in sync with canonical sources." | |
| - name: Verify intra-plugin version sync (Claude/Gemini/Codex per plugin) | |
| run: | | |
| # `bump-version.sh --check` without --plugin treats cross-plugin | |
| # version differences as informational. To catch a plugin whose 3 | |
| # manifests have drifted out of sync, run --check per plugin. | |
| failed_plugins=() | |
| while IFS= read -r plugin; do | |
| if ! bash scripts/bump-version.sh --plugin "$plugin" --check >/dev/null 2>&1; then | |
| echo "::error::Plugin '$plugin' has version drift across its 3 manifests. Run 'bash scripts/bump-version.sh --plugin $plugin --check' locally for details." | |
| failed_plugins+=("$plugin") | |
| fi | |
| done < <(jq -r '.files[].plugin' .version-bump.json | sort -u) | |
| if [[ ${#failed_plugins[@]} -gt 0 ]]; then | |
| echo "Drifted plugins: ${failed_plugins[*]}" | |
| exit 1 | |
| fi | |
| echo "All plugins are in version-sync across Claude/Gemini/Codex manifests." |