Add claude skills & agents #23
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| detect-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| ts-packages: ${{ steps.changes.outputs.ts-packages }} | |
| rust-packages: ${{ steps.changes.outputs.rust-packages }} | |
| python-packages: ${{ steps.changes.outputs.python-packages }} | |
| has-ts: ${{ steps.changes.outputs.has-ts }} | |
| has-rust: ${{ steps.changes.outputs.has-rust }} | |
| has-python: ${{ steps.changes.outputs.has-python }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect changed packages | |
| id: changes | |
| run: | | |
| if [ "${{ github.event_name }}" == "push" ] && [ "${{ github.ref }}" == "refs/heads/main" ]; then | |
| # On push to main, compare with previous commit | |
| BASE_SHA="${{ github.event.before }}" | |
| else | |
| # On PR, compare with base branch | |
| BASE_SHA="${{ github.event.pull_request.base.sha }}" | |
| fi | |
| # Get changed files | |
| CHANGED_FILES=$(git diff --name-only "$BASE_SHA" HEAD 2>/dev/null || echo "") | |
| # If we can't get diff (e.g., initial commit), run all | |
| if [ -z "$CHANGED_FILES" ]; then | |
| echo "Could not determine changed files, will run all tests" | |
| TS_PACKAGES=$(ls -d packages/*/ts 2>/dev/null | xargs -I{} dirname {} | xargs -I{} basename {} | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| RUST_PACKAGES=$(ls -d packages/*/rust 2>/dev/null | xargs -I{} dirname {} | xargs -I{} basename {} | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| PYTHON_PACKAGES=$(ls -d packages/*/python 2>/dev/null | xargs -I{} dirname {} | xargs -I{} basename {} | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| else | |
| # Extract unique package names for each language | |
| TS_PACKAGES=$(echo "$CHANGED_FILES" | grep -E '^packages/[^/]+/ts/' | sed 's|packages/\([^/]*\)/ts/.*|\1|' | sort -u | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| RUST_PACKAGES=$(echo "$CHANGED_FILES" | grep -E '^packages/[^/]+/rust/' | sed 's|packages/\([^/]*\)/rust/.*|\1|' | sort -u | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| PYTHON_PACKAGES=$(echo "$CHANGED_FILES" | grep -E '^packages/[^/]+/python/' | sed 's|packages/\([^/]*\)/python/.*|\1|' | sort -u | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| fi | |
| echo "ts-packages=$TS_PACKAGES" >> $GITHUB_OUTPUT | |
| echo "rust-packages=$RUST_PACKAGES" >> $GITHUB_OUTPUT | |
| echo "python-packages=$PYTHON_PACKAGES" >> $GITHUB_OUTPUT | |
| # Set boolean flags for whether each language has changes | |
| echo "has-ts=$( [ "$TS_PACKAGES" != "[]" ] && echo true || echo false )" >> $GITHUB_OUTPUT | |
| echo "has-rust=$( [ "$RUST_PACKAGES" != "[]" ] && echo true || echo false )" >> $GITHUB_OUTPUT | |
| echo "has-python=$( [ "$PYTHON_PACKAGES" != "[]" ] && echo true || echo false )" >> $GITHUB_OUTPUT | |
| echo "TypeScript packages: $TS_PACKAGES" | |
| echo "Rust packages: $RUST_PACKAGES" | |
| echo "Python packages: $PYTHON_PACKAGES" | |
| test-typescript: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.has-ts == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| - name: Install dependencies | |
| run: bun ci | |
| - name: Build and test changed packages | |
| run: | | |
| TS_PACKAGES='${{ needs.detect-changes.outputs.ts-packages }}' | |
| echo "$TS_PACKAGES" | jq -r '.[]' | while read -r pkg; do | |
| echo "==> $pkg" | |
| if [ -d "packages/$pkg/ts" ]; then | |
| ( | |
| cd "packages/$pkg/ts" | |
| if jq -e '.scripts.build' package.json >/dev/null; then | |
| bun run build | |
| else | |
| echo "No build script found, skipping" | |
| fi | |
| if jq -e '.scripts.test' package.json >/dev/null; then | |
| bun run test | |
| else | |
| echo "No test script found, skipping" | |
| fi | |
| ) | |
| else | |
| echo "Package path packages/$pkg/ts not found" | |
| exit 1 | |
| fi | |
| done | |
| test-rust: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.has-rust == 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| toolchain: [stable, beta, '1.78'] | |
| package: ${{ fromJson(needs.detect-changes.outputs.rust-packages) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Rust ${{ matrix.toolchain }} | |
| uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: ${{ matrix.toolchain }} | |
| components: rustfmt, clippy | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry/ | |
| ~/.cargo/git/ | |
| target/ | |
| key: cargo-${{ runner.os }}-${{ matrix.toolchain }}-${{ matrix.package }}-${{ hashFiles(format('packages/{0}/rust/Cargo.toml', matrix.package)) }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ matrix.toolchain }}-${{ matrix.package }}- | |
| cargo-${{ runner.os }}-${{ matrix.toolchain }}- | |
| - name: Check formatting | |
| working-directory: packages/${{ matrix.package }}/rust | |
| run: cargo fmt -- --check | |
| - name: Clippy | |
| working-directory: packages/${{ matrix.package }}/rust | |
| run: cargo clippy --all-targets --all-features -- -D warnings | |
| - name: Build | |
| working-directory: packages/${{ matrix.package }}/rust | |
| run: cargo build --all-targets | |
| - name: Test | |
| working-directory: packages/${{ matrix.package }}/rust | |
| run: cargo test | |
| test-python: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.has-python == 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] | |
| package: ${{ fromJson(needs.detect-changes.outputs.python-packages) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: 'pip' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install ruff pytest pytest-cov build | |
| - name: Install package | |
| working-directory: packages/${{ matrix.package }}/python | |
| run: pip install -e . | |
| - name: Lint with ruff | |
| working-directory: packages/${{ matrix.package }}/python | |
| run: ruff check . | |
| - name: Test with pytest | |
| working-directory: packages/${{ matrix.package }}/python | |
| run: | | |
| if [ -d "tests" ]; then | |
| pytest tests -v | |
| else | |
| echo "No tests directory found, skipping" | |
| fi | |
| ci-success: | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes, test-typescript, test-rust, test-python] | |
| if: | | |
| needs.detect-changes.result == 'success' && ( | |
| needs.detect-changes.outputs.has-ts == 'true' || | |
| needs.detect-changes.outputs.has-rust == 'true' || | |
| needs.detect-changes.outputs.has-python == 'true' | |
| ) | |
| steps: | |
| - name: Check CI status | |
| run: | | |
| if [[ "${{ needs.detect-changes.result }}" != "success" ]]; then | |
| echo "detect-changes failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.detect-changes.outputs.has-ts }}" == "true" ]] && \ | |
| [[ "${{ needs.test-typescript.result }}" != "success" ]]; then | |
| echo "TypeScript tests did not succeed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.detect-changes.outputs.has-rust }}" == "true" ]] && \ | |
| [[ "${{ needs.test-rust.result }}" != "success" ]]; then | |
| echo "Rust tests did not succeed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.detect-changes.outputs.has-python }}" == "true" ]] && \ | |
| [[ "${{ needs.test-python.result }}" != "success" ]]; then | |
| echo "Python tests did not succeed" | |
| exit 1 | |
| fi | |
| echo "All required checks passed" |