讓 CI 流水線保持綠燈已不再是難事
Running a Green CI Pipeline Isn't the Hard Part Anymore
AI 編碼助手提高提交量後,沿用原有驗證方式的 CI 流水線成為交付瓶頸,單一檔案改動仍可能觸發完整建置和測試。文章以 Harness CI 示範 Cache Intelligence、Test Intelligence 和 Build Intelligence 等功能;測試管線快取了 13 MB Maven 依賴,第二次執行在 9 秒內完成還原。
Six months ago, your team adopted an AI coding assistant. Pull requests doubled. Generated code started landing in branches faster than reviewers could read it. The CI pipeline kept up for about three weeks.
Now the queue backs up by mid-morning. Builds take 38 minutes. 4,000 tests run on every commit when 60 are relevant. The pipeline was designed for developers writing code. It is now processing code that machines write, at machine speed, with human-era validation.
This is for platform engineers and engineering leads dealing with what happens when AI-generated code meets a CI pipeline that was never built for that volume.
Green is the baseline. It is not the finish line.
AI writes the code faster. CI still validates it the slow way.
The bottleneck shifted. AI coding assistants removed the slowest part of the development cycle: writing code. What they did not touch is everything after the commit: dependency resolution, compilation, test execution, image builds. Those still run the same way they did when a developer pushed two PRs a day instead of ten.
Look at what happens on a single-file change: full dependency downloads, full compilation, full test suite, full Docker layer rebuilds. Multiply that by the PR volume an AI assistant generates. GitHub's 2023 developer experience survey found that developers already spend as much time waiting for builds as writing code. AI tools did not shrink that wait. They stacked more builds into it.
Incredibuild's survey found 98% of developers wasted time waiting for builds, with build times increasing nearly 16% year over year. That was measured before AI-generated commits were a factor.
Then there is the trust problem. More commits means more pipeline runs, which means more exposure to flaky tests. Slack's mobile team watched flaky tests drive their main branch build pass rate to 20%. Each failure took 28 minutes to triage. At AI-assisted commit velocity, flaky tests do not just slow you down. They stop the entire merge queue.
CircleCI's 2026 report, analysing 28 million workflows, confirms the pattern: increased code volume is exposing validation as a delivery bottleneck. AI made the input faster. The pipeline is still the same.
Two approaches to CI in the AI era: faster execution or less work
Most teams start with the first: bigger runners, parallelised tests, cached dependencies, conditional pipeline logic. These help. But they optimise the wrong layer. Doubling CPU on 5,000 tests still runs 4,700 unnecessary tests, whether a human or an AI wrote the change.
The more interesting approach: stop doing work that does not need to happen. Detect which dependencies changed, which modules need recompilation, which tests are affected by the code change, and skip everything else. At AI-generated volume, the savings multiply with every PR that skips redundant work.
That is the path this walkthrough follows with Harness CI.
Here is where each type of waste maps to a Harness CI feature. Every row in this table gets worse as AI-generated commit volume increases:
| Waste | What happens | Harness feature |
|---|---|---|
| Dependency re-downloads | Every run fetches the same packages | Cache Intelligence |
| Unnecessary recompilation | Unchanged modules rebuilt from scratch | Build Intelligence |
| Full test suite on small changes | 4,000 tests when 60 are relevant | Test Intelligence |
| Docker layer rebuilds | Base layers rebuilt despite no Dockerfile change | Docker Layer Caching |
| Serial test execution | Tests run single-threaded on one runner | Test splitting and parallelism |
| Flaky test noise | Intermittent failures block unrelated PRs | Flaky test detection and quarantine |
Enabling Cache Intelligence, Test Intelligence, and Build Intelligence
The Harness CI intelligence features work at the stage level. You do not install plugins or write custom caching scripts. You enable them in your pipeline configuration.
Here is a Java Maven pipeline with Cache Intelligence and Test Intelligence active, running on Harness Cloud:
pipeline:
name: ci green not enough - SD
inputs:
branch:
type: string
required: true
default: main
clone:
enabled: true
connector: shibam_github
repo: shibam17/ci-intelligence-lab
ref: ${{ inputs.branch }}
stages:
- id: build
name: Build
runtime: cloud
platform:
os: linux
arch: amd64
cache:
enabled: true
steps:
- id: run_tests
name: Run Tests
run-test:
container:
image: maven:3.9-eclipse-temurin-17
script: mvn clean test
intelligence:
disabled: false
report:
paths:
- "**/*.xml"
Two things are happening in this pipeline that do not happen in a standard CI setup:
Cache Intelligence (stage level)
cache:
enabled: true
That is it. Harness detects the build tooling (Maven in this case, also supports Gradle, Yarn, Go, .NET, Bazel) and automatically preserves and restores the dependency cache between runs. The cache key is derived from files like pom.xml or build.gradle. No manual cache key configuration, no hashFiles() expressions, no cache invalidation scripts.
On the first run, the cache step shows "file not found" because nothing has been saved yet. On every subsequent run, it restores the full .m2/repository in seconds. In our test pipeline, the cache save uploaded 13 MB of Maven dependencies, and the second run restored them in 9 seconds instead of re-downloading.
Run #7: Cache Intelligence saving 13 MB of Maven dependencies (compressed to 12 MB), cached in 745ms
Test Intelligence (run-test step)
run-test:
script: mvn clean test
intelligence:
disabled: false
Setting intelligence.disabled: false activates Test Intelligence. Harness uses code-change information and a call graph to identify which unit tests are affected by the changed code. It selects those tests, plus any new or modified tests. Everything else is skipped.
Test Intelligence supports Java, Python, Ruby, C#, Kotlin, and Scala. The call graph is built per language.
On our first run, TI built a call graph with 82 nodes and 39 test relations across all 42 tests. On the second run, after changing a single file (InputValidator.java), TI selected only 12 tests and skipped the remaining 30. The test run time dropped from 58ms to 16ms.
On broad-impact changes (like modifying pom.xml), the system runs the full suite automatically. It does not blindly skip.
Run #7: Test Intelligence selected 12 tests and skipped 30 after a single-file change to InputValidator.java
Build Intelligence (stage level)
For pipelines that compile code, Build Intelligence adds another layer:
build-intelligence:
enabled: true
Build Intelligence operates on compiled outputs. If the inputs for a module have not changed, Harness retrieves the previously generated build output instead of recompiling. Gradle, Bazel, and Maven 3.9+ are supported.
This layer stacks on top of Cache Intelligence: caching avoids re-downloading dependencies, Build Intelligence avoids re-compiling code that has not changed.
Two more layers worth knowing about: Docker Layer Caching stores previously built image layers so that only changed layers rebuild, which matters most for pipelines that build container images on every commit. Test splitting and parallelism distributes your test suite across multiple runners based on timing data, so a 20-minute serial test run can drop to 5 minutes across four parallel stages. Both stack with the intelligence features above.
Flaky test detection (automatic)
Harness tracks test results over a 14-day observation window. A test that has both passed and failed against the same commit within that window gets a FLAKY indicator. Quarantine mode keeps the test running and visible but prevents its failure from blocking the pipeline. The test exits quarantine after five consecutive successful runs.
Before and after
We ran this pipeline against a Java Maven project with 42 unit tests across 5 service modules (order, inventory, pricing, notification, validation). Here is what changed between the first run (no cache, no call graph) and the second run (single file changed):
| Metric | Run #6 (baseline) | Run #7 (with intelligence) |
|---|---|---|
| Cache restore | Miss (no prior cache) | Hit (13 MB restored in 9s) |
| Tests executed | 42 (full suite) | 12 (selected by TI) |
| Tests skipped by TI | 0 | 30 |
| Test run time | 58ms | 16ms |
| Call graph | Built (82 nodes, 39 relations) | Reused for selection |
| Failure rate | 2.38% (1 test bug) | 0% |
Before (Run #6): 42 tests, all executed, 1 failed, 0 skipped by TI
After (Run #7): 42 tests, 12 executed, 30 skipped by TI, 0 failures
The pipeline is still green. It is just doing 71% less test work to get there. On a larger codebase with thousands of tests, that ratio translates to minutes saved per commit.
What connects beyond CI
Faster CI is one layer. The bottlenecks on either side are different problems.
Code that passes CI and sits in staging for three weeks is a deployment problem. Continuous Delivery with progressive rollout and built-in verification closes that gap: code moves to production when it is ready, not when someone remembers to deploy it.
Security alerts from four different scanners creating duplicate noise is a triage problem. Security Testing Orchestration deduplicates findings and gives developers one prioritised list instead of four noisy dashboards.
CI costs spiralling across dozens of feature branches is a visibility problem. Cloud Cost Management shows what each pipeline actually costs, per branch, per team.
Try it against your pipeline
The fastest way to see the difference: take an existing pipeline, add cache: enabled: true at the stage level, and swap your run test step for a run-test step with intelligence: disabled: false. Run it twice. Compare the second run's test count against your baseline.
# The minimum change to enable intelligence on an existing pipeline:
stages:
- id: build
name: Build
runtime: cloud
cache:
enabled: true
steps:
- id: tests
name: Tests
run-test:
container:
image: maven:3.9-eclipse-temurin-17
script: mvn clean test
intelligence:
disabled: false
report:
paths:
- "**/*.xml"
Start with Harness CI documentation for the full configuration reference per language and build tool.
Frequently asked questions
How do I know if my CI pipeline is doing unnecessary work?
Look at what runs on a single-file change. If the pipeline downloads all dependencies, rebuilds all modules, and runs the full test suite, those are layers of repeated work. Cache hit rates, test selection ratios, and build output reuse are the metrics that matter.
What is the difference between Cache Intelligence and Build Intelligence?
Cache Intelligence preserves downloaded dependencies between runs so you do not fetch the same packages again. Build Intelligence preserves compiled build outputs so you do not recompile modules whose inputs have not changed. One avoids re-downloading. The other avoids re-building.
Does Test Intelligence skip tests randomly?
No. It uses code-change information and a call graph to determine which tests are associated with the changed code. It selects those tests plus any new or modified tests. It runs the full suite on broad-impact changes like pom.xml modifications.
Can these work with my existing pipeline?
Yes. Cache Intelligence and Test Intelligence work with Harness Cloud and self-hosted runners. You do not need to rewrite your pipeline. Enable caching at the stage level and swap your test step to run-test with intelligence: disabled: false.
What languages does Test Intelligence support?
Java, Python, Ruby, C#, Kotlin, and Scala.
來源:DEV Community · dev.to



