Lately I’ve been doing a lot of development work in C# and PowerShell. The bulk has been PowerShell modules, but I’ve also done quite a bit of work on API’s and Azure DevOps extensions. But one thing is fairly consistent throughout, the need to work with the code in a reliable and repeatable manner. I use psake for Build Automation tasks and for the past few weeks I’ve been iterating on my various automation scripts and have gotten to the point where I think I have something that’s pretty useful.

I created the LocalAutomation Github Repo as a place where I could keep these files together and to continue to iterate and improve on them. I hope that you can find them useful as well. Feel free to clone or fork the repo or even download the releases.

psakefile.ps1

This file defines the variables that will be used in all the tasks, and additionally defines all the Tasks that need to be run in order to accomplish my tasks. There are two variables I define at the top of this file:

  • $script:ModuleName
    • This variable is the name of the module and is used in various tasks and additional variables
  • $script:GithubOrg
    • This variable is either the Github Organization or your Github username
C:.
├───.vscode
├───AzDevOps
│   ├───azdevops
│   │   └───public
│   ├───build
│   │   ├───builds
│   │   │   └───public
│   │   ├───definitions
│   │   │   └───public
│   │   └───folders
│   │       └───public
│   ├───core
│   │   ├───processes
│   │   │   └───public
│   │   ├───projects
│   │   │   └───public
│   │   └───teams
│   │       └───public
│   └───operations
│       └───operations
│           └───public
├───docs
├───en-us
└───output
    └───AzDevOps
        ├───build
        ├───core
        └───operations

Above is the folder structure for the AzDevOps module, the top level folder AzDevOps is the ModuleName which is defined within the psakefile. For pure PowerShell modules, the public folders contain a script file for each function defined. For C-Sharp modules the Project and Solution files are contained within the ModuleName folder. In addition to preperaing the repository for work to start, I also have built in some code to install or import various modules that I use on a regular basis.

  • BuildHelpers : This is used for pure PowerShell modules
  • PowerShellForGithub : This is used in a few tasks for working with GitHub
  • PlatyPS : This is used to create and update help documentation
  • Pester : This is the PowerShell testing framework

Localuse

Invoke-psake Localuse

This task depends on several subtasks Clean, BuildModule and BuildManifest or BuildProject and CopyModuleFiles.

  1. Clean
    1. This task deletes the Output folder and everyting inside it
    2. It then re-creates the Output folder
  2. PowerShell Modules
    1. BuildModule
      1. This task collects all the scripts and appends them to the Module File
    2. BuildManifest
      1. This task is similar to the BuildModule but uses the AST to collect function names from each file and then adds them to the Module Manifest
  3. C-Sharp PowerShell Modules
    1. BuildProject
      1. This task uses dotnet build to compile the code into a DLL
    2. CopyModuleFiles
      1. This task copies the DLL and associated files from the project into the Output folder

Build

Invoke-psake Build

This task will build/compile the code and place it in the Output folder. It depends on the LocalUse task and additionally calls the PesterTest task to run all the tests. Additionally it uses the TestFile variable for the Nunit output file.

  1. PesterTest
    1. This task runs all Pester tests discovered within the project

Package

Invoke-psake Package

This task depends on the CreateExternalHelp, CreateCabFile and UpdateReadme tasks. It updates the help documentation and the CAB files for the online-help of the module. Finally it updates the README file.

  1. CreateExternalHelp
    1. This task uses PlatyPS to update the MD files from the imported module
  2. CreateCabFile
    1. This task uses PLatyPS to compile the External help and package it into a CAB
  3. UpdateReadme
    1. This task sets up the table at the top of the README with links to the Releases, PowerShell Gallery, Issues, License and Discord

Deploy

Invoke-psake Deploy

This task deploys the module to the PowerShell Gallery if our current branch is the branch defined as the DeployBranch in the psakefile, after it publishes the module it creates a Tagged Release and posts a message on Discord. This task depends on CheckBranch, PublishModule, NewTaggedRelease and Post2Discord tasks.

  1. CheckBranch
    1. This task determines the current branch and checks it against the DeployBranch variable
  2. PublishModule
    1. This task publishes the code to the PowerShell Gallery
  3. NewTaggedRelease
    1. This task creates a tag based on the module version, then pushes it and creates a relase from that tag
  4. Post2Discord
    1. THis task posts a message to a Discor Channel