John Liu .NET

View Original

Save all your Flows to VSTS via HTTP REST in 8 actions

I saw VSTS has "Send an HTTP Request to VSTS" a few days ago, and a quick test had me pulling back repo information in JSON.

 

My brother visited me on Sunday afternoon, after having Australian BBQ and playing Monster Hunter World, I sent him back via the train station.  On the way, I mentioned to him that Flow has VSTS connector now.  He joked that "Ah so now you can finally check your Flows into a proper source control".

Well... about that.
See...  I believe Flow can do anything.  So as I was pulling into my garage I've got some ideas to try in my head.

Plan

  • The magic of "Send HTTP Request to System" connectors
  • VSTS REST API
  • How to send all our Flow definitions into VSTS

"Send HTTP Request to System" Connectors

I'm a big fan of "Send HTTP Request to System" type of Connectors.  First we saw that with SharePoint - allowing a pre-authenticated action to call any REST API on SharePoint.

Now we see it on VSTS.

How about MSGraph next? :-)  Pretty please.  For delegate access.

VSTS REST API

The VSTS REST API are documented here: 
https://docs.microsoft.com/en-us/rest/api/vsts/?view=vsts-rest-5.0

In particular, v5 is in v5-preview
To perform a "push" via REST, we need the last Commit ID, then a POST Push JSON.

https://docs.microsoft.com/en-us/rest/api/vsts/git/commits?view=vsts-rest-5.0
https://docs.microsoft.com/en-us/rest/api/vsts/git/pushes/create?view=vsts-rest-5.0#add_a_text_file 

How we do it in Flow

The 'trigger' could be anything - a manual button, or a recurrence trigger.
Get all My Flows and loop through them.

To GIT PUSH - we need to have the last Commit Id, so perform a get commits and take the last one.
Then use Compose to pull the commitId from the result JSON.

NOTE - this will fail if you have never commit to the repo.  So just go to that repo and init by commit the README.md manually first.

List My Flows action outside of the For Each doesn't actually return Flow Definition.  So inside the For Each, call Get Flow again with the Flow Name.

Next we compose the GIT PUSH body json.  It needs oldObjectId we got from GIT Commits earlier.  And we are either "add" or "edit" files.  I use the Flow Name.json to be the file name - that is a GUID.  My reasoning is that guids don't change, display names do.  So guid would keep better history.  You may decide display names are better filenames.

Cast the flow.properties.definition (JSON) into a String, and set that as "content" of the PUSH body.

Call VSTS REST again with POST pushes

Trigger the Flow first time and we'll need to check and grant permissions to the two connectors.  They both run as me.  Auth is Easy and is Done. ;-)

Run Success!

Run it - success!
Note because the PUSH has to run one after another - the commit must be re-fetched per PUSH.  We can build more complex POST body and have it commit every Flow in one PUSH.

Flow Definition JSON usually is one big long line.  Make sure you do Format Document if you want a human to read it.

Summary

Take regular backups of your Flows.  And then use VSTS's change history to see what changed!

Some may be brave enough to try take Flow definitions from VSTS and patch them into live Flows.  Please tell me if that works well :-O