Basic Tasks and Conventions
Build scripts facilitate automation. Automating tasks reduces human touches and the potential for mistakes. Continuous improvement processes utilize automated processes to ensure that projects build consistently.
- DO have a consistent naming and casing convention for Psake tasks and PowerShell methods
- DO create tasks for ubiquitous development activities that all projects will consume
- Documentation Inside a Build Script
- DO document tasks and include detailed descriptions of their purpose.
- DO create terse but descriptive task names
- CONSIDER using the name Verb-Noun format when naming Tasks
- AVOID excessively long task names
- CONSIDER adding
-Alias
for longer, frequent task names - DO keep your scripts as platform-neutral as possible
- DO use forward slash for your path separation
- DO assume file and folder names are case-sensitive
DO have a consistent naming and casing convention for Psake tasks and PowerShell methods
Tasks are created in the psakefile.ps1
file. Naming and casing conventions are whatever the team decides. The PowerShell guidance convention is capitalized Kebab-Case. We also like regular kebab-case. You do you, but maintain consistency throughout the file.
DO create tasks for ubiquitous development activities that all projects will consume
In addition to building the solution, a proper build tool automates day-to-day developer activities with a menu of commands - cleaning the solution directories (\bin\, \obj\, etc.) of past build artifacts, running tests, migrating the database to the latest version or refreshing sample data, starting services on which the solution depends to function, etc. Therefore, build scripts give developers an easy way to browse available tasks and advertise their purpose.
Documentation Inside a Build Script
Psake offers a PowerShell StringLiteral -Description
as a parameter to hold task descriptions. Psake writes out the description for all tasks when passed the built in -Docs
or -DetailedDocs
parameters. The -Docs
parameter prints a list of tasks in simple rows. -DetailedDocs
iterates through the Task
objects and prints out the results of the Task
as a PowerShell object, with each property on a separate line.
DO document tasks and include detailed descriptions of their purpose.
The following Build task example has a Description that is displayed when a user executes Invoke-Psake -docs
.
task Build -Description "Builds the solution" {
dotnet build --framework $framework --configuration $configuration --no-logo
}
Psake simplifies task execution using an Alias, as an alternative to typing Tasks with long names.
task IntegrationTests -Alias itest -Description "Runs integration tests" {
# ...
}
> Invoke-Psake itest
Running RunIntegrationTests...
DO create terse but descriptive task names
Task names should be immediately readable for context by new developers. For example: Clean
, Build
, Test
, Migrate-Database
versus Delete-BinObjFolders
, Build-Solution
, Exec-Roundhouse
. For day-to-day tasks, Migrate-Database does the job.
CONSIDER using the name Verb-Noun format when naming Tasks
PowerShell naming convention uses a verb-noun format. Names like Run-IntegrationTests
, Migrate-Database
, Populate-SampleData
communicate the operation and what it is operating upon.
AVOID excessively long task names
CONSIDER adding -Alias
for longer, frequent task names
Forcing developers to type Execute-CompanyMandatedReductionProcedure
for a commonly used task will quickly become tedious, even if it is accessible in the buffer. It is best to provide a shorter alias for necessarily long task names. Keep task names under thirty characters, if possible. Maybe the team knows this particular task as the “squash” task. “Squash” would make a good candidate for an alias. Use good judgement and utilize existing domain language without inventing new terms.
Although Migrate-Database
, from above, is a good, terse task name, your users will appreciate it more if they only have to type Migrate
.
DO keep your scripts as platform-neutral as possible
PowerShell (and the .NET Core SDK) run on both Windows and Linux, so your build script should be able to work with both operating system environments seamlessly. Keep in mind that you may not be running in a Windows OS and you may not be running with administrative privileges.
DO use forward slash for your path separation
When defining paths in PowerShell strings, use the forward slash “/” as a path separator instead of backslash “\”. This will translate properly on both Windows and Linux and you can do path concatenation and separation universally. Also, use the Path APIs in your scripts instead of manually searching in a string for path separators.
DO assume file and folder names are case-sensitive
Linux filesystems are case-sensitive while Windows filesystems are not. This means that if you mix cases in a filename, you may end up with unexpected errors.
These filenames are not the same in Linux
Directory.build.props
Directory.Build.props
These two files mean the same thing in Windows and .NET Core SDK will pick up the files and use them the same. In Linux, however, the first form will be ignored entirely (without an error message), while the second form will be used as expected.
Similarly, if you are running executables as part of your build or referring to specific folders, the casing of the file or folder matters. You will later be able to test out your builds in a Docker container in case you are developing on a Windows machine and want to be sure your builds will work. The current Docker images for the .NET Core SDK 3.1 include PowerShell 7 in the Linux and Windows platforms.