<?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: kontrollanten </title>
    <description>The latest articles on Forem by kontrollanten  (@kontrollanten).</description>
    <link>https://forem.com/kontrollanten</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%2F94970%2Fee7e42e6-510d-4417-a377-60a134f23572.png</url>
      <title>Forem: kontrollanten </title>
      <link>https://forem.com/kontrollanten</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kontrollanten"/>
    <language>en</language>
    <item>
      <title>DuckduckBang productivity</title>
      <dc:creator>kontrollanten </dc:creator>
      <pubDate>Sat, 19 Sep 2020 18:28:40 +0000</pubDate>
      <link>https://forem.com/kontrollanten/duckduckbang-productivity-2dha</link>
      <guid>https://forem.com/kontrollanten/duckduckbang-productivity-2dha</guid>
      <description>&lt;p&gt;I've been using &lt;a href="https://duckduckgo.com" rel="noopener noreferrer"&gt;DuckDuckGo&lt;/a&gt; for &lt;a href="https://duckduckgo.com/privacy" rel="noopener noreferrer"&gt;privacy reasons&lt;/a&gt;, but now I've actually found a real productivity upside with it.&lt;/p&gt;

&lt;p&gt;As a developer I spend a lot of time read docs from different libraries and softwares. &lt;a href="https://duckduckgo.com/bang" rel="noopener noreferrer"&gt;bang shortcuts&lt;/a&gt; makes that smooth and simple. If I want to search for a npm package I just write &lt;code&gt;!npm algolia-places-react&lt;/code&gt; and DuckDuckGo will redirect that search query directly to npm:&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%2Fbye5p992ubij02fmv5ox.gif" 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%2Fbye5p992ubij02fmv5ox.gif" alt="Bang search example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's over 13 000 different bangs so you can be sure that your favorite sites can be found, just go ahead and check the list at &lt;a href="https://duckduckgo.com/bang" rel="noopener noreferrer"&gt;https://duckduckgo.com/bang&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How are you doing to quickly find docs for the software you're using?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>javascript</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Bashing inspiring quotes</title>
      <dc:creator>kontrollanten </dc:creator>
      <pubDate>Fri, 18 Sep 2020 21:51:33 +0000</pubDate>
      <link>https://forem.com/kontrollanten/bashing-inspiring-quotes-5ebm</link>
      <guid>https://forem.com/kontrollanten/bashing-inspiring-quotes-5ebm</guid>
      <description>&lt;p&gt;I like history and I like quotes. I think it's an easy way to widen my perspectives and get more humble to the world. But I also like Linux. So I decided to combine those two in a golang session.&lt;/p&gt;

&lt;p&gt;It resulted in &lt;a href="https://github.com/kontrollanten/bash-quotes"&gt;bash-quotes&lt;/a&gt;, a CLI for printing quotes from &lt;a href="http://quotes.cat-v.org/"&gt;http://quotes.cat-v.org/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's a pretty simple app that's divided into two parts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;download-quotes&lt;/strong&gt;&lt;br&gt;
As the name says this part downloads the webpage, scrapes it and uses the &lt;code&gt;&amp;lt;hr /&amp;gt;&lt;/code&gt; to identify when a quote ends. When that's done all the quotes are saved into a filepath that's given as an argument.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;read-quote&lt;/strong&gt;&lt;br&gt;
When calling this binary a randomly chosen quote is printed to the screen with some nice colors. This is the binary that I'm calling at shell login to keep me inspired with thoughtful quotes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;The web page has a lot of sections with quotes, I've only scraped the first page so I guess I'll scrape further next time I dig into this.&lt;/p&gt;

&lt;p&gt;You're welcome to download and use it by visiting &lt;a href="https://github.com/kontrollanten/bash-quotes"&gt;https://github.com/kontrollanten/bash-quotes&lt;/a&gt; and follow the install instructions. What do you think? Would you've done it another way?&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>bash</category>
      <category>linux</category>
    </item>
    <item>
      <title>What Netlify got wrong</title>
      <dc:creator>kontrollanten </dc:creator>
      <pubDate>Thu, 17 Sep 2020 20:14:18 +0000</pubDate>
      <link>https://forem.com/kontrollanten/what-netlify-got-wrong-5e93</link>
      <guid>https://forem.com/kontrollanten/what-netlify-got-wrong-5e93</guid>
      <description>&lt;p&gt;I love Netlify. Netlify have helped me save thousands of minutes during my career. Previously I'd been using huge virtual machines and then complicated AWS S3 to host my frontend sites. But when I met Netlify it was intense love. We saw each other every day and every minute. Netlify's only focus was my prosperity.&lt;/p&gt;

&lt;p&gt;But then came a day. She was coming home with a big bloat of stuff; AWS Lambda, Forms, Identity, plugins, etc. A bunch of features that I didn't need at all. And then I started to run into different bugs/problems in the build environment. I took a few steps back and saw that Netlify never was the perfect one.&lt;/p&gt;

&lt;p&gt;With a bit perspective it seems clear that Netlify's main purpose isn't frontend hosting, but instead to be a service minded problem solver for website builders. As a software company you can choose to either do one thing well or everything okay, and I think Netlify is the latter. And that's fine, many people want it that way, just look at AWS.&lt;/p&gt;

&lt;p&gt;But my requirements are quite different, I want it simple and easy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be able to run jobs before and after deployment.&lt;/li&gt;
&lt;li&gt;Build environment should only be configured once.&lt;/li&gt;
&lt;li&gt;Possibility to easy rollback the release if the e2e test failed.&lt;/li&gt;
&lt;li&gt;The whole CD process should be monitored from the CI environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And to find that I have to search further. Thanks for everything, Netlify.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>devops</category>
    </item>
    <item>
      <title>e2e testing Netlify deploy previews</title>
      <dc:creator>kontrollanten </dc:creator>
      <pubDate>Sun, 17 Mar 2019 11:14:45 +0000</pubDate>
      <link>https://forem.com/kontrollanten/e2e-testing-previews-with-netlify-travis-integration-3jop</link>
      <guid>https://forem.com/kontrollanten/e2e-testing-previews-with-netlify-travis-integration-3jop</guid>
      <description>&lt;p&gt;When working on my side projects I find it very important to get a straight testing process; since the projects can be untouched for months I want to be sure everything is ok when I push new code. Usually I use &lt;a href="http://netlify.com" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt; to deploy my sites; it's free (open source plan), it's easy to integrate with GitHub and it gives me &lt;a href="https://www.netlify.com/blog/2016/07/20/introducing-deploy-previews-in-netlify/" rel="noopener noreferrer"&gt;deploy previews&lt;/a&gt; for each pull request.&lt;/p&gt;

&lt;p&gt;Since e2e testing is all about being as close as possible to "real" environments I want my tests to run against Netlifys deploy previews instead of &lt;a href="https://www.npmjs.com/package/serve" rel="noopener noreferrer"&gt;serve&lt;/a&gt; or some other local server setup (actually I've found bugs which was only produced in Netlifys production).&lt;/p&gt;

&lt;p&gt;Netlify is creating deploy previews by listening for new PR's. I thought it was possible to deploy previews from CLI instead, and then wait for the response to run my e2e tests. Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn netlify deploy &amp;amp;&amp;amp; yarn e2e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it seems there's no way to deploy previews from &lt;a href="https://www.netlify.com/docs/api/" rel="noopener noreferrer"&gt;Netlifys REST API&lt;/a&gt; neither is it possible with their &lt;a href="https://www.netlify.com/docs/webhooks/#incoming-webhooks" rel="noopener noreferrer"&gt;incoming webhooks&lt;/a&gt;, so I had to figure out an alternative way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bridge between Netlify and CI environment with AWS Lambda
&lt;/h2&gt;

&lt;p&gt;To solve my problem I added an &lt;a href="https://www.netlify.com/docs/webhooks/#outgoing-webhooks-and-notifications" rel="noopener noreferrer"&gt;outgoing webhook&lt;/a&gt; who calls an URL upon deploy succeeded. I pointed the webhook to a custom AWS Lambda function I called &lt;a href="https://github.com/kontrollanten/netlify-travis-integration" rel="noopener noreferrer"&gt;netlify-travis-integration&lt;/a&gt;. netlify-travis-integration reads the deploy preview URL from the payload and triggers a Travis job to run e2e testing against.&lt;/p&gt;

&lt;h3&gt;
  
  
  Travis configuration
&lt;/h3&gt;

&lt;p&gt;Since I couldn't find a way to run a specific Travis job I had to distinguish my non-Netlify required jobs from my Netlify required jobs by checking if the build was triggered by API or not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  include:
    - stage: lint
      if: type != api
      script: yarn lint
    - stage: test
      if: type != api
      script: yarn test:ci &amp;amp;&amp;amp; codecov
    - stage: packtracker
      if: type != api
      script: yarn build
    - stage: lighthouse
      if: type = api
      script: yarn lh -- --perf=96 --bp=96 --no-comment $SITE_URL
    - stage: e2e
      if: type = api
      script: yarn e2e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a bit ugly, but I couldn't find a better way to solve it when using Travis. I think this is easier to solve with CircleCI, so I'll prefer to choose that for my next project.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub statuses
&lt;/h3&gt;

&lt;p&gt;To keep track of my e2e tests I added a webhook to my Travis config to let it call another AWS Lambda function. This function checks if the Travis job was triggered by an API and then creates a pull request status.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbswhhh9zgj43zphlwdu3.png" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbswhhh9zgj43zphlwdu3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;After one year and 100 pull requests I'm satisfied with the solution and it has caught a lot of errors I've missed. Especially it's comfortable when using &lt;a href="https://renovatebot.com" rel="noopener noreferrer"&gt;Renovate&lt;/a&gt; who creates PR's for dependency updates, then it's easy to find out whether something breaks or not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Way forward
&lt;/h2&gt;

&lt;p&gt;I created netlify-travis-integration just to solve a problem I had, but in case there's others who'd like to solve the same problem it's not super easy to do the setup; you need to create an AWS account, setup AWS permissions, configure Travis and Netlify and also create a GitHub API token. It should be considered as a proof of concept. Maybe I'll take the next step and make it easier to integrate with new projects.&lt;/p&gt;

&lt;p&gt;How are you solving this problem? Are you just running your e2e tests against a local web server?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kontrollanten/netlify-travis-integration" rel="noopener noreferrer"&gt;netlify-travis-integration&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>netlify</category>
      <category>e2e</category>
      <category>testing</category>
    </item>
    <item>
      <title>Combine coverage reports from Electron tests</title>
      <dc:creator>kontrollanten </dc:creator>
      <pubDate>Sun, 10 Mar 2019 09:35:42 +0000</pubDate>
      <link>https://forem.com/kontrollanten/combine-coverage-reports-from-electron-tests-1if6</link>
      <guid>https://forem.com/kontrollanten/combine-coverage-reports-from-electron-tests-1if6</guid>
      <description>&lt;p&gt;We're using &lt;a href="https://github.com/jprichardson/electron-mocha"&gt;electron-mocha&lt;/a&gt; to test main process and &lt;a href="http://jestjs.io"&gt;jest&lt;/a&gt; to test renderer process for the &lt;a href="https://github.com/protonmail-desktop/application"&gt;ProtonMail unofficial Desktop&lt;/a&gt; application. To keep track of the test coverage we'd like to create coverage reports and send to &lt;a href="https://codecov.io"&gt;codecov&lt;/a&gt;, but that was more troublesome than I first thought.&lt;/p&gt;

&lt;p&gt;There's a &lt;a href="https://github.com/jprichardson/electron-mocha/issues/135"&gt;good thread&lt;/a&gt; in the electron-mocha GitHub repo that helped us along the way. But to collect all information in one place I'll describe how we solved it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Coverage report with jest
&lt;/h1&gt;

&lt;p&gt;Since jest has coverage support out of the box the only thing needed is &lt;code&gt;yarn jest --coverage&lt;/code&gt;. Simple.&lt;/p&gt;

&lt;h1&gt;
  
  
  Coverage report with electron-mocha
&lt;/h1&gt;

&lt;p&gt;This wasn't just as easy as jest. To begin with I added &lt;a href="https://www.npmjs.com/package/babel-plugin-istanbul"&gt;babel-plugin-istanbul&lt;/a&gt; to &lt;a href="https://en.wikipedia.org/wiki/Instrumentation_(computer_programming)"&gt;instrument&lt;/a&gt; the code, which make it possible to trace the coverage.&lt;/p&gt;

&lt;p&gt;.babelrc.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    "env": {
      "test_main": {
        "plugins": ["istanbul"]
      }
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I didn't get babel-plugin-istanbul to &lt;a href="https://www.npmjs.com/package/babel-plugin-istanbul#mocha-on-nodejs-through-nyc"&gt;work with nyc&lt;/a&gt; so I took &lt;a href="https://github.com/jprichardson/electron-mocha/issues/135#issuecomment-464082312"&gt;this solution&lt;/a&gt; from &lt;a href="https://github.com/bennyn"&gt;bennyn&lt;/a&gt; which just saves the coverage data into &lt;code&gt;coverage/coverage-main.json&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;src/main/tests/coverage-after.spec.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import path from 'path';
import fs from 'fs-extra';

const writeCoverageReport = coverage =&amp;gt; {
  const outputFile = path.resolve(process.cwd(), 'coverage/coverage-main.json');
  fs.outputJsonSync(outputFile, coverage);
};


after(() =&amp;gt; {
  if (process.env.NODE_ENV === 'test_main') {
    console.info('--- Writing coverage report');
    writeCoverageReport((global).__coverage__);
  }
}); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create the coverage report we then run &lt;code&gt;yarn cross-env NODE_ENV=test_main yarn electron-mocha --require @babel/register src/main/**/*.spec.js src/main/*.spec.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This solution has one problem. It'll only show coverage for files included by tests. If you don't have any test you'll get 100% coverage. Almighty bennyn had &lt;a href="https://github.com/jprichardson/electron-mocha/issues/135#issuecomment-466020462"&gt;a solution&lt;/a&gt; for that also; require all JS files before creating the coverage report. In our case it ended up with this: &lt;/p&gt;

&lt;p&gt;src/main/tests/coverage-after.spec.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import glob from 'glob';
import path from 'path';
import fs from 'fs-extra';

const writeCoverageReport = coverage =&amp;gt; {
  const outputFile = path.resolve(process.cwd(), 'coverage/coverage-main.json');
  fs.outputJsonSync(outputFile, coverage);
};

// Load all source files to get accurate coverage data
const loadSourceCode = () =&amp;gt; {
  const intrumentedCode = path.join(__dirname, '..');

  glob(`${intrumentedCode}/**/*.js`, {
    sync: true,
  }).forEach(file =&amp;gt; require(path.resolve(file)));
};

after(() =&amp;gt; {
  if (process.env.NODE_ENV === 'test_main') {
    console.info('--- Load all files to collect coverage');
    loadSourceCode();
    console.info('--- Writing coverage report');
    writeCoverageReport((global).__coverage__);
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Tie the bag together
&lt;/h1&gt;

&lt;p&gt;Now we have to separate scripts to create two separate coverage reports. Let tie it together to one combined report.&lt;/p&gt;

&lt;p&gt;jest will create a coverage report in &lt;code&gt;./coverage&lt;/code&gt;  and we configured our main test to also put the report in &lt;code&gt;./coverage&lt;/code&gt;. By installing &lt;a href="https://www.npmjs.com/package/nyc"&gt;nyc&lt;/a&gt; we can combine the reports inside &lt;code&gt;./coverage&lt;/code&gt; and output it to &lt;code&gt;./coverage.json&lt;/code&gt;. If your test files isn't &lt;a href="https://www.npmjs.com/package/nyc#excluding-files"&gt;excluded by nyc's default config&lt;/a&gt;, you need to add the following to your config in &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "nyc": {
    "exclude": [
      "src/main/**/*.spec.js"
    ]
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can run &lt;code&gt;yarn nyc merge coverage&lt;/code&gt; combine the reports. That's it. To print the report in terminal we can run &lt;code&gt;yarn nyc report -t ./coverage&lt;/code&gt;, which creates a report from the coverage folder, and it should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcreewim69chexk8ko27p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcreewim69chexk8ko27p.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/protonmail-desktop/application/commit/1308bb5adf9c3b58d75c7600eb2e8137db3467f8"&gt;You can see the whole implementation commit here&lt;/a&gt; and &lt;a href="https://github.com/protonmail-desktop/application/pull/236"&gt;the follow up cleanup here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>electron</category>
      <category>testing</category>
      <category>javascript</category>
      <category>devops</category>
    </item>
    <item>
      <title>Super fast Electron builds with CircleCI 🚀</title>
      <dc:creator>kontrollanten </dc:creator>
      <pubDate>Sun, 03 Mar 2019 18:01:54 +0000</pubDate>
      <link>https://forem.com/kontrollanten/super-fast-electron-builds-with-circleci--5ghn</link>
      <guid>https://forem.com/kontrollanten/super-fast-electron-builds-with-circleci--5ghn</guid>
      <description>&lt;p&gt;Recently I switched from &lt;a href="https://travis-ci.org"&gt;Travis&lt;/a&gt; to &lt;a href="http://circleci.com"&gt;CircleCI&lt;/a&gt;, since I had some problems with getting my &lt;a href="https://docs.travis-ci.com/user/build-stages/"&gt;Travis stages&lt;/a&gt; working accurate. The results was overwhelming.&lt;/p&gt;

&lt;h1&gt;
  
  
  Simple Docker configuration
&lt;/h1&gt;

&lt;p&gt;Since CircleCI jobs can &lt;a href="https://circleci.com/docs/2.0/executor-types/#using-docker"&gt;run in Docker containers&lt;/a&gt;, it's get really simple to configure &lt;a href="https://www.electron.build/multi-platform-build#sample-travisyml-to-build-electron-app-for-macos-linux-and-windows"&gt;electron-builder multi build&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Travis
script:
  - |
    if [ "$TRAVIS_OS_NAME" == "linux" ]; then
      docker run --rm \
        --env-file &amp;lt;(env | grep -iE 'DEBUG|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS|APPVEYOR_|CSC_|_TOKEN|_KEY|AWS_|STRIP|BUILD_') \
        -v ${PWD}:/project \
        -v ~/.cache/electron:/root/.cache/electron \
        -v ~/.cache/electron-builder:/root/.cache/electron-builder \
        electronuserland/builder:wine \
        /bin/bash -c "yarn --link-duplicates --pure-lockfile &amp;amp;&amp;amp; yarn release --linux --win"
     fi

# CircleCI
deploy-linux:
  docker:
    - image: electronuserland/builder:wine
  steps:
    - run: yarn --link-duplicates --pure-lockfile
    - run: yarn release --linux --win
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The Circle config is much easier to read and maintain, since everything is based on Docker you don't need to pass environment variables you want to use in the container.&lt;/p&gt;

&lt;h1&gt;
  
  
  Almighty debug support
&lt;/h1&gt;

&lt;p&gt;With Docker you can always run the jobs with the same environment locally, which makes everything easier to debug. If that's not enough, you can always &lt;a href="https://circleci.com/docs/2.0/ssh-access-jobs/"&gt;SSH into the build container&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Super fast
&lt;/h1&gt;

&lt;p&gt;For 4 minutes after a push commit I've the response from&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linting&lt;/li&gt;
&lt;li&gt;React unit testing&lt;/li&gt;
&lt;li&gt;Electron unit testing&lt;/li&gt;
&lt;li&gt;Spectron e2e testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ten minutes later I'll also have Linux and MacOS builds deployed and ready to download. No more queues (at least yet) and no more waiting. Since a CI environment is supposed to support me as a developer I think it's vital that the feedback is quick and that I never have to wait for over 5-10 minutes until I have the response. A big plus is that I don't have to see the pride flag in my builds any more. 🥳&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/protonmail-desktop/application/blob/7289770d44f8f8acdda69f878643d354928e406e/.circleci/config.yml"&gt;To see my whole Circle config, you can check here.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>electron</category>
      <category>circleci</category>
    </item>
    <item>
      <title>REST API e2e testing with cURL</title>
      <dc:creator>kontrollanten </dc:creator>
      <pubDate>Fri, 15 Feb 2019 23:04:34 +0000</pubDate>
      <link>https://forem.com/kontrollanten/rest-api-e2e-testing-with-curl-i0j</link>
      <guid>https://forem.com/kontrollanten/rest-api-e2e-testing-with-curl-i0j</guid>
      <description>&lt;p&gt;A while ago I was looking for a simple way to e2e test my REST API, written in Flask. Since I was only interested in make HTTP requests and parse the JSON response I didn't see any point of using any assertion library or test framework. To improve my bash skills i decided to write it with cURL and bash functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Readable output
&lt;/h2&gt;

&lt;p&gt;Testing is to give us control and possibility to with ease find troubles. Therefore I made some colors and an icon to make it easy to parse the results for a human eye.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Green='\033[0;32m'
Red='\033[0;31m'
Color_Off='\033[0m'

Check_Mark='\xE2\x9C\x94'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Assertions
&lt;/h2&gt;

&lt;p&gt;To keep the tests simple I tested everything with "assert equals", which was ran by this function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assert_equals () {
  if [ "$1" = "$2" ]; then
    echo -e "$Green $Check_Mark Success $Color_Off"
  else
    echo -e "$Red Failed $Color_Off"
    echo -e "$Red Expected $1 to equal $2 $Color_Off"
    Errors=$((Errors  + 1))
  fi
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Parsing the JSON
&lt;/h2&gt;

&lt;p&gt;To parse the JSON I used jq, and created a helper function. The first argument is the JSON string and the second is the path, for example ".[0].title".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_json_value () {
  echo $1 | jq -r $2
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  The tests
&lt;/h2&gt;

&lt;p&gt;So finally came the tests that I run. They looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "### START /api/v2/shelters"
shelters_url="localhost:5000/api/v2/shelters/"

echo "When retrieving a shelter accurate properties should be given"
response=$(curl -s "${shelters_url}142784-8")
assert_equals "$(get_json_value "$response" ".shelterId")" "142784-8"
assert_equals "$(get_json_value "$response" ".address")" "Sockerbruksgatan 3"
assert_equals "$(get_json_value "$response" ".slots")" "80"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Am I happier?
&lt;/h2&gt;

&lt;p&gt;Yes. I guess it'd been easier to write it with Python, but this was more fun. I also think that we developers may tend to use bloated frameworks that moves us away from the core and the control. This was a good lesson for me to think outside of my small box, which I think is necessary to keep learning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hitta-skyddsrum/services/blob/78db77d36a5eddef8ef8b4f8178b64e63e0171d9/e2e/shelters.sh"&gt;You can see the full test suite here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>showdev</category>
      <category>api</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
