> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# CI/CD — Aspect Build Blog

> 14 CI/CD posts from the Aspect Build engineering blog on Bazel and developer productivity.

export const BlogCard = ({title, description, date, authors, tags, image, href, children}) => {
  const tagList = tags ? tags.split(", ").filter(Boolean) : [];
  const tagSlug = t => t.toLowerCase().replace(/&/g, "").replace(/\+/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
  const formattedDate = date ? new Date(date + "T00:00:00").toLocaleDateString("en-US", {
    year: "numeric",
    month: "short",
    day: "numeric"
  }) : "";
  const resolvedImage = typeof image === "string" && image.trim() === "" ? null : image;
  return <div data-tags={tagList.join(",")} className="blog-card flex flex-col rounded-xl border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 overflow-hidden hover:shadow-lg transition group">
      <a href={href} className="block">
        {resolvedImage ? typeof resolvedImage === "string" ? <img noZoom src={resolvedImage} alt={title} className="w-full" style={{
    height: "180px",
    objectFit: "cover"
  }} /> : <div className="blog-card-image">{resolvedImage}</div> : children ? <div className="blog-card-image">{children}</div> : null}
        <div className="px-5 pt-5">
          <h3 className="text-lg font-semibold text-zinc-900 dark:text-white group-hover:text-blue-600 dark:group-hover:text-blue-400 transition">
            {title}
          </h3>
          {description && <p className="mt-2 text-sm text-zinc-600 dark:text-zinc-400 line-clamp-2">
              {description}
            </p>}
          <div className="flex items-center gap-2 mt-3 text-xs text-zinc-500 dark:text-zinc-400">
            {authors && <span>{authors}</span>}
            {authors && formattedDate && <span>·</span>}
            {formattedDate && <span>{formattedDate}</span>}
          </div>
        </div>
      </a>
      {tagList.length > 0 && <div className="flex flex-wrap gap-1.5 px-5 pb-4 pt-3 mt-auto">
          {tagList.map(tag => <a key={tag} href={"/blog/tags/" + tagSlug(tag)} className="px-2 py-0.5 rounded-full text-xs bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 hover:bg-blue-100 dark:hover:bg-blue-900/40 hover:text-blue-700 dark:hover:text-blue-300 transition">
              {tag}
            </a>)}
        </div>}
    </div>;
};

export const MarketingPage = () => <div className="marketing-page-marker" style={{
  display: "none"
}} />;

export const Section = ({children, className = "", gray = false, dark = false, id}) => <section id={id} className={`w-full flex justify-center px-4 py-16 md:py-24 ${gray ? "bg-gray-50 dark:bg-zinc-900" : dark ? "bg-zinc-900 dark:bg-zinc-950" : ""} ${className}`}>
    <div className="w-full" style={{
  maxWidth: "1140px"
}}>
      {children}
    </div>
  </section>;

export const Hero = ({title, subtitle, badge, eyebrow, heroImageClassName = "", primaryCta, primaryHref = "#", secondaryCta, secondaryHref = "#", centered = true, children}) => <section className="w-full flex justify-center px-4 pt-16 pb-16 md:pt-24 md:pb-24" style={{
  background: "linear-gradient(180deg, var(--hero-gradient-start, #f8fafc) 0%, var(--hero-gradient-end, #ffffff) 100%)"
}}>
    <div className="w-full" style={{
  maxWidth: "1140px"
}}>
      {centered && !children ? <div className="flex flex-col items-center text-center">
          {badge && <div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-700 text-blue-700 dark:text-blue-300 text-sm font-medium mb-6">
              {badge}
            </div>}
          {eyebrow && <div className="text-xs font-semibold tracking-widest uppercase text-blue-600 dark:text-blue-400 mb-4">
              {eyebrow}
            </div>}
          <h1 className="text-4xl md:text-5xl font-semibold text-zinc-900 dark:text-white leading-tight tracking-tight" style={{
  maxWidth: "820px"
}}>
            {String(title).split(/\\n|\n/).map((line, i) => i ? [<br key={i} />, line] : line)}
          </h1>
          {subtitle && <div className="subtitle-gap text-lg md:text-xl text-zinc-500 dark:text-zinc-300 leading-relaxed" style={{
  marginTop: "1rem",
  maxWidth: "600px"
}}>
              {subtitle}
            </div>}
          <div className="flex flex-wrap gap-3 mt-10 justify-center">
            {primaryCta && <a href={primaryHref} className="inline-flex items-center px-6 py-3 rounded-lg bg-blue-600 text-white font-semibold hover:bg-blue-700 transition shadow-sm">
                {primaryCta}
              </a>}
            {secondaryCta && <a href={secondaryHref} className={`inline-flex items-center px-6 py-3 rounded-lg border border-zinc-300 dark:border-zinc-600 text-zinc-700 dark:text-zinc-200 font-semibold hover:bg-zinc-50 dark:hover:bg-zinc-800 transition ${secondaryHref === "/request-demo" ? "demo-gradient-btn" : ""}`}>
                {secondaryCta}
              </a>}
          </div>
        </div> : <div className="flex flex-col md:flex-row items-center gap-10 md:gap-16">
          <div className="flex-1 min-w-0">
            {badge && <div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-700 text-blue-700 dark:text-blue-300 text-sm font-medium mb-6">
                {badge}
              </div>}
            {eyebrow && <div className="text-xs font-semibold tracking-widest uppercase text-blue-600 dark:text-blue-400 mb-4">
                {eyebrow}
              </div>}
            <h1 className="text-4xl md:text-5xl font-semibold text-zinc-900 dark:text-white leading-tight tracking-tight">
            {String(title).split(/\\n|\n/).map((line, i) => i ? [<br key={i} />, line] : line)}
          </h1>
            {subtitle && <div className="subtitle-gap text-lg md:text-xl text-zinc-500 dark:text-zinc-300 leading-relaxed" style={{
  marginTop: "1rem"
}}>
                {subtitle}
              </div>}
            <div className="flex flex-wrap gap-3 mt-8">
              {primaryCta && <a href={primaryHref} className="inline-flex items-center px-6 py-3 rounded-lg bg-blue-600 text-white font-semibold hover:bg-blue-700 transition shadow-sm">
                  {primaryCta}
                </a>}
              {secondaryCta && <a href={secondaryHref} className={`inline-flex items-center px-6 py-3 rounded-lg border border-zinc-300 dark:border-zinc-600 text-zinc-700 dark:text-zinc-200 font-semibold hover:bg-zinc-50 dark:hover:bg-zinc-800 transition ${secondaryHref === "/request-demo" ? "demo-gradient-btn" : ""}`}>
                  {secondaryCta}
                </a>}
            </div>
          </div>
          {children && <div className={`flex-1 min-w-0 hero-image ${heroImageClassName}`}>
              {children}
            </div>}
        </div>}
    </div>
  </section>;

<MarketingPage />

<Hero title="Posts tagged CI/CD" subtitle="Engineering writing from the Aspect team on CI/CD." centered={true} />

<Section>
  <div className="mb-8">
    <a href="/blog" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">← All posts</a>
    <span className="mx-2 text-zinc-400">·</span>
    <a href="/blog/tags" className="text-blue-600 dark:text-blue-400 font-semibold hover:underline">Browse all tags</a>
  </div>

  <div className="marketing-grid-3">
    <BlogCard title="Which tests are affected? Ask the cache, run nothing." description="How aspect cache diff figures out which tests a change can break, using only a remote cache and Bazel's gRPC log, without executing anything." date="2026-06-19" authors="Şahin Yort" href="/blog/selective-testing-with-cache-diff" tags="Aspect CLI, Remote Cache, CI/CD, Bazel">
      <img noZoom src="https://mintcdn.com/aspectbuild/47KirY4nMIQxGx6F/images/blog/stock/box-selected.jpg?fit=max&auto=format&n=47KirY4nMIQxGx6F&q=85&s=7e551722ebee512510b1414a80a96bdc" alt="" width="1200" height="743" data-path="images/blog/stock/box-selected.jpg" />
    </BlogCard>

    <BlogCard title="Bazel technique for Continuous Delivery" description="Learn about using Bazel for Continuous Delivery, distinguishing between CI, CD, and Deployment, and optimizing artifact delivery processes" date="2025-07-03" authors="Alex Eagle" href="/blog/bazel-technique-for-continuous-delivery" tags="Selective Delivery, CI/CD, Bazel">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-44f882ad1c.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=e3ce520f18be74952a3158397543eed7" alt="" width="1600" height="1065" data-path="images/blog/hashnode/hn-44f882ad1c.jpeg" />
    </BlogCard>

    <BlogCard title="Dagger and Bazel" description="Compare Dagger and Bazel: explore key differences in containerization, configuration, language support, reproducibility, and community impact for build tool" date="2025-02-24" authors="Chris Chinchilla" href="/blog/dagger-and-bazel" tags="Bazel, CI/CD">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-ed4debf549.png?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=de9ef0c53f52b7a07d9fd551f05412b5" alt="" width="1914" height="1000" data-path="images/blog/hashnode/hn-ed4debf549.png" />
    </BlogCard>

    <BlogCard title="Self-hosting your CI/CD infra" description="Discover how Aspect Workflows powers Bazel CI/CD with a BYOC model, boosting security, compliance, cost control, and seamless integration in the cloud stack" date="2024-12-17" authors="Alex Eagle" href="/blog/self-hosting-your-cicd-infra" tags="CI/CD, Remote Execution">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-f821fe5c19.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=633954c396802c2a14ae6b6fb0914731" alt="" width="768" height="512" data-path="images/blog/hashnode/hn-f821fe5c19.jpeg" />
    </BlogCard>

    <BlogCard title="Announcing Remote Build Execution" description="Aspect Workflows now includes Remote Build Execution, speeding development by offloading computation to worker machines" date="2024-08-20" authors="Alex Eagle" href="/blog/announcing-remote-build-execution" tags="Remote Execution, CI/CD, Company">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-76283152cc.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=cbaecf858ba886265d2665cc6a8091ad" alt="" width="1627" height="1219" data-path="images/blog/hashnode/hn-76283152cc.jpeg" />
    </BlogCard>

    <BlogCard title="Keeping main green in a monorepo" description="Explore how to prevent red main branches with merge queues, on-call policies, and better CI practices to improve development workflows and team efficiency." date="2024-06-21" authors="Alex Eagle" href="/blog/keeping-main-green" tags="Monorepo, CI/CD">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-9071e4d0f6.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=3c35acebf82edbee6421490d4c6bad53" alt="" width="1600" height="1200" data-path="images/blog/hashnode/hn-9071e4d0f6.jpeg" />
    </BlogCard>

    <BlogCard title="Aspect Workflows Case Study: Sourcegraph" description="Learn how Sourcegraph improved CI/CD performance and reduced costs by implementing Aspect Workflows." date="2024-04-23" authors="Alex Eagle" href="/blog/case-study-sourcegraph" tags="Bazel, Company, CI/CD">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-4c92c9630e.png?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=a1f60c02f6c010f4cdbaa78aa8558999" alt="" width="1600" height="840" data-path="images/blog/hashnode/hn-4c92c9630e.png" />
    </BlogCard>

    <BlogCard title="Integration testing your container images with Bazel" description="Explore two approaches for migrating Docker Compose tests to Bazel for better integration and test management." date="2023-11-08" authors="Alex Eagle" href="/blog/integration-testing-oci" tags="Containers & OCI, CI/CD, Bazel">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-252202200a.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=23edcbf77f14f94fef4aa8724dd55fa5" alt="" width="1600" height="1067" data-path="images/blog/hashnode/hn-252202200a.jpeg" />
    </BlogCard>

    <BlogCard title="Automated testing of each commit != CI" description="Explore how microservice architectures hinder true Continuous Integration and why API contracts alone can't prevent integration issues. Learn how to fix it." date="2023-08-13" authors="Alex Eagle" href="/blog/automated-testing-of-each-commit-ci" tags="CI/CD, Bazel">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-894764dedd.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=814547b5e217ab01a1b616f28e619276" alt="" width="1600" height="1067" data-path="images/blog/hashnode/hn-894764dedd.jpeg" />
    </BlogCard>

    <BlogCard title="Estimating the effort to build a Bazel CI/CD" description="Learn the key challenges of integrating Bazel into CI/CD pipelines and the effort required." date="2023-02-25" authors="Alex Eagle" href="/blog/estimating-bazel-cicd" tags="CI/CD, Bazel, Migration">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-e7a3fd4726.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=cdb310b654211932ccf941c97c66cacd" alt="" width="1600" height="1067" data-path="images/blog/hashnode/hn-e7a3fd4726.jpeg" />
    </BlogCard>

    <BlogCard title="GitHub Actions Dynamic Matrix" description="Guide to configuring dynamic matrices in GitHub Actions using bash scripts and JSON arrays for flexible job handling." date="2022-10-28" authors="Alex Eagle" href="/blog/github-actions-dynamic-matrix" tags="CI/CD, Bazel">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/stock/network-mesh.jpg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=0911ebc13499261ebce9979ce56e500d" alt="" width="800" height="533" data-path="images/blog/stock/network-mesh.jpg" />
    </BlogCard>

    <BlogCard title="Monorepo Shared Green" description="Learn about the benefits of implementing a \\&#x22;shared green\\&#x22; monobuild model in a monorepo for improved code sharing and consistency" date="2022-08-08" authors="Alex Eagle" href="/blog/monorepo-shared-green" tags="Monorepo, CI/CD">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-22114cf9a4.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=d54583a6ac224882752e712c89eedab3" alt="" width="1600" height="1067" data-path="images/blog/hashnode/hn-22114cf9a4.jpeg" />
    </BlogCard>

    <BlogCard title="What is a build system and what is CI?" description="Discover the essence of build systems and CI in software development, unraveling their interconnected roles and impact on development processes" date="2021-06-01" authors="Alex Eagle" href="/blog/what-is-a-build-system-and-what-is-ci" tags="CI/CD, Bazel">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/stock/construction.jpg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=bf94f8005eb965dcedc8b66da772f6f4" alt="" width="800" height="533" data-path="images/blog/stock/construction.jpg" />
    </BlogCard>

    <BlogCard title="CBOI: Continuous Build, Occasional Integration" description="\\&#x22;Continuous Build, Occasional Integration\\&#x22; fails in software development and how to switch to effective Continuous Integration" date="2021-05-10" authors="Alex Eagle" href="/blog/cboi-continuous-build-occasional-integration" tags="CI/CD, Monorepo">
      <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-89d02e6ca2.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=6bb965e49720cb1efbeb65127114c3be" alt="" width="1437" height="958" data-path="images/blog/hashnode/hn-89d02e6ca2.jpeg" />
    </BlogCard>
  </div>
</Section>
