Devops-friendly Windows releases on-premise or in the cloud.
Goodbye, manual releases.
Inspired by ansible and rails , powerdelivery organizes everything Windows PowerShell can do within a secure, convention-based framework so you can stop being jealous of your linux friends when you release to Windows.
pure powershell | rollback-capable | encrypts secrets | open source
To discuss powerdelivery
anyone can join!
A birds-eye view
Before you read the docs, see some code.
Create a project
Administrator: Windows PowerShell
PS C:\MyApp > New-DeliveryProject MyApp "Local" , "Production"
Project successfully created at ".\MyAppDelivery"
param ( $target , $shared )
@{
SiteURL = "http://myapp.cloudapp.net" ;
ReleasesPath = ".\Releases"
}
MyAppDelivery\Configuration\Local.ps1
param ( $target , $shared )
@{
SiteURL = "http://www.myapp.com" ;
ReleasesPath = "\\MyShare\MyProduct\Releases"
}
MyAppDelivery\Configuration\Production.ps1
param ( $target , $config )
@{
Build = @{
Hosts = "localhost"
};
Web = @{
Hosts = "localhost"
}
}
MyAppDelivery\Environments\Local.ps1
param ( $target , $config )
@{
Build = @{
Hosts = "localhost"
};
Web = @{
Hosts = "x.x.x.3" , "x.x.x.4" ;
Credential = "MYDOMAIN\ops"
}
}
MyAppDelivery\Environments\Production.ps1
Administrator: Windows PowerShell
PS C:\MyApp\MyAppDelivery > New-DeliveryRole "Compile" , "Webapp"
Role created at ".\Roles\Compile"
Role created at ".\Roles\Webapp"
Delivery:Role {
param ( $target , $config , $node )
# Publish website into a directory
Invoke-MSBuild MyApp.sln -properties @{ DeployOnBuild = "true" ; PublishProfile = "MyApp" }
# \\SHARE\<ProjectName>\<StartedAt>
$remotePath = " $( $config . ReleasesPath ) \ $( $target . ProjectName ) \ $( $target . StartedAt ) "
# Copy website to a network drive, S3 bucket,
# or wherever the remote nodes can access
Copy-Item "MyApp\bin\publish" $remotePath -Recurse
}
MyAppDelivery\Roles\Compile\Always.ps1
Delivery:Role -Up {
param ( $target , $config , $node )
Import-Module PowerDeliveryNode
Add-PSSnapin WebAdministration
# \\SHARE\<ProjectName>\<StartedAt>
$remotePath = " $( $config . ReleasesPath ) \ $( $target . ProjectName ) \ $( $target . StartedAt ) "
# AppData\Roaming\MyApp\Current
# (symlinked to AppData\Roaming\MyApp\yyyyMMdd_HHmmss)
$appDataDir = [ Environment ]:: GetFolderPath ( "ApplicationData" )
$releasePath = New-DeliveryReleasePath $target $appDataDir
# Copy web content from the network drive to the current release
Copy-Item $remotePath $releasePath -Filter *.* -Recurse
# Create the web application
New-WebApplication $config . SiteURL MyApp $releasePath -Force
} -Down {
param ( $target , $config , $node )
Import-Module PowerDeliveryNode
# Rollback AppData\Roaming\MyApp\Current to previous release
$appDataDir = [ Environment ]:: GetFolderPath ( "ApplicationData" )
Undo-DeliveryReleasePath $target $appDataDir
}
MyAppDelivery\Roles\Webapp\Always.ps1
[ ordered ]@{
"Building the product" = @{
Roles = "Compile" ;
Nodes = "Build"
};
"Deploying the website" = @{
Roles = "Webapp" ;
Nodes = "Web"
}
}
MyAppDelivery\Targets\Release.ps1
Release locally
Administrator: Windows PowerShell
PS C:\MyApp > Start-Delivery MyApp Release Local
PowerDelivery v3.0.1
Target "Release" started by MYDOMAIN\dev
Delivering "MyApp" to "Local" environment...
[ ----- Building the product
[ --------- Compile - > ( localhost )
[ ----- Deploying the website
[ --------- Webapp - > ( localhost )
Target "Release" succeeded in 10 sec 453 ms.
Release to production
Administrator: Windows PowerShell
PS C:\MyApp > Start-Delivery MyApp Release Production
PowerDelivery v3.0.1
Target "Release" started by MYDOMAIN\ops
Delivering "MyApp" to "Production" environment...
[ ----- Building the product
[ --------- Compile - > ( localhost )
[ ----- Deploying the website
[ --------- Webapp - > ( x.x.x.3 )
[ --------- Webapp - > ( x.x.x.4 )
Target "Release" succeeded in 1 m 13 sec 56 ms.
Now get started automating your own releases!