Retention Policy

Octopus.Script exported 2016-08-27 by sarbis belongs to ‘Octopus’ category.

Applies retention policy for built-in package repository by specified package id. Useful when you are using variables in PackageId parameter of deploy package step and built-in retention policy for package repository is not deleting packages.

Parameters

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

Packages root directory

Retention.PackagesRootDirectory

Packages directory path on Octopus server (e.g. D:\Octopus\Packages).

Criteria

Retention.Criteria = days

Criteria by which to apply retention policy - days or number of packages.

Value

Retention.Value = 30

Value for selected criteria. Min value for days criteria - 3. Min value for number criteria - 10.

Package Id

Retention.PackageId

null

Fail on validate

Retention.FailOnValidate =

If true throws exception when parameter validation fails. If false just outputs warning messages to deployment log and doesn’t fail whole deployment.

Script body

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

Function Get-Parameter($Name, [switch]$Required, $Default, [switch]$FailOnValidate) {
    $result = $null
    $errMessage = [string]::Empty

    If ($OctopusParameters -ne $null) {
        $octopusParameterName = ("Retention." + $Name)
        $result = $OctopusParameters[$octopusParameterName]
        Write-Host "Octopus paramter value for $octopusParameterName : $result"
    }

    If ($result -eq $null) {
        $variable = Get-Variable $Name -EA SilentlyContinue
        if ($variable -ne $null) {
            $result = $variable.Value
        }
    }

    If ($result -eq $null) {
        If ($Required) {
            $errMessage = "Missing parameter value $Name"
        } Else {
            $result = $Default
        }
    } 

    If (-Not [string]::IsNullOrEmpty($errMessage)) {
        If ($FailOnValidate) {
            Throw $errMessage
        } Else {
            Write-Warning $errMessage
        }
    }

    return $result
}

Function Validate-Parameters([switch]$FailOnValidate) {
    $errMessage = [string]::Empty

    If ($retentionCriteria.ToLower() -eq "days") {
        If ($retentionValue -lt 3) {
            $errMessage = "Retention Value not specified or must be greater than 3 days!"
        }
    } ElseIf ($retentionCriteria.ToLower() -eq "number") {
        If ($retentionValue -lt 10) {
            $errMessage = "Retention Value not specified or must be greater than 9 packages!"
        }
    } Else {
        $errMessage = "Retention Criteria must be 'days' or 'number'!"
    }
    
    If ([string]::IsNullOrEmpty($errMessage)) {
       return $true;
    } Else {
        If ($FailOnValidate) {
            Throw $errMessage
        } Else {
            Write-Warning $errMessage
            return $false;
        }
    }
}

& {
    Write-Host "Start RetentionPolicy"

    $retentionFailOnValidate = [System.Convert]::ToBoolean([string](Get-Parameter "FailOnValidate" $false "False" $false))
    $packagesRootDirectoryPath = [string] (Get-Parameter "PackagesRootDirectory" $true [string]::Empty $retentionFailOnValidate)
    $retentionCriteria = [string] (Get-Parameter "Criteria" $true "days" $retentionFailOnValidate)
    $retentionValue = [int] (Get-Parameter "Value" $true 30 $retentionFailOnValidate)
    $retentionPackageId = [string] (Get-Parameter "PackageId" $true [string]::Empty $retentionFailOnValidate)

    If ((Validate-Parameters $retentionFailOnValidate)) {

        # Filter out package folders by name if parameter specified
        $packageDirectories = Get-ChildItem $packagesRootDirectoryPath | ?{ $_.PSIsContainer } | ?{ $_.Name -eq $retentionPackageId }

        If ($packageDirectories.Length -le 0) {
            Write-Warning "No package directories found!"
        } Else {
            ForEach ($packageDirectory in $packageDirectories) {
                $packageFiles = Get-ChildItem $packageDirectory.FullName
                If ($packageFiles.Length -gt 0) {
                    Write-Host ("Package files found in directory: " + $packageDirectory.FullName + " - " + $packageFiles.Length)
                    $packageFilesObsolete = @()

                    If ($retentionCriteria -eq "days") {
                        $packageFilesObsolete = $packageFiles | ?{ $_.LastWriteTime -le ((Get-Date).AddDays($retentionValue * -1)) }
                    } ElseIf ($retentionCriteria -eq "number") {
                        $filesToDelete = ($packageFiles.Length - $retentionValue)
                        If ($filesToDelete -gt 0) {
                            $packageFilesObsolete = $packageFiles | Sort-Object LastWriteTime | Select-Object -First $filesToDelete
                        }
                    }

                    If ($packageFilesObsolete.Length -gt 0) {
                        Write-Host ("Applying retention policy for " + $packageFilesObsolete.Length + " obsolete files in directory: " + $packageDirectory.FullName)
                        ForEach ($packageVersionFileObsolete in $packageFilesObsolete) {
                            Remove-Item -Path $packageVersionFileObsolete.FullName -Force -Recurse
                        }
                    } Else {
                        Write-Host ("No package files deleted, all files match policy rules!")
                    }
                } Else {
                    Write-Host ("No files found, removing empty directory: " + $packageDirectory.FullName)
                    Remove-Item -Path $packageDirectory.FullName -Force -Recurse
                }
            }
        }
    } ElseIf ($retentionFailOnValidate -eq $true) {
        throw "Missing or invalid parameter values!"
    }

    Write-Host "End RetentionPolicy"
}


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": "46705230-c116-41c6-ba4b-b58d43f4f0e1",
  "Name": "Retention Policy",
  "Description": "Applies retention policy for built-in package repository by specified package id. Useful when you are using variables in PackageId parameter of deploy package step and built-in retention policy for package repository is not deleting packages.",
  "Version": 15,
  "ExportedAt": "2016-08-27T20:53:13.764+00:00",
  "ActionType": "Octopus.Script",
  "Author": "sarbis",
  "Parameters": [
    {
      "Name": "Retention.PackagesRootDirectory",
      "Label": "Packages root directory",
      "HelpText": "Packages directory path on Octopus server (e.g. D:\\Octopus\\Packages).",
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "Retention.Criteria",
      "Label": "Criteria",
      "HelpText": "Criteria by which to apply retention policy - days or number of packages.",
      "DefaultValue": "days",
      "DisplaySettings": {
        "Octopus.ControlType": "Select",
        "Octopus.SelectOptions": "days|Days\nnumber|Number of packages"
      }
    },
    {
      "Name": "Retention.Value",
      "Label": "Value",
      "HelpText": "Value for selected criteria.\nMin value for days criteria - 3.\nMin value for number criteria - 10.",
      "DefaultValue": "30",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "Retention.PackageId",
      "Label": "Package Id",
      "HelpText": null,
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "Retention.FailOnValidate",
      "Label": "Fail on validate",
      "HelpText": "If true throws exception when parameter validation fails. If false just outputs warning messages to deployment log and doesn't fail whole deployment.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "Function Get-Parameter($Name, [switch]$Required, $Default, [switch]$FailOnValidate) {\n    $result = $null\n    $errMessage = [string]::Empty\n\n    If ($OctopusParameters -ne $null) {\n        $octopusParameterName = (\"Retention.\" + $Name)\n        $result = $OctopusParameters[$octopusParameterName]\n        Write-Host \"Octopus paramter value for $octopusParameterName : $result\"\n    }\n\n    If ($result -eq $null) {\n        $variable = Get-Variable $Name -EA SilentlyContinue\n        if ($variable -ne $null) {\n            $result = $variable.Value\n        }\n    }\n\n    If ($result -eq $null) {\n        If ($Required) {\n            $errMessage = \"Missing parameter value $Name\"\n        } Else {\n            $result = $Default\n        }\n    } \n\n    If (-Not [string]::IsNullOrEmpty($errMessage)) {\n        If ($FailOnValidate) {\n            Throw $errMessage\n        } Else {\n            Write-Warning $errMessage\n        }\n    }\n\n    return $result\n}\n\nFunction Validate-Parameters([switch]$FailOnValidate) {\n    $errMessage = [string]::Empty\n\n    If ($retentionCriteria.ToLower() -eq \"days\") {\n        If ($retentionValue -lt 3) {\n            $errMessage = \"Retention Value not specified or must be greater than 3 days!\"\n        }\n    } ElseIf ($retentionCriteria.ToLower() -eq \"number\") {\n        If ($retentionValue -lt 10) {\n            $errMessage = \"Retention Value not specified or must be greater than 9 packages!\"\n        }\n    } Else {\n        $errMessage = \"Retention Criteria must be 'days' or 'number'!\"\n    }\n    \n    If ([string]::IsNullOrEmpty($errMessage)) {\n       return $true;\n    } Else {\n        If ($FailOnValidate) {\n            Throw $errMessage\n        } Else {\n            Write-Warning $errMessage\n            return $false;\n        }\n    }\n}\n\n& {\n    Write-Host \"Start RetentionPolicy\"\n\n    $retentionFailOnValidate = [System.Convert]::ToBoolean([string](Get-Parameter \"FailOnValidate\" $false \"False\" $false))\n    $packagesRootDirectoryPath = [string] (Get-Parameter \"PackagesRootDirectory\" $true [string]::Empty $retentionFailOnValidate)\n    $retentionCriteria = [string] (Get-Parameter \"Criteria\" $true \"days\" $retentionFailOnValidate)\n    $retentionValue = [int] (Get-Parameter \"Value\" $true 30 $retentionFailOnValidate)\n    $retentionPackageId = [string] (Get-Parameter \"PackageId\" $true [string]::Empty $retentionFailOnValidate)\n\n    If ((Validate-Parameters $retentionFailOnValidate)) {\n\n        # Filter out package folders by name if parameter specified\n        $packageDirectories = Get-ChildItem $packagesRootDirectoryPath | ?{ $_.PSIsContainer } | ?{ $_.Name -eq $retentionPackageId }\n\n        If ($packageDirectories.Length -le 0) {\n            Write-Warning \"No package directories found!\"\n        } Else {\n            ForEach ($packageDirectory in $packageDirectories) {\n                $packageFiles = Get-ChildItem $packageDirectory.FullName\n                If ($packageFiles.Length -gt 0) {\n                    Write-Host (\"Package files found in directory: \" + $packageDirectory.FullName + \" - \" + $packageFiles.Length)\n                    $packageFilesObsolete = @()\n\n                    If ($retentionCriteria -eq \"days\") {\n                        $packageFilesObsolete = $packageFiles | ?{ $_.LastWriteTime -le ((Get-Date).AddDays($retentionValue * -1)) }\n                    } ElseIf ($retentionCriteria -eq \"number\") {\n                        $filesToDelete = ($packageFiles.Length - $retentionValue)\n                        If ($filesToDelete -gt 0) {\n                            $packageFilesObsolete = $packageFiles | Sort-Object LastWriteTime | Select-Object -First $filesToDelete\n                        }\n                    }\n\n                    If ($packageFilesObsolete.Length -gt 0) {\n                        Write-Host (\"Applying retention policy for \" + $packageFilesObsolete.Length + \" obsolete files in directory: \" + $packageDirectory.FullName)\n                        ForEach ($packageVersionFileObsolete in $packageFilesObsolete) {\n                            Remove-Item -Path $packageVersionFileObsolete.FullName -Force -Recurse\n                        }\n                    } Else {\n                        Write-Host (\"No package files deleted, all files match policy rules!\")\n                    }\n                } Else {\n                    Write-Host (\"No files found, removing empty directory: \" + $packageDirectory.FullName)\n                    Remove-Item -Path $packageDirectory.FullName -Force -Recurse\n                }\n            }\n        }\n    } ElseIf ($retentionFailOnValidate -eq $true) {\n        throw \"Missing or invalid parameter values!\"\n    }\n\n    Write-Host \"End RetentionPolicy\"\n}\n\n",
    "Octopus.Action.Script.ScriptFileName": null,
    "Octopus.Action.Package.NuGetFeedId": null,
    "Octopus.Action.Package.NuGetPackageId": null
  },
  "Category": "Octopus",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/retention-policy.json",
  "Website": "/step-templates/46705230-c116-41c6-ba4b-b58d43f4f0e1",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAC1QTFRFT6Tl////L5Pg8vj9Y67omsvwPJrisdfzfbzs5fL7y+T32Ov5isLucLXqvt31CJPHWwAABMJJREFUeNrs3deW4jAMAFDF3U75/89dlp0ZhiU4blJEjvQ8hYubLJsA00UCBCIQgQhEIAIRiEAEIhCBCEQgAhGIQAQiEIEIhD8kJm+t+QprfdKfB9HbYpx6CWfspj8HMi+gMgHL/AmQA8W3JTKH+ALFvzCeL0RbpyoCPE9IJeNOSQwh5Z3qd6yRGWQ2qi2cZQWxqj1WzQYSjeoJmJlAklOd4VlArOqPhQEkqBERToeMcfRJBkC0Uep8CfBpjz4JsHJ0zF3dkEWNje0kiB/sUC6eApndaIiCMyAa1PiwJ0AWhRGJHJJQHG2dC7h1rNbO1QOxSA7lNCkkKrQIpJCAB1GREILYIC1NAiwbpKFJgGWDNExcwGstfExcZBCHC6nOglshHtmhViLIig1RNBCN7qjtW8C0Z1UvJcC1Z9XmwMBzzvobmgAyEzgq91dtEEsBsQSQQAFZCSBAATEEEApHZbrVBIkkEIUPSVeB+KtALA0kXQUSrwKZBCIQBnk8Y4i5CsReBeKvkqLM+BCSDWJlrZFvGk9SRTHshkgjZCGAaArIxm3H3grhVzFlW2msfl1ca79UJ1bofYvsDHHlNdTZnlh5MghuPd5NdBDUNZHyCkfktIh03XzALGRPlBDPac7qgWjHZzWcmF5zmmkhidMQ6boKiDXcDTUEaylZqCGJ0Vjvu/fLJtHqhSANEvqb2OYqkOUqEHuVMbJcZdZCGiPhKhC4yjqiIjEE7XThMp8fAWII3mY3kUIQD+AMKQTzPiBhgQ63HlT/KSvgtoi0dq5mCPah1UIE0eh3sT0NhOByvKeAkFzi8PgQomumFhsyOxpIzZN4gLOj5plVwNpR0b2AuePWKBEHQu24pSsJA+LVCeHHQxZ1SiyDIdqok8IOhSSnTottHEQTdyt4ettAj4KkzA4dMikk2Dht2S5ptm1vswnPDxn0YyDZ5oDM3iToo2T5voWaYe+Q+vdjH80QyAzZhCgcDtLMI1Tmtz9w++XHgziHQHJJu/OZ3bs9Xn8gQ72NcP3dKqEfkp10F51xhoIi2I91R+LurXV/5q7pH+wx061CzO16oSQleMyr8fXvwMA0Pro8432DPD/ySx8XrHfSuDAM8n6UhnjQabaiXf5Bq/lREHvEeNtn1rJ08+C/uXkQZHeguxAPC3UvtcJYUogLzZX5hhZZvS6onG5lxXtzWGaygwb79vT/IXhdlNibwlKYOR6T8xjI7W8n+xV7T+GH4tMzWwR+lZhRkJYSsC0thpmCYqyngOz3rN2FLBZ2wZflBCggUHF0Vnp88JKienzIXLSEZCZqU7IKr/gQW9yx3pzV7Y9kvWZWTRRIqDmTtRUnU7b2lLcTYmoqHqnmiO1poER0SPkAeZMAZxaJx0Y3TCdAclsIqDz03ALcyxfTCZBsthoGXWmigGyVhWPLFJJfuuKQWycoEFdXbH4dJJoJxNR1eD/kshz6yn48cF8yW8sFoitflB1w6Q8n+/15Za7oA17/pYNmYgP5fmWm8L1NOHPWgK8kuFew1/JXtOA0yJCv7ah7X8ObUuT5kObU30+fDZm8+zqP+HTIpK0xQ796b5Kv2hSIQAQiEIEIRCACEYhABCIQgQhEIAIRiEAEIpBf8UeAAQAEjtYmlDTcCgAAAABJRU5ErkJggg==",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Saturday, August 27, 2016