name: CI on: push: branches: [main] pull_request: branches: - main - "v[0-9]*.[0-9]*.x" # Match version branches like v0.13.x, v1.0.x, etc. release: types: [created] # Cancel previous runs on same PR concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true env: CARGO_TERM_COLOR: always jobs: pre-commit-checks: name: "Cargo fmt, typos" runs-on: self-hosted timeout-minutes: 30 steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false installCommand: nix profile install nixpkgs#cachix continue-on-error: true - name: Cargo fmt run: nix develop -i -L .#stable --command cargo fmt --check - name: typos run: nix develop -i -L .#stable --command typos # Discover example checks from flake - single source of truth discover-examples: name: "Discover examples" runs-on: self-hosted timeout-minutes: 5 outputs: examples: ${{ steps.examples.outputs.examples }} steps: - name: checkout uses: actions/checkout@v4 - name: Get example check names id: examples run: | # Get all example check names (prefixed with "example-") examples=$(nix eval .#checks.x86_64-linux --apply 'attrs: builtins.filter (n: builtins.substring 0 8 n == "example-") (builtins.attrNames attrs)' --json) echo "examples=$examples" >> $GITHUB_OUTPUT echo "Found examples: $examples" examples: name: "Example: ${{ matrix.example }}" runs-on: self-hosted timeout-minutes: 30 needs: [pre-commit-checks, discover-examples] strategy: fail-fast: true matrix: example: ${{ fromJson(needs.discover-examples.outputs.examples) }} steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Build example run: nix build -L .#${{ matrix.example }} - name: Run example run: | # Extract binary name by removing "example-" prefix BINARY_NAME="${{ matrix.example }}" BINARY_NAME="${BINARY_NAME#example-}" ./result/bin/$BINARY_NAME # Discover clippy checks from flake - single source of truth discover-checks: name: "Discover clippy checks" runs-on: self-hosted timeout-minutes: 5 outputs: checks: ${{ steps.checks.outputs.checks }} steps: - name: checkout uses: actions/checkout@v4 - name: Get clippy check names id: checks run: | # Get all check names except pre-commit-check, example-*, msrv-*, wasm-*, doc-tests, strict-docs, ffi-tests # Those have their own dedicated CI jobs checks=$(nix eval .#checks.x86_64-linux --apply 'attrs: builtins.filter (n: n != "pre-commit-check" && n != "doc-tests" && n != "strict-docs" && n != "ffi-tests" && builtins.substring 0 8 n != "example-" && builtins.substring 0 5 n != "msrv-" && builtins.substring 0 5 n != "wasm-") (builtins.attrNames attrs)' --json) echo "checks=$checks" >> $GITHUB_OUTPUT echo "Found checks: $checks" # Dynamic clippy matrix - uses cached deps from Cachix clippy: name: "Clippy: ${{ matrix.check }}" runs-on: self-hosted timeout-minutes: 30 needs: [pre-commit-checks, discover-checks] strategy: fail-fast: false matrix: check: ${{ fromJson(needs.discover-checks.outputs.checks) }} steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Run clippy check run: nix build -L .#checks.x86_64-linux.${{ matrix.check }} # Run tests using nix develop (tests need to execute, not just build) tests: name: "Tests" runs-on: self-hosted timeout-minutes: 30 needs: pre-commit-checks steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Run workspace tests run: nix develop -i -L .#stable --command bash -c "start-postgres && cargo test --workspace --exclude cdk-integration-tests" regtest-itest: name: "Integration regtest tests" runs-on: self-hosted timeout-minutes: 30 needs: pre-commit-checks strategy: fail-fast: true matrix: database: [SQLITE, POSTGRES] steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Test run: nix develop -i -L .#stable --command just itest ${{ matrix.database }} fake-mint-itest: name: "Integration fake mint tests" runs-on: self-hosted timeout-minutes: 30 needs: pre-commit-checks strategy: fail-fast: true matrix: build-args: [-p cdk-integration-tests] database: [SQLITE, POSTGRES] steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Test fake mint run: nix develop -i -L .#stable --command just fake-mint-itest ${{ matrix.database }} pure-itest: name: "Integration fake wallet tests" runs-on: self-hosted timeout-minutes: 30 needs: pre-commit-checks strategy: fail-fast: true matrix: database: [memory, sqlite, redb] steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Test fake mint run: nix develop -i -L .#stable --command just test-pure ${{ matrix.database }} - name: Test mint with PostgreSQL run: nix develop -i -L .#stable --command bash -c "start-postgres && just test" payment-processor-itests: name: "Payment processor tests" runs-on: self-hosted timeout-minutes: 30 needs: pre-commit-checks strategy: fail-fast: true matrix: ln: [FAKEWALLET, CLN, LND] steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Test run: nix develop -i -L .#stable --command just itest-payment-processor ${{matrix.ln}} # Discover MSRV checks from flake - single source of truth discover-msrv-checks: name: "Discover MSRV checks" runs-on: self-hosted timeout-minutes: 5 outputs: checks: ${{ steps.checks.outputs.checks }} steps: - name: checkout uses: actions/checkout@v4 - name: Get MSRV check names id: checks run: | # Get all MSRV check names (prefixed with "msrv-") checks=$(nix eval .#checks.x86_64-linux --apply 'attrs: builtins.filter (n: builtins.substring 0 5 n == "msrv-") (builtins.attrNames attrs)' --json) echo "checks=$checks" >> $GITHUB_OUTPUT echo "Found MSRV checks: $checks" msrv-build: name: "MSRV: ${{ matrix.check }}" runs-on: self-hosted timeout-minutes: 30 needs: [pre-commit-checks, discover-msrv-checks] strategy: fail-fast: true matrix: check: ${{ fromJson(needs.discover-msrv-checks.outputs.checks) }} steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Build run: nix build -L .#checks.x86_64-linux.${{ matrix.check }} # Discover WASM checks from flake - single source of truth discover-wasm-checks: name: "Discover WASM checks" runs-on: self-hosted timeout-minutes: 5 outputs: checks: ${{ steps.checks.outputs.checks }} steps: - name: checkout uses: actions/checkout@v4 - name: Get WASM check names id: checks run: | # Get all WASM check names (prefixed with "wasm-") checks=$(nix eval .#checks.x86_64-linux --apply 'attrs: builtins.filter (n: builtins.substring 0 5 n == "wasm-") (builtins.attrNames attrs)' --json) echo "checks=$checks" >> $GITHUB_OUTPUT echo "Found WASM checks: $checks" check-wasm: name: "WASM: ${{ matrix.check }}" runs-on: self-hosted timeout-minutes: 30 needs: [pre-commit-checks, discover-wasm-checks] strategy: fail-fast: true matrix: check: ${{ fromJson(needs.discover-wasm-checks.outputs.checks) }} steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Build WASM run: nix build -L .#checks.x86_64-linux.${{ matrix.check }} fake-mint-auth-itest: name: "Integration fake mint auth tests" runs-on: self-hosted timeout-minutes: 30 needs: pre-commit-checks strategy: fail-fast: true matrix: database: [SQLITE] steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Start Keycloak with Backup run: | docker compose -f misc/keycloak/docker-compose-recover.yml up -d until docker logs $(docker ps -q --filter "ancestor=quay.io/keycloak/keycloak:25.0.6") | grep "Keycloak 25.0.6 on JVM (powered by Quarkus 3.8.5) started"; do sleep 1; done - name: Verify Keycloak Import run: | # Wait a bit more for import to complete sleep 5 # Check if the realm endpoint is accessible (better verification than log grep) curl -f -s http://127.0.0.1:8080/realms/cdk-test-realm/.well-known/openid-configuration > /dev/null && echo "Keycloak realm successfully imported" || (docker logs $(docker ps -q --filter "ancestor=quay.io/keycloak/keycloak:25.0.6") && exit 1) - name: Test fake auth mint run: nix develop -i -L .#stable --command just fake-auth-mint-itest ${{ matrix.database }} http://127.0.0.1:8080/realms/cdk-test-realm/.well-known/openid-configuration - name: Stop and clean up Docker Compose run: | docker compose -f misc/keycloak/docker-compose-recover.yml down docs: name: "Documentation tests" runs-on: self-hosted timeout-minutes: 30 needs: pre-commit-checks steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Run doc tests run: nix build -L .#checks.x86_64-linux.doc-tests strict-docs: name: "Strict Documentation Check" runs-on: self-hosted timeout-minutes: 30 needs: docs steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Check docs with strict warnings run: nix build -L .#checks.x86_64-linux.strict-docs ffi-tests: name: "FFI Python tests" runs-on: self-hosted timeout-minutes: 30 needs: pre-commit-checks steps: - name: checkout uses: actions/checkout@v4 - uses: cachix/cachix-action@v16 with: name: cashudevkit authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} useDaemon: false continue-on-error: true - name: Run FFI tests run: nix build -L .#checks.x86_64-linux.ffi-tests