web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Microsoft Dynamics 365 | Integration, Dataverse...
New Discussion

Hint: Apply portal skinning via SCSS and automatic pipeline-based compile and upload to Dynamics

(0) ShareShare
ReportReport
Posted on by

The "Challege": For skinning Dynamics Portal / Power Portal we wanted to use SCSS to take advantage of all the nice features of SCSS compared to CSS. However this does not fit well to the way MS allows to manage / edit files using point&click.

The "Solution":

During development: Set up any web IDE (JetBrains, ...), utilizing built-in scss compiler. Automatically upload this to any publicly accessible location (ftp server, any location outside dataverse) for sake of quicker turnaround times.

Release: 

Store all required scss source files in GIT repoin Azure DevOps. In our case, we have only one main "style.scss" in the root folder of the repo, utilizing a lot of modular scss files in subfolders.

Via ADO Pipeline, upon checkin (and push) this file is SCSS compiled via node module and, this is the tricky part, via PowerShell magic, added as "annotation" (aka "Note") to the corresponding "adx_webfile" with the same name we initially created manually on the target site.

In a nutshell, what the PS commands to:

  • Obtain access token via configured Service Credential (so the pipeline yaml does not need to store userid/password or token)
  • Compile assets and, for later reference, check back into GIT and tag
  • Fetch the GUID of the underlying adx_webfile by name
  • Wrap this into a entityreference
  • Upload a new "annotation", using the configured filename and Base64 encoded content of the file, and link it to the adx_webfile

The way Microsoft designed the storage of binary content of web files this will cause the new content to be accessible via the provided partial URL.

Voila!

As sharing is caring, maybe someone wants to use that as starting point for setting up a less point-and-click development cycle... ;-)

Have fun!

trigger:
- main

pool:
  vmImage: windows-latest

steps:
- task: NodeTool@0
  inputs:
    versionSpec: '10.x'
  displayName: 'Install Node.js'
- task: PowerPlatformSetConnectionVariables@2
  inputs:
    authenticationType: 'PowerPlatformSPN'
    PowerPlatformSPN: 'FOOBAR.crm4.dynamics.com'
    Environment: 'https://FOOBAR.crm4.dynamics.com/'
  name: connectionVariables
  displayName: Set Output Variables
  continueOnError: false
- powershell: Install-Module Microsoft.Xrm.Data.Powershell -Scope CurrentUser -Force
  displayName: 'Install Microsoft.Xrm.Data.PowerShell'
- powershell: |
    npm install -g sass
    git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" fetch --all
    git checkout main
    git branch
    md build -ea 0
    sass style.scss  --style compressed >build/FOOBAR.min.css
    git config user.email "devops@FOOBAR.com"
    git config user.name "Automatic Build"
    git add build/*
    git commit -m "Automatic Build $(Build.BuildNumber)"
    git tag $(build.buildNumber)
    echo push commit
    git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push origin main --tags
    $Cred=Get-CrmConnection -ConnectionString "AuthType=ClientSecret;url=https://FOOBAR.crm4.dynamics.com/;ClientId=$(connectionVariables.BuildTools.ApplicationId);ClientSecret=$(connectionVariables.BuildTools.ClientSecret)"
    cd build
    $filename="FOOBAR.min.css"
    $adx_webfile=(Get-CrmRecords -conn $Cred -EntityLogicalName adx_webfile -FilterAttribute adx_name -FilterOperator eq -FilterValue "$filename").CrmRecords[0].adx_webfileid
    $adx_webfileref=[Microsoft.Xrm.Sdk.EntityReference]::new("adx_webfile",$adx_webfile)
    New-CrmRecord -conn $Cred -EntityLogicalName annotation -Fields @{"filename"=$filename;"documentbody"=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((Get-Content $filename)));"objectid"=$adx_webfileref}
  displayName: 'SASS'

PS: Remember to replace FOOBAR with something more reasonable!

PPS: As we decided to pass this configuration via normal release process from environment to environment, above process is updating the CSS only on the Dev environment. A content release process then picks all assets up and moves to Test - and finally to Prod.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Meet the Microsoft Dynamics 365 Contact Center Champions

We are thrilled to have these Champions in our Community!

Congratulations to the March Top 10 Community Leaders

These are the community rock stars!

Leaderboard > Microsoft Dynamics 365 | Integration, Dataverse, and general topics

#1
11manish Profile Picture

11manish 172

#2
ManoVerse Profile Picture

ManoVerse 58 Super User 2026 Season 1

#3
Niki Patel Profile Picture

Niki Patel 42

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans