Scheduled Windows task that auto-pulls changes from higher Sitecore environment and pushes to Github

It is a common requirement to pull content changes from a higher-environment, commit to a main or master branch. Good if this process can be automated. This blog post provides such code for a scheduled task that checks for new yml files and pushes to github as a new feature branch. Then, a reviewer can merge the feature judiciously to the main branch. Now, the content is in your work flow and most importantly, your content editors won't complain about missing content during your next deployment/site publish in higher environments.


Step-by-step:

1. Perform usual shenanigans of create Repository and add  a basic module.json to main branch:


2. Next, create a PS Script that will be responsible for setting up a windows scheduler task:

#########################################################################

# Trigger

$atStartupeverySixtyMinutesTrigger = New-JobTrigger -once -At $(get-date) -RepetitionInterval $([timespan]::FromMinutes("60")) -RepeatIndefinitely


#beware hard-coded folder name below with script name

$scriptPath = 'C:\pstst\Content_Serialization_PS_Script.PS1'


Register-ScheduledJob -Name SitecoreContentSerializationScheduler -FilePath $scriptPath -Trigger $atStartupeverySixtyMinutesTrigger


########################################################################

3. Execute the PS script to see the task created in the scheduler:


4. Since the task invokes the actual Content_Serialization_PS_Script.PS1 script, here is the script:

#####################################################################

#Requires -RunAsAdministrator

param (

[ValidateNotNullOrEmpty()]

    [string] 

    $RepoName="https://github.com/navancommits/SerializationContent.git",  

    [ValidateNotNullOrEmpty()]

    [string] 

    $WorkingRootDirectory="C:\scs",   

[ValidateNotNullOrEmpty()]

    [string] 

    $WorkingDirectory="\SerializationContent",   


[ValidateNotNullOrEmpty()]

    [string] 

    $CheckoutBranch="main",

[ValidateNotNullOrEmpty()]

    [string] 

    $FeatureBranch="newfeature",

[ValidateNotNullOrEmpty()]

    [string] 

    $IdServerUrl="https://sc103tstijkidentityserver.dev.local",

[ValidateNotNullOrEmpty()]

    [string] 

    $CMServerUrl="https://sc103tstijksc.dev.local"

)


Set-Location $WorkingRootDirectory


$tstamp = Get-Date -Format o | ForEach-Object { $_ -replace ":", "" }


If ([System.Diagnostics.EventLog]::SourceExists('SCSScript') -eq $False) {


New-EventLog -LogName Application -Source 'SCSScript'


}


$RepoDirectory = $WorkingRootDirectory + $WorkingDirectory


if (-not(Test-Path -Path $RepoDirectory))

{

Write-EventLog -LogName Application -EventID 3000 -EntryType Information -Source 'SCSScript' -Message "Cloning repo $RepoName"

#Write-Host "Cloning repo $RepoName"

git clone $RepoName

git fetch origin

Write-Host "Restoring Sitecore CLI..." -ForegroundColor Green

Set-Location $RepoDirectory

    

dotnet tool restore

dotnet new tool-manifest

dotnet tool install Sitecore.CLI --add-source https://nuget.sitecore.com/resources/v3/index.json

dotnet sitecore init

dotnet nuget add source https://www.npmjs.com/ -n sc-packages

dotnet sitecore plugin add -n Sitecore.DevEx.Extensibility.Serialization

dotnet sitecore login --authority $IdServerUrl --cm $CMServerUrl --allow-write true --client-credentials true --client-id "NonInteractiveClient" --client-secret "SUPERLONGSECRETHERE"  

(Get-Content .\sitecore.json).replace('/TODO', '') | Set-Content .\sitecore.json

Write-EventLog -LogName Application -EventID 3000 -EntryType Information -Source 'SCSScript' -Message "First time Interactive login setup complete!"

}


Set-Location $RepoDirectory


git pull


git checkout $CheckoutBranch


Write-EventLog -LogName Application -EventID 3000 -EntryType Information -Source 'SCSScript' -Message "Checkout $CheckoutBranch"


dotnet sitecore ser pull


Write-EventLog -LogName Application -EventID 3000 -EntryType Information -Source 'SCSScript' -Message "Pull latest changes from Sitecore instance "


$status=git status -s


if ($status -ne $null)

{

$timestamp = Get-Date -Format o | ForEach-Object { $_ -replace ":", "" }


$FeatureBranch=$FeatureBranch + $timestamp


#Write-Host "Checking out $FeatureBranch"

Write-EventLog -LogName Application -EventID 3000 -EntryType Information -Source 'SCSScript' -Message "Checking out $FeatureBranch"


git checkout -b $FeatureBranch

#Write-Host "New files detected"

Write-EventLog -LogName Application -EventID 3000 -EntryType Information -Source 'SCSScript' -Message "New files detected but will check-in only yml files"

git add *.yml

$timestamp = Get-Date -Format o | ForEach-Object { $_ -replace ":", "." }

git commit -m "New Files found at $timestamp"

git push --set-upstream origin $FeatureBranch

}


#delete merged branches reference: https://blogs.blackmarble.co.uk/rfennell/tidying-up-local-branches-with-a-git-alias-and-a-powershell-script/


#Write-Host "Process complete!"

Write-EventLog -LogName Application -EventID 3000 -EntryType Information -Source 'SCSScript' -Message "Process complete!"


####################################################################

5. In the above script, ensure to adjust params like git repo name, folder, id server and cm server urls, branch name as per your need

6. Ensure Sitecore ID Server and CM Server accept non-interactive login as per Sitecore documentation.

7. Setup some MySample items in Sitecore and save:


8. Now, either wait for the task to trigger as per schedule or click the Run button in the task scheduler:


9. In a matter of few seconds, you must see the new branch in Github:


Once the branch is merged,  changes should be available for others to pickup from main.

10. Task logging:



Areas to improve: 

1. During the first run, the schemas folder and other artifacts should be manually checked-in for now since the commit filters just yml files.

2. Exception Handling

3. Hard-coded secrets

Scheduling Script

Content Serialization Script

Comments