diff --git a/CloneSpaceProject.ps1 b/CloneSpaceProject.ps1 index e18048f..b632b86 100644 --- a/CloneSpaceProject.ps1 +++ b/CloneSpaceProject.ps1 @@ -130,6 +130,7 @@ $cloneSpaceCommandLineOptions = @{ ChannelsToClone = $null; CertificatesToClone = $CertificatesToClone; ClonePackages = $clonePackages; + ProjectsToClone = $null; } $sourceData = Get-OctopusData -octopusUrl $SourceOctopusUrl -octopusApiKey $SourceOctopusApiKey -spaceName $SourceSpaceName -whatIf $whatIf @@ -380,6 +381,34 @@ function Add-OctopusActionSpaceTeamToCloneList } } +function Add-OctopusActionSubProjectsToCloneList +{ + param ( + $action, + $sourceData, + $cloneSpaceCommandlineOptions + ) + + if ($action.ActionType -ne "Octopus.DeployRelease") + { + return + } + + Write-OctopusVerbose "Adding the sub projects from the deploy a release step to the clone list." + if (Test-OctopusObjectHasProperty -objectToTest $action.Properties -propertyName "Octopus.Action.DeployRelease.ProjectId") + { + $projectToAdd = Get-OctopusItemById -ItemList $sourceData.ProjectList -ItemId $action.Properties.'Octopus.Action.DeployRelease.ProjectId' + if ($null -eq $projectToAdd) + { + Write-OctopusVerbose "Unable to find $($action.Properties.'Octopus.Action.DeployRelease.ProjectId')" + return + } + + Write-OctopusVerbose "Adding $($projectToAdd.Name) to the clone list" + $cloneSpaceCommandLineOptions.ProjectsToClone = Add-OctopusNameToCloneList -ItemName $projectToAdd.Name -destinationList $cloneSpaceCommandLineOptions.ProjectsToClone + } +} + function Add-OctopusDeploymentProcessToCloneList { param ( @@ -401,6 +430,7 @@ function Add-OctopusDeploymentProcessToCloneList Add-OctopusActionStepTemplateToCloneList -action $action -sourceData $sourceData -cloneSpaceCommandLineOptions $cloneSpaceCommandLineOptions Add-OctopusActionEnvironmentsToCloneList -action $action -sourceData $sourceData -cloneSpaceCommandLineOptions $cloneSpaceCommandLineOptions -envrionmentListToExclude $envrionmentListToExclude Add-OctopusActionWorkerPoolIdToCloneList -action $action -sourceData $sourceData -cloneSpaceCommandLineOptions $cloneSpaceCommandLineOptions + Add-OctopusActionSubProjectsToCloneList -action $action -sourceData $sourceData -cloneSpaceCommandlineOptions $cloneSpaceCommandLineOptions } } } @@ -589,10 +619,12 @@ $targetListToExclude = Get-OctopusExclusionList -itemList $sourceData.TargetList $variableSetListToExclude = Get-OctopusExclusionList -itemList $sourceData.VariableSetList -itemType "Library Variable Sets" -filters $LibraryVariableSetsToExclude -includeFilters $LibraryVariableSetsToInclude Write-OctopusSuccess "Building all project list to clone" -$projectListToClone = Get-OctopusFilteredList -itemList $sourceData.ProjectList -itemType "Projects" -filters $ProjectsToClone +$projectListToClone = @(Get-OctopusFilteredList -itemList $sourceData.ProjectList -itemType "Projects" -filters $ProjectsToClone) -foreach ($project in $projectListToClone) +for ($i = 0; $i -lt $projectListToClone.Count; $i++) { + $project = $projectListToClone[$i] + Write-OctopusSuccess "Starting $($project.Name)" Write-OctopusSuccess " Adding variable sets for $($project.Name)" foreach ($variableSetId in $project.IncludedLibraryVariableSetIds) @@ -631,8 +663,23 @@ foreach ($project in $projectListToClone) Write-OctopusSuccess " Getting the deployment process for $($project.Name)" $sourceDeploymentProcess = Get-OctopusProjectDeploymentProcess -project $project -OctopusData $sourceData + $beforeProjectCloneList = $cloneSpaceCommandLineOptions.ProjectsToClone Add-OctopusDeploymentProcessToCloneList -sourceData $sourceData -sourceDeploymentProcess $sourceDeploymentProcess -cloneSpaceCommandLineOptions $cloneSpaceCommandLineOptions -envrionmentListToExclude $envrionmentListToExclude -clonePackages $ClonePackages + if ($beforeProjectCloneList -ne $cloneSpaceCommandLineOptions.ProjectsToClone) + { + Write-OctopusSuccess "The projects to clone list has changed, updating the array to include additional projects" + $newProjectList = Get-OctopusFilteredList -itemList $sourceData.ProjectList -itemType "Projects" -filters $cloneSpaceCommandLineOptions.ProjectsToClone + foreach ($newProject in $newProjectList) + { + $existingProject = $projectListToClone | Where-Object {$_.Id -eq $newProject.Id} + if ($null -eq $existingProject) + { + $projectListToClone += $newProject + } + } + } + if ($sourceData.HasRunbooks -eq $true) { Write-OctopusSuccess " Getting Runbooks for $($Project.Name)" @@ -670,6 +717,7 @@ foreach ($project in $projectListToClone) } Add-OctopusTenantsToCloneList -cloneSpaceCommandLineOptions $cloneSpaceCommandLineOptions -sourceData $sourceData -tenantExclusionList $tenantExclusionList -project $project + $cloneSpaceCommandLineOptions.ProjectsToClone = Add-OctopusNameToCloneList -ItemName $project.Name -destinationList $cloneSpaceCommandLineOptions.ProjectsToClone } Add-OctopusLifeCycleEnvironmentsToCloneList -envrionmentListToExclude $envrionmentListToExclude -sourceData $sourceData -cloneSpaceCommandLineOptions $cloneSpaceCommandLineOptions @@ -684,7 +732,7 @@ Write-OctopusSuccess " -SourceSpaceName $SourceSpaceName" Write-OctopusSuccess " -DestinationOctopusUrl $DestinationOctopusUrl" Write-OctopusSuccess " -DestinationOctopusApiKey *************" Write-OctopusSuccess " -DestinationSpaceName $DestinationSpaceName" -Write-OctopusSuccess " -ProjectsToClone $ProjectsToClone" +Write-OctopusSuccess " -ProjectsToClone $($cloneSpaceCommandLineOptions.ProjectsToClone)" Write-OctopusSuccess " -EnvironmentsToClone $($cloneSpaceCommandLineOptions.EnvironmentsToClone)" Write-OctopusSuccess " -WorkerPoolsToClone $($cloneSpaceCommandLineOptions.WorkerPoolsToClone)" Write-OctopusSuccess " -ProjectGroupsToClone $($cloneSpaceCommandLineOptions.ProjectGroupsToClone)" @@ -742,7 +790,7 @@ $cloneSpaceScript = "$PSScriptRoot\CloneSpace.ps1" -DestinationOctopusUrl "$DestinationOctopusUrl" ` -DestinationOctopusApiKey "$DestinationOctopusApiKey" ` -DestinationSpaceName "$DestinationSpaceName" ` - -ProjectsToClone "$ProjectsToClone" ` + -ProjectsToClone "$($cloneSpaceCommandLineOptions.ProjectsToClone)" ` -EnvironmentsToClone "$($cloneSpaceCommandLineOptions.EnvironmentsToClone)" ` -WorkerPoolsToClone "$($cloneSpaceCommandLineOptions.WorkerPoolsToClone)" ` -ProjectGroupsToClone "$($cloneSpaceCommandLineOptions.ProjectGroupsToClone)" ` diff --git a/src/Cloners/ActionCloner.ps1 b/src/Cloners/ActionCloner.ps1 index 315c628..c0afcb2 100644 --- a/src/Cloners/ActionCloner.ps1 +++ b/src/Cloners/ActionCloner.ps1 @@ -42,7 +42,8 @@ function Copy-OctopusProcessStepAction Convert-OctopusProcessActionFeedId -action $action -sourceData $sourceData -destinationData $destinationData Convert-OctopusPackageList -item $action -sourceData $sourceData -destinationData $destinationData Convert-OctopusSinglePackageProprty -action $action -sourceData $sourceData -destinationData $destinationData - Convert-OctopusActionIdsForMatchingActionId -action $action -matchingAction $matchingAction + Convert-OctopusActionIdsForMatchingActionId -action $action -matchingAction $matchingAction + Convert-OctopusDeployAReleaseStep -action $action -sourceData $sourceData -destinationData $destinationData Write-OctopusPackagesToChangeLog -action $action -destinationData $destinationData @@ -272,7 +273,7 @@ function Convert-OctopusProcessActionFeedId if (Test-OctopusObjectHasProperty -objectToTest $action.Properties -propertyName "Octopus.Action.Package.FeedId") { - $action.Properties.'Octopus.Action.Package.FeedId' = Convert-SourceIdToDestinationId -SourceList $sourceData.FeedList -DestinationList $destinationData.FeedList -IdValue $action.Properties.'Octopus.Action.Package.FeedId' -ItemName "$($action.Name) Feed Id" -MatchingOption "ErrorUnlessExactMatch" + $action.Properties.'Octopus.Action.Package.FeedId' = Convert-SourceIdToDestinationId -SourceList $sourceData.FeedList -DestinationList $destinationData.FeedList -IdValue $action.Properties.'Octopus.Action.Package.FeedId' -ItemName "$($action.Name) Feed Id" -MatchingOption "ErrorUnlessExactMatch" Write-OctopusChangeLogListDetails -idList @($action.Properties.'Octopus.Action.Package.FeedId') -destinationList $DestinationData.FeedList -listType "Package Feed" -prefixSpaces " " $packageId = $action.Properties.'Octopus.Action.Package.PackageId' Write-OctopusChangeLog " - $packageId" @@ -329,6 +330,49 @@ function Convert-OctopusActionIdsForMatchingActionId } } +function Convert-OctopusDeployAReleaseStep +{ + param ( + $action, + $sourceData, + $destinationData + ) + + if ($action.ActionType -ne "Octopus.DeployRelease") + { + return + } + + $projectVariableUsed = $false + foreach ($package in $action.Packages) + { + if ($package.PackageId -like "#{*") + { + $projectVariableUsed = $true + Write-OctopusWarning "The package $($package.PackageId) appears to be a variable. Unable to convert this over. You will need to clean this up on the destination instance." + Write-OctopusPostCloneCleanUp "The step $($action.Name) uses a project variable. Please ensure that project variable is pointed to the right project id." + + continue + } + + $package.PackageId = Convert-SourceIdToDestinationId -SourceList $sourceData.ProjectList -DestinationList $destinationData.ProjectList -IdValue $package.PackageId -ItemName "$($action.Name) Sub Project" -MatchingOption "ErrorUnlessExactMatch" + } + + if ($projectVariableUsed -eq $true) + { + return + } + + if (Test-OctopusObjectHasProperty -objectToTest $action.Properties -propertyName "Octopus.Action.DeployRelease.ProjectId") + { + $action.Properties.'Octopus.Action.DeployRelease.ProjectId' = Convert-SourceIdToDestinationId -SourceList $sourceData.ProjectList -DestinationList $destinationData.ProjectList -IdValue $action.Properties.'Octopus.Action.DeployRelease.ProjectId' -ItemName "$($action.Name) Deploy A Release Project Properties" -MatchingOption "ErrorUnlessExactMatch" + } + else + { + $added = Add-PropertyIfMissing -objectToTest $action.Properties -propertyName "Octopus.Action.DeployRelease.ProjectId" -propertyValue $action.Packages[0].PackageId + } +} + function Write-OctopusPackagesToChangeLog { param ( diff --git a/src/Cloners/LogoCloner.ps1 b/src/Cloners/LogoCloner.ps1 index 4ff67bc..61d0c7f 100644 --- a/src/Cloners/LogoCloner.ps1 +++ b/src/Cloners/LogoCloner.ps1 @@ -5,9 +5,16 @@ function Copy-OctopusItemLogo $destinationItem, $SourceData, $DestinationData, - $CloneScriptOptions + $CloneScriptOptions, + $CloneLogo ) + if ([string]::IsNullOrWhiteSpace($CloneLogo) -or $cloneLogo -eq $false) + { + Write-OctopusVerbose "Cloning logos is set to $CloneLogo. Skipping the logo cloning for $($sourceItem.Name)." + return + } + $queryString = $sourceItem.Links.Logo.SubString($sourceItem.Links.Logo.IndexOf("?") + 4) if ($queryString -ne $sourceData.ApiInformation.Version) { @@ -42,6 +49,6 @@ function Copy-OctopusItemLogo } else { - Write-OctopusVerbose "The item $($item.Name) does not have a logo, skipping logo clone" + Write-OctopusVerbose "The item $($SourceItem.Name) does not have a logo because the links to is set to $($sourceItem.Links.Logo), which matches the API version. An actual logo will have a non-api version value." } } \ No newline at end of file diff --git a/src/Cloners/ProjectCloner.ps1 b/src/Cloners/ProjectCloner.ps1 index 8661928..3a1af77 100644 --- a/src/Cloners/ProjectCloner.ps1 +++ b/src/Cloners/ProjectCloner.ps1 @@ -53,11 +53,8 @@ function Copy-OctopusProjects Copy-OctopusProjectVariables -sourceChannelList $sourceChannels -destinationChannelList $destinationChannels -destinationProject $destinationProject -sourceProject $project -destinationData $DestinationData -sourceData $SourceData -cloneScriptOptions $CloneScriptOptions Copy-OctopusProjectChannelRules -sourceChannelList $sourceChannels -destinationChannelList $destinationChannels -destinationProject $destinationProject -sourceData $SourceData -destinationData $DestinationData -cloneScriptOptions $CloneScriptOptions $destinationProject = Copy-OctopusProjectReleaseVersioningSettings -sourceData $sourceData -sourceProject $project -sourceChannels $sourceChannels -destinationData $destinationData -destinationProject $destinationProject -destinationChannels $destinationChannels -CloneScriptOptions $CloneScriptOptions - - if ($CloneScriptOptions.CloneProjectLogos -eq $true) - { - Copy-OctopusItemLogo -sourceItem $project -destinationItem $destinationProject -sourceData $SourceData -destinationData $DestinationData -CloneScriptOptions $CloneScriptOptions - } + + Copy-OctopusItemLogo -sourceItem $project -destinationItem $destinationProject -sourceData $SourceData -destinationData $DestinationData -CloneScriptOptions $CloneScriptOptions -CloneLogo $CloneScriptOptions.CloneProjectLogos } Write-OctopusPostCloneCleanUpHeader "*****************Ending Clone for all projects***************" diff --git a/src/Cloners/StepTemplateCloner.ps1 b/src/Cloners/StepTemplateCloner.ps1 index 0985cc9..0ea002b 100644 --- a/src/Cloners/StepTemplateCloner.ps1 +++ b/src/Cloners/StepTemplateCloner.ps1 @@ -74,11 +74,8 @@ function Copy-OctopusStepTemplates } $destinationStepTemplate = Save-OctopusStepTemplate -StepTemplate $stepTemplateToClone -DestinationData $destinationData - - if ($cloneScriptOptions.CloneStepTemplateLogos -eq $true) - { - Copy-OctopusItemLogo -sourceItem $stepTemplate -destinationItem $destinationStepTemplate -sourceData $SourceData -destinationData $DestinationData -CloneScriptOptions $CloneScriptOptions - } + + Copy-OctopusItemLogo -sourceItem $stepTemplate -destinationItem $destinationStepTemplate -sourceData $SourceData -destinationData $DestinationData -CloneScriptOptions $CloneScriptOptions -CloneLogo $CloneScriptOptions.CloneStepTemplateLogos $destinationData.StepTemplates = Update-OctopusList -itemList $destinationData.StepTemplates -itemToReplace $destinationStepTemplate } diff --git a/src/Cloners/TenantCloner.ps1 b/src/Cloners/TenantCloner.ps1 index aa6e4ac..9f048cf 100644 --- a/src/Cloners/TenantCloner.ps1 +++ b/src/Cloners/TenantCloner.ps1 @@ -34,11 +34,9 @@ function Copy-OctopusTenants $destinationTenant = Save-OctopusTenant -Tenant $tenantToAdd -destinationData $destinationData $destinationData.TenantList = Update-OctopusList -itemList $destinationData.TenantList -itemToReplace $destinationTenant - - if ($CloneScriptOptions.CloneTenantLogos -eq $true) - { - Copy-OctopusItemLogo -sourceItem $tenant -destinationItem $destinationTenant -sourceData $SourceData -destinationData $DestinationData -CloneScriptOptions $CloneScriptOptions - } + + Copy-OctopusItemLogo -sourceItem $tenant -destinationItem $destinationTenant -sourceData $SourceData -destinationData $DestinationData -CloneScriptOptions $CloneScriptOptions -CloneLogo $CloneScriptOptions.CloneTenantLogos + } elseif ($firstRun -eq $false) { diff --git a/src/Core/Logging.ps1 b/src/Core/Logging.ps1 index e5ec4eb..2e025aa 100644 --- a/src/Core/Logging.ps1 +++ b/src/Core/Logging.ps1 @@ -1,6 +1,6 @@ $currentDate = Get-Date $currentDateFormatted = $currentDate.ToString("yyyy_MM_dd_HH_mm_ss") -$clonerVersion = "3.2.3" +$clonerVersion = "3.2.4" $logFolder = "$PSScriptRoot\..\..\" $logArchiveFolder = "$PSScriptRoot\..\..\logs\archive_$currentDateFormatted"