name: CI on: push: branches: [ main ] pull_request: branches: [ main ] permissions: contents: read env: PYTHONIOENCODING: utf-8 PYTHONUTF8: "1" jobs: validate: name: Lint & Verify (${{ matrix.os }}, Python ${{ matrix.python-version }}) strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ["3.11", "3.12"] runs-on: ${{ matrix.os }} timeout-minutes: 20 steps: - name: Checkout repository uses: actions/checkout@v4 env: GIT_CONFIG_COUNT: "1" GIT_CONFIG_KEY_0: "core.autocrlf" GIT_CONFIG_VALUE_0: "false" with: persist-credentials: false - name: Set up Python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Verify accessible SVG contract if: always() id: a11y run: python scripts/test-lint-a11y.py - name: Verify semantic pattern documentation if: always() id: semantic_docs run: python scripts/verify-semantic-motion.py --markdown-only - name: Verify animated example structure if: always() id: animated_example run: python scripts/verify-semantic-motion.py --example-only - name: Lint animated example skin if: always() id: animated_lint run: python scripts/lint-skin.py skills/diagram-design/assets/example-policy-trace-animated.html - name: Verify every shipped motion file if: always() id: shipped_motion run: python scripts/verify-motion.py --shipped - name: Verify URL SVG normalization if: always() id: url_icons run: python scripts/test-build-icons-quoted-attributes.py - name: Verify Devicon normalization if: always() id: devicon run: python scripts/test-build-icons-devicon.py - name: Verify mojibake repair utility if: always() id: mojibake run: python scripts/test-fix-mojibake.py - name: Run skin linter if: always() id: skin run: python scripts/lint-skin.py --all --baseline - name: Verify sequence OAuth specs if: always() id: oauth run: python scripts/verify-sequence-oauth.py - name: Verify draw.io import script if: always() id: drawio run: python scripts/verify-drawio-import.py - name: Verify Mermaid import script if: always() id: mermaid run: python scripts/verify-mermaid-import.py - name: Verify optional motion contract if: always() id: motion run: python scripts/test-verify-motion.py - name: Verify generated icon assets if: always() id: icons shell: bash run: | python scripts/build-icons.py git diff --ignore-space-at-eol --exit-code -- \ skills/diagram-design/assets/icons.html \ skills/diagram-design/references/primitive-icons.md - name: Generate CI execution summary table if: always() shell: bash run: | echo "### 📊 CI Verification Summary (${{ matrix.os }}, Python ${{ matrix.python-version }})" >> $GITHUB_STEP_SUMMARY echo "| Verification Gate | Outcome |" >> $GITHUB_STEP_SUMMARY echo "|---|---|" >> $GITHUB_STEP_SUMMARY echo "| SVG Accessibility Contract | ${{ steps.a11y.outcome == 'success' && '✅ Passed' || (steps.a11y.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Semantic Pattern Documentation | ${{ steps.semantic_docs.outcome == 'success' && '✅ Passed' || (steps.semantic_docs.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Animated Example Structure | ${{ steps.animated_example.outcome == 'success' && '✅ Passed' || (steps.animated_example.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Animated Example Skin | ${{ steps.animated_lint.outcome == 'success' && '✅ Passed' || (steps.animated_lint.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Shipped Motion HTML | ${{ steps.shipped_motion.outcome == 'success' && '✅ Passed' || (steps.shipped_motion.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| URL SVG Normalization | ${{ steps.url_icons.outcome == 'success' && '✅ Passed' || (steps.url_icons.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Devicon Normalization | ${{ steps.devicon.outcome == 'success' && '✅ Passed' || (steps.devicon.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Mojibake Repair Utility | ${{ steps.mojibake.outcome == 'success' && '✅ Passed' || (steps.mojibake.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Color Palette & Skin Linter | ${{ steps.skin.outcome == 'success' && '✅ Passed' || (steps.skin.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Sequence Diagram Grammar | ${{ steps.oauth.outcome == 'success' && '✅ Passed' || (steps.oauth.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Draw.io Import Extractor | ${{ steps.drawio.outcome == 'success' && '✅ Passed' || (steps.drawio.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Mermaid Import Extractor | ${{ steps.mermaid.outcome == 'success' && '✅ Passed' || (steps.mermaid.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Optional Motion Contract | ${{ steps.motion.outcome == 'success' && '✅ Passed' || (steps.motion.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY echo "| Primitive Icons & Documentation | ${{ steps.icons.outcome == 'success' && '✅ Passed' || (steps.icons.outcome == 'skipped' && '⏭️ Skipped' || '❌ Failed') }} |" >> $GITHUB_STEP_SUMMARY