Skip to content

Handle out-of-order split-include rows to prevent child collection loss under concurrent inserts #1092

Handle out-of-order split-include rows to prevent child collection loss under concurrent inserts

Handle out-of-order split-include rows to prevent child collection loss under concurrent inserts #1092

Workflow file for this run

name: Build
on:
push:
branches: [ main ]
pull_request:
permissions: {}
defaults:
run:
shell: bash
env:
# Test projects requiring SQL Server (run in the sqlserver job, excluded from the main test job)
SQLSERVER_TEST_PROJECTS: >-
test/EFCore.SqlServer.FunctionalTests
test/EFCore.SqlServer.HierarchyId.Tests
test/EFCore.CrossStore.FunctionalTests
test/EFCore.OData.FunctionalTests
test/EFCore.AspNet.SqlServer.FunctionalTests
test/EFCore.VisualBasic.FunctionalTests
test/EFCore.FSharp.FunctionalTests
jobs:
Main:
env:
# Additional projects to exclude (covered by other dedicated jobs, or not directly runnable)
ADDITIONAL_EXCLUDED_PROJECTS: >-
Cosmos.FunctionalTests
Specification.Tests
Microsoft.Data.Sqlite
EFCore.Sqlite
EFCore.AspNet.Sqlite
TrimmingTests
NativeAotTests
ApiBaseline
strategy:
fail-fast: false
matrix:
include:
- os: windows-2025
- os: ubuntu-24.04
- os: macos-15
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Restore
if: runner.os != 'Windows'
run: ./restore.sh
- name: Restore
if: runner.os == 'Windows'
shell: cmd
run: restore.cmd
- name: Test
run: |
mkdir -p artifacts/coverage
pattern=$(echo "$SQLSERVER_TEST_PROJECTS $ADDITIONAL_EXCLUDED_PROJECTS" | xargs -n1 | tr '\n' '|' | sed 's/|$//')
failed=0
for proj in $(find test -maxdepth 2 \( -name '*.csproj' -o -name '*.fsproj' -o -name '*.vbproj' \) \
| grep -v -E "$pattern"); do
dotnet test "$proj" \
-- --coverage --coverage-output-format cobertura \
--coverage-output "$PWD/artifacts/coverage/$(basename "$proj").cobertura.xml" \
--coverage-settings eng/efcore.coverage.xml || failed=1
done
exit $failed
- name: Upload coverage artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: coverage-main-${{ matrix.os }}
path: artifacts/coverage/*.cobertura.xml
if-no-files-found: ignore
- name: Publish Test Results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
if: always()
with:
name: test-results-main-${{ matrix.os }}
path: artifacts/log/Debug/*
Cosmos:
strategy:
fail-fast: false
matrix:
include:
- os: windows-2025
- os: ubuntu-24.04
runs-on: ${{ matrix.os }}
steps:
- name: Start Cosmos Emulator
if: runner.os == 'Windows'
shell: powershell
run: |
Import-Module "$env:ProgramFiles\Azure Cosmos DB Emulator\PSModules\Microsoft.Azure.CosmosDB.Emulator"
Start-CosmosDbEmulator -Timeout 540 -NoUI -NoTelemetry -NoFirewall -EnablePreview
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Restore
if: runner.os != 'Windows'
run: ./restore.sh
- name: Restore
if: runner.os == 'Windows'
shell: cmd
run: restore.cmd
- name: Test on Cosmos
run: |
mkdir -p artifacts/coverage
dotnet test test/EFCore.Cosmos.FunctionalTests/EFCore.Cosmos.FunctionalTests.csproj \
-- --coverage --coverage-output-format cobertura \
--coverage-output "$PWD/artifacts/coverage/EFCore.Cosmos.FunctionalTests.cobertura.xml" \
--coverage-settings eng/efcore.coverage.xml
env:
Test__Cosmos__DefaultConnection: ${{ runner.os == 'Windows' && 'https://localhost:8081' || '' }}
Test__Cosmos__SkipConnectionCheck: ${{ runner.os == 'Windows' && 'true' || '' }}
- name: Upload coverage artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: coverage-cosmos-${{ matrix.os }}
path: artifacts/coverage/*.cobertura.xml
if-no-files-found: ignore
- name: Publish Test Results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
if: always()
with:
name: test-results-cosmos-${{ matrix.os }}
path: artifacts/log/Debug/*
SqlServer:
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
sqlserver_version: [2025, 2022, 2019]
env:
MSSQL_SA_PASSWORD: 'PLACEHOLDERPass$$w0rd'
services:
mssql:
image: mcr.microsoft.com/mssql/server:${{ matrix.sqlserver_version }}-latest
env:
ACCEPT_EULA: Y
SA_PASSWORD: ${{ env.MSSQL_SA_PASSWORD }}
ports:
- 1433:1433
options: >-
--health-cmd="/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -Q 'SELECT 1' -C"
--health-start-period=20s
--health-interval=2s
--health-retries=30
--health-timeout=5s
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Restore
run: ./restore.sh
- name: Test on SQL Server
env:
Test__SqlServer__DefaultConnection: 'Server=localhost;Database=master;User=SA;Password=${{ env.MSSQL_SA_PASSWORD }};Connect Timeout=60;ConnectRetryCount=0;Trust Server Certificate=true'
run: |
mkdir -p artifacts/coverage
failed=0
for proj in $SQLSERVER_TEST_PROJECTS; do
dotnet test "$proj" \
-- --coverage --coverage-output-format cobertura \
--coverage-output "$PWD/artifacts/coverage/$(basename "$proj").cobertura.xml" \
--coverage-settings eng/efcore.coverage.xml || failed=1
done
exit $failed
- name: Upload coverage artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: coverage-sqlserver-${{ matrix.sqlserver_version }}
path: artifacts/coverage/*.cobertura.xml
if-no-files-found: ignore
- name: Publish Test Results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
if: always()
with:
name: test-results-sqlserver-${{ matrix.sqlserver_version }}
path: artifacts/log/Debug/*
Sqlite:
strategy:
fail-fast: false
matrix:
include:
- os: windows-2025
- os: ubuntu-24.04
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Restore
if: runner.os != 'Windows'
run: ./restore.sh
- name: Restore
if: runner.os == 'Windows'
shell: cmd
run: restore.cmd
- name: Test EF Core Sqlite
run: |
mkdir -p artifacts/coverage
failed=0
for proj in test/EFCore.Sqlite.FunctionalTests test/EFCore.Sqlite.Tests test/EFCore.AspNet.Sqlite.FunctionalTests; do
dotnet test "$proj" \
-- --coverage --coverage-output-format cobertura \
--coverage-output "$PWD/artifacts/coverage/$(basename "$proj").cobertura.xml" \
--coverage-settings eng/efcore.coverage.xml || failed=1
done
exit $failed
- name: Upload coverage artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: coverage-sqlite-${{ matrix.os }}
path: artifacts/coverage/*.cobertura.xml
if-no-files-found: ignore
- name: Publish Test Results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
if: always()
with:
name: test-results-sqlite-${{ matrix.os }}
path: artifacts/log/Debug/*
microsoft-data-sqlite:
name: Microsoft.Data.Sqlite
strategy:
fail-fast: false
matrix:
include:
- os: windows-2025
- os: ubuntu-24.04
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Restore
if: runner.os != 'Windows'
run: ./restore.sh
- name: Restore
if: runner.os == 'Windows'
shell: cmd
run: restore.cmd
- name: Test Microsoft.Data.Sqlite
run: |
mkdir -p artifacts/coverage
failed=0
for proj in $(find test/Microsoft.Data.Sqlite.Tests -name '*.csproj' \
| if [ "$RUNNER_OS" != "Windows" ]; then grep -v winsqlite3; else cat; fi); do
dotnet test "$proj" \
-- --coverage --coverage-output-format cobertura \
--coverage-output "$PWD/artifacts/coverage/$(basename "$proj").cobertura.xml" \
--coverage-settings eng/efcore.coverage.xml || failed=1
done
exit $failed
- name: Upload coverage artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: coverage-microsoft-data-sqlite-${{ matrix.os }}
path: artifacts/coverage/*.cobertura.xml
if-no-files-found: ignore
- name: Publish Test Results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
if: always()
with:
name: test-results-microsoft-data-sqlite-${{ matrix.os }}
path: artifacts/log/Debug/*
ApiBaselines:
name: API Baselines
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Restore
run: ./restore.sh
- name: Test API Baselines
run: dotnet test test/EFCore.ApiBaseline.Tests
coverage:
name: Upload coverage
needs: [Main, Cosmos, SqlServer, Sqlite, microsoft-data-sqlite]
runs-on: ubuntu-24.04
if: always()
permissions:
contents: read
code-quality: write
steps:
- name: Download coverage artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
with:
pattern: coverage-*
path: artifacts/coverage
- name: Merge coverage reports
continue-on-error: true
run: |
mapfile -d '' files < <(find artifacts/coverage -name '*.cobertura.xml' -print0 2>/dev/null)
if [ ${#files[@]} -gt 0 ]; then
export PATH="$PATH:$HOME/.dotnet/tools"
dotnet tool update --global dotnet-coverage || dotnet tool install --global dotnet-coverage
dotnet-coverage merge -o artifacts/coverage/coverage.cobertura.xml -f cobertura "${files[@]}"
fi
- name: Upload coverage report
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && hashFiles('artifacts/coverage/coverage.cobertura.xml') != ''
uses: actions/upload-code-coverage@abb5995db9e0199b0e2bb9dbd136fce4cb1ec4d3
with:
file: artifacts/coverage/coverage.cobertura.xml
language: C#
label: code-coverage
fail-on-error: false