* Added appsettings * Added test setup for different config * Added appsettings for external login * Added acceptance tests * Updated pipelines * Updated solution file * V15 QA Added external login provider tests and split pipeline into templates (#20049) * Added setup for external login * Started on yaml * Added test file * Updated pipeline * Use env vars * Added env variables and commented out test we don't need to run * Removed list from matrix * Updated condition * Updated package path * Updated testFolder * double slash * Updated condition * Updated condition again * Added port * Removed redundant values * Set as env vars * Added env vars beneath matrix * Get env * Updated naming * Updated usage of values * Added a check for client id, to see if value set * Moved env out of pool * Tried moving env * Trying to fix the env being empty * Removed env * Updated name of variable * Fixed A cyclical reference * Updated typo * More logging * Reverted change * Added env * Added env to tests * Cleaned up * Added yaml template files * Updated nighly pipepline to use templates * Updated sln * Split yaml into templates for e2e setup * Updated pipeline * Updated solution file * Set value * Added if statement * Added variables * Set default values * Updated values * Updated condition * Run multiple tests * Added env * Updated from parameter to variable * Fixed condition * Fixed condition to use actual value * Updated npx wait on command * Updated pwsh * Updated port again * Updated port value * Updated wait on * Updated condition * Restructured * Updated var * Updated run application steps * Added echo * Updated to boolean * Updated conditions * Updated test template usage * Added databaseType * Added another databaseType * Split up templates * Fixed indentation * Updated condition * updated path * removed build from path * Updated conditions for azureAd * Fixed indentation * Updated to single qoutes * Cleaned up * Removed unused file * Clarified namin * Moved * Updated pipeline, not done * Updated locator * Updated pipelines * Updated test helpers package * Skipped build stage for default app settings tests * Updated password var * Updated locators * Updated defaultconfig build setup * Split E2E stage in two * Added parameter for skipping integration tests * Cleaned up * Added ASPNETCORE_URLS * V15 QA acceptance tests with appsettings (#19550) * Start of appsetting * Updated setup of playwright * Adjusted the pipeline * Updated appsetting * Added install test * Added comments * Updated pipeline * Updated development app settings * Commented tests out * comment * Added if statement * Updated pipeline * Fixed condition * Changed to production * Added a log * Updated copy item * Added * Updated app settings * Updated pipeline * Moved playwright login * Updated pipeline * Updated app setting * Updated nightly * Updated appsettings * Updated get * Updated wait on * Updated appsettings * Updated connection string * Updates * Skips code * Updated variable * Updated pipeline * We want to always retain the trace, to see if the test runs as expected on the pipeline * Added a temporary wait till port is open * Fixed condition * Added missing tcp for wait on * Updated URL env * Updated setup * Fixed string * Updated locator * Split tests into SQLite and SQLServer * Updated pipeline to run all tests * Retain trace on failure * Added testFolder var * Added appsettings and program for delivery api tests * Updated playwright config * Split test runners into defaultconfig and different app settings * Added delivery api tests * Cleaned up tests * Bumped version * Updated pipeline * Small fixes * Added password * Updated connection string * Fixed * Removed quotes * Removed unnecessary connection string * Added missing password * Cleaned up * Cleaned up * Cleaned up * Updated to use helpers * Bumped version * Updated helper usage * Added password to variables and a condition * Added check * Indented value * Fixed condition * More updates * Updated variable * Removed settings * Updated delivery api tests * Bumped version * Updated test * Removed unnecessary variables * Updates based on copilot comments * Fixed merge conflict * Fixed env creation step * Bumped version * Updated tests to use new helper * Updated helper * Updated to string * Moved logic to conditions * bumped version * Use new name for helper * Remove echo * Added variable
877 lines
38 KiB
YAML
877 lines
38 KiB
YAML
name: $(TeamProject)_$(Build.DefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
|
|
|
|
parameters:
|
|
- name: sqlServerIntegrationTests
|
|
displayName: Run SQL Server Integration Tests
|
|
type: boolean
|
|
default: false
|
|
- name: sqlServerLinuxAcceptanceTests
|
|
displayName: Run SQL Server Linux Acceptance Tests
|
|
type: boolean
|
|
default: false
|
|
# Skipped due to DB locks, the tests are still being run on the Nightly build
|
|
- name: sqliteAcceptanceTests
|
|
displayName: Run SQLite Acceptance Tests
|
|
type: boolean
|
|
default: false
|
|
- name: myGetDeploy
|
|
displayName: Deploy to MyGet
|
|
type: boolean
|
|
default: false
|
|
- name: nuGetDeploy
|
|
displayName: Deploy to NuGet
|
|
type: boolean
|
|
default: false
|
|
- name: npmDeploy
|
|
displayName: Deploy to Npm
|
|
type: boolean
|
|
default: false
|
|
- name: buildApiDocs
|
|
displayName: Build API docs
|
|
type: boolean
|
|
default: false
|
|
- name: uploadApiDocs
|
|
displayName: Upload API docs
|
|
type: boolean
|
|
default: false
|
|
- name: forceReleaseTestFilter
|
|
displayName: Force to use the release test filters
|
|
type: boolean
|
|
default: false
|
|
- name: integrationNonReleaseTestFilter
|
|
displayName: TestFilter used for non-release type builds
|
|
type: string
|
|
default: "--filter TestCategory!=LongRunning&TestCategory!=NonCritical"
|
|
- name: integrationReleaseTestFilter
|
|
displayName: TestFilter used for release type builds
|
|
type: string
|
|
default: " "
|
|
- name: nonWindowsIntegrationNonReleaseTestFilter
|
|
displayName: TestFilter used for non-release type builds on non Windows agents
|
|
type: string
|
|
default: "--filter TestCategory!=LongRunning&TestCategory!=NonCritical"
|
|
- name: nonWindowsIntegrationReleaseTestFilter
|
|
displayName: TestFilter used for release type builds on non Windows agents
|
|
type: string
|
|
default: " "
|
|
- name: isNightly
|
|
displayName: "Is nightly build (used for MyGet feed)"
|
|
type: boolean
|
|
default: false
|
|
|
|
variables:
|
|
nodeVersion: 20
|
|
solution: umbraco.sln
|
|
buildConfiguration: Release
|
|
UMBRACO__CMS__GLOBAL__ID: 00000000-0000-0000-0000-000000000042
|
|
DOTNET_NOLOGO: true
|
|
DOTNET_GENERATE_ASPNET_CERTIFICATE: false
|
|
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
|
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
|
npm_config_cache: $(Pipeline.Workspace)/.npm_client
|
|
NODE_OPTIONS: --max_old_space_size=16384
|
|
|
|
stages:
|
|
###############################################
|
|
## Build
|
|
###############################################
|
|
- stage: Build
|
|
jobs:
|
|
- job: A
|
|
displayName: Build Umbraco CMS
|
|
pool:
|
|
vmImage: "windows-latest"
|
|
steps:
|
|
- checkout: self
|
|
submodules: false
|
|
lfs: false,
|
|
fetchDepth: 500
|
|
- template: templates/backoffice-install.yml
|
|
- task: UseDotNet@2
|
|
displayName: Use .NET SDK from global.json
|
|
inputs:
|
|
useGlobalJson: true
|
|
- task: DotNetCoreCLI@2
|
|
displayName: Run dotnet restore
|
|
inputs:
|
|
command: restore
|
|
projects: $(solution)
|
|
- task: DotNetCoreCLI@2
|
|
name: build
|
|
displayName: Run dotnet build and generate NuGet packages
|
|
inputs:
|
|
command: build
|
|
projects: $(solution)
|
|
arguments: "--configuration $(buildConfiguration) --no-restore --property:ContinuousIntegrationBuild=true --property:GeneratePackageOnBuild=true --property:PackageOutputPath=$(Build.ArtifactStagingDirectory)/nupkg"
|
|
- task: PublishPipelineArtifact@1
|
|
displayName: Publish nupkg
|
|
inputs:
|
|
targetPath: $(Build.ArtifactStagingDirectory)/nupkg
|
|
artifactName: nupkg
|
|
- task: PublishPipelineArtifact@1
|
|
displayName: Publish build artifacts
|
|
inputs:
|
|
targetPath: $(Build.SourcesDirectory)
|
|
artifactName: build_output
|
|
|
|
- job: B
|
|
displayName: Build Bellissima Package
|
|
pool:
|
|
vmImage: "ubuntu-latest"
|
|
steps:
|
|
- checkout: self
|
|
submodules: false
|
|
lfs: false,
|
|
fetchDepth: 500
|
|
- template: templates/backoffice-install.yml
|
|
- script: npm run build:for:npm
|
|
displayName: Run build:for:npm
|
|
workingDirectory: src/Umbraco.Web.UI.Client
|
|
- bash: |
|
|
echo "##[command]Running npm pack"
|
|
echo "##[debug]Output directory: $(Build.ArtifactStagingDirectory)"
|
|
mkdir $(Build.ArtifactStagingDirectory)/npm
|
|
npm pack --pack-destination $(Build.ArtifactStagingDirectory)/npm
|
|
mv .npmrc $(Build.ArtifactStagingDirectory)/npm/
|
|
displayName: Run npm pack
|
|
workingDirectory: src/Umbraco.Web.UI.Client
|
|
- task: PublishPipelineArtifact@1
|
|
displayName: Publish Bellissima npm artifact
|
|
inputs:
|
|
targetPath: $(Build.ArtifactStagingDirectory)/npm
|
|
artifactName: npm
|
|
|
|
- stage: Build_Docs
|
|
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.buildApiDocs}}))
|
|
displayName: Prepare API Documentation
|
|
dependsOn: Build
|
|
variables:
|
|
umbracoMajorVersion: $[ stageDependencies.Build.A.outputs['build.NBGV_VersionMajor'] ]
|
|
jobs:
|
|
# C# API Reference
|
|
- job:
|
|
displayName: Build C# API Reference
|
|
pool:
|
|
vmImage: "windows-latest"
|
|
steps:
|
|
- task: UseDotNet@2
|
|
displayName: Use .NET SDK from global.json
|
|
inputs:
|
|
useGlobalJson: true
|
|
- task: PowerShell@2
|
|
displayName: Install DocFX
|
|
inputs:
|
|
targetType: inline
|
|
script: |
|
|
choco install docfx --version=2.59.4 -y
|
|
if ($lastexitcode -ne 0){
|
|
throw ("Error installing DocFX")
|
|
}
|
|
- task: PowerShell@2
|
|
displayName: Generate metadata
|
|
inputs:
|
|
targetType: inline
|
|
script: |
|
|
docfx metadata "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
|
|
if ($lastexitcode -ne 0){
|
|
throw ("Error generating metadata.")
|
|
}
|
|
- task: PowerShell@2
|
|
displayName: Generate documentation
|
|
inputs:
|
|
targetType: inline
|
|
script: |
|
|
docfx build "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
|
|
if ($lastexitcode -ne 0){
|
|
throw ("Error generating documentation.")
|
|
}
|
|
- task: ArchiveFiles@2
|
|
displayName: Archive C# Docs
|
|
inputs:
|
|
rootFolderOrFile: $(Build.SourcesDirectory)/build/csharp-docs/_site
|
|
includeRootFolder: false
|
|
archiveFile: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
|
|
- task: PublishPipelineArtifact@1
|
|
displayName: Publish C# Docs
|
|
inputs:
|
|
targetPath: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
|
|
artifact: csharp-docs
|
|
|
|
# js API Reference
|
|
- job:
|
|
displayName: Build js API Reference
|
|
pool:
|
|
vmImage: "ubuntu-latest"
|
|
variables:
|
|
BASE_PATH: /v$(umbracoMajorVersion)/ui
|
|
steps:
|
|
- checkout: self
|
|
submodules: false
|
|
lfs: false,
|
|
fetchDepth: 1
|
|
fetchFilter: tree:0
|
|
- template: templates/backoffice-install.yml
|
|
- script: npm run storybook:build
|
|
displayName: Build Storybook
|
|
env:
|
|
VITE_BASE_PATH: $(BASE_PATH)/
|
|
workingDirectory: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Client
|
|
- script: sed -i "s|/umbraco/backoffice|$(BASE_PATH)/umbraco/backoffice|" assets/*.js
|
|
displayName: Replace BASE_PATH on assets
|
|
workingDirectory: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Client/storybook-static
|
|
- task: ArchiveFiles@2
|
|
displayName: Archive Storybook
|
|
inputs:
|
|
rootFolderOrFile: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Client/storybook-static
|
|
includeRootFolder: false
|
|
archiveFile: $(Build.ArtifactStagingDirectory)/ui-docs.zip
|
|
- task: PublishPipelineArtifact@1
|
|
displayName: Publish Storybook
|
|
inputs:
|
|
targetPath: $(Build.ArtifactStagingDirectory)/ui-docs.zip
|
|
artifact: ui-docs
|
|
- script: npm run generate:ui-api-docs
|
|
displayName: Generate API Docs
|
|
workingDirectory: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Client
|
|
- task: ArchiveFiles@2
|
|
displayName: Archive UI API Docs
|
|
inputs:
|
|
rootFolderOrFile: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Client/ui-api
|
|
includeRootFolder: false
|
|
archiveFile: $(Build.ArtifactStagingDirectory)/ui-api-docs.zip
|
|
- task: PublishPipelineArtifact@1
|
|
displayName: Publish UI API Docs
|
|
inputs:
|
|
targetPath: $(Build.ArtifactStagingDirectory)/ui-api-docs.zip
|
|
artifact: ui-api-docs
|
|
|
|
###############################################
|
|
## Test
|
|
###############################################
|
|
- stage: Unit
|
|
displayName: Unit Tests
|
|
dependsOn: Build
|
|
jobs:
|
|
# Unit Tests
|
|
- job:
|
|
displayName: Unit Tests
|
|
strategy:
|
|
matrix:
|
|
Windows:
|
|
vmImage: "windows-latest"
|
|
Linux:
|
|
vmImage: "ubuntu-latest"
|
|
macOS:
|
|
vmImage: "macOS-latest"
|
|
pool:
|
|
vmImage: $(vmImage)
|
|
steps:
|
|
- checkout: self
|
|
submodules: false
|
|
lfs: false,
|
|
fetchDepth: 1
|
|
fetchFilter: tree:0
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download build artifacts
|
|
inputs:
|
|
artifact: build_output
|
|
path: $(Build.SourcesDirectory)
|
|
- task: UseDotNet@2
|
|
displayName: Use .NET SDK from global.json
|
|
inputs:
|
|
useGlobalJson: true
|
|
- task: DotNetCoreCLI@2
|
|
displayName: Run dotnet test
|
|
inputs:
|
|
command: test
|
|
projects: "tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj"
|
|
arguments: "--configuration $(buildConfiguration) --no-build"
|
|
testRunTitle: Unit Tests - $(Agent.OS)
|
|
|
|
- stage: Integration
|
|
displayName: Integration Tests
|
|
dependsOn: Build
|
|
variables:
|
|
releaseTestFilter: eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True')
|
|
jobs:
|
|
# Integration Tests (SQLite)
|
|
- job:
|
|
timeoutInMinutes: 180
|
|
displayName: Integration Tests (SQLite)
|
|
strategy:
|
|
matrix:
|
|
# Windows:
|
|
# vmImage: 'windows-latest'
|
|
# We split the tests into 3 parts for each OS to reduce the time it takes to run them on the pipeline
|
|
LinuxPart1Of3:
|
|
vmImage: "ubuntu-latest"
|
|
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
|
|
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
|
|
LinuxPart2Of3:
|
|
vmImage: "ubuntu-latest"
|
|
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
|
|
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
|
LinuxPart3Of3:
|
|
vmImage: "ubuntu-latest"
|
|
# Filter tests that are not part of the Umbraco.Infrastructure namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
|
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
|
|
macOSPart1Of3:
|
|
vmImage: "macOS-latest"
|
|
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
|
|
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
|
|
macOSPart2Of3:
|
|
vmImage: "macOS-latest"
|
|
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
|
|
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
|
macOSPart3Of3:
|
|
vmImage: "macOS-latest"
|
|
# Filter tests that are not part of the Umbraco.Infrastructure namespace.
|
|
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
|
|
pool:
|
|
vmImage: $(vmImage)
|
|
variables:
|
|
Tests__Database__DatabaseType: "Sqlite"
|
|
steps:
|
|
- checkout: self
|
|
submodules: false
|
|
lfs: false,
|
|
fetchDepth: 1
|
|
fetchFilter: tree:0
|
|
# Setup test environment
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download build artifacts
|
|
inputs:
|
|
artifact: build_output
|
|
path: $(Build.SourcesDirectory)
|
|
|
|
- task: UseDotNet@2
|
|
displayName: Use .NET SDK from global.json
|
|
inputs:
|
|
useGlobalJson: true
|
|
|
|
# Test
|
|
- task: DotNetCoreCLI@2
|
|
displayName: Run dotnet test
|
|
inputs:
|
|
command: test
|
|
projects: "tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj"
|
|
testRunTitle: Integration Tests SQLite - $(Agent.OS)
|
|
${{ if and(eq(variables['Agent.OS'],'Windows_NT'), or(variables.releaseTestFilter, parameters.forceReleaseTestFilter)) }}:
|
|
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build ${{parameters.integrationReleaseTestFilter}}'
|
|
${{ elseif eq(variables['Agent.OS'],'Windows_NT') }}:
|
|
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build ${{parameters.integrationNonReleaseTestFilter}}'
|
|
${{ elseif or(variables.releaseTestFilter, parameters.forceReleaseTestFilter) }}:
|
|
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationReleaseTestFilter}}'
|
|
${{ else }}:
|
|
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationNonReleaseTestFilter}}'
|
|
# Integration Tests (SQL Server)
|
|
- job:
|
|
timeoutInMinutes: 180
|
|
# condition: or(eq(stageDependencies.Build.A.outputs['build.NBGV_PublicRelease'], 'True'), ${{parameters.sqlServerIntegrationTests}}) # Outcommented due to timeouts
|
|
condition: eq(${{parameters.sqlServerIntegrationTests}}, True)
|
|
displayName: Integration Tests (SQL Server)
|
|
strategy:
|
|
matrix:
|
|
# We split the tests into 3 parts for each OS to reduce the time it takes to run them on the pipeline
|
|
WindowsPart1Of3:
|
|
vmImage: "windows-latest"
|
|
Tests__Database__DatabaseType: LocalDb
|
|
Tests__Database__SQLServerMasterConnectionString: N/A
|
|
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
|
|
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
|
|
WindowsPart2Of3:
|
|
vmImage: "windows-latest"
|
|
Tests__Database__DatabaseType: LocalDb
|
|
Tests__Database__SQLServerMasterConnectionString: N/A
|
|
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
|
|
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
|
WindowsPart3Of3:
|
|
vmImage: "windows-latest"
|
|
Tests__Database__DatabaseType: LocalDb
|
|
Tests__Database__SQLServerMasterConnectionString: N/A
|
|
# Filter tests that are not part of the Umbraco.Infrastructure namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
|
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
|
|
LinuxPart1Of3:
|
|
vmImage: "ubuntu-latest"
|
|
SA_PASSWORD: UmbracoIntegration123!
|
|
Tests__Database__DatabaseType: SqlServer
|
|
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
|
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
|
|
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
|
|
LinuxPart2Of3:
|
|
vmImage: "ubuntu-latest"
|
|
SA_PASSWORD: UmbracoIntegration123!
|
|
Tests__Database__DatabaseType: SqlServer
|
|
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
|
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
|
|
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
|
LinuxPart3Of3:
|
|
vmImage: "ubuntu-latest"
|
|
SA_PASSWORD: UmbracoIntegration123!
|
|
Tests__Database__DatabaseType: SqlServer
|
|
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
|
# Filter tests that are not part of the Umbraco.Infrastructure namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
|
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
|
|
pool:
|
|
vmImage: $(vmImage)
|
|
steps:
|
|
# Setup test environment
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download build artifacts
|
|
inputs:
|
|
artifact: build_output
|
|
path: $(Build.SourcesDirectory)
|
|
|
|
- task: UseDotNet@2
|
|
displayName: Use .NET SDK from global.json
|
|
inputs:
|
|
useGlobalJson: true
|
|
|
|
# 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'))
|
|
|
|
- powershell: |
|
|
$maxAttempts = 12
|
|
$attempt = 0
|
|
$status = ""
|
|
|
|
while (($status -ne 'running') -and ($attempt -lt $maxAttempts)) {
|
|
Start-Sleep -Seconds 5
|
|
# We use the docker inspect command to check the status of the container. If the container is not running, we wait 5 seconds and try again. And if reaches 12 attempts, we fail the build.
|
|
$status = docker inspect -f '{{.State.Status}}' mssql
|
|
|
|
if ($status -ne 'running') {
|
|
Write-Host "Waiting for SQL Server to be ready... Attempt $($attempt + 1)"
|
|
$attempt++
|
|
}
|
|
}
|
|
|
|
if ($status -eq 'running') {
|
|
Write-Host "SQL Server container is running"
|
|
docker ps -a
|
|
} else {
|
|
Write-Host "SQL Server did not become ready in time. Last known status: $status"
|
|
docker logs mssql
|
|
exit 1
|
|
}
|
|
displayName: Wait for SQL Server to be ready (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
|
|
displayName: Run dotnet test
|
|
inputs:
|
|
command: test
|
|
projects: "tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj"
|
|
testRunTitle: Integration Tests SQL Server - $(Agent.OS)
|
|
${{ if and(eq(variables['Agent.OS'],'Windows_NT'), or(variables.releaseTestFilter, parameters.forceReleaseTestFilter)) }}:
|
|
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build ${{parameters.integrationReleaseTestFilter}}'
|
|
${{ elseif eq(variables['Agent.OS'],'Windows_NT') }}:
|
|
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build ${{parameters.integrationNonReleaseTestFilter}}'
|
|
${{ elseif or(variables.releaseTestFilter, parameters.forceReleaseTestFilter) }}:
|
|
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationReleaseTestFilter}}'
|
|
${{ else }}:
|
|
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationNonReleaseTestFilter}}'
|
|
|
|
# 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'))
|
|
|
|
- stage: E2E
|
|
displayName: E2E Tests
|
|
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:
|
|
# E2E Smoke Tests
|
|
- job:
|
|
displayName: E2E Smoke Tests (SQLite)
|
|
# currently disabled due to DB locks randomly occuring.
|
|
condition: eq(${{parameters.sqliteAcceptanceTests}}, True)
|
|
variables:
|
|
# Connection string
|
|
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=Umbraco;Mode=Memory;Cache=Shared;Foreign Keys=True;Pooling=True
|
|
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.Sqlite
|
|
DatabaseType: SQLite
|
|
additionalEnvironmentVariables: false
|
|
strategy:
|
|
matrix:
|
|
LinuxPart1Of3:
|
|
vmImage: "ubuntu-latest"
|
|
testFolder: "DefaultConfig"
|
|
testCommand: "npm run smokeTestSqlite -- --shard=1/3"
|
|
LinuxPart2Of3:
|
|
vmImage: "ubuntu-latest"
|
|
testFolder: "DefaultConfig"
|
|
testCommand: "npm run smokeTestSqlite -- --shard=2/3"
|
|
LinuxPart3Of3:
|
|
vmImage: "ubuntu-latest"
|
|
testFolder: "DefaultConfig"
|
|
testCommand: "npm run smokeTestSqlite -- --shard=3/3"
|
|
WindowsPart1Of3:
|
|
vmImage: "windows-latest"
|
|
testFolder: "DefaultConfig"
|
|
testCommand: "npm run smokeTestSqlite -- --shard=1/3"
|
|
WindowsPart2Of3:
|
|
vmImage: "windows-latest"
|
|
testFolder: "DefaultConfig"
|
|
testCommand: "npm run smokeTestSqlite -- --shard=2/3"
|
|
WindowsPart3Of3:
|
|
vmImage: "windows-latest"
|
|
testFolder: "DefaultConfig"
|
|
testCommand: "npm run smokeTestSqlite -- --shard=3/3"
|
|
pool:
|
|
vmImage: $(vmImage)
|
|
steps:
|
|
# Setup test environment Template
|
|
- template: nightly-E2E-setup-template.yml
|
|
parameters:
|
|
nodeVersion: ${{ variables.nodeVersion }}
|
|
PlaywrightUserEmail: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL }}
|
|
PlaywrightPassword: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD }}
|
|
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
|
npm_config_cache: ${{ variables.npm_config_cache }}
|
|
|
|
- pwsh: |
|
|
dotnet restore UmbracoProject
|
|
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
|
|
displayName: Restore project
|
|
workingDirectory: $(Agent.BuildDirectory)/app
|
|
|
|
- pwsh: |
|
|
dotnet build UmbracoProject --configuration ${{ variables.buildConfiguration }} --no-restore
|
|
dotnet dev-certs https
|
|
displayName: Build application
|
|
workingDirectory: $(Agent.BuildDirectory)/app
|
|
condition: succeeded()
|
|
|
|
# Run application Template
|
|
- template: nightly-E2E-run-application-template.yml
|
|
parameters:
|
|
DatabaseType: ${{ variables.DatabaseType }}
|
|
buildConfiguration: ${{ variables.buildConfiguration }}
|
|
additionalEnvironmentVariables: ${{ variables.additionalEnvironmentVariables }}
|
|
|
|
# Run tests Template
|
|
- template: nightly-E2E-run-tests-template.yml
|
|
parameters:
|
|
testCommand: $(testCommand)
|
|
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
|
DatabaseType: ${{ variables.DatabaseType }}
|
|
|
|
- job:
|
|
displayName: E2E Smoke Tests (SQL Server)
|
|
variables:
|
|
# Connection string
|
|
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Umbraco.mdf;Integrated Security=True
|
|
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.SqlClient
|
|
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
|
DatabaseType: SQLServer
|
|
additionalEnvironmentVariables: false
|
|
strategy:
|
|
matrix:
|
|
${{ if eq(parameters.sqlServerLinuxAcceptanceTests, True) }}:
|
|
LinuxPart1Of3:
|
|
testCommand: "npm run smokeTest -- --shard=1/3"
|
|
vmImage: "ubuntu-latest"
|
|
testFolder: "DefaultConfig"
|
|
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
|
LinuxPart2Of3:
|
|
testCommand: "npm run smokeTest -- --shard=2/3"
|
|
vmImage: "ubuntu-latest"
|
|
testFolder: "DefaultConfig"
|
|
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
|
LinuxPart3Of3:
|
|
testCommand: "npm run smokeTest -- --shard=3/3"
|
|
vmImage: "ubuntu-latest"
|
|
testFolder: "DefaultConfig"
|
|
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
|
WindowsPart1Of3:
|
|
vmImage: "windows-latest"
|
|
testFolder: "DefaultConfig"
|
|
testCommand: "npm run smokeTest -- --shard=1/3"
|
|
WindowsPart2Of3:
|
|
vmImage: "windows-latest"
|
|
testFolder: "DefaultConfig"
|
|
testCommand: "npm run smokeTest -- --shard=2/3"
|
|
WindowsPart3Of3:
|
|
vmImage: "windows-latest"
|
|
testFolder: "DefaultConfig"
|
|
testCommand: "npm run smokeTest -- --shard=3/3"
|
|
pool:
|
|
vmImage: $(vmImage)
|
|
steps:
|
|
# Setup test environment Template
|
|
- template: nightly-E2E-setup-template.yml
|
|
parameters:
|
|
nodeVersion: ${{ variables.nodeVersion }}
|
|
PlaywrightUserEmail: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL }}
|
|
PlaywrightPassword: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD }}
|
|
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
|
npm_config_cache: ${{ variables.npm_config_cache }}
|
|
|
|
- pwsh: |
|
|
dotnet restore UmbracoProject
|
|
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
|
|
displayName: Restore project
|
|
workingDirectory: $(Agent.BuildDirectory)/app
|
|
|
|
- pwsh: |
|
|
dotnet build UmbracoProject --configuration ${{ variables.buildConfiguration }} --no-restore
|
|
dotnet dev-certs https
|
|
displayName: Build application
|
|
workingDirectory: $(Agent.BuildDirectory)/app
|
|
condition: succeeded()
|
|
|
|
# Run application Template
|
|
- template: nightly-E2E-run-application-template.yml
|
|
parameters:
|
|
SA_PASSWORD: ${{ variables.SA_PASSWORD }}
|
|
buildConfiguration: ${{ variables.buildConfiguration }}
|
|
DatabaseType: ${{ variables.DatabaseType }}
|
|
additionalEnvironmentVariables: ${{ variables.additionalEnvironmentVariables }}
|
|
|
|
# Run tests Template
|
|
- template: nightly-E2E-run-tests-template.yml
|
|
parameters:
|
|
testCommand: $(testCommand)
|
|
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
|
DatabaseType: ${{ variables.DatabaseType }}
|
|
|
|
###############################################
|
|
## Release
|
|
###############################################
|
|
- stage: Deploy_MyGet
|
|
displayName: MyGet pre-release
|
|
dependsOn:
|
|
- Unit
|
|
- Integration
|
|
- E2E
|
|
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.myGetDeploy}}))
|
|
jobs:
|
|
- job:
|
|
pool:
|
|
vmImage: "windows-latest" # NuGetCommand@2 is no longer supported on Ubuntu 24.04 so we'll use windows until an alternative is available.
|
|
displayName: Push to pre-release feed
|
|
steps:
|
|
- checkout: none
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download nupkg
|
|
inputs:
|
|
artifact: nupkg
|
|
path: $(Build.ArtifactStagingDirectory)/nupkg
|
|
- task: NuGetCommand@2
|
|
displayName: NuGet push
|
|
inputs:
|
|
command: "push"
|
|
packagesToPush: $(Build.ArtifactStagingDirectory)/**/*.nupkg
|
|
nuGetFeedType: "external"
|
|
${{ if eq(parameters.isNightly, true) }}:
|
|
publishFeedCredentials: "MyGet - Umbraco Nightly"
|
|
${{ else }}:
|
|
publishFeedCredentials: "MyGet - Pre-releases"
|
|
- job:
|
|
displayName: Push to pre-release feed (npm)
|
|
steps:
|
|
- checkout: none
|
|
- download: current
|
|
artifact: npm
|
|
- bash: |
|
|
# Check if we are on a nightly build
|
|
if [ $isNightly = "False" ]; then
|
|
echo "##[debug]Prerelease build detected"
|
|
registry="https://www.myget.org/F/umbracoprereleases/npm/"
|
|
else
|
|
echo "##[debug]Nightly build detected"
|
|
registry="https://www.myget.org/F/umbraconightly/npm/"
|
|
fi
|
|
echo "@umbraco-cms:registry=$registry" >> .npmrc
|
|
env:
|
|
isNightly: ${{parameters.isNightly}}
|
|
workingDirectory: $(Pipeline.Workspace)/npm
|
|
displayName: Add scoped registry to .npmrc
|
|
- task: npmAuthenticate@0
|
|
displayName: Authenticate with npm (MyGet)
|
|
inputs:
|
|
workingFile: "$(Pipeline.Workspace)/npm/.npmrc"
|
|
customEndpoint: "MyGet (npm) - Umbracoprereleases, MyGet (npm) - Umbraconightly"
|
|
- bash: |
|
|
# Setup temp npm project to load in defaults from the local .npmrc
|
|
npm init -y
|
|
|
|
# Find the first .tgz file in the current directory and publish it
|
|
files=( ./*.tgz )
|
|
npm publish "${files[0]}"
|
|
displayName: Push to npm (MyGet)
|
|
workingDirectory: $(Pipeline.Workspace)/npm
|
|
|
|
- stage: Deploy_NuGet
|
|
displayName: NuGet release
|
|
dependsOn:
|
|
- Deploy_MyGet
|
|
- Build_Docs
|
|
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.nuGetDeploy}}))
|
|
jobs:
|
|
- job:
|
|
pool:
|
|
vmImage: "windows-latest" # NuGetCommand@2 is no longer supported on Ubuntu 24.04 so we'll use windows until an alternative is available.
|
|
displayName: Push to NuGet
|
|
steps:
|
|
- checkout: none
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download nupkg
|
|
inputs:
|
|
artifact: nupkg
|
|
path: $(Build.ArtifactStagingDirectory)/nupkg
|
|
- task: NuGetCommand@2
|
|
displayName: NuGet push
|
|
inputs:
|
|
command: "push"
|
|
packagesToPush: $(Build.ArtifactStagingDirectory)/**/*.nupkg
|
|
nuGetFeedType: "external"
|
|
publishFeedCredentials: "NuGet - Umbraco.*"
|
|
|
|
- stage: Deploy_Npm
|
|
displayName: Npm release
|
|
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.npmDeploy}}))
|
|
dependsOn:
|
|
- Deploy_NuGet
|
|
jobs:
|
|
- job: Publish
|
|
displayName: Push to NPM
|
|
steps:
|
|
- checkout: none
|
|
- download: current
|
|
artifact: npm
|
|
- bash: echo "@umbraco-cms:registry=https://registry.npmjs.org" >> .npmrc
|
|
workingDirectory: $(Pipeline.Workspace)/npm
|
|
displayName: Add scoped registry to .npmrc
|
|
- task: npmAuthenticate@0
|
|
displayName: Authenticate with npm
|
|
inputs:
|
|
workingFile: $(Pipeline.Workspace)/npm/.npmrc
|
|
customEndpoint: "NPM - Umbraco Backoffice"
|
|
- script: |
|
|
# Setup temp npm project to load in defaults from the local .npmrc
|
|
npm init -y
|
|
|
|
# Find the first .tgz file in the current directory and publish it
|
|
files=( ./*.tgz )
|
|
npm publish "${files[0]}"
|
|
displayName: Push to npm
|
|
workingDirectory: $(Pipeline.Workspace)/npm
|
|
|
|
- stage: Upload_API_Docs
|
|
pool:
|
|
vmImage: "windows-latest" # Apparently AzureFileCopy is windows only :(
|
|
variables:
|
|
umbracoMajorVersion: $[ stageDependencies.Build.A.outputs['build.NBGV_VersionMajor'] ]
|
|
displayName: Upload API Documentation
|
|
dependsOn:
|
|
- Build
|
|
- Deploy_NuGet
|
|
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.uploadApiDocs}}))
|
|
jobs:
|
|
- job:
|
|
displayName: Upload C# Docs
|
|
steps:
|
|
- checkout: none
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download artifact
|
|
inputs:
|
|
artifact: csharp-docs
|
|
path: $(Build.SourcesDirectory)
|
|
- task: ExtractFiles@1
|
|
inputs:
|
|
archiveFilePatterns: $(Build.SourcesDirectory)/csharp-docs.zip
|
|
destinationFolder: $(Build.ArtifactStagingDirectory)/csharp-docs
|
|
overwriteExistingFiles: true
|
|
- task: AzureFileCopy@4
|
|
displayName: "Copy C# Docs to blob storage"
|
|
inputs:
|
|
SourcePath: "$(Build.ArtifactStagingDirectory)/csharp-docs/*"
|
|
azureSubscription: umbraco-storage
|
|
Destination: AzureBlob
|
|
storage: umbracoapidocs
|
|
ContainerName: "$web"
|
|
BlobPrefix: v$(umbracoMajorVersion)/csharp
|
|
CleanTargetBeforeCopy: true
|
|
- job:
|
|
displayName: Upload Storybook
|
|
steps:
|
|
- checkout: none
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download artifact
|
|
inputs:
|
|
artifact: ui-docs
|
|
path: $(Build.SourcesDirectory)
|
|
- task: ExtractFiles@1
|
|
inputs:
|
|
archiveFilePatterns: $(Build.SourcesDirectory)/ui-docs.zip
|
|
destinationFolder: $(Build.ArtifactStagingDirectory)/ui-docs
|
|
overwriteExistingFiles: true
|
|
- task: AzureFileCopy@4
|
|
displayName: "Copy Storybook to blob storage"
|
|
inputs:
|
|
SourcePath: "$(Build.ArtifactStagingDirectory)/ui-docs/*"
|
|
azureSubscription: umbraco-storage
|
|
Destination: AzureBlob
|
|
storage: umbracoapidocs
|
|
ContainerName: "$web"
|
|
BlobPrefix: v$(umbracoMajorVersion)/ui
|
|
CleanTargetBeforeCopy: true
|
|
- job:
|
|
displayName: Upload UI API Docs
|
|
steps:
|
|
- checkout: none
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download artifact
|
|
inputs:
|
|
artifact: ui-api-docs
|
|
path: $(Build.SourcesDirectory)
|
|
- task: ExtractFiles@1
|
|
inputs:
|
|
archiveFilePatterns: $(Build.SourcesDirectory)/ui-api-docs.zip
|
|
destinationFolder: $(Build.ArtifactStagingDirectory)/ui-api-docs
|
|
overwriteExistingFiles: true
|
|
- task: AzureFileCopy@4
|
|
displayName: "Copy UI API Docs to blob storage"
|
|
inputs:
|
|
SourcePath: "$(Build.ArtifactStagingDirectory)/ui-api-docs/*"
|
|
azureSubscription: umbraco-storage
|
|
Destination: AzureBlob
|
|
storage: umbracoapidocs
|
|
ContainerName: "$web"
|
|
BlobPrefix: v$(umbracoMajorVersion)/ui-api
|
|
CleanTargetBeforeCopy: true
|