<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oleg Sucharevich</title>
    <description>The latest articles on DEV Community by Oleg Sucharevich (@olegsu).</description>
    <link>https://dev.to/olegsu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F188648%2F80c11f34-9399-413f-a7a4-8a042bdcbfc0.jpeg</url>
      <title>DEV Community: Oleg Sucharevich</title>
      <link>https://dev.to/olegsu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olegsu"/>
    <language>en</language>
    <item>
      <title>Sync RSS feed to Trello</title>
      <dc:creator>Oleg Sucharevich</dc:creator>
      <pubDate>Fri, 08 May 2020 13:58:07 +0000</pubDate>
      <link>https://dev.to/olegsu/sync-rss-feed-to-trello-595i</link>
      <guid>https://dev.to/olegsu/sync-rss-feed-to-trello-595i</guid>
      <description>&lt;p&gt;From &lt;a href="http://www.whatisrss.com/"&gt;whatisrss.com&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;RSS is a format for delivering regularly changing web content. Many news-related sites, weblogs, and other online publishers syndicate their content as an RSS Feed to whoever wants it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/olegsu/rss-sync"&gt;rss-sync&lt;/a&gt;, is an application I just published that lets you to sync your favorite RSS feeds into your Trello board.&lt;br&gt;
I use it to sync podcast RSS feeds into my Trello list. So each morning I see what podcast I need to listen to catch up. Using the &lt;a href="https://github.com/olegsu/rss-sync"&gt;rss-sync&lt;/a&gt; you can customize the card will be created, based on the information from the RSS feed.&lt;/p&gt;

&lt;h1&gt;
  
  
  The why
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;It is fun&lt;/li&gt;
&lt;li&gt;I love automation - read my previous &lt;a href="https://dev.to/olegsu/continuous-automation-with-open-integration-4f5a"&gt;post&lt;/a&gt; about productivity&lt;/li&gt;
&lt;li&gt;Zapier and other tools are too expensive :-)&lt;/li&gt;
&lt;li&gt;It is fun, really.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  The use-case
&lt;/h1&gt;

&lt;p&gt;I use RSS feeds to subscribe to podcasts. Of course, I don't manually check the RSS. I tried so many apps over the last two years. Finally, I decided to stay with Spotify. The main reasons were that it has an integration with Google Home, there are mobile and desktop applications, I already use Spotify to listen to music. The only downside in Spotify is that they are not allowed to add manually RSS. It must be done through Spotify platform. I have a few podcasts that are password-protected, which means that to get the RSS I need to "log-in". In the end, I decided that I will not stop using Spotify. I need to get the notifications about the podcasts into one place. All my tasks are managed in one Trello board, both my personal and my professional life on the same board. I decided that once a podcast has an update, I want to get a new ticket into the board and set it in the right list, condition-based.&lt;/p&gt;

&lt;h1&gt;
  
  
  Example
&lt;/h1&gt;

&lt;p&gt;In this example, we will sync the podcast show &lt;a href="https://www.iheart.com/podcast/105-stuff-you-should-know-26940277/"&gt;Stuff You Should Know&lt;/a&gt; and will create a new Trello card for each show that was published in the last 24 hours.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hGKMJDBn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/olegsu/blogs/blob/master/Sync-RSS-To-Trello/imgs/example.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hGKMJDBn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/olegsu/blogs/blob/master/Sync-RSS-To-Trello/imgs/example.png%3Fraw%3Dtrue" alt="example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download the binary from &lt;a href="https://github.com/olegsu/rss-sync/releases"&gt;Github&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Trello credentials - you need to get Key and API token from Trello. Go to Trello &lt;a href="https://trello.com/app-key"&gt;Developer API Keys&lt;/a&gt;. You can find immediately the Key, the token should be generated, follow the steps to generate it.&lt;/li&gt;
&lt;li&gt;Trello board data

&lt;ul&gt;
&lt;li&gt;Board ID - The board ID is part of the URL when you logged in (&lt;code&gt;https://trello.com/b/BOARD_ID/BOARD_NAME&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;List-ID - use the Trello API to get a JSON about your board, inside that you can find the List ID (&lt;code&gt;https://trello.com/b/{BOARD_ID}.json&lt;/code&gt;). &lt;/li&gt;
&lt;li&gt;Labels IDS - Similar to List-ID, but harder to find :-( (not required)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;RSS feed file - copy the content into &lt;code&gt;feed.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stuffyoushouldknow&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stuffyoushouldknow&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;This Week List&lt;/span&gt;

&lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;This Week List&lt;/span&gt;
    &lt;span class="na"&gt;trello&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;env.Getenv&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"TRELLO_TOKEN"&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;env.Getenv&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"TRELLO_KEY"&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
      &lt;span class="na"&gt;board-id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;env.Getenv&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"TRELLO_BOARD_ID"&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
      &lt;span class="na"&gt;list-id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;env.Getenv&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"TRELLO_LIST_ID"&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
      &lt;span class="na"&gt;card&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.source.name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}]&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Listen&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.item.title&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.feed.title&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Link:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.item.link&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Description:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.item.description&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

&lt;span class="na"&gt;sources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stuffyoushouldknow&lt;/span&gt;
  &lt;span class="na"&gt;res&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://feeds.megaphone.fm/stuffyoushouldknow&lt;/span&gt;
  &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;just-released&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;((time.Now).Add&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(time.Hour&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-24)).Before&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(time.Parse&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2006-01-02T15:04:05Z"&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;.item.publishedParsed)&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  The tech
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Using open-integration - read my previous &lt;a href="https://dev.to/olegsu/continuous-automation-with-open-integration-4f5a"&gt;post&lt;/a&gt; about it. What is the architecture, what are the usec-case a more.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;feed.yaml&lt;/code&gt; is composition of:

&lt;ul&gt;
&lt;li&gt;Sources&lt;/li&gt;
&lt;li&gt;Targets&lt;/li&gt;
&lt;li&gt;Bindings&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Golang template engine is used here to template the credentials and other values that cannot be published. It uses &lt;a href=""&gt;gomplate&lt;/a&gt; to extand the functionality of the basic tempalte library&lt;/li&gt;
&lt;li&gt;Additional datasources that are injected into the template language are:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;{{ .item }}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{ .source }}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{ .target }}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{ .binding }}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{ .feed }}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;It seems to me as a nice-to-have tool. Of course, it cannot replace for most of you the automation system like Zapier. I see a few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tools like Zapier are SAAS platform, you pay the price and you don't need to manage anything.&lt;/li&gt;
&lt;li&gt;Tools like Zapier will trigger this flow automatically without you running it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Disclosure: I work &lt;a class="comment-mentioned-user" href="https://dev.to/codefresh"&gt;@codefresh&lt;/a&gt;
.&lt;br&gt;
I use &lt;a href="https://codefresh.io/"&gt;Codefresh&lt;/a&gt;, which originally is a CI/CD platform for Kubernetes. Codefresh has a free plan with 1 concurrent pipeline, some limitations on the CPU and memory spec, and the most important, unlimited executions per month. To run the rss-sync, it more than enough. I use the &lt;a href="https://codefresh.io/docs/docs/configure-ci-cd-pipeline/triggers/cron-triggers/"&gt;Cron&lt;/a&gt; based trigger of Codefresh to run this process once a day to catch up on all my stuff. &lt;/p&gt;

</description>
      <category>productivity</category>
      <category>go</category>
      <category>podcast</category>
    </item>
    <item>
      <title>Continuous Automation with Open-Integration</title>
      <dc:creator>Oleg Sucharevich</dc:creator>
      <pubDate>Mon, 23 Mar 2020 18:49:52 +0000</pubDate>
      <link>https://dev.to/olegsu/continuous-automation-with-open-integration-4f5a</link>
      <guid>https://dev.to/olegsu/continuous-automation-with-open-integration-4f5a</guid>
      <description>&lt;p&gt;Open-Integration is a pipeline framework (aka pipeline-as-a-code), where you can create your pipeline, compile and execute it anywhere.  I created it because it helps me to automate some of my daily tasks to increase productivity.&lt;/p&gt;

&lt;p&gt;Disclosure: I work &lt;a class="comment-mentioned-user" href="https://dev.to/codefresh"&gt;@codefresh&lt;/a&gt;
, which is building a CI/CD platform with a strong orientation for a containerized application running in a Kubernetes environment. As Codefresh is adopting Golang, I wanted to learn and practice it. I, therefore, decided to write &lt;a href="https://github.com/open-integration/core"&gt;open-integration&lt;/a&gt; using Golang. My state of mind is all about automating anything that does not require my intervention, both at work and in my personal life.&lt;/p&gt;

&lt;p&gt;A couple of weeks ago, I was listening to a podcast (in Hebrew), where the guest in the show &lt;a href="https://barav.co/another-hour/"&gt;described&lt;/a&gt; how he is saving an hour each day, consolidating all the tasks into one place and continuously prioritizing it.&lt;/p&gt;

&lt;p&gt;TLDR: He is using &lt;a href="https://trello.com/"&gt;Trello&lt;/a&gt; with 4 lists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backlog - where he holds all the stuff that should be prioritized.&lt;/li&gt;
&lt;li&gt;Tomorrow - the plan for tomorrow.&lt;/li&gt;
&lt;li&gt;Today - the plan for today (prioritized).&lt;/li&gt;
&lt;li&gt;Done - what is done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The guest in the show said that he is checking the email inboxes and other channels every few hours to add new tasks to the Trello board, updating the relevant board, prioritizing it (if needed) and focusing on the prioritized list, ignoring all the channels until the next sync. For me it sounds great, to consolidate all the tasks into one place, both for my personal life and my professional career, so I gave it a try.&lt;/p&gt;

&lt;p&gt;I have made some changes that better worked for my workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I renamed the &lt;code&gt;Tomorrow&lt;/code&gt; to &lt;code&gt;This week&lt;/code&gt; list.&lt;/li&gt;
&lt;li&gt;I created labels with tags &lt;code&gt;Codefresh&lt;/code&gt;, &lt;code&gt;Personal Life&lt;/code&gt;, etc, to make sure I can group relevant cards.&lt;/li&gt;
&lt;li&gt;In the “Backlog” list, each card holds a checklist with the relevant tasks, each item will be converted into a single card when I move to “This Week” with the relevant labels.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Very quickly I noticed that there were too many cards in the &lt;code&gt;Done&lt;/code&gt; list and I wanted to remove them, but also to keep that data for my next retrospective. I wanted to automate the following flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update cards in Google spreadsheet&lt;/li&gt;
&lt;li&gt;add the card as a new row in case it is a new one&lt;/li&gt;
&lt;li&gt;update “update-at”, “labels”, “status” and other columns for cards that moved between lists&lt;/li&gt;
&lt;li&gt;Archive all cards in the “Done” list to keep the board clean.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I started to look for a solution that can archive them and also store them into my Google spreadsheet. This way I can come back to it in my next annual review to check exactly what was done in my professional life but also, to do some kind of personal retrospective.&lt;/p&gt;

&lt;p&gt;There are many tools out there that I tried: &lt;a href="https://zapier.com/"&gt;Zapier&lt;/a&gt;, &lt;a href="https://ifttt.com/"&gt;IFTTT&lt;/a&gt;, &lt;a href="https://automate.io/"&gt;automate.io&lt;/a&gt;, &lt;a href="https://www.integromat.com/"&gt;integromat&lt;/a&gt;, &lt;a href="https://flow.microsoft.com/en-us/"&gt;Microsoft flows&lt;/a&gt;. Some of them worked pretty well, some didn’t match my requirements, some were a bit expensive. I decided that a good side project to work on would be an open-source pipeline execution engine that can do the simple tasks that I wanted to automate in my life for so long.&lt;/p&gt;

&lt;p&gt;After this quick overview, which explained what was the motivation for me, and which tools I have checked, let’s dive into the Open-Integration project. The Open-Integration project is a pipeline framework, and it allows you to create pipeline-as-code. It is written in Golang. I took that approach of pipeline-as-code because of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have way too many configuration files today (tons of yamls,tomls, and jsons are everywhere!)&lt;/li&gt;
&lt;li&gt;Test and debug! I was missing this ability everywhere, as a developer, I am trying to cover my code with tests, there is no reason for me to not do the same with my automated flows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Example
&lt;/h1&gt;

&lt;p&gt;Lets create our first pipeline (requires go 1.11 and above):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://asciinema.org/a/312592"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L4MBIwth--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://asciinema.org/a/312592.svg" alt="asciicast"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First let's install &lt;code&gt;oictl&lt;/code&gt;, the command line tool that generates basic pipelines ( for mac you can use Homebrew, otherwise, download the binary from &lt;a href="https://github.com/open-integration/oictl/releases"&gt;Github&lt;/a&gt; )
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;    brew tap open-integration/oictl
    brew &lt;span class="nb"&gt;install &lt;/span&gt;oictl
    &lt;span class="nb"&gt;mkdir &lt;/span&gt;hello-world &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;hello-world
    oictl generate pipeline
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check the generated file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/open-integration/core"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/open-integration/core/pkg/state"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/open-integration/core/pkg/task"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pipe&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pipeline&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PipelineMetadata&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"hello-world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;Spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PipelineSpec&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;As&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="s"&gt;"exec"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;"exec"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;Reactions&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EventReaction&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EventReaction&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Condition&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConditionEngineStarted&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;Reaction&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="n"&gt;buildTaskCommand0&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEngine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EngineOptions&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Pipeline&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleEngineError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;buildTaskCommand0&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Metadata&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"hello-world-command-0-0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;Spec&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Spec&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"exec"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Endpoint&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Arguments&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Argument&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Argument&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;hello-world&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now simply run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;    go run main.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;See the output:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;cat &lt;/span&gt;logs/tasks/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s go over it:&lt;/p&gt;

&lt;p&gt;Concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engine (the &lt;code&gt;open-integration/core&lt;/code&gt; pkg) - the piece to code that is executing the pipeline.&lt;/li&gt;
&lt;li&gt;Event - Indicator that something has changed in the state of the engine, allows us to react to it (&lt;code&gt;EventReaction&lt;/code&gt; section).&lt;/li&gt;
&lt;li&gt;EventReation - A function that gets the current event and copy of the engine’s state, the function returns a set of tasks to be executed.&lt;/li&gt;
&lt;li&gt;Service - A standalone binary, the engine is communicating with it over gRPC, exposing endpoints to run some logical task.&lt;/li&gt;
&lt;li&gt;Task - execution of logical flow, a task is a request to call a service endpoint and pass the arguments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Architecture
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lpc4Bdb3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/open-integration/core/raw/master/docs/architecture.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lpc4Bdb3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/open-integration/core/raw/master/docs/architecture.png" alt="https://github.com/open-integration/core/raw/master/docs/architecture.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xGuHxY8h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/open-integration/core/raw/master/docs/flow-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xGuHxY8h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/open-integration/core/raw/master/docs/flow-diagram.png" alt="https://github.com/open-integration/core/raw/master/docs/flow-diagram.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Use Cases
&lt;/h1&gt;

&lt;p&gt;I have created a few pipelines which I use daily&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/olegsu/trello-sync"&gt;trello-google&lt;/a&gt;: a pipeline that will read my Trello board, update a Google spreadsheet with new, updated, done tasks, and archive the “Done” list - this way I can review the spreadsheet once a while, to understand (using the labels I have put earlier) what has been accomplished, what is staying in the “Backlog” for too long and so on.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/olegsu/jira-sync"&gt;jira-trello&lt;/a&gt;: I really love task management tools, Jira is the one we are using at Codefresh, but I really do not want to sync every time I am mentioned in an issue or an issue I am watching has been updated. This pipeline is executed before I arrive to the office, I request Jira information using JQL (Jira query language), and create cards on my “Today” list with proper labels, so I can start my working day quickly to understand what is the picture, ignoring all the emails Jira is sending.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/open-integration/core-ci-pipeline"&gt;open-integration/core CI&lt;/a&gt; - a pipeline that will use a Kubernetes service to run pods that are sharing a common PVC to clone, test, security scan, compile and release the &lt;code&gt;open-integration/core&lt;/code&gt; repo.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Contribution
&lt;/h1&gt;

&lt;p&gt;Project plan: &lt;a href="https://trello.com/b/BcAwtJXr/open-integration"&gt;Trello board&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open-Integration is an open-source tool, if you find it useful for you, please let me know. If you have any feedback, on the architecture, code, design, this blog post or any other stuff, I would love to talk to you! If you would like to contribute, please feel free to open a PR, the Open-Integration Github organization is made of the following repositories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/open-integration/core"&gt;core&lt;/a&gt;: the pipeline engine, exposing structs and functions to build the pipeline, services, task, etc.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/open-integration/oictl"&gt;oictl&lt;/a&gt;: a command-line tool to generate code for pipeline and services&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/open-integration/service-catalog"&gt;service-catalog&lt;/a&gt;: All the available services&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>opensource</category>
      <category>go</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
