Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Microsoft is giving away 50,000 FREE Microsoft Certification exam vouchers. Get Fabric certified for FREE! Learn more

Reply
MartinMason
Resolver I
Resolver I

Update from Git - Azure Devops Pipeline

I'm trying to construct an Azure Devops pipeline to orchestrate our deployment process. One of the first steps I need to accomplish is to update our Development workspace from Git. I was thinking it could be done by calling the updateFromGit Fabric REST API method. Unfortunately, while I believe I have an YAML script that works, that method will not work with Service Principals. Has anyone actually gotten something like this to work? Seems to me, this is an enormously huge miss in Microsoft's CI/CD strategy with Fabric.

 

- powershell: |
    $body = @{
      client_id = "$(PBI_CLIENT_ID)"
      scope = "https://api.fabric.microsoft.com/.default"
      client_secret = "$(PBI_CLIENT_SECRET)"
      grant_type = "client_credentials"
    }
    $response = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$(PBI_TENANT_ID)/oauth2/v2.0/token" -Method Post -ContentType "application/x-www-form-urlencoded" -Body $body
    $token = $response.access_token
    $headers = @{
      Authorization = "Bearer $token"
      "Content-Type" = "application/json"
    }
    $body = @{
      remoteCommitHash = "$(GIT_COMMIT_HASH)"
      conflictResolution = @{
        conflictResolutionType = "Workspace"
        conflictResolutionPolicy = "PreferWorkspace"
      }
      options = @{
        allowOverrideItems = $true
      }
    }
    Invoke-RestMethod -Uri "https://api.fabric.microsoft.com/v1/workspaces/$(PBI_WORKSPACE_ID)/git/updateFromGit" -Method Post -Headers $headers -Body ($body | ConvertTo-Json -Compress)
  displayName: 'Update Power BI Workspace from Git'
1 ACCEPTED SOLUTION
hackcrr
Super User
Super User

Hi, @MartinMason 

Update your pipeline's PowerShell script to use the PAT instead of trying to authenticate via Service Principal.

- powershell: |
    $pat = "$(PAT)"  # Your PAT stored securely in Azure DevOps
    $headers = @{
      Authorization = "Bearer $pat"
      "Content-Type" = "application/json"
    }
    $body = @{
      remoteCommitHash = "$(GIT_COMMIT_HASH)"
      conflictResolution = @{
        conflictResolutionType = "Workspace"
        conflictResolutionPolicy = "PreferWorkspace"
      }
      options = @{
        allowOverrideItems = $true
      }
    }
    Invoke-RestMethod -Uri "https://api.fabric.microsoft.com/v1/workspaces/$(PBI_WORKSPACE_ID)/git/updateFromGit" -Method Post -Headers $headers -Body ($body | ConvertTo-Json -Compress)
  displayName: 'Update Power BI Workspace from Git'

For now, the PAT approach or interactive user authentication are your best bets to achieve the desired functionality. Both have their pros and cons, but they can enable automated deployments until Microsoft officially supports Service Principal authentication for this endpoint.

 

View solution in original post

8 REPLIES 8
ayushpandey
Frequent Visitor

I am getting the following error when updating fabric workspace using the gitupdate API. In this scenario I have to manually tick the checkbox and continue. Is there any way to automate this processI am getting the following error when updating fabric workspace using the gitupdate API. In this scenario I have to manually tick the checkbox and continue. Is there any way to automate this process

 

 

 

 

 

 

 

 

hski-bayer
New Member

Have a look at https://www.techtacofriday.com/automating-workspace-updates-using-fabric-api/

Hector is describing the different steps there in detail in a recording and also is sharing hin PowerShell script. 

ayushpandey
Frequent Visitor

Hi @MartinMason,

I am trying to create a similar pipeline, can you tell me how to get the value for GIT_COMMIT_HASH variable.

Most of what I'm using, I'm pilfering from this page: 

Automate Git integration by using APIs - Microsoft Fabric | Microsoft Learn

The call to the workspaces/$workspaceId/git/status endpoint will return the remoteCommitHash and the workspaceHead value that need to be included in the body of the call to the workspaces/$workspaceId/git/updateFromGit endpoint. It's a long running operation so it'll return a 202 status code with the operation id that you'll need to check periodically to determine the status. Currently, we have to run it with the credentials of the semantic model/paginated report owner so it's of limited use in a triggered scenario

muhssamy
Resolver I
Resolver I

you can also use Tabular Editor CLI to Deploy your Model using this service Principle Account.

and benefit from Best Practice Analyzer.

 

hackcrr
Super User
Super User

Hi, @MartinMason 

Update your pipeline's PowerShell script to use the PAT instead of trying to authenticate via Service Principal.

- powershell: |
    $pat = "$(PAT)"  # Your PAT stored securely in Azure DevOps
    $headers = @{
      Authorization = "Bearer $pat"
      "Content-Type" = "application/json"
    }
    $body = @{
      remoteCommitHash = "$(GIT_COMMIT_HASH)"
      conflictResolution = @{
        conflictResolutionType = "Workspace"
        conflictResolutionPolicy = "PreferWorkspace"
      }
      options = @{
        allowOverrideItems = $true
      }
    }
    Invoke-RestMethod -Uri "https://api.fabric.microsoft.com/v1/workspaces/$(PBI_WORKSPACE_ID)/git/updateFromGit" -Method Post -Headers $headers -Body ($body | ConvertTo-Json -Compress)
  displayName: 'Update Power BI Workspace from Git'

For now, the PAT approach or interactive user authentication are your best bets to achieve the desired functionality. Both have their pros and cons, but they can enable automated deployments until Microsoft officially supports Service Principal authentication for this endpoint.

 

I guess you're correct. Seems kinda hackish as the PAT variable value would have to be updated before the pipeline is triggered. Interactive user authentication is not possible as 2FA is enabled for everything in our environment.

 

I was hoping to trigger the Azure Devops pipeline upon completion of a pull request to master. However, I guess for now, the pipeline will have to be triggered manually and the Power BI access token configured as a required parameter value upon pipeline execution.

Hi @MartinMason ,
Please check out this link where you can submit the features you would like to have 
https://ideas.fabric.microsoft.com/
Consider submiting your feature request if you think that will be helpful.

If you found @hackcrr's solution helpful please accept their solution so as to help other community members who may face similar issue in the future.

Thanks and regards

Helpful resources

Announcements
Notebook Gallery Carousel1

NEW! Community Notebooks Gallery

Explore and share Fabric Notebooks to boost Power BI insights in the new community notebooks gallery.

April2025 Carousel

Fabric Community Update - April 2025

Find out what's new and trending in the Fabric community.

"); $(".slidesjs-pagination" ).prependTo(".pagination_sec"); $(".slidesjs-pagination" ).append("
"); $(".slidesjs-play.slidesjs-navigation").appendTo(".playpause_sec"); $(".slidesjs-stop.slidesjs-navigation").appendTo(".playpause_sec"); $(".slidesjs-pagination" ).append(""); $(".slidesjs-pagination" ).append(""); } catch(e){ } /* End: This code is added by iTalent as part of iTrack COMPL-455 */ $(".slidesjs-previous.slidesjs-navigation").attr('tabindex', '0'); $(".slidesjs-next.slidesjs-navigation").attr('tabindex', '0'); /* start: This code is added by iTalent as part of iTrack 1859082 */ $('.slidesjs-play.slidesjs-navigation').attr('id','playtitle'); $('.slidesjs-stop.slidesjs-navigation').attr('id','stoptitle'); $('.slidesjs-play.slidesjs-navigation').attr('role','tab'); $('.slidesjs-stop.slidesjs-navigation').attr('role','tab'); $('.slidesjs-play.slidesjs-navigation').attr('aria-describedby','tip1'); $('.slidesjs-stop.slidesjs-navigation').attr('aria-describedby','tip2'); /* End: This code is added by iTalent as part of iTrack 1859082 */ }); $(document).ready(function() { if($("#slides .item").length < 2 ) { /* Fixing Single Slide click issue (commented following code)*/ // $(".item").css("left","0px"); $(".item.slidesjs-slide").attr('style', 'left:0px !important'); $(".slidesjs-stop.slidesjs-navigation").trigger('click'); $(".slidesjs-previous").css("display", "none"); $(".slidesjs-next").css("display", "none"); } var items_length = $(".item.slidesjs-slide").length; $(".slidesjs-pagination-item > button").attr("aria-setsize",items_length); $(".slidesjs-next, .slidesjs-pagination-item button").attr("tabindex","-1"); $(".slidesjs-pagination-item button").attr("role", "tab"); $(".slidesjs-previous").attr("tabindex","-1"); $(".slidesjs-next").attr("aria-hidden","true"); $(".slidesjs-previous").attr("aria-hidden","true"); $(".slidesjs-next").attr("aria-label","Next"); $(".slidesjs-previous").attr("aria-label","Previous"); //$(".slidesjs-stop.slidesjs-navigation").attr("role","button"); //$(".slidesjs-play.slidesjs-navigation").attr("role","button"); $(".slidesjs-pagination").attr("role","tablist").attr("aria-busy","true"); $("li.slidesjs-pagination-item").attr("role","list"); $(".item.slidesjs-slide").attr("tabindex","-1"); $(".item.slidesjs-slide").attr("aria-label","item"); /*$(".slidesjs-stop.slidesjs-navigation").on('click', function() { var itemNumber = parseInt($('.slidesjs-pagination-item > a.active').attr('data-slidesjs-item')); $($('.item.slidesjs-slide')[itemNumber]).find('.c-call-to-action').attr('tabindex', '0'); });*/ $(".slidesjs-stop.slidesjs-navigation, .slidesjs-pagination-item > button").on('click keydown', function() { $.each($('.item.slidesjs-slide'),function(i,el){ $(el).find('.c-call-to-action').attr('tabindex', '-1'); }); var itemNumber = parseInt($('.slidesjs-pagination-item > button.active').attr('data-slidesjs-item')); $($('.item.slidesjs-slide')[itemNumber]).find('.c-call-to-action').attr('tabindex', '0'); }); $(".slidesjs-play.slidesjs-navigation").on('click', function() { $.each($('.item.slidesjs-slide'),function(i,el){ $(el).find('.c-call-to-action').attr('tabindex', '-1'); }); }); $(".slidesjs-pagination-item button").keyup(function(e){ var keyCode = e.keyCode || e.which; if (keyCode == 9) { e.preventDefault(); $(".slidesjs-stop.slidesjs-navigation").trigger('click').blur(); $("button.active").focus(); } }); $(".slidesjs-play").on("click",function (event) { if (event.handleObj.type === "click") { $(".slidesjs-stop").focus(); } else if(event.handleObj.type === "keydown"){ if (event.which === 13 && $(event.target).hasClass("slidesjs-play")) { $(".slidesjs-stop").focus(); } } }); $(".slidesjs-stop").on("click",function (event) { if (event.handleObj.type === "click") { $(".slidesjs-play").focus(); } else if(event.handleObj.type === "keydown"){ if (event.which === 13 && $(event.target).hasClass("slidesjs-stop")) { $(".slidesjs-play").focus(); } } }); $(".slidesjs-pagination-item").keydown(function(e){ switch (e.which){ case 37: //left arrow key $(".slidesjs-previous.slidesjs-navigation").trigger('click'); e.preventDefault(); break; case 39: //right arrow key $(".slidesjs-next.slidesjs-navigation").trigger('click'); e.preventDefault(); break; default: return; } $(".slidesjs-pagination-item button.active").focus(); }); }); // Start This code is added by iTalent as part of iTrack 1859082 $(document).ready(function(){ $("#tip1").attr("aria-hidden","true").addClass("hidden"); $("#tip2").attr("aria-hidden","true").addClass("hidden"); $(".slidesjs-stop.slidesjs-navigation, .slidesjs-play.slidesjs-navigation").attr('title', ''); $("a#playtitle").focus(function(){ $("#tip1").attr("aria-hidden","false").removeClass("hidden"); }); $("a#playtitle").mouseover(function(){ $("#tip1").attr("aria-hidden","false").removeClass("hidden"); }); $("a#playtitle").blur(function(){ $("#tip1").attr("aria-hidden","true").addClass("hidden"); }); $("a#playtitle").mouseleave(function(){ $("#tip1").attr("aria-hidden","true").addClass("hidden"); }); $("a#play").keydown(function(ev){ if (ev.which ==27) { $("#tip1").attr("aria-hidden","true").addClass("hidden"); ev.preventDefault(); return false; } }); $("a#stoptitle").focus(function(){ $("#tip2").attr("aria-hidden","false").removeClass("hidden"); }); $("a#stoptitle").mouseover(function(){ $("#tip2").attr("aria-hidden","false").removeClass("hidden"); }); $("a#stoptitle").blur(function(){ $("#tip2").attr("aria-hidden","true").addClass("hidden"); }); $("a#stoptitle").mouseleave(function(){ $("#tip2").attr("aria-hidden","true").addClass("hidden"); }); $("a#stoptitle").keydown(function(ev){ if (ev.which ==27) { $("#tip2").attr("aria-hidden","true").addClass("hidden"); ev.preventDefault(); return false; } }); }); // End This code is added by iTalent as part of iTrack 1859082
Top Solution Authors
Top Kudoed Authors