Monday, July 25, 2016

Node.js / Gulp - SP Sync using Powershell from Visual Studio TaskRunner

One of the key thing during the SP development is to establish the flow of developing, unit testing and deploying to an environment. This can be achieved with the combination of dev tools (Visual studio , VSCode etc), Powershell, MSBuild, Gulp,  and other plugins. In this post, we will see how to invoke a powershell script from gulp to sync all the SharePoint project manifest files to a local environment (SP2016 on premises). 

Referenced:

SP Sync using Powershell from Visual Studio TaskRunner :

  • Create the Powershell script to sync all the elements file
$webclient = New-Object System.Web.Client
$url = "http://ift.tt/1vvCJX8"
 
$headers = @{accept = "application/json; odata=verbose"}
$formDigest = $null
 
function SetFormDigest() {
    $response = PostRequest ("/_api/contextinfo") 
    $formDigest = $response.d.GetContextWebInformation.FormDigestValue
    $headers.Add("X-RequestDigest", $formDigest);
    
}
 
function Request ($endpoint, $body, $method) {
    return Invoke-RestMethod -Uri ($url+$endpoint) -Headers $headers -Method $method -Body $body -UseDefaultCredentials -ContentType "application/json;odata=verbose"
}
 
function GetRequest ($endpoint, $body) {
    return Request $endpoint $body ([Microsoft.PowerShell.Commands.WebRequestMethod]::Get)
}
 
function PostRequest ($endpoint, $body) {
    return Request $endpoint $body ([Microsoft.PowerShell.Commands.WebRequestMethod]::Post)
}
 
 
function CheckOutFile($spFolderPath, $spFileName)
{
    try
    {
        $response = PostRequest ("/_api/web/getFileByServerRelativeURL('"  + $spFolderPath + "/" + $spFileName + "')/checkout()") (ConvertTo-Json @{})
    }
    catch{}
}
 
function UploadFile($spFolderPath, $localFilePath) {
    Write-Host "Uploading File : " + $localFilePath + "to the SP Folder : " + $spFolderPath
    $fileInfo = New-Object System.IO.FileInfo($localFilePath);
    $fileContent = [System.IO.File]::ReadAllBytes($fileInfo.FullName);
 
    CheckOutFile $spFolderPath $fileInfo.Name
    $response = PostRequest ("/_api/web/getFolderByServerRelativeURL('" + $folderPath + "')/files/add(url='" + $fileInfo.Name + "',overwrite=true)") ($fileContent);
}
 
SetFormDigest
 
$rootdirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
 
Get-ChildItem "$rootdirectory\\..\\*\\*" -Filter elements.xml -ErrorAction Ignore |
ForEach-Object {
    [Xml]$elementManifest = Get-Content $_.FullName;
    foreach($file in $elementManifest.Elements.Module.File){
        if($elementManifest.Elements.Module.Url){
            $folderPath = $elementManifest.Elements.Module.Url;
        }
        else {
            $folderPath = $file.Url.Substring(0,$file.Url.LastIndexOf('/'));
 
        }
 
        UploadFile $folderPath ("$rootdirectory\..\" + $file.Path)
    }
}

 

  • Create a task within the Gulp file to invoke the powershell as a shell command.

gulp.task('SPSync', function (done) {
var exec = require('child_process').exec;
exec("PowerShell.exe -Command \"& {& " + __dirname.replace(/ /g, "` ") + "'\\deploy\\spsync.ps1'}\"",
function (err, stdout, stderr) { 
console.log(stdout); 
done(err);
}); 
});

  • The above gulp task calls the custom powershell script within the folder "deploy" relative to the gulpfile.js as mentioned below.

  • Run the SPSync task from the task runner.

  • All the files mentioned in the elements.xml will get synced to the specified site within the spsync.ps1.

This allows us to extend / customise the gulp SPSync task easily. Recently we started using TDD using Intern (JS unit testing framework) and extended our spsync to compile TS, execute Unit test and sync the manifest files to the local environment.

Note: Since we are executing the .ps1 from the VS task runner, the PS cannot have the 64 bit commands.

There is a gulp npm module spsavespsync to sync the files, but the gulp / ps hybrid gives us a bit of more control over the process for the developers using the powershell. 


by Balamurugan Kailasam via Everyone's Blog Posts - SharePoint Community

No comments:

Post a Comment