Skip to Content
Technical Articles

Want to sync your IFlows to GitHub? FlashPipe it!

Did you say cpiGit?

One of the most requested feature on the Customer Influence Project for SAP Integration Suite is native Git support for Cloud Integration.

 

While waiting for SAP to provide such capability, this gap has been filled in various manners by the community, largely utilising the public API available to download the integration artifacts from the Cloud Integration tenant.

 

When FlashPipe was in its development phase, I was reluctant to include such functionality in it. It was my conviction that SAP should be delivering such a vital and much-requested functionality, especially in light of the fact that any self-respecting development platform these days would have such functionality natively. Additionally, I didn’t feel the urgency to reinvent the wheel in view of the existing ‘workarounds’ already available.

 

It has been more than a year since the above request was submitted and as time goes by, it is becoming uncertain if this will be delivered despite the huge demand for it from the partner and customer ecosystem.

 

Since the release of FlashPipe, I have revisited my position on this, and I have realised otherwise that I cannot wait any longer, and it is time to take it into my own hands. Coincidentally, whilst working on the GitHub platform, I also realised that such a functionality is a “low-hanging fruit” (since most of the functions required for it is already available in FlashPipe), but the benefits are aplenty.

 

All you need is love… FlashPipe!

I am happy to announce that since release 2.1.0, FlashPipe now supports syncing of Integration Flows from a Cloud Integration tenant to a Git repository.

In particular, if you are already using GitHub, you can get it up and running in a ⚡flash⚡(pardon the pun!)

 

Once you get the GitHub Actions workflow in place, you can run the workflow, and let FlashPipe do the heavy lifting for you – download the content from the tenant, compare it against the repository, and commit any differences.

 

 

 

Voila, and it’s done ✅!

 

Look mom, no tools to install!

Even if you do not use FlashPipe for deployment of your IFlows, it can come in handy to back up your precious IFlow development work to GitHub. And you can even schedule it on a periodic basis and have the peace of mind that your work is always safe! And all this is achieved without requiring any additional tool or programs to be installed on your local computer.

 

If you haven’t tried FlashPipe, head over to its documentation page and try it for yourself. The following page provides you the steps to get started.

Sync IFlows to GitHub with FlashPipe on GitHub Actions

 

Psst.. FlashPipe is open-source

Oh, and did I mention…. FlashPipe is open-source and licensed under Apache 2.0, so you don’t have to worry about giving it a go!

 

13 Comments
You must be Logged on to comment or reply to a post.
  • Thanks a lot for this wonderful blog.

     

    I tried to replicate but at Sync step getting 401 error.

     

    Client ID,  Client Secret  and environmental variables seems to be correct.

     

    nv:
    HOST_TMN: abc.it-cpitrial02.cfapps.eu10-001.hana.ondemand.com
    HOST_OAUTH: abc.authentication.eu10.hana.ondemand.com
    OAUTH_CLIENTID: ${{ secrets.DEV_CLIENT_ID }}
    OAUTH_CLIENTSECRET: ${{ secrets.DEV_CLIENT_SECRET }}

     

    [INFO] Using Basic Authentication for https://abc.authentication.eu10.hana.ondemand.com:443
    [INFO] Using OAuth 2.0 Authentication for https://abc.it-cpitrial02.cfapps.eu10-001.hana.ondemand.com:443
    [INFO] Getting artifacts in integration package PackageForTransportDemo
    
    [ERROR]  Response body = 
    Exception in thread "main" io.github.engswee.flashpipe.http.HTTPExecuterException: Get designtime artifacts of IntegrationPackages call failed with response code = 401
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    	at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
    	at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:77)
    	at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:84)
    	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
    	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:238)
    	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:250)
    	at io.github.engswee.flashpipe.http.HTTPExecuter.logError(HTTPExecuter.groovy:40)
    	at io.github.engswee.flashpipe.http.HTTPExecuter$logError$0.call(Unknown Source)
    	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
    	at io.github.engswee.flashpipe.cpi.api.IntegrationPackage.getIFlowsWithDraftState(IntegrationPackage.groovy:49)
    	at io.github.engswee.flashpipe.cpi.api.IntegrationPackage$getIFlowsWithDraftState.call(Unknown Source)
    	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
    	at io.github.engswee.flashpipe.cpi.exec.DownloadIntegrationPackageContent.execute(DownloadIntegrationPackageContent.groovy:48)
    	at io.github.engswee.flashpipe.cpi.exec.DownloadIntegrationPackageContent$execute.call(Unknown Source)
    	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
    	at io.github.engswee.flashpipe.cpi.exec.DownloadIntegrationPackageContent.main(DownloadIntegrationPackageContent.groovy:20)
    Error:   Execution of java command failed
    Error: Process completed with exit code 1.

     

  • I truly believe this will be a pivotal monent in de SAP Integration timeline! Thanks for developing this, can’t wait to get my hands dirty with this!

        • Good to hear that, Rob. About syncing to Azure Git Repo, I haven't tried that myself but I would think it would be possible.

          Why don't you give it a try? For GitHub Actions, there is an action available that does the "push to Git", so you'll have to find if there is an available task in Azure to do the same, or if not use the command line.

          • Hi Eng, indeed had to use the command line. I had some issues (mainly because this is the first time I create a pipeline) but got it working 😉 thanks for the great tool!

  • /