From d6cfc18b21221639c1799ff28406c7e102811f3a Mon Sep 17 00:00:00 2001 From: kryalama <66494519+kryalama@users.noreply.github.com> Date: Fri, 16 Apr 2021 14:52:16 -0700 Subject: [PATCH 1/2] add click plugin js to cdn --- .../rollup.config.js | 18 +- .../scripts/listCdnVersions.ps1 | 671 ++++++++++++++++ .../scripts/publishReleaseToCdn.ps1 | 594 ++++++++++++++ .../scripts/setActiveCdnVersion.ps1 | 731 ++++++++++++++++++ 4 files changed, 2008 insertions(+), 6 deletions(-) create mode 100644 extensions/applicationinsights-clickanalytics-js/scripts/listCdnVersions.ps1 create mode 100644 extensions/applicationinsights-clickanalytics-js/scripts/publishReleaseToCdn.ps1 create mode 100644 extensions/applicationinsights-clickanalytics-js/scripts/setActiveCdnVersion.ps1 diff --git a/extensions/applicationinsights-clickanalytics-js/rollup.config.js b/extensions/applicationinsights-clickanalytics-js/rollup.config.js index 39d24993a..bd7db25d5 100644 --- a/extensions/applicationinsights-clickanalytics-js/rollup.config.js +++ b/extensions/applicationinsights-clickanalytics-js/rollup.config.js @@ -8,6 +8,10 @@ import { updateDistEsmFiles } from "../../tools/updateDistEsm/updateDistEsm"; const version = require("./package.json").version; const outputName = "applicationinsights-clickanalytics-js"; +const verParts = version.split(".") +if (verParts.length != 3) { + throw "Invalid Version! [" + version + "]" +} const banner = [ "/*!", ` * Application Insights JavaScript SDK - Click Analytics, ${version}`, @@ -30,11 +34,11 @@ function doCleanup() { }) } -const browserRollupConfigFactory = isProduction => { +const browserRollupConfigFactory = (isProduction, libVersion) => { const browserRollupConfig = { input: `dist-esm/${outputName}.js`, output: { - file: `browser/${outputName}.js`, + file: `browser/ai.clck.${libVersion}.js`, banner: banner, format: "umd", name: "Microsoft.ApplicationInsights", @@ -61,7 +65,7 @@ const browserRollupConfigFactory = isProduction => { }; if (isProduction) { - browserRollupConfig.output.file = `browser/${outputName}.min.js`; + browserRollupConfig.output.file = `browser/ai.clck.${libVersion}.min.js`; browserRollupConfig.plugins.push( uglify({ ie8: true, @@ -132,8 +136,10 @@ const nodeUmdRollupConfigFactory = (isProduction) => { updateDistEsmFiles(replaceValues, banner); export default [ + browserRollupConfigFactory(true, version), + browserRollupConfigFactory(false, version), + browserRollupConfigFactory(true, verParts[0]), + browserRollupConfigFactory(false, verParts[0]), nodeUmdRollupConfigFactory(true), - nodeUmdRollupConfigFactory(false), - browserRollupConfigFactory(true), - browserRollupConfigFactory(false) + nodeUmdRollupConfigFactory(false) ]; diff --git a/extensions/applicationinsights-clickanalytics-js/scripts/listCdnVersions.ps1 b/extensions/applicationinsights-clickanalytics-js/scripts/listCdnVersions.ps1 new file mode 100644 index 000000000..5227fc9c9 --- /dev/null +++ b/extensions/applicationinsights-clickanalytics-js/scripts/listCdnVersions.ps1 @@ -0,0 +1,671 @@ +param ( + [string] $container = $null, # Identify the container that you want to check blank == all + [string] $storeContainer = "cdn", # Identifies the destination storage account container + [string] $cdnStorePath = "cdnstoragename", # Identifies the target Azure Storage account (by name) + [string] $subscriptionId = $null, # Identifies the target Azure Subscription Id (if not encoded in the cdnStorePath) + [string] $resourceGroup = $null, # Identifies the target Azure Subscription Resource Group (if not encoded in the cdnStorePath) + [string] $sasToken = $null, # The SAS Token to use rather than using or attempting to login + [string] $logPath = $null, # The location where logs should be written + [switch] $showFiles = $false, # Show the individual files with details as well + [switch] $activeOnly = $false, # Only show the active (deployed) versions + [switch] $testOnly = $false, # Uploads to a "tst" test container on the storage account + [switch] $cdn = $false # (No longer used -- kept for now for backward compatibility) +) + +$metaSdkVer = "aijssdkver" +$metaSdkSrc = "aijssdksrc" + +$global:hasErrors = $false +$global:sasToken = $sasToken +$global:resourceGroup = $resourceGroup +$global:storeName = $null # The endpoint needs to the base name of the endpoint, not the full URL (eg. “my-cdn” rather than “my-cdn.azureedge.net”) +$global:subscriptionId = $subscriptionId +$global:storageContext = $null + +Function Log-Params +{ + Log "Container : $container" + Log "Storage Container : $storeContainer" + Log "Store Path : $cdnStorePath" + Log "Log Path : $logDir" + Log "Show Files : $showFiles" + Log "Test Mode : $testOnly" + + if ([string]::IsNullOrWhiteSpace($global:sasToken) -eq $true) { + Log "Mode : User-Credentials" + } else { + Log "Mode : Sas-Token" + } +} + +## Function: Get-TimeStamp +## Purpose: Used to get the timestamp for logging +Function Get-TimeStamp +{ + return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date) +} + +Function Write-LogDetail( + [string] $value +) { + Add-Content $logFile "$(Get-TimeStamp) $value" +} + +## Function: Log +## Purpose: Used to log the output to both the Console and a log file +Function Log( + [string] $value +) { + Write-Host "$(Get-TimeStamp) $value" + Write-LogDetail $value +} + +## Function: Log-Warning +## Purpose: Used to log the output to both the Console and a log file +Function Log-Warning ( + [string] $value +) { + Write-Host "$(Get-TimeStamp) [WRN] $value" -ForegroundColor Yellow -BackgroundColor DarkBlue + Write-LogDetail "[WRN] $value" +} + +## Function: Log-Warning +## Purpose: Used to log the output to both the Console and a log file +Function Log-Failure ( + [string] $value, + [boolean] $isTerminal = $true +) { + if ($isTerminal -eq $true) { + Write-Host "$(Get-TimeStamp) [ERR] $value" -ForegroundColor Yellow -BackgroundColor DarkRed + Write-LogDetail "[ERR] $value" + $global:hasErrors = $true + } else { + Write-Host "$(Get-TimeStamp) [INF] $value" -ForegroundColor Red + Write-LogDetail "[INF] $value" + } +} + +Function Log-Exception( + [System.Management.Automation.ErrorRecord] $err, + [boolean] $asError = $true, + [string] $prefix = "" +) { + Log-Failure "$($prefix)Exception: $($err.Exception.Message)" $asError + Log-Failure "$($prefix)Source : $($err.Exception.Source)" $asError + Write-LogDetail "$($prefix)Full Exception: $($err.Exception)" + Log-Failure "$($prefix)$($err.ScriptStackTrace)" $asError +} + +Function Log-Errors( + [boolean] $asError = $true, + [string] $prefix = "" +) { + foreach ($err in $Error) { + Log-Exception $err $asError + foreach ($innerEx in $err.InnerExceptions) { + Log-Exception $innerEx $asError "$prefix " + } + } +} + +## Function: InstallRequiredModules +## Purpose: Checks and attempts to install the required AzureRM Modules +Function InstallRequiredModules ( + [int32] $retry = 1 +) { + if ($retry -le 0) { + Log-Warning "--------------------------------------" + Log-Warning "Failed to install the required Modules" + Log-Warning "--------------------------------------" + Log "" + Log "Please install / run the following from an administrator powershell window" + Log "Install-Module AzureRM" + Log "Install-Module Az.Storage" + Log "" + Log "Additional Notes for Internal Application Insights Team" + Log "Please review the 'Release to CDN Failures' Page on the teams documentation for further assistance" + + exit + } + + $commandsExist = $true + $c = Get-Command Login-AzureRMAccount -errorAction SilentlyContinue + if ($null -eq $c) { + $commandsExist = $false + } else { + Log "Importing Module $($c.Source) for Login-AzureRMAccount" + Import-Module $c.Source + $c = Get-Command Get-AzureRmStorageAccount -errorAction SilentlyContinue + if ($null -eq $c) { + $commandsExist = $false + } else { + Log "Importing Module $($c.Source) for Get-AzureRmStorageAccount" + Import-Module $c.Source + } + } + + if ($commandsExist -eq $false) { + # You will need to at least have the AzureRM module installed + $m = Get-Module -ListAvailable -Name "AzureRM" + if ($null -eq $m) { + Log "The AzureRM module is not currently installed -- it needs to be" + Log "Attempting to Install AzureRM Module" + + InstallRequiredModules $($retry-1) + } + } +} + +Function IsGuid( + [string] $value +) { + $guid = New-Object 'System.Guid' + return [System.Guid]::TryParse($value, [ref]$guid) +} + +Function CheckLogin +{ + $loggedIn = $false + $attempt = 0 + + Log "Checking Logged in status." + while ($loggedIn -eq $false) { + $Error.Clear() + + if ($attempt -ge 5) { + Log-Failure "Unable to login..." + exit 100; + } + + $loggedIn = $true + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + if ([string]::IsNullOrWhiteSpace($global:storeName) -eq $true) { + Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -AccountName $global:storeName -ErrorAction SilentlyContinue | Out-Null + } else { + Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -ErrorAction SilentlyContinue | Out-Null + } + } else { + Get-AzureRmStorageAccount -ErrorAction SilentlyContinue | Out-Null + } + + Log-Errors $false + + #Get-AzureRmSubscription -SubscriptionId $subscriptionId -ErrorAction SilentlyContinue + foreach ($eacherror in $Error) { + if ($eacherror.Exception.ToString() -like "* Login-AzureRmAccount*") { + $loggedIn = $false + + Log "Logging in... Atempt #$($attempt + 1)" + $Error.Clear() + Login-AzureRMAccount -ErrorAction SilentlyContinue + Log-Errors $false + break + } elseif ($eacherror.Exception.ToString() -like "* Connect-AzureRmAccount*") { + $loggedIn = $false + + Log "Connecting... Atempt #$($attempt + 1)" + $Error.Clear() + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true -and (IsGuid($global:subscriptionId) -eq $true)) { + Connect-AzureRmAccount -ErrorAction SilentlyContinue -Subscription $global:subscriptionId | Out-Null + } else { + Connect-AzureRmAccount -ErrorAction SilentlyContinue | Out-Null + } + + Log-Errors $false + break + } else { + $loggedIn = $false + Log-Warning "Unexpected failure $($eacherror.Exception)" + } + } + + $attempt ++ + } + + $Error.Clear() +} + +Function ParseCdnStorePath +{ + if ([string]::IsNullOrWhiteSpace($cdnStorePath) -eq $true) { + Log-Failure "Invalid Store Path ($cdnStorePath)" + exit 10 + } + + $global:storeName = $cdnStorePath + $splitOptions = [System.StringSplitOptions]::RemoveEmptyEntries + $parts = $cdnStorePath.split(":", $splitOptions) + if ($parts.Length -eq 3) { + $global:subscriptionId = $parts[0] + $global:resourceGroup = $parts[1] + $global:storeName = $parts[2] + } elseif ($parts.Length -eq 2) { + $global:subscriptionId = $parts[0] + $global:storeName = $parts[1] + } elseif ($parts.Length -ne 1) { + Log-Failure "Invalid Store Path ($cdnStorePath)" + exit 11 + } + + if ([string]::IsNullOrWhiteSpace($global:storeName) -eq $true) { + Log-Failure "Missing Storage name from Path ($cdnStorePath)" + exit 12 + } + + Log "----------------------------------------------------------------------" + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true) { + Log "Subscription: $global:subscriptionId" + } + + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + Log "Group : $global:resourceGroup" + } + + Log "StoreName : $global:storeName" + Log "----------------------------------------------------------------------" +} + +Function ValidateAccess +{ + CheckLogin | Out-Null + + $store = $null + $subs = $null + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true -and (IsGuid($global:subscriptionId) -eq $true)) { + Select-AzureRmSubscription -SubscriptionId $global:subscriptionId | Out-Null + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true -and [string]::IsNullOrWhiteSpace($global:storeName) -ne $true) { + Log " Getting Storage Account" + $accounts = Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -AccountName $global:storeName + if ($null -ne $accounts -and $accounts.Length -eq 1) { + $store = $accounts[0] + } + } + + if ($null -eq $store) { + Log " Selecting Subscription" + $subs = Get-AzureRmSubscription -SubscriptionId $global:subscriptionId | Where-Object State -eq "Enabled" + } + } else { + Log " Finding Subscriptions" + $subs = Get-AzureRmSubscription | Where-Object State -eq "Enabled" + } + + if ($null -eq $store -and $null -ne $subs) { + if ($null -eq $subs -or $subs.Length -eq 0) { + Log-Failure " - No Active Subscriptions" + exit 500; + } + + # Limit to the defined subscription + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true) { + $subs = $subs | Where-Object Id -like $("*$global:subscriptionId*") + } + + Log " Finding Storage Account" + $accounts = $null + foreach ($id in $subs) { + Log " Checking Subscription $($id.Id)" + Select-AzureRmSubscription -SubscriptionId $id.Id | Out-Null + $accounts = $null + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + if ([string]::IsNullOrWhiteSpace($global:storeName) -eq $true) { + $accounts = Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -AccountName $global:storeName + } else { + $accounts = Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup + } + } else { + $accounts = Get-AzureRmStorageAccount + } + + if ($null -ne $accounts -and $accounts.Length -ge 1) { + # If a resource group has been supplied limit to just that group + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + $accounts = $accounts | Where-Object ResourceGroupName -eq $global:resourceGroup + } + + $accounts = $accounts | Where-Object StorageAccountName -eq $global:storeName + + if ($accounts.Length -gt 1) { + Log-Failure " - Too many [$($accounts.Length)] matching storage accounts located for $($cdnStorePath) please specify the resource group as a prefix for the store name parameter '[:[:]]" + exit 300; + } elseif ($accounts.Length -eq 1 -and $null -eq $store) { + Log " - Found Candidate Subscription $($id.Id)" + $global:subscriptionId = $id.Id + $store = $accounts[0] + } elseif ($accounts.Length -ne 0 -or $null -ne $store) { + Log-Failure " - More than 1 storage account was located for $($cdnStorePath) please specify the resource group as a prefix for the store name parameter '[:[:]]" + exit 300; + } else { + Log " - No Matching Accounts" + } + } else { + Log " - No Storage Accounts" + } + } + } + + if ($null -eq $store) { + Log-Failure " Unable to access or locate a storage account $cdnStorePath" + exit 300; + } + + $global:storeName = $store.StorageAccountName + $global:resourceGroup = $store.ResourceGroupName + + Log "Getting StorageContext for" + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true) { + Log " Subscription: $global:subscriptionId" + } + + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + Log " Group : $global:resourceGroup" + } + + Log " StoreName : $global:storeName" + $global:storageContext = $store.context + if ($null -eq $global:storageContext) { + Log-Failure " - Unable to access or locate a storage account $cdnStorePath" + exit 301; + } +} + +Function GetVersion( + [string] $name +) { + $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+(\.\d+)*(-[^\.]+)?)(\.(?:gbl\.js|gbl\.min\.js|cjs\.js|cjs\.min\.js|js|min\.js)(?:\.map)?)$' + $match = ($name | select-string $regMatch -AllMatches).matches + + if ($null -eq $match) { + return $null + } + + [hashtable]$return = @{} + $return.path = $match.groups[1].value + $return.prefix = $match.groups[2].value + $return.ver = $match.groups[3].value + $return.verType = $match.groups[5].value + $return.ext = $match.groups[6].value + + return $return +} + +Function GetContainerContext( + [string] $storagePath +) { + # Don't try and publish anything if any errors have been logged + if ($global:hasErrors -eq $true) { + exit 2 + } + + while($storagePath.endsWith("/") -eq $true) { + $storagePath = $storagePath.Substring(0, $storagePath.Length-1) + } + + $blobPrefix = "" + $storageContainer = "" + + $tokens = $storagePath.split("/", 2) + if ($tokens.length -eq 0) { + Log-Warning "Invalid storage path - $storagePath" + exit + } + + $storageContainer = $tokens[0] + if ($tokens.Length -eq 2) { + $blobPrefix = $tokens[1] + "/" + } + + if ($testOnly -eq $true) { + $blobPrefix = $storageContainer + "/" + $blobPrefix + $storageContainer = "tst" + } + + if ($storeContainer.Length -gt 0) { + $blobPrefix = $storageContainer + "/" + $blobPrefix + $storageContainer = $storeContainer + } + + Log "Container : $storageContainer Prefix: $blobPrefix" + + # Use the Users Storage Context credentials + $azureContext = $global:storageContext + if ([string]::IsNullOrWhiteSpace($global:sasToken) -ne $true) { + # Use the Sas token + $azureContext = New-AzureStorageContext -StorageAccountName $global:storeName -Sastoken $global:sasToken -ErrorAction SilentlyContinue + } + + $azContainer = Get-AzureStorageContainer -Name $storageContainer -Context $azureContext -ErrorAction SilentlyContinue + if ($null -eq $azContainer) { + Log "Container [$storageContainer] does not exist" + return + } + + if ($global:hasErrors -eq $true) { + exit 3 + } + + [hashtable]$return = @{} + $return.azureContext = $azureContext + $return.container = $azContainer + $return.storageContainer = $storageContainer + $return.blobPrefix = $blobPrefix + + return $return +} + +Function GetVersionFiles( + [system.collections.generic.dictionary[string, system.collections.generic.list[hashtable]]] $files, + [string] $storagePath, + [string] $filePrefix +) { + + $context = GetContainerContext $storagePath + if ($null -eq $context) { + return + } + + $blobs = Get-AzureStorageBlob -Container $context.storageContainer -Context $context.azureContext -Prefix "$($context.blobPrefix)$filePrefix" -ErrorAction SilentlyContinue + foreach ($blob in $blobs) { + $version = GetVersion $blob.Name + + if ($null -ne $version -and [string]::IsNullOrWhiteSpace($version.ver) -ne $true -and $version.prefix -eq $filePrefix) { + $fileList = $null + if ($files.ContainsKey($version.ver) -ne $true) { + $fileList = New-Object 'system.collections.generic.list[hashtable]' + $files.Add($version.ver, $fileList) + } else { + $fileList = $files[$version.ver] + } + + $theBlob = [hashtable]@{} + $theBlob.path = "$($context.storageContainer)/$($version.path)" + $theBlob.blob = $blob + $fileList.Add($theBlob) + } + } +} + +Function HasMetaTag( + $blob, + [string] $metaKey +) { + foreach ($dataKey in $blob.ICloudBlob.Metadata.Keys) { + if ($dataKey -ieq $metaKey) { + return $true + } + } + + return $false +} + +Function GetMetaTagValue( + $blob, + [string] $metaKey +) { + $value = "" + + foreach ($dataKey in $blob.ICloudBlob.Metadata.Keys) { + if ($dataKey -ieq $metaKey) { + $value = $blob.ICloudBlob.Metadata[$dataKey] + break + } + } + + return $value +} + +Function ListVersions( + [system.collections.generic.dictionary[string, system.collections.generic.list[hashtable]]] $files +) { + + $sortedKeys = $files.Keys | Sort-Object + $orderedKeys = New-Object 'system.collections.generic.list[string]' + foreach ($key in $sortedKeys) { + $verParts = $key.split("."); + if ($verParts.Length -eq 3) { + continue + } + $orderedKeys.Add($key) + } + + if ($activeOnly -ne $true) { + foreach ($key in $sortedKeys) { + $verParts = $key.split("."); + if ($verParts.Length -ne 3) { + continue + } + $orderedKeys.Add($key) + } + } + + foreach ($key in $orderedKeys) { + $verParts = $key.split("."); + if ($activeOnly -eq $true -and $verParts.Length -gt 2) { + continue + } + + $fileList = $files[$key] + $paths = [hashtable]@{} + if ($showFiles -ne $true) { + $pathList = "" + foreach ($theBlob in $fileList) { + $thePath = $theBlob.path + if (HasMetaTag($theBlob, $metaSdkSrc)) { + $sdkVer = GetMetaTagValue $theBlob $metaSdkSrc + $version = GetVersion $sdkVer + $thePath = "$($version.path)$($version.prefix)$($version.ver)" + } + + if ($paths.ContainsKey($thePath) -ne $true) { + $paths[$thePath] = $true + $value = "{0,-20}" -f $thePath + $pathList = "$pathList$value " + } else { + $paths[$thePath] = ($paths[$thePath] + 1) + } + } + + foreach ($thePath in $paths.Keys | Sort-Object) { + Log $(" - {1,-40} ({0})" -f $paths[$thePath],$thePath) + } + + Log $("v{0,-12} ({1,2}) - {2}" -f $key,$($fileList.Count),$pathList.Trim()) + } else { + Log $("v{0,-12} ({1,2})" -f $key,$($fileList.Count)) + foreach ($theBlob in $fileList) { + $blob = $theBlob.blob + $blob.ICloudBlob.FetchAttributes() + $sdkVersion = GetMetaTagValue $blob $metaSdkVer + if ([string]::IsNullOrWhiteSpace($sdkVersion) -ne $true) { + $sdkVersion = "v$sdkVersion" + } else { + $sdkVersion = "---" + } + + $metaTags = "" + foreach ($dataKey in $blob.ICloudBlob.Metadata.Keys) { + if ($dataKey -ine $metaSdkVer) { + $metaTags = "$metaTags$dataKey=$($blob.ICloudBlob.Metadata[$dataKey]); " + } + } + + $cacheControl = $blob.ICloudBlob.Properties.CacheControl + $cacheControl = $cacheControl -replace "public","pub" + $cacheControl = $cacheControl -replace "max-age=31536000","1yr" + $cacheControl = $cacheControl -replace "max-age=1800","30m" + $cacheControl = $cacheControl -replace "max-age=900","15m" + $cacheControl = $cacheControl -replace "max-age=300"," 5m" + $cacheControl = $cacheControl -replace "immutable","im" + $cacheControl = $cacheControl -replace ", "," " + + Log $(" - {0,-44}{3,-13}{1,6:N1} Kb {2:yyyy-MM-dd HH:mm:ss} {4,10} {5}" -f $($blob.ICloudBlob.Container.Name + "/" + $blob.Name),($blob.Length/1kb),$blob.LastModified,$sdkVersion,$cacheControl,$metaTags) + } + } + } +} + +Function Validate-Params +{ + # Validate parameters + if ([string]::IsNullOrWhiteSpace($container) -ne $true -and "beta","next","public" -NotContains $container) { + Log-Failure "[$($container)] is not a valid value, must be beta, next or public" + } +} + +$Error.Clear() + +#----------------------------------------------------------------------------- +# Start of Script +#----------------------------------------------------------------------------- +$logDir = $logPath +if ([string]::IsNullOrWhiteSpace($logPath) -eq $true) { + $logDir = join-path ${env:SystemDrive} "\Logs" +} + +if (!(Test-Path -Path $logDir)) { + New-Item -ItemType directory -Path $logDir +} + +$fileTimeStamp = ((get-date).ToUniversalTime()).ToString("yyyyMMddThhmmss") +$logFile = "$logDir\listCdnVersionsLog_$fileTimeStamp.txt" + +Log-Params +Validate-Params + +# Don't try and list anything if any errors have been logged +if ($global:hasErrors -eq $true) { + exit 2 +} + +# You will need to at least have the AzureRM module installed +InstallRequiredModules +ParseCdnStorePath + +if ([string]::IsNullOrWhiteSpace($global:sasToken) -eq $true) { + Log "**********************************************************************" + Log "Validating user access" + Log "**********************************************************************" + ValidateAccess +} + +Log "======================================================================" +# List the files for each container +$files = New-Object 'system.collections.generic.dictionary[string, system.collections.generic.list[hashtable]]' + +# Get the beta files +if ([string]::IsNullOrWhiteSpace($container) -eq $true -or $container -eq "beta") { + GetVersionFiles $files "beta/ext" "ai.clck." +} + +# Get the next files +if ([string]::IsNullOrWhiteSpace($container) -eq $true -or $container -eq "next") { + GetVersionFiles $files "next/ext" "ai.clck." +} + +# Get the public files (scripts/b) +if ([string]::IsNullOrWhiteSpace($container) -eq $true -or $container -eq "public") { + GetVersionFiles $files "scripts/b/ext" "ai.clck." +} + +ListVersions $files +Log "======================================================================" diff --git a/extensions/applicationinsights-clickanalytics-js/scripts/publishReleaseToCdn.ps1 b/extensions/applicationinsights-clickanalytics-js/scripts/publishReleaseToCdn.ps1 new file mode 100644 index 000000000..03d882520 --- /dev/null +++ b/extensions/applicationinsights-clickanalytics-js/scripts/publishReleaseToCdn.ps1 @@ -0,0 +1,594 @@ +param ( + [string] $releaseFrom = $null, # The root path for where to find the files to be released + [string] $storeContainer = "cdn", # Identifies the destination storage account container + [string] $cdnStorePath = "cdnstoragename", # Identifies the target Azure Storage account (by name) + [string] $subscriptionId = $null, # Identifies the target Azure Subscription Id (if not encoded in the cdnStorePath) + [string] $resourceGroup = $null, # Identifies the target Azure Subscription Resource Group (if not encoded in the cdnStorePath) + [string] $sasToken = $null, # The SAS Token to use rather than using or attempting to login + [string] $logPath = $null, # The location where logs should be written + [switch] $overwrite = $false, # Overwrite any existing files + [switch] $testOnly = $false, # Uploads to a "tst" test container on the storage account + [switch] $cdn = $false # (No longer used -- kept for now for backward compatibility) +) + +$metaSdkVer = "aijssdkver" + +$global:hasErrors = $false +$global:cacheValue = $null +$global:sasToken = $sasToken +$global:resourceGroup = $resourceGroup +$global:storeName = $null # The endpoint needs to the base name of the endpoint, not the full URL (eg. “my-cdn” rather than “my-cdn.azureedge.net”) +$global:subscriptionId = $subscriptionId +$global:storageContext = $null + +Function Log-Params +{ + Log "Storage Container : $storeContainer" + Log "Store Path : $cdnStorePath" + Log "Overwrite : $overwrite" + Log "Test Mode : $testOnly" + Log "SourcePath : $jsSdkDir" + Log "Log Path : $logDir" + + if ([string]::IsNullOrWhiteSpace($global:sasToken) -eq $true) { + Log "Mode : User-Credentials" + } else { + Log "Mode : Sas-Token" + } +} + +## Function: Get-TimeStamp +## Purpose: Used to get the timestamp for logging +Function Get-TimeStamp +{ + return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date) +} + +Function Write-LogDetail( + [string] $value +) { + Add-Content $logFile "$(Get-TimeStamp) $value" +} + +## Function: Log +## Purpose: Used to log the output to both the Console and a log file +Function Log( + [string] $value +) { + Write-Host "$(Get-TimeStamp) $value" + Write-LogDetail $value +} + +## Function: Log-Warning +## Purpose: Used to log the output to both the Console and a log file +Function Log-Warning ( + [string] $value +) { + Write-Host "$(Get-TimeStamp) [WRN] $value" -ForegroundColor Yellow -BackgroundColor DarkBlue + Write-LogDetail "[WRN] $value" +} + +## Function: Log-Warning +## Purpose: Used to log the output to both the Console and a log file +Function Log-Failure ( + [string] $value, + [boolean] $isTerminal = $true +) { + if ($isTerminal -eq $true) { + Write-Host "$(Get-TimeStamp) [ERR] $value" -ForegroundColor Yellow -BackgroundColor DarkRed + Write-LogDetail "[ERR] $value" + $global:hasErrors = $true + } else { + Write-Host "$(Get-TimeStamp) [INF] $value" -ForegroundColor Red + Write-LogDetail "[INF] $value" + } +} + +Function Log-Exception( + [System.Management.Automation.ErrorRecord] $err, + [boolean] $asError = $true, + [string] $prefix = "" +) { + Log-Failure "$($prefix)Exception: $($err.Exception.Message)" $asError + Log-Failure "$($prefix)Source : $($err.Exception.Source)" $asError + Write-LogDetail "$($prefix)Full Exception: $($err.Exception)" + Log-Failure "$($prefix)$($err.ScriptStackTrace)" $asError +} + +Function Log-Errors( + [boolean] $asError = $true, + [string] $prefix = "" +) { + foreach ($err in $Error) { + Log-Exception $err $asError + foreach ($innerEx in $err.InnerExceptions) { + Log-Exception $innerEx $asError "$prefix " + } + } +} + +## Function: InstallRequiredModules +## Purpose: Checks and attempts to install the required AzureRM Modules +Function InstallRequiredModules ( + [int32] $retry = 1 +) { + if ($retry -le 0) { + Log-Warning "--------------------------------------" + Log-Warning "Failed to install the required Modules" + Log-Warning "--------------------------------------" + Log "" + Log "Please install / run the following from an administrator powershell window" + Log "Install-Module AzureRM" + Log "Install-Module Az.Storage" + Log "" + Log "Additional Notes for Internal Application Insights Team" + Log "Please review the 'Release to CDN Failures' Page on the teams documentation for further assistance" + + exit + } + + $commandsExist = $true + $c = Get-Command Login-AzureRMAccount -errorAction SilentlyContinue + if ($null -eq $c) { + $commandsExist = $false + } else { + Log "Importing Module $($c.Source) for Login-AzureRMAccount" + Import-Module $c.Source + $c = Get-Command Get-AzureRmStorageAccount -errorAction SilentlyContinue + if ($null -eq $c) { + $commandsExist = $false + } else { + Log "Importing Module $($c.Source) for Get-AzureRmStorageAccount" + Import-Module $c.Source + } + } + + if ($commandsExist -eq $false) { + # You will need to at least have the AzureRM module installed + $m = Get-Module -ListAvailable -Name "AzureRM" + if ($null -eq $m) { + Log "The AzureRM module is not currently installed -- it needs to be" + Log "Attempting to Install AzureRM Module" + + InstallRequiredModules $($retry-1) + } + } +} + +Function IsGuid( + [string] $value +) { + $guid = New-Object 'System.Guid' + return [System.Guid]::TryParse($value, [ref]$guid) +} + +Function CheckLogin +{ + $loggedIn = $false + $attempt = 0 + + Log "Checking Logged in status." + while ($loggedIn -eq $false) { + $Error.Clear() + + if ($attempt -ge 5) { + Log-Failure "Unable to login..." + exit 100; + } + + $loggedIn = $true + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + if ([string]::IsNullOrWhiteSpace($global:storeName) -eq $true) { + Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -AccountName $global:storeName -ErrorAction SilentlyContinue | Out-Null + } else { + Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -ErrorAction SilentlyContinue | Out-Null + } + } else { + Get-AzureRmStorageAccount -ErrorAction SilentlyContinue | Out-Null + } + + Log-Errors $false + + #Get-AzureRmSubscription -SubscriptionId $subscriptionId -ErrorAction SilentlyContinue + foreach ($eacherror in $Error) { + if ($eacherror.Exception.ToString() -like "* Login-AzureRmAccount*") { + $loggedIn = $false + + Log "Logging in... Atempt #$($attempt + 1)" + $Error.Clear() + Login-AzureRMAccount -ErrorAction SilentlyContinue + Log-Errors $false + break + } elseif ($eacherror.Exception.ToString() -like "* Connect-AzureRmAccount*") { + $loggedIn = $false + + Log "Connecting... Atempt #$($attempt + 1)" + $Error.Clear() + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true -and (IsGuid($global:subscriptionId) -eq $true)) { + Connect-AzureRmAccount -ErrorAction SilentlyContinue -Subscription $global:subscriptionId | Out-Null + } else { + Connect-AzureRmAccount -ErrorAction SilentlyContinue | Out-Null + } + + Log-Errors $false + break + } else { + $loggedIn = $false + Log-Warning "Unexpected failure $($eacherror.Exception)" + } + } + + $attempt ++ + } + + $Error.Clear() +} + +Function AddReleaseFile( + $files, + [string] $releaseDir, + [string] $name +) { + $sourcePath = (Join-Path $releaseDir -ChildPath ($name)) + + if (-Not (Test-Path $sourcePath)) { + Log-Warning "Missing expected source file '$sourcePath'"; + exit + } + + Log " - $sourcePath" + $files.Add($name, $sourcePath) +} + +Function GetReleaseFiles +{ + if ([string]::IsNullOrWhiteSpace($jsSdkDir) -eq $true) { + Log-Warning "Invalid JS Sdk Path" + exit + } + + Log "Releasing from : $jsSdkDir" + + # find version number + $packageJsonPath = Join-Path $jsSdkDir -ChildPath "package.json" + if (-Not (Test-Path $packageJsonPath)) { + Log-Warning "'$packageJsonPath' file not found, please enter the top JSSDK directory."; + exit + } + + $packagesJson = (Get-Content $packageJsonPath -Raw) | ConvertFrom-Json + $version = $packagesJson.version; + + Log "Version : $version" + + # check if the minified dir exists + $jsSdkSrcDir = Join-Path $jssdkDir -ChildPath "browser\"; + + if (-Not (Test-Path $jsSdkSrcDir)) { + Log-Warning "'$jsSdkSrcDir' directory doesn't exist. Compile JSSDK first."; + exit + } + + $files = New-Object 'system.collections.generic.dictionary[string,string]' + + Log "Adding files"; + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.js" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.js.map" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.min.js" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.min.js.map" + + return $files +} + +Function GetVersion( + [string] $name +) { + $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+(\.\d+)*(-[^\.]+)?)(\.(?:js|min\.js)(?:\.map)?)$' + $match = ($name | select-string $regMatch -AllMatches).matches + + if ($null -eq $match) { + return $null + } + + [hashtable]$return = @{} + $return.path = $match.groups[1].value + $return.prefix = $match.groups[2].value + $return.ver = $match.groups[3].value + $return.verType = $match.groups[5].value + $return.ext = $match.groups[6].value + + return $return +} + +Function PublishFiles( + $files, + [string] $storagePath, + [string] $cacheControlValue, + [bool] $overwrite +) { + + # Don't try and publish anything if any errors have been logged + if ($global:hasErrors -eq $true) { + exit 2 + } + + while($storagePath.endsWith("/") -eq $true) { + $storagePath = $storagePath.Substring(0, $storagePath.Length-1) + } + + $blobPrefix = "" + $storageContainer = "" + + $tokens = $storagePath.split("/", 2) + if ($tokens.length -eq 0) { + Log-Warning "Invalid storage path - $storagePath" + exit + } + + $storageContainer = $tokens[0] + if ($tokens.Length -eq 2) { + $blobPrefix = $tokens[1] + "/" + } + + if ($testOnly -eq $true) { + $blobPrefix = $storageContainer + "/" + $blobPrefix + $storageContainer = "tst" + } + + if ($storeContainer.Length -gt 0) { + $blobPrefix = $storageContainer + "/" + $blobPrefix + $storageContainer = $storeContainer + } + + Log "Container : $storageContainer Prefix: $blobPrefix" + Log " Using Cache Control: $cacheControlValue" + + # Use the Users Storage Context credentials + $azureContext = $global:storageContext + if ([string]::IsNullOrWhiteSpace($global:sasToken) -ne $true) { + # Use the Sas token + $azureContext = New-AzureStorageContext -StorageAccountName $global:storeName -Sastoken $global:sasToken + } + + $container = Get-AzureStorageContainer -Name $storageContainer -Context $azureContext -ErrorAction SilentlyContinue + if ($null -eq $container) { + $Error.Clear() + New-AzureStorageContainer -Name $storageContainer -Context $azureContext -Permission Blob -ErrorAction SilentlyContinue | Out-Null + Log-Errors + } + + if ($global:hasErrors -eq $true) { + exit 3 + } + + # upload files to Azure Storage + foreach($name in $files.Keys) { + $path = $files[$name] + + $metadata = [hashtable]@{} + $version = GetVersion $name + if ($null -ne $version) { + $metadata[$metaSdkVer] = $version.ver + } + + $newBlob = $null + $blob = Get-AzureStorageBlob -Container $storageContainer -Blob ($blobPrefix + $name) -Context $azureContext -ErrorAction SilentlyContinue + if ($null -ne $blob -and $blob.Count -ne 0) { + if ($overwrite -eq $true) { + Log " Overwriting $($blobPrefix + $name)" + $newBlob = Set-AzureStorageBlobContent -Force -Container $storageContainer -File $path -Blob ($blobPrefix + $name) -Context $azureContext -Properties @{CacheControl = $cacheControlValue; ContentType = $contentType} -Metadata $metadata + if ($null -eq $newBlob) { + Log-Failure " Failed to overwrite/upload $($blobPrefix + $name)" + } + } else { + Log-Warning " $($blobPrefix + $name) is already present" + } + } else { + Log " Uploading $($blobPrefix + $name)" + $newBlob = Set-AzureStorageBlobContent -Container $storageContainer -File $path -Blob ($blobPrefix + $name) -Context $azureContext -Properties @{CacheControl = $cacheControlValue; ContentType = $contentType} -Metadata $metadata + if ($null -eq $newBlob) { + Log-Failure " Failed to upload $($blobPrefix + $name)" + } + } + + # Stop publishing if any errors have been logged + if ($global:hasErrors -eq $true) { + exit 5 + } + } +} + +Function ParseCdnStorePath +{ + if ([string]::IsNullOrWhiteSpace($cdnStorePath) -eq $true) { + Log-Failure "Invalid Store Path ($cdnStorePath)" + exit 10 + } + + $global:storeName = $cdnStorePath + $splitOptions = [System.StringSplitOptions]::RemoveEmptyEntries + $parts = $cdnStorePath.split(":", $splitOptions) + if ($parts.Length -eq 3) { + $global:subscriptionId = $parts[0] + $global:resourceGroup = $parts[1] + $global:storeName = $parts[2] + } elseif ($parts.Length -eq 2) { + $global:subscriptionId = $parts[0] + $global:storeName = $parts[1] + } elseif ($parts.Length -ne 1) { + Log-Failure "Invalid Store Path ($cdnStorePath)" + exit 11 + } + + if ([string]::IsNullOrWhiteSpace($global:storeName) -eq $true) { + Log-Failure "Missing Storage name from Path ($cdnStorePath)" + exit 12 + } + + Log "----------------------------------------------------------------------" + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true) { + Log "Subscription: $global:subscriptionId" + } + + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + Log "Group : $global:resourceGroup" + } + + Log "StoreName : $global:storeName" + Log "----------------------------------------------------------------------" +} + +Function ValidateAccess +{ + CheckLogin | Out-Null + + $store = $null + $subs = $null + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true -and (IsGuid($global:subscriptionId) -eq $true)) { + Select-AzureRmSubscription -SubscriptionId $global:subscriptionId | Out-Null + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true -and [string]::IsNullOrWhiteSpace($global:storeName) -ne $true) { + Log " Getting Storage Account" + $accounts = Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -AccountName $global:storeName + if ($null -ne $accounts -and $accounts.Length -eq 1) { + $store = $accounts[0] + } + } + + if ($null -eq $store) { + Log " Selecting Subscription" + $subs = Get-AzureRmSubscription -SubscriptionId $global:subscriptionId | Where-Object State -eq "Enabled" + } + } else { + Log " Finding Subscriptions" + $subs = Get-AzureRmSubscription | Where-Object State -eq "Enabled" + } + + if ($null -eq $store -and $null -ne $subs) { + if ($null -eq $subs -or $subs.Length -eq 0) { + Log-Failure " - No Active Subscriptions" + exit 500; + } + + # Limit to the defined subscription + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true) { + $subs = $subs | Where-Object Id -like $("*$global:subscriptionId*") + } + + Log " Finding Storage Account" + $accounts = $null + foreach ($id in $subs) { + Log " Checking Subscription $($id.Id)" + Select-AzureRmSubscription -SubscriptionId $id.Id | Out-Null + $accounts = $null + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + if ([string]::IsNullOrWhiteSpace($global:storeName) -eq $true) { + $accounts = Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -AccountName $global:storeName + } else { + $accounts = Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup + } + } else { + $accounts = Get-AzureRmStorageAccount + } + + if ($null -ne $accounts -and $accounts.Length -ge 1) { + # If a resource group has been supplied limit to just that group + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + $accounts = $accounts | Where-Object ResourceGroupName -eq $global:resourceGroup + } + + $accounts = $accounts | Where-Object StorageAccountName -eq $global:storeName + + if ($accounts.Length -gt 1) { + Log-Failure " - Too many [$($accounts.Length)] matching storage accounts located for $($cdnStorePath) please specify the resource group as a prefix for the store name parameter '[:[:]]" + exit 300; + } elseif ($accounts.Length -eq 1 -and $null -eq $store) { + Log " - Found Candidate Subscription $($id.Id)" + $global:subscriptionId = $id.Id + $store = $accounts[0] + } elseif ($accounts.Length -ne 0 -or $null -ne $store) { + Log-Failure " - More than 1 storage account was located for $($cdnStorePath) please specify the resource group as a prefix for the store name parameter '[:[:]]" + exit 300; + } else { + Log " - No Matching Accounts" + } + } else { + Log " - No Storage Accounts" + } + } + } + + if ($null -eq $store) { + Log-Failure " Unable to access or locate a storage account $cdnStorePath" + exit 300; + } + + $global:storeName = $store.StorageAccountName + $global:resourceGroup = $store.ResourceGroupName + + Log "Getting StorageContext for" + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true) { + Log " Subscription: $global:subscriptionId" + } + + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + Log " Group : $global:resourceGroup" + } + + Log " StoreName : $global:storeName" + $global:storageContext = $store.context + if ($null -eq $global:storageContext) { + Log-Failure " - Unable to access or locate a storage account $cdnStorePath" + exit 301; + } +} + +#----------------------------------------------------------------------------- +# Start of Script +#----------------------------------------------------------------------------- +$logDir = $logPath +if ([string]::IsNullOrWhiteSpace($logPath) -eq $true) { + $logDir = join-path ${env:SystemDrive} "\Logs" +} + +if (!(Test-Path -Path $logDir)) { + New-Item -ItemType directory -Path $logDir +} + +$jsSdkDir = $releaseFrom +if ([string]::IsNullOrWhiteSpace($jsSdkDir) -eq $true) { + $jsSdkDir = Split-Path (Split-Path $MyInvocation.MyCommand.Path) -Parent +} + +$fileTimeStamp = ((get-date).ToUniversalTime()).ToString("yyyyMMddThhmmss") +$logFile = "$logDir\publishReleaseCdnLog_$fileTimeStamp.txt" + +$cacheControl1Year = "public, max-age=31536000, immutable"; +$contentType = "text/javascript; charset=utf-8"; + +Log-Params + +# You will need to at least have the AzureRM module installed +InstallRequiredModules +ParseCdnStorePath + +if ([string]::IsNullOrWhiteSpace($global:sasToken) -eq $true) { + Log "**********************************************************************" + Log "Validating user access" + Log "**********************************************************************" + ValidateAccess +} + +Log "======================================================================" +$releaseFiles = GetReleaseFiles $false # Get the versioned files only +if ($null -eq $releaseFiles -or $releaseFiles.Count -eq 0) { + Log-Failure "Unable to find any release files" +} + +Log "Release Files : $($releaseFiles.Count)" + +Log "----------------------------------------------------------------------" +# Publish the full versioned files to all release folders +PublishFiles $releaseFiles "beta/ext" $cacheControl1Year $overwrite +PublishFiles $releaseFiles "next/ext" $cacheControl1Year $overwrite +PublishFiles $releaseFiles "scripts/b/ext" $cacheControl1Year $overwrite +Log "======================================================================" diff --git a/extensions/applicationinsights-clickanalytics-js/scripts/setActiveCdnVersion.ps1 b/extensions/applicationinsights-clickanalytics-js/scripts/setActiveCdnVersion.ps1 new file mode 100644 index 000000000..97bbed068 --- /dev/null +++ b/extensions/applicationinsights-clickanalytics-js/scripts/setActiveCdnVersion.ps1 @@ -0,0 +1,731 @@ +[CmdletBinding()] +param ( + [string] $container = "", # The container to update + [string] $activeVersion = "", # The version to copy as the active version + [string] $storeContainer = "cdn", # Identifies the destination storage account container + [string] $cdnStorePath = "cdnstoragename", # Identifies the target Azure Storage account (by name) + [string] $subscriptionId = $null, # Identifies the target Azure Subscription Id (if not encoded in the cdnStorePath) + [string] $resourceGroup = $null, # Identifies the target Azure Subscription Resource Group (if not encoded in the cdnStorePath) + [string] $sasToken = $null, # The SAS Token to use rather than using or attempting to login + [string] $logPath = $null, # The location where logs should be written + [switch] $minorOnly = $false, # Only set the active minor version (v2.x) and not the major version (v2) + [switch] $testOnly = $false, # Uploads to a "tst" test container on the storage account + [switch] $cdn = $false # (No longer used -- kept for now for backward compatibility) +) + +$metaSdkVer = "aijssdkver" +$metaSdkSrc = "aijssdksrc" + +$global:hasErrors = $false +$global:sasToken = $sasToken +$global:resourceGroup = $resourceGroup +$global:storeName = $null # The endpoint needs to the base name of the endpoint, not the full URL (eg. “my-cdn” rather than “my-cdn.azureedge.net”) +$global:subscriptionId = $subscriptionId +$global:storageContext = $null + +Function Log-Params +{ + Log "Container : $container" + Log "Version : $activeVersion" + Log "Storage Container : $storeContainer" + Log "Store Path : $cdnStorePath" + Log "Test Mode : $testOnly" + Log "Log Path : $logDir" + + if ([string]::IsNullOrWhiteSpace($global:sasToken) -eq $true) { + Log "Mode : User-Credentials" + } else { + Log "Mode : Sas-Token" + } +} + +## Function: Get-TimeStamp +## Purpose: Used to get the timestamp for logging +Function Get-TimeStamp +{ + return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date) +} + +Function Write-LogDetail( + [string] $value +) { + Add-Content $logFile "$(Get-TimeStamp) $value" +} + +## Function: Log +## Purpose: Used to log the output to both the Console and a log file +Function Log( + [string] $value +) { + Write-Host "$(Get-TimeStamp) $value" + Write-LogDetail $value +} + +## Function: Log-Warning +## Purpose: Used to log the output to both the Console and a log file +Function Log-Warning ( + [string] $value +) { + Write-Host "$(Get-TimeStamp) [WRN] $value" -ForegroundColor Yellow -BackgroundColor DarkBlue + Write-LogDetail "[WRN] $value" +} + +## Function: Log-Warning +## Purpose: Used to log the output to both the Console and a log file +Function Log-Failure ( + [string] $value, + [boolean] $isTerminal = $true +) { + if ($isTerminal -eq $true) { + Write-Host "$(Get-TimeStamp) [ERR] $value" -ForegroundColor Yellow -BackgroundColor DarkRed + Write-LogDetail "[ERR] $value" + $global:hasErrors = $true + } else { + Write-Host "$(Get-TimeStamp) [INF] $value" -ForegroundColor Red + Write-LogDetail "[INF] $value" + } +} + +Function Log-Exception( + [System.Management.Automation.ErrorRecord] $err, + [boolean] $asError = $true, + [string] $prefix = "" +) { + Log-Failure "$($prefix)Exception: $($err.Exception.Message)" $asError + Log-Failure "$($prefix)Source : $($err.Exception.Source)" $asError + Write-LogDetail "$($prefix)Full Exception: $($err.Exception)" + Log-Failure "$($prefix)$($err.ScriptStackTrace)" $asError +} + +Function Log-Errors( + [boolean] $asError = $true, + [string] $prefix = "" +) { + foreach ($err in $Error) { + Log-Exception $err $asError + foreach ($innerEx in $err.InnerExceptions) { + Log-Exception $innerEx $asError "$prefix " + } + } +} + +## Function: InstallRequiredModules +## Purpose: Checks and attempts to install the required AzureRM Modules +Function InstallRequiredModules ( + [int32] $retry = 1 +) { + if ($retry -le 0) { + Log-Warning "--------------------------------------" + Log-Warning "Failed to install the required Modules" + Log-Warning "--------------------------------------" + Log "" + Log "Please install / run the following from an administrator powershell window" + Log "Install-Module AzureRM" + Log "Install-Module Az.Storage" + Log "" + Log "Additional Notes for Internal Application Insights Team" + Log "Please review the 'Release to CDN Failures' Page on the teams documentation for further assistance" + + exit + } + + $commandsExist = $true + $c = Get-Command Login-AzureRMAccount -errorAction SilentlyContinue + if ($null -eq $c) { + $commandsExist = $false + } else { + Log "Importing Module $($c.Source) for Login-AzureRMAccount" + Import-Module $c.Source + $c = Get-Command Get-AzureRmStorageAccount -errorAction SilentlyContinue + if ($null -eq $c) { + $commandsExist = $false + } else { + Log "Importing Module $($c.Source) for Get-AzureRmStorageAccount" + Import-Module $c.Source + } + } + + if ($commandsExist -eq $false) { + # You will need to at least have the AzureRM module installed + $m = Get-Module -ListAvailable -Name "AzureRM" + if ($null -eq $m) { + Log "The AzureRM module is not currently installed -- it needs to be" + Log "Attempting to Install AzureRM Module" + + InstallRequiredModules $($retry-1) + } + } +} + +Function IsGuid( + [string] $value +) { + $guid = New-Object 'System.Guid' + return [System.Guid]::TryParse($value, [ref]$guid) +} + +Function CheckLogin +{ + $loggedIn = $false + $attempt = 0 + + Log "Checking Logged in status." + while ($loggedIn -eq $false) { + $Error.Clear() + + if ($attempt -ge 5) { + Log-Failure "Unable to login..." + exit 100; + } + + $loggedIn = $true + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + if ([string]::IsNullOrWhiteSpace($global:storeName) -eq $true) { + Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -AccountName $global:storeName -ErrorAction SilentlyContinue | Out-Null + } else { + Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -ErrorAction SilentlyContinue | Out-Null + } + } else { + Get-AzureRmStorageAccount -ErrorAction SilentlyContinue | Out-Null + } + + Log-Errors $false + + #Get-AzureRmSubscription -SubscriptionId $subscriptionId -ErrorAction SilentlyContinue + foreach ($eacherror in $Error) { + if ($eacherror.Exception.ToString() -like "* Login-AzureRmAccount*") { + $loggedIn = $false + + Log "Logging in... Atempt #$($attempt + 1)" + $Error.Clear() + Login-AzureRMAccount -ErrorAction SilentlyContinue + Log-Errors $false + break + } elseif ($eacherror.Exception.ToString() -like "* Connect-AzureRmAccount*") { + $loggedIn = $false + + Log "Connecting... Atempt #$($attempt + 1)" + $Error.Clear() + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true -and (IsGuid($global:subscriptionId) -eq $true)) { + Connect-AzureRmAccount -ErrorAction SilentlyContinue -Subscription $global:subscriptionId | Out-Null + } else { + Connect-AzureRmAccount -ErrorAction SilentlyContinue | Out-Null + } + + Log-Errors $false + break + } else { + $loggedIn = $false + Log-Warning "Unexpected failure $($eacherror.Exception)" + } + } + + $attempt ++ + } + + $Error.Clear() +} + +Function ParseCdnStorePath +{ + if ([string]::IsNullOrWhiteSpace($cdnStorePath) -eq $true) { + Log-Failure "Invalid Store Path ($cdnStorePath)" + exit 10 + } + + $global:storeName = $cdnStorePath + $splitOptions = [System.StringSplitOptions]::RemoveEmptyEntries + $parts = $cdnStorePath.split(":", $splitOptions) + if ($parts.Length -eq 3) { + $global:subscriptionId = $parts[0] + $global:resourceGroup = $parts[1] + $global:storeName = $parts[2] + } elseif ($parts.Length -eq 2) { + $global:subscriptionId = $parts[0] + $global:storeName = $parts[1] + } elseif ($parts.Length -ne 1) { + Log-Failure "Invalid Store Path ($cdnStorePath)" + exit 11 + } + + if ([string]::IsNullOrWhiteSpace($global:storeName) -eq $true) { + Log-Failure "Missing Storage name from Path ($cdnStorePath)" + exit 12 + } + + Log "----------------------------------------------------------------------" + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true) { + Log "Subscription: $global:subscriptionId" + } + + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + Log "Group : $global:resourceGroup" + } + + Log "StoreName : $global:storeName" + Log "----------------------------------------------------------------------" +} + +Function ValidateAccess +{ + CheckLogin | Out-Null + + $store = $null + $subs = $null + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true -and (IsGuid($global:subscriptionId) -eq $true)) { + Select-AzureRmSubscription -SubscriptionId $global:subscriptionId | Out-Null + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true -and [string]::IsNullOrWhiteSpace($global:storeName) -ne $true) { + Log " Getting Storage Account" + $accounts = Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -AccountName $global:storeName + if ($null -ne $accounts -and $accounts.Length -eq 1) { + $store = $accounts[0] + } + } + + if ($null -eq $store) { + Log " Selecting Subscription" + $subs = Get-AzureRmSubscription -SubscriptionId $global:subscriptionId | Where-Object State -eq "Enabled" + } + } else { + Log " Finding Subscriptions" + $subs = Get-AzureRmSubscription | Where-Object State -eq "Enabled" + } + + if ($null -eq $store -and $null -ne $subs) { + if ($null -eq $subs -or $subs.Length -eq 0) { + Log-Failure " - No Active Subscriptions" + exit 500; + } + + # Limit to the defined subscription + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true) { + $subs = $subs | Where-Object Id -like $("*$global:subscriptionId*") + } + + Log " Finding Storage Account" + $accounts = $null + foreach ($id in $subs) { + Log " Checking Subscription $($id.Id)" + Select-AzureRmSubscription -SubscriptionId $id.Id | Out-Null + $accounts = $null + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + if ([string]::IsNullOrWhiteSpace($global:storeName) -eq $true) { + $accounts = Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup -AccountName $global:storeName + } else { + $accounts = Get-AzureRmStorageAccount -ResourceGroupName $global:resourceGroup + } + } else { + $accounts = Get-AzureRmStorageAccount + } + + if ($null -ne $accounts -and $accounts.Length -ge 1) { + # If a resource group has been supplied limit to just that group + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + $accounts = $accounts | Where-Object ResourceGroupName -eq $global:resourceGroup + } + + $accounts = $accounts | Where-Object StorageAccountName -eq $global:storeName + + if ($accounts.Length -gt 1) { + Log-Failure " - Too many [$($accounts.Length)] matching storage accounts located for $($cdnStorePath) please specify the resource group as a prefix for the store name parameter '[:[:]]" + exit 300; + } elseif ($accounts.Length -eq 1 -and $null -eq $store) { + Log " - Found Candidate Subscription $($id.Id)" + $global:subscriptionId = $id.Id + $store = $accounts[0] + } elseif ($accounts.Length -ne 0 -or $null -ne $store) { + Log-Failure " - More than 1 storage account was located for $($cdnStorePath) please specify the resource group as a prefix for the store name parameter '[:[:]]" + exit 300; + } else { + Log " - No Matching Accounts" + } + } else { + Log " - No Storage Accounts" + } + } + } + + if ($null -eq $store) { + Log-Failure " Unable to access or locate a storage account $cdnStorePath" + exit 300; + } + + $global:storeName = $store.StorageAccountName + $global:resourceGroup = $store.ResourceGroupName + + Log "Getting StorageContext for" + if ([string]::IsNullOrWhiteSpace($global:subscriptionId) -ne $true) { + Log " Subscription: $global:subscriptionId" + } + + if ([string]::IsNullOrWhiteSpace($global:resourceGroup) -ne $true) { + Log " Group : $global:resourceGroup" + } + + Log " StoreName : $global:storeName" + $global:storageContext = $store.context + if ($null -eq $global:storageContext) { + Log-Failure " - Unable to access or locate a storage account $cdnStorePath" + exit 301; + } +} + +Function GetVersion( + [string] $name +) { + $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+\.\d+\.\d+(-[^\.]+)?)(\.(?:js|min\.js)(?:\.map)?)$' + $match = ($name | select-string $regMatch -AllMatches).matches + + if ($null -eq $match) { + return $null + } + + [hashtable]$return = @{} + $return.path = $match.groups[1].value + $return.prefix = $match.groups[2].value + $return.ver = $match.groups[3].value + $return.verType = $match.groups[4].value + $return.ext = $match.groups[5].value + + return $return +} + +Function GetContainerContext( + [string] $storagePath +) { + # Don't try and publish anything if any errors have been logged + if ($global:hasErrors -eq $true) { + exit 2 + } + + while($storagePath.endsWith("/") -eq $true) { + $storagePath = $storagePath.Substring(0, $storagePath.Length-1) + } + + $blobPrefix = "" + $storageContainer = "" + + $tokens = $storagePath.split("/", 2) + if ($tokens.length -eq 0) { + Log-Warning "Invalid storage path - $storagePath" + exit + } + + $storageContainer = $tokens[0] + if ($tokens.Length -eq 2) { + $blobPrefix = $tokens[1] + "/" + } + + if ($testOnly -eq $true) { + $blobPrefix = $storageContainer + "/" + $blobPrefix + $storageContainer = "tst" + } + + if ($storeContainer.Length -gt 0) { + $blobPrefix = $storageContainer + "/" + $blobPrefix + $storageContainer = $storeContainer + } + + Log "Container : $storageContainer Prefix: $blobPrefix" + + # Use the Users Storage Context credentials + $azureContext = $global:storageContext + if ([string]::IsNullOrWhiteSpace($global:sasToken) -ne $true) { + # Use the Sas token + $azureContext = New-AzureStorageContext -StorageAccountName $global:storeName -Sastoken $global:sasToken -ErrorAction SilentlyContinue + } + + $container = Get-AzureStorageContainer -Name $storageContainer -Context $azureContext -ErrorAction SilentlyContinue + Log-Errors + + if ($global:hasErrors -eq $true) { + exit 3 + } + + if ($null -eq $container) { + Log "Container [$storageContainer] does not exist" + exit 4 + } + + [hashtable]$return = @{} + $return.azureContext = $azureContext + $return.container = $container + $return.storageContainer = $storageContainer + $return.blobPrefix = $blobPrefix + + return $return +} + +Function GetVersionFiles( + [system.collections.generic.dictionary[string, system.collections.generic.list[hashtable]]] $files, + [string] $storagePath, + [string] $filePrefix +) { + $context = GetContainerContext $storagePath + + $blobs = Get-AzureStorageBlob -Container $context.storageContainer -Context $context.azureContext -Prefix "$($context.blobPrefix)$filePrefix$activeVersion" -ErrorAction SilentlyContinue + foreach ($blob in $blobs) { + $parts = $blob.Name.Split("/") + $name = $parts[$parts.Length-1] + $version = GetVersion $name + if ($null -ne $version -and [string]::IsNullOrWhiteSpace($version.ver) -ne $true -and + $version.prefix -eq $filePrefix -and + $version.ver -eq $activeVersion) { + $fileList = $null + if ($files.ContainsKey($version.ver) -ne $true) { + $fileList = New-Object 'system.collections.generic.list[hashtable]' + $files.Add($version.ver, $fileList) + } else { + $fileList = $files[$version.ver] + } + + Log $(" - {0,-40} {1,6:N1} Kb {2:yyyy-MM-dd HH:mm:ss}" -f $($blob.ICloudBlob.Container.Name + "/" + $blob.Name),($blob.Length/1kb),$blob.LastModified) + $theBlob = [hashtable]@{} + $theBlob.blob = $blob + $theBlob.context = $context + $fileList.Add($theBlob) + } + } +} + +Function RemoveMetadata( + $cloudBlob, + [string] $dataKey +) { + # Removing and adding the attribute to avoid duplication of values when the key case is different + $changed = $true + while ($changed -eq $true) { + $changed = $false + foreach ($dstKey in $cloudBlob.Metadata.Keys) { + if ($dstKey -ieq $dataKey) { + $cloudBlob.Metadata.Remove($dstKey) | Out-Null + $changed = $true + break + } + } + } +} + +Function CopyBlob( + $blobContext, + $blob, + $destContext, + $destName +) { + Log-Errors + + # Don't perform any copyies if if any errors have been logged as we want to make sure the attributes have been set + if ($global:hasErrors -eq $true) { + exit 2 + } + + Log " - $($blob.Name) ==> $destName" + + $srcCloudBlob = $blob.ICloudBlob.FetchAttributes() + + $blobResult = Start-AzureStorageBlobCopy -Context $blobContext -CloudBlob $blob.ICloudBlob -DestContext $destContext.azureContext -DestContainer "$($destContext.storageContainer)" -DestBlob $destName -Force + Log-Errors + + # Don't try and publish anything if any errors have been logged + if ($global:hasErrors -eq $true) { + exit 2 + } + + $status = $blobResult | Get-AzureStorageBlobCopyState + while ($status.Status -eq "Pending") { + $status = $blobResult | Get-AzureStorageBlobCopyState + Log $status + Start-Sleep 10 + } + + # Don't try and publish anything if any errors have been logged + if ($global:hasErrors -eq $true) { + exit 2 + } + + # Make sure the metadata and properties are set correctly + # - When destination did not exist then the properties and metadata are set correctly + # - But when overwriting an existing blob the properties and metadata are not updated + $newBlob = Get-AzureStorageBlob -Context $destContext.azureContext -Container "$($destContext.storageContainer)" -Blob $destName + $cloudBlob = $newBlob.ICloudBlob + $cloudBlob.FetchAttributes() + $cloudBlob.Properties.CacheControl = $blob.ICloudBlob.Properties.CacheControl + foreach ($dataKey in $blob.ICloudBlob.Metadata.Keys) { + RemoveMetadata $cloudBlob $dataKey + $cloudBlob.Metadata.Add($dataKey, $blob.ICloudBlob.Metadata[$dataKey]) | Out-Null + } + + $cloudBlob.SetProperties() + $cloudBlob.SetMetadata() +} + +Function SetProperties( + $stagedBlob, + $srcName, + $ver +) { + $cloudBlob = $stagedBlob.ICloudBlob + $cloudBlob.FetchAttributes() + $cloudBlob.Properties.CacheControl = $cacheControl30Min + RemoveMetadata $cloudBlob $metaSdkSrc + $cloudBlob.Metadata.Add($metaSdkSrc, $srcName) | Out-Null + + # Make sure the version metadata is set + if ($cloudBlob.Metadata.ContainsKey($metaSdkVer) -eq $false -or + [string]::IsNullOrWhiteSpace($cloudBlob.Metadata[$metaSdkVer]) -eq $true) { + RemoveMetadata $cloudBlob $metaSdkVer + $cloudBlob.Metadata.Add($metaSdkVer, $ver) | Out-Null + } + $cloudBlob.SetProperties() + $cloudBlob.SetMetadata() + + Log-Errors + # Don't try and publish anything if any errors have been logged + if ($global:hasErrors -eq $true) { + exit 2 + } +} + +Function SetActiveVersion( + [system.collections.generic.list[hashtable]] $fileList, + [string] $storePath +) { + + $destContext = GetContainerContext $storePath + + Log "Storage Path : $storePath" + Log "Container : $($destContext.storageContainer)" + Log "BlobPrefix: $($destContext.blobPrefix)" + + # Stage the version updates + foreach ($theBlob in $fileList) { + $blob = $theBlob.blob + $blobContext = $theBlob.context.azureContext + Log $("Copying: {0,-40} {1,6:N1} Kb {2:yyyy-MM-dd HH:mm:ss}" -f $($blob.ICloudBlob.Container.Name + "/" + $blob.Name),($blob.Length/1kb),$blob.LastModified) + + $version = GetVersion $blob.Name + if ($null -ne $version) { + $verParts = $version.ver.Split(".") + if ($verParts.Length -ne 3) { + Log-Failure "ScriptError: Invalid Version! [$activeVersion]" + } + + # Don't try and publish anything if any errors have been logged + if ($global:hasErrors -eq $true) { + exit 2 + } + + $stageName = "$($version.path)$($version.prefix)$($verParts[0]).$($verParts[1])$($version.ext).stage" + CopyBlob $blobContext $blob $destContext $stageName + + $stagedBlob = Get-AzureStorageBlob -Context $destContext.azureContext -Container $destContext.storageContainer -Blob $stageName + SetProperties $stagedBlob "[$($destContext.storageContainer)]/$($blob.Name)" $version.ver + + $minorName = "$($version.path)$($version.prefix)$($verParts[0]).$($verParts[1])$($version.ext)" + CopyBlob $blobContext $stagedBlob $destContext $minorName + + if ($minorOnly -eq $false) { + $majorName = "$($version.path)$($version.prefix)$($verParts[0])$($version.ext)" + CopyBlob $blobContext $stagedBlob $destContext $majorName + } + + # Remove the staged files + $stagedBlob | Remove-AzureStorageBlob -Force + } + } +} + +Function Validate-Params +{ + # Validate parameters + if ("beta","next","public" -NotContains $container) { + Log-Failure "[$($container)] is not a valid value, must be beta, next or public" + } + + $checkVersion = $activeVersion + $subParts = $checkVersion.split("-") + if ($subParts.Length -gt 2) { + Log-Failure "[$($activeVersion)] is not a valid version number" + } elseif ($subParts.Length -eq 2) { + $checkVersion = $subParts[0] + } + + $versionParts = $checkVersion.Split(".") + if ($versionParts.Length -ne 3) { + Log-Failure "[$($activeVersion)] is not a valid version number" + } + + foreach ($verNum in $versionParts) { + [int]$value = 0 + if ([int32]::TryParse($verNum, [ref]$value) -ne $true) { + Log-Failure "[$($verNum)] is not a valid number within the version[$activeVersion]" + } + } +} + +$Error.Clear() + +#----------------------------------------------------------------------------- +# Start of Script +#----------------------------------------------------------------------------- +$logDir = $logPath +if ([string]::IsNullOrWhiteSpace($logPath) -eq $true) { + $logDir = join-path ${env:SystemDrive} "\Logs" +} + +if (!(Test-Path -Path $logDir)) { + New-Item -ItemType directory -Path $logDir +} + +$fileTimeStamp = ((get-date).ToUniversalTime()).ToString("yyyyMMddThhmmss") +$logFile = "$logDir\setActiveCdnVersionLog_$fileTimeStamp.txt" + +$cacheControl30Min = "public, max-age=1800, immutable"; +$contentType = "text/javascript; charset=utf-8"; + +Log-Params +Validate-Params + +# Don't try and publish anything if any errors have been logged +if ($global:hasErrors -eq $true) { + exit 2 +} + +# You will need to at least have the AzureRM module installed +InstallRequiredModules +ParseCdnStorePath + +if ([string]::IsNullOrWhiteSpace($global:sasToken) -eq $true) { + Log "**********************************************************************" + Log "Validating user access" + Log "**********************************************************************" + ValidateAccess +} + +Log "======================================================================" +# List the files for each container +$files = New-Object 'system.collections.generic.dictionary[string, system.collections.generic.list[hashtable]]' + +$storePath = $container +if ($container -eq "beta" -or $container -eq "next") { + $storePath = "$container/ext" + GetVersionFiles $files $storePath "ai.clck." +} elseif ($container -eq "public") { + $storePath = "scripts/b/ext" + GetVersionFiles $files $storePath "ai.clck." +} + +if ($files.ContainsKey($activeVersion) -ne $true) { + Log-Failure "Version [$activeVersion] does not appear to be deployed to [$container]" +} elseif ($files[$activeVersion].Count -ne 4) { + Log-Failure "Version [$activeVersion] does not fully deployed to [$container] -- only found [$($files[$activeVersion].Count)] file(s)" +} + +# Don't try and publish anything if any errors have been logged +if ($global:hasErrors -eq $true) { + exit 2 +} + +SetActiveVersion $files[$activeVersion] $storePath + +Log "======================================================================" From cf2429181661fe367cebdc0098f4115ee4d3c243 Mon Sep 17 00:00:00 2001 From: kryalama <66494519+kryalama@users.noreply.github.com> Date: Mon, 19 Apr 2021 14:39:30 -0700 Subject: [PATCH 2/2] add .gbl and .cjs files as well --- .../rollup.config.js | 22 ++++++++++++++----- .../scripts/publishReleaseToCdn.ps1 | 10 ++++++++- .../scripts/setActiveCdnVersion.ps1 | 2 +- .../rollup.config.js | 21 +++++++++++++----- .../scripts/publishReleaseToCdn.ps1 | 2 +- .../scripts/setActiveCdnVersion.ps1 | 2 +- 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/extensions/applicationinsights-clickanalytics-js/rollup.config.js b/extensions/applicationinsights-clickanalytics-js/rollup.config.js index bd7db25d5..8cc5143c1 100644 --- a/extensions/applicationinsights-clickanalytics-js/rollup.config.js +++ b/extensions/applicationinsights-clickanalytics-js/rollup.config.js @@ -12,6 +12,8 @@ const verParts = version.split(".") if (verParts.length != 3) { throw "Invalid Version! [" + version + "]" } +const majorVersion = verParts[0] + const banner = [ "/*!", ` * Application Insights JavaScript SDK - Click Analytics, ${version}`, @@ -34,13 +36,13 @@ function doCleanup() { }) } -const browserRollupConfigFactory = (isProduction, libVersion) => { +const browserRollupConfigFactory = (isProduction, libVersion, format = 'umd', postfix = '') => { const browserRollupConfig = { input: `dist-esm/${outputName}.js`, output: { - file: `browser/ai.clck.${libVersion}.js`, + file: `browser/ai.clck.${libVersion}${postfix}.js`, banner: banner, - format: "umd", + format: format, name: "Microsoft.ApplicationInsights", extend: true, freeze: false, @@ -65,7 +67,7 @@ const browserRollupConfigFactory = (isProduction, libVersion) => { }; if (isProduction) { - browserRollupConfig.output.file = `browser/ai.clck.${libVersion}.min.js`; + browserRollupConfig.output.file = `browser/ai.clck.${libVersion}${postfix}.min.js`; browserRollupConfig.plugins.push( uglify({ ie8: true, @@ -138,8 +140,16 @@ updateDistEsmFiles(replaceValues, banner); export default [ browserRollupConfigFactory(true, version), browserRollupConfigFactory(false, version), - browserRollupConfigFactory(true, verParts[0]), - browserRollupConfigFactory(false, verParts[0]), + browserRollupConfigFactory(true, majorVersion), + browserRollupConfigFactory(false, majorVersion), + browserRollupConfigFactory(true, majorVersion, 'cjs', '.cjs'), + browserRollupConfigFactory(false, majorVersion, 'cjs', '.cjs'), + browserRollupConfigFactory(true, version, 'cjs', '.cjs'), + browserRollupConfigFactory(false, version, 'cjs', '.cjs'), + browserRollupConfigFactory(true, majorVersion, 'iife', '.gbl'), + browserRollupConfigFactory(false, majorVersion, 'iife', '.gbl'), + browserRollupConfigFactory(true, version, 'iife', '.gbl'), + browserRollupConfigFactory(false, version, 'iife', '.gbl'), nodeUmdRollupConfigFactory(true), nodeUmdRollupConfigFactory(false) ]; diff --git a/extensions/applicationinsights-clickanalytics-js/scripts/publishReleaseToCdn.ps1 b/extensions/applicationinsights-clickanalytics-js/scripts/publishReleaseToCdn.ps1 index 03d882520..b8244d407 100644 --- a/extensions/applicationinsights-clickanalytics-js/scripts/publishReleaseToCdn.ps1 +++ b/extensions/applicationinsights-clickanalytics-js/scripts/publishReleaseToCdn.ps1 @@ -276,6 +276,14 @@ Function GetReleaseFiles AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.js.map" AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.min.js" AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.min.js.map" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.cjs.js" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.cjs.js.map" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.cjs.min.js" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.cjs.min.js.map" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.gbl.js" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.gbl.js.map" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.gbl.min.js" + AddReleaseFile $files $jsSdkSrcDir "ai.clck.$version.gbl.min.js.map" return $files } @@ -283,7 +291,7 @@ Function GetReleaseFiles Function GetVersion( [string] $name ) { - $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+(\.\d+)*(-[^\.]+)?)(\.(?:js|min\.js)(?:\.map)?)$' + $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+\.\d+\.\d+(-[^\.]+)?)(\.(?:gbl\.js|gbl\.min\.js|cjs\.js|cjs\.min\.js|js|min\.js)(?:\.map)?)$' $match = ($name | select-string $regMatch -AllMatches).matches if ($null -eq $match) { diff --git a/extensions/applicationinsights-clickanalytics-js/scripts/setActiveCdnVersion.ps1 b/extensions/applicationinsights-clickanalytics-js/scripts/setActiveCdnVersion.ps1 index 97bbed068..7da2482d5 100644 --- a/extensions/applicationinsights-clickanalytics-js/scripts/setActiveCdnVersion.ps1 +++ b/extensions/applicationinsights-clickanalytics-js/scripts/setActiveCdnVersion.ps1 @@ -373,7 +373,7 @@ Function ValidateAccess Function GetVersion( [string] $name ) { - $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+\.\d+\.\d+(-[^\.]+)?)(\.(?:js|min\.js)(?:\.map)?)$' + $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+\.\d+\.\d+(-[^\.]+)?)(\.(?:gbl\.js|gbl\.min\.js|cjs\.js|cjs\.min\.js|js|min\.js)(?:\.map)?)$' $match = ($name | select-string $regMatch -AllMatches).matches if ($null -eq $match) { diff --git a/extensions/applicationinsights-debugplugin-js/rollup.config.js b/extensions/applicationinsights-debugplugin-js/rollup.config.js index 60b297f56..89528a4a1 100644 --- a/extensions/applicationinsights-debugplugin-js/rollup.config.js +++ b/extensions/applicationinsights-debugplugin-js/rollup.config.js @@ -24,6 +24,7 @@ const verParts = version.split(".") if (verParts.length != 3) { throw "Invalid Version! [" + version + "]" } +const majorVersion = verParts[0] function doCleanup() { return cleanup({ @@ -35,13 +36,13 @@ function doCleanup() { }) } -const browserRollupConfigFactory = (isProduction, libVersion) => { +const browserRollupConfigFactory = (isProduction, libVersion, format = 'umd', postfix = '') => { const browserRollupConfig = { input: `dist-esm/${outputName}.js`, output: { - file: `browser/ai.dbg.${libVersion}.js`, + file: `browser/ai.dbg.${libVersion}${postfix}.js`, banner: banner, - format: "umd", + format: format, name: "Microsoft.ApplicationInsights", extend: true, freeze: false, @@ -66,7 +67,7 @@ const browserRollupConfigFactory = (isProduction, libVersion) => { }; if (isProduction) { - browserRollupConfig.output.file = `browser/ai.dbg.${libVersion}.min.js`; + browserRollupConfig.output.file = `browser/ai.dbg.${libVersion}${postfix}.min.js`; browserRollupConfig.plugins.push( uglify({ ie8: true, @@ -139,8 +140,16 @@ updateDistEsmFiles(replaceValues, banner); export default [ browserRollupConfigFactory(true, version), browserRollupConfigFactory(false, version), - browserRollupConfigFactory(true, verParts[0]), - browserRollupConfigFactory(false, verParts[0]), + browserRollupConfigFactory(true, majorVersion), + browserRollupConfigFactory(false, majorVersion), + browserRollupConfigFactory(true, majorVersion, 'cjs', '.cjs'), + browserRollupConfigFactory(false, majorVersion, 'cjs', '.cjs'), + browserRollupConfigFactory(true, version, 'cjs', '.cjs'), + browserRollupConfigFactory(false, version, 'cjs', '.cjs'), + browserRollupConfigFactory(true, majorVersion, 'iife', '.gbl'), + browserRollupConfigFactory(false, majorVersion, 'iife', '.gbl'), + browserRollupConfigFactory(true, version, 'iife', '.gbl'), + browserRollupConfigFactory(false, version, 'iife', '.gbl'), nodeUmdRollupConfigFactory(true), nodeUmdRollupConfigFactory(false) ]; diff --git a/extensions/applicationinsights-debugplugin-js/scripts/publishReleaseToCdn.ps1 b/extensions/applicationinsights-debugplugin-js/scripts/publishReleaseToCdn.ps1 index 7defb040f..b10b25dae 100644 --- a/extensions/applicationinsights-debugplugin-js/scripts/publishReleaseToCdn.ps1 +++ b/extensions/applicationinsights-debugplugin-js/scripts/publishReleaseToCdn.ps1 @@ -283,7 +283,7 @@ Function GetReleaseFiles Function GetVersion( [string] $name ) { - $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+(\.\d+)*(-[^\.]+)?)(\.(?:js|min\.js)(?:\.map)?)$' + $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+\.\d+\.\d+(-[^\.]+)?)(\.(?:gbl\.js|gbl\.min\.js|cjs\.js|cjs\.min\.js|js|min\.js)(?:\.map)?)$' $match = ($name | select-string $regMatch -AllMatches).matches if ($null -eq $match) { diff --git a/extensions/applicationinsights-debugplugin-js/scripts/setActiveCdnVersion.ps1 b/extensions/applicationinsights-debugplugin-js/scripts/setActiveCdnVersion.ps1 index 9d14843bc..45c00ab2d 100644 --- a/extensions/applicationinsights-debugplugin-js/scripts/setActiveCdnVersion.ps1 +++ b/extensions/applicationinsights-debugplugin-js/scripts/setActiveCdnVersion.ps1 @@ -373,7 +373,7 @@ Function ValidateAccess Function GetVersion( [string] $name ) { - $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+\.\d+\.\d+(-[^\.]+)?)(\.(?:js|min\.js)(?:\.map)?)$' + $regMatch = '^(.*\/)*([^\/\d]*\.)(\d+\.\d+\.\d+(-[^\.]+)?)(\.(?:gbl\.js|gbl\.min\.js|cjs\.js|cjs\.min\.js|js|min\.js)(?:\.map)?)$' $match = ($name | select-string $regMatch -AllMatches).matches if ($null -eq $match) {