<?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>DEV Community: kobima6813</title>
    <description>The latest articles on DEV Community by kobima6813 (@kobima6813).</description>
    <link>https://dev.to/kobima6813</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4196589%2F40972d6e-a4ab-4b64-9d3b-8a0539bb6c09.png</url>
      <title>DEV Community: kobima6813</title>
      <link>https://dev.to/kobima6813</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kobima6813"/>
    <language>en</language>
    <item>
      <title>How to tell if the ubuntu-latest 26.04 migration broke your build</title>
      <dc:creator>kobima6813</dc:creator>
      <pubDate>Tue, 20 Oct 2026 16:46:30 +0000</pubDate>
      <link>https://dev.to/kobima6813/how-to-tell-if-the-ubuntu-latest-2604-migration-broke-your-build-29fn</link>
      <guid>https://dev.to/kobima6813/how-to-tell-if-the-ubuntu-latest-2604-migration-broke-your-build-29fn</guid>
      <description>&lt;p&gt;GitHub is moving the &lt;code&gt;ubuntu-latest&lt;/code&gt; label from Ubuntu 24.04 to &lt;strong&gt;Ubuntu 26.04&lt;/strong&gt;. The rollout is gradual and runs &lt;strong&gt;between October 19 and November 19, 2026&lt;/strong&gt; (&lt;a href="https://github.blog/changelog/2026-09-17-ubuntu-26-generally-available-and-latest-migration/" rel="noopener noreferrer"&gt;GitHub changelog&lt;/a&gt;, &lt;a href="https://github.com/actions/runner-images/issues/14748" rel="noopener noreferrer"&gt;runner-images announcement #14748&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Because it is gradual, one run can land on 24.04 and the next on 26.04, with no change in your repo. If a build that was green yesterday is red today, this is how to check whether the image is the cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Check which image the job actually ran on
&lt;/h2&gt;

&lt;p&gt;Open the failed run and expand the &lt;strong&gt;Set up job&lt;/strong&gt; step. You will see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;Runner Image&lt;/span&gt;
  &lt;span class="s"&gt;Image&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-26.04&lt;/span&gt;
  &lt;span class="s"&gt;Version&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;20261012.163.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare it with the last green run. If the green run says &lt;code&gt;ubuntu-24.04&lt;/code&gt; and the red one says &lt;code&gt;ubuntu-26.04&lt;/code&gt;, you have your prime suspect.&lt;/p&gt;

&lt;p&gt;The same values are available as environment variables in every job, so you can print them explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "ImageOS=$ImageOS ImageVersion=$ImageVersion" &amp;amp;&amp;amp; lsb_release -ds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ImageOS&lt;/code&gt; is &lt;code&gt;ubuntu24&lt;/code&gt; or &lt;code&gt;ubuntu26&lt;/code&gt;. Logging this in every job makes later debugging much faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Confirm by pinning (the fastest test)
&lt;/h2&gt;

&lt;p&gt;Re-run the same commit with the old image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-24.04&lt;/span&gt;   &lt;span class="c1"&gt;# instead of ubuntu-latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Green on 24.04 and red on 26.04 means the image change is the cause.&lt;/li&gt;
&lt;li&gt;Red on both means the cause is something else (a dependency release, a flaky test, your own change).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pinning to &lt;code&gt;ubuntu-24.04&lt;/code&gt; is also the officially suggested escape hatch if you are not ready to move. Treat it as a temporary pin, not a permanent fix.&lt;/p&gt;

&lt;p&gt;To test ahead of time, add a matrix leg:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;os&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ubuntu-24.04&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;ubuntu-26.04&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.os }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Diff the installed software
&lt;/h2&gt;

&lt;p&gt;Each image has a software list in &lt;a href="https://github.com/actions/runner-images/tree/main/images/ubuntu" rel="noopener noreferrer"&gt;actions/runner-images&lt;/a&gt;:&lt;br&gt;
&lt;a href="https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md" rel="noopener noreferrer"&gt;Ubuntu2404-Readme.md&lt;/a&gt; and &lt;a href="https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2604-Readme.md" rel="noopener noreferrer"&gt;Ubuntu2604-Readme.md&lt;/a&gt;. Diff them for the tools your build uses, and check the &lt;a href="https://github.com/actions/runner-images/releases" rel="noopener noreferrer"&gt;releases page&lt;/a&gt; for the exact &lt;code&gt;ImageVersion&lt;/code&gt; you got.&lt;/p&gt;

&lt;p&gt;Differences we saw when comparing the two READMEs on 2026-10-20 (always re-check against the current files):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;Ubuntu 24.04&lt;/th&gt;
&lt;th&gt;Ubuntu 26.04&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Default Python&lt;/td&gt;
&lt;td&gt;3.12&lt;/td&gt;
&lt;td&gt;3.14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default Node.js&lt;/td&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ruby / PHP / Perl&lt;/td&gt;
&lt;td&gt;3.2 / 8.3 / 5.38&lt;/td&gt;
&lt;td&gt;3.3 / 8.5 / 5.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clang&lt;/td&gt;
&lt;td&gt;16–18&lt;/td&gt;
&lt;td&gt;20–22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenSSL&lt;/td&gt;
&lt;td&gt;3.0&lt;/td&gt;
&lt;td&gt;3.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker client&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kernel&lt;/td&gt;
&lt;td&gt;6.x azure&lt;/td&gt;
&lt;td&gt;7.0 azure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java 8 (&lt;code&gt;JAVA_HOME_8_X64&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;present&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;not listed&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Not listed on 26.04&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Fastlane, Julia, Lerna, Mercurial, Miniconda, Newman, Parcel, Pulumi, MediaInfo, Haveged, Sphinx search server&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  4. Common breakages and quick fixes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"command not found"&lt;/strong&gt; for a tool that used to be preinstalled: install it explicitly (&lt;code&gt;setup-*&lt;/code&gt; action, &lt;code&gt;apt-get install&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt;/&lt;code&gt;npm&lt;/code&gt; install) instead of relying on the image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python 3.14 / Node 24 default changes&lt;/strong&gt;: pin the version with &lt;code&gt;actions/setup-python&lt;/code&gt; / &lt;code&gt;actions/setup-node&lt;/code&gt; rather than using whatever the image ships. Watch for removed stdlib/deprecated APIs and native modules that have no wheels/prebuilds yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compiler upgrades&lt;/strong&gt; (newer GCC/Clang): new warnings become errors under &lt;code&gt;-Werror&lt;/code&gt;; old code may need flag changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenSSL 3.5&lt;/strong&gt;: legacy algorithms or old TLS settings in tests can fail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java 8 missing&lt;/strong&gt;: use &lt;code&gt;actions/setup-java&lt;/code&gt; with &lt;code&gt;java-version: 8&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;apt package names changed or removed&lt;/strong&gt;: &lt;code&gt;apt-get install&lt;/code&gt; fails with "Unable to locate package". Check the package name for 26.04 (resolute).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kernel / system changes&lt;/strong&gt;: low-level things (eBPF, ACLs, FUSE, container runtimes) can behave differently. One example reported on day 2 of the rollout: &lt;a href="https://github.com/actions/runner-images/issues/15004" rel="noopener noreferrer"&gt;setfacl fails on Ubuntu 26.04 (#15004)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache keys&lt;/strong&gt;: if your cache key does not include the OS version, a 24.04 cache restored on 26.04 can break native builds. Include &lt;code&gt;${{ runner.os }}-${{ env.ImageOS }}&lt;/code&gt; in the key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you find a real regression in the image, search and report it in &lt;a href="https://github.com/actions/runner-images/issues" rel="noopener noreferrer"&gt;actions/runner-images issues&lt;/a&gt; with the &lt;code&gt;ImageVersion&lt;/code&gt; from step 1.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Tell "it's the image" from "it's just me" across repos
&lt;/h2&gt;

&lt;p&gt;The hard part in a gradual rollout is knowing whether a red build is your problem or everybody's. Disclosure: I built a small free tool for this, &lt;strong&gt;&lt;a href="https://github.com/kobima6813/ci-earlywarn" rel="noopener noreferrer"&gt;CI Early-Warn&lt;/a&gt;&lt;/strong&gt;. A &lt;a href="https://github.com/marketplace/actions/ci-early-warn-beacon" rel="noopener noreferrer"&gt;GitHub Action&lt;/a&gt; reports minimal job metadata (OS, image version, pass/fail, failing-step category; no code, logs or repo names). When failures across many repos jump on a new image version, it raises an alert, and says "ambiguous" when it can't tell the cause. It is early and only useful with enough participants, so steps 1–4 above are the reliable method.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Look at &lt;strong&gt;Set up job → Runner Image&lt;/strong&gt; (or &lt;code&gt;$ImageOS&lt;/code&gt; / &lt;code&gt;$ImageVersion&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Re-run with &lt;code&gt;runs-on: ubuntu-24.04&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Diff the runner-images READMEs for the tools you use.&lt;/li&gt;
&lt;li&gt;Install/pin what you depend on explicitly, then move to 26.04 on your schedule.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Free CI cost audit:&lt;/strong&gt; email your GitHub Actions workflow file(s) to &lt;a href="mailto:conformance@mail.grokbot.com"&gt;conformance@mail.grokbot.com&lt;/a&gt; (subject "CI audit") and I'll reply within 2 business days with a short report on wasted runner minutes and concrete fixes. Workflow YAML only, no secrets or code; files deleted after 30 days.&lt;/p&gt;

</description>
      <category>githubactions</category>
      <category>ubuntu</category>
      <category>devops</category>
      <category>ci</category>
    </item>
  </channel>
</rss>
