Congratulations!

[Valid RSS] This is a valid RSS feed.

Recommendations

This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.

Source: http://arusahni.net/blog/rss.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Entropy</title><link>http://arusahni.net/</link><description>Aru Sahni's personal blog.</description><atom:link href="http://arusahni.net/blog/rss.xml" type="application/rss+xml" rel="self"></atom:link><language>en</language><lastBuildDate>Sun, 07 Apr 2024 14:25:06 GMT</lastBuildDate><generator>https://getnikola.com/</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Repairing a Botched Arch Linux Kernel Upgrade</title><link>http://arusahni.net/blog/2024/04/arch-crash-recovery-chroot.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;I made the jump to Arch Linux on my personal and work computers a few years
  3. ago. Ubuntu was a dependable experience, but a combination of issues with the
  4. Debian way of life (slow progress) and Canonical's stewardship of the project
  5. (e.g., Snaps) convinced me it was time to try another distribution.&lt;/p&gt;
  6. &lt;p&gt;It's been a great experience. Pacman is a wonderful package manager, and AUR is
  7. everything I wanted PPAs to be. I get the latest versions of packages
  8. (including the Linux kernel) shortly after they're released. Of course, that
  9. isn't &lt;em&gt;always&lt;/em&gt; a good thing, but rolling back to an older version is
  10. straightforward.&lt;/p&gt;
  11. &lt;p&gt;I recently stubbed my toe in a way that's unique to Arch - my computer crashed
  12. while I was in the middle of upgrading my kernel. What's great is I was able to
  13. recover with only an hour or so of downtime. What happened?&lt;/p&gt;
  14. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2024/04/arch-crash-recovery-chroot.html"&gt;Read more…&lt;/a&gt; (5 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>linux</category><guid>http://arusahni.net/blog/2024/04/arch-crash-recovery-chroot.html</guid><pubDate>Sun, 07 Apr 2024 02:00:00 GMT</pubDate></item><item><title>Migrating my Neovim Config to Lua</title><link>http://arusahni.net/blog/2022/10/neovim-lua-config.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;I've been a happy &lt;a href="https://neovim.io"&gt;Neovim&lt;/a&gt; user for the past several years.
  15. The pace of development, quality of the product, and energy of the community
  16. have made it enjoyable to use. Recently, the project has introduced
  17. &lt;a href="https://en.wikipedia.org/wiki/Lua_(programming_language)"&gt;Lua&lt;/a&gt; as a first-class
  18. citizen in the editor. In places where you may otherwise be forced to wrangle
  19. the mess that is VimL (aka Vimscript), you can instead use a saner, faster
  20. scripting language.&lt;/p&gt;
  21. &lt;p&gt;I initially refrained from making the jump over to Lua as I held the ideal of
  22. being able to return to Vim whenever I wanted. With the release of Vim version
  23. 8, which doubled down on VimL, I realized my folly. Vim wasn't going to
  24. suddenly adopt the good parts of Neovim, nor was that community going to
  25. change overnight. With that, I sat down one Saturday to get to porting. After a
  26. few weeks of on-and-off experimentation (and exploring both /r/neovim and
  27. GitHub to see how other people did things) , I landed on a stable, Lua-first
  28. config that's been humming along for several weeks now.&lt;/p&gt;
  29. &lt;p&gt;Let's dive in!&lt;/p&gt;
  30. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2022/10/neovim-lua-config.html"&gt;Read more…&lt;/a&gt; (6 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>vim</category><guid>http://arusahni.net/blog/2022/10/neovim-lua-config.html</guid><pubDate>Sun, 20 Nov 2022 23:04:45 GMT</pubDate></item><item><title>How Git Checkout's Previous Branch Shortcut Works Under the Hood</title><link>http://arusahni.net/blog/2021/04/git-revisions.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;One piece of Git shorthand I use all the time is &lt;code&gt;git checkout -&lt;/code&gt;. Much like
  31. &lt;code&gt;cd -&lt;/code&gt;, it references the previous item in your history. In the case of &lt;code&gt;cd&lt;/code&gt;,
  32. it will change your current directory to the previous one you were in. So,&lt;/p&gt;
  33. &lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PWD&lt;/span&gt;
  34. /home/aru
  35. &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;code/git-req
  36. &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PWD&lt;/span&gt;
  37. /home/aru/code/git-req
  38. &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; -
  39. ~
  40. &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PWD&lt;/span&gt;
  41. /home/aru
  42. &lt;/pre&gt;
  43.  
  44.  
  45. &lt;p&gt;Git has its own version of this:&lt;/p&gt;
  46. &lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git branch --show-current
  47. master
  48. &lt;span class="nv"&gt;$ &lt;/span&gt;git checkout my-new-feature
  49. Switched to branch &lt;span class="s1"&gt;'my-new-feature'&lt;/span&gt;
  50. Your branch is up to date with &lt;span class="s1"&gt;'origin/my-new-feature'&lt;/span&gt;.
  51. &lt;span class="nv"&gt;$ &lt;/span&gt;git checkout -
  52. Switched to branch &lt;span class="s1"&gt;'master'&lt;/span&gt;
  53. Your branch is up to date with &lt;span class="s1"&gt;'origin/master'&lt;/span&gt;.
  54. &lt;/pre&gt;
  55.  
  56.  
  57. &lt;p&gt;Handy! But how does it work? I poked through the files in &lt;code&gt;.git&lt;/code&gt; (and even
  58. watched the filesystem for changes, but nothing jumped out).&lt;/p&gt;
  59. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2021/04/git-revisions.html"&gt;Read more…&lt;/a&gt; (3 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>tech</category><guid>http://arusahni.net/blog/2021/04/git-revisions.html</guid><pubDate>Mon, 26 Apr 2021 22:02:51 GMT</pubDate></item><item><title>Elixir Development with Vim</title><link>http://arusahni.net/blog/2020/08/elixir-vim.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;I love Vim (more specifically, &lt;a href="http://neovim.org"&gt;the NeoVim fork&lt;/a&gt;). Modal
  60. editing as part of my
  61. &lt;a href="https://sanctum.geek.nz/arabesque/unix-as-ide-introduction/"&gt;Unix IDE&lt;/a&gt; brings
  62. an immense amount of productivity and enjoyment to my day-to-day development
  63. activities. As such, whenever I take up a new language or framework, I enjoy
  64. experimenting with how best to integrate it into my existing workflow.&lt;/p&gt;
  65. &lt;p&gt;Having started programming in Elixir, I've started the customization journey
  66. for the language.  Much as with Maslow's Hierarchy of Needs, there's a
  67. hierarchy of editor support required for an fulfilling programming experience.
  68. Let's get there with Elixir!&lt;/p&gt;
  69. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2020/08/elixir-vim.html"&gt;Read more…&lt;/a&gt; (3 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>elixir</category><category>tech</category><category>vim</category><guid>http://arusahni.net/blog/2020/08/elixir-vim.html</guid><pubDate>Tue, 25 Aug 2020 17:41:20 GMT</pubDate></item><item><title>Kicking the Tires with Elixir, Part 1 - Pipes</title><link>http://arusahni.net/blog/2020/08/elxir-intro-01.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;Lately I've been playing with Elixir, a functional language that sits over
  70. &lt;a href="https://www.erlang.org/"&gt;Erlang&lt;/a&gt; and
  71. &lt;a href="https://learnyousomeerlang.com/what-is-otp"&gt;the OTP framework&lt;/a&gt;. It's exciting
  72. because it handles embarrassingly scalable problems with aplomb, enabling a
  73. high level of parallelism and concurrency with a great developer experience.
  74. While I think Rust shines at the system programming level, Elixir seems like a
  75. perfect candidate for web services - balancing power with ergonomics.&lt;/p&gt;
  76. &lt;p&gt;There are plenty of well-written posts about the language and its associated
  77. libraries. I wanted to touch on what stood out to me as a Pythonista, web
  78. developer, and nerd. I don't know how many posts will comprise the series, but
  79. I have at least a few topics in mind.&lt;/p&gt;
  80. &lt;p&gt;First up: pipes.&lt;/p&gt;
  81. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2020/08/elxir-intro-01.html"&gt;Read more…&lt;/a&gt; (2 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>elixir</category><category>tech</category><guid>http://arusahni.net/blog/2020/08/elxir-intro-01.html</guid><pubDate>Wed, 12 Aug 2020 21:41:11 GMT</pubDate></item><item><title>Migrating from Gmail to Fastmail</title><link>http://arusahni.net/blog/2020/08/gmail-to-fastmail.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;In 2004, Google launched Gmail. This service changed everything. You didn't
  82. have to worry about running over your few megabytes of quota - your storage
  83. space was "unlimited" (with a ticker and everything)! Deletion was a thing of
  84. the past, you now archive! Folders were so ninety-ninety-late, there
  85. were labels! I got an invite within the first two weeks of it launching, and it
  86. was good.&lt;/p&gt;
  87. &lt;p&gt;A decade or so later, Google launched Inbox, which brought innovations like
  88. bundles, snoozing, highlights, pinning, sweeping, and smart filtering to the
  89. deluge of email that flooded your account each day. I switched from Gmail to
  90. Inbox, and it was better.&lt;/p&gt;
  91. &lt;p&gt;Then, in true Google fashion, it was sacrificed at the altar of project
  92. mismanagement (or whatever the lack of product strategy is called). And it
  93. was bad.&lt;/p&gt;
  94. &lt;p&gt;Since being forced back to Gmail, I've constantly lamented the death of a
  95. service that made dealing with email less painful for me. Gmail is not only
  96. without new innovation, but it's also slow; It regularly fails to load new
  97. messages, or seemingly loses track of what it should be showing, necessitating
  98. a hard refresh. Sure, Google has thrown a few bones at it, like smart replies,
  99. but I respond to so few emails that spending a few seconds to formulate a
  100. response has never been an issue.&lt;/p&gt;
  101. &lt;p&gt;Given these concerns, I realized that the "stickiness" of Gmail was gone.
  102. I have the means to pay for service, and nothing is keeping me on Gmail
  103. (other than the fact that everyone's been using my Gmail address for 16 years).
  104. Leaving Gmail sounded doable, and I owned a personal domain on that I'd love to
  105. use for email. The only question was: where do I go for hosting?&lt;/p&gt;
  106. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2020/08/gmail-to-fastmail.html"&gt;Read more…&lt;/a&gt; (4 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>tech</category><guid>http://arusahni.net/blog/2020/08/gmail-to-fastmail.html</guid><pubDate>Sun, 02 Aug 2020 21:47:35 GMT</pubDate></item><item><title>Optimizing Rust Binary Size</title><link>http://arusahni.net/blog/2020/03/optimizing-rust-binary-size.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;I develop and maintain a git extension called
  107. &lt;a href="https://arusahni.github.io/git-req/"&gt;git-req&lt;/a&gt;. It enables developers to check
  108. out pull requests from GitHub and GitLab by their number instead of branch
  109. name. It initially started out as a bash script that invoked Python for harder
  110. tasks (e.g., JSON parsing). It worked well enough, but I wanted to add
  111. functionality that would have been painful to implement in bash.  Additionally,
  112. one of my goals was to make it as portable as possible, and requiring a Python
  113. distribution be available flew against that. That meant that I needed to
  114. distribute this as a binary instead of a script, so I set about finding a
  115. programming language to use. After surveying what was available, and
  116. determining what would be the best addition to my toolbox, &lt;a href="https://www.rust-lang.org/"&gt;I selected
  117. Rust&lt;/a&gt;.&lt;/p&gt;
  118. &lt;p&gt;The programming language has a steep learning curve, but has been fun to learn
  119. and immerse myself within.  The community is great, and I'm excited to find
  120. more opportunities to use Rust in the future.&lt;/p&gt;
  121. &lt;p&gt;The rewrite took a while to accomplish, but when all was said and done,
  122. everything worked, and worked well.  I was able to implement some snazzy new
  123. features as well as polish some rough edges. However, for how "simple" I felt
  124. the underlying program to be, it clocked in at 13 megabytes. That felt like a
  125. lot.  So, I decided to see what could be done.&lt;/p&gt;
  126. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2020/03/optimizing-rust-binary-size.html"&gt;Read more…&lt;/a&gt; (5 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>code</category><category>rust</category><guid>http://arusahni.net/blog/2020/03/optimizing-rust-binary-size.html</guid><pubDate>Tue, 31 Mar 2020 00:00:05 GMT</pubDate></item><item><title>Elasticsearch Frustration: The Curious Query</title><link>http://arusahni.net/blog/2017/04/elasticsearch-frustration.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;Last year I was poking at an Elasticsearch cluster to review the indexed data
  127. and verify that things were healthy. It was all good until I stumbled upon this
  128. weird document:&lt;/p&gt;
  129. &lt;pre class="code javascript"&gt;&lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-1"&gt;&lt;/a&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  130. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-2"&gt;&lt;/a&gt;  &lt;span class="s2"&gt;"_version"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  131. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-3"&gt;&lt;/a&gt;  &lt;span class="s2"&gt;"_index"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"events"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  132. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-4"&gt;&lt;/a&gt;  &lt;span class="s2"&gt;"_type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  133. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-5"&gt;&lt;/a&gt;  &lt;span class="s2"&gt;"_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"_query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  134. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-6"&gt;&lt;/a&gt;  &lt;span class="s2"&gt;"_score"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  135. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-7"&gt;&lt;/a&gt;  &lt;span class="s2"&gt;"_source"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  136. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-8"&gt;&lt;/a&gt;    &lt;span class="s2"&gt;"query"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  137. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-9"&gt;&lt;/a&gt;      &lt;span class="s2"&gt;"bool"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  138. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-10"&gt;&lt;/a&gt;        &lt;span class="s2"&gt;"must"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  139. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-11"&gt;&lt;/a&gt;          &lt;span class="p"&gt;{&lt;/span&gt;
  140. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-12"&gt;&lt;/a&gt;            &lt;span class="s2"&gt;"range"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  141. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-13"&gt;&lt;/a&gt;              &lt;span class="s2"&gt;"date_created"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  142. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-14"&gt;&lt;/a&gt;                &lt;span class="s2"&gt;"gte"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-01-01"&lt;/span&gt;
  143. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-15"&gt;&lt;/a&gt;              &lt;span class="p"&gt;}&lt;/span&gt;
  144. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-16"&gt;&lt;/a&gt;            &lt;span class="p"&gt;}&lt;/span&gt;
  145. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-17"&gt;&lt;/a&gt;          &lt;span class="p"&gt;}&lt;/span&gt;
  146. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-18"&gt;&lt;/a&gt;        &lt;span class="p"&gt;]&lt;/span&gt;
  147. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-19"&gt;&lt;/a&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
  148. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-20"&gt;&lt;/a&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
  149. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-21"&gt;&lt;/a&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
  150. &lt;a name="rest_code_449e2e266b6741e3ae7d914101720a04-22"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  151. &lt;/pre&gt;&lt;p&gt;It may not be immediately obvious what's going on in the above snippet.
  152. Instead of a valid &lt;code&gt;event&lt;/code&gt; document, there's a document with a query as
  153. the contents. Additionally, the document ID appears to be &lt;code&gt;_query&lt;/code&gt;
  154. instead of the expected GUID. The combination of these two irregularities makes
  155. it seem as if someone accidentally posted a query to the wrong endpoint. No
  156. problem, just delete the document, right?&lt;/p&gt;
  157. &lt;pre class="code text"&gt;&lt;a name="rest_code_d4e473b5b0f64d98b1f9f6914c54dfc2-1"&gt;&lt;/a&gt;DELETE /events/event/_query
  158. &lt;a name="rest_code_d4e473b5b0f64d98b1f9f6914c54dfc2-2"&gt;&lt;/a&gt;ActionRequestValidationException[Validation Failed: 1: source is missing;]
  159. &lt;/pre&gt;&lt;p&gt;Wat.&lt;/p&gt;
  160. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2017/04/elasticsearch-frustration.html"&gt;Read more…&lt;/a&gt; (1 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>elasticsearch</category><category>tech</category><guid>http://arusahni.net/blog/2017/04/elasticsearch-frustration.html</guid><pubDate>Sun, 23 Apr 2017 20:23:28 GMT</pubDate></item><item><title>A DevOps Workflow, Part 3: Deployment</title><link>http://arusahni.net/blog/2017/01/devops-workflow-deployment.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;&lt;em&gt;This series is a longform version of an internal talk I gave at a former
  161. company. It wasn't recorded. It has been mirrored here for posterity.&lt;/em&gt;&lt;/p&gt;
  162. &lt;p&gt;Congratulations, &lt;a href="http://arusahni.net/blog/2017/01/devops-workflow-ci.html"&gt;your code looks good&lt;/a&gt;! Now
  163. all you need to do is put your application in front of your users to discover
  164. all the creative ways they'll break it. In order to do this, we'll have to
  165. create our instances, configure them, and deploy our code.&lt;/p&gt;
  166. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2017/01/devops-workflow-deployment.html"&gt;Read more…&lt;/a&gt; (12 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>devops</category><category>tech</category><guid>http://arusahni.net/blog/2017/01/devops-workflow-deployment.html</guid><pubDate>Thu, 26 Jan 2017 14:48:21 GMT</pubDate></item><item><title>A DevOps Workflow, Part 2: Continuous Integration</title><link>http://arusahni.net/blog/2017/01/devops-workflow-ci.html</link><dc:creator>Aru Sahni</dc:creator><description>&lt;div&gt;&lt;p&gt;&lt;em&gt;This series is a longform version of an internal talk I gave at a former
  167. company. It wasn't recorded. It has been mirrored here for posterity.&lt;/em&gt;&lt;/p&gt;
  168. &lt;p&gt;Look at you – &lt;a href="http://arusahni.net/blog/2017/01/devops-workflow-local-development.html"&gt;all fancy with your consistent and easily-managed development
  169. environment&lt;/a&gt;. However, that's
  170. only half of the local development puzzle. Sure, now developers can no longer
  171. use "it works on my machine" as an excuse, but all that means is they know that
  172. something runs. Without validation, your artisanal ramen may be
  173. indistinguishable from burned spaghetti. This is where unit testing and
  174. continuous integration really prove their worth.&lt;/p&gt;
  175. &lt;p&gt;&lt;a href="http://arusahni.net/blog/2017/01/devops-workflow-ci.html"&gt;Read more…&lt;/a&gt; (6 min remaining to read)&lt;/p&gt;&lt;/div&gt;</description><category>devops</category><category>tech</category><guid>http://arusahni.net/blog/2017/01/devops-workflow-ci.html</guid><pubDate>Thu, 19 Jan 2017 14:48:21 GMT</pubDate></item></channel></rss>

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid RSS" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

http://www.feedvalidator.org/check.cgi?url=http%3A//arusahni.net/blog/rss.xml

Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda