From da3c634639f59b8c52bc9ae221d6ed3bd75386cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Malec?= Date: Wed, 6 Nov 2024 13:02:11 +0100 Subject: [PATCH] update scripts, setting auto hotfix from pipeline --- .github/workflows/ci.yml | 351 +++++++++++++----------- Directory.Packages.props | 45 +-- examples/DancingGoat/DancingGoat.csproj | 62 ++--- scripts/Init-Project.ps1 | 65 +++++ scripts/Reset-DatabaseConsistency.ps1 | 15 + scripts/Restore-CI.ps1 | 50 ++-- scripts/Restore-Database.ps1 | 58 ++++ scripts/Settings/Settings.psm1 | 45 +++ scripts/Toggle-CI.ps1 | 37 +++ scripts/Update-DB.ps1 | 32 +++ scripts/Utilities/Utilities.psm1 | 105 +++---- 11 files changed, 558 insertions(+), 307 deletions(-) create mode 100644 scripts/Init-Project.ps1 create mode 100644 scripts/Reset-DatabaseConsistency.ps1 create mode 100644 scripts/Restore-Database.ps1 create mode 100644 scripts/Settings/Settings.psm1 create mode 100644 scripts/Toggle-CI.ps1 create mode 100644 scripts/Update-DB.ps1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 31710a3..82d8339 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,161 +1,190 @@ -name: "CI: Build and Test" - -on: - push: - branches: [main, feat/automatic_E2E_testing] - # paths: - # - "**.cs" - # - "**.tsx" - # - "**.js" - # - "**.csproj" - # - "**.props" - # - "**.targets" - # - "**.sln" - # - "**/Client/**/*.json" - pull_request: - branches: [main] - paths: - - "**.cs" - - "**.cshtml" - - "**.tsx" - - "**.js" - - "**.json" - - "**.csproj" - - "**.props" - - "**.targets" - - "**.sln" - -jobs: - build_and_test: - name: Build and Test - runs-on: ubuntu-latest - defaults: - run: - shell: pwsh - - env: - ASPNETCORE_ENVIRONMENT: CI - DATABASE_BACKUP_FILENAME: "" - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 - DOTNET_NOLOGO: 1 - PROJECT_NAME: DancingGoat - ASPNETCORE_URLS: https://localhost:14070 - STATUS_CHECK_URL: https://localhost:14070/status - DATABASE_USER: "sa" - DATABASE_PASSWORD: "Pass@12345" - DATABASE_NAME: "XByK_DancingGoat_Zapier" - - steps: - - uses: actions/checkout@v4 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - global-json-file: global.json - - - name: Install dependencies - run: | - dotnet restore ` - --locked-mode - - - name: Build Solution - run: | - dotnet build ` - --configuration Release ` - --no-restore - - - name: Get Database Backup Name - run: | - $latestBackup = Get-Content -Path "./database/backups.txt" -TotalCount 1 - "DATABASE_BACKUP_FILENAME=$latestBackup" >> $env:GITHUB_ENV - - - name: Extract Database Backup - run: | - Expand-Archive ` - -Path "./database/${{ env.DATABASE_BACKUP_FILENAME }}.zip" ` - -DestinationPath "./database" - - - name: Install a SQL Server suite of tools (SQLEngine, SQLPackage) - uses: potatoqualitee/mssqlsuite@9a0136e208df60b8ecb62909f076bc34854fa55a # set as a commit hash for security - v1.7 - with: - install: sqlpackage, sqlengine - sa-password: ${{ env.DATABASE_PASSWORD }} - version: 2022 - - - name: Restore Database .bak - run: | - docker exec sql mkdir /var/opt/mssql/backup - docker cp "./database/${{ env.DATABASE_BACKUP_FILENAME }}" sql:/var/opt/mssql/backup - sqlcmd ` - -S localhost ` - -d master ` - -U ${{ env.DATABASE_USER }} ` - -P ${{ env.DATABASE_PASSWORD }} ` - -Q "RESTORE DATABASE [XByK_DancingGoat_Zapier] FROM DISK='/var/opt/mssql/backup/${{ env.DATABASE_BACKUP_FILENAME }}' WITH MOVE 'XByK_DancingGoat_Zapier' TO '/var/opt/mssql/data/XByK_DancingGoat_Zapier.mdf', MOVE 'XByK_DancingGoat_Zapier_log' TO '/var/opt/mssql/data/XByK_DancingGoat_Zapier_log.ldf'" - - - name: Restore CI Repository - working-directory: "./scripts" - run: | - ./Restore-CI.ps1 - - - name: Publish Application - run: | - dotnet publish ` - ./examples/${{ env.PROJECT_NAME }} ` - -c Release ` - -o ./publish ` - --no-build ` - --no-restore - #- name: Install Playwright Dependencies - # TODO: to je blbost - #run: | - # ./test/Kentico.Community.Portal.Web.E2E.Tests/bin/Release/net8.0/playwright.ps1 install - - - name: Install Azurite - id: azuright - uses: potatoqualitee/azuright@e56d2754eb15218d507961493bc83ca037216887 # set as a commit hash for security - v1.1 - - - - name: Test Solution - run: | - dotnet test ` - --configuration Release ` - --no-build ` - --no-restore - - - name: Run Application and E2E Tests - run: | - # Run the ASP.NET Core app as a background job - cd ./publish - Start-Job -ScriptBlock { dotnet ./${{ env.PROJECT_NAME }}.dll } -Name ${{ env.PROJECT_NAME }} - Receive-Job -Name ${{ env.PROJECT_NAME }} - cd ../ - # The ASP.NET Core app can take a few seconds to start, so we delay running tests - # until it is ready, and fail if we go over a maximum wait time - $limit = 10 - $attempts = 0 - $success = $false - while ($attempts -lt $limit -and -not $success) { - Start-Sleep -Seconds 1 - try { - $response = Invoke-WebRequest -Uri ${{ env.STATUS_CHECK_URL }} -Method Get -SkipCertificateCheck - if ($response.StatusCode -eq 200) { - Write-Output "Application is ready." - $success = $true - } - } - catch { - Write-Output "Attempt $attempts - Application not ready yet." - } - $attempts++ - } - if (-not $success) { - Write-Output "Application did not respond in time." - exit 1 - } - # TODO: Run the E2E tests - # Stop the background ASP.NET Core application - Receive-Job -Name ${{ env.PROJECT_NAME }} - Stop-Job -Name ${{ env.PROJECT_NAME }} - Remove-Job -Name ${{ env.PROJECT_NAME }} +name: "CI: Build and Test" + +on: + push: + branches: [main, feat/automatic_E2E_testing] + # paths: + # - "**.cs" + # - "**.tsx" + # - "**.js" + # - "**.csproj" + # - "**.props" + # - "**.targets" + # - "**.sln" + # - "**/Client/**/*.json" + pull_request: + branches: [main] + paths: + - "**.cs" + - "**.cshtml" + - "**.tsx" + - "**.js" + - "**.json" + - "**.csproj" + - "**.props" + - "**.targets" + - "**.sln" + +jobs: + build_and_test: + name: Test E2E + runs-on: ubuntu-latest + defaults: + run: + shell: pwsh + + env: + ASPNETCORE_ENVIRONMENT: CI + DATABASE_BACKUP_FILENAME: "" + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + PROJECT_NAME: DancingGoat + STATUS_CHECK_URL: https://localhost:14070/status + DATABASE_USER: "sa" + DATABASE_PASSWORD: "Pass@12345" + DATABASE_NAME: "XByK_DancingGoat_Zapier" + XPERIENCE_BY_KENTICO_LICENSE: ${{ secrets.XPERIENCE_BY_KENTICO_LICENSE }} + + steps: + - uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: lts/* + + # - name: Install NPM + # run: | + # cd test/Playwright + # npm ci + # npx playwright install --with-deps + # cd ../.. + + - name: Get Database Backup Name + run: | + $latestBackup = Get-Content -Path "./database/backups.txt" -TotalCount 1 + "DATABASE_BACKUP_FILENAME=$latestBackup" >> $env:GITHUB_ENV + + - name: Extract Database Backup + run: | + Expand-Archive ` + -Path "./database/${{ env.DATABASE_BACKUP_FILENAME }}.zip" ` + -DestinationPath "./database" + + - name: Install a SQL Server suite of tools (SQLEngine, SQLPackage) + uses: potatoqualitee/mssqlsuite@9a0136e208df60b8ecb62909f076bc34854fa55a # set as a commit hash for security - v1.7 + with: + install: sqlpackage, sqlengine + sa-password: ${{ env.DATABASE_PASSWORD }} + version: 2022 + + - name: Restore Database .bak + run: | + docker exec sql mkdir /var/opt/mssql/backup + docker cp "./database/${{ env.DATABASE_BACKUP_FILENAME }}" sql:/var/opt/mssql/backup + sqlcmd ` + -S localhost ` + -d master ` + -U ${{ env.DATABASE_USER }} ` + -P ${{ env.DATABASE_PASSWORD }} ` + -Q "RESTORE DATABASE [XByK_DancingGoat_Zapier] FROM DISK='/var/opt/mssql/backup/${{ env.DATABASE_BACKUP_FILENAME }}' WITH MOVE 'XByK_DancingGoat_Zapier' TO '/var/opt/mssql/data/XByK_DancingGoat_Zapier.mdf', MOVE 'XByK_DancingGoat_Zapier_log' TO '/var/opt/mssql/data/XByK_DancingGoat_Zapier_log.ldf'" + + # - name: Imports license key to DB + # run: | + # sqlcmd ` + # -S localhost ` + # -d ${{ env.DATABASE_NAME }} ` + # -U ${{ env.DATABASE_USER }} ` + # -P ${{ env.DATABASE_PASSWORD }} ` + # -Q "UPDATE CMS_SettingsKey SET KeyValue='${{ env.XPERIENCE_BY_KENTICO_LICENSE }}' WHERE KeyName='CMSLicenseKey'" + + - name: Reset DB consistency for last applied hotfix + run: | + dotnet build ` + --configuration Release + cd scripts + ./Reset-DatabaseConsistency.ps1 + cd .. + + - name: Build Solution for last hotfix + run: | + dotnet build ` + --configuration Release ` + -p:XbyKVersion=* + cd scripts + ./Reset-DatabaseConsistency.ps1 -ExcludeCIRestore + cd .. + + - name: Publish Application + run: | + dotnet publish ` + ./examples/${{ env.PROJECT_NAME }} ` + -c Release ` + -o ./publish ` + --no-build ` + --no-restore + + - name: Install Azurite + id: azuright + uses: potatoqualitee/azuright@e56d2754eb15218d507961493bc83ca037216887 # set as a commit hash for security - v1.1 + + + - name: Test Solution + run: | + dotnet test ` + --configuration Release ` + --no-build ` + --no-restore + + - name: Run Application and E2E Tests + run: | + # Run the ASP.NET Core app as a background job + cd ./publish + Start-Job -ScriptBlock { dotnet ./${{ env.PROJECT_NAME }}.dll } -Name ${{ env.PROJECT_NAME }} + Receive-Job -Name ${{ env.PROJECT_NAME }} + cd ../ + # The ASP.NET Core app can take a few seconds to start, so we delay running tests + # until it is ready, and fail if we go over a maximum wait time + $limit = 10 + $attempts = 0 + $success = $false + while ($attempts -lt $limit -and -not $success) { + Start-Sleep -Seconds 1 + try { + $response = Invoke-WebRequest -Uri ${{ env.STATUS_CHECK_URL }} -Method Get -SkipCertificateCheck + if ($response.StatusCode -eq 200) { + Write-Output "Application is ready." + $success = $true + } + } + catch { + Write-Output "Attempt $attempts - Application not ready yet." + } + $attempts++ + } + if (-not $success) { + Write-Output "Application did not respond in time." + exit 1 + } + # TODO: Run the E2E tests + # cd test/Playwright + # npx playwright test + # cd ../.. + + + # Stop the background ASP.NET Core application + Receive-Job -Name ${{ env.PROJECT_NAME }} + Stop-Job -Name ${{ env.PROJECT_NAME }} + Remove-Job -Name ${{ env.PROJECT_NAME }} + + # - uses: actions/upload-artifact@v4 + # with: + # name: playwright-report + # path: ./test/Playwright/playwright-report/ + # retention-days: 30 diff --git a/Directory.Packages.props b/Directory.Packages.props index d52dbc9..3f94a44 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,22 +1,25 @@ - - - true - false - true - true - - - - - - - - - - - - - - - + + + true + true + true + true + true + 29.3.0 + $(LastAppliedHotfix) + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/DancingGoat/DancingGoat.csproj b/examples/DancingGoat/DancingGoat.csproj index 9ab9a6b..607e535 100644 --- a/examples/DancingGoat/DancingGoat.csproj +++ b/examples/DancingGoat/DancingGoat.csproj @@ -1,32 +1,32 @@ - - - DancingGoat - 4bb57401-f6b2-4cf0-b115-a805042eeb98 - false - disable - - - - - - - PreserveNewest - - - - - - - - $(DefineConstants);SEPARATED_ADMIN - - - - - - - - - - + + + DancingGoat + 4bb57401-f6b2-4cf0-b115-a805042eeb98 + false + disable + + + + + + + PreserveNewest + + + + + + + + $(DefineConstants);SEPARATED_ADMIN + + + + + + + + + + \ No newline at end of file diff --git a/scripts/Init-Project.ps1 b/scripts/Init-Project.ps1 new file mode 100644 index 0000000..3a4b7e5 --- /dev/null +++ b/scripts/Init-Project.ps1 @@ -0,0 +1,65 @@ +<# +.Synopsis + Restore DBs for project. + Add license keys for project. + Set DB to consistent state. +#> + +Import-Module (Resolve-Path Settings) ` + -Function ` + Get-AppSettings ` + -Force + +Import-Module (Resolve-Path Utilities) ` + -Function ` + Invoke-ExpressionWithException, ` + Get-ConnectionString, ` + Write-Status ` + -Force + +$appSettings = Get-AppSettings +$connectionString = Get-ConnectionString $appSettings + +$backupDatabaseFolderPath = Resolve-Path(Join-Path $($appSettings.WorkspaceFolder) "database") +$backupFileListPath = Join-Path -Path $backupDatabaseFolderPath -ChildPath "backups.txt" + +# Read the list of .bak file names from backup.txt +$bakFileNames = Get-Content -Path $backupFileListPath + + +$extractedBakFiles = @() + +# Loop through each .bak file name +foreach ($bakFileName in $bakFileNames) { + # Define the expected path of the unzipped .bak file + $bakFilePath = Join-Path -Path $backupDatabaseFolderPath -ChildPath $bakFileName + + # Check if the .bak file already exists + if (!(Test-Path -Path $bakFilePath)) { + # If the .bak file doesn't exist, look for the corresponding .zip file + $zipFilePath = "$bakFilePath.zip" + + # Check if the .zip file exists + if (Test-Path -Path $zipFilePath) { + # Unzip the .zip file to the database folder + Write-Output "Extracting $zipFilePath..." + Expand-Archive -Path $zipFilePath -DestinationPath $backupDatabaseFolderPath -Force + } else { + Write-Output "Warning: Zip file $zipFilePath not found." + continue + } + } + + # Add the extracted .bak file path to the array + $extractedBakFiles += $bakFileName +} + +foreach ($extractedBakFile in $extractedBakFiles) { + ./Restore-Database.ps1 $extractedBakFile +} + +Write-Host "Import license key to imported DBs, then press any key to continue..." +[System.Console]::ReadKey() | Out-Null + +./Reset-DatabaseConsistency.ps1 + diff --git a/scripts/Reset-DatabaseConsistency.ps1 b/scripts/Reset-DatabaseConsistency.ps1 new file mode 100644 index 0000000..242d705 --- /dev/null +++ b/scripts/Reset-DatabaseConsistency.ps1 @@ -0,0 +1,15 @@ +<# +.Synopsis + Updates the local database to last hotfix version and then update it with all the objects in the CI repository +#> + +param ( + [switch]$ExcludeCIRestore +) + +./Toggle-CI.ps1; +./Update-DB.ps1; +./Toggle-CI.ps1 -CIEnabled; +if (-not $ExcludeCIRestore) { + ./Restore-CI.ps1; +} \ No newline at end of file diff --git a/scripts/Restore-CI.ps1 b/scripts/Restore-CI.ps1 index 4f92107..ccdcbd4 100644 --- a/scripts/Restore-CI.ps1 +++ b/scripts/Restore-CI.ps1 @@ -1,47 +1,31 @@ +<# +.Synopsis + Updates the local database with all the objects in the CI repository +#> + +Import-Module (Resolve-Path Settings) ` + -Function ` + Get-AppSettings ` + -Force + Import-Module (Resolve-Path Utilities) ` -Function ` - Get-WebProjectPath, ` Invoke-ExpressionWithException, ` Write-Status ` -Force -$projectPath = Get-WebProjectPath -$repositoryPath = Join-Path $projectPath "App_Data/CIRepository" -$launchProfile = $Env:ASPNETCORE_ENVIRONMENT -eq "CI" ? "Zapier.WebCI" : "DancingGoat" -$configuration = $Env:ASPNETCORE_ENVIRONMENT -eq "CI" ? "Release" : "Debug" -$dbName = $Env:DATABASE_NAME -$dbUser = $Env:DATABASE_USER -$dbPassword = $Env:DATABASE_PASSWORD +$appSettings = Get-AppSettings -$restoreCommand = "dotnet run " + ` - "--launch-profile $launchProfile " + ` - "-c $configuration " + ` +$command = "dotnet run " + ` + "--launch-profile $($appSettings.LaunchProfile) " + ` + "-c $($appSettings.Configuration) " + ` "--no-build " + ` "--no-restore " + ` - "--project $projectPath " + ` + "--project $($appSettings.XbKProjectPath) " + ` "--kxp-ci-restore" -$turnOffCI = "sqlcmd " + ` - "-S localhost " + ` - "-d $dbName " + ` - "-U $dbUser " + ` - "-P $dbPassword " + ` - "-Q `"UPDATE CMS_SettingsKey SET KeyValue = N'False' WHERE KeyName = N'CMSEnableCI'`"" - -$updateCommand = "dotnet run " + ` - "--launch-profile $launchProfile " + ` - "-c $configuration " + ` - "--no-build " + ` - "--project $projectPath " + ` - "--kxp-update " + ` - "--skip-confirmation" - -Invoke-ExpressionWithException $restoreCommand -Invoke-ExpressionWithException $turnOffCI -Invoke-ExpressionWithException $updateCommand - - +Invoke-ExpressionWithException $command Write-Host "`n" -Write-Status 'CI files processed' +Write-Status "CI files processed" Write-Host "`n" \ No newline at end of file diff --git a/scripts/Restore-Database.ps1 b/scripts/Restore-Database.ps1 new file mode 100644 index 0000000..ab83d46 --- /dev/null +++ b/scripts/Restore-Database.ps1 @@ -0,0 +1,58 @@ + +<# +.Synopsis + Restore DB from Backup. +#> + +param ( + [Parameter(Mandatory=$true)] + [string]$backupName +) + +Import-Module (Resolve-Path Settings) ` + -Function ` + Get-AppSettings ` + -Force + +Import-Module (Resolve-Path Utilities) ` + -Function ` + Invoke-ExpressionWithException, ` + Get-ConnectionString, ` + Write-Status ` + -Force + + +$appSettings = Get-AppSettings +$connectionString = Get-ConnectionString $appSettings +$connectionStringMaster = $connectionString -replace 'Initial Catalog=[^;]+', 'Initial Catalog=master' + +$backupDatabaseFolderPath = Resolve-Path(Join-Path $($appSettings.WorkspaceFolder) "database") +$backupDatabaseFilePath = Resolve-Path(Join-Path $($backupDatabaseFolderPath) $($backupName)) + +$fileListQuery = "RESTORE FILELISTONLY FROM DISK = N'$backupDatabaseFilePath'" +$fileList = Invoke-Sqlcmd -Query $fileListQuery -ConnectionString $connectionStringMaster + +$logicalDataFile = ($fileList | Where-Object { $_.Type -eq 'D' }).LogicalName +$logicalLogFile = ($fileList | Where-Object { $_.Type -eq 'L' }).LogicalName + +$dataFilePath = Join-Path -Path $appSettings.SqlExpressPath -ChildPath "$logicalDataFile.mdf" +$logFilePath = Join-Path -Path $appSettings.SqlExpressPath -ChildPath "$logicalLogFile.ldf" + +$restoreQuery = @" + RESTORE DATABASE [$logicalDataFile] + FROM DISK = N'$backupDatabaseFilePath' + WITH FILE = 1, + MOVE N'$logicalDataFile' TO N'$dataFilePath', + MOVE N'$logicalLogFile' TO N'$logFilePath', + REPLACE; +"@ + +$command = "Invoke-Sqlcmd " + ` + "-Query ""$restoreQuery"" " + ` + "-ConnectionString ""$connectionStringMaster"" " + +Invoke-ExpressionWithException $command + +Write-Host "`n" +Write-Status "Database $logicalDataFile restored from backup $backupName" +Write-Host "`n" diff --git a/scripts/Settings/Settings.psm1 b/scripts/Settings/Settings.psm1 new file mode 100644 index 0000000..4b5f586 --- /dev/null +++ b/scripts/Settings/Settings.psm1 @@ -0,0 +1,45 @@ +# Constant settings for environment +$EnvAppSettings = @{ + CI = @{ + LaunchProfile = "Zapier.WebCI" + Configuration = "Release" + AppSettingsFileName = "appsettings.CI.json" + } + default = @{ + LaunchProfile = "DancingGoat" + Configuration = "Debug" + AppSettingsFileName = "appsettings.json" + } +} + +function Get-AppSettings { + # --- Constant settings --- # + $workspaceFolder = ".." + $solutionFileName = "Kentico.Xperience.Zapier.sln" + $assemblyName = "DancingGoat" + $dancingGoatXbKPath = "examples/DancingGoat-Zapier" + $repositoryPath = "App_Data/CIRepository" + $sqlExpressPath = "C:\Program Files\Microsoft SQL Server\MSSQL16.SQLEXPRESS\MSSQL\DATA" + + # --- Derived settings --- # + # Select the settings based on the environment variable with fallback to default + $envKey = if ($Env:ASPNETCORE_ENVIRONMENT) { $Env:ASPNETCORE_ENVIRONMENT } else { "default" } + $appSettings = $EnvAppSettings[$envKey] + $solutionPath = Resolve-Path(Join-Path $($workspaceFolder) $($solutionFileName)) + $XbKProjectPath = Resolve-Path(Join-Path $($workspaceFolder) $($dancingGoatXbKPath)) + $repositoryPath = Join-Path $XbKProjectPath $repositoryPath + + # Return as a custom object + return @{ + WorkspaceFolder = $workspaceFolder + SolutionFileName = $solutionFileName + AssemblyName = $assemblyName + SolutionPath = $solutionPath + XbKProjectPath = $XbKProjectPath + RepositoryPath = $repositoryPath + SqlExpressPath = $sqlExpressPath + LaunchProfile = $appSettings.launchProfile + Configuration = $appSettings.Configuration + AppSettingsFileName = $appSettings.AppSettingsFileName + } +} \ No newline at end of file diff --git a/scripts/Toggle-CI.ps1 b/scripts/Toggle-CI.ps1 new file mode 100644 index 0000000..6ec633f --- /dev/null +++ b/scripts/Toggle-CI.ps1 @@ -0,0 +1,37 @@ +<# +.Synopsis + Toggle CMSEnableCI Key valu in DB with flag. +#> + +param ( + [switch]$CIEnabled +) + +Import-Module (Resolve-Path Settings) ` + -Function ` + Get-AppSettings ` + -Force + +Import-Module (Resolve-Path Utilities) ` + -Function ` + Invoke-ExpressionWithException, ` + Invoke-SqlQuery, ` + Get-ConnectionString, ` + Write-Status ` + -Force + +# Use a conditional expression to set KeyValue based on the boolean $Argument +$keyValue = if ($CIEnabled) { 'True' } else { 'False' } + +$appSettings = Get-AppSettings +$connection = Get-ConnectionString $appSettings + +$command = "Invoke-SqlQuery " + ` + "-connectionString ""$connection"" " + ` + "-query ""UPDATE CMS_SettingsKey SET KeyValue='$keyValue' WHERE KeyName='CMSEnableCI'"" " + +Invoke-ExpressionWithException $command + +Write-Host "`n" +Write-Status "CI restore for Enabled=$keyValue" +Write-Host "`n" \ No newline at end of file diff --git a/scripts/Update-DB.ps1 b/scripts/Update-DB.ps1 new file mode 100644 index 0000000..dc85ac3 --- /dev/null +++ b/scripts/Update-DB.ps1 @@ -0,0 +1,32 @@ +<# +.Synopsis + Updates the local with hotfix according to version of packages of live site. +#> + +Import-Module (Resolve-Path Settings) ` + -Function ` + Get-AppSettings ` + -Force + +Import-Module (Resolve-Path Utilities) ` + -Function ` + Invoke-ExpressionWithException, ` + Write-Status ` + -Force + +$appSettings = Get-AppSettings + +$command = "dotnet run " + ` + "--launch-profile $($appSettings.LaunchProfile) " + ` + "-c $($appSettings.Configuration) " + ` + "--no-build " + ` + "--no-restore " + ` + "--project $($appSettings.XbKProjectPath) " + ` + "--kxp-update " + ` + "--skip-confirmation" + +Invoke-ExpressionWithException $command + +Write-Host "`n" +Write-Status "Updated DB to latest hotfix" +Write-Host "`n" diff --git a/scripts/Utilities/Utilities.psm1 b/scripts/Utilities/Utilities.psm1 index b2493e6..5bc6835 100644 --- a/scripts/Utilities/Utilities.psm1 +++ b/scripts/Utilities/Utilities.psm1 @@ -1,65 +1,15 @@ # Utilities -$scriptConfig = @{} -$scriptConfig.WorkspaceFolder = ".." -$scriptConfig.SolutionFileName = "Kentico.Xperience.Zapier.sln" -$scriptConfig.AssemblyName = "DancingGoat" - -<# - .DESCRIPTION - Returns shared configuration for PowerShell scripts -#> -function Get-ScriptConfig { - return $scriptConfig -} - -<# - .DESCRIPTION - Returns the main solution file path -#> -function Get-SolutionPath { - return Resolve-Path(Join-Path $($scriptConfig.WorkspaceFolder) $($scriptConfig.SolutionFileName)) -} - -<# - .DESCRIPTION - Returns the web application folder path from the workspace root -#> -function Get-WebProjectPath { - return Resolve-Path(Join-Path $($scriptConfig.WorkspaceFolder) "examples/DancingGoat") -} - -<# - .DESCRIPTION - Returns the admin application folder path from the workspace root -#> -<#function Get-AdminProjectPath { - return Resolve-Path(Join-Path $($scriptConfig.WorkspaceFolder) "src/Kentico.Community.Portal.Admin") -}#> - -<# - .DESCRIPTION - Returns the admin client application folder path from the workspace root -#> -<#function Get-AdminClientProjectPath { - return Resolve-Path(Join-Path $($scriptConfig.WorkspaceFolder) "src/Kentico.Community.Portal.Admin/Client") -}#> - -<# - .DESCRIPTION - Returns the Core project folder path from the workspace root -#> -<#function Get-CoreProjectPath { - return Resolve-Path(Join-Path $($scriptConfig.WorkspaceFolder) "src/Kentico.Community.Portal.Core") -}#> - - <# .DESCRIPTION Gets the database connection string from the user secrets or appsettings.json file #> -<#function Get-ConnectionString { - $projectPath = Get-WebProjectPath +function Get-ConnectionString { + param ( + [PSCustomObject]$appSettings + ) + + $projectPath = $appSettings.XbKProjectPath # Try to get the connection string from user secrets first Write-Host "Checking for a connection string user secrets for project: $projectPath" @@ -74,7 +24,7 @@ function Get-WebProjectPath { return $connectionString } - $appSettingFileName = $Env:ASPNETCORE_ENVIRONMENT -eq "CI" ? 'appsettings.CI.json' : 'appsettings.json' + $appSettingFileName = $appSettings.AppSettingsFileName $jsonFilePath = Join-Path $projectPath $appSettingFileName @@ -92,12 +42,45 @@ function Get-WebProjectPath { } return $connectionString; -}#> +} <# -.DESCRIPTION - Ensures the expression successfully exits and throws an exception - with the failed expression if it does not. + .DESCRIPTION + Executes SQL query given by string with provided connection string +#> +function Invoke-SqlQuery { + param ( + [string]$connectionString, + [string]$query + ) + + # Create and open a SQL connection + $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString) + + try { + $connection.Open() + $command = $connection.CreateCommand() + $command.CommandText = $query + $rowsAffected = $command.ExecuteNonQuery() # Return the number of affected rows + + if ($rowsAffected -ne $null) { + Write-Notification "Rows affected: $rowsAffected" + } + return $rowsAffected + } + catch { + Write-Error "An error occurred: $_" + return $null + } + finally { + $connection.Close() + } +} + +<# + .DESCRIPTION + Ensures the expression successfully exits and throws an exception + with the failed expression if it does not. #> function Invoke-ExpressionWithException { param(