diff --git a/step-templates/flyway-database-migrations.json b/step-templates/flyway-database-migrations.json index d0355eee..3ea24f36 100644 --- a/step-templates/flyway-database-migrations.json +++ b/step-templates/flyway-database-migrations.json @@ -3,7 +3,7 @@ "Name": "Flyway Database Migrations", "Description": "Step template to leverage Flyway to deploy migration scripts. This is the latest and greatest Flyway step template that leverages all the newest features of both Flyway and Octopus Deploy.\n\n- You can include the flyway executables in your package, if you include the `flyway` (Linux) or `flyway.cmd` (Windows) in the root of the package this step template will automatically find them.\n- You can use this with an execution container, negating the need to include Flyway in the package. If Flyway isn't found in the package it will attempt to find `/flyway/flyway` (when using Linux containers) or `flyway` in the environment path and use that.\n- Support for all Flyway commands, including the `undo` command.\n- Support for flyway community, teams, enterprise, and pro editions. \n\nPlease note this requires Octopus Deploy **2019.10.0** or newer along with PowerShell Core installed on the machines running this step.\nAWS EC2 IAM Authentication requires the AWS CLI to be installed.", "ActionType": "Octopus.Script", - "Version": 14, + "Version": 15, "Packages": [ { "Name": "Flyway.Package.Value", @@ -21,7 +21,7 @@ "Properties": { "Octopus.Action.Script.ScriptSource": "Inline", "Octopus.Action.Script.Syntax": "PowerShell", - "Octopus.Action.Script.ScriptBody": "$VerboseActionPreference=\"Continue\"\n\nfunction Get-FlywayExecutablePath\n{\n\tparam (\n \t$providedPath\n )\n \n if ([string]::IsNullOrWhiteSpace($providedPath) -eq $false)\n {\n \tWrite-Host \"The executable path was provided, testing to see if it is absolute or relative\"\n\t\tif ([IO.Path]::IsPathRooted($providedPath))\n {\n \tWrite-Host \"The provided path is absolute, using that\"\n \n \treturn $providedPath\n }\n \n Write-Host \"The provided path was relative, combining $(Get-Location) with $providedPath\"\n return Join-Path $(Get-Location) $providedPath\n }\n \n Write-Host \"Checking to see if we are currently running on Linux\"\n if ($IsLinux) \n {\n \tWrite-Host \"Currently running on Linux\"\n \tWrite-Host \"Checking to see if flyway was included with the package\"\n \tif (Test-Path \"./flyway\")\n {\n \tWrite-Host \"It was, using that version of flyway\"\n \treturn \"flyway\"\n }\n \n Write-Host \"Testing to see if we are on an execution container with /flyway/flyway as the path\"\n \tif (Test-Path \"/flyway/flyway\")\n {\n \tWrite-Host \"We are, using /flyway/flyway\"\n \treturn \"/flyway/flyway\"\n } \n }\n \n Write-Host \"Currently running on Windows\"\n \n Write-Host \"Testing to see if flyway.cmd was included with the package\"\n if (Test-Path \".\\flyway.cmd\")\n {\n \tWrite-Host \"It was, using that version.\"\n \treturn \".\\flyway.cmd\"\n }\n \n Write-Host \"Testing to see if flyway can be found in the env path\"\n $flywayExecutable = (Get-Command \"flyway\" -ErrorAction SilentlyContinue)\n if ($null -ne $flywayExecutable)\n {\n \tWrite-Host \"The flyway folder is part of the environment path\"\n return $flywayExecutable.Source\n }\n \n Fail-Step \"Unable to find flyway executable. Please include it as part of the package, or provide the path to it.\"\n}\n\nfunction Test-AddParameterToCommandline\n{\n\tparam (\n \t$acceptedCommands,\n $selectedCommand,\n $parameterValue,\n $defaultValue,\n $parameterName\n )\n \n if ([string]::IsNullOrWhiteSpace($parameterValue) -eq $true)\n { \t\n \tWrite-Verbose \"$parameterName is empty, returning false\"\n \treturn $false\n }\n \n if ([string]::IsNullOrWhiteSpace($defaultValue) -eq $false -and $parameterValue.ToLower().Trim() -eq $defaultValue.ToLower().Trim())\n {\n \tWrite-Verbose \"$parameterName is matches the default value, returning false\"\n \treturn $false\n }\n \n if ([string]::IsNullOrWhiteSpace($acceptedCommands) -eq $true -or $acceptedCommands -eq \"any\")\n {\n \tWrite-Verbose \"$parameterName has a value and this is for any command, returning true\"\n \treturn $true\n }\n \n $acceptedCommandArray = $acceptedCommands -split \",\"\n foreach ($command in $acceptedCommandArray)\n {\n \tif ($command.ToLower().Trim() -eq $selectedCommand.ToLower().Trim())\n {\n \tWrite-Verbose \"$parameterName has a value and the current command $selectedCommand matches the accepted command $command, returning true\"\n \treturn $true\n }\n }\n \n Write-Verbose \"$parameterName has a value but is not accepted in the current command, returning false\"\n return $false\n}\n\nfunction Get-ParsedUrl\n{\n\t# Define parameters\n param (\n \t$ConnectionUrl\n )\n \n # Remove the 'jdbc:' portion from the $ConnectionUrl parameter\n $ConnectionUrl = $ConnectionUrl.ToLower().Replace(\"jdbc:\", \"\")\n \n # Parse and return the url\n return [System.Uri]$ConnectionUrl\n}\n\n# Declaring the path to the NuGet package\n$flywayPackagePath = $OctopusParameters[\"Octopus.Action.Package[Flyway.Package.Value].ExtractedPath\"]\n$flywayUrl = $OctopusParameters[\"Flyway.Target.Url\"]\n$flywayUser = $OctopusParameters[\"Flyway.Database.User\"]\n$flywayUserPassword = $OctopusParameters[\"Flyway.Database.User.Password\"]\n$flywayCommand = $OctopusParameters[\"Flyway.Command.Value\"]\n$flywayLicenseKey = $OctopusParameters[\"Flyway.License.Key\"]\n$flywayExecutablePath = $OctopusParameters[\"Flyway.Executable.Path\"]\n$flywaySchemas = $OctopusParameters[\"Flyway.Command.Schemas\"]\n$flywayTarget = $OctopusParameters[\"Flyway.Command.Target\"]\n$flywayInfoSinceDate = $OctopusParameters[\"Flyway.Command.InfoSinceDate\"]\n$flywayInfoSinceVersion = $OctopusParameters[\"Flyway.Command.InfoSinceVersion\"]\n$flywayLicensedEdition = $OctopusParameters[\"Flyway.License.Version\"]\n$flywayCherryPick = $OctopusParameters[\"Flyway.Command.CherryPick\"]\n$flywayOutOfOrder = $OctopusParameters[\"Flyway.Command.OutOfOrder\"]\n$flywaySkipExecutingMigrations = $OctopusParameters[\"Flyway.Command.SkipExecutingMigrations\"]\n$flywayPlaceHolders = $OctopusParameters[\"Flyway.Command.PlaceHolders\"]\n$flywayBaseLineVersion = $OctopusParameters[\"Flyway.Command.BaselineVersion\"]\n$flywayBaselineDescription = $OctopusParameters[\"Flyway.Command.BaselineDescription\"]\n$flywayAuthenticationMethod = $OctopusParameters[\"Flyway.Authentication.Method\"]\n$flywayLocations = $OctopusParameters[\"Flyway.Command.Locations\"]\n$flywayAdditionalArguments = $OctopusParameters[\"Flyway.Additional.Arguments\"]\n$flywayStepName = $OctopusParameters[\"Octopus.Action.StepName\"]\n$flywayEnvironment = $OctopusParameters[\"Octopus.Environment.Name\"]\n$flywayCheckBuildUrl = $OctopusParameters[\"Flyway.Command.CheckBuildUrl\"]\n$flywayCheckBuildUsername = $OctopusParameters[\"Flyway.Database.Check.User\"]\n$flywayCheckBuildPassword = $OctopusParameters[\"Flyway.Database.Check.User.Password\"]\n$flywayBaselineOnMigrate = $OctopusParameters[\"Flyway.Command.BaseLineOnMigrate\"]\n$flywaySnapshotFileName = $OctopusParameters[\"Flyway.Command.Snapshot.FileName\"]\n$flywayCheckFailOnDrift = $OctopusParameters[\"Flyway.Command.FailOnDrift\"]\n\nif ([string]::IsNullOrWhitespace($flywayLocations))\n{\n\t$flywayLocations = \"filesystem:$flywayPackagePath\"\n}\n\n\n# Logging for troubleshooting\nWrite-Host \"*******************************************\"\nWrite-Host \"Logging variables:\"\nWrite-Host \" - - - - - - - - - - - - - - - - - - - - -\"\nWrite-Host \"PackagePath: $flywayPackagePath\"\nWrite-Host \"Flyway Executable Path: $flywayExecutablePath\"\nWrite-Host \"Flyway Command: $flywayCommand\"\nWrite-Host \"-url: $flywayUrl\"\nWrite-Host \"-user: $flywayUser\"\nWrite-Host \"-schemas: $flywaySchemas\"\nWrite-Host \"-target: $flywayTarget\"\nWrite-Host \"-cherryPick: $flywayCherryPick\"\nWrite-Host \"-outOfOrder: $flywayOutOfOrder\"\nWrite-Host \"-skipExecutingMigrations: $flywaySkipExecutingMigrations\"\nWrite-Host \"-infoSinceDate: $flywayInfoSinceDate\"\nWrite-Host \"-infoSinceVersion: $flywayInfoSinceVersion\"\nWrite-Host \"-baselineOnMigrate: $flywayBaselineOnMigrate\"\nWrite-Host \"-baselineVersion: $flywayBaselineVersion\"\nWrite-Host \"-baselineDescription: $flywayBaselineDescription\"\nWrite-Host \"-locations: $flywayLocations\"\nWrite-Host \"-check.BuildUrl: $flywayCheckBuildUrl\"\nWrite-Host \"-check.failOnDrift: $flywayCheckFailOnDrift\"\nWrite-Host \"-snapshot.FileName OR check.DeployedSnapshot: $flywaySnapshotFileName\"\nWrite-Host \"Additional Arguments: $flywayAdditionalArguments\"\nWrite-Host \"placeHolders: $flywayPlaceHolders\"\nWrite-Host \"*******************************************\"\n\nif ($null -eq $IsWindows) {\n Write-Host \"Determining Operating System...\"\n $IsWindows = ([System.Environment]::OSVersion.Platform -eq \"Win32NT\")\n $IsLinux = ([System.Environment]::OSVersion.Platform -eq \"Unix\")\n}\n\nWrite-Host \"Setting execution location to: $flywayPackagePath\"\nSet-Location $flywayPackagePath\n\n$flywayCmd = Get-FlywayExecutablePath -providedPath $flywayExecutablePath\n\n$commandToUse = $flywayCommand\nif ($flywayCommand -eq \"migrate dry run\")\n{\n\t$commandToUse = \"migrate\"\n}\n\nif ($flywayCommand -eq \"check dry run\" -or $flywayCommand -eq \"check changes\" -or $flywayCommand -eq \"check drift\")\n{\n\t$commandToUse = \"check\"\n}\n\n$arguments = @(\n\t$commandToUse \n)\n\nif ($flywayCommand -eq \"check dry run\")\n{\n\t$arguments += \"-dryrun\"\n}\n\nif ($flywayCommand -eq \"check changes\")\n{\n\t$arguments += \"-changes\"\n $arguments += \"-dryrun\"\n}\n\nif ($flywayCommand -eq \"check drift\")\n{\n\t$arguments += \"-drift\"\n}\n\n# Deteremine authentication method\nswitch ($flywayAuthenticationMethod)\n{\n\t\"awsiam\"\n {\n\t\t# Check to see if OS is Windows and running in a container\n if ($IsWindows -and $env:DOTNET_RUNNING_IN_CONTAINER)\n {\n \tthrow \"IAM Role authentication is not supported in a Windows container.\"\n }\n\n\t\t# Get parsed connection string url\n $parsedUrl = Get-ParsedUrl -ConnectionUrl $flywayUrl\n \n # Region is part of the RDS endpoint, extract\n $region = ($parsedUrl.Host.Split(\".\"))[2]\n\n\t\tWrite-Host \"Generating AWS IAM token ...\"\n\t\t$flywayUserPassword = (aws rds generate-db-auth-token --hostname $parsedUrl.Host --region $region --port $parsedUrl.Port --username $flywayUser)\n\n\t\t$arguments += \"-user=`\"$flywayUser`\"\"\n \t$arguments += \"-password=`\"$flywayUserPassword`\"\"\n\n\t\tbreak\n }\n\t\"azuremanagedidentity\"\n {\n\t\t# Check to see if OS is Windows and running in a container\n if ($IsWindows -and $env:DOTNET_RUNNING_IN_CONTAINER)\n {\n \tthrow \"Azure Managed Identity is not supported in a Windows container.\"\n }\n \n # SQL Server driver doesn't assign password\n if (!$flywayUrl.ToLower().Contains(\"jdbc:sqlserver:\"))\n { \n # Get login token\n Write-Host \"Generating Azure Managed Identity token ...\"\n $token = Invoke-RestMethod -Method GET -Uri \"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://ossrdbms-aad.database.windows.net\" -Headers @{\"MetaData\" = \"true\"} -UseBasicParsing\n\n $flywayUserPassword = $token.access_token\n $arguments += \"-password=`\"$flywayUserPassword`\"\"\n $arguments += \"-user=`\"$flywayUser`\"\"\n }\n else\n {\n \n\t\t\t# Check to see if the querstring parameter for Azure Managed Identity is present\n if (!$flywayUrl.ToLower().Contains(\"authentication=activedirectorymsi\"))\n {\n # Add the authentication piece to the jdbc url\n if (!$flywayUrl.EndsWith(\";\"))\n {\n \t# Add the separator\n $flywayUrl += \";\"\n }\n \n # Add authentication piece\n $flywayUrl += \"Authentication=ActiveDirectoryMSI\"\n }\n }\n \n break\n }\n \"gcpserviceaccount\"\n {\n\t\t# Check to see if OS is Windows and running in a container\n if ($IsWindows -and $env:DOTNET_RUNNING_IN_CONTAINER)\n {\n \tthrow \"GCP Service Account authentication is not supported in a Windows container.\"\n }\n \n # Define header\n $header = @{ \"Metadata-Flavor\" = \"Google\"}\n\n # Retrieve service accounts\n $serviceAccounts = Invoke-RestMethod -Method Get -Uri \"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/\" -Headers $header -UseBasicParsing\n\n # Results returned in plain text format, get into array and remove empty entries\n $serviceAccounts = $serviceAccounts.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries)\n\n # Retreive the specific service account assigned to the VM\n $serviceAccount = $serviceAccounts | Where-Object {$_.ToLower().Contains(\"iam.gserviceaccount.com\") }\n\n\t\tWrite-Host \"Generating GCP IAM token ...\"\n # Retrieve token for account\n $token = Invoke-RestMethod -Method Get -Uri \"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/$serviceAccount/token\" -Headers $header -UseBasicParsing\n \n $flywayUserPassword = $token.access_token\n \n $arguments += \"-user=`\"$flywayUser`\"\"\n $arguments += \"-password=`\"$flywayUserPassword`\"\"\n #$env:FLYWAY_PASSWORD = $flywayUserPassword\n \n break\n } \n \"usernamepassword\"\n {\n \t# Add password\n Write-Host \"Testing for parameters that can be applied to any command\"\n if (Test-AddParameterToCommandline -parameterValue $flywayUser -acceptedCommands \"any\" -selectedCommand $flywayCommand -parameterName \"-user\")\n {\n Write-Host \"User provided, adding user and password command line argument\"\n $arguments += \"-user=`\"$flywayUser`\"\"\n $arguments += \"-password=`\"$flywayUserPassword`\"\"\n }\n \n break\n }\n \"windowsauthentication\"\n {\n \t# Display to the user they've selected windows authentication. Though this is dictated by the jdbc url, this is added to make sure the user knows that's what is\n # being used\n Write-Host \"Using Windows Authentication\"\n \n # Check for integratedauthentication=true in url\n if (!$flywayUrl.ToLower().Contains(\"integratedsecurity=true\"))\n {\n \t# Check to see if the connection url ends with a ;\n if (!$flywayUrl.EndsWith(\";\"))\n {\n \t# Add the ;\n $flywayUrl += \";\"\n }\n \n $flywayUrl += \"integratedSecurity=true;\"\n }\n break\n }\n}\n\n$arguments += \"-url=`\"$flywayUrl`\"\"\n$arguments += \"-locations=`\"$flywayLocations`\"\"\n\nif (Test-AddParameterToCommandline -parameterValue $flywaySchemas -acceptedCommands \"any\" -selectedCommand $flywayCommand -parameterName \"-schemas\")\n{\n\tWrite-Host \"Schemas provided, adding schemas command line argument\"\n\t$arguments += \"-schemas=`\"$flywaySchemas`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayLicenseKey -acceptedCommands \"any\" -selectedCommand $flywayCommand -parameterName \"-licenseKey\")\n{\n\tWrite-Host \"License key provided, adding -licenseKey command line argument\"\n\t$arguments += \"-licenseKey=`\"$flywayLicenseKey`\"\" \n}\nWrite-Host \"Finished testing for parameters that can be applied to any command, moving onto command specific parameters\"\n\nif (Test-AddParameterToCommandline -parameterValue $flywayCherryPick -acceptedCommands \"migrate,info,validate,check\" -selectedCommand $flywayCommand -parameterName \"-cherryPick\")\n{\n\tWrite-Host \"Cherry pick provided, adding cherry pick command line argument\"\n\t$arguments += \"-cherryPick=`\"$flywayCherryPick`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayOutOfOrder -defaultValue \"false\" -acceptedCommands \"migrate,info,validate,check\" -selectedCommand $commandToUse -parameterName \"-outOfOrder\")\n{\n\tWrite-Host \"Out of order is not false, adding out of order command line argument\"\n\t$arguments += \"-outOfOrder=`\"$flywayOutOfOrder`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayPlaceHolders -acceptedCommands \"migrate,info,validate,undo,repair,check\" -selectedCommand $commandToUse -parameterName \"-placeHolders\")\n{\n\tWrite-Host \"Placeholder parameter provided, adding them to the command line arguments\"\n \n $placeHolderValueList = @(($flywayPlaceHolders -Split \"`n\").Trim())\n foreach ($placeHolder in $placeHolderValueList)\n {\n \t$placeHolderSplit = $placeHolder -Split \"::\"\n $placeHolderKey = $placeHolderSplit[0]\n $placeHolderValue = $placeHolderSplit[1]\n Write-Host \"Adding -placeHolders.$placeHolderKey = $placeHolderValue to the argument list\"\n \n $arguments += \"-placeholders.$placeHolderKey=`\"$placeHolderValue`\"\" \n } \t\n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayTarget -acceptedCommands \"migrate,info,validate,undo,check\" -selectedCommand $commandToUse -parameterName \"-target\")\n{\n\tWrite-Host \"Target provided, adding target command line argument\"\n\n\tif ($flywayTarget.ToLower().Trim() -eq \"latest\" -and $flywayCommand -eq \"undo\")\n\t{\n\t\tWrite-Host \"The current target is latest, but the command is undo, changing the target to be current\"\n\t\t$flywayTarget = \"current\"\n\t}\n\n\t$arguments += \"-target=`\"$flywayTarget`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywaySkipExecutingMigrations -defaultValue \"false\" -acceptedCommands \"migrate\" -selectedCommand $flywayCommand -parameterName \"-skipExecutingMigrations\")\n{\n\tWrite-Host \"Skip executing migrations is not false, adding skip executing migrations command line argument\"\n\t$arguments += \"-skipExecutingMigrations=`\"$flywaySkipExecutingMigrations`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayBaselineOnMigrate -defaultValue \"false\" -acceptedCommands \"migrate\" -selectedCommand $flywayCommand -parameterName \"-baselineOnMigrate\")\n{\n\tWrite-Host \"Baseline on migrate is not false, adding the baseline on migrate argument\"\n\t$arguments += \"-baselineOnMigrate=`\"$flywayBaselineOnMigrate`\"\" \n \n if (Test-AddParameterToCommandline -parameterValue $flywayBaselineVersion -acceptedCommands \"migrate\" -selectedCommand $flywayCommand -parameterName \"-baselineVersion\")\n {\n \tWrite-Host \"Baseline version has been specified, adding baseline version argument\"\n\t\t$arguments += \"-baselineVersion=`\"$flywayBaselineVersion`\"\" \n }\n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayBaselineVersion -acceptedCommands \"baseline\" -selectedCommand $flywayCommand -parameterName \"-baselineVersion\")\n{\n\tWrite-Host \"Doing a baseline, adding baseline version and description\"\n\t$arguments += \"-baselineVersion=`\"$flywayBaselineVersion`\"\" \n $arguments += \"-baselineDescription=`\"$flywayBaselineDescription`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayInfoSinceDate -acceptedCommands \"info\" -selectedCommand $flywayCommand -parameterName \"-infoSinceDate\")\n{\n\tWrite-Host \"Info since date has been provided, adding that to the command line arguments\"\n\t$arguments += \"-infoSinceDate=`\"$flywayInfoSinceDate`\"\"\n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayInfoSinceVersion -acceptedCommands \"info\" -selectedCommand $flywayCommand -parameterName \"-infoSinceVersion\")\n{\n\tWrite-Host \"Info since version has been provided, adding that to the command line arguments\"\n\t$arguments += \"-infoSinceVersion=`\"$flywayInfoSinceVersion`\"\"\n} \n\nif (Test-AddParameterToCommandline -parameterValue $flywaySnapshotFileName -acceptedCommands \"snapshot\" -selectedCommand $commandToUse -parameterName \"-snapshot.filename\")\n{\n\tWrite-Host \"Snapshot filename has been provided, adding that to the command line arguments\"\n $folderName = Split-Path -Parent $flywaySnapshotFileName\n if ((test-path $folderName) -eq $false)\n {\n \tNew-Item $folderName -ItemType Directory\n }\n $arguments += \"-snapshot.filename=`\"$flywaySnapshotFileName`\"\"\n}\n\n$snapshotFileNameforCheckProvided = $false\nif (Test-AddParameterToCommandline -parameterValue $flywaySnapshotFileName -acceptedCommands \"check\" -selectedCommand $commandToUse -parameterName \"-check.deployedSnapshot\")\n{\n\tWrite-Host \"Snapshot filename has been provided for the check command, adding that to the command line arguments\"\n $folderName = Split-Path -Parent $flywaySnapshotFileName\n if ((test-path $folderName) -eq $false)\n {\n \tNew-Item $folderName -ItemType Directory\n }\n $arguments += \"-check.deployedSnapshot=`\"$flywaySnapshotFileName`\"\"\n $snapshotFileNameforCheckProvided = $true\n}\n\nif ((Test-AddParameterToCommandline -parameterValue $flywayCheckBuildUrl -acceptedCommands \"check\" -selectedCommand $commandToUse -parameterName \"-check.buildUrl\") -eq $true -and $snapshotFileNameforCheckProvided -eq $false)\n{\n\tWrite-Host \"Check build URL has been provided, adding that to the command line arguments\"\n\t$arguments += \"-check.buildUrl=`\"$flywayCheckBuildUrl`\"\"\n}\n\nWrite-Host \"Checking to see if the check username and password were supplied\"\nif ((Test-AddParameterToCommandline -parameterValue $flywayCheckBuildUsername -acceptedCommands \"check\" -selectedCommand $commandToUse -parameterName \"-user\") -eq $true -and $snapshotFileNameforCheckProvided -eq $false)\n{\n\tWrite-Host \"Check User provided, adding check user and check password command line argument\"\n\t$arguments += \"-check.buildUser=`\"$flywayCheckBuildUsername`\"\"\n\t$arguments += \"-check.buildPassword=`\"$flywayCheckBuildPassword`\"\"\n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayCheckFailOnDrift -acceptedCommands \"check drift\" -selectedCommand $flywayCommand -parameterName \"-check.failOnDrift\")\n{\n\tWrite-Host \"Doing a check drift command, adding the fail on drift\"\n\t$arguments += \"-check.failOnDrift=`\"$flywayCheckFailOnDrift`\"\"\n}\n\n\nWrite-Host \"Finished checking for command specific parameters, moving onto execution\"\n$dryRunOutputFile = \"\"\n\nif ($flywayCommand -eq \"migrate dry run\")\n{\n\t$dryRunOutputFile = Join-Path $(Get-Location) \"dryRunOutput\"\n Write-Host \"Adding the argument dryRunOutput so Flyway will perform a dry run and not an actual migration.\"\n $arguments += \"-dryRunOutput=`\"$dryRunOutputFile`\"\"\n}\n\n# Check to see if there's any additional arguments to add\nif (![string]::IsNullOrWhitespace($flywayAdditionalArguments))\n{\n\t# Split on space\n $flywayAdditionalArgumentsArray = ($flywayAdditionalArguments.Split(\" \", [System.StringSplitOptions]::RemoveEmptyEntries))\n\n # Loop through array\n foreach ($newArgument in $flywayAdditionalArgumentsArray)\n {\n \t# Add the arguments\n \t$arguments += $newArgument\n }\n}\n\n# Display what's going to be run\nif (![string]::IsNullOrWhitespace($flywayUserPassword))\n{\n $flywayDisplayArguments = $arguments.PSObject.Copy()\n $arrayIndex = 0\n for ($i = 0; $i -lt $flywayDisplayArguments.Count; $i++)\n {\n if ($null -ne $flywayDisplayArguments[$i])\n {\n if ($flywayDisplayArguments[$i].Contains($flywayUserPassword))\n {\n $flywayDisplayArguments[$i] = $flywayDisplayArguments[$i].Replace($flywayUserPassword, \"****\")\n }\n }\n }\n\n Write-Host \"Executing the following command: $flywayCmd $flywayDisplayArguments\"\n}\nelse\n{\n Write-Host \"Executing the following command: $flywayCmd $arguments\"\n}\n\n# Attempt to find driver path for java\n$driverPath = (Get-ChildItem -Path (Get-ChildItem -Path $flywayCmd).Directory -Recurse | Where-Object {$_.PSIsContainer -eq $true -and $_.Name -eq \"drivers\"})\n\n# If found, add driver path to the PATH environment varaible\nif ($null -ne $driverPath)\n{\n\t$env:PATH += \"$([IO.Path]::PathSeparator)$($driverPath.FullName)\"\n}\n\n# Adjust call to flyway command based on OS\nif ($IsLinux)\n{\n & bash $flywayCmd $arguments\n}\nelse\n{\n & $flywayCmd $arguments\n}\n\n# Check exit code\nif ($lastExitCode -ne 0)\n{\n\t# Fail the step\n Write-Error \"Execution of Flyway failed!\"\n}\n\n$currentDate = Get-Date\n$currentDateFormatted = $currentDate.ToString(\"yyyyMMdd_HHmmss\")\n\n# Check to see if the dry run variable has a value\nif (![string]::IsNullOrWhitespace($dryRunOutputFile))\n{ \n $sqlDryRunFile = \"$($dryRunOutputFile).sql\"\n $htmlDryRunFile = \"$($dryRunOutputFile).html\"\n \n if (Test-Path $sqlDryRunFile)\n {\n \tNew-OctopusArtifact -Path $sqlDryRunFile -Name \"$($flywayStepName)_$($flywayEnvironment)_$($currentDateFormatted)_dryRunOutput.sql\"\n }\n \n if (Test-Path $htmlDryRunFile)\n {\n \tNew-OctopusArtifact -Path $htmlDryRunFile -Name \"$($flywayStepName)_$($flywayEnvironment)_$($currentDateFormatted)_dryRunOutput.html\"\n }\n}\n\n$reportFile = Join-Path $(Get-Location) \"report.html\"\n \nif (Test-Path $reportFile)\n{\n \tNew-OctopusArtifact -Path $reportFile -Name \"$($flywayStepName)_$($flywayEnvironment)_$($currentDateFormatted)_report.html\"\n}", + "Octopus.Action.Script.ScriptBody": "$VerboseActionPreference=\"Continue\"\n\nfunction Get-FlywayExecutablePath\n{\n\tparam (\n \t$providedPath\n )\n \n if ([string]::IsNullOrWhiteSpace($providedPath) -eq $false)\n {\n \tWrite-Host \"The executable path was provided, testing to see if it is absolute or relative\"\n\t\tif ([IO.Path]::IsPathRooted($providedPath))\n {\n \tWrite-Host \"The provided path is absolute, using that\"\n \n \treturn $providedPath\n }\n \n Write-Host \"The provided path was relative, combining $(Get-Location) with $providedPath\"\n return Join-Path $(Get-Location) $providedPath\n }\n \n Write-Host \"Checking to see if we are currently running on Linux\"\n if ($IsLinux) \n {\n \tWrite-Host \"Currently running on Linux\"\n \tWrite-Host \"Checking to see if flyway was included with the package\"\n \tif (Test-Path \"./flyway\")\n {\n \tWrite-Host \"It was, using that version of flyway\"\n \treturn \"flyway\"\n }\n \n Write-Host \"Testing to see if we are on an execution container with /flyway/flyway as the path\"\n \tif (Test-Path \"/flyway/flyway\")\n {\n \tWrite-Host \"We are, using /flyway/flyway\"\n \treturn \"/flyway/flyway\"\n } \n }\n \n Write-Host \"Currently running on Windows\"\n \n Write-Host \"Testing to see if flyway.cmd was included with the package\"\n if (Test-Path \".\\flyway.cmd\")\n {\n \tWrite-Host \"It was, using that version.\"\n \treturn \".\\flyway.cmd\"\n }\n \n Write-Host \"Testing to see if flyway can be found in the env path\"\n $flywayExecutable = (Get-Command \"flyway\" -ErrorAction SilentlyContinue)\n if ($null -ne $flywayExecutable)\n {\n \tWrite-Host \"The flyway folder is part of the environment path\"\n return $flywayExecutable.Source\n }\n \n Fail-Step \"Unable to find flyway executable. Please include it as part of the package, or provide the path to it.\"\n}\n\nfunction Test-AddParameterToCommandline\n{\n\tparam (\n \t$acceptedCommands,\n $selectedCommand,\n $parameterValue,\n $defaultValue,\n $parameterName\n )\n \n if ([string]::IsNullOrWhiteSpace($parameterValue) -eq $true)\n { \t\n \tWrite-Verbose \"$parameterName is empty, returning false\"\n \treturn $false\n }\n \n if ([string]::IsNullOrWhiteSpace($defaultValue) -eq $false -and $parameterValue.ToLower().Trim() -eq $defaultValue.ToLower().Trim())\n {\n \tWrite-Verbose \"$parameterName is matches the default value, returning false\"\n \treturn $false\n }\n \n if ([string]::IsNullOrWhiteSpace($acceptedCommands) -eq $true -or $acceptedCommands -eq \"any\")\n {\n \tWrite-Verbose \"$parameterName has a value and this is for any command, returning true\"\n \treturn $true\n }\n \n $acceptedCommandArray = $acceptedCommands -split \",\"\n foreach ($command in $acceptedCommandArray)\n {\n \tif ($command.ToLower().Trim() -eq $selectedCommand.ToLower().Trim())\n {\n \tWrite-Verbose \"$parameterName has a value and the current command $selectedCommand matches the accepted command $command, returning true\"\n \treturn $true\n }\n }\n \n Write-Verbose \"$parameterName has a value but is not accepted in the current command, returning false\"\n return $false\n}\n\nfunction Get-ParsedUrl\n{\n\t# Define parameters\n param (\n \t$ConnectionUrl\n )\n \n # Remove the 'jdbc:' portion from the $ConnectionUrl parameter\n $ConnectionUrl = $ConnectionUrl.ToLower().Replace(\"jdbc:\", \"\")\n \n # Parse and return the url\n return [System.Uri]$ConnectionUrl\n}\n\n# Declaring the path to the NuGet package\n$flywayPackagePath = $OctopusParameters[\"Octopus.Action.Package[Flyway.Package.Value].ExtractedPath\"]\n$flywayUrl = $OctopusParameters[\"Flyway.Target.Url\"]\n$flywayUser = $OctopusParameters[\"Flyway.Database.User\"]\n$flywayUserPassword = $OctopusParameters[\"Flyway.Database.User.Password\"]\n$flywayCommand = $OctopusParameters[\"Flyway.Command.Value\"]\n$flywayLicenseKey = $OctopusParameters[\"Flyway.License.Key\"]\n$flywayLicenseEmail = $OctopusParameters[\"Flyway.Email.Address\"]\n$flywayLicensePAT = $OctopusParameters[\"Flyway.PersonalAccessToken\"]\n$flywayExecutablePath = $OctopusParameters[\"Flyway.Executable.Path\"]\n$flywaySchemas = $OctopusParameters[\"Flyway.Command.Schemas\"]\n$flywayTarget = $OctopusParameters[\"Flyway.Command.Target\"]\n$flywayInfoSinceDate = $OctopusParameters[\"Flyway.Command.InfoSinceDate\"]\n$flywayInfoSinceVersion = $OctopusParameters[\"Flyway.Command.InfoSinceVersion\"]\n$flywayLicensedEdition = $OctopusParameters[\"Flyway.License.Version\"]\n$flywayCherryPick = $OctopusParameters[\"Flyway.Command.CherryPick\"]\n$flywayOutOfOrder = $OctopusParameters[\"Flyway.Command.OutOfOrder\"]\n$flywaySkipExecutingMigrations = $OctopusParameters[\"Flyway.Command.SkipExecutingMigrations\"]\n$flywayPlaceHolders = $OctopusParameters[\"Flyway.Command.PlaceHolders\"]\n$flywayBaseLineVersion = $OctopusParameters[\"Flyway.Command.BaselineVersion\"]\n$flywayBaselineDescription = $OctopusParameters[\"Flyway.Command.BaselineDescription\"]\n$flywayAuthenticationMethod = $OctopusParameters[\"Flyway.Authentication.Method\"]\n$flywayLocations = $OctopusParameters[\"Flyway.Command.Locations\"]\n$flywayAdditionalArguments = $OctopusParameters[\"Flyway.Additional.Arguments\"]\n$flywayStepName = $OctopusParameters[\"Octopus.Action.StepName\"]\n$flywayEnvironment = $OctopusParameters[\"Octopus.Environment.Name\"]\n$flywayCheckBuildUrl = $OctopusParameters[\"Flyway.Command.CheckBuildUrl\"]\n$flywayCheckBuildUsername = $OctopusParameters[\"Flyway.Database.Check.User\"]\n$flywayCheckBuildPassword = $OctopusParameters[\"Flyway.Database.Check.User.Password\"]\n$flywayBaselineOnMigrate = $OctopusParameters[\"Flyway.Command.BaseLineOnMigrate\"]\n$flywaySnapshotFileName = $OctopusParameters[\"Flyway.Command.Snapshot.FileName\"]\n$flywayCheckFailOnDrift = $OctopusParameters[\"Flyway.Command.FailOnDrift\"]\n\nif ([string]::IsNullOrWhitespace($flywayLocations))\n{\n\t$flywayLocations = \"filesystem:$flywayPackagePath\"\n}\n\n\n# Logging for troubleshooting\nWrite-Host \"*******************************************\"\nWrite-Host \"Logging variables:\"\nWrite-Host \" - - - - - - - - - - - - - - - - - - - - -\"\nWrite-Host \"PackagePath: $flywayPackagePath\"\nWrite-Host \"Flyway Executable Path: $flywayExecutablePath\"\nWrite-Host \"Flyway Command: $flywayCommand\"\nWrite-Host \"-url: $flywayUrl\"\nWrite-Host \"-user: $flywayUser\"\nWrite-Host \"-schemas: $flywaySchemas\"\nWrite-Host \"-target: $flywayTarget\"\nWrite-Host \"-cherryPick: $flywayCherryPick\"\nWrite-Host \"-outOfOrder: $flywayOutOfOrder\"\nWrite-Host \"-skipExecutingMigrations: $flywaySkipExecutingMigrations\"\nWrite-Host \"-infoSinceDate: $flywayInfoSinceDate\"\nWrite-Host \"-infoSinceVersion: $flywayInfoSinceVersion\"\nWrite-Host \"-baselineOnMigrate: $flywayBaselineOnMigrate\"\nWrite-Host \"-baselineVersion: $flywayBaselineVersion\"\nWrite-Host \"-baselineDescription: $flywayBaselineDescription\"\nWrite-Host \"-locations: $flywayLocations\"\nWrite-Host \"-check.BuildUrl: $flywayCheckBuildUrl\"\nWrite-Host \"-check.failOnDrift: $flywayCheckFailOnDrift\"\nWrite-Host \"-snapshot.FileName OR check.DeployedSnapshot: $flywaySnapshotFileName\"\nWrite-Host \"Additional Arguments: $flywayAdditionalArguments\"\nWrite-Host \"placeHolders: $flywayPlaceHolders\"\nWrite-Host \"*******************************************\"\n\nif ($null -eq $IsWindows) {\n Write-Host \"Determining Operating System...\"\n $IsWindows = ([System.Environment]::OSVersion.Platform -eq \"Win32NT\")\n $IsLinux = ([System.Environment]::OSVersion.Platform -eq \"Unix\")\n}\n\nWrite-Host \"Setting execution location to: $flywayPackagePath\"\nSet-Location $flywayPackagePath\n\n$flywayCmd = Get-FlywayExecutablePath -providedPath $flywayExecutablePath\n\n$commandToUse = $flywayCommand\nif ($flywayCommand -eq \"migrate dry run\")\n{\n\t$commandToUse = \"migrate\"\n}\n\nif ($flywayCommand -eq \"check dry run\" -or $flywayCommand -eq \"check changes\" -or $flywayCommand -eq \"check drift\")\n{\n\t$commandToUse = \"check\"\n}\n\n$arguments = @(\n\t$commandToUse \n)\n\nif ($flywayCommand -eq \"check dry run\")\n{\n\t$arguments += \"-dryrun\"\n}\n\nif ($flywayCommand -eq \"check changes\")\n{\n\t$arguments += \"-changes\"\n $arguments += \"-dryrun\"\n}\n\nif ($flywayCommand -eq \"check drift\")\n{\n\t$arguments += \"-drift\"\n}\n\n# Deteremine authentication method\nswitch ($flywayAuthenticationMethod)\n{\n\t\"awsiam\"\n {\n\t\t# Check to see if OS is Windows and running in a container\n if ($IsWindows -and $env:DOTNET_RUNNING_IN_CONTAINER)\n {\n \tthrow \"IAM Role authentication is not supported in a Windows container.\"\n }\n\n\t\t# Get parsed connection string url\n $parsedUrl = Get-ParsedUrl -ConnectionUrl $flywayUrl\n \n # Region is part of the RDS endpoint, extract\n $region = ($parsedUrl.Host.Split(\".\"))[2]\n\n\t\tWrite-Host \"Generating AWS IAM token ...\"\n\t\t$flywayUserPassword = (aws rds generate-db-auth-token --hostname $parsedUrl.Host --region $region --port $parsedUrl.Port --username $flywayUser)\n\n\t\t$arguments += \"-user=`\"$flywayUser`\"\"\n \t$arguments += \"-password=`\"$flywayUserPassword`\"\"\n\n\t\tbreak\n }\n\t\"azuremanagedidentity\"\n {\n\t\t# Check to see if OS is Windows and running in a container\n if ($IsWindows -and $env:DOTNET_RUNNING_IN_CONTAINER)\n {\n \tthrow \"Azure Managed Identity is not supported in a Windows container.\"\n }\n \n # SQL Server driver doesn't assign password\n if (!$flywayUrl.ToLower().Contains(\"jdbc:sqlserver:\"))\n { \n # Get login token\n Write-Host \"Generating Azure Managed Identity token ...\"\n $token = Invoke-RestMethod -Method GET -Uri \"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://ossrdbms-aad.database.windows.net\" -Headers @{\"MetaData\" = \"true\"} -UseBasicParsing\n\n $flywayUserPassword = $token.access_token\n $arguments += \"-password=`\"$flywayUserPassword`\"\"\n $arguments += \"-user=`\"$flywayUser`\"\"\n }\n else\n {\n \n\t\t\t# Check to see if the querstring parameter for Azure Managed Identity is present\n if (!$flywayUrl.ToLower().Contains(\"authentication=activedirectorymsi\"))\n {\n # Add the authentication piece to the jdbc url\n if (!$flywayUrl.EndsWith(\";\"))\n {\n \t# Add the separator\n $flywayUrl += \";\"\n }\n \n # Add authentication piece\n $flywayUrl += \"Authentication=ActiveDirectoryMSI\"\n }\n }\n \n break\n }\n \"gcpserviceaccount\"\n {\n\t\t# Check to see if OS is Windows and running in a container\n if ($IsWindows -and $env:DOTNET_RUNNING_IN_CONTAINER)\n {\n \tthrow \"GCP Service Account authentication is not supported in a Windows container.\"\n }\n \n # Define header\n $header = @{ \"Metadata-Flavor\" = \"Google\"}\n\n # Retrieve service accounts\n $serviceAccounts = Invoke-RestMethod -Method Get -Uri \"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/\" -Headers $header -UseBasicParsing\n\n # Results returned in plain text format, get into array and remove empty entries\n $serviceAccounts = $serviceAccounts.Split([Environment]::NewLine, [StringSplitOptions]::RemoveEmptyEntries)\n\n # Retreive the specific service account assigned to the VM\n $serviceAccount = $serviceAccounts | Where-Object {$_.ToLower().Contains(\"iam.gserviceaccount.com\") }\n\n\t\tWrite-Host \"Generating GCP IAM token ...\"\n # Retrieve token for account\n $token = Invoke-RestMethod -Method Get -Uri \"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/$serviceAccount/token\" -Headers $header -UseBasicParsing\n \n $flywayUserPassword = $token.access_token\n \n $arguments += \"-user=`\"$flywayUser`\"\"\n $arguments += \"-password=`\"$flywayUserPassword`\"\"\n #$env:FLYWAY_PASSWORD = $flywayUserPassword\n \n break\n } \n \"usernamepassword\"\n {\n \t# Add password\n Write-Host \"Testing for parameters that can be applied to any command\"\n if (Test-AddParameterToCommandline -parameterValue $flywayUser -acceptedCommands \"any\" -selectedCommand $flywayCommand -parameterName \"-user\")\n {\n Write-Host \"User provided, adding user and password command line argument\"\n $arguments += \"-user=`\"$flywayUser`\"\"\n $arguments += \"-password=`\"$flywayUserPassword`\"\"\n }\n \n break\n }\n \"windowsauthentication\"\n {\n \t# Display to the user they've selected windows authentication. Though this is dictated by the jdbc url, this is added to make sure the user knows that's what is\n # being used\n Write-Host \"Using Windows Authentication\"\n \n # Check for integratedauthentication=true in url\n if (!$flywayUrl.ToLower().Contains(\"integratedsecurity=true\"))\n {\n \t# Check to see if the connection url ends with a ;\n if (!$flywayUrl.EndsWith(\";\"))\n {\n \t# Add the ;\n $flywayUrl += \";\"\n }\n \n $flywayUrl += \"integratedSecurity=true;\"\n }\n break\n }\n}\n\n$arguments += \"-url=`\"$flywayUrl`\"\"\n$arguments += \"-locations=`\"$flywayLocations`\"\"\n\nif (Test-AddParameterToCommandline -parameterValue $flywaySchemas -acceptedCommands \"any\" -selectedCommand $flywayCommand -parameterName \"-schemas\")\n{\n\tWrite-Host \"Schemas provided, adding schemas command line argument\"\n\t$arguments += \"-schemas=`\"$flywaySchemas`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayLicenseKey -acceptedCommands \"any\" -selectedCommand $flywayCommand -parameterName \"-licenseKey\")\n{\n\tWrite-Host \"License key provided, adding -licenseKey command line argument\"\n Write-Host \"*****WARNING***** Use of the License Key has been deprecated by Redgate and will be removed in future versions, use the Personal Access Token method instead.\"\n\t$arguments += \"-licenseKey=`\"$flywayLicenseKey`\"\" \n}\n\nif (![string]::IsNullOrWhiteSpace($flywayLicenseEmail) -and ![string]::IsNullOrWhiteSpace($flywayLicensePAT))\n{\n if (Test-AddParameterToCommandline -parameterValue $flywayLicensePAT -acceptedCommands \"any\" -selectedCommand $flywayCommand -parameterName \"-token\")\n {\n Write-Host \"Personal Access Token provided, adding -email and -token command line arguments\"\n $arguments += @(\"-email=`\"$flywayLicenseEmail`\"\", \"-token=`\"$flywayLicensePAT`\"\")\n }\n}\n\nWrite-Host \"Finished testing for parameters that can be applied to any command, moving onto command specific parameters\"\n\nif (Test-AddParameterToCommandline -parameterValue $flywayCherryPick -acceptedCommands \"migrate,info,validate,check\" -selectedCommand $flywayCommand -parameterName \"-cherryPick\")\n{\n\tWrite-Host \"Cherry pick provided, adding cherry pick command line argument\"\n\t$arguments += \"-cherryPick=`\"$flywayCherryPick`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayOutOfOrder -defaultValue \"false\" -acceptedCommands \"migrate,info,validate,check\" -selectedCommand $commandToUse -parameterName \"-outOfOrder\")\n{\n\tWrite-Host \"Out of order is not false, adding out of order command line argument\"\n\t$arguments += \"-outOfOrder=`\"$flywayOutOfOrder`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayPlaceHolders -acceptedCommands \"migrate,info,validate,undo,repair,check\" -selectedCommand $commandToUse -parameterName \"-placeHolders\")\n{\n\tWrite-Host \"Placeholder parameter provided, adding them to the command line arguments\"\n \n $placeHolderValueList = @(($flywayPlaceHolders -Split \"`n\").Trim())\n foreach ($placeHolder in $placeHolderValueList)\n {\n \t$placeHolderSplit = $placeHolder -Split \"::\"\n $placeHolderKey = $placeHolderSplit[0]\n $placeHolderValue = $placeHolderSplit[1]\n Write-Host \"Adding -placeHolders.$placeHolderKey = $placeHolderValue to the argument list\"\n \n $arguments += \"-placeholders.$placeHolderKey=`\"$placeHolderValue`\"\" \n } \t\n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayTarget -acceptedCommands \"migrate,info,validate,undo,check\" -selectedCommand $commandToUse -parameterName \"-target\")\n{\n\tWrite-Host \"Target provided, adding target command line argument\"\n\n\tif ($flywayTarget.ToLower().Trim() -eq \"latest\" -and $flywayCommand -eq \"undo\")\n\t{\n\t\tWrite-Host \"The current target is latest, but the command is undo, changing the target to be current\"\n\t\t$flywayTarget = \"current\"\n\t}\n\n\t$arguments += \"-target=`\"$flywayTarget`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywaySkipExecutingMigrations -defaultValue \"false\" -acceptedCommands \"migrate\" -selectedCommand $flywayCommand -parameterName \"-skipExecutingMigrations\")\n{\n\tWrite-Host \"Skip executing migrations is not false, adding skip executing migrations command line argument\"\n\t$arguments += \"-skipExecutingMigrations=`\"$flywaySkipExecutingMigrations`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayBaselineOnMigrate -defaultValue \"false\" -acceptedCommands \"migrate\" -selectedCommand $flywayCommand -parameterName \"-baselineOnMigrate\")\n{\n\tWrite-Host \"Baseline on migrate is not false, adding the baseline on migrate argument\"\n\t$arguments += \"-baselineOnMigrate=`\"$flywayBaselineOnMigrate`\"\" \n \n if (Test-AddParameterToCommandline -parameterValue $flywayBaselineVersion -acceptedCommands \"migrate\" -selectedCommand $flywayCommand -parameterName \"-baselineVersion\")\n {\n \tWrite-Host \"Baseline version has been specified, adding baseline version argument\"\n\t\t$arguments += \"-baselineVersion=`\"$flywayBaselineVersion`\"\" \n }\n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayBaselineVersion -acceptedCommands \"baseline\" -selectedCommand $flywayCommand -parameterName \"-baselineVersion\")\n{\n\tWrite-Host \"Doing a baseline, adding baseline version and description\"\n\t$arguments += \"-baselineVersion=`\"$flywayBaselineVersion`\"\" \n $arguments += \"-baselineDescription=`\"$flywayBaselineDescription`\"\" \n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayInfoSinceDate -acceptedCommands \"info\" -selectedCommand $flywayCommand -parameterName \"-infoSinceDate\")\n{\n\tWrite-Host \"Info since date has been provided, adding that to the command line arguments\"\n\t$arguments += \"-infoSinceDate=`\"$flywayInfoSinceDate`\"\"\n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayInfoSinceVersion -acceptedCommands \"info\" -selectedCommand $flywayCommand -parameterName \"-infoSinceVersion\")\n{\n\tWrite-Host \"Info since version has been provided, adding that to the command line arguments\"\n\t$arguments += \"-infoSinceVersion=`\"$flywayInfoSinceVersion`\"\"\n} \n\nif (Test-AddParameterToCommandline -parameterValue $flywaySnapshotFileName -acceptedCommands \"snapshot\" -selectedCommand $commandToUse -parameterName \"-snapshot.filename\")\n{\n\tWrite-Host \"Snapshot filename has been provided, adding that to the command line arguments\"\n $folderName = Split-Path -Parent $flywaySnapshotFileName\n if ((test-path $folderName) -eq $false)\n {\n \tNew-Item $folderName -ItemType Directory\n }\n $arguments += \"-snapshot.filename=`\"$flywaySnapshotFileName`\"\"\n}\n\n$snapshotFileNameforCheckProvided = $false\nif (Test-AddParameterToCommandline -parameterValue $flywaySnapshotFileName -acceptedCommands \"check\" -selectedCommand $commandToUse -parameterName \"-check.deployedSnapshot\")\n{\n\tWrite-Host \"Snapshot filename has been provided for the check command, adding that to the command line arguments\"\n $folderName = Split-Path -Parent $flywaySnapshotFileName\n if ((test-path $folderName) -eq $false)\n {\n \tNew-Item $folderName -ItemType Directory\n }\n $arguments += \"-check.deployedSnapshot=`\"$flywaySnapshotFileName`\"\"\n $snapshotFileNameforCheckProvided = $true\n}\n\nif ((Test-AddParameterToCommandline -parameterValue $flywayCheckBuildUrl -acceptedCommands \"check\" -selectedCommand $commandToUse -parameterName \"-check.buildUrl\") -eq $true -and $snapshotFileNameforCheckProvided -eq $false)\n{\n\tWrite-Host \"Check build URL has been provided, adding that to the command line arguments\"\n\t$arguments += \"-check.buildUrl=`\"$flywayCheckBuildUrl`\"\"\n}\n\nWrite-Host \"Checking to see if the check username and password were supplied\"\nif ((Test-AddParameterToCommandline -parameterValue $flywayCheckBuildUsername -acceptedCommands \"check\" -selectedCommand $commandToUse -parameterName \"-user\") -eq $true -and $snapshotFileNameforCheckProvided -eq $false)\n{\n\tWrite-Host \"Check User provided, adding check user and check password command line argument\"\n\t$arguments += \"-check.buildUser=`\"$flywayCheckBuildUsername`\"\"\n\t$arguments += \"-check.buildPassword=`\"$flywayCheckBuildPassword`\"\"\n}\n\nif (Test-AddParameterToCommandline -parameterValue $flywayCheckFailOnDrift -acceptedCommands \"check drift\" -selectedCommand $flywayCommand -parameterName \"-check.failOnDrift\")\n{\n\tWrite-Host \"Doing a check drift command, adding the fail on drift\"\n\t$arguments += \"-check.failOnDrift=`\"$flywayCheckFailOnDrift`\"\"\n}\n\n\nWrite-Host \"Finished checking for command specific parameters, moving onto execution\"\n$dryRunOutputFile = \"\"\n\nif ($flywayCommand -eq \"migrate dry run\")\n{\n\t$dryRunOutputFile = Join-Path $(Get-Location) \"dryRunOutput\"\n Write-Host \"Adding the argument dryRunOutput so Flyway will perform a dry run and not an actual migration.\"\n $arguments += \"-dryRunOutput=`\"$dryRunOutputFile`\"\"\n}\n\n# Check to see if there's any additional arguments to add\nif (![string]::IsNullOrWhitespace($flywayAdditionalArguments))\n{\n\t# Split on space\n $flywayAdditionalArgumentsArray = ($flywayAdditionalArguments.Split(\" \", [System.StringSplitOptions]::RemoveEmptyEntries))\n\n # Loop through array\n foreach ($newArgument in $flywayAdditionalArgumentsArray)\n {\n \t# Add the arguments\n \t$arguments += $newArgument\n }\n}\n\n# Display what's going to be run\nif (![string]::IsNullOrWhitespace($flywayUserPassword))\n{\n $flywayDisplayArguments = $arguments.PSObject.Copy()\n $arrayIndex = 0\n for ($i = 0; $i -lt $flywayDisplayArguments.Count; $i++)\n {\n if ($null -ne $flywayDisplayArguments[$i])\n {\n if ($flywayDisplayArguments[$i].Contains($flywayUserPassword))\n {\n $flywayDisplayArguments[$i] = $flywayDisplayArguments[$i].Replace($flywayUserPassword, \"****\")\n }\n }\n }\n\n Write-Host \"Executing the following command: $flywayCmd $flywayDisplayArguments\"\n}\nelse\n{\n Write-Host \"Executing the following command: $flywayCmd $arguments\"\n}\n\n# Attempt to find driver path for java\n$driverPath = (Get-ChildItem -Path (Get-ChildItem -Path $flywayCmd).Directory -Recurse | Where-Object {$_.PSIsContainer -eq $true -and $_.Name -eq \"drivers\"})\n\n# If found, add driver path to the PATH environment varaible\nif ($null -ne $driverPath)\n{\n\t$env:PATH += \"$([IO.Path]::PathSeparator)$($driverPath.FullName)\"\n}\n\n# Adjust call to flyway command based on OS\nif ($IsLinux)\n{\n & bash $flywayCmd $arguments\n}\nelse\n{\n & $flywayCmd $arguments\n}\n\n# Check exit code\nif ($lastExitCode -ne 0)\n{\n\t# Fail the step\n Write-Error \"Execution of Flyway failed!\"\n}\n\n$currentDate = Get-Date\n$currentDateFormatted = $currentDate.ToString(\"yyyyMMdd_HHmmss\")\n\n# Check to see if the dry run variable has a value\nif (![string]::IsNullOrWhitespace($dryRunOutputFile))\n{ \n $sqlDryRunFile = \"$($dryRunOutputFile).sql\"\n $htmlDryRunFile = \"$($dryRunOutputFile).html\"\n \n if (Test-Path $sqlDryRunFile)\n {\n \tNew-OctopusArtifact -Path $sqlDryRunFile -Name \"$($flywayStepName)_$($flywayEnvironment)_$($currentDateFormatted)_dryRunOutput.sql\"\n }\n \n if (Test-Path $htmlDryRunFile)\n {\n \tNew-OctopusArtifact -Path $htmlDryRunFile -Name \"$($flywayStepName)_$($flywayEnvironment)_$($currentDateFormatted)_dryRunOutput.html\"\n }\n}\n\n$reportFile = Join-Path $(Get-Location) \"report.html\"\n \nif (Test-Path $reportFile)\n{\n \tNew-OctopusArtifact -Path $reportFile -Name \"$($flywayStepName)_$($flywayEnvironment)_$($currentDateFormatted)_report.html\"\n}", "Octopus.Action.PowerShell.Edition": "Core", "Octopus.Action.EnabledFeatures": "Octopus.Features.SelectPowerShellEditionForWindows" }, @@ -60,13 +60,33 @@ { "Id": "e648821f-221c-4b8b-85fb-654f0d7379c5", "Name": "Flyway.License.Key", - "Label": "License Key", + "Label": "License Key (deprecated)", "HelpText": "**Optional**\n\nThe [Flyway Teams](https://flywaydb.org/download) or `Enterprise` license key will enable undo functionality and the ability to dry run a migration.", "DefaultValue": "", "DisplaySettings": { "Octopus.ControlType": "Sensitive" } }, + { + "Id": "99b59d45-5f58-4d04-b4b1-6ccfeda42136", + "Name": "Flyway.Email.Address", + "Label": "Email address", + "HelpText": "The email address associated with the Personal Access Token (PAT).", + "DefaultValue": "", + "DisplaySettings": { + "Octopus.ControlType": "SingleLineText" + } + }, + { + "Id": "7fb0cb33-950f-47f5-8678-323e62c90770", + "Name": "Flyway.PersonalAccessToken", + "Label": "Personal Access Token (PAT)", + "HelpText": "The Personal Access Token (PAT) to authenticate with for Enterprise features. \n\nReplaces the License Key.", + "DefaultValue": "", + "DisplaySettings": { + "Octopus.ControlType": "Sensitive" + } + }, { "Id": "bb9d99ac-96b4-4d46-ae8f-87e5a7214278", "Name": "Flyway.Target.Url", @@ -294,8 +314,8 @@ } ], "$Meta": { - "ExportedAt": "2024-03-05T19:05:40.264Z", - "OctopusVersion": "2024.1.11865", + "ExportedAt": "2024-10-28T15:04:11.309Z", + "OctopusVersion": "2024.3.12899", "Type": "ActionTemplate" }, "LastModifiedBy": "twerthi",