From 09b95e17db84ddcd4435853ea363bfcf1251c6ac Mon Sep 17 00:00:00 2001 From: sunuk-salad <113859258+sunuk-salad@users.noreply.github.com> Date: Wed, 31 May 2023 16:46:14 -0700 Subject: [PATCH] Azure devops (#1004) * Netlify ci/cd * Netlify ci/cd * Update Netlify azure pipeline * Fix environment name * Cleanup * temp comment yarn check * Add back yarn check * remove npmAlwaysAuth * Adding back npmAlwaysAuth remove from yarnrc.yml * Update param --- packages/web-app/.azure-pipelines/build.ps1 | 61 +++ packages/web-app/.azure-pipelines/deploy.ps1 | 57 +++ .../web-app/.azure-pipelines/initialize.ps1 | 96 ++++ .../stages/deploy-preview-stage.yaml | 24 + .../stages/deploy-prod-stage.yaml | 25 ++ .../stages/deploy-test-stage.yaml | 25 ++ .../.azure-pipelines/steps/deploy-steps.yaml | 40 ++ .../tasks/install-node-task.yaml | 40 ++ .../.azure-pipelines/tasks/pwsh-task.yaml | 24 + .../web-app/.azure-pipelines/utilities.ps1 | 417 ++++++++++++++++++ packages/web-app/.yarnrc.yml | 2 - packages/web-app/azure-pipelines.yml | 45 ++ 12 files changed, 854 insertions(+), 2 deletions(-) create mode 100755 packages/web-app/.azure-pipelines/build.ps1 create mode 100644 packages/web-app/.azure-pipelines/deploy.ps1 create mode 100755 packages/web-app/.azure-pipelines/initialize.ps1 create mode 100644 packages/web-app/.azure-pipelines/stages/deploy-preview-stage.yaml create mode 100644 packages/web-app/.azure-pipelines/stages/deploy-prod-stage.yaml create mode 100644 packages/web-app/.azure-pipelines/stages/deploy-test-stage.yaml create mode 100644 packages/web-app/.azure-pipelines/steps/deploy-steps.yaml create mode 100644 packages/web-app/.azure-pipelines/tasks/install-node-task.yaml create mode 100644 packages/web-app/.azure-pipelines/tasks/pwsh-task.yaml create mode 100644 packages/web-app/.azure-pipelines/utilities.ps1 create mode 100644 packages/web-app/azure-pipelines.yml diff --git a/packages/web-app/.azure-pipelines/build.ps1 b/packages/web-app/.azure-pipelines/build.ps1 new file mode 100755 index 000000000..f43c70c23 --- /dev/null +++ b/packages/web-app/.azure-pipelines/build.ps1 @@ -0,0 +1,61 @@ +#!/usr/bin/env pwsh +#Requires -Version 7 +[CmdletBinding()] +param( + [Parameter(Mandatory = $True)] + [string]$SiteName, + [Parameter(Mandatory = $True)] + [string]$Context +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$projectRoot = Split-Path -Path $PSScriptRoot -Parent +Push-Location -Path $projectRoot +try { + . (Join-Path -Path $projectRoot -ChildPath '.azure-pipelines' -AdditionalChildPath 'utilities.ps1') + + # Setting up environment variables + Show-LogSection -Content 'Setting up environment variables...' + if ($Context -eq 'production') { + Show-LogInfo -Content 'Setting public url and mixpanel token.' + $Env:PUBLIC_URL = '/app' + if ($SiteName -eq 'test') { + $Env:REACT_APP_MIXPANEL_TOKEN = '4b245bace4eed86ffdfa35efc3addf1d' + $Env:REACT_APP_API_URL = 'https://app-api-testing.salad.com' + $Env:REACT_APP_PAYPAL_URL = 'https://www.sandbox.paypal.com/connect/?flowEntry=static&client_id=AYjYnvjB968mKTIhMqUtLlNa8CJuF9rg_Q4m0Oym5gFvBkZEMPPoooXcG94OjSCjih7kI1_KM25EgfDs&response_type=code&scope=openid%20email%20https%3A%2F%2Furi.paypal.com%2Fservices%2Fpaypalattributes&redirect_uri=https%253A%252F%252Fapp-api-testing.salad.com%252Fapi%252Fv2%252Fpaypal-account-callback' + $Env:REACT_APP_PROHASHING_USERNAME = 'saladtest' + $Env:REACT_APP_SEARCH_ENGINE = 'salad-rewards-test' + $Env:REACT_APP_SEARCH_KEY = 'search-qced4ibef8m4s7xacm9hoqyk' + $Env:REACT_APP_STRAPI_UPLOAD_URL = 'https://cms-api-testing.salad.io' + $Env:REACT_APP_UNLEASH_API_KEY = 'zrujLzhnwVZkIOlS74oZZ0DK7ZXs3Ifo' + $Env:REACT_APP_UNLEASH_URL = 'https://features-testing.salad.com/proxy' + } + else { + $Env:REACT_APP_MIXPANEL_TOKEN = '68db9194f229525012624f3cf368921f' + } + } + + # Build projects. + Show-LogSection -Content 'Building projects...' + Show-LogCommand -Content "yarn run build " + & yarn run build + Assert-LastExitCodeSuccess -LastExecutableName 'yarn' +} +catch { + if (($null -ne $_.ErrorDetails) -and ($null -ne $_.ErrorDetails.Message)) { + Show-LogError -Content $_.ErrorDetails.Message + } + elseif (($null -ne $_.Exception) -and ($null -ne $_.Exception.Message)) { + Show-LogError -Content $_.Exception.Message + } + else { + Show-LogError -Content $_ + } + + exit 1 +} +finally { + Pop-Location +} diff --git a/packages/web-app/.azure-pipelines/deploy.ps1 b/packages/web-app/.azure-pipelines/deploy.ps1 new file mode 100644 index 000000000..49b821c0b --- /dev/null +++ b/packages/web-app/.azure-pipelines/deploy.ps1 @@ -0,0 +1,57 @@ +#!/usr/bin/env pwsh +[CmdletBinding()] +param( + [Parameter(Mandatory = $True)] + [string]$Context +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$projectRoot = Split-Path -Path $PSScriptRoot -Parent +Push-Location -Path $projectRoot +try { + . (Join-Path -Path $projectRoot -ChildPath '.azure-pipelines' -AdditionalChildPath 'utilities.ps1') + + $buildDirectory = Join-Path -Path $projectRoot -ChildPath 'build' + + # Deploy to Netlify + Write-LogSection -Content 'Deploying to Netlify...' + if ($Context -eq 'production') { + Write-LogCommand -Content "netlify deploy --dir ${buildDirectory} --prodIfUnlocked" + & netlify deploy --dir $buildDirectory --prodIfUnlocked + Assert-LastExitCodeSuccess -LastExecutableName 'netlify' + } + else { + $alias = '' + $message = '' + if (Test-AzureDevOpsEnvironment) { + $shortHash = $Env:BUILD_SOURCEVERSION.Substring(0, 7) + $message = "Deploy Preview #${Env:SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}: ${Env:SYSTEM_PULLREQUEST_SOURCEBRANCH}@${shortHash}" + $alias = "deploy-preview-${Env:SYSTEM_PULLREQUEST_PULLREQUESTNUMBER}" + } + else { + $alias = 'no-alias' + $message = 'no-message' + } + Write-LogCommand -Content "netlify deploy --dir ${buildDirectory} --alias ${alias} --message ${message}" + & netlify deploy --dir $buildDirectory --alias $alias --message $message + Assert-LastExitCodeSuccess -LastExecutableName 'netlify' + } +} +catch { + if (($null -ne $_.ErrorDetails) -and ($null -ne $_.ErrorDetails.Message)) { + Write-LogError -Content $_.ErrorDetails.Message + } + elseif (($null -ne $_.Exception) -and ($null -ne $_.Exception.Message)) { + Write-LogError -Content $_.Exception.Message + } + else { + Write-LogError -Content $_ + } + + exit 1 +} +finally { + Pop-Location +} diff --git a/packages/web-app/.azure-pipelines/initialize.ps1 b/packages/web-app/.azure-pipelines/initialize.ps1 new file mode 100755 index 000000000..d72bb0a88 --- /dev/null +++ b/packages/web-app/.azure-pipelines/initialize.ps1 @@ -0,0 +1,96 @@ +#!/usr/bin/env pwsh +[CmdletBinding()] +param() + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$projectRoot = Split-Path -Path $PSScriptRoot -Parent +Push-Location -Path $projectRoot +try { + . (Join-Path -Path $projectRoot -ChildPath '.azure-pipelines' -AdditionalChildPath 'utilities.ps1') + + $buildDirectory = Join-Path -Path $projectRoot -ChildPath 'build' + $srcDirectory = Join-Path -Path $projectRoot -ChildPath 'src' + + # Verify Node.js and npm + Show-LogSection -Content 'Verifying Node.js, npm, and Yarn...' + + $nodeVersion = Get-NodeVersion + if ($null -eq $nodeVersion) { + Write-Error -Message 'Node.js is not installed' + } + + $nvmrcVersion = Get-NvmrcVersion + if ($null -eq $nvmrcVersion -or 0 -ne (Compare-NodeVersion -FirstVersion $nodeVersion -SecondVersion $nvmrcVersion)) { + Write-Error -Message "Node.js ${nvmrcVersion} is not installed (found ${nodeVersion})" + } + + Show-LogInfo -Content "Node.js ${nodeVersion} is installed" + + $npmVersion = Get-NpmVersion + if ($null -eq $npmVersion) { + Write-Error -Message 'npm is not installed' + } + + Show-LogInfo -Content "npm ${npmVersion} is installed" + + $yarnVersion = Get-YarnVersion + if ($null -eq $yarnVersion) { + Write-Error -Message 'Yarn is not installed' + } + + Show-LogInfo -Content "Yarn ${yarnVersion} is installed" + + # Install dependencies + Show-LogSection -Content 'Installing dependencies...' + + Show-LogCommand -Content 'yarn install' + & yarn install + Assert-LastExitCodeSuccess -LastExecutableName 'yarn' + + $netlifyVersion = $null + & npm list netlify-cli --global --depth 0 | Out-Null + if (0 -eq $LastExitCode) { + $netlifyVersion = Get-NetlifyVersion + } + + if ($null -eq $netlifyVersion) { + Show-LogCommand -Content 'npm install --global netlify-cli' + & npm install --global netlify-cli + Assert-LastExitCodeSuccess -LastExecutableName 'npm' + + $netlifyVersion = Get-NetlifyVersion + if ($null -eq $netlifyVersion) { + Write-Error -Message 'Failed to install Netlify CLI' + } + } + + Show-LogInfo -Content "Netlify CLI ${netlifyVersion} is installed" + + # Clean + Show-LogSection -Content 'Cleaning...' + + if (Test-Path -Path $buildDirectory) { + Remove-Item -Path $buildDirectory -Recurse -Force + } + + New-Item -ItemType Directory -Path $buildDirectory | Out-Null + +} +catch { + if (($null -ne $_.ErrorDetails) -and ($null -ne $_.ErrorDetails.Message)) { + Show-LogError -Content $_.ErrorDetails.Message + } + elseif (($null -ne $_.Exception) -and ($null -ne $_.Exception.Message)) { + Show-LogError -Content $_.Exception.Message + } + else { + Show-LogError -Content $_ + } + + exit 1 +} +finally { + Pop-Location +} diff --git a/packages/web-app/.azure-pipelines/stages/deploy-preview-stage.yaml b/packages/web-app/.azure-pipelines/stages/deploy-preview-stage.yaml new file mode 100644 index 000000000..bc5561a19 --- /dev/null +++ b/packages/web-app/.azure-pipelines/stages/deploy-preview-stage.yaml @@ -0,0 +1,24 @@ +parameters: + - name: workingDirectory + type: string + default: "" + +stages: + - stage: DeployPreview + displayName: Deploy Site Preview + jobs: + - deployment: DeployPreview + displayName: Deploy Site Preview + variables: + - group: Netlify + environment: Netlify Test + strategy: + runOnce: + deploy: + steps: + - template: ../steps/deploy-steps.yaml + parameters: + workingDirectory: ${{ parameters.workingDirectory }} + siteId: b32d496d-3b42-4727-bd8c-5798a32b1ad4 + siteName: test + context: deploy-preview diff --git a/packages/web-app/.azure-pipelines/stages/deploy-prod-stage.yaml b/packages/web-app/.azure-pipelines/stages/deploy-prod-stage.yaml new file mode 100644 index 000000000..5518cbc28 --- /dev/null +++ b/packages/web-app/.azure-pipelines/stages/deploy-prod-stage.yaml @@ -0,0 +1,25 @@ +parameters: + - name: workingDirectory + type: string + default: "" + +stages: + - stage: DeployProd + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'), ne(variables['Build.Reason'], 'PullRequest')) + displayName: Deploy to Production Site + jobs: + - deployment: DeployProd + displayName: Deploy to Production Site + variables: + - group: Netlify + environment: Netlify Web App + strategy: + runOnce: + deploy: + steps: + - template: ../steps/deploy-steps.yaml + parameters: + workingDirectory: ${{ parameters.workingDirectory }} + siteId: d5fb99c8-d018-48be-a2c8-1a1900831793 + siteName: production + context: production diff --git a/packages/web-app/.azure-pipelines/stages/deploy-test-stage.yaml b/packages/web-app/.azure-pipelines/stages/deploy-test-stage.yaml new file mode 100644 index 000000000..68f12c445 --- /dev/null +++ b/packages/web-app/.azure-pipelines/stages/deploy-test-stage.yaml @@ -0,0 +1,25 @@ +parameters: + - name: workingDirectory + type: string + default: "" + +stages: + - stage: DeployDev + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'), ne(variables['Build.Reason'], 'PullRequest')) + displayName: Deploy to Test Site + jobs: + - deployment: DeployDev + displayName: Deploy to Test Site + variables: + - group: Netlify + environment: Netlify Test + strategy: + runOnce: + deploy: + steps: + - template: ../steps/deploy-steps.yaml + parameters: + workingDirectory: ${{ parameters.workingDirectory }} + siteId: b32d496d-3b42-4727-bd8c-5798a32b1ad4 + siteName: test + context: production diff --git a/packages/web-app/.azure-pipelines/steps/deploy-steps.yaml b/packages/web-app/.azure-pipelines/steps/deploy-steps.yaml new file mode 100644 index 000000000..ecb935536 --- /dev/null +++ b/packages/web-app/.azure-pipelines/steps/deploy-steps.yaml @@ -0,0 +1,40 @@ +parameters: + - name: workingDirectory + type: string + default: "" + - name: siteId + type: string + default: "" + - name: siteName + type: string + default: "" + - name: context + type: string + default: "" + +steps: + - download: none + - checkout: self + - template: ../tasks/install-node-task.yaml + parameters: + projectDirectory: ${{ parameters.workingDirectory }} + - template: ../tasks/pwsh-task.yaml + parameters: + projectDirectory: ${{ parameters.workingDirectory }} + scriptFile: initialize.ps1 + - template: ../tasks/pwsh-task.yaml + parameters: + projectDirectory: ${{ parameters.workingDirectory }} + scriptFile: build.ps1 + arguments: -SiteName "${{ parameters.siteName }}" -Context "${{ parameters.context }}" + env: + NETLIFY_AUTH_TOKEN: $(NETLIFY_AUTH_TOKEN) + NETLIFY_SITE_ID: ${{ parameters.siteId }} + - template: ../tasks/pwsh-task.yaml + parameters: + projectDirectory: ${{ parameters.workingDirectory }} + scriptFile: deploy.ps1 + arguments: -Context "${{ parameters.context }}" + env: + NETLIFY_AUTH_TOKEN: $(NETLIFY_AUTH_TOKEN) + NETLIFY_SITE_ID: ${{ parameters.siteId }} diff --git a/packages/web-app/.azure-pipelines/tasks/install-node-task.yaml b/packages/web-app/.azure-pipelines/tasks/install-node-task.yaml new file mode 100644 index 000000000..6623315b4 --- /dev/null +++ b/packages/web-app/.azure-pipelines/tasks/install-node-task.yaml @@ -0,0 +1,40 @@ +parameters: + - name: projectDirectory + type: string + default: "" + - name: authenticateNpm + type: boolean + default: true + - name: authenticateYarn + type: boolean + default: true + +steps: + - pwsh: | + $version = (Get-Content -Path .nvmrc -Raw -Encoding utf8).Trim() + Write-Host -Object "##vso[task.setvariable variable=Argument.NodeVersion;isreadonly=true;]${version}" + displayName: Get Node.js version + workingDirectory: ${{ parameters.projectDirectory }} + - task: NodeTool@0 + displayName: Install Node.js + inputs: + versionSpec: "$(Argument.NodeVersion)" + - ${{ if eq(parameters.authenticateNpm, true) }}: + - task: npmAuthenticate@0 + displayName: Login to Azure Artifacts (npm) + inputs: + workingFile: ${{ parameters.projectDirectory }}/.npmrc + - ${{ if eq(parameters.authenticateYarn, true) }}: + - pwsh: | + $yarnConfig = Get-Content -Path .yarnrc.yml -Encoding utf8 + $yarnRegistryLine = $yarnConfig | Select-String -Pattern 'npmRegistryServer:' -SimpleMatch -CaseSensitive + if ($null -ne $yarnRegistryLine) { + $yarnConfig[0..$($yarnRegistryLine[0].LineNumber - 1)], ` + ' npmAlwaysAuth: true', " npmAuthIdent: `"ApiKey:$($Env:SYSTEM_ACCESSTOKEN)`"", ` + $yarnConfig[$($yarnRegistryLine[0].LineNumber)..$($yarnConfig.Count - 1)] | ` + Set-Content -Path .yarnrc.yml -Encoding utf8 + } + displayName: Login to Azure Artifacts (Yarn) + workingDirectory: ${{ parameters.projectDirectory }} + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) diff --git a/packages/web-app/.azure-pipelines/tasks/pwsh-task.yaml b/packages/web-app/.azure-pipelines/tasks/pwsh-task.yaml new file mode 100644 index 000000000..ec503311e --- /dev/null +++ b/packages/web-app/.azure-pipelines/tasks/pwsh-task.yaml @@ -0,0 +1,24 @@ +parameters: + - name: projectDirectory + type: string + default: "" + - name: scriptFile + type: string + default: "" + - name: arguments + type: string + default: "" + - name: env + type: object + default: {} + +steps: + - task: PowerShell@2 + displayName: pwsh ${{ parameters.scriptFile }} + inputs: + filePath: ${{ parameters.projectDirectory }}/.azure-pipelines/${{ parameters.scriptFile }} + pwsh: true + workingDirectory: ${{ parameters.projectDirectory }} + arguments: ${{ parameters.arguments }} + env: + ${{ insert }}: ${{ parameters.env }} diff --git a/packages/web-app/.azure-pipelines/utilities.ps1 b/packages/web-app/.azure-pipelines/utilities.ps1 new file mode 100644 index 000000000..4f8ccb082 --- /dev/null +++ b/packages/web-app/.azure-pipelines/utilities.ps1 @@ -0,0 +1,417 @@ +Set-StrictMode -Version Latest + +function Assert-LastExitCodeSuccess { + [CmdletBinding()] + [OutputType([void])] + param( + # The first version to compare. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $LastExecutableName + ) + + process { + if (0 -lt $LastExitCode) { + Write-Error -Message "${LastExecutableName} exited with code ${LastExitCode}" + } + } +} + +function Compare-NodeVersion { + [CmdletBinding()] + [OutputType([int])] + param( + # The first version to compare. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $FirstVersion, + + # The second version to compare. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $SecondVersion + ) + + process { + $FirstVersion = [System.Management.Automation.SemanticVersion]::new($FirstVersion.TrimStart('v')) + $SecondVersion = [System.Management.Automation.SemanticVersion]::new($SecondVersion.TrimStart('v')) + $FirstVersion.CompareTo($SecondVersion) + } +} + +function Get-NetlifyVersion { + [CmdletBinding()] + [OutputType([string])] + param() + + process { + Get-ToolVersion -ScriptBlock { & netlify --version } + Assert-LastExitCodeSuccess -LastExecutableName 'netlify' + } +} + +function Get-BuildContainerPath { + [CmdletBinding()] + [OutputType([string])] + param( + # The property name. + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] + $Path + ) + + process { + if ([string]::IsNullOrEmpty($Path)) { + '/project' + } + else { + $projectRoot = Split-Path -Path $PSScriptRoot -Parent + $relativePath = [System.IO.Path]::GetRelativePath($projectRoot, $Path) + if ($relativePath.Equals($Path)) { + throw 'The specified path is not a child of the project.' + } + + "/project/$($relativePath -replace '\\', '/')" + } + } +} + +function Get-BuildContainerVolume { + [CmdletBinding()] + [OutputType([string])] + param() + + process { + $projectRoot = Split-Path -Path $PSScriptRoot -Parent + "$($projectRoot):/project" + } +} + +function Get-JsonContent { + [CmdletBinding()] + [OutputType([bool])] + param( + # The path to the JSON file. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Path + ) + + process { + Get-Content -Path $Path -Raw -Encoding utf8 | ConvertFrom-Json + } +} + +function Get-JsonTable { + [CmdletBinding()] + [OutputType([bool])] + param( + # The path to the JSON file. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Path + ) + + process { + Get-Content -Path $Path -Raw -Encoding utf8 | ConvertFrom-Json -AsHashtable + } +} + +function Get-NodeVersion { + [CmdletBinding()] + [OutputType([string])] + param() + + process { + Get-ToolVersion -ScriptBlock { & node --version } + Assert-LastExitCodeSuccess -LastExecutableName 'node' + } +} + +function Get-NpmVersion { + [CmdletBinding()] + [OutputType([string])] + param() + + process { + Get-ToolVersion -ScriptBlock { & npm --version } + Assert-LastExitCodeSuccess -LastExecutableName 'npm' + } +} + +function Get-NvmrcVersion { + [CmdletBinding()] + [OutputType([string])] + param() + + process { + $projectRoot = Split-Path -Path $PSScriptRoot -Parent + try { + $version = Get-Content -Path (Join-Path -Path $projectRoot -ChildPath '.nvmrc') -Raw -Encoding utf8 + if ([string]::IsNullOrWhiteSpace($version)) { + $version = $null + } + else { + $version = $version.Trim() + if (-not $version.StartsWith('v', [System.StringComparison]::Ordinal)) { + $version = "v${version}" + } + } + } + catch { + $version = $null + } + + $version + } +} + +function Get-ToolVersion { + [CmdletBinding()] + [OutputType([string])] + param( + # The script block used to get the tool version. + [Parameter(Mandatory = $true)] + [ValidateNotNull()] + [scriptblock] + $ScriptBlock + ) + + process { + try { + $version = Invoke-Command -ScriptBlock $ScriptBlock + if ([string]::IsNullOrWhiteSpace($version)) { + $version = $null + } + else { + $version = $version.Trim() + } + } + catch { + $version = $null + } + + $version + } +} + +function Get-WorkspacePackages { + [CmdletBinding()] + [OutputType([string[]])] + param() + + process { + $projectRoot = Split-Path -Path $PSScriptRoot -Parent + Push-Location -Path $projectRoot + try { + & yarn workspaces list --verbose --json | ` + ConvertFrom-Json | ` + ForEach-Object -Process { Join-Path -Path $projectRoot -ChildPath $_.location -Resolve } | ` + Where-Object -FilterScript { (Test-Path -Path (Join-Path -Path $_ -ChildPath 'buf.yaml')) -and (Test-Path -Path (Join-Path -Path $_ -ChildPath 'buf.gen.yaml')) } + Assert-LastExitCodeSuccess -LastExecutableName 'yarn' + } + finally { + Pop-Location + } + } +} + +function Get-YarnVersion { + [CmdletBinding()] + [OutputType([string])] + param() + + process { + Get-ToolVersion -ScriptBlock { & yarn --version } + Assert-LastExitCodeSuccess -LastExecutableName 'yarn' + } +} + +function Test-AzureDevOpsEnvironment { + [CmdletBinding()] + [OutputType([bool])] + param() + + process { + [string]::Equals($Env:TF_BUILD, 'True', [StringComparison]::OrdinalIgnoreCase) + } +} + +function Test-JsonProperty { + [CmdletBinding()] + [OutputType([bool])] + param( + # The input object created using `ConvertFrom-Json`. + [Parameter(Mandatory = $true)] + [ValidateNotNull()] + [object] + $InputObject, + + # The property name. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $PropertyName + ) + + process { + $null -ne $InputObject.PSObject.Properties[$PropertyName] + } +} + +function Show-LogCommand { + [CmdletBinding()] + [OutputType([void])] + param( + # The content to write. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Content + ) + + process { + if (Test-AzureDevOpsEnvironment) { + Write-Host -Object "##[command]${Content}" + } + else { + Write-Host -Object $Content -ForegroundColor Cyan + } + } +} + +function Show-LogDebug { + [CmdletBinding()] + [OutputType([void])] + param( + # The content to write. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Content + ) + + process { + if (Test-AzureDevOpsEnvironment) { + Write-Host -Object "##[debug]${Content}" + } + else { + Write-Host -Object $Content -ForegroundColor Magenta + } + } +} + +function Show-LogError { + [CmdletBinding()] + [OutputType([void])] + param( + # The content to write. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Content + ) + + process { + if (Test-AzureDevOpsEnvironment) { + Write-Host -Object "##vso[task.logissue type=error;]${Content}" + } + else { + Write-Host -Object $Content -ForegroundColor Red + } + } +} + +function Show-LogGroupBegin { + [CmdletBinding()] + [OutputType([void])] + param( + # The content to write. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Content + ) + + process { + if (Test-AzureDevOpsEnvironment) { + Write-Host -Object "##[group]${Content}" + } + } +} + +function Show-LogGroupEnd { + [CmdletBinding()] + [OutputType([void])] + param() + + process { + if (Test-AzureDevOpsEnvironment) { + Write-Host -Object '##[endgroup]' + } + } +} + +function Show-LogInfo { + [CmdletBinding()] + [OutputType([void])] + param( + # The content to write. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Content + ) + + process { + Write-Host -Object $Content + } +} + +function Show-LogSection { + [CmdletBinding()] + [OutputType([void])] + param( + # The content to write. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Content + ) + + process { + if (Test-AzureDevOpsEnvironment) { + Write-Host -Object "##[section]${Content}" + } + else { + Write-Host -Object $Content -ForegroundColor Green + } + } +} + +function Show-LogWarning { + [CmdletBinding()] + [OutputType([void])] + param( + # The content to write. + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] + $Content + ) + + process { + if (Test-AzureDevOpsEnvironment) { + Write-Host -Object "##vso[task.logissue type=warning;]${Content}" + } + else { + Write-Host -Object $Content -ForegroundColor Yellow + } + } +} diff --git a/packages/web-app/.yarnrc.yml b/packages/web-app/.yarnrc.yml index ee65b6601..f5390d76c 100644 --- a/packages/web-app/.yarnrc.yml +++ b/packages/web-app/.yarnrc.yml @@ -12,8 +12,6 @@ logFilters: npmScopes: saladtechnologies: - npmAlwaysAuth: true - npmAuthIdent: "VssSessionToken:${NPM_TOKEN}" npmRegistryServer: "https://pkgs.dev.azure.com/SaladTechnologies/_packaging/SaladTechnologies/npm/registry/" packageExtensions: diff --git a/packages/web-app/azure-pipelines.yml b/packages/web-app/azure-pipelines.yml new file mode 100644 index 000000000..9af2739bd --- /dev/null +++ b/packages/web-app/azure-pipelines.yml @@ -0,0 +1,45 @@ +variables: + - name: workingDirectory + value: packages/web-app/ + +trigger: + branches: + include: + - master + paths: + include: + - packages/web-app + exclude: + - packages/web-app/.vscode + - packages/web-app/scripts + - packages/web-app/.gitignore + - packages/web-app/README.md + +pr: + branches: + include: + - master + paths: + include: + - packages/web-app + exclude: + - packages/web-app/.vscode + - packages/web-app/scripts + - packages/web-app/.gitignore + - packages/web-app/README.md + +pool: + vmImage: ubuntu-latest + +stages: + - ${{ if or(ne(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['Build.Reason'], 'PullRequest')) }}: + - template: .azure-pipelines/stages/deploy-preview-stage.yaml + parameters: + workingDirectory: $(Build.Repository.LocalPath)/$(workingDirectory) + - ${{ if and(eq(variables['Build.SourceBranch'], 'refs/heads/master'), ne(variables['Build.Reason'], 'PullRequest')) }}: + - template: .azure-pipelines/stages/deploy-test-stage.yaml + parameters: + workingDirectory: $(Build.Repository.LocalPath)/$(workingDirectory) + - template: .azure-pipelines/stages/deploy-prod-stage.yaml + parameters: + workingDirectory: $(Build.Repository.LocalPath)/$(workingDirectory)