<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>ciseries &amp;mdash; csantosb</title>
    <link>https://infosec.press/csantosb/tag:ciseries</link>
    <description>Random thoughts</description>
    <pubDate>Wed, 13 May 2026 22:30:39 +0000</pubDate>
    <item>
      <title>sourcehut as guix test farm</title>
      <link>https://infosec.press/csantosb/sourcehut-as-guix-test-farm</link>
      <description>&lt;![CDATA[img br/&#xA;It is possible to contribute to improving #guix as the need for new functionalities, packages, fixes or upgrades arise. This is one of the strongest points in open communities: the possibility to participate on the development and continuous improvement of the tool. Let’s see how it goes when it comes to guix.!--more-- br/&#xA;Guix is a huge project which follows closely the #freesoftware paradigm, and collaboration works in two directions. You take advantage of other developers contributions to guix, while you participate yourself to improving guix repositories with your fixes, updates or new features, once they have been tested. In a first approach, from my own experience, one may create a personal local repository of package definitions, for a personal use. As a second step, it is possible to create a public guix channel, in parallel to contributing upstream. br/&#xA;Contributing your code to guix comes to sending #email with your patches attached, it’s that simple. Don&#39;t be intimidated by the details (this is used by lots of open communities, after all). Once your patches are submitted, a review of your code follows, see details. Some tools, like mumi, are helpful to that purpose. br/&#xA;&#xA;In detail&#xA;&#xA;Following the kind of contribution (new additions, fixes or upgrades), these simple steps will allow you to start contributing to guix: br/&#xA;&#xA;    git clone guix itselft br/&#xA;    from the guix repository, do: br/&#xA;    &#xA;        guix shell -D guix -CPW&#xA;    ./bootstrap&#xA;    ./configure&#xA;    make -j$(nproc)&#xA;    ./pre-inst-env guix build hello&#xA;        add and commit your changes, watch the commit message br/&#xA;    beware your synopses and descriptions br/&#xA;    remember to run the package tests, if relevant br/&#xA;    check the license br/&#xA;    use an alphabetical order in input lists br/&#xA;    no sign off your commits br/&#xA;    don’t forget to use lint/style/refresh -l/dependents to check your code br/&#xA;&#xA;Boring and routinary, right ? br/&#xA;&#xA;Use sourcehut&#xA;&#xA;img br/&#xA;Most of all the of the previous can be run automatically with help of sourcehut build farm #ci capabilities. Just simply, push the guix repository to sr.ht. At this point, it is possible to use this manifest file to run the lint/style/refresh -l/dependents testing stages on the yosys package definition, por example: br/&#xA;&#xA;image: guix&#xA;shell: true&#xA;environment:&#xA;  prj: guix.guix&#xA;  cmd: &#34;guix shell -D guix -CPWN git nss-certs -- ./pre-inst-env guix&#34;&#xA;sources:&#xA;  https://git.sr.ht/~csantosb/guix.guix&#xA;tasks:&#xA;  defpkg: |&#xA;      cd &#34;$prj&#34;&#xA;      pkg=$(git log -1 --oneline | cut -d&#39;:&#39; -f 2 | xargs)&#xA;      echo &#34;export pkg=$pkg&#34;     &#34;$HOME/.buildenv&#34;&#xA;  setup: |&#xA;      cd &#34;$prj&#34;&#xA;      guix shell -D guix -CPW -- ./bootstrap&#xA;      guix shell -D guix -CPW -- ./configure&#xA;      guix shell -D guix -CPW -- make -j $(nproc)&#xA;  build: |&#xA;      cd &#34;$prj&#34;&#xA;      eval &#34;$cmd build --rounds=5 $pkg&#34;&#xA;  lint: |&#xA;      cd &#34;$prj&#34;&#xA;      eval &#34;$cmd lint $pkg&#34;&#xA;  style: |&#xA;      cd &#34;$prj&#34;&#xA;      eval &#34;$cmd style $pkg --dry-run&#34;&#xA;  refresh: |&#xA;      cd &#34;$prj&#34;&#xA;      eval &#34;$cmd refresh -l $pkg&#34;&#xA;  dependents: |&#xA;      cd &#34;$prj&#34;&#xA;      eval &#34;$cmd build --dependents $pkg&#34;&#xA;triggers:&#xA;  condition: failure&#xA;    action: email&#xA;    to: builds.sr.ht@csantosb.mozmail.com&#xA;&#xA;Submit the manifest with br/&#xA;&#xA;hut builds submit # --edit&#xA;&#xA;You’ll be able to log into the build farm to follow the build process or to debug it with br/&#xA;&#xA;hut builds ssh ID&#xA;&#xA;Check the log here. As you can see, it fails: building of yosys succeeds, but building of packages which depend on it (--dependents) fails. br/&#xA;&#xA;Advanced&#xA;&#xA;Sourcehut provides a facility to automatize patch submission and testing. Using its hub integrator, one may just send an email to the email list related to your project (guix in this case), which mimics guix behavior for accepting patches. br/&#xA;The trick here consists on appending the project name as a prefix to the subject of the message, for example PATCH project-name], which will trigger the build of previous [.build.yml manifest file at the root of the project, after applying the patch. Neat, right ? br/&#xA;If you followed right here, you’ll notice that previous build manifest file is monolithic, affecting always the same package (yosys), which is kind of useless, as we are here interested in testing our patch. Thus, the question on how to trigger a custom build containing an updated $pkg variable related to the patch to test remains open. br/&#xA;To update the contents of the $pkg variable in the build manifest, one has to parse the commit message in the patch, extracting from there the package name. This is not a problem, as guix imposes clear commit messages in patches, so typically something like br/&#xA;&#xA;gnu: gnunet: Update to 0.23.0&#xA;&#xA;or br/&#xA;&#xA;gnu: texmacs: Add qtwayland-5&#xA;&#xA;Hopefully, parsing these messages to get the package name, and so the value of $pkg is trivial. br/&#xA;Then, it remains to include in our build manifest a first task which updates the contents of &#34;$HOME/.buildenv&#34;. This file is automatically populated using the environment variables in the manifest, and its contents are sourced at the beginning of all tasks. This mechanism allows passing variables between tasks. br/&#xA;&#xA;echo &#34;export pkg=value&#34;     &#34;$HOME/.buildenv&#34;&#xA;&#xA;Send your contribution&#xA;&#xA;Finally, once your changes go through all the tests, br/&#xA;&#xA;    use git send-email to create and send a patch br/&#xA;    consider reviews, if any, updating your patch accordingly with git ammend br/&#xA;    resend a new patch including a patch version (v1, v2 ...) br/&#xA;&#xA;Interested ? Consult the documentation for details, you’ll learn a lot about how to contribute to a common good and collaboration with other people. br/&#xA;ciseries br/]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://git.sr.ht/~csantosb/blog.csantosb/blob/master/pics/guix.png" alt="img"> <br/>
It is possible to contribute to improving <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a> as the need for new functionalities, packages, fixes or upgrades arise. This is one of the strongest points in open communities: the possibility to participate on the development and continuous improvement of the tool. Let’s see how it goes when it comes to <a href="https://guix.gnu.org/" rel="nofollow">guix</a>. <br/>
Guix is a huge project which follows closely the <a href="/csantosb/tag:freesoftware" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">freesoftware</span></a> paradigm, and collaboration works in two directions. You take advantage of other developers contributions to guix, while you participate yourself to improving guix repositories with your fixes, updates or new features, once they have been tested. In a first approach, from my own experience, one may create a personal local repository of package definitions, for a personal use. As a second step, it is possible to create a public <a href="https://infosec.press/csantosb/guix-channels" rel="nofollow">guix channel</a>, in parallel to <a href="https://infosec.press/csantosb/guix-channels#contributing" rel="nofollow">contributing</a> upstream. <br/>
<a href="https://guix.gnu.org/manual/en/html_node/Contributing.html" rel="nofollow">Contributing</a> your code to guix comes to <a href="https://git-send-email.io/" rel="nofollow">sending <a href="/csantosb/tag:email" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">email</span></a></a> <a href="https://www.futurile.net/2022/03/07/git-patches-email-workflow/" rel="nofollow">with your patches</a> attached, it’s that simple. Don&#39;t be intimidated by the details (this is used by lots of open communities, after all). Once your patches are submitted, a review of your code follows, see <a href="https://libreplanet.org/wiki?title=Group:Guix/PatchReviewSessions2024" rel="nofollow">details</a>. Some tools, like <a href="https://www.youtube.com/watch?v=8m8igXrKaqU" rel="nofollow">mumi</a>, are helpful to that purpose. <br/></p>

<h1 id="in-detail">In detail</h1>

<p>Following the kind of contribution (new additions, fixes or upgrades), these simple steps will allow you to start contributing to guix: <br/></p>

<p>    git clone <a href="https://git.savannah.gnu.org/git/guix.git" rel="nofollow">guix itselft</a> <br/>
    from the guix repository, do: <br/></p>

<p>    <code>sh
    guix shell -D guix -CPW
    ./bootstrap
    ./configure
    make -j$(nproc)
    ./pre-inst-env guix build hello
</code>
    add and commit your changes, watch the commit message <br/>
    beware your <a href="https://guix.gnu.org/manual/en/html_node/Synopses-and-Descriptions.html" rel="nofollow">synopses and descriptions</a> <br/>
    remember to run the package tests, if relevant <br/>
    check the license <br/>
    use an alphabetical order in input lists <br/>
    no sign off your commits <br/>
    don’t forget to use <code>lint/style/refresh -l/dependents</code> to check your code <br/></p>

<p>Boring and routinary, right ? <br/></p>

<h1 id="use-sourcehut">Use sourcehut</h1>

<p><img src="https://git.sr.ht/~csantosb/blog.csantosb/blob/master/pics/sourcehut.png" alt="img"> <br/>
Most of all the of the previous can be run automatically with help of <a href="https://infosec.press/csantosb/tag:ciseries" rel="nofollow">sourcehut</a> build farm <a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a> capabilities. Just simply, push the guix repository to <a href="https://git.sr.ht/~csantosb/guix.guix" rel="nofollow">sr.ht</a>. At this point, it is possible to use <a href="https://builds.sr.ht/~csantosb/job/1391146/manifest" rel="nofollow">this manifest</a> file to run the <code>lint/style/refresh -l/dependents</code> testing stages on the <code>yosys</code> package definition, por example: <br/></p>

<pre><code class="language-yaml">image: guix
shell: true
environment:
  prj: guix.guix
  cmd: &#34;guix shell -D guix -CPWN git nss-certs -- ./pre-inst-env guix&#34;
sources:
  - https://git.sr.ht/~csantosb/guix.guix
tasks:
  - def_pkg: |
      cd &#34;$prj&#34;
      _pkg=$(git log -1 --oneline | cut -d&#39;:&#39; -f 2 | xargs)
      echo &#34;export pkg=$_pkg&#34; &gt;&gt; &#34;$HOME/.buildenv&#34;
  - setup: |
      cd &#34;$prj&#34;
      guix shell -D guix -CPW -- ./bootstrap
      guix shell -D guix -CPW -- ./configure
      guix shell -D guix -CPW -- make -j $(nproc)
  - build: |
      cd &#34;$prj&#34;
      eval &#34;$cmd build --rounds=5 $pkg&#34;
  - lint: |
      cd &#34;$prj&#34;
      eval &#34;$cmd lint $pkg&#34;
  - style: |
      cd &#34;$prj&#34;
      eval &#34;$cmd style $pkg --dry-run&#34;
  - refresh: |
      cd &#34;$prj&#34;
      eval &#34;$cmd refresh -l $pkg&#34;
  - dependents: |
      cd &#34;$prj&#34;
      eval &#34;$cmd build --dependents $pkg&#34;
triggers:
  - condition: failure
    action: email
    to: builds.sr.ht@csantosb.mozmail.com
</code></pre>

<p>Submit the manifest with <br/></p>

<pre><code class="language-sh">hut builds submit # --edit
</code></pre>

<p>You’ll be able to log into the build farm to follow the build process or to debug it with <br/></p>

<pre><code class="language-sh">hut builds ssh ID
</code></pre>

<p>Check the log <a href="https://builds.sr.ht/~csantosb/job/1391146" rel="nofollow">here</a>. As you can see, it fails: building of <code>yosys</code> succeeds, but building of packages which depend on it (<code>--dependents</code>) <a href="https://builds.sr.ht/~csantosb/job/1391146#task-dependents" rel="nofollow">fails</a>. <br/></p>

<h1 id="advanced">Advanced</h1>

<p>Sourcehut provides a facility to automatize <a href="https://man.sr.ht/builds.sr.ht/#integrations" rel="nofollow">patch submission and testing</a>. Using its <code>hub</code> integrator, one may just send an email to the email list related to your project (guix in this case), which mimics guix behavior for accepting patches. <br/>
The trick here consists on appending the project name as a prefix to the subject of the message, for example <code>[PATCH project-name]</code>, which will trigger the build of previous <a href="https://builds.sr.ht/~csantosb/job/1391146/manifest" rel="nofollow">.build.yml</a> manifest file at the root of the project, after applying the patch. Neat, right ? <br/>
If you followed right here, you’ll notice that previous build manifest file is monolithic, affecting always the same package (yosys), which is kind of useless, as we are here interested in testing our patch. Thus, the question on how to trigger a custom build containing an updated <code>$pkg</code> variable related to the patch to test remains open. <br/>
To update the contents of the <code>$pkg</code> variable in the build manifest, one has to parse the commit message in the patch, extracting from there the package name. This is not a problem, as guix imposes clear commit messages in patches, so typically something like <br/></p>

<pre><code class="language-sh">* gnu: gnunet: Update to 0.23.0
</code></pre>

<p>or <br/></p>

<pre><code class="language-sh">* gnu: texmacs: Add qtwayland-5
</code></pre>

<p>Hopefully, parsing these messages to get the package name, and so the value of <code>$pkg</code> is trivial. <br/>
Then, it remains to include in our build manifest a first task which updates the contents of <code>&#34;$HOME/.buildenv&#34;</code>. This file is automatically populated using the environment variables in the manifest, and its contents are sourced at the beginning of all tasks. This mechanism allows passing variables between tasks. <br/></p>

<pre><code class="language-sh">echo &#34;export pkg=value&#34; &gt;&gt; &#34;$HOME/.buildenv&#34;
</code></pre>

<h1 id="send-your-contribution">Send your contribution</h1>

<p>Finally, once your changes go through all the tests, <br/></p>

<p>    use <a href="https://git-send-email.io/" rel="nofollow">git send-email</a> to create and <a href="https://guix.gnu.org/manual/en/html_node/Submitting-Patches.html" rel="nofollow">send a patch</a> <br/>
    consider reviews, if any, updating your patch accordingly with <code>git ammend</code> <br/>
    resend a new patch including a patch version (v1, v2 ...) <br/></p>

<p>Interested ? Consult <a href="https://guix.gnu.org/manual/en/html_node/Contributing.html" rel="nofollow">the documentation</a> for details, you’ll learn a lot about how to contribute to a common good and collaboration with other people. <br/>
<a href="/csantosb/tag:ciseries" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ciseries</span></a> <br/></p>
]]></content:encoded>
      <guid>https://infosec.press/csantosb/sourcehut-as-guix-test-farm</guid>
      <pubDate>Tue, 17 Dec 2024 16:57:05 +0000</pubDate>
    </item>
    <item>
      <title>ci (sourcehut): alu</title>
      <link>https://infosec.press/csantosb/ci-sourcehut-alu</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 how to implement it with detail using sourcehut and a real world example. !--more-- br/&#xA;Sourcehut is a lightweight #gitforge where I host my #git repositories. Not only it is based on a paradigm perfectly adapted to #modernhw, but also its builds service includes support for guix (x8664) images. This means that we will be able to execute all of our testing online inside guix profiles, shells or natively on top of the bare-bones image. br/&#xA;&#xA;Alu&#xA;&#xA;Let’s consider now a variant of the previous example with open-logic. Here, we concentrate on a toy design only for demonstration purposes, a dummy alu emulator, which uses #osvvm as verification framework and relies on a few #openlogic blocs. In this case, its dependencies are defined in a manifest.scm file, including both fw-open-logic and osvvm, among other dependencies. br/&#xA;Install dependencies locally, in a new profile with br/&#xA;&#xA;cd alu&#xA;mkdir deps&#xA;export GUIXPROFILE=open-logic/deps&#xA;guix install -P $GUIXPROFILE -m .builds/manifest.scm&#xA;. $GUIXPROFILE/etc/profile&#xA;&#xA;In this case, we will test the design using, first, a custom made makefile. Secondly, we will use hdlmake to automatically produce our makefile. Similarly to previous #openlogic example, two build manifest are used: br/&#xA;&#xA;    profile1 br/&#xA;    profile2 br/&#xA;&#xA;You’ll realise how some of the tasks are common with the case of previous #openlogic example (update channels, auth and update profile). br/&#xA;&#xA;osvvm&#xA;&#xA;In this case, we also need to compile osvvm libraries br/&#xA;&#xA;    compile\_osvvm, produce a compiled version of #osvvm verification libraries; this is necessary as we are using here the tcl  scripts included in the library itself to follow the correct order of compilation. Libraries will appear within the local profile under $GUIXPROFILE/VHDLLIBS/GHDL-X.Y.Z br/&#xA;&#xA;test&#xA;&#xA;    test, for a fully custom made testing pipeline; in this case, using a Makefile br/&#xA;    Just simply, source the .envrc file where the local $GUIXPROFILE variable is defined, cd to the ghdl directory and call make to compile the design and run the simulation in two steps: first, clean all and include sources in its corresponding libraries with br/&#xA;    &#xA;        make cleanall include&#xA;        &#xA;    Then, produce a new Makefile using ghdl. br/&#xA;    &#xA;        ./makefile.sh # ghdl --gen-makefile ...&#xA;        &#xA;    Finally, run the simulation with br/&#xA;    &#xA;        make GHDLRUNFLAGS=&#34;--stop-time=4us --disp-time --ieee-asserts=enable&#34; run&#xA;        &#xA;    This will produce a executable file before running it with the provided parameters. br/&#xA;    You may notice that, in this case, you need to produce somehow your own Makefile, or equivalent pipeline, right ? br/&#xA;&#xA;hdlmake&#xA;&#xA;Wouldn’t it be nice if we had a tool to deploy online which produces makefiles for us ? It exists, and its name is #hdlmake. br/&#xA;&#xA;    test\hdlmake br/&#xA;    Source the .envrc file where the local $GUIXPROFILE variable is defined, cd to the .builds/hdlmake directory where all Manifest.py files are located, and call hdlmake to produce the Makefile. Finally, just run make to compile the design, produce an executable and run it. br/&#xA;&#xA;Check the resulting logs inline here, for example. br/]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://git.sr.ht/~csantosb/csbwiki/blob/master/pics/sourcehut.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 how to implement it with detail using <a href="https://sourcehut.org/" rel="nofollow">sourcehut</a> and a real world example.  <br/>
<a href="https://infosec.press/csantosb/sourcehut-crash-course" rel="nofollow">Sourcehut</a> is a lightweight <a href="/csantosb/tag:gitforge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitforge</span></a> where I host my <a href="/csantosb/tag:git" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">git</span></a> repositories. Not only it is <a href="https://infosec.press/csantosb/git-forges#sourcehut" rel="nofollow">based on a paradigm</a> perfectly adapted to <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a>, but also its <a href="https://infosec.press/csantosb/sourcehut-crash-course#builds" rel="nofollow">builds</a> service includes support for <a href="https://man.sr.ht/builds.sr.ht/compatibility.md#guix-system" rel="nofollow">guix</a> (x86_64) images. This means that we will be able to execute all of our testing online inside <a href="https://infosec.press/csantosb/guix-crash-course#profiles-and-generations" rel="nofollow">guix profiles</a>, <a href="https://infosec.press/csantosb/guix-crash-course#shell-containers" rel="nofollow">shells</a> or natively on top of the bare-bones image. <br/></p>

<h1 id="alu">Alu</h1>

<p>Let’s consider now a variant of the <a href="https://infosec.press/csantosb/ci-sourcehut" rel="nofollow">previous example with open-logic</a>. Here, we concentrate on a <a href="https://git.sr.ht/~csantosb/ip.alu/tree" rel="nofollow">toy design</a> only for demonstration purposes, a <a href="https://git.sr.ht/~csantosb/ip.alu/tree/master/item/src/alu.vhd" rel="nofollow">dummy alu emulator</a>, which uses <a href="/csantosb/tag:osvvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">osvvm</span></a> as verification framework and relies on a few <a href="/csantosb/tag:openlogic" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">openlogic</span></a> blocs. In this case, its dependencies are defined in a <a href="https://git.sr.ht/~csantosb/ip.alu/tree/test/item/.builds/manifest.scm" rel="nofollow">manifest.scm</a> file, including both <code>fw-open-logic</code> and <code>osvvm</code>, among other dependencies. <br/>
Install dependencies locally, in a new <a href="https://infosec.press/csantosb/guix-crash-course#profiles-and-generations" rel="nofollow">profile</a> with <br/></p>

<pre><code class="language-sh">cd alu
mkdir _deps
export GUIX_PROFILE=open-logic/_deps
guix install -P $GUIX_PROFILE -m .builds/manifest.scm
. $GUIX_PROFILE/etc/profile
</code></pre>

<p>In this case, we will test the design using, first, a custom made makefile. Secondly, we will use <a href="https://hdlmake.readthedocs.io/en/master/" rel="nofollow">hdlmake</a> to automatically produce our makefile. Similarly to <a href="https://infosec.press/csantosb/ci-sourcehut" rel="nofollow">previous</a> <a href="/csantosb/tag:openlogic" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">openlogic</span></a> example, two build manifest are used: <br/></p>

<p>    <a href="https://git.sr.ht/~csantosb/ip.alu/tree/test/item/.builds/profile1.yml" rel="nofollow">profile1</a> <br/>
    <a href="https://git.sr.ht/~csantosb/ip.alu/tree/test/item/.builds/profile2.yml" rel="nofollow">profile2</a> <br/></p>

<p>You’ll realise how some of the tasks are common with the case of previous <a href="/csantosb/tag:openlogic" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">openlogic</span></a> example (update channels, auth and update profile). <br/></p>

<h2 id="osvvm">osvvm</h2>

<p>In this case, we also need to compile osvvm libraries <br/></p>

<p>    <strong>compile__osvvm</strong>, <a href="https://builds.sr.ht/~csantosb/job/1389146#task-compile_osvvm" rel="nofollow">produce a compiled version</a> of <a href="/csantosb/tag:osvvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">osvvm</span></a> verification libraries; this is necessary as we are using here the <code>tcl</code>  scripts included in the library itself to follow the correct order of compilation. Libraries will appear within the local profile under <code>$GUIX_PROFILE/VHDL_LIBS/GHDL-X.Y.Z</code> <br/></p>

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

<p>    <strong>test</strong>, for a fully custom made testing pipeline; in this case, using a <code>Makefile</code> <br/>
    Just simply, source the <code>.envrc</code> file where the local <code>$GUIX_PROFILE</code> variable is defined, cd to the <code>ghdl</code> directory and call make to compile the design and run the simulation in two steps: first, clean all and include sources in its corresponding libraries with <br/></p>

<p>    <code>sh
    make __clean_all __include
</code></p>

<p>    Then, produce a new <code>Makefile</code> using <code>ghdl</code>. <br/></p>

<p>    <code>sh
    ./makefile.sh # ghdl --gen-makefile ...
</code></p>

<p>    Finally, run the simulation with <br/></p>

<p>    <code>sh
    make GHDLRUNFLAGS=&#34;--stop-time=4us --disp-time --ieee-asserts=enable&#34; run
</code></p>

<p>    This will produce a executable file before <a href="https://builds.sr.ht/~csantosb/job/1389146#task-test" rel="nofollow">running it</a> with the provided parameters. <br/>
    You may notice that, in this case, you need to produce somehow your own <code>Makefile</code>, or equivalent pipeline, right ? <br/></p>

<h2 id="hdlmake">hdlmake</h2>

<p>Wouldn’t it be nice if we had a tool to deploy online which produces makefiles for us ? It exists, and its name is <a href="/csantosb/tag:hdlmake" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">hdlmake</span></a>. <br/></p>

<p>    <strong>test__hdlmake</strong> <br/>
    <a href="https://git.sr.ht/~csantosb/ip.alu/tree/8324cd0fcb838cfb8303aae9e668b6831a329cbb/.builds/profile1.yml#L39" rel="nofollow">Source</a> the <code>.envrc</code> file where the local <code>$GUIX_PROFILE</code> variable is defined, cd to the <code>.builds/hdlmake</code> directory where all <code>Manifest.py</code> files are located, and call <code>hdlmake</code> to produce the <code>Makefile</code>. Finally, just run make to compile the design, produce an executable and run it. <br/></p>

<p>Check the resulting logs inline <a href="https://builds.sr.ht/~csantosb/job/1389146#task-test_hdlmake" rel="nofollow">here</a>, for example. <br/></p>
]]></content:encoded>
      <guid>https://infosec.press/csantosb/ci-sourcehut-alu</guid>
      <pubDate>Fri, 13 Dec 2024 12:38:24 +0000</pubDate>
    </item>
    <item>
      <title>ci (sourcehut): open-logic</title>
      <link>https://infosec.press/csantosb/ci-sourcehut</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 how to implement it with detail using sourcehut and a real world example. !--more-- br/&#xA;Sourcehut is a lightweight #gitforge where I host my #git repositories. Not only it is based on a paradigm perfectly adapted to #modernhw, but also its builds service includes support for guix (x8664) images. This means that we will be able to execute all of our testing online inside guix profiles, shells or natively on top of the bare-bones image. br/&#xA;&#xA;Open logic&#xA;&#xA;Let’s see how in detail using the cookbook as a starting point, and taking as a complete example the fw-open-logic #openlogic firmware package which comes with the electronics guix channel. br/&#xA;Get it with: br/&#xA;&#xA;guix install fw-open-logic:out&#xA;&#xA;Open logic is a useful #vhdl library of commonly used components, implemented in a reusable and vendor/tool-independent way.  As any other #modernhw library, it includes tests sets for any of its components, using the vunit utility in this case. br/&#xA;To run the full tests suite use (user wide using the default $GUIXPROFILE), install its dependencies, defined in a manifest.scm file (ghdl-clang and python-vunit in this case). br/&#xA;&#xA;cd open-logic&#xA;guix install -m .builds/manifest.scm&#xA;cd sim&#xA;python3 run.py --ghdl -v&#xA;&#xA;or local to the project, using a profile br/&#xA;&#xA;cd open-logic&#xA;mkdir deps&#xA;export GUIXPROFILE=open-logic/deps&#xA;guix install -P $GUIXPROFILE -m .builds/manifest.scm&#xA;. $GUIXPROFILE/etc/profile&#xA;cd sim&#xA;python3 run.py --ghdl -v&#xA;&#xA;go remote&#xA;&#xA;img br/&#xA;Now, how do we proceed online using #sourcehut #ci builds facility ? Builds will pop up a new environment based on an up to date guix-system image when we push a commit to git.sr.ht, provided we include a .build.yml build manifest file, or by a .build folder with up to 4 build manifest files, at the root of the git project 1]. Be careful: consider that this image is [built daily using a crontab job, which is a good and a bad thing at the same time. From one side, you won’t be using the same environment for your tests, which breaks #reproducibility (see comments section below). On the other side, #guix is a rolling release, and new fancy features and new fixes are added every day. Keep this in mind. br/&#xA;Let’s create a .builds folder in a topic test branch, with the following contents: br/&#xA;&#xA;    manifest.scm, list of dependencies in our project br/&#xA;    guix.scm, default guix repository, redundant, included here for convenience br/&#xA;    channels.scm, list of guix channels remote repositories, in addition to the default guix repository, from where we pull packages br/&#xA;    We will be using here my own electronics channel (no substitutes), as well as the guix science channel (which provides substitutes). br/&#xA;    (note how here we load the local guix.scm file, instead of making use of the %default-channels global variable) br/&#xA;    &#xA;        (load &#34;guix.scm&#34;)&#xA;    ;;; %default-channels&#xA;        key.pub, auth key to access substitutes of packages in guix channels br/&#xA;&#xA;build manifests&#xA;&#xA;From now on, every new push to the test #git branch will trigger the execution of the tasks defined in the three build manifest files br/&#xA;&#xA;    profile1 br/&#xA;    profile2 br/&#xA;    shell1 br/&#xA;&#xA;The two profile build manifest files use a slightly different approach, and are given here for comparison purposes only. The shell build manifest uses an isolated shell container within the image itself to illustrate this feature. br/&#xA;Inside the manifests, I declare the image to use, guix, and the global environment variables sourced before each task is run: prj (project name), srv (list of servers with substitutes), manifest and channels (pointing to the corresponding files) and key (same). It is important to declare a trigger action, to receive an email with all relevant information in case of failure (log, id, commit, etc.). br/&#xA;&#xA;tasks&#xA;&#xA;What’s interesting here is the list of tasks. Some of them are common to all three manifests br/&#xA;&#xA;    env, useful only for debugging br/&#xA;    guix\updatechannels, replace the default project local guix.scm file by the output of br/&#xA;    &#xA;        guix describe --format=channels&#xA;        &#xA;    The goal here is avoid pulling latest guix upstream, useless and cpu and time consuming, and using the local version instead. Remember that the guix system image we are using here is updated daily. br/&#xA;    &#xA;        guix\auth, runs the authorize command to add the key.pub file to guix, so that we will be able to download package substitutes when necessary br/&#xA;        &#xA;                sudo guix archive --authorize &lt; &#34;$key&#34;&#xA;                &#xA;        Here, one may opt by doing a br/&#xA;        &#xA;                guix pull --channels=&#34;$channels&#34;&#xA;                &#xA;        as in profile2, to set the revision of the guix channels we are using (remember channels are nothing but git repositories). br/&#xA;        Note how in profile1 and shell1 we opt for a different approach. br/&#xA;        guix\updateprofile, where we create a deps folder to be used as a local $GUIXPROFILE (defined in .envrc). br/&#xA;        Then, one of br/&#xA;        &#xA;                # profile1&#xA;        guix time-machine --channels=&#34;$channels&#34; -- \&#xA;             package -p &#34;$GUIXPROFILE&#34; \&#xA;             --substitute-urls=&#34;$srv&#34; \&#xA;             -m &#34;$manifest&#34;&#xA;                &#xA;        or br/&#xA;        &#xA;                # profile2&#xA;        guix \&#xA;            package -p &#34;$GUIXPROFILE&#34; \&#xA;            --substitute-urls=&#34;$srv&#34; \&#xA;            -m &#34;$manifest&#34;&#xA;                &#xA;        will install packages in $manifest into the $GUIXPROFILE. I’m using here the time-machine mechanism to set the revision of the guix channels, depending if guix pull was run in the previous stage or not. br/&#xA;        vunit, sets env variables in .envrc and runs python3 run.py --ghdl -v inside sim directory br/&#xA;        Note that here, we are using ghdl-clang and python-vunit packages, provided respectively by guix-science and the electronics channel. br/&#xA;        guix\shelltest, used by shell1, make use of time-machine (no former guix pull, then), to create a shell container, where to install project dependencies. Then, if calls inmediately run.sh to run the unit tests br/&#xA;        &#xA;                guix time-machine --channels=&#34;$channels&#34; -- shell -C --substitute-urls=&#34;$srv&#34; -m &#34;$manifest&#34; -- ./.builds/run.sh&#xA;        &#xA;&#xA;comments&#xA;&#xA;You may check the logs of profile1, profile2 and shell1 manifests, including a section with logs per task, to better understand what’s going on here. Remember that #sourcehut gives ssh access to the builds by connecting to the runners in case of failures, which provides a practical way of debugging the manifest files. br/&#xA;You may see how, using the remove guix image, it is possible to deploy a series of tasks to test our #modernhw design as we develop it: we will get an email in case of failure to pass the tests. Here, I present three approaches: guix pulling to set the repositories revisions on use; time-machine, to achieve the same, and guix shell to create an isolated container. These three alternatives are not necessary here, of course, but are given as a simple and practical demo of what can be achieved with #guix, #sourcehut and #ci. br/&#xA;To conclude this long post, it is important to stress once again that the point on using #guix resides in its reproducibility capabilities. By keeping a couple of #plaintext files, namely the manifest.scm and channels.scm, one can obtain #determinism in the execution of the tests. Even if the guix image is upgraded and rebuilt daily (and so it changes), by fixing the revision of our channels (remember, guix pull or guix time-machine) we obtain always the same products out of our tests, as we run the same (project and tests) code, within exactly the same environment. br/&#xA;&#xA;---&#xA;&#xA;[1] It is also possible to automatically submit builds when a patch to a repo with build manifests is sent to a mailing list. This is achieved by appending the project name as a prefix to the subject of the message, for example [PATCH project-name]. br/]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://git.sr.ht/~csantosb/csbwiki/blob/master/pics/sourcehut.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 how to implement it with detail using <a href="https://sourcehut.org/" rel="nofollow">sourcehut</a> and a real world example.  <br/>
<a href="https://infosec.press/csantosb/sourcehut-crash-course" rel="nofollow">Sourcehut</a> is a lightweight <a href="/csantosb/tag:gitforge" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gitforge</span></a> where I host my <a href="/csantosb/tag:git" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">git</span></a> repositories. Not only it is <a href="https://infosec.press/csantosb/git-forges#sourcehut" rel="nofollow">based on a paradigm</a> perfectly adapted to <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a>, but also its <a href="https://infosec.press/csantosb/sourcehut-crash-course#builds" rel="nofollow">builds</a> service includes support for <a href="https://man.sr.ht/builds.sr.ht/compatibility.md#guix-system" rel="nofollow">guix</a> (x86_64) images. This means that we will be able to execute all of our testing online inside <a href="https://infosec.press/csantosb/guix-crash-course#profiles-and-generations" rel="nofollow">guix profiles</a>, <a href="https://infosec.press/csantosb/guix-crash-course#shell-containers" rel="nofollow">shells</a> or natively on top of the bare-bones image. <br/></p>

<h1 id="open-logic">Open logic</h1>

<p>Let’s see how in detail using the <a href="https://man.sr.ht/~whereiseveryone/builds.sr.ht-guix-cookbook/" rel="nofollow">cookbook</a> as a starting point, and taking as a complete example the <code>fw-open-logic</code> <a href="/csantosb/tag:openlogic" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">openlogic</span></a> firmware package which comes with the <a href="https://infosec.press/csantosb/guix-channels#electronics-channel" rel="nofollow">electronics guix channel</a>. <br/>
Get it with: <br/></p>

<pre><code class="language-sh">guix install fw-open-logic:out
</code></pre>

<p><a href="https://github.com/open-logic/open-logic" rel="nofollow">Open logic</a> is a useful <a href="/csantosb/tag:vhdl" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">vhdl</span></a> library of commonly used components, implemented in a reusable and vendor/tool-independent way.  As any other <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a> library, it includes tests sets for any of its components, using the <a href="https://infosec.press/csantosb/on-testing#vunit" rel="nofollow">vunit</a> utility in this case. <br/>
To run the full tests suite use (user wide using the default <code>$GUIX_PROFILE</code>), install its dependencies, defined in a <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/manifest.scm" rel="nofollow">manifest.scm</a> file (<code>ghdl-clang</code> and <code>python-vunit</code> in this case). <br/></p>

<pre><code class="language-sh">cd open-logic
guix install -m .builds/manifest.scm
cd sim
python3 run.py --ghdl -v
</code></pre>

<p>or local to the project, using <a href="https://infosec.press/csantosb/guix-crash-course#profiles-and-generations" rel="nofollow">a profile</a> <br/></p>

<pre><code class="language-sh">cd open-logic
mkdir _deps
export GUIX_PROFILE=open-logic/_deps
guix install -P $GUIX_PROFILE -m .builds/manifest.scm
. $GUIX_PROFILE/etc/profile
cd sim
python3 run.py --ghdl -v
</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/>
Now, how do we proceed online using <a href="/csantosb/tag:sourcehut" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">sourcehut</span></a> <a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a> <code>builds</code> facility ? <a href="https://infosec.press/csantosb/sourcehut-crash-course#builds" rel="nofollow">Builds</a> will pop up a new environment based on an up to date <code>guix-system</code> image when we push a commit to <code>git.sr.ht</code>, provided we include a <code>.build.yml</code> build manifest file, or by a <code>.build</code> folder with up to 4 build manifest files, at the root of the git project [1]. Be careful: consider that this image is <a href="https://git.sr.ht/~sircmpwn/builds.sr.ht/tree/master/item/images/guix" rel="nofollow">built daily</a> using a <a href="https://git.sr.ht/~sircmpwn/builds.sr.ht/tree/master/item/contrib/crontab" rel="nofollow">crontab</a> job, which is a good and a bad thing at the same time. From one side, you won’t be using the same environment for your tests, which breaks <a href="/csantosb/tag:reproducibility" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproducibility</span></a> (see <strong>comments</strong> section below). On the other side, <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a> is a rolling release, and new fancy features and new fixes are added every day. Keep this in mind. <br/>
Let’s create a <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds" rel="nofollow">.builds</a> folder in a topic <code>test branch</code>, with the following contents: <br/></p>

<p>    <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/manifest.scm" rel="nofollow">manifest.scm</a>, list of dependencies in our project <br/>
    <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/guix.scm" rel="nofollow">guix.scm</a>, default guix repository, redundant, included here for convenience <br/>
    <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/channels.scm" rel="nofollow">channels.scm</a>, list of <a href="https://infosec.press/csantosb/guix-channels" rel="nofollow">guix channels</a> remote repositories, in addition to the default guix repository, from where we pull packages <br/>
    We will be using here my own <a href="https://infosec.press/csantosb/guix-channels#electronics-channel" rel="nofollow">electronics channel</a> (no substitutes), as well as the <a href="https://codeberg.org/guix-science/guix-science" rel="nofollow">guix science</a> channel (which provides substitutes). <br/>
    (note how here we load the local <code>guix.scm</code> file, instead of making use of the <code>%default-channels</code> global variable) <br/></p>

<p>    <code>scheme
    (load &#34;guix.scm&#34;)
    ;;; %default-channels
</code>
    <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/key.pub" rel="nofollow">key.pub</a>, <a href="https://man.sr.ht/~whereiseveryone/builds.sr.ht-guix-cookbook/" rel="nofollow">auth key</a> to access <a href="https://infosec.press/csantosb/guix-crash-course#packages" rel="nofollow">substitutes</a> of packages in guix channels <br/></p>

<h3 id="build-manifests">build manifests</h3>

<p>From now on, every new push to the <code>test</code> <a href="/csantosb/tag:git" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">git</span></a> branch will trigger the execution of the tasks defined in the three <a href="https://man.sr.ht/builds.sr.ht/#build-manifests" rel="nofollow">build manifest files</a> <br/></p>

<p>    <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/profile1.yml" rel="nofollow">profile1</a> <br/>
    <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/profile2.yml" rel="nofollow">profile2</a> <br/>
    <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/shell1.yml" rel="nofollow">shell1</a> <br/></p>

<p>The two profile build manifest files use a slightly different approach, and are given here for comparison purposes only. The shell build manifest uses an isolated shell container <em>within</em> the image itself to illustrate this feature. <br/>
Inside the manifests, I declare the image to use, <code>guix</code>, and the global environment variables sourced before each task is run: <code>prj</code> (project name), <code>srv</code> (list of servers with substitutes), <code>manifest</code> and <code>channels</code> (pointing to the corresponding files) and <code>key</code> (same). It is important to declare a trigger action, to receive an email with all relevant information in case of failure (log, id, commit, etc.). <br/></p>

<h3 id="tasks">tasks</h3>

<p>What’s interesting here is the list of tasks. Some of them are common to all three manifests <br/></p>

<p>    <strong>env</strong>, useful only for debugging <br/>
    <strong>guix__update__channels</strong>, replace the default project local <code>guix.scm</code> file by the output of <br/></p>

<p>    <code>sh
    guix describe --format=channels
</code></p>

<p>    The goal here is avoid pulling latest guix upstream, useless and cpu and time consuming, and using the local version instead. Remember that the guix system image we are using here is <a href="https://git.sr.ht/~sircmpwn/builds.sr.ht/tree/master/item/images/guix" rel="nofollow">updated daily</a>. <br/></p>

<p>        <strong>guix__auth</strong>, runs the authorize command to add the <code>key.pub</code> file to guix, so that we will be able to download package substitutes when necessary <br/></p>

<p>        <code>sh
        sudo guix archive --authorize &lt; &#34;$key&#34;
</code></p>

<p>        Here, one may opt by doing a <br/></p>

<p>        <code>sh
        guix pull --channels=&#34;$channels&#34;
</code></p>

<p>        as in <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/profile2.yml" rel="nofollow">profile2</a>, to set the revision of the guix channels we are using (remember channels are nothing but git repositories). <br/>
        Note how in <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/profile1.yml" rel="nofollow">profile1</a> and <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/shell1.yml" rel="nofollow">shell1</a> we opt for a different approach. <br/>
        <strong>guix__update__profile</strong>, where we create a <code>_deps</code> folder to be used as a local <code>$GUIX_PROFILE</code> (defined in <code>.envrc</code>). <br/>
        Then, one of <br/></p>

<p>        <code>sh
        # profile1
        guix time-machine --channels=&#34;$channels&#34; -- \
             package -p &#34;$GUIX_PROFILE&#34; \
             --substitute-urls=&#34;$srv&#34; \
             -m &#34;$manifest&#34;
</code></p>

<p>        or <br/></p>

<p>        <code>sh
        # profile2
        guix \
            package -p &#34;$GUIX_PROFILE&#34; \
            --substitute-urls=&#34;$srv&#34; \
            -m &#34;$manifest&#34;
</code></p>

<p>        will install packages in <code>$manifest</code> into the <code>$GUIX_PROFILE</code>. I’m using here the <a href="https://infosec.press/csantosb/guix-crash-course#time-machine" rel="nofollow">time-machine</a> mechanism to set the revision of the guix channels, depending if <code>guix pull</code> was run in the previous stage or not. <br/>
        <strong>vunit</strong>, sets env variables in <code>.envrc</code> and runs <code>python3 run.py --ghdl -v</code> inside <code>sim</code> directory <br/>
        Note that here, we are using <code>ghdl-clang</code> and <code>python-vunit</code> packages, provided respectively by <code>guix-science</code> and the <code>electronics</code> channel. <br/>
        <strong>guix__shell__test</strong>, used by <a href="https://git.sr.ht/~csantosb/ip.open-logic/tree/test/item/.builds/shell1.yml" rel="nofollow">shell1</a>, make use of <code>time-machine</code> (no former <code>guix pull</code>, then), to create a <a href="https://infosec.press/csantosb/guix-crash-course#time-machine%23shell-containers" rel="nofollow">shell container</a>, where to install project dependencies. Then, if calls inmediately <code>run.sh</code> to run the unit tests <br/></p>

<p>        <code>sh
        guix time-machine --channels=&#34;$channels&#34; -- shell -C --substitute-urls=&#34;$srv&#34; -m &#34;$manifest&#34; -- ./.builds/run.sh
</code></p>

<h2 id="comments">comments</h2>

<p>You may check the logs of <a href="https://builds.sr.ht/~csantosb/job/1384658" rel="nofollow">profile1</a>, <a href="https://builds.sr.ht/~csantosb/job/1384659" rel="nofollow">profile2</a> and <a href="https://builds.sr.ht/~csantosb/job/1384660" rel="nofollow">shell1</a> manifests, including a section with logs per task, to better understand what’s going on here. Remember that <a href="/csantosb/tag:sourcehut" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">sourcehut</span></a> gives <a href="https://man.sr.ht/builds.sr.ht/build-ssh.md" rel="nofollow">ssh access</a> to the builds by connecting to the runners in case of failures, which provides a practical way of debugging the manifest files. <br/>
You may see how, using the remove guix image, it is possible to deploy a series of tasks to test our <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a> design as we develop it: we will get an email in case of failure to pass the tests. Here, I present three approaches: <code>guix pulling</code> to set the repositories revisions on use; <code>time-machine</code>, to achieve the same, and <code>guix shell</code> to create an isolated container. These three alternatives are not necessary here, of course, but are given as a simple and practical demo of what can be achieved with <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a>, <a href="/csantosb/tag:sourcehut" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">sourcehut</span></a> and <a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a>. <br/>
To conclude this long post, it is important to stress once again that the point on using <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a> resides in its <a href="https://infosec.press/csantosb/use-guix#reproducibility" rel="nofollow">reproducibility</a> capabilities. By keeping a couple of <a href="/csantosb/tag:plaintext" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">plaintext</span></a> files, namely the <a href="https://infosec.press/csantosb/guix-crash-course#manifest-channels" rel="nofollow">manifest.scm and channels.scm</a>, one can obtain <a href="/csantosb/tag:determinism" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">determinism</span></a> in the execution of the tests. Even if the guix image is upgraded and rebuilt daily (and so it changes), by fixing the revision of our channels (remember, <code>guix pull</code> or <code>guix time-machine</code>) we obtain always the same products out of our tests, as we run the same (project and tests) code, within exactly the same environment. <br/></p>

<hr>

<p>[1] It is also possible to automatically submit builds when a patch to a repo with build manifests is sent to a mailing list. This is achieved by appending the project name as a prefix to the subject of the message, for example [PATCH project-name]. <br/></p>
]]></content:encoded>
      <guid>https://infosec.press/csantosb/ci-sourcehut</guid>
      <pubDate>Fri, 13 Dec 2024 10:18:11 +0000</pubDate>
    </item>
    <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>
    <item>
      <title>ci (intro)</title>
      <link>https://infosec.press/csantosb/ci-intro</link>
      <description>&lt;![CDATA[img br/&#xA;How to seek, detect, be notified, analyze logs, understand and react to the different possible kind of issues one may encounter in a digital design is a vast topic of research, well beyond the scope of this modest post. But there are a couple of things we may state about here, though: automatizing issue detection is the way to go. Continuous integration (#ci) testing is a practice to adopt in #modernhw as a way to ensure that our design complies with its constraints. Let’s see this in more detail. !--more-- br/&#xA;&#xA;git&#xA;&#xA;We said #git, then, as mandatory when tracking changes (in documentation, project development, taking notes, etc.). Meaningful changes imply new commits (and good commit messages, for what it takes), but this comes along with a risk of introducing issues. Some kind of mechanism is necessary to automatize the execution of a checkout list to be run per new commit. The list is project aware, for sure, but may also be different following the git branch, and even the kind of commit (merges are to be considered differently to regular commits in topic branches, for example). We need to consider what an issue exactly is, and then you’ll need to adopt a different perspective on kinds of checkout lists. br/&#xA;&#xA;verification&#xA;&#xA;First (ideally), one starts with clear specifications about the goals of current development effort (in practice this never happens in research, and if you ever have it, they’ll evolve with time). These specifications (you’ll figure out where to find them somehow) will define the tests to run. For example, if you need to implement in firmware a deep neural network, you’ll probably have access to a test data set to verify the outcomes are correct. You may tune, improve or even completely change the architecture of your network, at the very end, you’ll have to verify your design with help of the test data set. Additionally, you may define more sophisticated tests: consumption, area, resources, etc. These all fall into the category of verification testing. br/&#xA;&#xA;unit tests&#xA;&#xA;Secondly, you’ll be running unit tests during your whole design cycle (and they’ll evolve along with it), and target tests (the one we mentioned just before). Does this addition perform correctly ? What if we stress a module with random inputs ? Are we going through all code in a given design unit ? Do we cover all values of some input/output signal in this important module ? These are all unit testing checkouts, and they’ll help us to detect issues in an early stage of design. br/&#xA;&#xA;codesign&#xA;&#xA;Codesign falls somewhere in between the two previous: as a testing methodology, it includes concepts of verification and unit testing (and can be combined with them). It is way more ambitious and complex, but also more powerful. No matter your testing strategy, the point here is that you’ll be running these tests (fully or partially) automatically at the several different stages of your development cycle. If they fail, you’ll have to be warned. br/&#xA;&#xA;guix&#xA;&#xA;img br/&#xA;Guix, as a package manager, provides all necessary software to deploy our tests (and can be extended with additional tooling). It also includes all that&#39;s necessary to create a running environment where we will execute our tests. Most importantly, #guix does so in a #deterministic and #reproductible way: we will be able to reproduce our tests in the future under exactly the same conditions. Shell containers, profiles and the time machine mechanism allow the degree of #reproducibility we need here. All it takes is a couple of text files. br/&#xA;&#xA;---&#xA;&#xA;Most usually, we will focus on two strategies to seek for issues: local, and remote. Local strategies are greatly based on git hooks, and will be topic of another post. Let’s see now in practice what can be done with help of remote tools, based on #ci, understood as a methodology consisting on automatically executing a set of tests procedures on a digital design. br/&#xA;ciseries br/]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://git.sr.ht/~csantosb/csbwiki/blob/master/pics/ci.png" alt="img"> <br/>
How to seek, detect, be notified, analyze logs, understand and react to the <a href="https://infosec.press/csantosb/on-testing" rel="nofollow">different possible kind of issues</a> one may encounter in a digital design is a vast topic of research, well beyond the scope of this modest post. But there are a couple of things we may state about here, though: automatizing issue detection is the way to go. <a href="https://en.wikipedia.org/wiki/Continuous_integration" rel="nofollow">Continuous integration</a> (<a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a>) testing is a practice to adopt in <a href="/csantosb/tag:modernhw" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">modernhw</span></a> as a way to ensure that our design complies with its constraints. Let’s see this in more detail.  <br/></p>

<h1 id="git">git</h1>

<p>We said <a href="/csantosb/tag:git" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">git</span></a>, then, as mandatory when <a href="https://infosec.press/csantosb/on-dependencies" rel="nofollow">tracking changes</a> (in documentation, project development, taking notes, etc.). Meaningful changes imply new commits (and good <a href="https://www.freecodecamp.org/news/how-to-write-better-git-commit-messages/" rel="nofollow">commit messages</a>, for what it takes), but this comes along with a risk of introducing issues. Some kind of mechanism is necessary to automatize the execution of a checkout list to be run per new commit. The list is project aware, for sure, but may also be different following the git branch, and even the kind of commit (merges are to be considered differently to regular commits in topic branches, for example). We need to consider what an issue exactly is, and then you’ll need to adopt a different perspective on kinds of checkout lists. <br/></p>

<h1 id="verification">verification</h1>

<p>First (ideally), one starts with clear specifications about the goals of current development effort (in practice this never happens in research, and if you ever have it, they’ll evolve with time). These specifications (you’ll figure out where to find them somehow) will define the tests to run. For example, if you need to implement in firmware a deep neural network, you’ll probably have access to a test data set to verify the outcomes are correct. You may tune, improve or even completely change the architecture of your network, at the very end, you’ll <a href="https://infosec.press/csantosb/on-testing#osvvm" rel="nofollow">have to verify your design</a> with help of the test data set. Additionally, you may define more sophisticated tests: consumption, area, resources, etc. These all fall into the category of <strong>verification testing</strong>. <br/></p>

<h1 id="unit-tests">unit tests</h1>

<p>Secondly, you’ll be running <a href="https://infosec.press/csantosb/on-testing#vunit" rel="nofollow">unit tests</a> during your whole design cycle (and they’ll evolve along with it), and target tests (the one we mentioned just before). Does this addition perform correctly ? What if we stress a module with random inputs ? Are we going through all code in a given design unit ? Do we cover all values of some input/output signal in this important module ? These are all <strong>unit testing</strong> checkouts, and they’ll help us to detect issues in an early stage of design. <br/></p>

<h1 id="codesign">codesign</h1>

<p><a href="https://infosec.press/csantosb/on-testing#cocotb" rel="nofollow">Codesign</a> falls somewhere in between the two previous: as a testing methodology, it includes concepts of verification and unit testing (and can be combined with them). It is way more ambitious and complex, but also more powerful. No matter your testing strategy, the point here is that you’ll be running these tests (fully or partially) automatically at the several different stages of your development cycle. If they fail, you’ll have to be warned. <br/></p>

<h1 id="guix">guix</h1>

<p><img src="https://git.sr.ht/~csantosb/csbwiki/blob/master/pics/guix.png" alt="img"> <br/>
<a href="https://infosec.press/csantosb/use-guix" rel="nofollow">Guix</a>, as a package manager, provides all necessary software to deploy our tests (and can be <a href="https://infosec.press/csantosb/guix-channels" rel="nofollow">extended</a> with additional tooling). It also includes <a href="https://infosec.press/csantosb/guix-crash-course" rel="nofollow">all that&#39;s necessary</a> to create a running environment where we will execute our tests. Most importantly, <a href="/csantosb/tag:guix" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">guix</span></a> does so in a <a href="/csantosb/tag:deterministic" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">deterministic</span></a> and <a href="/csantosb/tag:reproductible" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproductible</span></a> way: we will be able to reproduce our tests in the future under exactly the same conditions. <a href="https://infosec.press/csantosb/guix-crash-course#shell-containers" rel="nofollow">Shell containers</a>, <a href="https://infosec.press/csantosb/guix-crash-course#profiles-and-generations" rel="nofollow">profiles</a> and the <a href="https://infosec.press/csantosb/guix-crash-course#time-machine" rel="nofollow">time machine mechanism</a> allow the degree of <a href="/csantosb/tag:reproducibility" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">reproducibility</span></a> we need here. All it takes is <a href="https://infosec.press/csantosb/guix-crash-course#manifest-channels" rel="nofollow">a couple of text files</a>. <br/></p>

<hr>

<p>Most usually, we will focus on two strategies to seek for issues: local, and remote. Local strategies are greatly based on <a href="https://git-scm.com/book/ms/v2/Customizing-Git-Git-Hooks" rel="nofollow">git hooks</a>, and will be topic of another post. <a href="https://infosec.press/csantosb/tag:ciseries" rel="nofollow">Let’s see now in practice</a> what can be done with help of remote tools, based on <a href="/csantosb/tag:ci" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ci</span></a>, understood as a methodology consisting on automatically executing a set of tests procedures on a digital design. <br/>
<a href="/csantosb/tag:ciseries" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">ciseries</span></a> <br/></p>
]]></content:encoded>
      <guid>https://infosec.press/csantosb/ci-intro</guid>
      <pubDate>Sun, 08 Dec 2024 21:19:43 +0000</pubDate>
    </item>
  </channel>
</rss>