Resources/psake.ps1
# Copyright: (c) 2018, Jordan Borean (@jborean93) <jborean93@gmail.com> # MIT License (see LICENSE or https://opensource.org/licenses/MIT) [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "", Justification="Global vars are used outside of where they are declared")] param() # PSake makes variables declared here available in other scriptblocks Properties { # load the module's private functions again, they are not available in # psake by default Get-ChildItem -Path $ps_ansible_tester_root\Private\*.ps1 -ErrorAction SilentlyContinue | ` ForEach-Object { . $_.FullName } $lines = '----------------------------------------------------------------------' # populated when called with Invoke-psake $role_metadata = $metadata $role_name = $metadata.name $role_version = $metadata.version $role_path = $path $role_bash_path = Get-BashPath -Path $path $role_test_path = Join-Path -Path $role_path -ChildPath tests $role_test_bash_path = Get-BashPath -Path $role_test_path $role_inventory_bash_path = "$role_test_bash_path/$($metadata.inventory)" $virtual_environments = $venvs $inventory_path = Join-Path -Path $role_test_path -ChildPath inventory.ini # use the first venv when running Ansible commands (non playbook) $venv_source_cmd = "source `"$($virtual_environments[0])/bin/activate`"" } Task Default -Depends Test Task Setup { Write-ConsoleOutput -Message $lines if ($PSVersionTable.PSVersion -ge [Version]"6.0") { $platform_os = $PSVersionTable.OS } else { $win32_os = Get-CimInstance -ClassName Win32_OperatingSystem -Property Version $platform_os = "Microsoft Windows $($win32_os.Version)" } $startup_msg = @" SETUP: Starting role tester pipeline Role Name: $role_name Role Path: $role_path Role Version: $role_version Ansible Versions: $($metadata.ansible_versions -join ", ") Platform: $($metadata.ci_platform) OS: $platform_os Date: $(Get-Date -Format s) "@ Write-ConsoleOutput -Message $startup_msg $requirements_path = Join-Path -Path $role_test_path -ChildPath requirements.yml if (Test-Path -Path $requirements_path) { Write-ConsoleOutput -Message "`n`tSETUP: '$requirements_path` exists, installing roles with ansible-galaxy" $galaxy_rc = Invoke-Bash -Arguments "$venv_source_cmd; ansible-galaxy install -r `"$role_test_bash_path/requirements.yml`" -p `"$role_test_bash_path/roles`"" if ($galaxy_rc -ne 0) { Write-Error -Message "ansible-galaxy install failed to install role dependencies, rc: $galaxy_rc" } } Write-ConsoleOutput -Message "`n" } Task Sanity -Depends Setup { Write-ConsoleOutput -Message $lines Write-ConsoleOutput -Message "`n`tSANITY: Running ansible-lint for role at '$role_path'" $lint_rc = Invoke-Bash -Arguments "$venv_source_cmd; ansible-lint `"$role_bash_path`"" if ($lint_rc -ne 0) { Write-Error -Message "ansible-lint `"$role_bash_path`" failed, rc: $lint_rc" } Write-ConsoleOutput -Message "`n" } Task Test -Depends Sanity { Write-ConsoleOutput -Message $lines foreach ($venv in $virtual_environments) { $test_playbook = Join-Path -Path $role_test_path -ChildPath main.yml Write-ConsoleOutput -Message "`n`tTEST: Running '$test_playbook' on $venv in check mode" Invoke-AnsiblePlaybook -Inventory $role_inventory_bash_path ` -Playbook "$role_test_bash_path/main.yml" ` -VirtualEnvPath $venv ` -Verbosity $role_metadata.verbosity ` -CheckMode Write-ConsoleOutput -Message "`n`tTEST: Running '$test_playbook' on $venv" Invoke-AnsiblePlaybook -Inventory $role_inventory_bash_path ` -Playbook "$role_test_bash_path/main.yml" ` -VirtualEnvPath $venv ` -Verbosity $role_metadata.verbosity $cleanup_playbook = Join-Path -Path $role_test_path -ChildPath cleanup.yml if (Test-Path -Path $cleanup_playbook) { Write-ConsoleOutput -Message "`n`tTEST: Running '$cleanup_playbook' on $venv after completing testing" Invoke-AnsiblePlaybook -Inventory $role_inventory_bash_path ` -Playbook "$role_test_bash_path/cleanup.yml" ` -VirtualEnvPath $venv ` -Verbosity $role_metadata.verbosity } } Write-ConsoleOutput -Message "`n" } Function Write-ConsoleOutput { param ( [Parameter(Mandatory=$true)][String]$Message ) if ($null -ne $host.UI) { $host.UI.WriteLine($Message) } } Function Get-BashPath { param ( [Parameter(Mandatory=$true)][String]$Path ) # bash_bin_path is specific for Cygwin, WSL's conversion exe should be # on the PATH env var and is set to $null $get_bash_path.Invoke($Path, $bash_bin_path) } Function Invoke-Bash { param ( [Parameter(Mandatory=$true)][String]$Arguments ) # the bash shell to use is dynamic and based on the environment/metadata # the invoke_bash_func and bash_exe are defined when calling Invoke-psake # and use the chosen bash shell for this run $invoke_bash_func.Invoke($bash_exe, $Arguments) } Function Invoke-AnsiblePlaybook { param ( [Parameter(Mandatory=$true)][String]$Inventory, [Parameter(Mandatory=$true)][String]$Playbook, [Parameter(Mandatory=$true)][String]$VirtualEnvPath, [Int]$Verbosity = 3, [Switch]$CheckMode ) $venv_source = "source `"$VirtualEnvPath/bin/activate`"" $command = "ansible-playbook -i `"$Inventory`" `"$Playbook`" -$('v' * $Verbosity)" if ($CheckMode) { $command += " --check" } $rc = Invoke-Bash -Arguments "$venv_source; $command" if ($rc -ne 0) { Write-Error -Message "$venv_source; $command failed with rc: $rc" } } |