Git - Clone, copy, push from a Package

Octopus.Script exported 2023-09-12 by twerthi belongs to ‘Git’ category.

Clones a repository, copies files from the Source Package to the Destination Path then commits to the repository.

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Git Repository URL

Template.Git.Repo.Url =

The URL used for the git clone operation.

Git Username

Template.Git.User.Name =

Username of the credentials to use to log into git.

Git User Password

Template.Git.User.Password =

Password for the git credential.

Package

Template.Package.Reference =

Choose the package to copy files from into the Git repository.

Destination Path

Template.Git.Destination.Path =

Relative path to the folder to copy items to. This is the folder name only.

Structured Configuration Variables

Template.VariableReplacement.Paths =

Target files need to be new line seperated, relative to the package contents. Extended wildcard syntax is supported. E.g., appsettings.json, Config*.xml, **\specific-folder*.yaml. Learn more about Structured Configuration Variables and view examples.

Script body

Steps based on this template will execute the following PowerShell script.

Function Invoke-Git
{
	# Define parameters
    param (
    	$GitRepositoryUrl,
        $GitFolder,
        $GitUsername,
        $GitPassword,
        $GitCommand,
        $AdditionalArguments
    )
    
    # Get current work folder
    $workDirectory = Get-Location

	# Check to see if GitFolder exists
    if (![String]::IsNullOrWhitespace($GitFolder) -and (Test-Path -Path $GitFolder) -eq $false)
    {
    	# Create the folder
        New-Item -Path $GitFolder -ItemType "Directory" -Force | Out-Null
        
        # Set the location to the new folder
        Set-Location -Path $GitFolder
    }
    
    # Create arguments array
    $gitArguments = @()
    $gitArguments += $GitCommand
    
    # Check for url
    if (![string]::IsNullOrWhitespace($GitRepositoryUrl))
    {
      # Convert url to URI object
      $gitUri = [System.Uri]$GitRepositoryUrl
      $gitUrl = "{0}://{1}:{2}@{3}:{4}{5}" -f $gitUri.Scheme, $GitUsername, $GitPassword, $gitUri.Host, $gitUri.Port, $gitUri.PathAndQuery
      $gitArguments += $gitUrl

      # Get the newly created folder name
      $gitFolderName = $GitRepositoryUrl.SubString($GitRepositoryUrl.LastIndexOf("/") + 1)
      if ($gitFolderName.Contains(".git"))
      {
          $gitFolderName = $gitFolderName.SubString(0, $gitFolderName.IndexOf("."))
      }
    }
   
    
    # Check for additional arguments
    if ($null -ne $AdditionalArguments)
    {
 		# Add the additional arguments
        $gitArguments += $AdditionalArguments
    }
    
    # Execute git command
    $results = Execute-Command -commandPath "git" -commandArguments $gitArguments -workingDir $GitFolder
    
    Write-Host $results.stdout
    Write-Host $results.stderr
    
    # Return the foldername
    Set-Location -Path $workDirectory
    
    # Check to see if GitFolder is null
    if ($null -ne $GitFolder)
    {
    	return Join-Path -Path $GitFolder -ChildPath $gitFolderName
    }
}

# Check to see if $IsWindows is available
if ($null -eq $IsWindows) {
    Write-Host "Determining Operating System..."
    $IsWindows = ([System.Environment]::OSVersion.Platform -eq "Win32NT")
    $IsLinux = ([System.Environment]::OSVersion.Platform -eq "Unix")
}

Function Copy-Files
{
	# Define parameters
    param (
    	$SourcePath,
        $DestinationPath
    )
    
    # Copy the items from source path to destination path
    $copyArguments = @{}
    $copyArguments.Add("Path", $SourcePath)
    $copyArguments.Add("Destination", $DestinationPath)
    
    # Check to make sure destination exists
    if ((Test-Path -Path $DestinationPath) -eq $false)
    {
    	# Create the destination path
        New-Item -Path $DestinationPath -ItemType "Directory" | Out-Null
    }
    
    # Check for wildcard
    if ($SourcePath.EndsWith("/*") -or $SourcePath.EndsWith("\*"))
    {
		# Add recurse argument
		$copyArguments.Add("Recurse", $true)
    }
    
    $copyArguments.Add("Force", $true)
    
    # Copy files
    Copy-Item @copyArguments
}

Function Execute-Command
{
	param (
    	$commandPath,
        $commandArguments,
        $workingDir
    )

	$gitExitCode = 0
    $executionResults = $null

  Try {
    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = $commandPath
    $pinfo.WorkingDirectory = $workingDir
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = $commandArguments
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $executionResults = [pscustomobject]@{
        stdout = $p.StandardOutput.ReadToEnd()
        stderr = $p.StandardError.ReadToEnd()
        ExitCode = $null
    }
    $p.WaitForExit()
    $gitExitCode = [int]$p.ExitCode
    $executionResults.ExitCode = $gitExitCode
    
    if ($gitExitCode -ge 2) 
    {
		# Fail the step
        throw
    }
    
    return $executionResults
  }
  Catch {
    # Check exit code
    Write-Error -Message "$($executionResults.stderr)" -ErrorId $gitExitCode
    exit $gitExitCode
  }

}

Function Get-GitExecutable
{
	# Define parameters
    param (
    	$WorkingDirectory
    )
      
    # Define variables
    $gitExe = "PortableGit-2.41.0.3-64-bit.7z.exe"
    $gitDownloadUrl = "https://github.com/git-for-windows/git/releases/download/v2.41.0.windows.3/$gitExe"
    $gitDownloadArguments = @{}
    $gitDownloadArguments.Add("Uri", $gitDownloadUrl)
    $gitDownloadArguments.Add("OutFile", "$WorkingDirectory/git/$gitExe")
    
    # This makes downloading faster
    $ProgressPreference = 'SilentlyContinue'
    
    # Check to see if git subfolder exists
    if ((Test-Path -Path "$WorkingDirectory/git") -eq $false)
    {
    	# Create subfolder
        New-Item -Path "$WorkingDirectory/git"  -ItemType Directory
    }
    
    # Check PowerShell version
    if ($PSVersionTable.PSVersion.Major -lt 6)
    {
    	# Use basic parsing is required
        $gitDownloadArguments.Add("UseBasicParsing", $true)
    }
    
    # Download Git
    Write-Host "Downloading Git ..."
    Invoke-WebRequest @gitDownloadArguments
    
    # Extract Git
    $gitExtractArguments = @()
    $gitExtractArguments += "-o"
    $gitExtractArguments += "$WorkingDirectory\git"
    $gitExtractArguments += "-y"
    $gitExtractArguments += "-bd"

    Write-Host "Extracting Git download ..."
    & "$WorkingDirectory\git\$gitExe" $gitExtractArguments

    # Wait until unzip action is complete
    while ($null -ne (Get-Process | Where-Object {$_.ProcessName -eq ($gitExe.Substring(0, $gitExe.LastIndexOf(".")))}))
    {
        Start-Sleep 5
    }
    
    # Add bin folder to path
    $env:PATH = "$WorkingDirectory\git\bin$([IO.Path]::PathSeparator)" + $env:PATH
    
    # Disable promopt for credential helper
    Invoke-Git -GitCommand "config" -AdditionalArguments @("--system", "--unset", "credential.helper")
}

# Get variables
$gitUrl = $OctopusParameters['Template.Git.Repo.Url']
$gitUser = $OctopusParameters['Template.Git.User.Name']
$gitPassword = $OctopusParameters['Template.Git.User.Password']
$sourceItems = $OctopusParameters['Octopus.Action.Package[Template.Package.Reference].ExtractedPath']
$destinationPath = $OctopusParameters['Template.Git.Destination.Path']
$gitSource = $null
$gitDestination = $null

# Check to see if it's Windows
if ($IsWindows -and $OctopusParameters['Octopus.Workerpool.Name'] -eq "Hosted Windows")
{
	# Dynamic worker don't have git, download portable version and add to path for execution
    Write-Host "Detected usage of Windows Dynamic Worker ..."
    Get-GitExecutable -WorkingDirectory $PWD
}

# Clone repository
$folderName = Invoke-Git -GitRepositoryUrl $gitUrl -GitUsername $gitUser -GitPassword $gitPassword -GitCommand "clone" -GitFolder "$($PWD)/default"

$gitSource = $sourceItems
$gitDestination = $folderName

# Copy files from source to destination
Copy-Files -SourcePath "$($gitSource)/*" -DestinationPath "$($gitDestination)$($destinationPath)"

# Set user
$gitAuthorName = $OctopusParameters['Octopus.Deployment.CreatedBy.DisplayName']
$gitAuthorEmail = $OctopusParameters['Octopus.Deployment.CreatedBy.EmailAddress']

# Check to see if user is system
if ([string]::IsNullOrWhitespace($gitAuthorEmail) -and $gitAuthorName -eq "System")
{
	# Initiated by the Octopus server via automated process, put something in for the email address
    $gitAuthorEmail = "system@octopus.local"
}

Invoke-Git -GitCommand "config" -AdditionalArguments @("user.name", $gitAuthorName) -GitFolder "$($folderName)" | Out-Null
Invoke-Git -GitCommand "config" -AdditionalArguments @("user.email", $gitAuthorEmail) -GitFolder "$($folderName)" | Out-Null

# Commit changes
Invoke-Git -GitCommand "add" -GitFolder "$folderName" -AdditionalArguments @(".") | Out-Null
Invoke-Git -GitCommand "commit" -GitFolder "$folderName" -AdditionalArguments @("-m", "`"Commit from #{Octopus.Project.Name} release version #{Octopus.Release.Number}`"") | Out-Null

# Push the changes back to git
Invoke-Git -GitCommand "push" -GitFolder "$folderName" | Out-Null


Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "4d541683-4731-4f43-a342-5b9f6c915c4d",
  "Name": "Git - Clone, copy, push from a Package",
  "Description": "Clones a repository, copies files from the `Source Package` to the `Destination Path` then commits to the repository.",
  "Version": 2,
  "ExportedAt": "2023-09-12T15:31:36.900Z",
  "ActionType": "Octopus.Script",
  "Author": "twerthi",
  "Packages": [
    {
      "Id": "88b1ab11-c878-4c7f-8227-610c3784311b",
      "Name": "Template.Package.Reference",
      "PackageId": null,
      "FeedId": null,
      "AcquisitionLocation": "Server",
      "Properties": {
        "Extract": "True",
        "SelectionMode": "deferred",
        "PackageParameterName": "Template.Package.Reference",
        "Purpose": ""
      }
    }
  ],
  "Parameters": [
    {
      "Id": "674d5325-aa93-4779-a734-cee8e5690f17",
      "Name": "Template.Git.Repo.Url",
      "Label": "Git Repository URL",
      "HelpText": "The URL used for the `git clone` operation.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "f2d07c9c-85fc-485e-8057-5577efd9a26d",
      "Name": "Template.Git.User.Name",
      "Label": "Git Username",
      "HelpText": "Username of the credentials to use to log into git.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "597ae9a5-1ef4-4062-a435-2d9bb1fb16a2",
      "Name": "Template.Git.User.Password",
      "Label": "Git User Password",
      "HelpText": "Password for the git credential.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "6d6b0662-22bd-4fbc-b0dd-15799b158abe",
      "Name": "Template.Package.Reference",
      "Label": "Package",
      "HelpText": "Choose the package to copy files from into the Git repository.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Package"
      }
    },
    {
      "Id": "f9a2141a-bcfa-4e53-862b-429b4f9892d9",
      "Name": "Template.Git.Destination.Path",
      "Label": "Destination Path",
      "HelpText": "Relative path to the folder to copy items to.  This is the folder name only.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "e382b0db-0ea2-47bb-968b-2dae9a8b861d",
      "Name": "Template.VariableReplacement.Paths",
      "Label": "Structured Configuration Variables",
      "HelpText": "Target files need to be new line seperated, relative to the package contents. Extended wildcard syntax is supported. E.g., appsettings.json, Config\\*.xml, **\\specific-folder\\*.yaml. Learn more about Structured Configuration Variables and view examples.",
      "DefaultValue": " ",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "Function Invoke-Git\n{\n\t# Define parameters\n    param (\n    \t$GitRepositoryUrl,\n        $GitFolder,\n        $GitUsername,\n        $GitPassword,\n        $GitCommand,\n        $AdditionalArguments\n    )\n    \n    # Get current work folder\n    $workDirectory = Get-Location\n\n\t# Check to see if GitFolder exists\n    if (![String]::IsNullOrWhitespace($GitFolder) -and (Test-Path -Path $GitFolder) -eq $false)\n    {\n    \t# Create the folder\n        New-Item -Path $GitFolder -ItemType \"Directory\" -Force | Out-Null\n        \n        # Set the location to the new folder\n        Set-Location -Path $GitFolder\n    }\n    \n    # Create arguments array\n    $gitArguments = @()\n    $gitArguments += $GitCommand\n    \n    # Check for url\n    if (![string]::IsNullOrWhitespace($GitRepositoryUrl))\n    {\n      # Convert url to URI object\n      $gitUri = [System.Uri]$GitRepositoryUrl\n      $gitUrl = \"{0}://{1}:{2}@{3}:{4}{5}\" -f $gitUri.Scheme, $GitUsername, $GitPassword, $gitUri.Host, $gitUri.Port, $gitUri.PathAndQuery\n      $gitArguments += $gitUrl\n\n      # Get the newly created folder name\n      $gitFolderName = $GitRepositoryUrl.SubString($GitRepositoryUrl.LastIndexOf(\"/\") + 1)\n      if ($gitFolderName.Contains(\".git\"))\n      {\n          $gitFolderName = $gitFolderName.SubString(0, $gitFolderName.IndexOf(\".\"))\n      }\n    }\n   \n    \n    # Check for additional arguments\n    if ($null -ne $AdditionalArguments)\n    {\n \t\t# Add the additional arguments\n        $gitArguments += $AdditionalArguments\n    }\n    \n    # Execute git command\n    $results = Execute-Command -commandPath \"git\" -commandArguments $gitArguments -workingDir $GitFolder\n    \n    Write-Host $results.stdout\n    Write-Host $results.stderr\n    \n    # Return the foldername\n    Set-Location -Path $workDirectory\n    \n    # Check to see if GitFolder is null\n    if ($null -ne $GitFolder)\n    {\n    \treturn Join-Path -Path $GitFolder -ChildPath $gitFolderName\n    }\n}\n\n# Check to see if $IsWindows is available\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\nFunction Copy-Files\n{\n\t# Define parameters\n    param (\n    \t$SourcePath,\n        $DestinationPath\n    )\n    \n    # Copy the items from source path to destination path\n    $copyArguments = @{}\n    $copyArguments.Add(\"Path\", $SourcePath)\n    $copyArguments.Add(\"Destination\", $DestinationPath)\n    \n    # Check to make sure destination exists\n    if ((Test-Path -Path $DestinationPath) -eq $false)\n    {\n    \t# Create the destination path\n        New-Item -Path $DestinationPath -ItemType \"Directory\" | Out-Null\n    }\n    \n    # Check for wildcard\n    if ($SourcePath.EndsWith(\"/*\") -or $SourcePath.EndsWith(\"\\*\"))\n    {\n\t\t# Add recurse argument\n\t\t$copyArguments.Add(\"Recurse\", $true)\n    }\n    \n    $copyArguments.Add(\"Force\", $true)\n    \n    # Copy files\n    Copy-Item @copyArguments\n}\n\nFunction Execute-Command\n{\n\tparam (\n    \t$commandPath,\n        $commandArguments,\n        $workingDir\n    )\n\n\t$gitExitCode = 0\n    $executionResults = $null\n\n  Try {\n    $pinfo = New-Object System.Diagnostics.ProcessStartInfo\n    $pinfo.FileName = $commandPath\n    $pinfo.WorkingDirectory = $workingDir\n    $pinfo.RedirectStandardError = $true\n    $pinfo.RedirectStandardOutput = $true\n    $pinfo.UseShellExecute = $false\n    $pinfo.Arguments = $commandArguments\n    $p = New-Object System.Diagnostics.Process\n    $p.StartInfo = $pinfo\n    $p.Start() | Out-Null\n    $executionResults = [pscustomobject]@{\n        stdout = $p.StandardOutput.ReadToEnd()\n        stderr = $p.StandardError.ReadToEnd()\n        ExitCode = $null\n    }\n    $p.WaitForExit()\n    $gitExitCode = [int]$p.ExitCode\n    $executionResults.ExitCode = $gitExitCode\n    \n    if ($gitExitCode -ge 2) \n    {\n\t\t# Fail the step\n        throw\n    }\n    \n    return $executionResults\n  }\n  Catch {\n    # Check exit code\n    Write-Error -Message \"$($executionResults.stderr)\" -ErrorId $gitExitCode\n    exit $gitExitCode\n  }\n\n}\n\nFunction Get-GitExecutable\n{\n\t# Define parameters\n    param (\n    \t$WorkingDirectory\n    )\n      \n    # Define variables\n    $gitExe = \"PortableGit-2.41.0.3-64-bit.7z.exe\"\n    $gitDownloadUrl = \"https://github.com/git-for-windows/git/releases/download/v2.41.0.windows.3/$gitExe\"\n    $gitDownloadArguments = @{}\n    $gitDownloadArguments.Add(\"Uri\", $gitDownloadUrl)\n    $gitDownloadArguments.Add(\"OutFile\", \"$WorkingDirectory/git/$gitExe\")\n    \n    # This makes downloading faster\n    $ProgressPreference = 'SilentlyContinue'\n    \n    # Check to see if git subfolder exists\n    if ((Test-Path -Path \"$WorkingDirectory/git\") -eq $false)\n    {\n    \t# Create subfolder\n        New-Item -Path \"$WorkingDirectory/git\"  -ItemType Directory\n    }\n    \n    # Check PowerShell version\n    if ($PSVersionTable.PSVersion.Major -lt 6)\n    {\n    \t# Use basic parsing is required\n        $gitDownloadArguments.Add(\"UseBasicParsing\", $true)\n    }\n    \n    # Download Git\n    Write-Host \"Downloading Git ...\"\n    Invoke-WebRequest @gitDownloadArguments\n    \n    # Extract Git\n    $gitExtractArguments = @()\n    $gitExtractArguments += \"-o\"\n    $gitExtractArguments += \"$WorkingDirectory\\git\"\n    $gitExtractArguments += \"-y\"\n    $gitExtractArguments += \"-bd\"\n\n    Write-Host \"Extracting Git download ...\"\n    & \"$WorkingDirectory\\git\\$gitExe\" $gitExtractArguments\n\n    # Wait until unzip action is complete\n    while ($null -ne (Get-Process | Where-Object {$_.ProcessName -eq ($gitExe.Substring(0, $gitExe.LastIndexOf(\".\")))}))\n    {\n        Start-Sleep 5\n    }\n    \n    # Add bin folder to path\n    $env:PATH = \"$WorkingDirectory\\git\\bin$([IO.Path]::PathSeparator)\" + $env:PATH\n    \n    # Disable promopt for credential helper\n    Invoke-Git -GitCommand \"config\" -AdditionalArguments @(\"--system\", \"--unset\", \"credential.helper\")\n}\n\n# Get variables\n$gitUrl = $OctopusParameters['Template.Git.Repo.Url']\n$gitUser = $OctopusParameters['Template.Git.User.Name']\n$gitPassword = $OctopusParameters['Template.Git.User.Password']\n$sourceItems = $OctopusParameters['Octopus.Action.Package[Template.Package.Reference].ExtractedPath']\n$destinationPath = $OctopusParameters['Template.Git.Destination.Path']\n$gitSource = $null\n$gitDestination = $null\n\n# Check to see if it's Windows\nif ($IsWindows -and $OctopusParameters['Octopus.Workerpool.Name'] -eq \"Hosted Windows\")\n{\n\t# Dynamic worker don't have git, download portable version and add to path for execution\n    Write-Host \"Detected usage of Windows Dynamic Worker ...\"\n    Get-GitExecutable -WorkingDirectory $PWD\n}\n\n# Clone repository\n$folderName = Invoke-Git -GitRepositoryUrl $gitUrl -GitUsername $gitUser -GitPassword $gitPassword -GitCommand \"clone\" -GitFolder \"$($PWD)/default\"\n\n$gitSource = $sourceItems\n$gitDestination = $folderName\n\n# Copy files from source to destination\nCopy-Files -SourcePath \"$($gitSource)/*\" -DestinationPath \"$($gitDestination)$($destinationPath)\"\n\n# Set user\n$gitAuthorName = $OctopusParameters['Octopus.Deployment.CreatedBy.DisplayName']\n$gitAuthorEmail = $OctopusParameters['Octopus.Deployment.CreatedBy.EmailAddress']\n\n# Check to see if user is system\nif ([string]::IsNullOrWhitespace($gitAuthorEmail) -and $gitAuthorName -eq \"System\")\n{\n\t# Initiated by the Octopus server via automated process, put something in for the email address\n    $gitAuthorEmail = \"system@octopus.local\"\n}\n\nInvoke-Git -GitCommand \"config\" -AdditionalArguments @(\"user.name\", $gitAuthorName) -GitFolder \"$($folderName)\" | Out-Null\nInvoke-Git -GitCommand \"config\" -AdditionalArguments @(\"user.email\", $gitAuthorEmail) -GitFolder \"$($folderName)\" | Out-Null\n\n# Commit changes\nInvoke-Git -GitCommand \"add\" -GitFolder \"$folderName\" -AdditionalArguments @(\".\") | Out-Null\nInvoke-Git -GitCommand \"commit\" -GitFolder \"$folderName\" -AdditionalArguments @(\"-m\", \"`\"Commit from #{Octopus.Project.Name} release version #{Octopus.Release.Number}`\"\") | Out-Null\n\n# Push the changes back to git\nInvoke-Git -GitCommand \"push\" -GitFolder \"$folderName\" | Out-Null\n\n",
    "Octopus.Action.EnabledFeatures": "Octopus.Features.JsonConfigurationVariables",
    "Octopus.Action.Package.JsonConfigurationVariablesTargets": "#{Template.VariableReplacement.Paths}"
  },
  "Category": "Git",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/git-clone-copy-push-package.json",
  "Website": "/step-templates/4d541683-4731-4f43-a342-5b9f6c915c4d",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRF////9CQ09TJB/dbZ9k1a/vHy+ZGZ/MjM+HaA92l0+62z91tn/uTm+YSN9T9N/Lq/+p+mxWmzxwAAA/5JREFUeNrs3dlyqzAMBmAWs0Po+z9t007OaUJskCXZljL6r3pDqi94w6bTqrJYLBaLxWKxWCwWi8VisVgYsw736GfMrv7NpNvSPhi/lE6xo6mf4rrPcOiVHB1aJe8OnRKfQ6PE79AnCTm0ScIOXZIzhybJuUOP5MqhRXLt0CGBODRIYA4Fkltdf4YEekdMYhKTmKRw7S+bJHol98rdJ0h+6/4AyaNq9ZL/NSuXPFWsWvJSr2LJoVq1krdalUo8laqUeOs8SG5T3/dLI1oS+L5fSvr3877IlQTbjb+kvREqOWn//pJWJ1Jy2o/9JXU3gZKL8chfUiuvn7S4Br9JkwDmh9HbTYSNwpB5bvZeOYmSgObr1Xvpl6Q5HuRo/NcOglYrsPXT4r94lbPuAq4DA5BOzAoSup4lNK0sEvi63F/KLGRVD3cEht9RxvNJhCPQSWQ8acU46noQK4lz1E7qDnekI7DaKi+JdgiVIBzBFzJLSlCO+7TYC5MgHff8fYQECd7xB+nH8hKC4wlSF5dQHM+Q0hKS4wVSVkJzvEJKSoiOA6SchOo4QkpJyI43SBkJ3fEOOUjcNg/D3rukEgaHBxLYgxzTSTgcPkhgVTykOj9hcXghAUmX5vyEx+GHhCRJ7omrE0JCrevyASfeMddJIQHJ5Wb9UOqGBCH1nueWrHVqiL+538CfB8yQGhLY5B6521ZySGCHpVcH8e9KVPunQGb2YSs1ZEI2rTUWMiWG3HC/1lWlhq3gd92iFilz/NQ+JYaMmC7iEGutzqWF+Fr71Vs3TVsVk4QhS/SrKjgHk+RkPBojGxbWwSM5G1jHTA4WyekMsTz1k25K5+CQXEx142OmbrcmpYNBcj1nL/dcPlZTHXQJfPGR1kGWsEA4HFQJB4THQZQwQLgcNAkdwucgScgQTgdFQoXwOggSIoTbgZfQIPwOpGRcn450ZDgwkmaPedrI5YiXvNUxy3BES4bYJ8BcjkjJRtvjT+mIkjQdaZMprSNGsuGODTI5IiT+TdpNigMuoWxg5nBAJaG3fuU4gJIFv8ufywGT4O9IPgdMgu0jOR0gSYs7yMnrgEg21PF9bgdAgprZ8zsAkj7+hpRwACRtbA8p47iWxD6PlHJES76kOiD95K/Hr4tcB2TsGvcfyzpPtWQH29lvcQeXpLyDRyLBwSGR4aBLpDioEjkOmkSSgyKR5cBLpDmwEnkOnESiA3V+ItLBcH6iVCLXESeR7IiRyHbAJdIdUIl8B0yiwQGR6HAg9ruUSvQ4ziWaHGcSXY6wRJsjJNHn8Es0OnwSnY53iVbHUaLX8fo3IU6x457hQXFzpT4//yB4rSwWi8VisVgsFovFYrFYLBbGfAswAOAaON62iVbvAAAAAElFTkSuQmCC",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Tuesday, September 12, 2023