<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 -->
<h2 id="continuous-integration-for-geode" class="position-relative d-flex align-items-center group">
<span>Continuous Integration for Geode</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="continuous-integration-for-geode"
aria-haspopup="dialog"
aria-label="Share link: Continuous Integration for Geode">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h2><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden>
<div class="hsm-dialog" role="document">
<div class="hsm-header">
<h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2>
<button type="button" class="hsm-close" aria-label="Close">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<div class="hsm-body">
<label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label>
<div class="input-group mb-4 hsm-url-group">
<input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" />
<button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy">
<i class="fa-duotone fa-clipboard" aria-hidden="true"></i>
</button>
</div>
<div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div>
<div class="hsm-share-grid">
<a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-twitter me-2"></i>Twitter
</a>
<a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-linkedin me-2"></i>LinkedIn
</a>
<a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-facebook me-2"></i>Facebook
</a>
</div>
</div>
</div>
</div>
<style>
.heading-share-modal {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.6);
z-index: 1050;
padding: 1rem;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
.heading-share-modal[hidden] { display: none !important; }
.hsm-dialog {
max-width: 420px;
width: 100%;
background: var(--bs-body-bg, #fff);
color: var(--bs-body-color, #212529);
border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
border-radius: 1rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
overflow: hidden;
animation: hsm-fade-in 0.2s ease-out;
}
@keyframes hsm-fade-in {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
[data-bs-theme="dark"] .hsm-dialog {
background: #1e293b;
border-color: rgba(255,255,255,0.1);
color: #f8f9fa;
}
.hsm-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
background: rgba(0,0,0,0.02);
}
[data-bs-theme="dark"] .hsm-header {
background: rgba(255,255,255,0.02);
border-color: rgba(255,255,255,0.1);
}
.hsm-close {
background: transparent;
border: none;
color: inherit;
opacity: 0.5;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 1.2rem;
line-height: 1;
transition: opacity 0.2s;
}
.hsm-close:hover {
opacity: 1;
}
.hsm-body {
padding: 1.5rem;
}
.hsm-url-group {
display: flex !important;
align-items: stretch;
}
.hsm-url-group .form-control {
flex: 1;
min-width: 0;
margin: 0;
background: var(--bs-secondary-bg, #f8f9fa);
border-color: var(--bs-border-color, #dee2e6);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
height: 42px;
}
.hsm-url-group .btn {
flex: 0 0 auto;
margin: 0;
margin-left: -1px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 1.25rem;
z-index: 2;
}
[data-bs-theme="dark"] .hsm-url-group .form-control {
background: #0f172a;
border-color: #334155;
color: #e2e8f0;
}
.hsm-share-grid {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.hsm-share-grid .btn {
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
padding: 0.6rem;
border-color: var(--bs-border-color);
width: 100%;
}
[data-bs-theme="dark"] .hsm-share-grid .btn {
color: #e2e8f0;
border-color: #475569;
}
[data-bs-theme="dark"] .hsm-share-grid .btn:hover {
background: #334155;
border-color: #cbd5e1;
}
</style>
<script>
(function(){
const modal = document.getElementById('headingShareModal');
if(!modal) return;
const input = modal.querySelector('#headingShareInput');
const copyBtn = modal.querySelector('.hsm-copy');
const twitter = modal.querySelector('#share-twitter');
const linkedin = modal.querySelector('#share-linkedin');
const facebook = modal.querySelector('#share-facebook');
const closeBtn = modal.querySelector('.hsm-close');
let lastFocus=null;
let trapBound=false;
function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; }
function isOpen(){ return !modal.hasAttribute('hidden'); }
function hydrate(id){
const url=buildUrl(id);
input.value=url;
const enc=encodeURIComponent(url);
const text=encodeURIComponent(document.title);
if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`;
if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`;
if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`;
}
function openModal(id){
lastFocus=document.activeElement;
hydrate(id);
if(!isOpen()){
modal.removeAttribute('hidden');
}
requestAnimationFrame(()=>{ input.focus(); });
trapFocus();
}
function closeModal(){
if(!isOpen()) return;
modal.setAttribute('hidden','');
if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus();
}
function copyCurrent(){
try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); }
catch(e){ fallback(); }
}
function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} }
function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); }
function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); }
function bindShareButtons(){
document.querySelectorAll('.h-share').forEach(btn=>{
if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; }
});
}
bindShareButtons();
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded', bindShareButtons);
} else {
requestAnimationFrame(bindShareButtons);
}
document.addEventListener('click', function(e){
const shareBtn=e.target.closest && e.target.closest('.h-share');
if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); }
}, true);
document.addEventListener('click', e=>{
if(e.target===modal) closeModal();
if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); }
if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); }
});
document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); });
function trapFocus(){
if(trapBound) return;
trapBound=true;
modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } });
}
if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); });
})();
</script><p>Continuous Integration (CI) is the practice of automatically building, testing, and validating code changes as they’re committed to version control. For Geode, CI ensures that every change maintains database correctness, preserves GQL standards compliance, prevents performance regressions, and validates polyglot client compatibility.</p>
<h3 id="foundations-of-continuous-integration" class="position-relative d-flex align-items-center group">
<span>Foundations of Continuous Integration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="foundations-of-continuous-integration"
aria-haspopup="dialog"
aria-label="Share link: Foundations of Continuous Integration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Continuous Integration is built on several core principles:</p>
<p><strong>Frequent Integration</strong>: Developers integrate code changes multiple times daily, preventing large merge conflicts and integration issues.</p>
<p><strong>Automated Building</strong>: Every commit triggers an automated build process that compiles the codebase and identifies compilation errors immediately.</p>
<p><strong>Automated Testing</strong>: Comprehensive test suites run automatically, providing rapid feedback on functionality and preventing regressions.</p>
<p><strong>Fast Feedback</strong>: Developers receive build and test results within minutes, enabling quick fixes before context switching.</p>
<p><strong>Maintain a Single Source Repository</strong>: All code, tests, and configuration reside in version control (Git), ensuring reproducibility.</p>
<p>For database systems like Geode, CI is particularly critical because bugs can result in data corruption, lost transactions, or query correctness issues that are difficult to debug in production.</p>
<h3 id="geodes-ci-implementation" class="position-relative d-flex align-items-center group">
<span>Geode&rsquo;s CI Implementation</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="geodes-ci-implementation"
aria-haspopup="dialog"
aria-label="Share link: Geodes CI Implementation">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="repository-structure" class="position-relative d-flex align-items-center group">
<span>Repository Structure</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="repository-structure"
aria-haspopup="dialog"
aria-label="Share link: Repository Structure">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Geode’s monorepo structure enables comprehensive CI across all components:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">/home/benji/src/gl/devnw/codepros/geode/
</span></span><span class="line"><span class="cl">├── geode/ # Server (Zig)
</span></span><span class="line"><span class="cl">│ ├── src/
</span></span><span class="line"><span class="cl">│ ├── test/
</span></span><span class="line"><span class="cl">│ └── build.zig
</span></span><span class="line"><span class="cl">├── geode-client-go/ # Go client
</span></span><span class="line"><span class="cl">├── geode-client-python/ # Python client
</span></span><span class="line"><span class="cl">├── geode-client-rust/ # Rust client
</span></span><span class="line"><span class="cl">├── geode-client-zig/ # Zig client
</span></span><span class="line"><span class="cl">├── geode-test-harness/ # Cross-client tests
</span></span><span class="line"><span class="cl">└── .github/workflows/ # CI configuration
</span></span></code></pre></div><p>This structure allows CI to:</p>
<ul>
<li>Build all components in a single pipeline</li>
<li>Test server changes against all clients</li>
<li>Validate cross-client compatibility</li>
<li>Ensure end-to-end functionality</li>
</ul>
<h4 id="build-process" class="position-relative d-flex align-items-center group">
<span>Build Process</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="build-process"
aria-haspopup="dialog"
aria-label="Share link: Build Process">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Server Build</strong> (Zig):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># geode/Makefile</span>
</span></span><span class="line"><span class="cl">build:
</span></span><span class="line"><span class="cl"> zig build -Doptimize<span class="o">=</span>ReleaseSafe
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">test:
</span></span><span class="line"><span class="cl"> zig build <span class="nb">test</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">geodetestlab-comprehensive:
</span></span><span class="line"><span class="cl"> zig build <span class="nb">test</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Run comprehensive test suite (1,688 tests)</span>
</span></span><span class="line"><span class="cl"> ./zig-out/bin/geodetestlab --comprehensive
</span></span></code></pre></div><p><strong>CI Build Configuration</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># .github/workflows/build.yml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build Geode</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">push</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">main, develop]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">pull_request</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">main]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">build-zig</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build Server (Zig ${{ matrix.zig }})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">${{ matrix.os }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">strategy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">matrix</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">os</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">ubuntu-24.04, macos-14]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">zig</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="m">0.1.0</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup Zig</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">goto-bus-stop/setup-zig@v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="l">${{ matrix.zig }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build Geode</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">working-directory</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> zig build -Doptimize=ReleaseSafe
</span></span></span><span class="line"><span class="cl"><span class="sd"> ./zig-out/bin/geode --version</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Verify Binary</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> file geode/zig-out/bin/geode
</span></span></span><span class="line"><span class="cl"><span class="sd"> ldd geode/zig-out/bin/geode || true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Upload Binary</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/upload-artifact@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">geode-${{ matrix.os }}-${{ matrix.zig }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">geode/zig-out/bin/geode</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">retention-days</span><span class="p">:</span><span class="w"> </span><span class="m">7</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="automated-testing" class="position-relative d-flex align-items-center group">
<span>Automated Testing</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="automated-testing"
aria-haspopup="dialog"
aria-label="Share link: Automated Testing">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Geode’s CI runs multiple test suites:</p>
<p><strong>1. Unit Tests</strong> (Core functionality):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">unit-tests</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Unit Tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-24.04</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="l">build-zig</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup Zig</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">goto-bus-stop/setup-zig@v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="m">0.1.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run Unit Tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">working-directory</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> zig build test -Dtest-filter="*"</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Parse Test Results</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Extract test counts
</span></span></span><span class="line"><span class="cl"><span class="sd"> echo "Tests run, passed, failed"</span><span class="w">
</span></span></span></code></pre></div><p><strong>2. GeodeTestLab Comprehensive Suite</strong> (1,688 tests):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run GeodeTestLab</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">working-directory</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> make geodetestlab-comprehensive</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Check Pass Rate</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Require 97.4% pass rate (1644/1688)
</span></span></span><span class="line"><span class="cl"><span class="sd"> python scripts/check-pass-rate.py \
</span></span></span><span class="line"><span class="cl"><span class="sd"> --results geode/test-results.json \
</span></span></span><span class="line"><span class="cl"><span class="sd"> --threshold 0.974</span><span class="w">
</span></span></span></code></pre></div><p><strong>3. GQL Compliance Tests</strong> (ISO/IEC 39075:2024):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">gql-compliance</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">GQL Compliance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="l">build-zig</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Download Server Binary</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/download-artifact@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Start Geode</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> chmod +x geode
</span></span></span><span class="line"><span class="cl"><span class="sd"> ./geode serve --listen 0.0.0.0:3141 &
</span></span></span><span class="line"><span class="cl"><span class="sd"> sleep 5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run Conformance Profile Tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Must pass profile scope (see conformance profile)
</span></span></span><span class="line"><span class="cl"><span class="sd"> python gql/iso-tests/run-suite.py \
</span></span></span><span class="line"><span class="cl"><span class="sd"> --host localhost:3141 \
</span></span></span><span class="line"><span class="cl"><span class="sd"> --strict</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Enforce Conformance Profile</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> if [ $? -ne 0 ]; then
</span></span></span><span class="line"><span class="cl"><span class="sd"> echo "GQL conformance profile tests failed - blocking merge"
</span></span></span><span class="line"><span class="cl"><span class="sd"> exit 1
</span></span></span><span class="line"><span class="cl"><span class="sd"> fi</span><span class="w">
</span></span></span></code></pre></div><p><strong>4. Client Library Tests</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">client-tests</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Test ${{ matrix.client }} Client</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="l">build-zig</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">strategy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">matrix</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">client</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">go, python, rust, zig]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Download Server</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/download-artifact@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Start Server</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> ./geode serve &
</span></span></span><span class="line"><span class="cl"><span class="sd"> sleep 5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup ${{ matrix.client }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">./.github/actions/setup-${{ matrix.client }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run Tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">working-directory</span><span class="p">:</span><span class="w"> </span><span class="l">geode-client-${{ matrix.client }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">make test</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Upload Results</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">if</span><span class="p">:</span><span class="w"> </span><span class="l">always()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/upload-artifact@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">test-results-${{ matrix.client }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">geode-client-${{ matrix.client }}/test-results/</span><span class="w">
</span></span></span></code></pre></div><p><strong>5. Cross-Client Integration Tests</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">integration-tests</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Integration Tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="l">client-tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup Test Harness</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">working-directory</span><span class="p">:</span><span class="w"> </span><span class="l">geode-test-harness</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">make setup</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run All Client Tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> make test-all
</span></span></span><span class="line"><span class="cl"><span class="sd"> make test-all-html</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Upload HTML Report</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/upload-artifact@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">integration-report</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">geode-test-harness/reports/</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="code-quality-checks" class="position-relative d-flex align-items-center group">
<span>Code Quality Checks</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="code-quality-checks"
aria-haspopup="dialog"
aria-label="Share link: Code Quality Checks">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Linting and Formatting</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">code-quality</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Code Quality</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-24.04</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Check Zig Formatting</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> find geode/src -name "*.zig" | xargs zig fmt --check</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Lint Go Client</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">working-directory</span><span class="p">:</span><span class="w"> </span><span class="l">geode-client-go</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> go fmt ./...
</span></span></span><span class="line"><span class="cl"><span class="sd"> go vet ./...
</span></span></span><span class="line"><span class="cl"><span class="sd"> golangci-lint run</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Lint Python Client</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">working-directory</span><span class="p">:</span><span class="w"> </span><span class="l">geode-client-python</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> black --check .
</span></span></span><span class="line"><span class="cl"><span class="sd"> pylint geode_client/
</span></span></span><span class="line"><span class="cl"><span class="sd"> mypy geode_client/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Lint Rust Client</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">working-directory</span><span class="p">:</span><span class="w"> </span><span class="l">geode-client-rust</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> cargo fmt -- --check
</span></span></span><span class="line"><span class="cl"><span class="sd"> cargo clippy -- -D warnings</span><span class="w">
</span></span></span></code></pre></div><p><strong>Static Analysis</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run Static Analysis</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Memory safety checks
</span></span></span><span class="line"><span class="cl"><span class="sd"> zig build -Dcheck
</span></span></span><span class="line"><span class="cl"><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Security scanning
</span></span></span><span class="line"><span class="cl"><span class="sd"> semgrep --config=auto geode/src/
</span></span></span><span class="line"><span class="cl"><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Dependency audit
</span></span></span><span class="line"><span class="cl"><span class="sd"> cd geode-client-go && go list -m all | nancy sleuth
</span></span></span><span class="line"><span class="cl"><span class="sd"> cd geode-client-rust && cargo audit</span><span class="w">
</span></span></span></code></pre></div><p><strong>CANARY Marker Validation</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Validate CANARY Markers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Ensure all implementations have CANARY markers
</span></span></span><span class="line"><span class="cl"><span class="sd"> python scripts/validate-canary-markers.py \
</span></span></span><span class="line"><span class="cl"><span class="sd"> --dir geode/src \
</span></span></span><span class="line"><span class="cl"><span class="sd"> --require-evidence</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="advanced-ci-patterns" class="position-relative d-flex align-items-center group">
<span>Advanced CI Patterns</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="advanced-ci-patterns"
aria-haspopup="dialog"
aria-label="Share link: Advanced CI Patterns">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="parallel-test-execution" class="position-relative d-flex align-items-center group">
<span>Parallel Test Execution</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="parallel-test-execution"
aria-haspopup="dialog"
aria-label="Share link: Parallel Test Execution">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Geode parallelizes tests for faster feedback:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">test-parallel</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Parallel Tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-24.04</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">strategy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">fail-fast</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">matrix</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">shard</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="m">2</span><span class="p">,</span><span class="w"> </span><span class="m">3</span><span class="p">,</span><span class="w"> </span><span class="m">4</span><span class="p">,</span><span class="w"> </span><span class="m">5</span><span class="p">,</span><span class="w"> </span><span class="m">6</span><span class="p">,</span><span class="w"> </span><span class="m">7</span><span class="p">,</span><span class="w"> </span><span class="m">8</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run Test Shard ${{ matrix.shard }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Split tests into 8 shards
</span></span></span><span class="line"><span class="cl"><span class="sd"> zig build test -Dshard=${{ matrix.shard }} -Dtotal-shards=8</span><span class="w">
</span></span></span></code></pre></div><p><strong>Benefits</strong>:</p>
<ul>
<li>8-minute test suite runs in 1-2 minutes</li>
<li>Early failure detection</li>
<li>Better resource utilization</li>
</ul>
<h4 id="incremental-testing" class="position-relative d-flex align-items-center group">
<span>Incremental Testing</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="incremental-testing"
aria-haspopup="dialog"
aria-label="Share link: Incremental Testing">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Only test affected components:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Detect Changed Files</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l">changed</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Get changed files since last commit
</span></span></span><span class="line"><span class="cl"><span class="sd"> CHANGED=$(git diff --name-only HEAD~1 HEAD)
</span></span></span><span class="line"><span class="cl"><span class="sd"> echo "files=$CHANGED" >> $GITHUB_OUTPUT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run Targeted Tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> if echo "${{ steps.changed.outputs.files }}" | grep -q "geode/src/parser"; then
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Parser changed - run parser tests
</span></span></span><span class="line"><span class="cl"><span class="sd"> zig build test -Dtest-filter="parser.*"
</span></span></span><span class="line"><span class="cl"><span class="sd"> fi
</span></span></span><span class="line"><span class="cl"><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> if echo "${{ steps.changed.outputs.files }}" | grep -q "geode-client-python"; then
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Python client changed
</span></span></span><span class="line"><span class="cl"><span class="sd"> cd geode-client-python && pytest
</span></span></span><span class="line"><span class="cl"><span class="sd"> fi</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="dependency-caching" class="position-relative d-flex align-items-center group">
<span>Dependency Caching</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="dependency-caching"
aria-haspopup="dialog"
aria-label="Share link: Dependency Caching">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Cache dependencies to speed up builds:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Cache Zig Dependencies</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/cache@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> ~/.cache/zig
</span></span></span><span class="line"><span class="cl"><span class="sd"> geode/zig-cache
</span></span></span><span class="line"><span class="cl"><span class="sd"> geode/zig-out</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">${{ runner.os }}-zig-${{ hashFiles('**/build.zig.zon') }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">restore-keys</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> ${{ runner.os }}-zig-</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Cache Go Modules</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/cache@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">~/go/pkg/mod</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Cache Rust Dependencies</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/cache@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> ~/.cargo/registry
</span></span></span><span class="line"><span class="cl"><span class="sd"> ~/.cargo/git
</span></span></span><span class="line"><span class="cl"><span class="sd"> geode-client-rust/target</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="test-result-reporting" class="position-relative d-flex align-items-center group">
<span>Test Result Reporting</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="test-result-reporting"
aria-haspopup="dialog"
aria-label="Share link: Test Result Reporting">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Generate comprehensive test reports:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Generate Test Report</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">if</span><span class="p">:</span><span class="w"> </span><span class="l">always()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> python scripts/generate-test-report.py \
</span></span></span><span class="line"><span class="cl"><span class="sd"> --input test-results/ \
</span></span></span><span class="line"><span class="cl"><span class="sd"> --output test-report.html \
</span></span></span><span class="line"><span class="cl"><span class="sd"> --format html</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Publish Test Results</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">EnricoMi/publish-unit-test-result-action@v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">if</span><span class="p">:</span><span class="w"> </span><span class="l">always()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">files</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> geode/test-results/**/*.xml
</span></span></span><span class="line"><span class="cl"><span class="sd"> geode-client-*/test-results/**/*.xml
</span></span></span><span class="line"><span class="cl"><span class="sd"> geode-test-harness/reports/**/*.xml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Comment PR with Results</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">if</span><span class="p">:</span><span class="w"> </span><span class="l">github.event_name == 'pull_request'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/github-script@v7</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> const fs = require('fs');
</span></span></span><span class="line"><span class="cl"><span class="sd"> const report = fs.readFileSync('test-report.html', 'utf8');
</span></span></span><span class="line"><span class="cl"><span class="sd"> github.rest.issues.createComment({
</span></span></span><span class="line"><span class="cl"><span class="sd"> issue_number: context.issue.number,
</span></span></span><span class="line"><span class="cl"><span class="sd"> owner: context.repo.owner,
</span></span></span><span class="line"><span class="cl"><span class="sd"> repo: context.repo.repo,
</span></span></span><span class="line"><span class="cl"><span class="sd"> body: report
</span></span></span><span class="line"><span class="cl"><span class="sd"> });</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="ci-best-practices-for-geode" class="position-relative d-flex align-items-center group">
<span>CI Best Practices for Geode</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="ci-best-practices-for-geode"
aria-haspopup="dialog"
aria-label="Share link: CI Best Practices for Geode">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="1-fail-fast" class="position-relative d-flex align-items-center group">
<span>1. Fail Fast</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="1-fail-fast"
aria-haspopup="dialog"
aria-label="Share link: 1. Fail Fast">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Prioritize quick checks first:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Run fast checks first</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">quick-checks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-24.04</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Lint (30 seconds)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Format Check (20 seconds)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Compile Check (1 minute)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Run expensive tests only if quick checks pass</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">comprehensive-tests</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="l">quick-checks</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Full Test Suite (8 minutes)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Performance Tests (15 minutes)</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="2-keep-ci-fast" class="position-relative d-flex align-items-center group">
<span>2. Keep CI Fast</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="2-keep-ci-fast"
aria-haspopup="dialog"
aria-label="Share link: 2. Keep CI Fast">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Target: Feedback within 10 minutes</p>
<p><strong>Optimization strategies</strong>:</p>
<ul>
<li>Cache aggressively (builds, dependencies, test data)</li>
<li>Parallelize independent tests</li>
<li>Use incremental testing</li>
<li>Run expensive tests nightly instead of per-commit</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">push</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">main]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">pull_request</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Fast tests on PR</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">types</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">opened, synchronize]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">schedule</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Comprehensive tests nightly</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">cron</span><span class="p">:</span><span class="w"> </span><span class="s1">'0 2 * * *'</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="3-make-ci-reproducible" class="position-relative d-flex align-items-center group">
<span>3. Make CI Reproducible</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="3-make-ci-reproducible"
aria-haspopup="dialog"
aria-label="Share link: 3. Make CI Reproducible">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Pin all versions</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">env</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ZIG_VERSION</span><span class="p">:</span><span class="w"> </span><span class="m">0.1.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">GO_VERSION</span><span class="p">:</span><span class="w"> </span><span class="m">1.24.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">PYTHON_VERSION</span><span class="p">:</span><span class="w"> </span><span class="m">3.11.8</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">RUST_VERSION</span><span class="p">:</span><span class="w"> </span><span class="m">1.70.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Pin action versions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">CHECKOUT_VERSION</span><span class="p">:</span><span class="w"> </span><span class="l">v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">SETUP_GO_VERSION</span><span class="p">:</span><span class="w"> </span><span class="l">v5</span><span class="w">
</span></span></span></code></pre></div><p><strong>Use deterministic builds</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Zig builds are deterministic by default</span>
</span></span><span class="line"><span class="cl">zig build -Doptimize<span class="o">=</span>ReleaseSafe
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Go builds with reproducibility</span>
</span></span><span class="line"><span class="cl">go build -trimpath -ldflags<span class="o">=</span><span class="s2">"-buildid="</span>
</span></span></code></pre></div>
<h4 id="4-test-in-clean-environments" class="position-relative d-flex align-items-center group">
<span>4. Test in Clean Environments</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="4-test-in-clean-environments"
aria-haspopup="dialog"
aria-label="Share link: 4. Test in Clean Environments">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Avoid environment pollution</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run Tests in Clean Environment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Each test gets fresh database
</span></span></span><span class="line"><span class="cl"><span class="sd"> for test in tests/*; do
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Clean state
</span></span></span><span class="line"><span class="cl"><span class="sd"> rm -rf /tmp/geode-test-data
</span></span></span><span class="line"><span class="cl"><span class="sd"> mkdir -p /tmp/geode-test-data
</span></span></span><span class="line"><span class="cl"><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Run isolated
</span></span></span><span class="line"><span class="cl"><span class="sd"> GEODE_DATA_DIR=/tmp/geode-test-data $test
</span></span></span><span class="line"><span class="cl"><span class="sd"> done</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="5-monitor-ci-health" class="position-relative d-flex align-items-center group">
<span>5. Monitor CI Health</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="5-monitor-ci-health"
aria-haspopup="dialog"
aria-label="Share link: 5. Monitor CI Health">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Track CI metrics:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># scripts/ci-metrics.py</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">prometheus_client</span> <span class="kn">import</span> <span class="n">Counter</span><span class="p">,</span> <span class="n">Histogram</span><span class="p">,</span> <span class="n">push_to_gateway</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">ci_duration</span> <span class="o">=</span> <span class="n">Histogram</span><span class="p">(</span><span class="s1">'ci_duration_seconds'</span><span class="p">,</span> <span class="s1">'CI duration'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'job'</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">ci_failures</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="s1">'ci_failures_total'</span><span class="p">,</span> <span class="s1">'CI failures'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'job'</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">report_ci_metrics</span><span class="p">(</span><span class="n">job_name</span><span class="p">,</span> <span class="n">duration</span><span class="p">,</span> <span class="n">success</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">ci_duration</span><span class="o">.</span><span class="n">labels</span><span class="p">(</span><span class="n">job</span><span class="o">=</span><span class="n">job_name</span><span class="p">)</span><span class="o">.</span><span class="n">observe</span><span class="p">(</span><span class="n">duration</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">success</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">ci_failures</span><span class="o">.</span><span class="n">labels</span><span class="p">(</span><span class="n">job</span><span class="o">=</span><span class="n">job_name</span><span class="p">)</span><span class="o">.</span><span class="n">inc</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">push_to_gateway</span><span class="p">(</span><span class="s1">'monitoring.geodedb.com:9091'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">job</span><span class="o">=</span><span class="s1">'ci-metrics'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">registry</span><span class="o">=</span><span class="n">registry</span><span class="p">)</span>
</span></span></code></pre></div>
<h3 id="debugging-ci-failures" class="position-relative d-flex align-items-center group">
<span>Debugging CI Failures</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="debugging-ci-failures"
aria-haspopup="dialog"
aria-label="Share link: Debugging CI Failures">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="access-build-logs" class="position-relative d-flex align-items-center group">
<span>Access Build Logs</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="access-build-logs"
aria-haspopup="dialog"
aria-label="Share link: Access Build Logs">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Download logs from GitHub Actions</span>
</span></span><span class="line"><span class="cl">gh run view <run-id> --log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Or via API</span>
</span></span><span class="line"><span class="cl">curl -L <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> -H <span class="s2">"Accept: application/vnd.github+json"</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> -H <span class="s2">"Authorization: Bearer </span><span class="nv">$GITHUB_TOKEN</span><span class="s2">"</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> https://api.github.com/repos/devnw/geode/actions/runs/<run-id>/logs
</span></span></code></pre></div>
<h4 id="reproduce-locally" class="position-relative d-flex align-items-center group">
<span>Reproduce Locally</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="reproduce-locally"
aria-haspopup="dialog"
aria-label="Share link: Reproduce Locally">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Use act to run GitHub Actions locally:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Install act</span>
</span></span><span class="line"><span class="cl">brew install act <span class="c1"># macOS</span>
</span></span><span class="line"><span class="cl"><span class="c1"># or</span>
</span></span><span class="line"><span class="cl">curl https://raw.githubusercontent.com/nektos/act/master/install.sh <span class="p">|</span> bash
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Run specific job</span>
</span></span><span class="line"><span class="cl">act -j unit-tests
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Run entire workflow</span>
</span></span><span class="line"><span class="cl">act push
</span></span></code></pre></div>
<h4 id="debug-mode" class="position-relative d-flex align-items-center group">
<span>Debug Mode</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="debug-mode"
aria-haspopup="dialog"
aria-label="Share link: Debug Mode">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Enable debug logging:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Enable Debug Logging</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">if</span><span class="p">:</span><span class="w"> </span><span class="l">runner.debug</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> export GEODE_LOG_LEVEL=debug
</span></span></span><span class="line"><span class="cl"><span class="sd"> export GEODE_TRACE=1
</span></span></span><span class="line"><span class="cl"><span class="sd"> zig build test -Dlog-level=debug</span><span class="w">
</span></span></span></code></pre></div><p>Trigger with:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">gh workflow run ci.yml -f <span class="nv">debug</span><span class="o">=</span><span class="nb">true</span>
</span></span></code></pre></div>
<h4 id="common-ci-issues" class="position-relative d-flex align-items-center group">
<span>Common CI Issues</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="common-ci-issues"
aria-haspopup="dialog"
aria-label="Share link: Common CI Issues">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Issue 1: Flaky Tests</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Mark flaky tests with retries</span>
</span></span><span class="line"><span class="cl"><span class="nd">@pytest.mark.flaky</span><span class="p">(</span><span class="n">reruns</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">reruns_delay</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_concurrent_transactions</span><span class="p">():</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Test that occasionally fails due to timing</span>
</span></span><span class="line"><span class="cl"> <span class="k">pass</span>
</span></span></code></pre></div><p><strong>Issue 2: Resource Exhaustion</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Clean Up Resources</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">if</span><span class="p">:</span><span class="w"> </span><span class="l">always()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Stop all Geode processes
</span></span></span><span class="line"><span class="cl"><span class="sd"> pkill -9 geode || true
</span></span></span><span class="line"><span class="cl"><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Clean temp data
</span></span></span><span class="line"><span class="cl"><span class="sd"> rm -rf /tmp/geode-*
</span></span></span><span class="line"><span class="cl"><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Free memory
</span></span></span><span class="line"><span class="cl"><span class="sd"> sync; echo 3 > /proc/sys/vm/drop_caches || true</span><span class="w">
</span></span></span></code></pre></div><p><strong>Issue 3: Timeout Issues</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">test</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">timeout-minutes</span><span class="p">:</span><span class="w"> </span><span class="m">30</span><span class="w"> </span><span class="c"># Prevent hanging builds</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run Tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">timeout-minutes</span><span class="p">:</span><span class="w"> </span><span class="m">20</span><span class="w"> </span><span class="c"># Per-step timeout</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">make test</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="ci-security-considerations" class="position-relative d-flex align-items-center group">
<span>CI Security Considerations</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="ci-security-considerations"
aria-haspopup="dialog"
aria-label="Share link: CI Security Considerations">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="secret-management" class="position-relative d-flex align-items-center group">
<span>Secret Management</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="secret-management"
aria-haspopup="dialog"
aria-label="Share link: Secret Management">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Configure Secrets</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">env</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">GEODE_LICENSE_KEY</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.GEODE_LICENSE_KEY }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">AWS_SECRET_KEY</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.AWS_SECRET_KEY }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Never echo secrets
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Never log secrets
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Use secrets only where needed</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="dependency-scanning" class="position-relative d-flex align-items-center group">
<span>Dependency Scanning</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="dependency-scanning"
aria-haspopup="dialog"
aria-label="Share link: Dependency Scanning">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Scan Dependencies</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd"> # Scan for vulnerabilities
</span></span></span><span class="line"><span class="cl"><span class="sd"> cd geode-client-go && govulncheck ./...
</span></span></span><span class="line"><span class="cl"><span class="sd"> cd geode-client-rust && cargo audit
</span></span></span><span class="line"><span class="cl"><span class="sd"> cd geode-client-python && safety check</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="code-scanning" class="position-relative d-flex align-items-center group">
<span>Code Scanning</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="code-scanning"
aria-haspopup="dialog"
aria-label="Share link: Code Scanning">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">CodeQL Analysis</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">github/codeql-action/analyze@v3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">languages</span><span class="p">:</span><span class="w"> </span><span class="l">go, python, cpp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">queries</span><span class="p">:</span><span class="w"> </span><span class="l">security-and-quality</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="related-topics" class="position-relative d-flex align-items-center group">
<span>Related Topics</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="related-topics"
aria-haspopup="dialog"
aria-label="Share link: Related Topics">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><ul>
<li><strong><a
href="/tags/ci-cd/"
>CI/CD</a>
</strong>: Complete CI/CD pipeline</li>
<li><strong><a
href="/tags/unit-tests/"
>Unit Tests</a>
</strong>: Unit testing strategies</li>
<li><strong><a
href="/tags/integration-tests/"
>Integration Tests</a>
</strong>: Integration testing</li>
<li><strong><a
href="/tags/deployment/"
>Deployment</a>
</strong>: Deployment automation</li>
<li><strong><a
href="/tags/containers/"
>Containers</a>
</strong>: Container-based CI</li>
<li><strong><a
href="/tags/cloud/"
>Cloud</a>
</strong>: Cloud-based CI/CD platforms</li>
</ul>
<h3 id="further-reading" class="position-relative d-flex align-items-center group">
<span>Further Reading</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="further-reading"
aria-haspopup="dialog"
aria-label="Share link: Further Reading">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><ul>
<li><strong>CI Best Practices</strong>: <code>/docs/development/ci-best-practices/</code></li>
<li><strong>Test Automation Guide</strong>: <code>/docs/development/test-automation/</code></li>
<li><strong>GitHub Actions Reference</strong>: <code>/docs/operations/github-actions/</code></li>
<li><strong>Build Optimization</strong>: <code>/docs/development/build-optimization/</code></li>
<li><strong>Quality Assurance</strong>: <code>/docs/development/quality-assurance/</code></li>
</ul>
Related Articles
No articles found with this tag yet.
Back to Home