Automating deployment of a Hugo website to Github Pages using powershell scripts
Overview
The following article describes how this blog is automatically deployed. The technology stack for this blog is:
- Source content written within the Hugo framework (a static website generator written in the Go language.
- Hosted by GitHub Pages, directly from this repository which contains the website build (the source code is in a separate repository).
- Cloudflare for cached content delivery (along with many other things).
If the technology stack for your project is completely different, this article should still provide you with:
- Inspiration for how you could automate your production workflow, and
- Some useful Powershell scripting tips.
The Code
Because of the simplicity of this static website, I do not have separate development and production deployments, so after I have written an article or edited the template and previewed it using hugo server
, the website is pushed straight into production.
The production automation script comprises three files:
config.json
: stores secret keys. Remember to add it to.gitignore
!publish.ps1
: imports secret keys and passes them as parameters when calling the main script.build_commit_push_clear_cache.ps1
: builds the website, uploads to server (in this case, via a git commit to GitHub), clears Cloudflare content delivery cache.
config.json
{
'production_build_directory': 'PATH//TO//PRODUCTION//BUILD//DIRECTORY',
'CloudflareAdminEmail': 'YOUR_CLOUDFLARE_ADMIN_EMAIL',
'CloudflareApiKey': 'YOUR_CLOUDFLARE_API_KEY',
'CloudflareZoneId': 'YOUR_CLOUDFLARE_ZONE_ID'
}
Note the double backslashes \\
in the production_build_directory
path. The first backslash is an escape character used by the Powershell ConvertFrom-Json
parser.
publish.ps1
# Import configurations and secret keys from config.json
$config = Get-Content -Raw -Path .\scripts\config.json | ConvertFrom-Json
# Pass the configurations and secret keys as arguments into the script that does the actual work:
### **`./scripts/build_commit_push_clear_cache.ps1`**
-production_build_directory $config.production_build_directory `
-CloudflareAdminEmail $config.CloudflareAdminEmail `
-CloudflareApiKey $config.CloudflareApiKey `
-CloudflareZoneId $config.CloudflareZoneId
Note that the production_build_directory
is a separate git repository to the Hugo source code, in order to comply with Github Pages hosting requirements.
The real work is done by build_commit_push_clear_cache.ps1
:
build_commit_push_clear_cache.ps1
Param(
[parameter(Mandatory=$true)]
[string] $production_build_directory,
[parameter(Mandatory=$true)]
[string] $AdminEmail,
[parameter(Mandatory=$true)]
[string] $ApiKey,
[parameter(Mandatory=$true)]
[string] $ZoneId
);
# Build the website
Read-Host -Prompt ("Initializing production build. This will delete all files in " `
+ $production_build_directory `
+ ". Press any key to continue, or ctrl+c to abort")
hugo --cleanDestinationDir `
--destination $production_build_directory
# Upload the website
Read-Host -prompt ("Initializing git commit and push for all files in " `
+ $production_build_directory `
+ ". Press any key to continue or ctrl+c to abort")
git -C $production_build_directory add *
git -C $production_build_directory status
$git_commit_message = Read-Host ("Enter a short commit message, or ctrl+c to abort")
git -C $production_build_directory checkout master
git -C $production_build_directory commit -a -m $git_commit_message
git -C $production_build_directory push
# Clear the Cloudflare cache
<# Credit to [Niels Swimberghe]
(https://swimburger.net/blog/powershell/powershell-snippet-clearing-cloudflare-cache-with-cloudflares-api) #>
Read-Host -Prompt "About to clear the Cloudflare cache. Press any key to continue, or ctrl+c to abort"
$PurgeCacheUri = "https://api.cloudflare.com/client/v4/zones/$ZoneId/purge_cache";
$RequestHeader = @{
'X-Auth-Email' = $AdminEmail
'X-Auth-Key' = $ApiKey
};
$RequestBody = '{"purge_everything":true}';
Invoke-RestMethod `
-Uri $PurgeCacheUri `
-Method Delete `
-ContentType "application/json" `
-Headers $requestHeader `
-Body $RequestBody
Notes
Read-Host -Prompt
statements are used to inform the user of impending actions and provide a chance to abort. It is also used to set the Git commit message. Important if there is a chance that a script will be re-used in a setting where{number_of_users} > 1
, or if a less-technical client will be using it – UX is not just for front-end design!git -C <path>
runs commands as if git was started in the directory instead of the current working directory.- Backticks
`
are used to split single commands over multiple lines for readability. - Credit to Niels Swimberghe for sharing his Powershell script for clearing the Cloudflare cache via the Cloudflare API.