<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Andrew Zakordonets]]></title><description><![CDATA[Hi, i'm Andrew , an Software Engineer in Test who loves to learn something new in coding and making machines do the routine work instead of me. I'm located in Amsterdam at the moment.]]></description><link>https://biercoff.com/</link><image><url>http://biercoff.com/favicon.png</url><title>Andrew Zakordonets</title><link>https://biercoff.com/</link></image><generator>Ghost 1.25</generator><lastBuildDate>Sun, 12 Apr 2026 23:51:49 GMT</lastBuildDate><atom:link href="https://biercoff.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[How to print nicely in MacOS terminal path with spaces using pwd]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Something that was bothering me in the past - if I would need to copy paste a path in terminal that have spaces, then I would have to escape spaces manually, which is annoying and slow. Thanks to AI I know have this alias:</p>
<pre><code class="language-bash">alias pwd=&quot;printf '%q\</code></pre></div>]]></description><link>https://biercoff.com/how-to-print-nicely-in-macos-terminal-path-with-spaces-using-pwd/</link><guid isPermaLink="false">68e4e1ddd5406b075fcc7d14</guid><category><![CDATA[macosx]]></category><category><![CDATA[pwd]]></category><category><![CDATA[terminal]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Tue, 07 Oct 2025 09:50:32 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Something that was bothering me in the past - if I would need to copy paste a path in terminal that have spaces, then I would have to escape spaces manually, which is annoying and slow. Thanks to AI I know have this alias:</p>
<pre><code class="language-bash">alias pwd=&quot;printf '%q\n' \&quot;$(pwd)\&quot;&quot;
</code></pre>
<p>which does exactly what you need. You can even do <code>ppwd | pbcoy</code> to get that path to your clipboard in one command.</p>
<p>Happy coding :)</p>
</div>]]></content:encoded></item><item><title><![CDATA[Switching to main/master branch easily]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Have you ever had this problem, when trying to do <code>git checkout master</code> and receiving an error that such branch does not exist ? That's because some projects have switched to a new <code>main</code> branch and other projects are too old and nobody is moving them to <code>main</code>. Remembering which project</p></div>]]></description><link>https://biercoff.com/switching-to-main-master-branch-easily/</link><guid isPermaLink="false">64ee52a8d5406b075fcc7c23</guid><category><![CDATA[bash]]></category><category><![CDATA[git]]></category><category><![CDATA[master]]></category><category><![CDATA[main]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Tue, 29 Aug 2023 20:21:17 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Have you ever had this problem, when trying to do <code>git checkout master</code> and receiving an error that such branch does not exist ? That's because some projects have switched to a new <code>main</code> branch and other projects are too old and nobody is moving them to <code>main</code>. Remembering which project is having which type of main branch was too much for me, so I have added following alias to my zsh:</p>
<pre><code class="language-bash">function git_checkout_main_or_master {
    git show-ref --verify --quiet refs/heads/master
    if [ $? -eq 0 ]; then
        git checkout master
    else
        git checkout main
    fi
}
alias m=git_checkout_main_or_master
</code></pre>
<p>And now I just do <code>m</code> in my terminal and git automatically switches me to the right branch.</p>
<p>Hope this helps someone besides me in the future :)</p>
</div>]]></content:encoded></item><item><title><![CDATA[Measuring elapsed time in milliseconds in bash]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I was working on a Telemetry project in my company and I had to instrument some of our bash scripts with code that would measure elapsed time of script execution. You can easily achive this with the following code</p>
<pre><code class="language-bash">calculate_duration() {
    # Start time in nanoseconds
    start_time=$(date +%s%N)</code></pre></div>]]></description><link>https://biercoff.com/measuring-elapsed-time-in-milliseconds-in-bash/</link><guid isPermaLink="false">64e70ec9d5406b075fcc7c15</guid><category><![CDATA[bash]]></category><category><![CDATA[date]]></category><category><![CDATA[elapsedTime]]></category><category><![CDATA[coreutils]]></category><category><![CDATA[gnu]]></category><category><![CDATA[value too great for base]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Thu, 24 Aug 2023 08:09:16 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I was working on a Telemetry project in my company and I had to instrument some of our bash scripts with code that would measure elapsed time of script execution. You can easily achive this with the following code</p>
<pre><code class="language-bash">calculate_duration() {
    # Start time in nanoseconds
    start_time=$(date +%s%N)

    &quot;$@&quot;

    # End time in nanoseconds
    end_time=$(date +%s%N)

    # Calculate duration in nanoseconds
    duration_ns=$((end_time - start_time))

    # Convert duration to milliseconds
    duration_ms=$((duration_ns / 1000000))

    echo &quot;$duration_ms&quot;
}

# Test
time_in_ms=$(calculate_duration sleep 0.5)
echo &quot;Execution time: $time_in_ms ms&quot;
</code></pre>
<p>One thing to keep in mind for this. With different bash versions you can end up with a different behaviour of <code>date</code> utility.<br>
With bash V3 the <code>$(date +%s%N)</code> command will return something like <code>1692824647N:</code> and when you will try to calculate the different you will end up with <code>1692824647N: value too great for base</code> error. In bash V4 this problem is solved, but if you still on bash 3 and you want to overcome this problem then it's better to use <code>/usr/local/gnu/coreutils/bin/date</code> library from GNU coreutils. On a mac you can easily install it with <code>brew</code> :</p>
<pre><code class="language-bash">brew install coreutils
</code></pre>
</div>]]></content:encoded></item><item><title><![CDATA[Cmd+Shift+A ( Find Action ) opens Terminal with some weird error in Intellij product]]></title><description><![CDATA[<div class="kg-card-markdown"><p>As someone who uses <a href="https://jetbrains.com/">Jetbrains</a> products a lot, it can be really annoying when I try to use the &quot;Cmd + Shift + A&quot; shortcut to open the &quot;Find Action&quot; menu and a random terminal window pops up with some gibberish error message. Every time I get a</p></div>]]></description><link>https://biercoff.com/cmd-shift-a-opens-terminal/</link><guid isPermaLink="false">6426d020d5406b075fcc7c05</guid><category><![CDATA[jetbrains]]></category><category><![CDATA[find_action]]></category><category><![CDATA[terminal]]></category><category><![CDATA[shortkut]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Fri, 31 Mar 2023 12:29:00 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>As someone who uses <a href="https://jetbrains.com/">Jetbrains</a> products a lot, it can be really annoying when I try to use the &quot;Cmd + Shift + A&quot; shortcut to open the &quot;Find Action&quot; menu and a random terminal window pops up with some gibberish error message. Every time I get a new laptop, I struggle with this issue and have to Google how to solve it. So, I finally decided to write a blog post for me in the future to faster solve the problem</p>
<p>Basically, the issue is that the <code>Cmd + Shift + A</code> shortcut is assigned to the &quot;Search man Page Index in Terminal&quot; option in Services section of  MacOS Keyboard settings, which conflicts with IntelliJ's &quot;Find Action&quot; menu. To fix this, all you have to do is go to <code>System Preferences</code> -&gt; <code>Keyboard</code> -&gt; <code>Keyboard Shortcuts</code> -&gt; `Services, find &quot;Search man Page Index in Terminal&quot; under the &quot;Text&quot; category, and uncheck the box next to it.</p>
<p><img src="https://biercoff.com/content/images/2023/03/Screenshot-2023-03-31-at-14.27.40.png" alt="Screenshot-2023-03-31-at-14.27.40"></p>
<p>That's it! Your &quot;Cmd + Shift + A&quot; shortcut should now work just fine in IntelliJ products without opening any random terminal windows. So, if you're ever struggling with weird keyboard shortcuts in your applications, always check your keyboard settings first. You never know, it might be a simple fix!</p>
</div>]]></content:encoded></item><item><title><![CDATA[Running Jest tests in parallel in Gitlab with multiple jobs]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I've been working a lot lately with Jest tests. Some projects had 1k+ of Jest unit tests. Another project was using Jest for running integration and E2E tests. In both cases we wanted to get feedback on CI as fast as possible. Our initial solution was following:</p>
<ol>
<li>Split tests into</li></ol></div>]]></description><link>https://biercoff.com/running-jest-tests-in-parallel-in-gitlab-with-multiple-jobs/</link><guid isPermaLink="false">636d4d1bd5406b075fcc7be2</guid><category><![CDATA[gitlab]]></category><category><![CDATA[jest]]></category><category><![CDATA[parallel]]></category><category><![CDATA[ci]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Thu, 10 Nov 2022 19:30:55 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I've been working a lot lately with Jest tests. Some projects had 1k+ of Jest unit tests. Another project was using Jest for running integration and E2E tests. In both cases we wanted to get feedback on CI as fast as possible. Our initial solution was following:</p>
<ol>
<li>Split tests into different folderds</li>
<li>Make sure that there's one Jest <code>spec</code> file per test - this way Jest will run tests in parallel better</li>
<li>Create a series of npm scripts in <code>package.json</code> file</li>
<li>Create a list of similar jobs in <code>.gitlab-ci.yml</code> that trigger different npm scripts</li>
<li>Gather together artifacts from this tests and aggregate a one Test Report.</li>
</ol>
<p>The big problem with this approach is that it's not really scalable. Also, with unit tests it's not always convinient to group them by folders and always check that you have not missed or forgot some folder to inlucde into the test run.</p>
<p>Luckily, one of my colleguas showed me a better approach to this. It appears that Jest has <a href="https://www.npmjs.com/package/@jest/test-sequencer">test-sequencer</a> which can be extended. It allows to split tests into separate groups and assign a list of tests per node. Gitlab has a feature that allows you to run the same job in multiple instances. It's called <a href="https://docs.gitlab.com/ee/ci/jobs/job_control.html#parallelize-large-jobs">parallelization</a></p>
<p>This two factors enabled us to write an easily code that would scale in the future with no manual input fromt he developers. I have prepared a small Gist that gathers all the changes that are required to add to your Jest framework and things should just work faster :)</p>
<script src="https://gist.github.com/azakordonets/7b53c1309403ad2196da4e2d916589f0.js"></script></div>]]></content:encoded></item><item><title><![CDATA[Fixing "The following signatures couldn't be verified because the public key is not available: NO_PUBKEY: %s" error]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I was recently trying to build an old Docker container for one of our projects and I faced this error:</p>
<pre><code>#7 10.88 W: GPG error: http://apt.datad0g.com stable Release: The following signatures couldn't
be verified because the public key is not available: NO_PUBKEY {{key}}
#7 10.</code></pre></div>]]></description><link>https://biercoff.com/fixing-2/</link><guid isPermaLink="false">6310a5cbd5406b075fcc7bd2</guid><category><![CDATA[docker]]></category><category><![CDATA[debian]]></category><category><![CDATA[keyserver]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Thu, 01 Sep 2022 12:33:12 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I was recently trying to build an old Docker container for one of our projects and I faced this error:</p>
<pre><code>#7 10.88 W: GPG error: http://apt.datad0g.com stable Release: The following signatures couldn't
be verified because the public key is not available: NO_PUBKEY {{key}}
#7 10.88 E: The repository 'http://apt.datad0g.com stable Release' is not signed.
</code></pre>
<p>In case you were wondering what is going on like I did, it appers that the apt packaging system has a set of trusted keys that determine whether a package can be authenticated and therefore trusted to be installed on the system. Sometimes the system does not have all the keys it needs and runs into this issue.</p>
<p>Luckily this can be easily fixed by adding</p>
<pre><code>apt-key adv --keyserver keyserver.ubuntu.com --recv-keys {{key}}
</code></pre>
<p>run command to your Dockerfile.</p>
<p>Hope that will help me in the future as well :)</p>
<p>Happy coding.</p>
</div>]]></content:encoded></item><item><title><![CDATA[How to use your crypto.com card with Apple/Google/Samsung pay and get cashback everytime]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I'm a big fan of cashback. I really like how it works in Ukraine with Monobank and I do like the credit card system in US where you can jump from one card to another depending on cashback value. It's like a treasure hunt in a way :) Well, it appears</p></div>]]></description><link>https://biercoff.com/how-to-add-cryptocom-card-to-apple-pay/</link><guid isPermaLink="false">61eb2ed7d5406b075fcc7b90</guid><category><![CDATA[crypto.com]]></category><category><![CDATA[curve]]></category><category><![CDATA[cashback]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Fri, 21 Jan 2022 23:18:31 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I'm a big fan of cashback. I really like how it works in Ukraine with Monobank and I do like the credit card system in US where you can jump from one card to another depending on cashback value. It's like a treasure hunt in a way :) Well, it appears that because of European Bank Regulations, cashbacks are not profitable in Europe and therefore you won't see here much options where you can get an actual cashback. That's why when I discovered <a href="https://crypto.com/">Crypto.com</a> service. They allow you to make a virtual credit card and pay with it for anything you want. If you will stake 350 Euro worth of their own CRO currency, then this card will give you the following bonuses:</p>
<ul>
<li>2% card cashback on your purchases ( the cashback will be in CRO )</li>
<li>100% money back for Spotify payments ( money are returned to you in CRO as well )</li>
</ul>
<p>To be honest, one of the reasons, why I decided to try Crypto.com credit card was to cover my expences for Spotify :) But then, when I saw that on every purchase that I make, I get 2% cashback, i thought that it's not bad at all. It's 20 Euro of every 1000 spent. If you look at it only for 1 month, then you might save 20-40 euros. ( maybe more maybe less ) .But if you look at it on a year scale - that's 240-480 Euro a year in your pocket. Sounds better, right :) So, I thought that I could use this card for all my grosseries and other small purchaces. But there was one culprit - I couldn't add crypto.com credit card to my Apple pay. This is only supported in US at the moment. That was a big bummer for me. Luckily, I found on internet another cool service called <a href="https://www.curve.com/">Curve</a> - this services allows you to link multiple cards to your account and it acts as a smart front end for them. You can easily add your Curve card to your apple pay and link your crypto.com card to your curve account. As a result, you are actually paying with Crypto.com card and what is more awesome - you get cashback in both Curve and Crypto.com! ( free tier in Curve allows you to get 1% cashback on all purchases in the first 30 days ). So, the steps that you would need to achieve this are quite simple</p>
<ol>
<li>Register in <a href="https://crypto.com/">Crypto.com</a>. You can use my referal  <a href="https://crypto.com/app/6bb5pu96j3">link</a> to sign up for Crypto.com and we both get $25 USD :) Use <code>6bb5pu96j3</code> referal code in the form</li>
<li>But 350 Euro worth of CRO and stake it in the app</li>
<li>Order a credit card and write down it's details</li>
<li>Go to <a href="https://www.curve.com/">Curve</a> and register there. You can use this referal <a href="https://www.curve.com/join#NR4Z8J6N">link</a> to get some bonuses on the signup</li>
<li>In the curve app, add your Crypto.com card</li>
<li>Add your curve app to your Apple/Google/Samsung pay</li>
<li>You should be all set :) Physical card will be delivered soon to you, but personally I'm usually paying with my Apple Watch and I can't imagine my life without it anymore :)</li>
</ol>
<p>Couple things to keep in mind:</p>
<ol>
<li>When you activate your Curve physical card, then your initial card details might change - you might need to update card details in online services ( Amazon, Spotify etc )</li>
<li>Curve cashback is delivered in British Pounds and you can actually select in the curve app &quot;Cash&quot; option to pay when you get enough cashback</li>
<li>In Netherlands, Albert Hijn network usually do not accept Visa or Mastercard, which means that Curve card most probably won't work there ( except couple stores ), but Jumbo has no problems with this card and now I'm just buying more groceries in Jumbo :)</li>
</ol>
<p>I hope you will find this as useful as I do :)</p>
</div>]]></content:encoded></item><item><title><![CDATA[Gitlab v14 introduces a breaking change to secrets detection job]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Recently we started to get a pipeline failure in Gitlab for one of our projects. The issues was :</p>
<pre><code>jobs secret detection default branch config should implement a script: or a trigger: keyword
</code></pre>
<p>In this project we were using Gitlab Secrets Detection jobs templates like this :</p>
<pre><code>include:
  - template: Security/SAST.</code></pre></div>]]></description><link>https://biercoff.com/gitlab-v14-introduces-a-breaking-change-to-secrets-detection-templates/</link><guid isPermaLink="false">60ded180d5406b075fcc7b5e</guid><category><![CDATA[gitlab]]></category><category><![CDATA[secret]]></category><category><![CDATA[detection]]></category><category><![CDATA[14]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Fri, 02 Jul 2021 08:46:54 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Recently we started to get a pipeline failure in Gitlab for one of our projects. The issues was :</p>
<pre><code>jobs secret detection default branch config should implement a script: or a trigger: keyword
</code></pre>
<p>In this project we were using Gitlab Secrets Detection jobs templates like this :</p>
<pre><code>include:
  - template: Security/SAST.gitlab-ci.yml
  - template: Security/Dependency-Scanning.gitlab-ci.yml
  - template: Security/License-Scanning.gitlab-ci.yml
  - template: Security/Secret-Detection.gitlab-ci.yml
</code></pre>
<p>At first, I thought that it was related to the fact that in Gitlab 14 default branch was changed from <code>master</code> to <code>main</code>, but after talking to Gitlab support, it appeared the root cause in different place :</p>
<pre><code>Hello Andrew,
Thanks for reaching out.
We indeed introduced a breaking change to Secret Detection job with 14.0 release, however, it deals not with default branch name changes, 
but with us merging the two jobs secret_detection_default_branch and secret_detection. This work was done in 
Remove secret_detection_default_branch job Merge Request.
I looked through your configuration on project {project_name} and it seems like in order to fix the issue, 
you simply need to remove the secret_detection_default_branch job from the configuration.
Let me know how it goes.
Best regards,
</code></pre>
<p>Here's the <a href="https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63534">link</a> to the Github PR.</p>
<p>Happy coding :)</p>
</div>]]></content:encoded></item><item><title><![CDATA[Fixing next.js export path to assets issue]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Recenlty I had to create a simple report page for one of the tools I built and this page had to be fully static, but reading from a JSON file that I would add to it. I'm not a big specialist in Front End and CSS, but I decided to</p></div>]]></description><link>https://biercoff.com/fixing-next-js-export-path-to-assets-issue/</link><guid isPermaLink="false">60b097aad5406b075fcc7b46</guid><category><![CDATA[nextjs]]></category><category><![CDATA[react]]></category><category><![CDATA[static]]></category><category><![CDATA[fix]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Fri, 28 May 2021 07:28:39 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Recenlty I had to create a simple report page for one of the tools I built and this page had to be fully static, but reading from a JSON file that I would add to it. I'm not a big specialist in Front End and CSS, but I decided to play around with React + Next.js. Surprisingly everything was done quite fast and I was already celebrating final result the moment I would run <code>next export</code>, but unfortunatelly I discovered that css and javascript was not loaded and I got a very ugly html page :(<br>
The problem was that all static assets were linked in html under <code>/_next/static/</code> folder path.<br>
After quite some googling and try outs I finally found <a href="https://github.com/vercel/next.js/issues/8158#issuecomment-659674968">Github ticket</a> where first sir <a href="https://github.com/cargallo">cargallo</a> gave a nice tip on how to approach this with a plugin, but <a href="https://github.com/vercel/next.js/issues/8158#issuecomment-687707467">lower</a> <a href="https://github.com/spudmashmedia">Johnny Dong</a> suggested that ther's a configuration option for this in <code>next.config.js</code>:</p>
<pre><code class="language-javascript">module.exports = {
    assetPrefix: &quot;.&quot;,
  };
</code></pre>
<p>And now you can run <code>npm run export</code> and everything will work like a charm 🚀</p>
<p>Happy coding everyone :) 🎉</p>
</div>]]></content:encoded></item><item><title><![CDATA[Generating JSON Schema in Java with "additionalProperties" set to "true"]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Recently i was working on a new tool for contract testing that we decided to develop in <a href="https://new10.com">New10</a> from scratch. We decided that we would like to use JSON Schema's for contracts validation and for that i needed to implement several SDK's in typescript, java, python in order to support</p></div>]]></description><link>https://biercoff.com/generating-json-schema-in-java-with-additionalproperties-set-to-true/</link><guid isPermaLink="false">6022c89ed5406b075fcc7b17</guid><category><![CDATA[jackson]]></category><category><![CDATA[json]]></category><category><![CDATA[schema]]></category><category><![CDATA[java]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Tue, 09 Feb 2021 17:49:30 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Recently i was working on a new tool for contract testing that we decided to develop in <a href="https://new10.com">New10</a> from scratch. We decided that we would like to use JSON Schema's for contracts validation and for that i needed to implement several SDK's in typescript, java, python in order to support all the services we have. While working on Java SDK, i faced a problem with JSON schema generation for some of our models. At first i was using <a href="https://github.com/FasterXML/jackson-module-jsonSchema">jackson-module-jsonSchema</a> library, where i faced with one major problem - i couldn't generate <code>&quot;required&quot;: []</code> attribute because of <a href="https://github.com/FasterXML/jackson-module-jsonSchema/issues/94">this issue</a><br>
So, instead, i found another <a href="https://github.com/mbknor/mbknor-jackson-jsonSchema">library</a> that was working better for me. But with it i faced with another problem - by default it was setting <code>additionalProperties</code>: <code>true</code> for every class, which is a bummer for me. Luckily i managed to find some hints in the documentation and code that allowed me to bypass this situation and now i would like to share it with everyone ( and myself in the future) :</p>
<pre><code class="language-java">public static JSONObject generateJsonSchema(Class clazz) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        JsonSchemaConfig config = JsonSchemaConfig.vanillaJsonSchemaDraft4().withFailOnUnknownProperties(false);
        config = config.withFailOnUnknownProperties(false);
        JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(mapper, config);
        JsonNode jsonSchema = jsonSchemaGenerator.generateJsonSchema(clazz);
        String json = mapper.writeValueAsString(jsonSchema);
        return new JSONObject(json);
    }
</code></pre>
<p>That's pretty much everything you need in order to generate a JSON Schema out of a Java class.</p>
<p>Hope it help someone besides me :)</p>
<p>Happy coding everyone.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Fixing "Gitleaks analysis failed" issue in Gitlab pipeline]]></title><description><![CDATA[<div class="kg-card-markdown"><p>In <a href="https://new10.com">New10</a> we have recently moved our security scans from <a href="https://snyk.io/">Snyk</a> to <a href="https://docs.gitlab.com/ee/development/integrations/secure.html">Security scanner integration</a>. Recently, when i was integrating this with another service, i got this error</p>
<pre><code class="language-bash">[INFO] [secrets] [2020-12-31T08:17:48Z] ▶ GitLab secrets analyzer v3.13.1
[INFO] [secrets] [2020-12-31T08:17:48Z] ▶ Running scan from commits file 06efd4ca11ae36382f34720e9eae3e1e6e0_</code></pre></div>]]></description><link>https://biercoff.com/fixing-gitleaks-analysis-failed-issue-in-gitlab-pipeline/</link><guid isPermaLink="false">5fed8b52d5406b075fcc7afd</guid><category><![CDATA[gitlab]]></category><category><![CDATA[gitleaks]]></category><category><![CDATA[security]]></category><category><![CDATA[scan]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Thu, 31 Dec 2020 08:32:55 GMT</pubDate><media:content url="https://biercoff.com/content/images/2020/12/Screenshot-2020-12-31-at-09.28.46-1.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://biercoff.com/content/images/2020/12/Screenshot-2020-12-31-at-09.28.46-1.png" alt="Fixing "Gitleaks analysis failed" issue in Gitlab pipeline"><p>In <a href="https://new10.com">New10</a> we have recently moved our security scans from <a href="https://snyk.io/">Snyk</a> to <a href="https://docs.gitlab.com/ee/development/integrations/secure.html">Security scanner integration</a>. Recently, when i was integrating this with another service, i got this error</p>
<pre><code class="language-bash">[INFO] [secrets] [2020-12-31T08:17:48Z] ▶ GitLab secrets analyzer v3.13.1
[INFO] [secrets] [2020-12-31T08:17:48Z] ▶ Running scan from commits file 06efd4ca11ae36382f34720e9eae3e1e6e0_commit_list.txt 
on commits 06efd4ca11ae36382f3472ea9210e9eae3e1e6e0
..956d4cb597f092deda891115ed3c4c1b312
[ERRO] [secrets] [2020-12-31T08:17:50Z] ▶ Couldn't run the gitleaks command: exit status 2
[ERRO] [secrets] [2020-12-31T08:17:50Z] ▶ Gitleaks analysis failed: exit status 2
</code></pre>
<p>Well, such errors make everything so clear, right ? :)</p>
<iframe src="https://giphy.com/embed/j3HQ1zWosr1NS" width="480" height="447" frameborder="0" class="giphy-embed" allowfullscreen></iframe><p><a href="https://giphy.com/gifs/the-big-bang-theory-sheldon-cooper-j3HQ1zWosr1NS">via GIPHY</a></p>
<p>Thanks to my colleagues, i was able to fix this. The only thing you need to do is in your <code>.gitlab-ci.yml</code> file add next variable:</p>
<pre><code class="language-yml">variables:
    GIT_DEPTH: '2' # Tells git to fetch all the branches of the project, required by the analysis task
</code></pre>
<p>That should do the trick. Hope i help someone besides me ( I will definatelly will come back to this post in the future :) )</p>
</div>]]></content:encoded></item><item><title><![CDATA[Building a folder structure tree recursively with typescript and reduce]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Recenlty i was working on a new CLI tool for my company, where we would have to work a lot with file system and files manipulation. For one of the tasks i needed to have a method that would generate me a directory structure in JSON format with all child</p></div>]]></description><link>https://biercoff.com/building-a-folder-structure-tree-recursively-with-typescript-and-reduce/</link><guid isPermaLink="false">5fc9517bd5406b075fcc7aed</guid><category><![CDATA[typescript]]></category><category><![CDATA[recursive]]></category><category><![CDATA[reduce]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Thu, 03 Dec 2020 21:05:17 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Recenlty i was working on a new CLI tool for my company, where we would have to work a lot with file system and files manipulation. For one of the tasks i needed to have a method that would generate me a directory structure in JSON format with all child directories and files listed. Now, i have to admit, that I still have struggles with reduce methods, but here it was exactly what i needed and , to be honest, I'm a bit proud of the solution i managed to get. My small personal victory. I'm writing it here, so that future me could use this and also I really hope that it will help others, who face with this problem as well. Here's what the method looks like :</p>
<pre><code class="language-typescript">import fs, { readdirSync, statSync } from 'fs'
import { dirname, resolve } from 'path'
export type GenericObject = Record&lt;string, unknown&gt;

export const getListOfFilesInDirectory = (dirPath: string): string[] =&gt; {
    return readdirSync(dirPath).filter((entry) =&gt; statSync(resolve(dirPath, entry)).isFile())
}

export const getListOfDirectoriesInDirectory = (dirPath: string): string[] =&gt; {
    return readdirSync(dirPath).filter((entry) =&gt; statSync(resolve(dirPath, entry)).isDirectory())
}

export const describeDirStructure = (dirPath: string): GenericObject =&gt; {
    return readdirSync(dirPath).reduce((acc: GenericObject, currentPointer: string) =&gt; {
        if (statSync(resolve(dirPath, currentPointer)).isDirectory()) {
            const files: string[] = getListOfFilesInDirectory(resolve(dirPath, currentPointer))
            const dirs: string[] = getListOfDirectoriesInDirectory(resolve(dirPath, currentPointer))
            if (files.length &gt; 0 &amp;&amp; dirs.length &gt; 0) {
                const innerStructure = {
                    [currentPointer]: {
                        files,
                        ...describeDirStructure(resolve(dirPath, currentPointer)),
                    },
                }
                acc = {
                    ...acc,
                    ...innerStructure,
                }
                return acc
            }
            if (dirs.length === 0 &amp;&amp; files.length &gt; 0) {
                acc = {
                    ...acc,
                    ...{ [currentPointer]: files },
                }
            } else {
                acc = {
                    ...acc,
                    ...{ [currentPointer]: describeDirStructure(resolve(dirPath, currentPointer)) },
                }
            }
        }
        return acc
    }, {})
}
</code></pre>
<p>In order to verify this, i made a simple directory example that looks like this :</p>
<pre><code>└── list-directory-example
    └── demo
        ├── service-data
        │   ├── service-details.json
        │   └── transactions
        │       └── transactions.json
        └── user-data
            ├── billing.json
            └── personal-information.json
</code></pre>
<p>And the unit test is also quite simple :</p>
<pre><code class="language-typescript">    test('🟢 I can get a full list of all files in all directories recursively', () =&gt; {
        const result = describeDirStructure(
            resolve('./src/utils/__tests__/fixtures', 'list-directory-example')
        )
        expect(result).toEqual({
            demo: {
                'service-data': {
                    files: ['service-details.json'],
                    transactions: ['transactions.json'],
                },
                'user-data': ['billing.json', 'personal-information.json'],
            },
        })
    })
</code></pre>
<p>I really hope that this will be helpful not only for me, but for others as well.</p>
<p>Happy coding everyone ! ☺️</p>
</div>]]></content:encoded></item><item><title><![CDATA[Generating typescript API client from Swagger]]></title><description><![CDATA[<div class="kg-card-markdown"><p>When it comes to API Test Frameworks, I prefer to generate code and not to write everything manually. In my current company, we managed to build a Test Framework using <a href="https://github.com/swagger-api/swagger-codegen">swagger-codegen</a> and Java bindings. It was relatively simple to set up a process where we would generate API clients using</p></div>]]></description><link>https://biercoff.com/my-small-investigation-about-swagger-codegen-generation-in-typescript/</link><guid isPermaLink="false">5f44e1ccd5406b075fcc7ac1</guid><category><![CDATA[typescript]]></category><category><![CDATA[axios]]></category><category><![CDATA[swagger-codegen]]></category><category><![CDATA[openapi-generator]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Thu, 27 Aug 2020 20:10:41 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>When it comes to API Test Frameworks, I prefer to generate code and not to write everything manually. In my current company, we managed to build a Test Framework using <a href="https://github.com/swagger-api/swagger-codegen">swagger-codegen</a> and Java bindings. It was relatively simple to set up a process where we would generate API clients using swagger-codegen, push them to our Nexus repository and use this library as a dependency in our Test Framework. It works well for us, but recently we concluded that we need to build something similar in Typescript. So, based on our previous experience we managed to define the set of requirements for the generated client:</p>
<ul>
<li>We should be able to have multiple instances of the same API Client</li>
<li>We should be able to set custom headers (<code>request-trace-id</code>, <code>Authorization</code>, etc) for every API Client</li>
<li>We should be able to set request/response interceptors to:
<ul>
<li>properly log request/response details (we were using <a href="https://github.com/dkorobtsov/plinter">plinter</a> library for that)</li>
<li>attach request/response details into <a href="http://allure.qatools.ru/">Allure report</a></li>
</ul>
</li>
<li>And of course we would like to generate Api client in typescript</li>
</ul>
<p>At first, I thought that I will use <a href="https://github.com/swagger-api/swagger-codegen">swagger-codegen</a> just like I used it for generating our Java API clients. But it was unpleasantly surprising to see that the swagger-codegen has next typescript options:</p>
<ul>
<li>Typescript (Node) - it's using <a href="https://www.npmjs.com/package/request">request</a> under the hood which is deprecated</li>
<li>Typescript (Angular) - which is handy to be used in Angular projects, which was not my case</li>
<li>Typescript (Fetch) - the problem here is that you can't get multiple instances of the same API Client. <code>fetch</code> is global and therefore it's impossible to set different Authorization headers for the same API Client</li>
<li>Typescript (jQuery) - obviously also is not an option for our case :)</li>
</ul>
<p>So I started looking into other options and I discovered that <code>it's not that easy to find a library, that would match all my requirements</code>.</p>
<p>Eventually, I found a solution, but I would like to tell more about my journey and give a short review of every library I could find on the web.</p>
<h3 id="swaggertypescriptcodegen">Swagger-typescript-codegen</h3>
<p>The first library I found was this <a href="https://github.com/mtennoe/swagger-typescript-codegen">one</a>. It looked promising at first, but then I discovered that it's using <a href="https://www.npmjs.com/package/superagent">superagent</a> under the hood and that and this library is not using classes for API clients generation. For my purpose, I would prefer <a href="https://www.npmjs.com/package/axios">Axios</a>, so I decided not to go with this library</p>
<h3 id="swaggerjscodegen">Swagger-js-codegen</h3>
<p>This <a href="https://github.com/wcandillon/swagger-js-codegen">library</a> is looking for a new maintainer and is not under active development, so not an option for me either.</p>
<h3 id="swaggeraxioscodegen">Swagger-axios-codegen</h3>
<p>At first, I was excited to see this <a href="https://github.com/Manweill/swagger-axios-codegen">library</a>, since it was using Axios and I was able to pass custom Axios instance. The problem was that it was impossible to create multiple instances of the same API Client, but I've spent more than a week trying to make <a href="https://github.com/Manweill/swagger-axios-codegen/issues/105">local version to work for me:( </a>.<br>
After finally resolving the issue, I have discovered another issue - <a href="https://github.com/Manweill/swagger-axios-codegen/issues/53">the library doesn't support generating parameters by reference</a>, which is quite serious. Even with these issues, I decided to give it a try and generate a client for me - unfortunately, the generated code was not even close to what I was expecting and I decided not to proceed with it.</p>
<h3 id="swaggertots">Swagger-to-ts</h3>
<p>From what I understood this <a href="https://github.com/manifoldco/swagger-to-ts">library</a> only generates models of requests/responses and not the actual client.</p>
<h3 id="openapigenerator">Openapi-generator 🏆</h3>
<p>And this is the <a href="https://github.com/OpenAPITools/openapi-generator">winner</a>! Here's why:</p>
<ul>
<li>It supports Swagger V2 and V3</li>
<li>It has <code>typescript-Axios</code> client generation</li>
<li>You can create multiple instances of the same API Client</li>
<li>You can pass custom Axios instance to the client</li>
<li>Axios allows you to set custom headers and interceptors.</li>
</ul>
<p>In case you want to quickly try it for yourself, you can do the following:</p>
<pre><code class="language-bash">wget https://petstore.swagger.io/v2/swagger.json

wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.0.0-beta/openapi-generator-cli-5.0.0-beta.jar -O openapi-generator-cli.jar

openapi-generator generate \
    -i swagger.json \
    -o api-client \
    -g typescript-axios
    --artifact-version 1.0.0-SNAPSHOT
</code></pre>
<p>This should be enough to see what is the result and whether it fit your needs.</p>
<p>There was a moment when I thought that we would use <code>swagger-codegen</code> for generating only models for request/response and write API client methods manually, but I'm glad that I tried <code>openapi-generator</code> at the end.</p>
<p>I hope my findings will be helpful for other people as well.</p>
<p>Happy coding :)</p>
</div>]]></content:encoded></item><item><title><![CDATA[Handling ThrottlingException in Cloudwatch Goland SDK]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I've been recently working on a new cli tool that was helping our Teams to subscribe cloudwatch log groups to a specific lambda that forwards logs to Datadog. However, when a project has big number of lambda's, we were facing with <code>ThrottlingException</code> from cloudwatch. This allowed me to learn how</p></div>]]></description><link>https://biercoff.com/handling-throttlingexception-in-cloudwatch-goland-sdk/</link><guid isPermaLink="false">5f46ccb5d5406b075fcc7ac5</guid><category><![CDATA[go]]></category><category><![CDATA[cloudwatch]]></category><category><![CDATA[throttlingexception]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Wed, 26 Aug 2020 21:01:33 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I've been recently working on a new cli tool that was helping our Teams to subscribe cloudwatch log groups to a specific lambda that forwards logs to Datadog. However, when a project has big number of lambda's, we were facing with <code>ThrottlingException</code> from cloudwatch. This allowed me to learn how to handle specific exception in Goland and i decided to share it with everyone.<br>
Let's start with client itself:</p>
<script src="https://gist.github.com/azakordonets/e19e6e72a113b336164c36ae9a4ca34f.js"></script>
<ul>
<li><code>isThrottlingError</code> method defines if error is the one we need</li>
<li>each method is accepting <code>cloudwatchClient cloudwatchlogsiface.CloudWatchLogsAPI</code> - we need this for writing unit tests for our methods</li>
</ul>
<p>Of course we can't leave this code without unit tests. In order to check all the cases, we need to create mock first:</p>
<script src="https://gist.github.com/azakordonets/e4b934640c0c6b3f3f7ac59ab94fa9ba.js"></script>
<p>After that we can write all the unit tests to verify functions behaviour:</p>
<script src="https://gist.github.com/azakordonets/4e0452d0b820944fce62a0c22c0ca6ac.js"></script>
<p>And this is how we can write cloudwatch client that will retry on Throttling exception and will do the job :)</p>
<p>Happy coding everyone :)</p>
</div>]]></content:encoded></item><item><title><![CDATA[Running Typescript scratches in Webstorm IDE]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Recently i started to work more closely with Typescript and therefore i need to test some small ideas more often in typescript. Scratches are the best place to do that while you're building something. Unfortunatelly <a href="https://www.jetbrains.com/webstorm/">Webstorm</a> doesn't support running typescript scratches out of the box. It can only understand Js</p></div>]]></description><link>https://biercoff.com/running-typescript-scratches-in-webstorm-ide/</link><guid isPermaLink="false">5f43b699d5406b075fcc7ab8</guid><category><![CDATA[webstorm]]></category><category><![CDATA[typescript]]></category><category><![CDATA[scratch]]></category><dc:creator><![CDATA[Andrew Zakordonets]]></dc:creator><pubDate>Mon, 24 Aug 2020 12:52:52 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Recently i started to work more closely with Typescript and therefore i need to test some small ideas more often in typescript. Scratches are the best place to do that while you're building something. Unfortunatelly <a href="https://www.jetbrains.com/webstorm/">Webstorm</a> doesn't support running typescript scratches out of the box. It can only understand Js files. I wasn't excited about this, but i managed to find a quick solution to this. Hope it will help others as well.</p>
<ol>
<li>First we need to install <code>ts-node</code> package with <code>npm install -g ts-node</code> command</li>
<li>Create typescript scratch in Webstorm IDE</li>
<li><code>Cmd + Shift + A</code> -&gt; <code>Edit Configuration</code></li>
<li>Create new Node configuration with next settings :<br>
<img src="https://biercoff.com/content/images/2020/08/Screenshot-2020-08-24-at-14.45.50-1.png" alt="Screenshot-2020-08-24-at-14.45.50-1"></li>
</ol>
<p>The key here is to specify <code>--require ts-node/register</code> in <code>Node parameters</code> section. This will tell IDE to transpile ts scratch file into js file and run it.</p>
<p>Thanks <a href="https://intellij-support.jetbrains.com/hc/en-us/profiles/1283147511-Elena-Pogorelova">Elena Pogorelova</a> for this <a href="https://intellij-support.jetbrains.com/hc/en-us/profiles/1283147511-Elena-Pogorelova">tip</a> !</p>
</div>]]></content:encoded></item></channel></rss>