* implement interface * add build targets for login screen * package lock * move components to pages folder * load logo and background from property * styling * move mocks around * remove unused vars * add backoffice handlers * install rxjs * add mock data * add element and context for localization * mock data * use umb-localize * remove the extra logic with check for section_ * change key for login button * add base to vite environment * login styling * cleanup and button styling * use correct reset url * change body of reset request * validate password reset code * redirect to /login/new on reset password code verify * add obsolete messages * remove inline scripts for old backoffice * remove shadowdom from localize element * Revert "remove shadowdom from localize element" This reverts commit 46ae282f7ce9235c15f160d57d54acd5d3378668. * hook up reset password to api * rename pages to state as it is not actually used as different pages * reset password styling * more styling * add confirmation page to new password * set router to firstUpdated to avoid rAF * set a custom baseUrl on the router to make sure it works without trailing slash * use route parameters to redirect on the login page to ensure correct escaping * add server variables * make sure auth layout uses the provided properties for images * format * redirect to code expired page * add missing properties * use allowPasswordReset and allowInvite properties in routing and layout * make ts happy * cleanup * init invite page * hook up usernameIsEmail * init external login providers * add mock provider * add padding to buttons * replace uui button with normal button * add external login providers as slot * add disableLocalLogin property * add form to external login providers * remove unused method * fix build errors * add attributes for external login * add custom view to external login * add new custom icon registry * attach two icon registries * use relative paths * use relative paths * use main registry instead of providing directly * add look and color to external login * implement getIcons() method * use getIcons() to request icons * install remixicon to supplement backoffice icons (replacing font-awesome eventually) * move icon registries to auth element * Revert "install remixicon to supplement backoffice icons (replacing font-awesome eventually)" This reverts commit 0c6659d8d9dfe0664314ec6a3acaa8e20cb606ed. * add icons for common external providers * add more icons * remove resetCode hack as it is no longer needed * add validation to new password * get gretting from translation file * add hack to get text left aligned in uui-button * add custom router * WIP Use router * also change the URL during an action * update login action to redirect to /new when needed * redirect to login from reset and new if not allowed * fix new password button href * use property on login element instead of context * check for redirect on invite-user * move fake external login providers to index.html for use in dev server * allow password reset on dev server * add look and color * only set styles for default view buttons * suppress vite import warning * check and inform for errors and show 'nothing' if a custom view fails to load * fix mock path for localizedtext * fix build errors * ensure that msw (and all its dependencies) do not end up in the production bundle (saved ~500 KB) * Revert AngularValueExternalLoginInfoScriptAsync removal * forward the providerName to custom views * change default icon * add button look and color to external login provider options * add obsolete to ButtonStyle and add a mapper to new values * add required xml comments * map external login providers to <umb-login-external /> * fix typo * only show external login layout if there are slotted children * pass on name as "provider" * send externalLoginUrl to custom views * cleanup * global import * hide external logins completely when empty * cleanup * setup redirect to invite * rename pages to name-page * fix names and paths * use new password layout for invite and new password * add comments * cleanup and use confirmation element * set parameters after successful verifyinvite * map display-name and provider-name to the external element * map display-name * set up external login to handle correct display- and provider-name with documentation * add support for disabling local login * update path to handlers * add more localization * add handlers for 2fa * router should support a factory for component * push login to ?flow=mfa on 402 codes * add page to handle 2fa/mfa * add support for custom routing * add fallback for welcome greeting * handle AngularJS silliness * fix typo * fix router and replace custom umbroute:statechange event with native pushState * simplify code and cleanup * a11y improvements * you can now navigate to anywhere from anywhere with pushState * access the "twoFactorView" from the backend * set the default implemented twoFactorView to NULL * add initial logic to handle a custom mfa view * roll back custom pushState changes * add mocks for 2fa custom view * use router redirect * re-enable click url change * cleanup * remove debug buttons * add unsafeHTML to localize element * load mfa custom views * load custom view * improve external login custom views * using optimisation * add current culture * only show mfa page if 402 code has been encountered in same session * format * remove unnesesary action * add new user invite password * remove console log * fix getting stuck at new password page if you've triggered custom validity * unify layouts * add styling to buttons in error layout * remove unused css * add error message to new password page * add error message to reset password * add error message to invite page * fix invite page not being rendered * cleanup * add obsolete notice to PostSetInvitedUserPassword * add request model to set a new password for an invited user * add new method to handle invited user password * add get password config api call * fix password config parameters and add invite call * get invited user * get password config * assign unique guid to login project * add userId to get password config and use the config as validation * fix * add alerts * fix the new password layout * auth redirects invite error to error page * use password config on new password page * remove console log * move file and remove unused extension * make ts happy * file structure * rename login-extern to external-login-provider * update element name * update dependencies * export custom-view.element.ts * remove debug * use umb-custom-view to load custom views * build types * move @umbraco/uui to the login app and import from there in backoffice * make the ui library and icon registry generally available as exports from the login app * add mock handler for icons * cleanup package * use uui for external login providers in the backoffice * add imports and enable the backoffice icon registry globally * disable shadowdom * default background image * use undefined * revert angular values * remove legacy sys variables * add logic to handle mfa in an overlay scenario without routing * add new login screen to replace the overlay when logged in to the backoffice * update spec to work with locators * cleanup of legacy context * ViewData is not always required * add method to solely return the default view of the backoffice to simply BackofficeController as well as unit tests * add test for the login view * cleanup usings * Apply suggestions from code review Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> * remove 'remember me' * add more contrast to external login divider * update dependencies * set "lang" attribute to lowercase * remove default headline * localize the "Or" divider and add aria-hidden * remove Umbraco reference from logo and add aria-hidden * add aria-hidden to uui-icon inside external login buttons * format code * update dependencies * update dependencies * add translations to invite user page * use back to login button * update localization-context.ts to match api from old LocalizeService in Angular * add tsc to watch * formatting * add missing localizations * fix a11y issues with muted text * refresh current user after login * remove unused variable * add localization * add localization for error messages * remove unused var * return user after login and set successful auth * retry request queue after login * add language keys for failed login * add language keys for failed login * render the views without a router so that it works inside a modal in the backoffice * add autocomplete to reset password fields * add autocomplete to login screen * add generic error layout to new-password-page * new-password-layout should be able to handle with and without username * update language keys * check for userId before trying to request invited user * show error when no invited user is found * place back-to-login button on all error layouts * update lockfile --------- Co-authored-by: Jesper Møller Jensen <26099018+JesmoDev@users.noreply.github.com> Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
634 lines
27 KiB
YAML
634 lines
27 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: myGetDeploy
|
|
displayName: Deploy to MyGet
|
|
type: boolean
|
|
default: false
|
|
- name: nuGetDeploy
|
|
displayName: Deploy to NuGet
|
|
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: ' '
|
|
|
|
variables:
|
|
nodeVersion: 18.16.x
|
|
dotnetVersion: 8.x
|
|
dotnetIncludePreviewVersions: true
|
|
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
|
|
|
|
stages:
|
|
###############################################
|
|
## Build
|
|
###############################################
|
|
- stage: Build
|
|
variables:
|
|
npm_config_cache: $(Pipeline.Workspace)/.npm_client
|
|
jobs:
|
|
- job: A
|
|
displayName: Build Umbraco CMS
|
|
pool:
|
|
vmImage: 'ubuntu-latest'
|
|
steps:
|
|
- task: NodeTool@0
|
|
displayName: Use Node.js $(nodeVersion)
|
|
inputs:
|
|
versionSpec: $(nodeVersion)
|
|
- task: Cache@2
|
|
displayName: Cache node_modules
|
|
inputs:
|
|
key: '"npm_client" | "$(Agent.OS)" | $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Client/package-lock.json'
|
|
restoreKeys: |
|
|
"npm_client" | "$(Agent.OS)"
|
|
"npm_client"
|
|
path: $(npm_config_cache)
|
|
- script: npm ci --no-fund --no-audit --prefer-offline
|
|
workingDirectory: src/Umbraco.Web.UI.Client
|
|
displayName: Run npm ci
|
|
- task: gulp@0
|
|
displayName: Run gulp build
|
|
inputs:
|
|
gulpFile: src/Umbraco.Web.UI.Client/gulpfile.js
|
|
targets: coreBuild
|
|
workingDirectory: src/Umbraco.Web.UI.Client
|
|
- task: npm@1
|
|
displayName: Run npm ci
|
|
inputs:
|
|
command: custom
|
|
workingDir: src/Umbraco.Web.UI.Login
|
|
verbose: false
|
|
customCommand: ci
|
|
- task: npm@1
|
|
displayName: Run npm build
|
|
inputs:
|
|
command: custom
|
|
workingDir: src/Umbraco.Web.UI.Login
|
|
verbose: false
|
|
customCommand: run build
|
|
- task: UseDotNet@2
|
|
displayName: Use .NET $(dotnetVersion)
|
|
inputs:
|
|
version: $(dotnetVersion)
|
|
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
|
- 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
|
|
|
|
- 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: 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'
|
|
steps:
|
|
- task: NodeTool@0
|
|
displayName: Use Node.js 10.15.x
|
|
inputs:
|
|
versionSpec: 10.15.x # Won't work with higher versions
|
|
- script: |
|
|
npm ci --no-fund --no-audit --prefer-offline
|
|
npx gulp docs
|
|
|
|
major="$(umbracoMajorVersion)"
|
|
echo "major version: $major"
|
|
|
|
baseUrl="https://apidocs.umbraco.com/v$major/ui/"
|
|
echo "baseUrl: $baseUrl"
|
|
|
|
sed -i "s|baseUrl = .*|baseUrl = '$baseUrl',|" api/index.html
|
|
displayName: Generate js Docs
|
|
workingDirectory: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Docs
|
|
- task: ArchiveFiles@2
|
|
displayName: Archive js Docs
|
|
inputs:
|
|
rootFolderOrFile: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Docs/api
|
|
includeRootFolder: false
|
|
archiveFile: $(Build.ArtifactStagingDirectory)/ui-docs.zip
|
|
- task: PublishPipelineArtifact@1
|
|
displayName: Publish js Docs
|
|
inputs:
|
|
targetPath: $(Build.ArtifactStagingDirectory)/ui-docs.zip
|
|
artifact: ui-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:
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download build artifacts
|
|
inputs:
|
|
artifact: build_output
|
|
path: $(Build.SourcesDirectory)
|
|
- task: UseDotNet@2
|
|
displayName: Use .NET $(dotnetVersion)
|
|
inputs:
|
|
version: $(dotnetVersion)
|
|
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
|
- task: DotNetCoreCLI@2
|
|
displayName: Run dotnet test
|
|
inputs:
|
|
command: test
|
|
projects: '**/*.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:
|
|
displayName: Integration Tests (SQLite)
|
|
strategy:
|
|
matrix:
|
|
Windows:
|
|
vmImage: 'windows-latest'
|
|
Linux:
|
|
vmImage: 'ubuntu-latest'
|
|
macOS:
|
|
vmImage: 'macOS-latest'
|
|
pool:
|
|
vmImage: $(vmImage)
|
|
steps:
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download build artifacts
|
|
inputs:
|
|
artifact: build_output
|
|
path: $(Build.SourcesDirectory)
|
|
- task: UseDotNet@2
|
|
displayName: Use .NET $(dotnetVersion)
|
|
inputs:
|
|
version: $(dotnetVersion)
|
|
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
|
- task: DotNetCoreCLI@2
|
|
displayName: Run dotnet test Windows
|
|
condition: eq(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.integrationReleaseTestFilter}}'
|
|
${{ else }}:
|
|
arguments: '--configuration $(buildConfiguration) ${{parameters.integrationNonReleaseTestFilter}}'
|
|
env:
|
|
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}}'
|
|
${{ else }}:
|
|
arguments: '--configuration $(buildConfiguration) ${{parameters.nonWindowsIntegrationNonReleaseTestFilter}}'
|
|
env:
|
|
Tests__Database__DatabaseType: 'Sqlite'
|
|
Umbraco__CMS__Global__MainDomLock: 'FileSystemMainDomLock'
|
|
|
|
# Integration Tests (SQL Server)
|
|
- job:
|
|
timeoutInMinutes: 120
|
|
condition: or(eq(stageDependencies.Build.A.outputs['build.NBGV_PublicRelease'], 'True'), ${{parameters.sqlServerIntegrationTests}})
|
|
displayName: Integration Tests (SQL Server)
|
|
strategy:
|
|
matrix:
|
|
Windows:
|
|
vmImage: 'windows-latest'
|
|
testDb: LocalDb
|
|
connectionString: N/A
|
|
Linux:
|
|
vmImage: 'ubuntu-latest'
|
|
testDb: SqlServer
|
|
connectionString: 'Server=localhost,1433;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=true'
|
|
pool:
|
|
vmImage: $(vmImage)
|
|
variables:
|
|
SA_PASSWORD: UmbracoIntegration123!
|
|
steps:
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download build artifacts
|
|
inputs:
|
|
artifact: build_output
|
|
path: $(Build.SourcesDirectory)
|
|
- task: UseDotNet@2
|
|
displayName: Use .NET $(dotnetVersion)
|
|
inputs:
|
|
version: $(dotnetVersion)
|
|
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
|
- powershell: sqllocaldb start mssqllocaldb
|
|
displayName: Start localdb (Windows only)
|
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
|
- 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'))
|
|
- task: DotNetCoreCLI@2
|
|
displayName: Run dotnet test Windows
|
|
condition: eq(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.integrationReleaseTestFilter}}'
|
|
${{ else }}:
|
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.integrationNonReleaseTestFilter}}'
|
|
env:
|
|
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}}'
|
|
${{ else }}:
|
|
arguments: '--configuration $(buildConfiguration) --no-build ${{parameters.nonWindowsIntegrationNonReleaseTestFilter}}'
|
|
env:
|
|
Tests__Database__DatabaseType: $(testDb)
|
|
Tests__Database__SQLServerMasterConnectionString: $(connectionString)
|
|
Umbraco__CMS__Global__MainDomLock: 'SqlMainDomLock'
|
|
|
|
- stage: E2E
|
|
variables:
|
|
npm_config_cache: $(Pipeline.Workspace)/.npm_e2e
|
|
displayName: E2E Tests
|
|
dependsOn: Build
|
|
jobs:
|
|
# E2E Tests
|
|
- job:
|
|
displayName: E2E Tests
|
|
timeoutInMinutes: 120
|
|
variables:
|
|
Umbraco__CMS__Unattended__UnattendedUserName: Playwright Test
|
|
Umbraco__CMS__Unattended__UnattendedUserPassword: UmbracoAcceptance123!
|
|
Umbraco__CMS__Unattended__UnattendedUserEmail: playwright@umbraco.com
|
|
ASPNETCORE_URLS: https://localhost:8443
|
|
strategy:
|
|
matrix:
|
|
Linux:
|
|
vmImage: 'ubuntu-latest'
|
|
dockerfile: umbraco-linux.docker
|
|
dockerImageName: umbraco-linux
|
|
Windows:
|
|
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:
|
|
vmImage: $(vmImage)
|
|
steps:
|
|
- task: DownloadPipelineArtifact@2
|
|
displayName: Download nupkg
|
|
inputs:
|
|
artifact: nupkg
|
|
path: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/misc/nupkg
|
|
- task: NodeTool@0
|
|
displayName: Use Node.js $(nodeVersion)
|
|
inputs:
|
|
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
|
|
displayName: Use .NET $(dotnetVersion)
|
|
inputs:
|
|
version: $(dotnetVersion)
|
|
includePreviewVersions: $(dotnetIncludePreviewVersions)
|
|
- pwsh: |
|
|
$sha = 'g$(Build.SourceVersion)'.substring(0, 8)
|
|
docker build -t $(dockerImageName):$sha -f $(dockerfile) .
|
|
mkdir -p $(Build.ArtifactStagingDirectory)/docker-images
|
|
docker save -o $(Build.ArtifactStagingDirectory)/docker-images/$(dockerImageName).$sha.tar $(dockerImageName):$sha
|
|
dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p $(Umbraco__CMS__Unattended__UnattendedUserPassword)
|
|
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
|
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
|
displayName: Build and run container (Linux only)
|
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest/misc
|
|
- pwsh: |
|
|
dotnet new --install ./nupkg/Umbraco.Templates.*.nupkg
|
|
dotnet new umbraco --name AcceptanceTestProject --no-restore --output .
|
|
dotnet restore --configfile ./nuget.config
|
|
dotnet build --configuration $(buildConfiguration) --no-restore
|
|
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
|
|
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
|
|
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
|
displayName: Build and run app (Windows only)
|
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest/misc
|
|
- pwsh: npx wait-on -v --interval 1000 --timeout 120000 $(ASPNETCORE_URLS)
|
|
displayName: Wait for app
|
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
|
- pwsh: npx playwright install --with-deps
|
|
displayName: Install Playwright
|
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
|
- pwsh: npm run test --ignore-certificate-errors
|
|
displayName: Run Playwright (Desktop)
|
|
continueOnError: true
|
|
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
|
env:
|
|
CI: true
|
|
CommitId: $(Build.SourceVersion)
|
|
AgentOs: $(Agent.OS)
|
|
- pwsh: |
|
|
docker logs $(dockerImageName) > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1
|
|
docker stop $(dockerImageName)
|
|
condition: eq(variables['Agent.OS'], 'Linux')
|
|
displayName: Stop app (Linux only)
|
|
- pwsh: Stop-Process $env:AcceptanceTestProcessId
|
|
condition: eq(variables['Agent.OS'], 'Windows_NT')
|
|
displayName: Stop app (Windows only)
|
|
- 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
|
|
condition: always()
|
|
displayName: Publish test artifacts
|
|
inputs:
|
|
targetPath: $(Build.ArtifactStagingDirectory)
|
|
artifact: 'E2E artifacts - $(Agent.OS) - Attempt #$(System.JobAttempt)'
|
|
|
|
|
|
###############################################
|
|
## Release
|
|
###############################################
|
|
- stage: Deploy_MyGet
|
|
displayName: MyGet pre-release
|
|
dependsOn:
|
|
- Unit
|
|
- Integration
|
|
# - E2E # TODO: Enable when stable.
|
|
condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.myGetDeploy}}))
|
|
jobs:
|
|
- job:
|
|
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'
|
|
publishFeedCredentials: 'MyGet - Pre-releases'
|
|
- 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:
|
|
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: Upload_API_Docs
|
|
pool:
|
|
vmImage: 'windows-latest' # Apparently AzureFileCopy is windows only :(
|
|
variables:
|
|
umbracoMajorVersion: $[ stageDependencies.Build.A.outputs['build.NBGV_VersionMajor'] ]
|
|
displayName: Upload API Documention
|
|
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
|
|
- 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
|
|
- job:
|
|
displayName: Upload js Docs
|
|
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
|
|
- task: AzureFileCopy@4
|
|
displayName: 'Copy UI Docs to blob storage'
|
|
inputs:
|
|
SourcePath: '$(Build.ArtifactStagingDirectory)/ui-docs/*'
|
|
azureSubscription: umbraco-storage
|
|
Destination: AzureBlob
|
|
storage: umbracoapidocs
|
|
ContainerName: '$web'
|
|
BlobPrefix: v$(umbracoMajorVersion)/ui
|