The previous post discussed an alternative to using Azure Devops to build and release this Jekyll blog. It covered building it locally and using Azure Storage Explorer to copy new and updated file to the sites Blob Storage. Each upload provides a copy of the az command performed suggesting scripting of this. This post covers a script that does just that.

When a new post is authored and the site is built the updates to the _site content is:

  • Root index.html
  • cats and tags folders
  • The built html file for the blog post in a folder named by the post’s category

The following script could be improved by working with a diff file (later).

The following script:

  • (Optionally) build the Jekyll site
  • (Optionally) uploads the updated root index.html [ONLY]
  • If a category is named (-c) (Typically the new pots’s category)
    • (By default) root index.htmr is uploaded
    • (By default) updated cats folder is uploaded
    • (By default) updated tags folder is uploaded
    • The named category folder is uploaded of it exists.

    Example of use:

    scripts/buildjekyl  -B -C powershell -T
    
    • Build
    • copy _site\powershell folder etc
    • Don’t copy tags folder

File: scripts/buildjekyl.ps1

param(
    [switch]$B,    # Build Jekyll
    [switch]$I,    # Copy index.html
    [switch]$II,   # Not Copy index.html if $C is set
    [string]$C,    # Built blog post's category Copy all
    [switch]$N,    # NoOverwrite of existing files
    [switch]$K,    # Don't do cat folder
    [switch]$T,     # Don't do tags folder
    [string]$FF,    # Single file to copy File Foldername only
    [string]$FN     # Single file to copy File Filename only

)

Write-Host "Build B: $B, Category Folder C: $C, N: $N , Copy cats folder K: $K, Copy tags folder TT: $T, II: $II, File: $FN, Folder: $FF"
#y Note need to esacpe the $ in the $web variable with a tick!
$target =  "`$web/$C"
write-host "C Target: $target"



$OVERWRITEFILES = "--overwrite"

if ($N) {
    $OVERWRITEFILES = ""
}

if ($B) {
    Write-Host "Building Jekyll"
	bundle exec jekyll build
}

$accountname =  "blobstorageaccountname"
$accountkey = "accountkey=="
$source = "_site"

if($FF)
{
    if($FN)
    {
        $fsource = "$source\$FF\$FN"
        $target = "`$web/$FF"
        # Just do one file
        Write-Host "Uploading $fsource file to Azure Blob Storage at $target"
        az storage blob upload --file $fsource --container-name $target --account-name $accountname  --account-key $accountkey $OVERWRITEFILES --output table
    }
}
else
{
    if($I)
    {
        # Just do index.html
        Write-Host "Uploading blog post root file index.html (ONLY) to Azure Blob Storage"
        az storage blob upload --file $source\index.html --container-name '$web' --account-name $accountname  --account-key $accountkey $OVERWRITEFILES --output table
    }
    else
    {
        if($C)
        {

            if(-not $K)
            {
                write-host "Uploading cat folder to Azure Blob Storage"
                az storage blob upload-batch --source $source\cats --destination '$web/cats' --account-name $accountname --account-key $accountkey   $OVERWRITEFILES --output table
            }
            if(-not $T)
            {   
                write-host "Uploading tags folder to Azure Blob Storage"
                az storage blob upload-batch --source $source\tags --destination '$web/tags' --account-name $accountname --account-key $accountkey   $OVERWRITEFILES --output table
            }
            if(-not $II)
            {
                Write-Host "Uploading blog post root index.html to Azure Blob Storage"
                az storage blob upload --file $source\index.html --container-name '$web' --account-name $accountname  --account-key $accountkey $OVERWRITEFILES --output table
            }
            if (Test-Path -Path $source\$C ) {
                write-Host "Uploading posts $C folder to Azure Blob Storage"
                az storage blob upload-batch --source $source\$C --destination $target --account-name $accountname --account-key $accountkey   $OVERWRITEFILES --output table
            } else {
                Write-Host "The folder  $C does not exist."
            }
        }
    }
}


Note that boolean parameters if not on command line default to false, true if named.


## Examples

 # Examples of usage:
# NB: root index.html is copied to the $web container for each
# Just build
# .\scripts\buildjekyl.ps1 -B 
# Just build and upload blob(category) folder as well an index.html, cats and tags folder
# .\scripts\buildjekyl.ps1 -B -C "blog" 
# Just build and upload blob(category) folder. Use if just updating a blob in the category folder
# .\scripts\buildjekyl.ps1 -B -C "blog"  -K -T -II
# Just uploadindex.html
# .\scripts\buildjekyl.ps1 -I
# Just build and upload cats and tags folders: -C param folder doesn't exist
# .\scripts\buildjekyl.ps1 -B -C "none" 
# Update the images folder after adding or updating an image, after building the site
# .\scripts\buildjekyl.ps1 -B -C "images"  -K -T -II
##############################################################################
# Just copy one specific file to the $web container into a sub older
# .\scripts/\uildjekyl  -FF 'pix' -FN 'cdndone.png'
# Uploading _site\pix\cdndone.png file to Azure Blob Storage at $web/pix

Escaping the $ in $web, the target Blob Storage Container.

Note in the line

$target =  "`$web/$C"

A tick is need to escape the dollar symbol character


## Conclusion

This script solves my issue of not being able to release the built site from Azure Devops to Azure Blob Storage. Still using Devops as the repository though. Unlike the Devops path, it does afford only selectively uploading changed or new content, speeding up deployment significantly as the previous method copied the whole site.

## 2Dos

  • In the -C folder only copy last modified/new folder.
  • Use a Diff file to determine what to copy.
  • Images and other similar conetnt hasn’t been handled yet.
    • Can be handled post build though with scripts/buildjekyl -C images -II -T -K
      • Where _site/images has the site’s images
      • But if only adding one image file it is a bit of overkill as all files in the folder are copied/overwritten.
  • If just updating an existing post use:
    scripts/buildjekyl -B -C web -K -T -II
    • Where _site/web contains the updated post
      • i.e. it’s category is web
    • Doesn’t copy meta-info files

Footnote: A Sample run

PS C:\Folders\Source\repos\BlogSite\DJzBlog> scripts/buildjekyl  -B -C powershell

BUILD
-----
Build B: True, Category Folder C: powershell, N: False , Copy cats folder K: False, Copy tags folder TT: False, II: False
Target: $web/powershell
Building Jekyll
C:/Ruby34-x64/lib/ruby/gems/3.4.0/gems/jekyll-4.4.1/lib/jekyll.rb:26: warning: logger was loaded from the standard library, but will no longer be part of the default gems starting from Ruby 3.5.0.
You can add logger to your Gemfile or gemspec to silence this warning.
Configuration file: C:/Folders/Source/repos/BlogSite/DJzBlog/_config.yml
            Source: C:/Folders/Source/repos/BlogSite/DJzBlog
       Destination: C:/Folders/Source/repos/BlogSite/DJzBlog/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
==== Create a catpage for any cat without a page.====
==== Create a tagpage for any tag without a page.====
                    done in 312.251 seconds.

Uploading cat folder to Azure Blob Storage
Finished[#############################################################]  100.0000%

CATS
====
Blob                                                                               Last Modified              Type       ETag
---------------------------------------------------------------------------------  -------------------------  ---------  -------------------
https://STORGAENAME.blob.core.windows.net/%24web/cats/index.html             2025-03-28T06:22:36+00:00  text/html  "0x8DD6DC0EF1C6E3C"
https://STORGAENAME.blob.core.windows.net/%24web/cats/about/index.html       2025-03-28T06:22:37+00:00  text/html  "0x8DD6DC0EF346F0F"
https://STORGAENAME.blob.core.windows.net/%24web/cats/aged/index.html        2025-03-28T06:22:37+00:00  text/html  "0x8DD6DC0EF4BAD76"



https://STORGAENAME.blob.core.windows.net/%24web/cats/twilio/index.html      2025-03-28T06:22:42+00:00  text/html  "0x8DD6DC0F277FEF4"
https://STORGAENAME.blob.core.windows.net/%24web/cats/web/index.html         2025-03-28T06:22:42+00:00  text/html  "0x8DD6DC0F28FFFD7"
https://STORGAENAME.blob.core.windows.net/%24web/cats/xam/index.html         2025-03-28T06:22:42+00:00  text/html  "0x8DD6DC0F2A9D367"
Uploading tags folder to Azure Blob Storage
Finished[#############################################################]  100.0000%

TAGS
====
Blob                                                                                                 Last Modified              Type       ETag
---------------------------------------------------------------------------------------------------  -------------------------  ---------  -------------------
https://STORGAENAME.blob.core.windows.net/%24web/tags/74hc165/index.html                       2025-03-28T06:23:02+00:00  text/html  "0x8DD6DC0FE740706"
https://STORGAENAME.blob.core.windows.net/%24web/tags/actuator/index.html                      2025-03-28T06:23:02+00:00  text/html  "0x8DD6DC0FEA08A41"
https://STORGAENAME.blob.core.windows.net/%24web/tags/aged-care/index.html                     2025-03-28T06:23:03+00:00  text/html  "0x8DD6DC0FEB8B205"
https://STORGAENAME.blob.core.windows.net/%24web/tags/yaml/index.html                          2025-03-28T06:23:42+00:00  text/html  "0x8DD6DC116142059"
https://STORGAENAME.blob.core.windows.net/%24web/tags/youtube/index.html                       2025-03-28T06:23:42+00:00  text/html  "0x8DD6DC1162CE3B3"
https://STORGAENAME.blob.core.windows.net/%24web/tags/zipfile/index.html                       2025-03-28T06:23:43+00:00  text/html  "0x8DD6DC116D0A8C5"
Uploading blog post root index.html to Azure Blob Storage
Finished[#############################################################]  100.0000%
24web/tags/zipfile/index.html                       2025-03-28T06:23:43+00:00  text/html  "0x8DD6DC116D0A8C5"
Uploading blog post root index.html to Azure Blob Storage
Finished[#############################################################]  100.0000%
Client_request_id                     Content_md5               Date                       LastModified               Request_id                      Uploading blog post root index.html to Azure Blob Storage
Finished[#############################################################]  100.0000%
Client_request_id                     Content_md5               Date                       LastModified               Request_id                            Request_server_encrypted    Version
------------------------------------  ------------------------  -------------------------  -------------------------  ------------------------------------  --------------------------  ----------
00000000-0000-0000-0000-000000000  QASDFG12344cvtg5Q==  2025-03-28T06:24:05+00:00  2025-03-28T06:24:05+00:00  00000000-0000-0000-0000-000000000   True                        2022-11-02

Uploading posts powershell folder to Azure Blob Storage
Finished[#############################################################]  100.0000%e-azure.html"[]  100.0000%

BlOG POST
=========
Blob                                                                                                                                                        Last Modified              Type       ETag
----------------------------------------------------------------------------------------------------------------------------------------------------------  -------------------------  ---------  -------------------
https://STORGAENAME.blob.core.windows.net/%24web/powershell/Jekyll-Scripts_to_directly_Deploy_built_updates-powershell-jekyll-blobstorage-azure.html  2025-03-28T06:24:29+00:00  text/html  "0x8DD6DC1325730D4"

😄 😄 😄 😄 😄

Further Footnote

A version of the script that can clean the target and and copy the whole site, like the DevOps route would be useful.


 TopicSubtopic
  Next: > Blockly
   
 This Category Links 
Category:Web Sites Index:Web Sites
  Next: > Jekyll
<  Prev:   Azure Devops