Setup automation for Windows and macOS
At the beginning of the chapter, I proclaimed anything that can be expressed as a CLI command can also be automated. Throughout the setup process, we have ensured that every tool being used was set up and its functionality was verifiable through a CLI command. This means we can easily create a PowerShell or bash script to string these commands together and ease the task of setting up and verifying new environments.
Let's implement rudimentary but effective scripts to help set up your development environment.
PowerShell script
For Windows-based development environments, you need to create a PowerShell script.
- Create a file named
setup-windows-dev-env.ps1
- Insert the following text, also available at https://github.com/duluca/web-dev-environment-setup, in the file:
setup-windows-dev-env.ps1 # This script is intentionally kept simple to demonstrate basic automation techniques. Write-Output "You must run this script in an elevated command shell, using 'Run as Administrator'" $title = "Setup Web Development Environment" $message = "Select the appropriate option to continue (Absolutely NO WARRANTIES or GUARANTEES are provided):" $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Install Software using Chocolatey", ` "Setup development environment." $no = New-Object System.Management.Automation.Host.ChoiceDescription "&Exit", ` "Do not execute script." $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) $result = $host.ui.PromptForChoice($title, $message, $options, 1) switch ($result) { 0 { Write-Output "Installing chocolatey" Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) Write-Output "Refreshing environment variables. If rest of the script fails, restart elevated shell and rerun script." $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") Write-Output "Assuming chocolatey is already installed" Write-Output "Installing Git & GitHub Desktop" choco.exe upgrade git github-desktop -y Write-Output "Installing NodeJS and NVS" choco.exe upgrade nodejs-lts nvs -y Write-Output "Installing Docker" choco.exe upgrade docker docker-for-windows -y Write-Output "Installing AWS" choco.exe upgrade awscli -y Write-Output "Installing VS Code" choco.exe upgrade VisualStudioCode -y RefreshEnv.cmd Write-Output "Results:" Write-Output "Verify installation of AWS, Docker, GitHub Desktop and VS Code manually." $gitVersion = git.exe --version Write-Output "git: $gitVersion" $nodeVersion = node.exe -v Write-Output "Node: $nodeVersion" $npmVersion = npm.cmd -v Write-Output "npm: $npmVersion" } 1 { "Aborted." } }
- To execute the script, run:
PS> Set-ExecutionPolicy Unrestricted; .\setup-windows-dev-env.ps1
Alternatively, you can install and execute the script directly from the PowerShell Gallery, located at https://www.powershellgallery.com, by executing the following command:
PS> Install-Script -Name setup-windows-dev-env
PS> setup-windows-dev-env.ps1
By executing this script, you have successfully set up your development environment on Windows.
If you're interested in publishing your own scripts to the PowerShell Gallery or generally interested in advancing your PowerShell skills, I suggest you install PowerShell Core, a multi-platform version of PowerShell. from https://github.com/PowerShell/PowerShell.
Now, let's look into how you can achieve a similar setup on Mac.
Bash script
For Mac-based development environments, you need to create a bash script.
- Create a file named
setup-mac-dev-env.sh
- Run
chmod a+x setup-mac-dev-env.sh
to make the file executable - Insert the following text, also available at https://github.com/duluca/web-dev-environment-setup, in the file:
setup-mac-dev-env.sh #!/bin/bash echo "Execute Installation Script" read -r -p "Absolutely NO WARRANTIES or GUARANTEES are provided. Are you sure you want to continue? [y/N] " response if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]] then echo "Installing brew" /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" echo "Installing git" brew install git brew upgrade git echo "Installing GitHub Desktop" brew cask install github brew cask upgrade github echo "Installing NodeJS" brew install node@12 brew upgrade node@12 echo "Installing Docker" brew cask install docker brew cask upgrade docker echo "Installing AWS" brew install awscli brew upgrade awscli echo "Installing VS Code" brew cask install visual-studio-code brew cask upgrade visual-studio-code echo "Results:" echo "Verify installation of AWS, Docker, GitHub Desktop and VS Code manually." gitVersion=$(git --version) echo "git: $gitVersion" nodeVersion=$(node -v) echo "Node: $nodeVersion" npmVersion=$(npm -v) echo "npm: $npmVersion" else echo "Aborted." fi
- To execute the script, run:
$ ./setup-mac-dev-env.sh
By executing this script, you have successfully set up your development environment on Mac. Here is an example of a more sophisticated install and verify routine, where you can check to see if a particular program, like brew
or node
, is already installed, before attempting to install them:
echo "Checking if brew is installed"
which -s brew
if [[ $? != 0 ]] ; then
echo "Installing brew"
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null
else
echo "Found brew"
fi
echo "Checking for Node version ${NODE_VERSION}"
node -v | grep ${NODE_VERSION}
if [[ $? != 0 ]] ; then
echo "Installing Node version ${NODE_VERSION}"
brew install nodejs
else
echo "Found Node version ${NODE_VERSION}"
fi
Now, you have a pretty good idea of what it looks like to automate the execution of your scripts. The harsh reality is that these scripts do not represent a very capable or resilient solution. Scripts can't be executed or managed remotely, and they can't quickly recover from errors or survive machine boot cycles. Besides, your IT requirements may be above and beyond what is covered here.
If you deal with large teams and have a frequent turnover of staff, an automation tool pays dividends handsomely, whereas if you're on your own or part of a smaller, stable team, it is overkill. I encourage you to explore tools such as Puppet, Chef, Ansible, and Vagrant to help you decide which one best fits your needs or whether a simple script is just good enough.