This module helps in creating declarative publish configuration.
A basic publish map is a powershell dictionary with three levels: group, project, profile.
$map = @{
my_group = @{
my_project = @{
my_property1 = "abc"
my_property2 = "cde"
profiles = @{
my_dev_profile = @{
my_profile_property = "dev"
}
my_prod_profile = @{
my_profile_property = "prod"
}
}
}
}
}
A profile (my_dev_profile
and my_prod_profile
) is a description of a deployment that should have all properties required to deploy a piece of code to a server. This may include target server machine, build configuration, etc.
A project (my_project
) is a logical unit that represents one application or service. It may have several publish profiles (i.e. you may want to publish your website to dev environment or to production).
A group (my_group
) is just a grouping of multiple projects.
A group consists of projects, which in turn may have multiple profiles.
Lets take a look at a real-life publishmap example:
$map = @{
qlogger = @{
viewer = @{
sln = "Qlogger.sln"
proj = "src\Qlogger.Viewer.Web\Qlogger.Viewer.Web.csproj"
appname = "/viewer"
deployprop="DeployLogViewer"
profiles = @{
dev = @{
Config = "Debug"
ComputerName = "phobos"
Machine = "phobos:8172"
BaseAppPath = "devserver-dev"
test = "http://phobos:10080/svc/log"
}
}
}
}
}
Now, lets say I want to build the project:
PS> msbuild $($map.qlogger.viewer.sln) -property:Configuration=$($map.qlogger.viewer.profiles.dev.Config)
Then I can use other properties to run msdeploy and deploy the website.
So far, this isn't very impressive. I can do better and write a script that takes a profile and invokes msbuild for me, which I would call like this:
PS> build.ps1 $map.qlogger.viewer.profiles.dev
The script could look like this:
param($profile)
& msbuild $($profile.sln) -property:Configuration=$($profile.Config)
But wait a minute... $profile
doesn't have a property named "sln" - the parent viewer
project has it, but the profile doesn't know anything about it.
Here's where Publishmap module comes into play.
Publishmap module takes a dictionary with a structure showed above and processes it, so the final profile nodes have access to every information from parent nodes.
It also creates a shortcut for individual profiles at project level, so you can say $map.qlogger.viewer.dev
instead of $map.qlogger.viewer.profiles.dev
.
This includes the following properties:
project
- points at parent project (use it:$profile.project.sln
)_fullpath
- full path in the map tree ($map.qlogger.viewer.dev._fullpath
="qlogger.viewer.dev"
)_name
- name of current node ($map.qlogger.viewer.dev._name
="dev"
)_level
- node's level in the map ($map.qlogger.viewer.dev._level
=3
)
Additional auto-properties:
_autogenerated
- the profile was automatically generated_inherit_from
- the profile is inherited from another profile
If you have many projects (like: a main website, an admin panel, some API), chances are their profiles will share many of the properties (like same target machine, same config, and so on). You can use global_profiles
nodes to define these properties:
$map = @{
qlogger = @{
global_profiles = @{
dev = @{
Config = "Debug"
ComputerName = "phobos"
Machine = "phobos:8172"
BaseAppPath = "devserver-dev"
}
}
viewer = @{
sln = "Qlogger.sln"
proj = "src\Qlogger.Viewer.Web\Qlogger.Viewer.Web.csproj"
appname = "/svc/log"
deployprop="DeployLogViewer"
}
}
}
The profiles from global_profiles
node will be inherited in every project.
If you want to override some properties from a global profile, just declare it as a profile at project level:
$map = @{
qlogger = @{
global_profiles = @{
dev = @{
Config = "Debug"
ComputerName = "phobos"
Machine = "phobos:8172"
BaseAppPath = "devserver-dev"
}
}
viewer = @{
sln = "Qlogger.sln"
proj = "src\Qlogger.Viewer.Web\Qlogger.Viewer.Web.csproj"
appname = "/svc/log"
deployprop="DeployLogViewer"
profiles = @{
dev = @{
Config = "Devel"
}
}
}
}
}
- staging and swap profiles are automatically generated for all profiles other than
swap_.*
and.*_staging
A sample map file (lets call it mymap.config.ps1
) looks like this:
@{
qlogger = @{
global_profiles = @{
dev = @{
Config = "Debug"
ComputerName = "phobos"
Machine = "phobos:8172"
BaseAppPath = "devserver-dev"
}
}
viewer = @{
sln = "Qlogger.sln"
proj = "src\Qlogger.Viewer.Web\Qlogger.Viewer.Web.csproj"
appname = "/svc/log"
deployprop="DeployLogViewer"
profiles = @{
dev = @{
test = "http://phobos:10080/svc/log"
}
dev_staging = @{
test = "http://phobos:10080/svc/log-staging"
}
}
}
}
}
To convert it to a publishmap, use Import-Publishmap
function:
PS> $map = Import-Publishmap mymap.config.ps1
PS> $profile = Get-Entry "qlogger.viewer.dev" $map