Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts: # .artifactignore # build/azure-pipelines.yml # tests/Umbraco.Tests.AcceptanceTest/misc/umbraco-linux.docker
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
**/*
|
**/*
|
||||||
!**/bin/**
|
!tests/Umbraco.Tests.Integration/bin/**
|
||||||
!**/obj/**
|
!tests/Umbraco.Tests.UnitTests/bin/**
|
||||||
**/node_modules
|
**/node_modules
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ parameters:
|
|||||||
displayName: Run SQL Server Integration Tests
|
displayName: Run SQL Server Integration Tests
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
- name: sqlServerAcceptanceTests
|
||||||
|
displayName: Run SQL Server Acceptance Tests
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
- name: myGetDeploy
|
- name: myGetDeploy
|
||||||
displayName: Deploy to MyGet
|
displayName: Deploy to MyGet
|
||||||
type: boolean
|
type: boolean
|
||||||
@@ -38,11 +42,11 @@ parameters:
|
|||||||
type: string
|
type: string
|
||||||
default: ' '
|
default: ' '
|
||||||
- name: nonWindowsIntegrationNonReleaseTestFilter
|
- name: nonWindowsIntegrationNonReleaseTestFilter
|
||||||
displayName: TestFilter used for non-release type builds on non windows agents
|
displayName: TestFilter used for non-release type builds on non Windows agents
|
||||||
type: string
|
type: string
|
||||||
default: '--filter TestCategory!=LongRunning&TestCategory!=NonCritical'
|
default: '--filter TestCategory!=LongRunning&TestCategory!=NonCritical'
|
||||||
- name: nonWindowsIntegrationReleaseTestFilter
|
- name: nonWindowsIntegrationReleaseTestFilter
|
||||||
displayName: TestFilter used for release type builds on non windows agents
|
displayName: TestFilter used for release type builds on non Windows agents
|
||||||
type: string
|
type: string
|
||||||
default: ' '
|
default: ' '
|
||||||
- name: isNightly
|
- name: isNightly
|
||||||
@@ -52,8 +56,6 @@ parameters:
|
|||||||
|
|
||||||
variables:
|
variables:
|
||||||
nodeVersion: 20
|
nodeVersion: 20
|
||||||
dotnetVersion: 8.x
|
|
||||||
dotnetIncludePreviewVersions: true
|
|
||||||
solution: umbraco.sln
|
solution: umbraco.sln
|
||||||
buildConfiguration: Release
|
buildConfiguration: Release
|
||||||
UMBRACO__CMS__GLOBAL__ID: 00000000-0000-0000-0000-000000000042
|
UMBRACO__CMS__GLOBAL__ID: 00000000-0000-0000-0000-000000000042
|
||||||
@@ -116,11 +118,9 @@ stages:
|
|||||||
displayName: Run Login Build (Bellissima)
|
displayName: Run Login Build (Bellissima)
|
||||||
workingDirectory: src/Umbraco.Web.UI.New.Client/apps/auth
|
workingDirectory: src/Umbraco.Web.UI.New.Client/apps/auth
|
||||||
- task: UseDotNet@2
|
- task: UseDotNet@2
|
||||||
displayName: Use .NET $(dotnetVersion)
|
displayName: Use .NET SDK from global.json
|
||||||
inputs:
|
inputs:
|
||||||
version: $(dotnetVersion)
|
useGlobalJson: true
|
||||||
performMultiLevelLookup: true
|
|
||||||
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
|
||||||
- task: DotNetCoreCLI@2
|
- task: DotNetCoreCLI@2
|
||||||
displayName: Run dotnet restore
|
displayName: Run dotnet restore
|
||||||
inputs:
|
inputs:
|
||||||
@@ -294,16 +294,14 @@ stages:
|
|||||||
artifact: build_output
|
artifact: build_output
|
||||||
path: $(Build.SourcesDirectory)
|
path: $(Build.SourcesDirectory)
|
||||||
- task: UseDotNet@2
|
- task: UseDotNet@2
|
||||||
displayName: Use .NET $(dotnetVersion)
|
displayName: Use .NET SDK from global.json
|
||||||
inputs:
|
inputs:
|
||||||
version: $(dotnetVersion)
|
useGlobalJson: true
|
||||||
performMultiLevelLookup: true
|
|
||||||
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
|
||||||
- task: DotNetCoreCLI@2
|
- task: DotNetCoreCLI@2
|
||||||
displayName: Run dotnet test
|
displayName: Run dotnet test
|
||||||
inputs:
|
inputs:
|
||||||
command: test
|
command: test
|
||||||
projects: '**/*.Tests.UnitTests.csproj'
|
projects: 'tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj'
|
||||||
arguments: '--configuration $(buildConfiguration) --no-build'
|
arguments: '--configuration $(buildConfiguration) --no-build'
|
||||||
testRunTitle: Unit Tests - $(Agent.OS)
|
testRunTitle: Unit Tests - $(Agent.OS)
|
||||||
|
|
||||||
@@ -326,48 +324,36 @@ stages:
|
|||||||
vmImage: 'macOS-latest'
|
vmImage: 'macOS-latest'
|
||||||
pool:
|
pool:
|
||||||
vmImage: $(vmImage)
|
vmImage: $(vmImage)
|
||||||
|
variables:
|
||||||
|
Tests__Database__DatabaseType: 'Sqlite'
|
||||||
steps:
|
steps:
|
||||||
- checkout: self
|
# Setup test environment
|
||||||
submodules: true
|
|
||||||
- task: DownloadPipelineArtifact@2
|
- task: DownloadPipelineArtifact@2
|
||||||
displayName: Download build artifacts
|
displayName: Download build artifacts
|
||||||
inputs:
|
inputs:
|
||||||
artifact: build_output
|
artifact: build_output
|
||||||
path: $(Build.SourcesDirectory)
|
path: $(Build.SourcesDirectory)
|
||||||
|
|
||||||
- task: UseDotNet@2
|
- task: UseDotNet@2
|
||||||
displayName: Use .NET $(dotnetVersion)
|
displayName: Use .NET SDK from global.json
|
||||||
inputs:
|
inputs:
|
||||||
version: $(dotnetVersion)
|
useGlobalJson: true
|
||||||
performMultiLevelLookup: true
|
|
||||||
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
# Test
|
||||||
- task: DotNetCoreCLI@2
|
- task: DotNetCoreCLI@2
|
||||||
displayName: Run dotnet test Windows
|
displayName: Run dotnet test
|
||||||
condition: eq(variables['Agent.OS'],'Windows_NT')
|
|
||||||
inputs:
|
inputs:
|
||||||
command: test
|
command: test
|
||||||
projects: '**/*.Tests.Integration.csproj'
|
projects: 'tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj'
|
||||||
testRunTitle: Integration Tests SQLite - $(Agent.OS)
|
testRunTitle: Integration Tests SQLite - $(Agent.OS)
|
||||||
${{ if or(variables.releaseTestFilter, parameters.forceReleaseTestFilter) }}:
|
${{ if and(eq(variables['Agent.OS'],'Windows_NT'), or(variables.releaseTestFilter, parameters.forceReleaseTestFilter)) }}:
|
||||||
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.integrationReleaseTestFilter}}'
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.integrationReleaseTestFilter}}'
|
||||||
${{ else }}:
|
${{ elseif eq(variables['Agent.OS'],'Windows_NT') }}:
|
||||||
arguments: '--configuration $(buildConfiguration) ${{parameters.integrationNonReleaseTestFilter}}'
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.integrationNonReleaseTestFilter}}'
|
||||||
env:
|
${{ elseif or(variables.releaseTestFilter, parameters.forceReleaseTestFilter) }}:
|
||||||
Tests__Database__DatabaseType: 'Sqlite'
|
|
||||||
Umbraco__CMS__Global__MainDomLock: 'FileSystemMainDomLock'
|
|
||||||
- task: DotNetCoreCLI@2
|
|
||||||
displayName: Run dotnet test Non Windows
|
|
||||||
condition: ne(variables['Agent.OS'],'Windows_NT')
|
|
||||||
inputs:
|
|
||||||
command: test
|
|
||||||
projects: '**/*.Tests.Integration.csproj'
|
|
||||||
testRunTitle: Integration Tests SQLite - $(Agent.OS)
|
|
||||||
${{ if or(variables.releaseTestFilter, parameters.forceReleaseTestFilter) }}:
|
|
||||||
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationReleaseTestFilter}}'
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationReleaseTestFilter}}'
|
||||||
${{ else }}:
|
${{ else }}:
|
||||||
arguments: '--configuration $(buildConfiguration) ${{parameters.nonWindowsIntegrationNonReleaseTestFilter}}'
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationNonReleaseTestFilter}}'
|
||||||
env:
|
|
||||||
Tests__Database__DatabaseType: 'Sqlite'
|
|
||||||
Umbraco__CMS__Global__MainDomLock: 'FileSystemMainDomLock'
|
|
||||||
|
|
||||||
# Integration Tests (SQL Server)
|
# Integration Tests (SQL Server)
|
||||||
- job:
|
- job:
|
||||||
@@ -378,208 +364,363 @@ stages:
|
|||||||
matrix:
|
matrix:
|
||||||
Windows:
|
Windows:
|
||||||
vmImage: 'windows-latest'
|
vmImage: 'windows-latest'
|
||||||
testDb: LocalDb
|
Tests__Database__DatabaseType: LocalDb
|
||||||
connectionString: N/A
|
Tests__Database__SQLServerMasterConnectionString: N/A
|
||||||
Linux:
|
Linux:
|
||||||
vmImage: 'ubuntu-latest'
|
vmImage: 'ubuntu-latest'
|
||||||
testDb: SqlServer
|
SA_PASSWORD: UmbracoIntegration123!
|
||||||
connectionString: 'Server=localhost,1433;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=true'
|
Tests__Database__DatabaseType: SqlServer
|
||||||
|
Tests__Database__SQLServerMasterConnectionString: 'Server=(local);User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True'
|
||||||
pool:
|
pool:
|
||||||
vmImage: $(vmImage)
|
vmImage: $(vmImage)
|
||||||
variables:
|
|
||||||
SA_PASSWORD: UmbracoIntegration123!
|
|
||||||
steps:
|
steps:
|
||||||
|
# Setup test environment
|
||||||
- task: DownloadPipelineArtifact@2
|
- task: DownloadPipelineArtifact@2
|
||||||
displayName: Download build artifacts
|
displayName: Download build artifacts
|
||||||
inputs:
|
inputs:
|
||||||
artifact: build_output
|
artifact: build_output
|
||||||
path: $(Build.SourcesDirectory)
|
path: $(Build.SourcesDirectory)
|
||||||
|
|
||||||
- task: UseDotNet@2
|
- task: UseDotNet@2
|
||||||
displayName: Use .NET $(dotnetVersion)
|
displayName: Use .NET SDK from global.json
|
||||||
inputs:
|
inputs:
|
||||||
version: $(dotnetVersion)
|
useGlobalJson: true
|
||||||
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
|
||||||
- powershell: sqllocaldb start mssqllocaldb
|
# Start SQL Server
|
||||||
displayName: Start localdb (Windows only)
|
- powershell: docker run --name mssql -d -p 1433:1433 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=$(SA_PASSWORD)" mcr.microsoft.com/mssql/server:2022-latest
|
||||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
displayName: Start SQL Server Docker image (Linux)
|
||||||
- powershell: docker run --name mssql -d -p 1433:1433 -e ACCEPT_EULA=Y -e SA_PASSWORD=$(SA_PASSWORD) -e MSSQL_PID=Developer mcr.microsoft.com/mssql/server:2019-latest
|
|
||||||
displayName: Start SQL Server (Linux only)
|
|
||||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||||
|
|
||||||
|
- pwsh: SqlLocalDB start MSSQLLocalDB
|
||||||
|
displayName: Start SQL Server LocalDB (Windows)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
|
|
||||||
|
# Test
|
||||||
- task: DotNetCoreCLI@2
|
- task: DotNetCoreCLI@2
|
||||||
displayName: Run dotnet test Windows
|
displayName: Run dotnet test
|
||||||
condition: eq(variables['Agent.OS'],'Windows_NT')
|
|
||||||
inputs:
|
inputs:
|
||||||
command: test
|
command: test
|
||||||
projects: '**/*.Tests.Integration.csproj'
|
projects: 'tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj'
|
||||||
testRunTitle: Integration Tests SQL Server - $(Agent.OS)
|
testRunTitle: Integration Tests SQL Server - $(Agent.OS)
|
||||||
${{ if or(variables.releaseTestFilter, parameters.forceReleaseTestFilter) }}:
|
${{ if and(eq(variables['Agent.OS'],'Windows_NT'), or(variables.releaseTestFilter, parameters.forceReleaseTestFilter)) }}:
|
||||||
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.integrationReleaseTestFilter}}'
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.integrationReleaseTestFilter}}'
|
||||||
${{ else }}:
|
${{ elseif eq(variables['Agent.OS'],'Windows_NT') }}:
|
||||||
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.integrationNonReleaseTestFilter}}'
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.integrationNonReleaseTestFilter}}'
|
||||||
env:
|
${{ elseif or(variables.releaseTestFilter, parameters.forceReleaseTestFilter) }}:
|
||||||
Tests__Database__DatabaseType: $(testDb)
|
|
||||||
Tests__Database__SQLServerMasterConnectionString: $(connectionString)
|
|
||||||
Umbraco__CMS__Global__MainDomLock: 'SqlMainDomLock'
|
|
||||||
- task: DotNetCoreCLI@2
|
|
||||||
displayName: Run dotnet test NonWindows
|
|
||||||
condition: ne(variables['Agent.OS'],'Windows_NT')
|
|
||||||
inputs:
|
|
||||||
command: test
|
|
||||||
projects: '**/*.Tests.Integration.csproj'
|
|
||||||
testRunTitle: Integration Tests SQL Server - $(Agent.OS)
|
|
||||||
${{ if or(variables.releaseTestFilter, parameters.forceReleaseTestFilter) }}:
|
|
||||||
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationReleaseTestFilter}}'
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationReleaseTestFilter}}'
|
||||||
${{ else }}:
|
${{ else }}:
|
||||||
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationNonReleaseTestFilter}}'
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationNonReleaseTestFilter}}'
|
||||||
env:
|
|
||||||
Tests__Database__DatabaseType: $(testDb)
|
# Stop SQL Server
|
||||||
Tests__Database__SQLServerMasterConnectionString: $(connectionString)
|
- pwsh: docker stop mssql
|
||||||
Umbraco__CMS__Global__MainDomLock: 'SqlMainDomLock'
|
displayName: Stop SQL Server Docker image (Linux)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||||
|
|
||||||
|
- pwsh: SqlLocalDB stop MSSQLLocalDB
|
||||||
|
displayName: Stop SQL Server LocalDB (Windows)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
|
|
||||||
- stage: E2E
|
- stage: E2E
|
||||||
variables:
|
|
||||||
npm_config_cache: $(Pipeline.Workspace)/.npm_e2e
|
|
||||||
displayName: E2E Tests
|
displayName: E2E Tests
|
||||||
dependsOn: Build
|
dependsOn: Build
|
||||||
|
variables:
|
||||||
|
npm_config_cache: $(Pipeline.Workspace)/.npm_e2e
|
||||||
|
# Enable console logging in Release mode
|
||||||
|
SERILOG__WRITETO__0__NAME: Async
|
||||||
|
SERILOG__WRITETO__0__ARGS__CONFIGURE__0__NAME: Console
|
||||||
|
# Set unattended install settings
|
||||||
|
UMBRACO__CMS__UNATTENDED__INSTALLUNATTENDED: true
|
||||||
|
UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERNAME: Playwright Test
|
||||||
|
UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD: UmbracoAcceptance123!
|
||||||
|
UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL: playwright@umbraco.com
|
||||||
|
# Custom Umbraco settings
|
||||||
|
UMBRACO__CMS__CONTENT__CONTENTVERSIONCLEANUPPOLICY__ENABLECLEANUP: false
|
||||||
|
UMBRACO__CMS__GLOBAL__DISABLEELECTIONFORSINGLESERVER: true
|
||||||
|
UMBRACO__CMS__GLOBAL__INSTALLMISSINGDATABASE: true
|
||||||
|
UMBRACO__CMS__GLOBAL__ID: 00000000-0000-0000-0000-000000000042
|
||||||
|
UMBRACO__CMS__GLOBAL__VERSIONCHECKPERIOD: 0
|
||||||
|
UMBRACO__CMS__GLOBAL__USEHTTPS: true
|
||||||
|
UMBRACO__CMS__HEALTHCHECKS__NOTIFICATION__ENABLED: false
|
||||||
|
UMBRACO__CMS__KEEPALIVE__DISABLEKEEPALIVETASK: true
|
||||||
|
UMBRACO__CMS__WEBROUTING__UMBRACOAPPLICATIONURL: https://localhost:44331/
|
||||||
|
ASPNETCORE_URLS: https://localhost:44331
|
||||||
jobs:
|
jobs:
|
||||||
# E2E Tests
|
# E2E Tests
|
||||||
- job:
|
- job:
|
||||||
displayName: E2E Tests
|
displayName: E2E Tests (SQLite)
|
||||||
timeoutInMinutes: 120
|
|
||||||
variables:
|
variables:
|
||||||
Umbraco__CMS__Unattended__UnattendedUserName: Playwright Test
|
# Connection string
|
||||||
Umbraco__CMS__Unattended__UnattendedUserPassword: UmbracoAcceptance123!
|
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=Umbraco;Mode=Memory;Cache=Shared;Foreign Keys=True;Pooling=True
|
||||||
Umbraco__CMS__Unattended__UnattendedUserEmail: playwright@umbraco.com
|
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.Sqlite
|
||||||
ASPNETCORE_URLS: https://localhost:8443
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
Linux:
|
Linux:
|
||||||
vmImage: 'ubuntu-latest'
|
vmImage: 'ubuntu-latest'
|
||||||
dockerfile: umbraco-linux.docker
|
|
||||||
dockerImageName: umbraco-linux
|
|
||||||
Windows:
|
Windows:
|
||||||
vmImage: 'windows-latest'
|
vmImage: 'windows-latest'
|
||||||
DOTNET_GENERATE_ASPNET_CERTIFICATE: true # Automatically generate HTTPS development certificate on Windows
|
|
||||||
# Enable console logging in Release mode
|
|
||||||
Serilog__WriteTo__0__Name: Async
|
|
||||||
Serilog__WriteTo__0__Args__configure__0__Name: Console
|
|
||||||
# Set unattended install settings
|
|
||||||
Umbraco__CMS__Unattended__InstallUnattended: true
|
|
||||||
Umbraco__CMS__Global__InstallMissingDatabase: true
|
|
||||||
UmbracoDatabaseServer: (LocalDB)\MSSQLLocalDB
|
|
||||||
UmbracoDatabaseName: AcceptanceTestDB
|
|
||||||
ConnectionStrings__umbracoDbDSN: Server=$(UmbracoDatabaseServer);Database=$(UmbracoDatabaseName);Integrated Security=true;
|
|
||||||
# Custom Umbraco settings
|
|
||||||
Umbraco__CMS__Global__VersionCheckPeriod: 0
|
|
||||||
Umbraco__CMS__Global__UseHttps: true
|
|
||||||
Umbraco__CMS__HealthChecks__Notification__Enabled: false
|
|
||||||
Umbraco__CMS__KeepAlive__DisableKeepAliveTask: true
|
|
||||||
pool:
|
pool:
|
||||||
vmImage: $(vmImage)
|
vmImage: $(vmImage)
|
||||||
steps:
|
steps:
|
||||||
|
# Setup test environment
|
||||||
- task: DownloadPipelineArtifact@2
|
- task: DownloadPipelineArtifact@2
|
||||||
displayName: Download nupkg
|
displayName: Download NuGet artifacts
|
||||||
inputs:
|
inputs:
|
||||||
artifact: nupkg
|
artifact: nupkg
|
||||||
path: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/misc/nupkg
|
path: $(Agent.BuildDirectory)/app/nupkg
|
||||||
|
|
||||||
- task: NodeTool@0
|
- task: NodeTool@0
|
||||||
displayName: Use Node.js $(nodeVersion)
|
displayName: Use Node.js $(nodeVersion)
|
||||||
retryCountOnTaskFailure: 3
|
retryCountOnTaskFailure: 3
|
||||||
inputs:
|
inputs:
|
||||||
versionSpec: $(nodeVersion)
|
versionSpec: $(nodeVersion)
|
||||||
- task: Cache@2
|
|
||||||
displayName: Cache node_modules
|
|
||||||
inputs:
|
|
||||||
key: '"npm_e2e" | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
|
|
||||||
restoreKeys: |
|
|
||||||
"npm_e2e" | "$(Agent.OS)"
|
|
||||||
"npm_e2e"
|
|
||||||
path: $(npm_config_cache)
|
|
||||||
- pwsh: |
|
|
||||||
New-Item -Path "." -Name ".env" -ItemType "file" -Value "UMBRACO_USER_LOGIN=$(Umbraco__CMS__Unattended__UnattendedUserEmail)
|
|
||||||
UMBRACO_USER_PASSWORD=$(Umbraco__CMS__Unattended__UnattendedUserPassword)
|
|
||||||
URL=$(ASPNETCORE_URLS)"
|
|
||||||
displayName: Generate .env
|
|
||||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/
|
|
||||||
- script: npm ci --no-fund --no-audit --prefer-offline
|
|
||||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/
|
|
||||||
displayName: Run npm ci
|
|
||||||
- pwsh: sqllocaldb start mssqllocaldb
|
|
||||||
displayName: Start localdb (Windows only)
|
|
||||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
|
||||||
- pwsh: Invoke-Sqlcmd -Query "CREATE DATABASE $env:UmbracoDatabaseName" -ServerInstance $env:UmbracoDatabaseServer
|
|
||||||
displayName: Create database (Windows only)
|
|
||||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
|
||||||
- task: UseDotNet@2
|
- task: UseDotNet@2
|
||||||
displayName: Use .NET $(dotnetVersion)
|
displayName: Use .NET SDK from global.json
|
||||||
inputs:
|
inputs:
|
||||||
version: $(dotnetVersion)
|
useGlobalJson: true
|
||||||
performMultiLevelLookup: true
|
|
||||||
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
|
||||||
- pwsh: |
|
- pwsh: |
|
||||||
$sha = 'g$(Build.SourceVersion)'.substring(0, 8)
|
"UMBRACO_USER_LOGIN=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL)
|
||||||
docker build -t $(dockerImageName):$sha -f $(dockerfile) .
|
UMBRACO_USER_PASSWORD=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||||
mkdir -p $(Build.ArtifactStagingDirectory)/docker-images
|
URL=$(ASPNETCORE_URLS)" | Out-File .env
|
||||||
docker save -o $(Build.ArtifactStagingDirectory)/docker-images/$(dockerImageName).$sha.tar $(dockerImageName):$sha
|
displayName: Generate .env
|
||||||
dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p $(Umbraco__CMS__Unattended__UnattendedUserPassword)
|
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||||
docker run --name $(dockerImageName) -dp 8080:5000 -dp 8443:5001 -e UMBRACO__CMS__GLOBAL__ID=$(UMBRACO__CMS__GLOBAL__ID) -e ASPNETCORE_Kestrel__Certificates__Default__Password="$(Umbraco__CMS__Unattended__UnattendedUserPassword)" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v ${HOME}/.aspnet/https:/https/ $(dockerImageName):$sha
|
|
||||||
docker ps
|
# Cache and restore NPM packages
|
||||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
- task: Cache@2
|
||||||
displayName: Build and run container (Linux only)
|
displayName: Cache NPM packages
|
||||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest/misc
|
inputs:
|
||||||
|
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
|
||||||
|
restoreKeys: |
|
||||||
|
npm_e2e | "$(Agent.OS)"
|
||||||
|
npm_e2e
|
||||||
|
path: $(npm_config_cache)
|
||||||
|
|
||||||
|
- script: npm ci --no-fund --no-audit --prefer-offline
|
||||||
|
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||||
|
displayName: Restore NPM packages
|
||||||
|
|
||||||
|
# Build application
|
||||||
- pwsh: |
|
- pwsh: |
|
||||||
dotnet new --install ./nupkg/Umbraco.Templates.*.nupkg
|
$cmsVersion = "$(Build.BuildNumber)" -replace "\+",".g"
|
||||||
dotnet new umbraco --name AcceptanceTestProject --no-restore --output .
|
dotnet new nugetconfig
|
||||||
dotnet restore --configfile ./nuget.config
|
dotnet nuget add source ./nupkg --name Local
|
||||||
dotnet build --configuration $(buildConfiguration) --no-restore
|
dotnet new install Umbraco.Templates::$cmsVersion
|
||||||
|
dotnet new umbraco --name UmbracoProject --version $cmsVersion --exclude-gitignore --no-restore --no-update-check
|
||||||
|
dotnet restore UmbracoProject
|
||||||
|
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
|
||||||
|
dotnet build UmbracoProject --configuration $(buildConfiguration) --no-restore
|
||||||
dotnet dev-certs https
|
dotnet dev-certs https
|
||||||
$process = Start-Process -FilePath "dotnet" -ArgumentList "run --configuration $(buildConfiguration) --no-build --no-launch-profile 2>&1" -PassThru -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
|
displayName: Build application
|
||||||
|
workingDirectory: $(Agent.BuildDirectory)/app
|
||||||
|
|
||||||
|
# Run application
|
||||||
|
- bash: |
|
||||||
|
nohup dotnet run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1 &
|
||||||
|
echo "##vso[task.setvariable variable=AcceptanceTestProcessId]$!"
|
||||||
|
displayName: Run application (Linux)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||||
|
workingDirectory: $(Agent.BuildDirectory)/app
|
||||||
|
|
||||||
|
- pwsh: |
|
||||||
|
$process = Start-Process dotnet "run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile 2>&1" -PassThru -NoNewWindow -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
|
||||||
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
|
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
|
||||||
|
displayName: Run application (Windows)
|
||||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
displayName: Build and run app (Windows only)
|
workingDirectory: $(Agent.BuildDirectory)/app
|
||||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest/misc
|
|
||||||
|
# Wait for application to start responding to requests
|
||||||
- pwsh: npx wait-on -v --interval 1000 --timeout 120000 $(ASPNETCORE_URLS)
|
- pwsh: npx wait-on -v --interval 1000 --timeout 120000 $(ASPNETCORE_URLS)
|
||||||
displayName: Wait for app
|
displayName: Wait for application
|
||||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||||
|
|
||||||
|
# Install Playwright and dependencies
|
||||||
- pwsh: npx playwright install --with-deps
|
- pwsh: npx playwright install --with-deps
|
||||||
displayName: Install Playwright
|
displayName: Install Playwright
|
||||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||||
|
|
||||||
|
# Test
|
||||||
- pwsh: npm run test --ignore-certificate-errors
|
- pwsh: npm run test --ignore-certificate-errors
|
||||||
displayName: Run Playwright (Desktop)
|
displayName: Run Playwright tests
|
||||||
continueOnError: true
|
continueOnError: true
|
||||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||||
env:
|
env:
|
||||||
CI: true
|
CI: true
|
||||||
CommitId: $(Build.SourceVersion)
|
CommitId: $(Build.SourceVersion)
|
||||||
AgentOs: $(Agent.OS)
|
AgentOs: $(Agent.OS)
|
||||||
|
|
||||||
|
# Stop application
|
||||||
|
- bash: kill -15 $(AcceptanceTestProcessId)
|
||||||
|
displayName: Stop application (Linux)
|
||||||
|
condition: and(succeeded(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Linux'))
|
||||||
|
|
||||||
|
- pwsh: Stop-Process -Id $(AcceptanceTestProcessId)
|
||||||
|
displayName: Stop application (Windows)
|
||||||
|
condition: and(succeeded(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
|
|
||||||
|
# Copy artifacts
|
||||||
- pwsh: |
|
- pwsh: |
|
||||||
docker logs $(dockerImageName) > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1
|
if (Test-Path tests/Umbraco.Tests.AcceptanceTest/results/*) {
|
||||||
docker stop $(dockerImageName)
|
Copy-Item tests/Umbraco.Tests.AcceptanceTest/results $(Build.ArtifactStagingDirectory) -Recurse
|
||||||
condition: eq(variables['Agent.OS'], 'Linux')
|
}
|
||||||
displayName: Stop app (Linux only)
|
displayName: Copy Playwright results
|
||||||
- pwsh: Stop-Process $env:AcceptanceTestProcessId
|
condition: succeededOrFailed()
|
||||||
condition: eq(variables['Agent.OS'], 'Windows_NT')
|
|
||||||
displayName: Stop app (Windows only)
|
# Publish
|
||||||
- task: PowerShell@2
|
|
||||||
displayName: Check if artifacts folder exists
|
|
||||||
inputs:
|
|
||||||
targetType: inline
|
|
||||||
script: |
|
|
||||||
$MyVariable = Test-Path -Path $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/results
|
|
||||||
Write-Host "##vso[task.setvariable variable=resultFolderExists;]$MyVariable"
|
|
||||||
- task: CopyFiles@2
|
|
||||||
displayName: Prepare artifacts
|
|
||||||
condition: eq(variables.resultFolderExists, 'True')
|
|
||||||
inputs:
|
|
||||||
sourceFolder: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/results/
|
|
||||||
targetFolder: $(Build.ArtifactStagingDirectory)/playwright
|
|
||||||
- task: PublishPipelineArtifact@1
|
- task: PublishPipelineArtifact@1
|
||||||
condition: always()
|
|
||||||
displayName: Publish test artifacts
|
displayName: Publish test artifacts
|
||||||
|
condition: succeededOrFailed()
|
||||||
inputs:
|
inputs:
|
||||||
targetPath: $(Build.ArtifactStagingDirectory)
|
targetPath: $(Build.ArtifactStagingDirectory)
|
||||||
artifact: 'E2E artifacts - $(Agent.OS) - Attempt #$(System.JobAttempt)'
|
artifact: 'Acceptance Tests - $(Agent.JobName) - Attempt #$(System.JobAttempt)'
|
||||||
|
|
||||||
|
- job:
|
||||||
|
displayName: E2E Tests (SQL Server)
|
||||||
|
condition: or(eq(stageDependencies.Build.A.outputs['build.NBGV_PublicRelease'], 'True'), ${{parameters.sqlServerAcceptanceTests}})
|
||||||
|
variables:
|
||||||
|
# Connection string
|
||||||
|
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Umbraco.mdf;Integrated Security=True
|
||||||
|
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.SqlClient
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
Linux:
|
||||||
|
vmImage: 'ubuntu-latest'
|
||||||
|
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||||
|
CONNECTIONSTRINGS__UMBRACODBDSN: 'Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True'
|
||||||
|
Windows:
|
||||||
|
vmImage: 'windows-latest'
|
||||||
|
pool:
|
||||||
|
vmImage: $(vmImage)
|
||||||
|
steps:
|
||||||
|
# Setup test environment
|
||||||
|
- task: DownloadPipelineArtifact@2
|
||||||
|
displayName: Download NuGet artifacts
|
||||||
|
inputs:
|
||||||
|
artifact: nupkg
|
||||||
|
path: $(Agent.BuildDirectory)/app/nupkg
|
||||||
|
|
||||||
|
- task: NodeTool@0
|
||||||
|
displayName: Use Node.js $(nodeVersion)
|
||||||
|
inputs:
|
||||||
|
versionSpec: $(nodeVersion)
|
||||||
|
|
||||||
|
- task: UseDotNet@2
|
||||||
|
displayName: Use .NET SDK from global.json
|
||||||
|
inputs:
|
||||||
|
useGlobalJson: true
|
||||||
|
|
||||||
|
- pwsh: |
|
||||||
|
"UMBRACO_USER_LOGIN=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL)
|
||||||
|
UMBRACO_USER_PASSWORD=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||||
|
URL=$(ASPNETCORE_URLS)" | Out-File .env
|
||||||
|
displayName: Generate .env
|
||||||
|
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||||
|
|
||||||
|
# Cache and restore NPM packages
|
||||||
|
- task: Cache@2
|
||||||
|
displayName: Cache NPM packages
|
||||||
|
inputs:
|
||||||
|
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
|
||||||
|
restoreKeys: |
|
||||||
|
npm_e2e | "$(Agent.OS)"
|
||||||
|
npm_e2e
|
||||||
|
path: $(npm_config_cache)
|
||||||
|
|
||||||
|
- script: npm ci --no-fund --no-audit --prefer-offline
|
||||||
|
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||||
|
displayName: Restore NPM packages
|
||||||
|
|
||||||
|
# Build application
|
||||||
|
- pwsh: |
|
||||||
|
$cmsVersion = "$(Build.BuildNumber)" -replace "\+",".g"
|
||||||
|
dotnet new nugetconfig
|
||||||
|
dotnet nuget add source ./nupkg --name Local
|
||||||
|
dotnet new install Umbraco.Templates::$cmsVersion
|
||||||
|
dotnet new umbraco --name UmbracoProject --version $cmsVersion --exclude-gitignore --no-restore --no-update-check
|
||||||
|
dotnet restore UmbracoProject
|
||||||
|
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
|
||||||
|
dotnet build UmbracoProject --configuration $(buildConfiguration) --no-restore
|
||||||
|
dotnet dev-certs https
|
||||||
|
displayName: Build application
|
||||||
|
workingDirectory: $(Agent.BuildDirectory)/app
|
||||||
|
|
||||||
|
# Start SQL Server
|
||||||
|
- powershell: docker run --name mssql -d -p 1433:1433 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=$(SA_PASSWORD)" mcr.microsoft.com/mssql/server:2022-latest
|
||||||
|
displayName: Start SQL Server Docker image (Linux)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||||
|
|
||||||
|
- pwsh: SqlLocalDB start MSSQLLocalDB
|
||||||
|
displayName: Start SQL Server LocalDB (Windows)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
|
|
||||||
|
# Run application
|
||||||
|
- bash: |
|
||||||
|
nohup dotnet run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1 &
|
||||||
|
echo "##vso[task.setvariable variable=AcceptanceTestProcessId]$!"
|
||||||
|
displayName: Run application (Linux)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||||
|
workingDirectory: $(Agent.BuildDirectory)/app
|
||||||
|
|
||||||
|
- pwsh: |
|
||||||
|
$process = Start-Process dotnet "run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile 2>&1" -PassThru -NoNewWindow -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
|
||||||
|
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
|
||||||
|
displayName: Run application (Windows)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
|
workingDirectory: $(Agent.BuildDirectory)/app
|
||||||
|
|
||||||
|
# Wait for application to start responding to requests
|
||||||
|
- pwsh: npx wait-on -v --interval 1000 --timeout 120000 $(ASPNETCORE_URLS)
|
||||||
|
displayName: Wait for application
|
||||||
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||||
|
|
||||||
|
# Install Playwright and dependencies
|
||||||
|
- pwsh: npx playwright install --with-deps
|
||||||
|
displayName: Install Playwright
|
||||||
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||||
|
|
||||||
|
# Test
|
||||||
|
- pwsh: npm run test --ignore-certificate-errors
|
||||||
|
displayName: Run Playwright tests
|
||||||
|
continueOnError: true
|
||||||
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
CommitId: $(Build.SourceVersion)
|
||||||
|
AgentOs: $(Agent.OS)
|
||||||
|
|
||||||
|
# Stop application
|
||||||
|
- bash: kill -15 $(AcceptanceTestProcessId)
|
||||||
|
displayName: Stop application (Linux)
|
||||||
|
condition: and(succeeded(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Linux'))
|
||||||
|
|
||||||
|
- pwsh: Stop-Process -Id $(AcceptanceTestProcessId)
|
||||||
|
displayName: Stop application (Windows)
|
||||||
|
condition: and(succeeded(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
|
|
||||||
|
# Stop SQL Server
|
||||||
|
- pwsh: docker stop mssql
|
||||||
|
displayName: Stop SQL Server Docker image (Linux)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||||
|
|
||||||
|
- pwsh: SqlLocalDB stop MSSQLLocalDB
|
||||||
|
displayName: Stop SQL Server LocalDB (Windows)
|
||||||
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||||
|
|
||||||
|
# Copy artifacts
|
||||||
|
- pwsh: |
|
||||||
|
if (Test-Path tests/Umbraco.Tests.AcceptanceTest/results/*) {
|
||||||
|
Copy-Item tests/Umbraco.Tests.AcceptanceTest/results $(Build.ArtifactStagingDirectory) -Recurse
|
||||||
|
}
|
||||||
|
displayName: Copy Playwright results
|
||||||
|
condition: succeededOrFailed()
|
||||||
|
|
||||||
|
# Publish
|
||||||
|
- task: PublishPipelineArtifact@1
|
||||||
|
displayName: Publish test artifacts
|
||||||
|
condition: succeededOrFailed()
|
||||||
|
inputs:
|
||||||
|
targetPath: $(Build.ArtifactStagingDirectory)
|
||||||
|
artifact: 'Acceptance Tests - $(Agent.JobName) - Attempt #$(System.JobAttempt)'
|
||||||
|
|
||||||
###############################################
|
###############################################
|
||||||
## Release
|
## Release
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "8.0.0",
|
"version": "8.0.100",
|
||||||
"rollForward": "latestFeature",
|
"rollForward": "latestFeature"
|
||||||
"allowPrerelease": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ internal abstract class NestedPropertyIndexValueFactoryBase<TSerialized, TItem>
|
|||||||
published,
|
published,
|
||||||
propertyTypeDictionary,
|
propertyTypeDictionary,
|
||||||
nestedContentRowValue,
|
nestedContentRowValue,
|
||||||
availableCultures));
|
availableCultures,
|
||||||
|
contentTypeDictionary));
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@@ -213,7 +214,8 @@ internal abstract class NestedPropertyIndexValueFactoryBase<TSerialized, TItem>
|
|||||||
bool published,
|
bool published,
|
||||||
IDictionary<string, IPropertyType> propertyTypeDictionary,
|
IDictionary<string, IPropertyType> propertyTypeDictionary,
|
||||||
TItem nestedContentRowValue,
|
TItem nestedContentRowValue,
|
||||||
IEnumerable<string> availableCultures)
|
IEnumerable<string> availableCultures,
|
||||||
|
IDictionary<Guid,IContentType> contentTypeDictionary)
|
||||||
{
|
{
|
||||||
foreach ((var propertyAlias, var propertyValue) in GetRawProperty(nestedContentRowValue))
|
foreach ((var propertyAlias, var propertyValue) in GetRawProperty(nestedContentRowValue))
|
||||||
{
|
{
|
||||||
@@ -238,7 +240,7 @@ internal abstract class NestedPropertyIndexValueFactoryBase<TSerialized, TItem>
|
|||||||
subProperty.PublishValues(availableCulture, segment ?? "*");
|
subProperty.PublishValues(availableCulture, segment ?? "*");
|
||||||
}
|
}
|
||||||
indexValues =
|
indexValues =
|
||||||
editor.PropertyIndexValueFactory.GetIndexValues(subProperty, availableCulture, segment, published, availableCultures);
|
editor.PropertyIndexValueFactory.GetIndexValues(subProperty, availableCulture, segment, published, availableCultures, contentTypeDictionary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -248,7 +250,7 @@ internal abstract class NestedPropertyIndexValueFactoryBase<TSerialized, TItem>
|
|||||||
{
|
{
|
||||||
subProperty.PublishValues(culture ?? "*", segment ?? "*");
|
subProperty.PublishValues(culture ?? "*", segment ?? "*");
|
||||||
}
|
}
|
||||||
indexValues = editor.PropertyIndexValueFactory.GetIndexValues(subProperty, culture, segment, published, availableCultures);
|
indexValues = editor.PropertyIndexValueFactory.GetIndexValues(subProperty, culture, segment, published, availableCultures, contentTypeDictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ((var nestedAlias, IEnumerable<object?> nestedValue) in indexValues)
|
foreach ((var nestedAlias, IEnumerable<object?> nestedValue) in indexValues)
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ public static class ImageCropperTemplateCoreExtensions
|
|||||||
throw new ArgumentNullException(nameof(mediaItem));
|
throw new ArgumentNullException(nameof(mediaItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaItem.HasProperty(propertyAlias) == false || mediaItem.HasValue(propertyAlias) == false)
|
if (mediaItem.HasProperty(propertyAlias) == false || mediaItem.HasValue(publishedValueFallback, propertyAlias) == false)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using Microsoft.Data.Sqlite;
|
||||||
|
using Umbraco.Cms.Core;
|
||||||
|
using Umbraco.Cms.Core.Composing;
|
||||||
|
using Umbraco.Cms.Core.DependencyInjection;
|
||||||
|
using Umbraco.Extensions;
|
||||||
|
|
||||||
|
namespace UmbracoProject;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ensures a SQLite in-memory database is persisted for the whole application duration.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class SQLiteMemoryComposer : IComposer
|
||||||
|
{
|
||||||
|
public void Compose(IUmbracoBuilder builder)
|
||||||
|
{
|
||||||
|
var connectionString = builder.Config.GetUmbracoConnectionString(out var providerName);
|
||||||
|
if (!string.IsNullOrEmpty(connectionString) &&
|
||||||
|
Constants.ProviderNames.SQLLite.InvariantEquals(providerName) &&
|
||||||
|
connectionString.InvariantContains("Mode=Memory"))
|
||||||
|
{
|
||||||
|
// Open new SQLite connection to ensure in-memory database is persisted for the whole application duration
|
||||||
|
var connection = new SqliteConnection(connectionString);
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
// And ensure connection is kept open (by keeping a reference) and gets gracefully closed/disposed when application stops
|
||||||
|
builder.Services.AddHostedService(_ => new SQLiteMemoryHostedService(connection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class SQLiteMemoryHostedService : IHostedService, IAsyncDisposable
|
||||||
|
{
|
||||||
|
private readonly SqliteConnection _connection;
|
||||||
|
|
||||||
|
public SQLiteMemoryHostedService(SqliteConnection connection) => _connection = connection;
|
||||||
|
|
||||||
|
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||||
|
|
||||||
|
public async Task StopAsync(CancellationToken cancellationToken) => await _connection.CloseAsync();
|
||||||
|
|
||||||
|
public async ValueTask DisposeAsync() => await _connection.DisposeAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Umbraco.Cms.Core;
|
||||||
|
using Umbraco.Cms.Core.Composing;
|
||||||
|
using Umbraco.Cms.Core.Configuration.Models;
|
||||||
|
using Umbraco.Cms.Core.DependencyInjection;
|
||||||
|
using Umbraco.Cms.Core.Events;
|
||||||
|
using Umbraco.Cms.Core.Notifications;
|
||||||
|
using Umbraco.Extensions;
|
||||||
|
|
||||||
|
namespace UmbracoProject;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disable waiting on log IO to finish when commiting a transaction (we can tolerate some data loss) on SQL Server.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class SqlServerDelayedDurabilityComposer : IComposer
|
||||||
|
{
|
||||||
|
public void Compose(IUmbracoBuilder builder)
|
||||||
|
{
|
||||||
|
var connectionString = builder.Config.GetUmbracoConnectionString(out var providerName);
|
||||||
|
if (!string.IsNullOrEmpty(connectionString) &&
|
||||||
|
Constants.ProviderNames.SQLServer.InvariantEquals(providerName))
|
||||||
|
{
|
||||||
|
builder.AddNotificationAsyncHandler<UnattendedInstallNotification, SqlServerDelayedDurabilityInstallNotification>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class SqlServerDelayedDurabilityInstallNotification : INotificationAsyncHandler<UnattendedInstallNotification>
|
||||||
|
{
|
||||||
|
private readonly IOptions<ConnectionStrings> _connectionStrings;
|
||||||
|
|
||||||
|
public SqlServerDelayedDurabilityInstallNotification(IOptions<ConnectionStrings> connectionStrings) => _connectionStrings = connectionStrings;
|
||||||
|
|
||||||
|
public async Task HandleAsync(UnattendedInstallNotification notification, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
using var connection = new SqlConnection(_connectionStrings.Value.ConnectionString);
|
||||||
|
await connection.OpenAsync(cancellationToken);
|
||||||
|
|
||||||
|
// Disable waiting on log IO to finish when commiting a transaction (we can tolerate some data loss)
|
||||||
|
var command = new SqlCommand("ALTER DATABASE CURRENT SET DELAYED_DURABILITY = FORCED;", connection);
|
||||||
|
await command.ExecuteNonQueryAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Umbraco.Cms.Core.Composing;
|
||||||
|
using Umbraco.Cms.Core.DependencyInjection;
|
||||||
|
using Umbraco.Cms.Infrastructure;
|
||||||
|
|
||||||
|
namespace UmbracoProject;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Suspends/disables scheduled publishing, because that takes an eager write lock every minute, resulting in flaky test runs on SQLite.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class SuspendScheduledPublishingComposer : IComposer
|
||||||
|
{
|
||||||
|
public void Compose(IUmbracoBuilder builder) => Suspendable.ScheduledPublishing.Suspend();
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
<PropertyGroup>
|
||||||
|
<!-- All C# files in the root of this project will be copied to the E2E/Acceptance Test application during build -->
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<RootNamespace>UmbracoProject</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\Umbraco.Cms\Umbraco.Cms.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project>
|
|
||||||
<!--
|
|
||||||
Keep this empty Directory.Build.props file to prevent inheriting from parent directories,
|
|
||||||
because the Windows E2E test that outputs a new Umbraco project into this directory otherwise won't build.
|
|
||||||
-->
|
|
||||||
</Project>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<packageSources>
|
|
||||||
<clear />
|
|
||||||
<add key="local" value="./nupkg" />
|
|
||||||
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
|
|
||||||
</packageSources>
|
|
||||||
</configuration>
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
############################################
|
|
||||||
## Build
|
|
||||||
############################################
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/nightly/sdk:8.0.100-rc.2-jammy AS build
|
|
||||||
|
|
||||||
COPY nuget.config .
|
|
||||||
|
|
||||||
COPY nuget.config .
|
|
||||||
|
|
||||||
WORKDIR /nupkg
|
|
||||||
COPY nupkg .
|
|
||||||
|
|
||||||
WORKDIR /build
|
|
||||||
RUN dotnet new --install /nupkg/Umbraco.Templates.*.nupkg
|
|
||||||
RUN dotnet new umbraco --name AcceptanceTestProject --no-restore --output .
|
|
||||||
RUN dotnet restore --configfile /nuget.config
|
|
||||||
RUN dotnet build --configuration Release --no-restore
|
|
||||||
RUN dotnet publish --configuration Release --no-build --output /dist
|
|
||||||
|
|
||||||
############################################
|
|
||||||
## Run
|
|
||||||
############################################
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/nightly/aspnet:8.0.0-rc.2-jammy AS run
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
COPY --from=build dist .
|
|
||||||
|
|
||||||
# Enable console logging in Release mode
|
|
||||||
ENV Serilog__WriteTo__0__Name=Async
|
|
||||||
ENV Serilog__WriteTo__0__Args__configure__0__Name=Console
|
|
||||||
|
|
||||||
# Set unattended install settings
|
|
||||||
ENV ConnectionStrings__umbracoDbDSN_ProviderName="Microsoft.Data.Sqlite"
|
|
||||||
ENV ConnectionStrings__umbracoDbDSN="Data Source=|DataDirectory|/Umbraco.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True"
|
|
||||||
ENV Umbraco__CMS__Unattended__InstallUnattended="true"
|
|
||||||
ENV Umbraco__CMS__Unattended__UnattendedUserName="Playwright Test"
|
|
||||||
ENV Umbraco__CMS__Unattended__UnattendedUserEmail="playwright@umbraco.com"
|
|
||||||
ENV Umbraco__CMS__Unattended__UnattendedUserPassword="UmbracoAcceptance123!"
|
|
||||||
|
|
||||||
# Custom Umbraco settings
|
|
||||||
ENV Umbraco__CMS__Global__VersionCheckPeriod="0"
|
|
||||||
ENV Umbraco__CMS__Global__UseHttps="true"
|
|
||||||
ENV Umbraco__CMS__HealthChecks__Notification__Enabled="false"
|
|
||||||
ENV Umbraco__CMS__KeepAlive__DisableKeepAliveTask="true"
|
|
||||||
|
|
||||||
# Set application URL
|
|
||||||
ENV ASPNETCORE_URLS="http://0.0.0.0:5000;https://0.0.0.0:5001"
|
|
||||||
|
|
||||||
CMD dotnet AcceptanceTestProject.dll
|
|
||||||
12
umbraco.sln
12
umbraco.sln
@@ -140,14 +140,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
global.json = global.json
|
global.json = global.json
|
||||||
icon.png = icon.png
|
icon.png = icon.png
|
||||||
LICENSE.md = LICENSE.md
|
LICENSE.md = LICENSE.md
|
||||||
umbraco.sln.DotSettings = umbraco.sln.DotSettings
|
|
||||||
nuget.config = nuget.config
|
nuget.config = nuget.config
|
||||||
|
umbraco.sln.DotSettings = umbraco.sln.DotSettings
|
||||||
version.json = version.json
|
version.json = version.json
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{20CE9C97-9314-4A19-BCF1-D12CF49B7205}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{20CE9C97-9314-4A19-BCF1-D12CF49B7205}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
build\azure-pipelines.yml = build\azure-pipelines.yml
|
build\azure-pipelines.yml = build\azure-pipelines.yml
|
||||||
|
build\nightly-build-trigger.yml = build\nightly-build-trigger.yml
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp-docs", "csharp-docs", "{F2BF84D9-0A14-40AF-A0F3-B9BBBBC16A44}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "csharp-docs", "csharp-docs", "{F2BF84D9-0A14-40AF-A0F3-B9BBBBC16A44}"
|
||||||
@@ -214,6 +215,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Cms.Persistence.EFC
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Cms.Persistence.EFCore.SqlServer", "src\Umbraco.Cms.Persistence.EFCore.SqlServer\Umbraco.Cms.Persistence.EFCore.SqlServer.csproj", "{9276C3F0-0DC9-46C9-BF32-9EE79D92AE02}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Cms.Persistence.EFCore.SqlServer", "src\Umbraco.Cms.Persistence.EFCore.SqlServer\Umbraco.Cms.Persistence.EFCore.SqlServer.csproj", "{9276C3F0-0DC9-46C9-BF32-9EE79D92AE02}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests.AcceptanceTest.UmbracoProject", "tests\Umbraco.Tests.AcceptanceTest.UmbracoProject\Umbraco.Tests.AcceptanceTest.UmbracoProject.csproj", "{A13FF0A0-69FA-468A-9F79-565401D5C341}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -408,6 +411,12 @@ Global
|
|||||||
{9276C3F0-0DC9-46C9-BF32-9EE79D92AE02}.Release|Any CPU.Build.0 = Release|Any CPU
|
{9276C3F0-0DC9-46C9-BF32-9EE79D92AE02}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{9276C3F0-0DC9-46C9-BF32-9EE79D92AE02}.SkipTests|Any CPU.ActiveCfg = Debug|Any CPU
|
{9276C3F0-0DC9-46C9-BF32-9EE79D92AE02}.SkipTests|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{9276C3F0-0DC9-46C9-BF32-9EE79D92AE02}.SkipTests|Any CPU.Build.0 = Debug|Any CPU
|
{9276C3F0-0DC9-46C9-BF32-9EE79D92AE02}.SkipTests|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A13FF0A0-69FA-468A-9F79-565401D5C341}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A13FF0A0-69FA-468A-9F79-565401D5C341}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A13FF0A0-69FA-468A-9F79-565401D5C341}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A13FF0A0-69FA-468A-9F79-565401D5C341}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A13FF0A0-69FA-468A-9F79-565401D5C341}.SkipTests|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A13FF0A0-69FA-468A-9F79-565401D5C341}.SkipTests|Any CPU.Build.0 = Debug|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -429,6 +438,7 @@ Global
|
|||||||
{EA628ABD-624E-4AF3-B548-6710D4D66531} = {2B47AD9F-FFF1-448A-88F1-D4F568811738}
|
{EA628ABD-624E-4AF3-B548-6710D4D66531} = {2B47AD9F-FFF1-448A-88F1-D4F568811738}
|
||||||
{C55CA725-9F4E-4618-9435-6B8AE05DA14D} = {995D9EFA-8BB1-4333-80AD-C525A06FD984}
|
{C55CA725-9F4E-4618-9435-6B8AE05DA14D} = {995D9EFA-8BB1-4333-80AD-C525A06FD984}
|
||||||
{D88A926B-E8D6-495A-A2ED-8EFD0C847C62} = {995D9EFA-8BB1-4333-80AD-C525A06FD984}
|
{D88A926B-E8D6-495A-A2ED-8EFD0C847C62} = {995D9EFA-8BB1-4333-80AD-C525A06FD984}
|
||||||
|
{A13FF0A0-69FA-468A-9F79-565401D5C341} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {7A0F2E34-D2AF-4DAB-86A0-7D7764B3D0EC}
|
SolutionGuid = {7A0F2E34-D2AF-4DAB-86A0-7D7764B3D0EC}
|
||||||
|
|||||||
Reference in New Issue
Block a user