Rename projects to Nimblesite.* namespace, remove Gatekeeper and Samples #93
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: CI | |
| on: | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| DOTNET_VERSION: '9.0.x' | |
| DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true | |
| DOTNET_CLI_TELEMETRY_OPTOUT: true | |
| jobs: | |
| # Track 1: Format Check All -> Lint All -> DataProvider Tests | |
| lint-and-dataprovider: | |
| name: Lint + DataProvider Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt, clippy | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Cache NuGet packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.fsproj') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| - name: Cache Cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| Lql/lql-lsp-rust/target | |
| key: ${{ runner.os }}-cargo-lint-${{ hashFiles('Lql/lql-lsp-rust/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-lint- | |
| ${{ runner.os }}-cargo- | |
| - name: Restore .NET tools | |
| run: dotnet tool restore | |
| - name: Install Node dependencies (LQL Extension) | |
| run: cd Lql/LqlExtension && npm install --no-audit --no-fund | |
| - name: Format check | |
| run: make fmt-check | |
| - name: Lint | |
| run: make lint | |
| - name: Build CLI tools (needed by F# Type Provider MSBuild targets) | |
| run: | | |
| dotnet build Migration/Nimblesite.DataProvider.Migration.Cli -c Debug | |
| dotnet build DataProvider/Nimblesite.DataProvider.SQLite.Cli -c Debug | |
| - name: Test DataProvider (with coverage enforcement) | |
| run: | | |
| for proj in DataProvider/Nimblesite.DataProvider.Tests DataProvider/Nimblesite.DataProvider.Example.Tests; do | |
| THRESHOLD=$(jq -r ".projects[\"$proj\"].threshold // .default_threshold" coverage-thresholds.json) | |
| INCLUDE=$(jq -r ".projects[\"$proj\"].include // empty" coverage-thresholds.json) | |
| echo "==> Testing $proj (threshold: ${THRESHOLD}%)" | |
| rm -rf "$proj/TestResults" | |
| if [ -n "$INCLUDE" ]; then | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal \ | |
| -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="$INCLUDE" | |
| else | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal | |
| fi | |
| COBERTURA=$(find "$proj/TestResults" -name "coverage.cobertura.xml" -type f | head -1) | |
| if [ -z "$COBERTURA" ]; then echo "FAIL: No coverage file for $proj"; exit 1; fi | |
| LINE_RATE=$(sed -n 's/.*line-rate="\([0-9.]*\)".*/\1/p' "$COBERTURA" | head -1) | |
| COVERAGE=$(echo "$LINE_RATE * 100" | bc -l) | |
| COVERAGE_FMT=$(printf "%.2f" $COVERAGE) | |
| echo " Coverage: ${COVERAGE_FMT}% | Threshold: ${THRESHOLD}%" | |
| BELOW=$(echo "$COVERAGE < $THRESHOLD" | bc -l) | |
| if [ "$BELOW" = "1" ]; then | |
| echo " FAIL: ${COVERAGE_FMT}% is BELOW threshold ${THRESHOLD}%" | |
| exit 1 | |
| fi | |
| echo " PASS" | |
| done | |
| - name: Upload test results | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: test-results-dataprovider | |
| path: '**/TestResults/*.trx' | |
| # Track 2: Build All -> LQL Tests -> Migration Tests -> Sync Tests | |
| build-and-test: | |
| name: Build + LQL / Migration / Sync Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| services: | |
| postgres: | |
| image: postgres:16 | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: changeme | |
| POSTGRES_DB: postgres | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| env: | |
| DOTNET_CLI_DO_NOT_USE_MSBUILD_SERVER: 1 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install cargo-tarpaulin | |
| run: cargo install cargo-tarpaulin | |
| - name: Cache NuGet packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.fsproj') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| - name: Cache Cargo registry + build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| Lql/lql-lsp-rust/target | |
| key: ${{ runner.os }}-cargo-build-${{ hashFiles('Lql/lql-lsp-rust/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-build- | |
| ${{ runner.os }}-cargo- | |
| - name: Build .NET | |
| run: dotnet build DataProvider.sln -c Debug | |
| - name: Build Rust | |
| run: cd Lql/lql-lsp-rust && cargo build | |
| - name: Test LQL .NET (with coverage enforcement) | |
| run: | | |
| for proj in Lql/Nimblesite.Lql.Tests; do | |
| THRESHOLD=$(jq -r ".projects[\"$proj\"].threshold // .default_threshold" coverage-thresholds.json) | |
| INCLUDE=$(jq -r ".projects[\"$proj\"].include // empty" coverage-thresholds.json) | |
| echo "==> Testing $proj (threshold: ${THRESHOLD}%)" | |
| rm -rf "$proj/TestResults" | |
| if [ -n "$INCLUDE" ]; then | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal \ | |
| -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="$INCLUDE" | |
| else | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal | |
| fi | |
| COBERTURA=$(find "$proj/TestResults" -name "coverage.cobertura.xml" -type f | head -1) | |
| if [ -z "$COBERTURA" ]; then echo "FAIL: No coverage file for $proj"; exit 1; fi | |
| LINE_RATE=$(sed -n 's/.*line-rate="\([0-9.]*\)".*/\1/p' "$COBERTURA" | head -1) | |
| COVERAGE=$(echo "$LINE_RATE * 100" | bc -l) | |
| COVERAGE_FMT=$(printf "%.2f" $COVERAGE) | |
| echo " Coverage: ${COVERAGE_FMT}% | Threshold: ${THRESHOLD}%" | |
| BELOW=$(echo "$COVERAGE < $THRESHOLD" | bc -l) | |
| if [ "$BELOW" = "1" ]; then | |
| echo " FAIL: ${COVERAGE_FMT}% is BELOW threshold ${THRESHOLD}%" | |
| exit 1 | |
| fi | |
| echo " PASS" | |
| done | |
| - name: Test LQL F# Type Provider (with coverage enforcement) | |
| run: | | |
| proj="Lql/Nimblesite.Lql.TypeProvider.FSharp.Tests" | |
| THRESHOLD=$(jq -r ".projects[\"$proj\"].threshold // .default_threshold" coverage-thresholds.json) | |
| INCLUDE=$(jq -r ".projects[\"$proj\"].include // empty" coverage-thresholds.json) | |
| echo "==> Testing $proj (threshold: ${THRESHOLD}%)" | |
| rm -rf "$proj/TestResults" | |
| if [ -n "$INCLUDE" ]; then | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal \ | |
| -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="$INCLUDE" | |
| else | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal | |
| fi | |
| COBERTURA=$(find "$proj/TestResults" -name "coverage.cobertura.xml" -type f | head -1) | |
| if [ -z "$COBERTURA" ]; then echo "FAIL: No coverage file for $proj"; exit 1; fi | |
| LINE_RATE=$(sed -n 's/.*line-rate="\([0-9.]*\)".*/\1/p' "$COBERTURA" | head -1) | |
| COVERAGE=$(echo "$LINE_RATE * 100" | bc -l) | |
| COVERAGE_FMT=$(printf "%.2f" $COVERAGE) | |
| echo " Coverage: ${COVERAGE_FMT}% | Threshold: ${THRESHOLD}%" | |
| BELOW=$(echo "$COVERAGE < $THRESHOLD" | bc -l) | |
| if [ "$BELOW" = "1" ]; then | |
| echo " FAIL: ${COVERAGE_FMT}% is BELOW threshold ${THRESHOLD}%" | |
| exit 1 | |
| fi | |
| echo " PASS" | |
| - name: Test LQL Rust (with coverage enforcement) | |
| run: | | |
| THRESHOLD=$(jq -r '.projects["Lql/lql-lsp-rust"].threshold // .default_threshold' coverage-thresholds.json) | |
| echo "==> Testing Lql/lql-lsp-rust (threshold: ${THRESHOLD}%)" | |
| cd Lql/lql-lsp-rust && cargo tarpaulin --workspace --skip-clean 2>&1 | tee /tmp/_dp_tarpaulin_out.txt | |
| COVERAGE=$(grep -oE '[0-9]+\.[0-9]+% coverage' /tmp/_dp_tarpaulin_out.txt | tail -1 | grep -oE '[0-9]+\.[0-9]+') | |
| if [ -z "$COVERAGE" ]; then echo "FAIL: Could not parse tarpaulin coverage"; exit 1; fi | |
| echo " Coverage: ${COVERAGE}% | Threshold: ${THRESHOLD}%" | |
| BELOW=$(echo "$COVERAGE < $THRESHOLD" | bc -l) | |
| if [ "$BELOW" = "1" ]; then | |
| echo " FAIL: ${COVERAGE}% is BELOW threshold ${THRESHOLD}%" | |
| exit 1 | |
| fi | |
| echo " PASS" | |
| - name: Test Migration (with coverage enforcement) | |
| run: | | |
| proj="Migration/Nimblesite.DataProvider.Migration.Tests" | |
| THRESHOLD=$(jq -r ".projects[\"$proj\"].threshold // .default_threshold" coverage-thresholds.json) | |
| INCLUDE=$(jq -r ".projects[\"$proj\"].include // empty" coverage-thresholds.json) | |
| echo "==> Testing $proj (threshold: ${THRESHOLD}%)" | |
| rm -rf "$proj/TestResults" | |
| if [ -n "$INCLUDE" ]; then | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal \ | |
| -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="$INCLUDE" | |
| else | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal | |
| fi | |
| COBERTURA=$(find "$proj/TestResults" -name "coverage.cobertura.xml" -type f | head -1) | |
| if [ -z "$COBERTURA" ]; then echo "FAIL: No coverage file for $proj"; exit 1; fi | |
| LINE_RATE=$(sed -n 's/.*line-rate="\([0-9.]*\)".*/\1/p' "$COBERTURA" | head -1) | |
| COVERAGE=$(echo "$LINE_RATE * 100" | bc -l) | |
| COVERAGE_FMT=$(printf "%.2f" $COVERAGE) | |
| echo " Coverage: ${COVERAGE_FMT}% | Threshold: ${THRESHOLD}%" | |
| BELOW=$(echo "$COVERAGE < $THRESHOLD" | bc -l) | |
| if [ "$BELOW" = "1" ]; then | |
| echo " FAIL: ${COVERAGE_FMT}% is BELOW threshold ${THRESHOLD}%" | |
| exit 1 | |
| fi | |
| echo " PASS" | |
| - name: Test Sync SQLite (with coverage enforcement) | |
| run: | | |
| for proj in Sync/Nimblesite.Sync.Tests Sync/Nimblesite.Sync.SQLite.Tests; do | |
| THRESHOLD=$(jq -r ".projects[\"$proj\"].threshold // .default_threshold" coverage-thresholds.json) | |
| INCLUDE=$(jq -r ".projects[\"$proj\"].include // empty" coverage-thresholds.json) | |
| echo "==> Testing $proj (threshold: ${THRESHOLD}%)" | |
| rm -rf "$proj/TestResults" | |
| if [ -n "$INCLUDE" ]; then | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal \ | |
| -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="$INCLUDE" | |
| else | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal | |
| fi | |
| COBERTURA=$(find "$proj/TestResults" -name "coverage.cobertura.xml" -type f | head -1) | |
| if [ -z "$COBERTURA" ]; then echo "FAIL: No coverage file for $proj"; exit 1; fi | |
| LINE_RATE=$(sed -n 's/.*line-rate="\([0-9.]*\)".*/\1/p' "$COBERTURA" | head -1) | |
| COVERAGE=$(echo "$LINE_RATE * 100" | bc -l) | |
| COVERAGE_FMT=$(printf "%.2f" $COVERAGE) | |
| echo " Coverage: ${COVERAGE_FMT}% | Threshold: ${THRESHOLD}%" | |
| BELOW=$(echo "$COVERAGE < $THRESHOLD" | bc -l) | |
| if [ "$BELOW" = "1" ]; then | |
| echo " FAIL: ${COVERAGE_FMT}% is BELOW threshold ${THRESHOLD}%" | |
| exit 1 | |
| fi | |
| echo " PASS" | |
| done | |
| - name: Test Sync Postgres (with coverage enforcement) | |
| run: | | |
| for proj in Sync/Nimblesite.Sync.Postgres.Tests Sync/Nimblesite.Sync.Integration.Tests Sync/Nimblesite.Sync.Http.Tests; do | |
| THRESHOLD=$(jq -r ".projects[\"$proj\"].threshold // .default_threshold" coverage-thresholds.json) | |
| INCLUDE=$(jq -r ".projects[\"$proj\"].include // empty" coverage-thresholds.json) | |
| echo "==> Testing $proj (threshold: ${THRESHOLD}%)" | |
| rm -rf "$proj/TestResults" | |
| if [ -n "$INCLUDE" ]; then | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal \ | |
| -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Include="$INCLUDE" | |
| else | |
| dotnet test "$proj" --configuration Release \ | |
| --settings coverlet.runsettings \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory "$proj/TestResults" \ | |
| --verbosity normal | |
| fi | |
| COBERTURA=$(find "$proj/TestResults" -name "coverage.cobertura.xml" -type f | head -1) | |
| if [ -z "$COBERTURA" ]; then echo "FAIL: No coverage file for $proj"; exit 1; fi | |
| LINE_RATE=$(sed -n 's/.*line-rate="\([0-9.]*\)".*/\1/p' "$COBERTURA" | head -1) | |
| COVERAGE=$(echo "$LINE_RATE * 100" | bc -l) | |
| COVERAGE_FMT=$(printf "%.2f" $COVERAGE) | |
| echo " Coverage: ${COVERAGE_FMT}% | Threshold: ${THRESHOLD}%" | |
| BELOW=$(echo "$COVERAGE < $THRESHOLD" | bc -l) | |
| if [ "$BELOW" = "1" ]; then | |
| echo " FAIL: ${COVERAGE_FMT}% is BELOW threshold ${THRESHOLD}%" | |
| exit 1 | |
| fi | |
| echo " PASS" | |
| done | |
| env: | |
| TESTCONTAINERS_RYUK_DISABLED: false | |
| - name: Upload test results | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: test-results-build | |
| path: '**/TestResults/*.trx' | |
| # Track 3: Build All -> LQL Extension Tests | |
| extension-tests: | |
| name: LQL Extension Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| defaults: | |
| run: | |
| working-directory: Lql/LqlExtension | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install dependencies | |
| run: npm install --no-audit --no-fund | |
| - name: Run tests with coverage | |
| run: | | |
| npm run compile | |
| rm -rf out-cov && npx nyc instrument out out-cov && rm -rf out && mv out-cov out | |
| xvfb-run -a node ./out/test/runTest.js | |
| npx nyc report --reporter=json-summary --reporter=text | |
| - name: Enforce coverage threshold | |
| working-directory: . | |
| run: | | |
| THRESHOLD=$(jq -r '.projects["Lql/LqlExtension"].threshold // .default_threshold' coverage-thresholds.json) | |
| SUMMARY="Lql/LqlExtension/coverage/coverage-summary.json" | |
| if [ ! -f "$SUMMARY" ]; then | |
| SUMMARY="Lql/LqlExtension/.nyc_output/coverage-summary.json" | |
| fi | |
| if [ ! -f "$SUMMARY" ]; then | |
| echo "FAIL: No coverage summary produced for Lql/LqlExtension" | |
| exit 1 | |
| fi | |
| COVERAGE=$(jq -r '.total.lines.pct' "$SUMMARY") | |
| echo " Coverage: ${COVERAGE}% | Threshold: ${THRESHOLD}%" | |
| BELOW=$(echo "$COVERAGE < $THRESHOLD" | bc -l) | |
| if [ "$BELOW" = "1" ]; then | |
| echo " FAIL: ${COVERAGE}% is BELOW threshold ${THRESHOLD}%" | |
| exit 1 | |
| fi | |
| echo " PASS" | |
| - name: Package VSIX (dry run) | |
| run: npm run compile && npx vsce package --no-git-tag-version --no-update-package-json |