<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.1.1">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2022-09-25T21:59:58+00:00</updated><id>/feed.xml</id><title type="html">agundy</title><subtitle>Writings of a keyboard operator</subtitle><author><name>Aaron Gunderson</name></author><entry><title type="html">The Myth of the Virtuous Driver</title><link href="/2021/10/29/the-myth-of-the-virtuous-driver.html" rel="alternate" type="text/html" title="The Myth of the Virtuous Driver" /><published>2021-10-29T00:00:00+00:00</published><updated>2021-10-29T00:00:00+00:00</updated><id>/2021/10/29/the-myth-of-the-virtuous-driver</id><content type="html" xml:base="/2021/10/29/the-myth-of-the-virtuous-driver.html">&lt;p&gt;This is a riff of &lt;a href=&quot;https://www.cambridgeday.com/2021/10/28/the-myth-of-the-virtuous-cyclist/&quot;&gt;The Myth of the Virtuous Cyclist&lt;/a&gt; a puff editorial piece that seems to think one rule breaking cyclist is proof we need to cancel biking and continue allowing drivers the deference as the sole users of our roads.&lt;/p&gt;

&lt;p&gt;This Wednesday, at about 8pm, in the middle of Beacon St, I saw an SUV run a red turning left across traffic during the walk cycle. As the pedestrian walk light came on, he cut across the opposite traffic lane, across two cross walks to get to a parking lot entrance.  There he parked presumably as a delivery driver who couldn’t wait 60 seconds for a light cycle. I couldn’t imagine why he thought it was okay or what was in his mind, but he seemed unconcerned about the risk he posed to others or that he might be reprimanded.&lt;/p&gt;

&lt;p&gt;Everyone who walks or bikes around in Cambridge knows that flagrant “anything goes” behavior is the normal it has spread among delivery drivers, tractor trailers, work trucks, commuters, Uber drivers and the like.&lt;/p&gt;

&lt;p&gt;This outbreak of norm-breaking by drivers may in part be due to advances in cellphone technology that make driving distracted easier and more enjoyable. It may in part be that continued lax enforcement in driving laws and infrastructure that has long stimulated a desire to push boundaries with wide open lanes to gun it. It may also be generational, a badge of boomer entitlement identity.&lt;/p&gt;

&lt;p&gt;The norm-breaking driver is not alone. A belief that “anything goes” for an extra 10 seconds saved is widespread throughout society, and driving is all about that 10 seconds. Witness the City’s Bicycle Safety Ordinance amendment passed by the City Council in 2020. This remarkable piece of legislation was enacted via Zoom with little discussion by a public who were preoccupied with the pandemic as well as myriad disruptions to normal life and lulled by the proposal’s benign and highly misleading title.&lt;/p&gt;

&lt;p&gt;The law in fact contains a detailed menu and timeline of mandates for the city to build separated bicycle lanes on less than 5% (?) of our of public ways. It briefly references the goal of bicycle safety but none of the other recognized means of improving safety, such as enforcement of traffic regulations, driver re-education or signs. It simply asserts that an elaborate and inflexible plan is necessary to reduce systemic risks to cyclists and makes no provision for evaluation of impacts, or reconsideration as progress is made, circumstances change or new information comes to light. Further, it explicitly privileges needs and lives of local residents over single occupancy car commuters on the public ways.&lt;/p&gt;

&lt;p&gt;In approving this law, councillors showed that they are willing to choose people over cars, protecting lives and livelihoods, to “build the future you want,” the mantra of optimism, that developers are comfortable with a policy that may force settled residents to continue living there normal lives as on average non-drivers. Running reds, distracted driving, honking horns, dangerous passes this is the norm of drivers in Cambridge, I believe we need to break these habits that drivers insist on. It is surprising and encouraging that our local government leaders, our representatives, recognize we cannot just keep prioritizing cars in our spaces.&lt;/p&gt;

&lt;p&gt;We need to support city councillors who are willing to reconsider the timeline and details of the 2020 ordinance speeding it up and expanding it’s scope. They cannot do this without upsetting the minority of entitled residents in our midst, drivers. We build these safe bike networks to remove and reduce the dangers for all citizens, giving walkers and bikers increased space to co-exist without fighting over the scraps left after feeding the space guzzling automobile.&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><summary type="html">This is a riff of The Myth of the Virtuous Cyclist a puff editorial piece that seems to think one rule breaking cyclist is proof we need to cancel biking and continue allowing drivers the deference as the sole users of our roads.</summary></entry><entry><title type="html">Elixir Gitlab CI Example</title><link href="/2021/03/10/elixir-gitlab-ci.html" rel="alternate" type="text/html" title="Elixir Gitlab CI Example" /><published>2021-03-10T00:00:00+00:00</published><updated>2021-03-10T00:00:00+00:00</updated><id>/2021/03/10/elixir-gitlab-ci</id><content type="html" xml:base="/2021/03/10/elixir-gitlab-ci.html">&lt;p&gt;Inspired by &lt;a href=&quot;https://mobile.twitter.com/akoutmos&quot;&gt;@akoutmos&lt;/a&gt;’s tweet on Elixir
test coverage &lt;a href=&quot;https://mobile.twitter.com/akoutmos/status/1369709645993017344&quot;&gt;ExUnit Test Coverage Tweet&lt;/a&gt;,
I wanted to show off how you can integrate this into Gitlab CI for
tracking test coverage in Gitlab.&lt;/p&gt;

&lt;p&gt;At Skylla we have been using Gitlab for source control and CI for a while a
now. I have enjoyed using Gitlab and it works well for us. Gitlab CI has a ton of
different options and ways to use it so I wanted to showcase an Elixir app
pipeline.&lt;/p&gt;

&lt;p&gt;This example will walk through setting up CI tests, test coverage tracking,
linting, and publishing an Elixir release.&lt;/p&gt;

&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;

&lt;p&gt;For this I set up a new mix project with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix new example_gitlab_ci_ex&lt;/code&gt; and set
up a Gitlab repository at
&lt;a href=&quot;https://gitlab.com/agundy/example_gitlab_ci_ex&quot;&gt;agundy/example_gitlab_ci_ex&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;gitlab-ciyml&quot;&gt;.gitlab-ci.yml&lt;/h2&gt;

&lt;p&gt;Gitlab CI reads a file in the root directory and can include templates or other
files in subdirectories. For now everything well be in one file and we’ll set
up which stages our CI pipeline will have and a reusable Elixir helper for
different CI jobs.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;stages&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;publish&lt;/span&gt;

&lt;span class=&quot;s&quot;&gt;.elixir&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;&amp;amp;elixir&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;elixir:1.11&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;before_script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mix local.hex --force&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mix local.rebar --force&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mix deps.get --only $MIX_ENV&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;linting&quot;&gt;Linting&lt;/h2&gt;

&lt;p&gt;Elixir has some nice built in code quality tools. I set up this repo to be
strict, rejecting code that if is not formated or there are any compilation
warnings.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;lint:elixir:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;.elixir&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;stage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;variables&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;MIX_ENV&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mix compile --warnings-as-errors --force&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mix format --check-formatted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you want to be less strict you could remove some of the checks or add
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allow_failure: true&lt;/code&gt; to the block. Allow failure tells Gitlab CI to run the
job but don’t error if the check fails, just show a warning.&lt;/p&gt;

&lt;h2 id=&quot;tests-and-coverage&quot;&gt;Tests and Coverage&lt;/h2&gt;

&lt;p&gt;CI with tests does not provide much value so let’s add a test stage. Here’s a
basic Elixir test stage that will run tests in the repo, reusing that same
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.elixir&lt;/code&gt; job partial.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;test:elixir:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;.elixir&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;stage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;variables&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;MIX_ENV&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mix test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Test coverage is a whole other blog post, I do not believe in 100% code test
coverage or hard requirements but use it as a lossy signal of repository
health. I treat it the same way I do a step counter, good for viewing overall
trends but a poor snapshot judging a specific day/merge request. Updating our
script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix test&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix test --cover&lt;/code&gt; gets us a nice little report for
viewing in the CI output.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/elixir-gitlab-ci/coverage-report.jpg&quot; alt=&quot;Elixir Test Coverage Report&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once we have coverage in CI what else can we do? Gitlab has two features we can
integrate with to get even more information into our merge requests and project
analytics, coverage percentage information and parsed test failure feedback.&lt;/p&gt;

&lt;h3 id=&quot;coverage&quot;&gt;Coverage&lt;/h3&gt;

&lt;p&gt;In the projects CI/CD configuration under “General pipeline settings” is a
“Test coverage parsing” field and the Regex we want to add there is:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\d+.\d+\%\s+\|\s+Total&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;reports&quot;&gt;Reports&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;Gitlab&quot;&gt;Gitlab&lt;/a&gt; supports &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;junit.xml&lt;/code&gt; reports which are a standard for test reports. Elixir
does not export these by default but we can install a package that helps us and
configure it in two steps.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix.exs&lt;/code&gt; add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{:junit_formatter, &quot;~&amp;gt; 3.1&quot;, only: [:test]}&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deps&lt;/code&gt; section.&lt;/li&gt;
  &lt;li&gt;In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test/test_helpers.exs&lt;/code&gt; add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ExUnit.configure(formatters: [JUnitFormatter])&lt;/code&gt; to the top.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this setup jobs will show how many tests and an include timing as well as
test failures in the UI. Here is a merge request with report summaries visible: &lt;a href=&quot;https://gitlab.com/agundy/example_gitlab_ci_ex/-/merge_requests/2&quot;&gt;Gitlab Merge request&lt;/a&gt; and the &lt;a href=&quot;https://gitlab.com/agundy/example_gitlab_ci_ex/-/pipelines/268544955/test_report&quot;&gt;pipeline test summary&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/elixir-gitlab-ci/test-reports.jpg&quot; alt=&quot;Gitlab merge request test reports&quot; /&gt;
&lt;img src=&quot;/assets/img/posts/elixir-gitlab-ci/pipeline-test-summary.jpg&quot; alt=&quot;Gitlab pipeline test summary&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;Our final test CI job will look like this:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;test:elixir:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;.elixir&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;stage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;variables&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;MIX_ENV&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mix test --cover&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;artifacts&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;_build/test/lib/example_gitlab_ci_ex/test-junit-report.xml&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;reports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;junit&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;_build/test/lib/example_gitlab_ci_ex/test-junit-report.xml&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;publishing&quot;&gt;Publishing&lt;/h2&gt;

&lt;p&gt;Elixir has a few different deployment options depending on how and where you
are using the code. At Skylla we use releases and so I’ll show that off here,
I’m sure there are other ways to do this but one way to deploy is to set up a
release, publish it to an artifact and then download it and unpack on whichever
server we are running our app on.&lt;/p&gt;

&lt;p&gt;Configure the app to compile and then compress the project in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix.exs&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-elixir highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;      &lt;span class=&quot;ss&quot;&gt;releases:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;example_gitlab_ci_ex:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;steps:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:assemble&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:tar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;applications:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;runtime_tools:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:permanent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;include_executables_for:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:unix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once it’s packing up a tar we can run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix release&lt;/code&gt; and have a tar under the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_build/ENV&lt;/code&gt; folder. For CI purposes I added a little script to move it up to the
root level and we store it in Gitlab artifacts.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;publish:elixir:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;stage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;publish&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;extends&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;.elixir&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;variables&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;MIX_ENV&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prod&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ARCH&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;amd64&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mix release --overwrite&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ARTIFACT_NAME=&quot;$(find . -name &quot;example_gitlab_ci_ex-*.tar.gz&quot; -exec basename {} .tar.gz \;)&quot;&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mv _build/prod/${ARTIFACT_NAME}.tar.gz ${ARTIFACT_NAME}-${ARCH}.tar.gz&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;artifacts&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;example_gitlab_ci_ex-${CI_COMMIT_REF_SLUG:-CI_COMMIT_SHA}-${ARCH}.tar.gz&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;example_gitlab_ci_ex-*.tar.gz&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;rules&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$CI_COMMIT_TAG&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;$CI_COMMIT_BRANCH&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;$CI_DEFAULT_BRANCH'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;

&lt;p&gt;With this setup we now have an Elixir application that integrates with Gitlab
running tests, linting, and publishing a release artifact that is downloadable
from any server or device we want. Left as an exercise to the reader is getting
the artifact downloaded but you can leverage Gitlab API’s with curl.&lt;/p&gt;

&lt;p&gt;You can explore all the code and the integrations over in Gitlab at
&lt;a href=&quot;https://gitlab.com/agundy/example_gitlab_ci_ex&quot;&gt;agundy/example_gitlab_ci_ex&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some related things we’ve tackled you may find interesting enough to pester me
to blog about include bundling static site docs into an Phoenix release and
cross compiling Elixir for ARM in Gitlab CI.&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><category term="elixir" /><category term="CI" /><category term="Gitlab" /><summary type="html">Inspired by @akoutmos’s tweet on Elixir test coverage ExUnit Test Coverage Tweet, I wanted to show off how you can integrate this into Gitlab CI for tracking test coverage in Gitlab.</summary></entry><entry><title type="html">reMarkable 2 Tablet Review</title><link href="/2020/11/24/reMarkable-tablet-review.html" rel="alternate" type="text/html" title="reMarkable 2 Tablet Review" /><published>2020-11-24T00:00:00+00:00</published><updated>2020-11-24T00:00:00+00:00</updated><id>/2020/11/24/reMarkable-tablet-review</id><content type="html" xml:base="/2020/11/24/reMarkable-tablet-review.html">&lt;p&gt;Belated initial impressions on the &lt;a href=&quot;https://remarkable.com/&quot;&gt;reMarkable 2 tablet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/remarkable-tablet-review/unboxing.webp&quot; alt=&quot;reMarkable tablet, folio and pen boxes stacked&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The hardware feels premium with a nice with a metal border, one part that
really caught my eye is the asymetry of the bezel when comparing the top versus
the bottom of the display. Between the premium materials and the large screen
the device is heavy to hold one handed for long times.&lt;/p&gt;

&lt;p&gt;The pencil feels good in the hand and the writing is 99% of the time fast and
responsive. I say 98% because occasionally I’ve caught the UI spending a split
second catching up to the writing, but this has been rare for me this far.&lt;/p&gt;

&lt;h2 id=&quot;planned-use-cases&quot;&gt;Planned Use Cases&lt;/h2&gt;

&lt;p&gt;I plan on using the device for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Writing and sketching out thoughts and ideas.&lt;/li&gt;
  &lt;li&gt;Reading PDF’s&lt;/li&gt;
  &lt;li&gt;Reading books as EPUB&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;writing&quot;&gt;Writing&lt;/h3&gt;

&lt;p&gt;Writing on the tablet is smooth and easy. My handwriting is roughly the same as
it is on actually notebook paper unlike when I try to write with the Apple
Pencil on my normal iPad.&lt;/p&gt;

&lt;p&gt;One part of the writing experience I need to figure out still is how to handle
a notebook explosion. I have created a bunch of notebooks but probably should
go back down to only a few. I am unsure yet of what referencing old pages and
notes will be like with the electronic setup.&lt;/p&gt;

&lt;h3 id=&quot;reading-pdfs&quot;&gt;Reading PDF’s&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/remarkable-tablet-review/reading-pdf.webp&quot; alt=&quot;Boston Green New Deal PDF&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Reading PDF’s is pretty smooth, it can handle larger books and can use
hyperlinks in the table of contents. There are options for configuring cropping
for the view, setting landscape or portrait mode and a preview list that can be
flipped through. This device has the perfect size eInk display for reading
PDF’s with minimal cropping or fuss.&lt;/p&gt;

&lt;p&gt;Obviously if you read a lot of PDF’s where color is important you will not be
seeing the colors though it tries to render shades of gray.&lt;/p&gt;

&lt;h3 id=&quot;reading-books&quot;&gt;Reading Books&lt;/h3&gt;

&lt;p&gt;EPUB support on the reMarkable needs work. I am a fan of small font for fitting
a lot on a screen but the minimum font size is too large. Some EPUB’s did not
load correctly and could not be read.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/remarkable-tablet-review/broken-epub-render.webp&quot; alt=&quot;EPUB renders black boxes instead of text&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When changing a font or font size with EPUB book it appears to kick off a re-render of
the book which can take a while to complete.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/remarkable-tablet-review/epub-font-choices.webp&quot; alt=&quot;EPUB Font menu with smallest font selected&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;missing-features&quot;&gt;Missing Features&lt;/h2&gt;

&lt;p&gt;A relatively new and small company releasing only their second product means
that it’s not all there. I’ve never used the reMarkable 1 but here are my takes
on the hardware and software for the second generation device.&lt;/p&gt;

&lt;h3 id=&quot;selective-sync&quot;&gt;Selective Sync&lt;/h3&gt;

&lt;p&gt;For privacy purposes I would love to have notebooks that were guaranteed to
stay on device. The software currently allows working fully offline or fully
online. Fully offline means no sending notes, no handwriting to text conversion
or syncing to phone.&lt;/p&gt;

&lt;p&gt;reMarkable does not advertise information about full end to end encryption or
other privacy protecting measures. Though their &lt;a href=&quot;https://support.remarkable.com/hc/en-us/articles/360000416478-reMarkable-s-privacy-policy&quot;&gt;privacy policy&lt;/a&gt;
does a decent job of encouraging me that the data is not being sold or used for
other purposes.&lt;/p&gt;

&lt;h3 id=&quot;read-later-support&quot;&gt;Read Later Support&lt;/h3&gt;

&lt;p&gt;I have been using Pocket for years and have the apps and a huge backlog to work
through. I would love to be able to read Pocket on the tablet.  I have the Kobo
Aura one that integrates with Pocket for reading articles on the run and love
it. Instead of integrating with an existing read it later application
reMarkable has made their own read it later integration that is Chrome only and
because of this I have not been able to try it yet.&lt;/p&gt;

&lt;h3 id=&quot;better-syncing-support&quot;&gt;Better Syncing Support&lt;/h3&gt;

&lt;p&gt;reMarkable has applications for syncing in Windows and Mac OS that I have not
been able to use because I only have Linux computers, so this is only a review
of the experience on Linux.&lt;/p&gt;

&lt;p&gt;Plugging in the tablet to a computers USB port does not expose a USB system
with drag and drop file support in your file browser. Instead to sync to and
from the tablet on Linux a toggle in the settings on the tablet advertises
enabling a web server and lists and IP address that you can type into your web
browser to access the tablet files and drag uploads. This interface is really
rudimentary and can only handle simple upload and download tasks.&lt;/p&gt;

&lt;h2 id=&quot;take-aways&quot;&gt;Take Aways&lt;/h2&gt;

&lt;p&gt;I am enjoying the reMarkable 2 so far it’s great hardware and I love the form
factor and functionality for reading and writing. The software is promising but
needs a lot of work.&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><category term="technology" /><category term="reviews" /><summary type="html">Belated initial impressions on the reMarkable 2 tablet.</summary></entry><entry><title type="html">Affirming Black Lives Matter</title><link href="/2020/07/14/black-lives-matter.html" rel="alternate" type="text/html" title="Affirming Black Lives Matter" /><published>2020-07-14T00:00:00+00:00</published><updated>2020-07-14T00:00:00+00:00</updated><id>/2020/07/14/black-lives-matter</id><content type="html" xml:base="/2020/07/14/black-lives-matter.html">&lt;p&gt;I am affirming that black lives matter.&lt;/p&gt;

&lt;p&gt;Does that upset you?&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;It should not.&lt;/p&gt;

&lt;p&gt;If I say your life matters does that mean your life is the only one that
matters? Of course not. But right now, in American, we need to pronounce that
Black Lives Matter and take a serious hard look at our systems and ensure we
are making them equitable in their distribution of freedom and justice.&lt;/p&gt;

&lt;p&gt;I encourage you to make contributions in your community to help shape a diverse
and equitable future.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Since I work in technology and live in Boston, I wanted to call out two local
programs: Both of these projects help support and empower Black and Latinx to
break and flourish in the tech industry.&lt;/p&gt;

&lt;h3 id=&quot;hackdiversity&quot;&gt;Hack.Diversity&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://hackdiversity.com/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hack.Diversity is a high energy, positive group that I
&lt;a href=&quot;https://medium.com/hack-diversity-movement/automated-testing-strategies-a-software-engineers-competitive-edge-443edd0a11f0&quot;&gt;volunteered with once at BookBub&lt;/a&gt;.
Read how you can support them here: &lt;a href=&quot;https://medium.com/hack-diversity-movement/act-in-solidarity-with-hack-diversity-9eaa45d62e25&quot;&gt;Act in Solidarity with Hack.Diversity&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;resilient-coders&quot;&gt;Resilient Coders&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.resilientcoders.org/&quot;&gt;Website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Resilient Coders is a boot camp to train people of color for careers as
software engineers. I have committed to a monthly monetary donation for them
and encourage you to do the same. &lt;a href=&quot;https://www.resilientcoders.org/donate&quot;&gt;Donate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;If you have the authority and the openings both of these organizations are
looking for placements for their engineers! Hire diverse tech talent, we need
it.&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><category term="culture" /><summary type="html">I am affirming that black lives matter.</summary></entry><entry><title type="html">Gitlab Status Bar</title><link href="/2020/03/20/gitlab-status-bar.html" rel="alternate" type="text/html" title="Gitlab Status Bar" /><published>2020-03-20T00:00:00+00:00</published><updated>2020-03-20T00:00:00+00:00</updated><id>/2020/03/20/gitlab-status-bar</id><content type="html" xml:base="/2020/03/20/gitlab-status-bar.html">&lt;p&gt;&lt;img src=&quot;/assets/img/posts/gitlab-status-bar/status-bar.jpg&quot; alt=&quot;Led status bar image with two green and two blue lights lit in front of git terminal&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Augmenting my workflow and home with unobstrusive intelligent devices has long
been interesting to me. My apartment is decidedly not smart but this has been a
project I was thinking about for a while. I programmed a &lt;a href=&quot;https://www.blinkstick.com/products/blinkstick-strip&quot;&gt;Blinkstick Strip&lt;/a&gt;
as a display bar visualizing the status of continuous integration builds for
Gitlab.&lt;/p&gt;

&lt;p&gt;Status bar is reminiscient of the Canary monitoring project I began back in
college for a class project. Originally inspired by &lt;a href=&quot;https://medium.com/@barshow/the-mailbox-lights-7aa2dae8ba65#.batfmtkxw&quot;&gt;The Mailbox Lights&lt;/a&gt;
the idea is to translate events into a light pattern. An intriguing way to show
the gestalt of a complex system.&lt;/p&gt;

&lt;p&gt;I have a few more ideas on helpful tasks to visualize and I want spend a little
more time honing the project in the future. Introduce some personal and private
&lt;a href=&quot;https://en.wikipedia.org/wiki/Ambient_intelligence&quot;&gt;ambient intelligence&lt;/a&gt; into
my workflow.&lt;/p&gt;

&lt;p&gt;Here is another photo of the bar showcasing the running pipeline visible in
browser and on the bar.
&lt;img src=&quot;/assets/img/posts/gitlab-status-bar/status-bar-with-screen.jpg&quot; alt=&quot;Status bar with one blue light in front of Gitlab CI screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Right now the project is only a couple hours into development and not
complicated but you can still check out the code I wrote on Gitlab
&lt;a href=&quot;https://gitlab.com/agundy/gitlab-status-bar&quot;&gt;here&lt;/a&gt;. Anything you think would
be interesting to visualize this way?&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><category term="gitlab" /><category term="ci" /><category term="ambient-intelligence" /><summary type="html"></summary></entry><entry><title type="html">Ubuntu 18.04 Thinkpad P1 Gen 2 Setup</title><link href="/2019/12/16/ubuntu-18-04-thinkpad-p1-gen-2-setup.html" rel="alternate" type="text/html" title="Ubuntu 18.04 Thinkpad P1 Gen 2 Setup" /><published>2019-12-16T00:00:00+00:00</published><updated>2019-12-16T00:00:00+00:00</updated><id>/2019/12/16/ubuntu-18-04-thinkpad-p1-gen-2-setup</id><content type="html" xml:base="/2019/12/16/ubuntu-18-04-thinkpad-p1-gen-2-setup.html">&lt;p&gt;Skylla recently set up Ubuntu 18.04 on the new Thinkpad P1 Gen 2 and had some
issues with no WiFi drivers after install. Looking for a fix I found &lt;a href=&quot;https://askubuntu.com/a/1184921&quot;&gt;this Stack Overflow answer&lt;/a&gt;
which pointed to the wireless driver issues. They suggested upgrading to Ubuntu
19.04 but this is not an option for work, we need the Long Term Support
version.&lt;/p&gt;

&lt;p&gt;Instead to get this working on Ubuntu 18.04 you can install a newer kernel with:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;linux-generic-hwe-18.04-edge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After this installs reboot and WiFi should be up!&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><category term="linux" /><category term="ubuntu" /><summary type="html">Skylla recently set up Ubuntu 18.04 on the new Thinkpad P1 Gen 2 and had some issues with no WiFi drivers after install. Looking for a fix I found this Stack Overflow answer which pointed to the wireless driver issues. They suggested upgrading to Ubuntu 19.04 but this is not an option for work, we need the Long Term Support version.</summary></entry><entry><title type="html">elementary OS Hera First Impressions</title><link href="/2019/12/14/elementary-os-first-impressions.html" rel="alternate" type="text/html" title="elementary OS Hera First Impressions" /><published>2019-12-14T00:00:00+00:00</published><updated>2019-12-14T00:00:00+00:00</updated><id>/2019/12/14/elementary-os-first-impressions</id><content type="html" xml:base="/2019/12/14/elementary-os-first-impressions.html">&lt;p&gt;My hot take on elementary OS Hera. This is my first install of elementary OS. I
have watched elementary from afar for a few years now and appreciated what it
was doing but never committed to setting it up. I finally did and here is what
I got out of it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/elementary-os-impressions/elementary-desktop.png&quot; alt=&quot;elementary OS Screenshot&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;dislikes&quot;&gt;Dislikes&lt;/h2&gt;

&lt;h3 id=&quot;touchpad&quot;&gt;Touchpad&lt;/h3&gt;

&lt;p&gt;After install I couldn’t get 2 finger scrolling working well.
Not sure where I went wrong. I felt like the touchpad was much jumpier and
lost the mouse a few times before I finally got comfortable using it.&lt;/p&gt;

&lt;h3 id=&quot;keyboard-bindings&quot;&gt;Keyboard Bindings&lt;/h3&gt;

&lt;p&gt;This might be just because I’m coming from Ubuntu but
a lot of the keyboard bindings are slightly off. I know they are trying to
be Mac like but they have taken me a bit to get used to.&lt;/p&gt;

&lt;h3 id=&quot;application-store&quot;&gt;Application Store&lt;/h3&gt;

&lt;p&gt;The store is slick but a bit buggy and not fully featured.&lt;/p&gt;

&lt;p&gt;The main issues I ran into:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Installed applications is an empty list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/elementary-os-impressions/elementary-app-store-installed.png&quot; alt=&quot;Empty App Store install list screenshot&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Screenshot previews struggle to load.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/elementary-os-impressions/elementary-app-store-images.png&quot; alt=&quot;Missing app store images screenshot&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Searching from meta launcher if App Store is already open and filtered to a
category means your global search might return no results, when it should.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;unknown-distro&quot;&gt;Unknown Distro&lt;/h3&gt;

&lt;p&gt;Not a huge surprise but because it’s not a main stream Linux distro
installation for some packages and apt repos fail without minor tweaks.&lt;/p&gt;

&lt;p&gt;I have not installed a ton of software but two I hit already are Erlang/Elixir
and Nodejs. Erlang repos tried using hera instead of bionic for releases and
couldn’t find any packages.&lt;/p&gt;

&lt;p&gt;Nodejs seems to handle elementary OS but had not been updated to include Hera.
I ended up making a &lt;a href=&quot;https://github.com/nodesource/distributions/pull/982&quot;&gt;pull request&lt;/a&gt;
for this on the nodesource/distributions repo.&lt;/p&gt;

&lt;h2 id=&quot;likes&quot;&gt;Likes&lt;/h2&gt;

&lt;h3 id=&quot;ubuntu-base&quot;&gt;Ubuntu Base&lt;/h3&gt;

&lt;p&gt;Being Ubuntu based all the software I’ve needed to run so far has been pretty
easy to get going with little hiccups and a familiar environment.&lt;/p&gt;

&lt;h3 id=&quot;style&quot;&gt;Style&lt;/h3&gt;

&lt;p&gt;elementary OS feels cohesive and well thought out. Theming is consistent,
appealing and practical. The mail application is smooth, the files application
is pretty and over all I dig the attention to cohesive styling.&lt;/p&gt;

&lt;h3 id=&quot;notifications&quot;&gt;Notifications&lt;/h3&gt;

&lt;p&gt;Notifications feel much more native and smooth. It might
get annoying but during setup it was really nice to have the command
finished notifications for terminal commands.&lt;/p&gt;

&lt;p&gt;I also appreciate the notifcations being smaller and in the corner. Gnome
center screen default notifications are annoying to me. The grouping of the
notifications is slick and helpful too.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;elementary OS is coming along nicely. I am not sure I will put it on my primary
work machine yet but I am comfortable dropping it on my home computer and being
productive there. This is a great introduction to well designed open source
operating systems. elementary OS is not on par with Windows or Mac yet on the
just works but it’s a great looking Ubuntu alternative that comes close to
being ready for the masses.&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><category term="os" /><category term="linux" /><summary type="html">My hot take on elementary OS Hera. This is my first install of elementary OS. I have watched elementary from afar for a few years now and appreciated what it was doing but never committed to setting it up. I finally did and here is what I got out of it.</summary></entry><entry><title type="html">Required Reading for Technologists</title><link href="/2019/11/06/required-reading.html" rel="alternate" type="text/html" title="Required Reading for Technologists" /><published>2019-11-06T00:00:00+00:00</published><updated>2019-11-06T00:00:00+00:00</updated><id>/2019/11/06/required-reading</id><content type="html" xml:base="/2019/11/06/required-reading.html">&lt;p&gt;Wired released an article covering what happened with with Uber killing a
pedestrian and it is a 
&lt;a href=&quot;https://www.wired.com/story/ubers-self-driving-car-didnt-know-pedestrians-could-jaywalk/&quot;&gt;sobering read&lt;/a&gt;.
This case study should be required reading for software engineers and CS
majors.&lt;/p&gt;

&lt;p&gt;Working in the technology field there are exciting technologies and things that
can be built but as engineers we are responsible for what we create. Reading
through the article it’s hard to understand everything that went into the
systems faulting but it’s clear it was a systemic engineering failure.&lt;/p&gt;

&lt;p&gt;As engineers building large and safety critical systems there are numerous
complexities and real guarantees are hard, that does not let you skip out.
Safety is a requirement that does not get put second. Never forget that there
are people on the other end of our algorithms.&lt;/p&gt;

&lt;p&gt;Is zero pedestrian deaths by driverless cars possible, no? But there are
preventable deaths and other algorithmic decisions going awry across our
industry, yes. What are you doing to make sure the systems you build do not let
this happen on your projects?&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><summary type="html">Wired released an article covering what happened with with Uber killing a pedestrian and it is a sobering read. This case study should be required reading for software engineers and CS majors.</summary></entry><entry><title type="html">Doing Just Enough</title><link href="/2019/11/04/doing-just-enough.html" rel="alternate" type="text/html" title="Doing Just Enough" /><published>2019-11-04T00:00:00+00:00</published><updated>2019-11-04T00:00:00+00:00</updated><id>/2019/11/04/doing-just-enough</id><content type="html" xml:base="/2019/11/04/doing-just-enough.html">&lt;p&gt;Working on a small team with lots to do, one thing I have been getting better
at it is doing just enough. Finding the highest priority work is hard but once
you find what to do you have to reduce the scope.&lt;/p&gt;

&lt;p&gt;Instead of over building, build enough to unblock and make sure it is done well
enought to last for the needs of the system. Once you have gotten that far
there are a bunch of optimizations, refactors, better engineering, and more
that could be done, DO NOT DO THEM.&lt;/p&gt;

&lt;p&gt;You have what you need; get going on the next task after pushing all the cool
ideas and future work plans into your project management system. You may end up
needing them and you may end up needing something different or the first pass
you complete works well enough for longer than expected.&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><summary type="html">Working on a small team with lots to do, one thing I have been getting better at it is doing just enough. Finding the highest priority work is hard but once you find what to do you have to reduce the scope.</summary></entry><entry><title type="html">Tips for Code Reviews</title><link href="/2019/10/15/tips-for-code-reviews.html" rel="alternate" type="text/html" title="Tips for Code Reviews" /><published>2019-10-15T00:00:00+00:00</published><updated>2019-10-15T00:00:00+00:00</updated><id>/2019/10/15/tips-for-code-reviews</id><content type="html" xml:base="/2019/10/15/tips-for-code-reviews.html">&lt;p&gt;Code reviews are super important for keeping track of changes, learning from team members and improving the quality of your code base. They take a lot of effort and can sometimes be hard to get right. I have compiled a list of things I like to keep in mind when prepping my code for review or doing a review of other’s work.&lt;/p&gt;

&lt;p&gt;Some things to keep in mind when getting your code ready for review by others:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Review your code with a fresh set of eyes before assigning some one else. I struggle to do this one sometimes but it’s a great thing to do to respect your teammate’s time and help you catch things too.&lt;/li&gt;
  &lt;li&gt;Make sure to let your reviewer know expectations of what kind of feedback you need. If it’s just a draft and you want feedback on approach it will be different than a final review before shipping.&lt;/li&gt;
  &lt;li&gt;Try to keep your changes small and atomic. Sometimes this can not be helped but when this happens try to chunk the review into pieces. I try to create commit chains that can be stepped through.&lt;/li&gt;
  &lt;li&gt;Separate the code that you wrote from your ego as much as possible. This is hard to do and most people struggle to do this completely but it’s important that you realize getting feedback should not reflect on you as an individual entirely.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Things to think about when reviewing:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Do not nitpick. Try to recognize when things are personal design opinions versus actual issues. If there are small stylistic suggestions, make clear that it is that and not an actual problem. I like to preface comments like these with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nit:&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Take your time. To do a good review it might take some digging and work on your end. I sometimes end up digging into documentation, sample code libraries and more before giving advice.&lt;/li&gt;
  &lt;li&gt;Do not dismiss choices or make vague suggestions, instead be clear with the problem you see and try to make strides to fix the issue with an alternative name, library or example code.&lt;/li&gt;
  &lt;li&gt;Be careful to balance your remarks with calling out things you like too. Remember there is a person on the other end with feelings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Obviously these are not exhaustive lists, there a lot more things to consider but these are some of the big things I try to keep in mind when reviewing or publishing code to be reviewed.&lt;/p&gt;</content><author><name>Aaron Gunderson</name></author><summary type="html">Code reviews are super important for keeping track of changes, learning from team members and improving the quality of your code base. They take a lot of effort and can sometimes be hard to get right. I have compiled a list of things I like to keep in mind when prepping my code for review or doing a review of other’s work.</summary></entry></feed>