<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>arturz</title><description>Software Engineer</description><link>https://arturz.com</link><item><title>Why opening a PR turns your source branch red in GitHub Actions</title><link>https://arturz.com/blog/why-opening-a-pr-turns-your-source-branch-red-in-github-actions</link><guid isPermaLink="true">https://arturz.com/blog/why-opening-a-pr-turns-your-source-branch-red-in-github-actions</guid><description>How a shared commit hash between your branch and a pull request can turn your passing CI red.</description><pubDate>Tue, 17 Feb 2026 07:30:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Imagine the following scenario: you merge the latest changes to the &lt;em&gt;main&lt;/em&gt; branch, and CI passes ✅. Everything&apos;s looking good!&lt;/p&gt;
&lt;p&gt;You have a standard GitHub Actions workflow that runs CI on every push and pull request on both &lt;em&gt;main&lt;/em&gt; and &lt;em&gt;staging&lt;/em&gt; branches:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;on:
  pull_request:
    branches: [ main, staging ]
  push:
    branches: [ main, staging ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You also have a CD configured that automatically deploys the latest changes from &lt;em&gt;staging&lt;/em&gt; branch, so you create a PR to merge changes from &lt;em&gt;main&lt;/em&gt; to &lt;em&gt;staging&lt;/em&gt; to live test new features in the staging environment.&lt;/p&gt;
&lt;p&gt;Suddenly, CI status on the &lt;em&gt;main&lt;/em&gt; branch changes from ✅ to ❌️.&lt;/p&gt;
&lt;p&gt;What happened?&lt;/p&gt;
&lt;p&gt;You see that the PR failed. GitHub Actions attaches check results to &lt;strong&gt;commit hashes&lt;/strong&gt;, not branches. The status you see on a branch is the status of its latest commit, and since your &lt;em&gt;main&lt;/em&gt; branch and new PR both point to the same commit, the PR&apos;s check failure shows up on &lt;em&gt;main&lt;/em&gt; too.&lt;/p&gt;
&lt;p&gt;If you go into failure details on your &lt;em&gt;main&lt;/em&gt; branch, you&apos;ll see both checks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;❌️ CI / build (pull_request)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;✅ CI / build (push)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And because at least one of them is failing, the whole check is red.&lt;/p&gt;
&lt;h2&gt;What can be done about it&lt;/h2&gt;
&lt;p&gt;A modern DevOps industry standard is to use the &lt;strong&gt;Build Once, Deploy Anywhere&lt;/strong&gt; pattern instead of &lt;strong&gt;environment branching&lt;/strong&gt; to deploy to different environments.&lt;/p&gt;
&lt;p&gt;But there are a lot of legacy codebases and simpler setups out there, and there&apos;s no simple solution that does not have its trade-off.&lt;/p&gt;
&lt;p&gt;You can create a GitHub branch protection rule to only require a &lt;code&gt;push&lt;/code&gt; check on &lt;em&gt;main&lt;/em&gt; for passing ✅. But by the time someone creates a new check, let&apos;s say for E2E tests, you will likely have forgotten about this rule, and it won&apos;t show on &lt;em&gt;main&lt;/em&gt; as a failure ❌️ until someone notices. Right now, it&apos;s not possible to create a rule that requires &lt;strong&gt;all checks except&lt;/strong&gt; &lt;code&gt;pull_request&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can also configure your GitHub Actions workflow not to run checks on PRs to &lt;em&gt;staging&lt;/em&gt;, but then you&apos;ll find out about errors only after they are merged into &lt;em&gt;staging&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Resolution&lt;/h2&gt;
&lt;p&gt;After fixing failing CI on new PR and rerunning checks (or after merging it and pushing new commits to &lt;em&gt;main&lt;/em&gt; branch), the old &lt;code&gt;pull_request&lt;/code&gt; check is overwritten and &lt;em&gt;main&lt;/em&gt; turns green again ✅.&lt;/p&gt;</content:encoded><h:img src="/_astro/transition.CPkBWkCa.png"/><enclosure url="/_astro/transition.CPkBWkCa.png"/></item><item><title>TIL: Ecto preload with a custom query</title><link>https://arturz.com/blog/ecto-preloads-with-custom-query</link><guid isPermaLink="true">https://arturz.com/blog/ecto-preloads-with-custom-query</guid><description>How to use custom queries with Ecto preloads when dealing with filtered associations.</description><pubDate>Thu, 05 Feb 2026 20:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sometimes you may want to pass a custom query to &lt;code&gt;preload&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;There&apos;re department with employees schemata that can be soft-deleted:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-elixir&quot;&gt;# Department schema
defmodule HR.Department do
  use Ecto.Schema

  schema &quot;departments&quot; do
    field :name, :string
    has_many :employees,
      HR.Employee,
      where: [deleted_at: nil]
    timestamps()
  end
end

# Employee schema
defmodule HR.Employee do
  use Ecto.Schema

  schema &quot;employees&quot; do
    field :email, :string
    field :deleted_at, :utc_datetime_usec
    belongs_to :department, HR.Department
    timestamps()
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s say we want to get department info with all employees, including those that were deleted.&lt;/p&gt;
&lt;p&gt;❌️ We cannot just preload it, because &lt;code&gt;has_many&lt;/code&gt; field has &lt;code&gt;where: [deleted_at: nil]&lt;/code&gt; &lt;a href=&quot;https://hexdocs.pm/ecto/Ecto.Schema.html#has_many/3-filtering-associations&quot;&gt;filtering association&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-elixir&quot;&gt;HR.Department
|&gt; preload([_department], :employees)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;❌️ You can pass custom query to preload via joined binding, but it won&apos;t work if you use the &lt;code&gt;assoc&lt;/code&gt; macro which respects filtering associations.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-elixir&quot;&gt;HR.Department
|&gt; join(:left, [department], employees in assoc(department, :employees))
|&gt; preload([_department], {employees, :employees})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;✅ Instead, you need to build your joined binding from scratch:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-elixir&quot;&gt;HR.Department
|&gt; join(:left, [department], employees in HR.Employee, on: department.id == employee.department_id)
|&gt; preload([_department], {employees, :employees})
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/img-rivers-fork.77oulIFv.jpg"/><enclosure url="/_astro/img-rivers-fork.77oulIFv.jpg"/></item><item><title>Introducing Kanta - Translations for Elixir &amp; Phoenix</title><link>https://curiosum.com/blog/introducing-kanta-elixir-phoenix-open-source-translation-tool</link><guid isPermaLink="true">https://curiosum.com/blog/introducing-kanta-elixir-phoenix-open-source-translation-tool</guid><description>An open source solution for handling translations in Elixir and Phoenix applications</description><pubDate>Tue, 05 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Handling translations in web applications can be a challenging and time-consuming task. The process entails managing various files, tracking modifications, and ensuring that translations remain current as the project progresses. These complexities can slow down development and introduce errors. That&apos;s why we decided to create an open source solution: Kanta.&lt;/p&gt;
&lt;p&gt;In this blog post, we&apos;ll explore the problem of managing translations in web apps, and how Kanta simplifies the process. We&apos;ll also compare it with other translation management tools and delve into its powerful plugins.&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>What does AI dream about? Stable Diffusion in Elixir</title><link>https://curiosum.com/blog/what-does-ai-dream-about-stable-diffusion-in-elixir</link><guid isPermaLink="true">https://curiosum.com/blog/what-does-ai-dream-about-stable-diffusion-in-elixir</guid><description>Exploring AI image generation with Stable Diffusion using Elixir</description><pubDate>Mon, 06 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Tools like ChatGPT and DALL·E2 brought immense interest to AI. The go-to language to work with machine learning and artificial intelligence is Python, but market share may shift thanks to some tools created recently in Elixir programming language.&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>TIL: Check if Elixir map has a key in a guard</title><link>https://curiosum.com/til/check-elixir-map-has-key-in-guard</link><guid isPermaLink="true">https://curiosum.com/til/check-elixir-map-has-key-in-guard</guid><description>A quick tip on checking map keys in Elixir guards</description><pubDate>Thu, 22 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today&apos;s Advent of Code puzzle inspired me to create this TIL. It may sound trivial, but in fact, it&apos;s tricky if you are unfamiliar with the nuances of guards&apos; functioning.&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>How to program an IoT device in Elixir using Nerves</title><link>https://curiosum.com/blog/how-program-iot-device-elixir-using-nerves</link><guid isPermaLink="true">https://curiosum.com/blog/how-program-iot-device-elixir-using-nerves</guid><description>Building IoT applications with Elixir and the Nerves framework</description><pubDate>Sat, 30 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Elixir is a great choice language for IoT devices due to its fault-tolerant nature, but also because of the ability to handle a lot of concurrent I/O operations thanks to the BEAM scheduler running under the hood.&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item></channel></rss>