<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Ray's Dev Blog</title><link>http://blog.cloudy9101.com/posts/</link><description>Recent content in Posts on Ray's Dev Blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 31 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="http://blog.cloudy9101.com/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>How I Cut Our GitHub Actions Pipeline Time by More Than 50%</title><link>http://blog.cloudy9101.com/posts/faster-ci-with-a-base-docker-image/</link><pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate><guid>http://blog.cloudy9101.com/posts/faster-ci-with-a-base-docker-image/</guid><description>&lt;p&gt;&lt;img src="https://images.unsplash.com/photo-1499377193864-82682aefed04?crop=entropy&amp;amp;cs=tinysrgb&amp;amp;fit=max&amp;amp;fm=jpg&amp;amp;ixid=M3wzNjAwOTd8MHwxfHNlYXJjaHwyNHx8dGltZXxlbnwwfDB8fHwxNzc0NTE3NTYxfDA&amp;amp;ixlib=rb-4.1.0&amp;amp;q=80&amp;amp;w=1080" alt="Sand in an hourglass"&gt;
&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@heyquilia?utm_source=Obsidian%20Image%20Inserter%20Plugin&amp;amp;utm_medium=referral" class="external-link" target="_blank" rel="noopener"&gt;Kenny Eliason&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=Obsidian%20Image%20Inserter%20Plugin&amp;amp;utm_medium=referral" class="external-link" target="_blank" rel="noopener"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="problem"&gt;
 Problem
 &lt;a class="heading-link" href="#problem"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Our CI pipeline was taking 20 minutes on average to finish in every pull request. It wasn&amp;rsquo;t reliable either because tools installation would occasionally fail due to network issues or rate limits. Our team needed a faster feedback loop.&lt;/p&gt;
&lt;pre class="mermaid"&gt;
 flowchart TB
	A[PR opened / pushed] --&amp;gt; B[Install tools]
	B --&amp;gt; C[Kubernetes cluster setup]
	C --&amp;gt; D[Build services, Run tests, Lint]
&lt;/pre&gt;

&lt;p&gt;The project is a medium-complexity Go codebase with several microservices. For every PR, each workflow went through the same steps: checkout, install a suite of binary tools, build, test, etc. Build and unit tests were fast by themselves. Most of the time was consumed by installing those binary tools on every single run. And since these installations depended on external networks, they were a constant source of inconsistent failures which led workflows failing for unrelated reasons.
We had been recording per-step timing via OpenTelemetry. Looking at the data, tool installation was repeated on every single run despite never changing between PRs. That was the real target.&lt;/p&gt;</description></item><item><title>Learn In Public</title><link>http://blog.cloudy9101.com/posts/learn-in-public/</link><pubDate>Tue, 24 Jan 2023 00:00:00 +0000</pubDate><guid>http://blog.cloudy9101.com/posts/learn-in-public/</guid><description>&lt;p&gt;&lt;em&gt;I write this blog after I saw the &lt;a href="https://www.swyx.io/learn-in-public/" class="external-link" target="_blank" rel="noopener"&gt;Learn In Public&lt;/a&gt; article from &lt;a href="https://twitter.com/intent/user?screen_name=swyx" class="external-link" target="_blank" rel="noopener"&gt;@swyx&lt;/a&gt;. It&amp;rsquo;s basically my thought or summary of the article.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://images.unsplash.com/reserve/NV0eHnNkQDHA21GC3BAJ_Paris%20Louvr.jpg?crop=entropy&amp;amp;cs=tinysrgb&amp;amp;fit=max&amp;amp;fm=jpg&amp;amp;ixid=MnwzNjAwOTd8MHwxfHNlYXJjaHwxfHxwdWJsaWN8ZW58MHwwfHx8MTY2MjEyNjgzNA&amp;amp;ixlib=rb-1.2.1&amp;amp;q=80&amp;amp;w=1080" alt="Busy stair"&gt;
&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@martinirc?utm_source=obsidian-image-inserter&amp;amp;utm_medium=referral" class="external-link" target="_blank" rel="noopener"&gt;José Martín Ramírez Carrasco&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=obsidian-image-inserter&amp;amp;utm_medium=referral" class="external-link" target="_blank" rel="noopener"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h1 id="what-is-learn-in-public"&gt;
 What is Learn In Public
 &lt;a class="heading-link" href="#what-is-learn-in-public"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Most people learn in private include myself. We want to grow. We want to be an expert. We keep learning hardly day by day. We consume lots of contents like blogs, tutorials, youtube videos etc. All those hard works make us think that we are great and we will grow and be an expert eventually. But that&amp;rsquo;s not quite right. That&amp;rsquo;s what called learn in private.
Learn in public means we publish things about what we are learning. It could be a blog written by us, a video make by us, talking at conference, contribute to open source project, a twitter thread etc.
&lt;strong&gt;It means we need to produce something whenever we learned anything.&lt;/strong&gt; No matter what the knowledge is and how small it is.&lt;/p&gt;</description></item><item><title>Build an Obsidian Image Inserter Plugin</title><link>http://blog.cloudy9101.com/posts/build-an-obsidian-image-inserter-plugin/</link><pubDate>Sun, 22 Jan 2023 00:00:00 +0000</pubDate><guid>http://blog.cloudy9101.com/posts/build-an-obsidian-image-inserter-plugin/</guid><description>&lt;p&gt;&lt;img src="https://images.unsplash.com/photo-1452860606245-08befc0ff44b?crop=entropy&amp;amp;cs=tinysrgb&amp;amp;fit=max&amp;amp;fm=jpg&amp;amp;ixid=MnwzNjAwOTd8MHwxfHNlYXJjaHw2fHx0b29sfGVufDB8MHx8fDE2NjM0MDE1MTg&amp;amp;ixlib=rb-1.2.1&amp;amp;q=80&amp;amp;w=1080" alt="Everything"&gt;
&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@joszczepanska?utm_source=Obsidian%20Image%20Inserter%20Plugin&amp;amp;utm_medium=referral" class="external-link" target="_blank" rel="noopener"&gt;Jo Szczepanska&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=Obsidian%20Image%20Inserter%20Plugin&amp;amp;utm_medium=referral" class="external-link" target="_blank" rel="noopener"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h1 id="why-need-a-plugin"&gt;
 Why need a plugin
 &lt;a class="heading-link" href="#why-need-a-plugin"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Recently I use Obsidian as my note taking app and try to build a second brain based on it.
Obsidian is a note taking application based on markdown files. Plugin system is an awesome feature in Obsidian.
When writing blogs with Obsidian, sometimes I need to insert a related but random image to my blog to make it not that boring. So I&amp;rsquo;m thinking it would be great if I can search and insert image from &lt;a href="https://unsplash.com" class="external-link" target="_blank" rel="noopener"&gt;Unsplash&lt;/a&gt; inside Obsidian editor without leaving the editor and open browser tab to get the image.&lt;/p&gt;</description></item></channel></rss>