<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>github &amp;mdash; csantosb</title>
    <link>https://infosec.press/csantosb/tag:github</link>
    <description>Random thoughts</description>
    <pubDate>Mon, 18 May 2026 11:16:48 +0000</pubDate>
    <item>
      <title>ci (gitlab/hub)</title>
      <link>https://infosec.press/csantosb/ci-gitlab-hub</link>
      <description>&lt;![CDATA[img br/&#xA;Remote #ci is the way to go in #modernhw digital design testing. In this #ciseries, let’s see it in practice with some detail using two of the most popular forges out there. !--more-- br/&#xA;&#xA;Gitlab&#xA;&#xA;The gitlab #gitforge includes tones of features. Among these, a facility called the container registry, which stores per project container images. Guix pack allows the creation of custom #reproductible environments as images. In particular, it is possible to create a docker image out of our manifest and channels files with br/&#xA;&#xA;guix time-machine -C channels.scm -- pack --compression=xz --save-provenance -f docker -m manifest.scm&#xA;&#xA;Check the documentation for options. br/&#xA;Remember that there are obviously alternative methods to produce docker images. The point on using guix resides on its reproducibility capabilities: you’ll be able to create a new, identical docker image, out of the manifest and channels files at any point in time. Even more: you’ll have the capacity to retrieve your manifest file out of the binary image in case your manifest file gets lost. br/&#xA;Then, this image must be loaded into the local docker store with br/&#xA;&#xA;docker load &lt; IMAGE&#xA;&#xA;and renamed to something meaningful br/&#xA;&#xA;docker tag IMAGE:latest gitlab-registry.whatever.fr/domain/group/NAME:TAG&#xA;&#xA;go remote&#xA;&#xA;img br/&#xA;Finally, pushed to the remote container registry of your project with br/&#xA;&#xA;docker push gitlab-registry.whatever.fr/domain/group/NAME:TAG&#xA;&#xA;At this point, you have an environment where you’ll run your tests using gitlab&#39;s ci features. You’ll set up your gitlab’s runners and manifest files to use this container to execute your jobs. br/&#xA;As an alternative, you could use a ssh executor running on your own fast and powerful hardware resources (dedicated machine, shared cluster, etc.). In this case, you’d rather produce an apptainer  container image with: br/&#xA;&#xA;guix time-machine -C channels.scm -- pack -f squashfs ...&#xA;&#xA;scp this container file to your computing resources and call it from the #gitlab runner. br/&#xA;&#xA;Github&#xA;&#xA;The github is probably the most popular #gitforge out there. It follows a similar to #gitlab in its conception (pull requests and merge requests, you catch the idea ?). It also includes a container registry, and the set of features if offers may be exchanged with ease with any other #gitforge following the same paradigm. No need to go into more details. br/&#xA;There is a couple of interesting tips about using #github, though. It happens more usually than not that users encounter frequently problems of #reproducibility when using container images hosted on ghcr.io, the hosting service for user images. These images are usually employed for running #ci testing pipelines, and they usually break as upstream changes happen: updates, image definition changes, image packages upgrades, etc. If you read my dependencies hell post, this should ring a bell. br/&#xA;What can be done about in what concerns #modernhw ? Well, we have #guix. Let’s try a differente approach: building an image locally, and pushing it to #github registry. Let’s see how. br/&#xA;&#xA;in practice&#xA;&#xA;An example repository shows tha way to proceed. Its contents allow to create a docker container image to be hosted remotely. It includes all that’s necessary to perform remote #ci testing of a #modernhw #vhdl design. br/&#xA;&#xA;docker pull ghcr.io/csantosb/hdl&#xA;docker images # check $ID&#xA;docker run -ti $ID bash&#xA;&#xA;It includes a couple of #plaintext files to produce a #deterministic container. First, the channels.scm file with the list of guix chanels to use to pull packages from. Then, a manifest.scm, with the list of packages to be install within the container. br/&#xA;The image container may be build with br/&#xA;&#xA;image=$(guix time-machine --channels=channels.scm -- \&#xA;             pack -f docker \&#xA;             -S /bin=bin \&#xA;             --save-provenance \&#xA;             -m manifest.scm)&#xA;&#xA;At this point, it is to be load to the docker store with br/&#xA;&#xA;docker load &lt; $image&#xA;docker images&#xA;&#xA;Now it is time to tag the image br/&#xA;&#xA;docker tag IMID ghcr.io/USER/REPO:RELEASE&#xA;&#xA;and login to ghcr.io br/&#xA;&#xA;docker login -u USER -p PASSWORD ghcr.io&#xA;&#xA;Finally, the image is to be push remotely br/&#xA;&#xA;docker push ghcr.io/USER/HDL:RELEASE&#xA;&#xA;test&#xA;&#xA;You’ll may test this image using the neorv32 project, for example, with: br/&#xA;&#xA;docker pull ghcr.io/csantosb/hdl&#xA;docker run -ti ID bash&#xA;git clone --depth=1 https://github.com/stnolting/neorv32&#xA;cd neorv32&#xA;git clone --depth=1 https://github.com/stnolting/neorv32-vunit test&#xA;cd test&#xA;rm -rf neorv32&#xA;ln -sf ../../neorv32 neorv32&#xA;python3 sim/run.py --ci-mode -v&#xA;`]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://git.sr.ht/~csantosb/csbwiki/blob/master/pics/gitlab.png" alt="img"> <br/>
Remote <a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a> is the <a href="https://infosec.press/csantosb/tag:ciseries" rel="nofollow">way to go</a> in <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a> digital design testing. In this <a href="/csantosb/tag:ciseries" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ciseries</span></a>, let’s see it in practice with some detail using two of the most popular forges out there.  <br/></p>

<h1 id="gitlab">Gitlab</h1>

<p>The <a href="https://gitlab.com/" rel="nofollow">gitlab</a> <a href="/csantosb/tag:gitforge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitforge</span></a> includes tones of features. Among these, a facility called the <a href="https://docs.gitlab.com/ee/user/packages/container_registry/" rel="nofollow">container registry</a>, which stores per project container images. <a href="https://infosec.press/csantosb/guix-crash-course#packs" rel="nofollow">Guix pack</a> allows the creation of custom <a href="/csantosb/tag:reproductible" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproductible</span></a> environments as images. In particular, it is possible to create a docker image out of our <a href="https://infosec.press/csantosb/guix-crash-course#manifest-channels" rel="nofollow">manifest and channels files</a> with <br/></p>

<pre><code class="language-sh">guix time-machine -C channels.scm -- pack --compression=xz --save-provenance -f docker -m manifest.scm
</code></pre>

<p>Check the <a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix-pack.html" rel="nofollow">documentation</a> for options. <br/>
Remember that there are obviously alternative methods to produce docker images. The point on using guix resides on its <a href="https://infosec.press/csantosb/use-guix#reproducibility" rel="nofollow">reproducibility</a> capabilities: you’ll be able to create a new, identical docker image, out of the <a href="https://infosec.press/csantosb/guix-crash-course#manifest-channels" rel="nofollow">manifest and channels files</a> at any point in time. Even more: you’ll have the capacity to retrieve your manifest file out of the binary image in case your manifest file gets lost. <br/>
Then, this image must be loaded into the local docker store with <br/></p>

<pre><code class="language-shell">docker load &lt; IMAGE
</code></pre>

<p>and renamed to something meaningful <br/></p>

<pre><code class="language-shell">docker tag IMAGE:latest gitlab-registry.whatever.fr/domain/group/NAME:TAG
</code></pre>

<h2 id="go-remote">go remote</h2>

<p><img src="https://git.sr.ht/~csantosb/csbwiki/blob/master/pics/ci2.png" alt="img"> <br/>
Finally, pushed to the remote container registry of your project with <br/></p>

<pre><code class="language-shell">docker push gitlab-registry.whatever.fr/domain/group/NAME:TAG
</code></pre>

<p>At this point, you have an environment where you’ll run your tests using <a href="https://docs.gitlab.com/ee/ci/" rel="nofollow">gitlab&#39;s ci</a> features. You’ll set up your gitlab’s <a href="https://docs.gitlab.com/runner/" rel="nofollow">runners</a> and <a href="https://docs.gitlab.com/ee/ci/#step-1-create-a-gitlab-ciyml-file" rel="nofollow">manifest files</a> to use this container to execute your jobs. <br/>
As an alternative, you could use a <a href="https://docs.gitlab.com/runner/executors/ssh.html" rel="nofollow">ssh executor</a> running on your own fast and powerful hardware resources (dedicated machine, shared cluster, etc.). In this case, you’d rather produce an apptainer  container image with: <br/></p>

<pre><code class="language-sh">guix time-machine -C channels.scm -- pack -f squashfs ...
</code></pre>

<p><code>scp</code> this container file to your computing resources and call it from the <a href="/csantosb/tag:gitlab" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitlab</span></a> runner. <br/></p>

<h1 id="github">Github</h1>

<p>The <a href="https://github.com/" rel="nofollow">github</a> is probably the most popular <a href="/csantosb/tag:gitforge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitforge</span></a> out there. It follows a similar to <a href="/csantosb/tag:gitlab" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitlab</span></a> in its conception (pull requests and merge requests, you catch the idea ?). It also includes a <a href="https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry" rel="nofollow">container registry</a>, and the set of features if offers may be exchanged with ease with any other <a href="/csantosb/tag:gitforge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitforge</span></a> following the same paradigm. No need to go into more details. <br/>
There is a couple of interesting tips about using <a href="/csantosb/tag:github" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">github</span></a>, though. It happens more usually than not that users encounter frequently problems of <a href="/csantosb/tag:reproducibility" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproducibility</span></a> when using container images hosted on <code>ghcr.io</code>, the hosting service for user images. These images are usually employed for running <a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a> testing pipelines, and they <a href="https://github.com/stnolting/neorv32/issues/1116#issuecomment-2532796271" rel="nofollow">usually break</a> as upstream changes happen: updates, image definition changes, image packages upgrades, etc. If you read my <a href="https://infosec.press/csantosb/on-dependencies" rel="nofollow">dependencies hell</a> post, this should ring a bell. <br/>
What can be done about in what concerns <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a> ? Well, we have <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a>. Let’s try a differente approach: building an image locally, and pushing it to <a href="/csantosb/tag:github" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">github</span></a> registry. Let’s see how. <br/></p>

<h2 id="in-practice">in practice</h2>

<p>An <a href="https://github.com/csantosb/hdl-image.git" rel="nofollow">example repository</a> shows tha way to proceed. Its contents allow to create a docker container image to be hosted remotely. It includes <a href="https://raw.githubusercontent.com/csantosb/hdl-image/refs/heads/master/manifest.scm" rel="nofollow">all that’s necessary</a> to perform remote <a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a> testing of a <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a> <a href="/csantosb/tag:vhdl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">vhdl</span></a> design. <br/></p>

<pre><code class="language-sh">docker pull ghcr.io/csantosb/hdl
docker images # check $ID
docker run -ti $ID bash
</code></pre>

<p>It includes a couple of <a href="/csantosb/tag:plaintext" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">plaintext</span></a> <a href="https://infosec.press/csantosb/guix-crash-course#manifest-channels" rel="nofollow">files</a> to produce a <a href="/csantosb/tag:deterministic" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">deterministic</span></a> container. First, the <a href="https://github.com/csantosb/hdl-image/blob/master/channels.scm" rel="nofollow">channels.scm</a> file with the list of guix chanels to use to pull packages from. Then, a <a href="https://github.com/csantosb/hdl-image/blob/master/manifest.scm" rel="nofollow">manifest.scm</a>, with the list of packages to be install within the container. <br/>
The image container may be <a href="https://git.sr.ht/~csantosb/hdl-image/tree/b1ab9a56802e56e3326c8985bd1b61c93173c5ab/readme.org#L3" rel="nofollow">build</a> with <br/></p>

<pre><code class="language-sh">image=$(guix time-machine --channels=channels.scm -- \
             pack -f docker \
             -S /bin=bin \
             --save-provenance \
             -m manifest.scm)
</code></pre>

<p>At this point, it is to be load to the docker store with <br/></p>

<pre><code class="language-sh">docker load &lt; $image
# docker images
</code></pre>

<p>Now it is time to tag the image <br/></p>

<pre><code class="language-sh">docker tag IMID ghcr.io/USER/REPO:RELEASE
</code></pre>

<p>and login to <code>ghcr.io</code> <br/></p>

<pre><code class="language-sh">docker login -u USER -p PASSWORD ghcr.io
</code></pre>

<p>Finally, the image is to be push remotely <br/></p>

<pre><code class="language-sh">docker push ghcr.io/USER/HDL:RELEASE
</code></pre>

<h2 id="test">test</h2>

<p>You’ll may test this image using the <a href="https://github.com/stnolting/neorv32" rel="nofollow">neorv32</a> project, for example, with: <br/></p>

<pre><code class="language-sh">docker pull ghcr.io/csantosb/hdl
docker run -ti ID bash
git clone --depth=1 https://github.com/stnolting/neorv32
cd neorv32
git clone --depth=1 https://github.com/stnolting/neorv32-vunit test
cd test
rm -rf neorv32
ln -sf ../../neorv32 neorv32
python3 sim/run.py --ci-mode -v
</code></pre>
]]></content:encoded>
      <guid>https://infosec.press/csantosb/ci-gitlab-hub</guid>
      <pubDate>Wed, 11 Dec 2024 12:50:04 +0000</pubDate>
    </item>
  </channel>
</rss>