<?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>Forem: Elad Chen</title>
    <description>The latest articles on Forem by Elad Chen (@eladchen).</description>
    <link>https://forem.com/eladchen</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%2F29483%2F0342f5ce-be46-436c-a8cf-0ef43a0f2210.jpeg</url>
      <title>Forem: Elad Chen</title>
      <link>https://forem.com/eladchen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/eladchen"/>
    <language>en</language>
    <item>
      <title>Atomic Release: An all-or-nothing strategy to release code.</title>
      <dc:creator>Elad Chen</dc:creator>
      <pubDate>Mon, 01 Nov 2021 17:25:30 +0000</pubDate>
      <link>https://forem.com/eladchen/atomic-release-an-all-or-nothing-strategy-to-release-code-540d</link>
      <guid>https://forem.com/eladchen/atomic-release-an-all-or-nothing-strategy-to-release-code-540d</guid>
      <description>&lt;p&gt;Have you ever encountered a failure during a release process?&lt;br&gt;
Did you have to "undo" steps taken before starting again?&lt;br&gt;
If the answer to the above questions is yes, then keep reading.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;br&gt;
A release process usually involves a series of automatic steps that must be performed to complete successfully, but what happens when a step fails?&lt;/p&gt;

&lt;p&gt;If you want to start the release process with a clean slate&lt;br&gt;
you have to determine which steps succeeded and "undo" whatever action they took… 😖&lt;/p&gt;

&lt;p&gt;In other words, automated releases are rarely written to handle a failure, which means they leave a mess behind when a step fails halfway through.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I8KPzfW6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ap7tJ7FMUu3B7muy3pbNLqQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I8KPzfW6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ap7tJ7FMUu3B7muy3pbNLqQ.gif" alt="solution" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The solution&lt;/strong&gt;&lt;br&gt;
Realising the above problem, I figured it can be solved&lt;br&gt;
using the "Command" design pattern, and so atomic-release came into existence.&lt;/p&gt;

&lt;p&gt;Today I'm happy to announce the first release of atomic-release&lt;br&gt;
an NPM package that aims to help create automated releases using the command pattern.&lt;/p&gt;

&lt;p&gt;The package is more of an SDK than a general-purpose solution, it has 2 core concepts and a reference implementation for releasing NPM packages.&lt;/p&gt;

&lt;p&gt;Highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript friendly.&lt;/li&gt;
&lt;li&gt;APIs are loosely coupled. Use just what you need.&lt;/li&gt;
&lt;li&gt;Can be used to automate the release of any project type.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Core concept #1 - "Strategy"
&lt;/h2&gt;

&lt;p&gt;An abstract class that decides whether a release should be made, and&lt;br&gt;
the commands to execute during a release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core concept #2 - "Command"
&lt;/h2&gt;

&lt;p&gt;An abstract class with two methods, "do" which performs an action, and "undo" which undoes actions taken by the "do" method.&lt;/p&gt;

&lt;p&gt;There are several pre-written commands available in the SDK.&lt;br&gt;
See the commands docs for more details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can also write your own commands! Here are a few random ideas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Slack&lt;/strong&gt;: A command that notifies a slack channel of a successful release.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Jira&lt;/strong&gt;: A command that comments on issues mentioned in the commits included in the release.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;… Anything you can think of&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;GithubNpmPackageStrategy&lt;/em&gt;&lt;br&gt;
This strategy was created to illustrate an implementation of the SDK.&lt;/p&gt;

&lt;p&gt;The strategy automates the release process end-to-end, it uses conventional commits to bump semantic versions, and generate change-logs.&lt;/p&gt;

&lt;p&gt;Here's a demo showcasing a failure during a release and the undo taken:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mKhIMxak--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AbxpNSdn7OflgbjVsTLeMeg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mKhIMxak--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AbxpNSdn7OflgbjVsTLeMeg.gif" alt="demo" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://github.com/abstracter-io/atomic-release/blob/main/docs/strategies/github-npm-package-strategy.md"&gt;GithubNpmPackageStrategy&lt;/a&gt; for more details.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fun fact:&lt;br&gt;
The package itself is released using GithubNpmPackageStrategy 🤯&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;If you are interested in learning more, head over to the official repository.&lt;/p&gt;

&lt;p&gt;As always, If you have any questions or feedback, please leave a comment below.&lt;/p&gt;

</description>
      <category>semanticversion</category>
      <category>javascript</category>
      <category>automation</category>
      <category>versionmanagement</category>
    </item>
    <item>
      <title>Protecting your Github workflows</title>
      <dc:creator>Elad Chen</dc:creator>
      <pubDate>Fri, 09 Oct 2020 14:47:02 +0000</pubDate>
      <link>https://forem.com/eladchen/protecting-your-github-workflows-lhe</link>
      <guid>https://forem.com/eladchen/protecting-your-github-workflows-lhe</guid>
      <description>&lt;p&gt;Have you ever tried to reveal a secret value stored in your continuous integration/delivery service? No? Well, maybe &lt;br&gt;
someone else did.&lt;/p&gt;



&lt;p&gt;Automation (or "CI") services… We are all using them, or at least should be they are the standard these days, and yet they are rarely given the attention they need.&lt;/p&gt;


&lt;h4&gt;
  
  
  Chapter One: Question Everything
&lt;/h4&gt;

&lt;p&gt;I recently decided to use &lt;a href="https://docs.github.com/en/actions" rel="noopener noreferrer"&gt;Github Actions&lt;/a&gt; to build, test, and release one of my Node.js open source projects, so I did what every developer would, I read the documentation and ran a few experiments, and soon after that, I realized that I'll have to store the NPM registry token as a secret to automate the release process.&lt;/p&gt;

&lt;p&gt;Whenever I hear the word "secret" the following questions pop into my head:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What will happen if the secret is revealed? Can it be revealed?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Automation services are nothing new - I've worked for several companies throughout my career, and there was always some automation&lt;br&gt;
service being used - point is, most secrets I've encountered in those automation services always gave me the chills because deep inside of me I knew if I can (and I could) turn them into plain text so does someone with malicious intents.&lt;/p&gt;


&lt;h4&gt;
  
  
  Chapter Two: The Quest For Answers
&lt;/h4&gt;

&lt;p&gt;A quick search of my questions came up with a two very interesting read-ups and I recommend reading them, they describe the inherent vulnerability automation services introduce, and why they are a prime candidate when it comes to bug bounty programs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nathandavison.com/blog/shaking-secrets-out-of-circleci-builds" rel="noopener noreferrer"&gt;Shaking secrets out of CircleCI builds&lt;/a&gt; (&lt;strong&gt;I highly recommend reading this&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://edoverflow.com/2019/ci-knew-there-would-be-bugs-here/" rel="noopener noreferrer"&gt;CI Knew There Would Be Bugs Here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;
  
  
  Chapter Three: Making The World A Safer Place
&lt;/h4&gt;

&lt;p&gt;Typically automation services are set up to act on any change happening throughout a codebase - whenever a change is pushed, a revision of the change will be fetched and executed.&lt;/p&gt;

&lt;p&gt;Automation services (unlike me), do not have trust issues, especially when it comes to open source projects, because now, instead of trusting a limited number of actors, they trust any actor. 🤯&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe1kr6yy85dd5dyq2vti5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe1kr6yy85dd5dyq2vti5.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we discuss the solution, let's discuss the possible changes a malicious actor can do in a codebase - A Node.js project for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a malicious module to the package.json dependencies&lt;/li&gt;
&lt;li&gt;Modifying your workflows (.github/workflows/** ) to reveal secrets&lt;/li&gt;
&lt;li&gt;Changing scripts that may be used during the build phase&lt;/li&gt;
&lt;li&gt;…?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above risks are relevant to any automation service and project type, not just Github Actions + Node.js project.&lt;br&gt;
… Scary stuff if you ask me 🙀&lt;/p&gt;



&lt;p&gt;So what can we expect from Github Actions? Not much.&lt;br&gt;
The only thing worth mentioning is workflows that are triggered by a pull request will not have access to the original repository secrets.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The above is only partially true. Read the following announcement:&lt;br&gt;
&lt;a href="https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/" rel="noopener noreferrer"&gt;GitHub Actions improvements for fork and pull request workflows&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wouldn't it be nice if workflow runs could be monitored and even canceled under specific conditions? Actually, that is possible!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The solution&lt;/strong&gt;: &lt;a href="https://github.com/apps/protected-workflows" rel="noopener noreferrer"&gt;Protected Workflows&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Protected Workflows is a &lt;a href="https://github.com/apps/protected-workflows" rel="noopener noreferrer"&gt;Github Application&lt;/a&gt;&lt;br&gt;
and is designed to cancel workflow runs by enforcing rules you configure, you can for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specify user names who are allowed to trigger workflow runs&lt;/li&gt;
&lt;li&gt;Specify file paths that may be changed&lt;/li&gt;
&lt;li&gt;Specify paths that may not be changed (globs are supported as well)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is an example of how a config file may look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Fallback rule in case nothing specific is set.&lt;/span&gt;
&lt;span class="na"&gt;anyEvent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;trustOrgMembers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
 &lt;span class="na"&gt;trustCollaborators&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;basic_rule&lt;/span&gt;
      &lt;span class="na"&gt;trustAnyone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;disallowed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/**"&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;package.json"&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;package-lock.json"&lt;/span&gt;

  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;*basic_rule&lt;/span&gt;
  &lt;span class="na"&gt;pull_request_target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;*basic_rule&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above config is using anchors, which is a useful YAML feature that enables re-using certain text blocks, and has a single rule defined ("basic_rule") used by events "push", "pull_request" and "pull_request_target".&lt;/p&gt;

&lt;p&gt;The shared rule simply trusts any actor and will cancel workflow runs&lt;br&gt;
in case certain paths were changed during the contextual event.&lt;/p&gt;

&lt;p&gt;Its a wrap!&lt;/p&gt;

&lt;p&gt;If you are interested in learning more, head over to the official &lt;a href="https://github.com/eladchen/protected-workflows" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for taking the time to read this article! 🤓&lt;br&gt;
If you have any questions or feedback, please leave a comment below.&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>security</category>
      <category>ci</category>
      <category>cd</category>
    </item>
  </channel>
</rss>
