惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
T
Threatpost
T
Tor Project blog
S
Schneier on Security
Project Zero
Project Zero
Know Your Adversary
Know Your Adversary
P
Proofpoint News Feed
K
Kaspersky official blog
P
Privacy International News Feed
Latest news
Latest news
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
The Hacker News
The Hacker News
D
Docker
aimingoo的专栏
aimingoo的专栏
S
Securelist
C
Cyber Attacks, Cyber Crime and Cyber Security
Spread Privacy
Spread Privacy
TaoSecurity Blog
TaoSecurity Blog
T
The Blog of Author Tim Ferriss
T
Threat Research - Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 三生石上(FineUI控件)
人人都是产品经理
人人都是产品经理
Security Latest
Security Latest
V
Visual Studio Blog
WordPress大学
WordPress大学
J
Java Code Geeks
O
OpenAI News
T
Tailwind CSS Blog
S
Secure Thoughts
G
Google Developers Blog
博客园_首页
The Cloudflare Blog
The Register - Security
The Register - Security
A
Arctic Wolf
Y
Y Combinator Blog
阮一峰的网络日志
阮一峰的网络日志
B
Blog RSS Feed
IT之家
IT之家
美团技术团队
D
Darknet – Hacking Tools, Hacker News & Cyber Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
G
GRAHAM CLULEY
S
Security Affairs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Palo Alto Networks Blog
C
CERT Recently Published Vulnerability Notes
W
WeLiveSecurity

Graphite blog

Introducing Code Tours: a new way to review Introducing Cursor Cloud Agents in Graphite Building the future of software development with Cursor Reimagining the PR Page: Designing for speed and focus Graphite changelog [11-20-2025] Graphite changelog [11-04-2025] Graphite changelog [10-16-2025] The future of engineering is collaborative (and already here) Meet Graphite Agent: the next evolution of AI code review Introducing frozen branches: A safer way to build on your teammates’ work Graphite changelog [09-17-2025] How we sped up code search for Graphite Chat Introducing Graphite Chat AI is writing code—here's why it also needs to review that code How I got Claude to write code I could actually ship How we built the first stack-aware merge queue (and why it matters) How we organize our monorepo to ship fast Graphite brings stacking to Tower Code review tooling: Should you build or buy? Making AI code review available to everyone Introducing: The new Graphite + Linear integration Graphite raises $52M and launches Diamond to reimagine code review for the age of AI Why AI will never replace human code review How stacked PRs unblock distributed development teams Graphite is going to Developer Week 2025 Beating the end of year code freeze How Graphite’s eng team ships code remarkably fast Why we chose Anthropic's Claude to power Graphite Reviewer AI code generation will remain fragmented How we redesigned Graphite's landing page in-house Introducing Graphite Reviewer: your AI code review companion How AI code review reduces review cycles to improve developer productivity What if you could get instant feedback on your code? The new developer toolchain Not Rocket Science - How Bors and Google’s TAP inspired modern merge queues Graphite's State of code review 2024 How Google migrated billions of lines of code from Perforce to Piper Going from 0 to 1: How to write better unit tests when there are none Speed up your merges: Parallel CI is now generally available for teams using Graphite’s merge queue Down for less than four minutes a month: how AWS deploys code BitKeeper, Linux, and licensing disputes: How Linus wrote Git in 14 days Graphite is now free for startups and open source projects Launch week wrap-up (May 2024) Reduce CI costs for Buildkite and GitHub Actions Cheaper CI & faster merging with batching How Google does code review The technical learning curve at a startup is gentler than you might think Graphite will now automatically rebase your partially-merged stacks Multiple engineers can now seamlessly collaborate on the same stack of PRs Do you ever outgrow GitHub? From the 80's to 2024 - how CI tests were invented and optimized Graphite changelog [4/10/2024] 🎺 Graphite changelog [4/25/2024] 🐸 How Stack Overflow replaced Experts Exchange How GitHub monopolized code hosting Graphite changelog [3/27/2024] 🤝 The core principles of building a good AI feature Onboarding roulette: deleting our employee accounts daily Graphite changelog [3/13/2024] 🚁 Why Facebook doesn’t use Git How to recreate the Phabricator code review workflow Types of code reviews: Improve performance, velocity, and quality What's the best GitHub pull request merge strategy? Phabricator vs GitHub vs Graphite: How do they stack up? Improving team velocity through better pull request practices Moving fast breaks things: the importance of a staging environment Building trust as a software engineer Keeping code simple: moving fast by avoiding over-engineering What's better than GitHub pull request filters? The Graphite pull request inbox 7 Best Phabricator alternatives for PR stacking + code review [2024] Accurate eng estimations: predicting and negotiating the future Tracking and understanding GitHub PR stats: A step-by-step guide 8 pull request best practices for optimal engineering What’s next for Graphite Graphite Q1 Launch week: Stacking with the tools you love Graphite Q1 Launch week: Making stacking seamless Accelerating code review The Mom Test How to use stacked PRs to unblock your entire team Graphite Q1 launch week 2024 The practical and philosophical problems with AI code review Empirically sup code review best practices Call site attribution: how to pinpoint rogue SQL queries throttling your performance Every engineer should understand git reflog Post mortem: we took 124 seconds from you, here's 378 back Your GitHub pull request workflow is slowing everyone down Why we use AWS instead of Vercel to host our Next.js app How large pull requests slow down development 3 key lessons in application server optimization Trunk-based development: why you should stop using feature branches Git was built in 5 days Why large companies and fast-moving startups are banning merge commits How long should your CI take? Experimenting with AI code review CRA to AppRouter in 5 Steps: A case study with Graphite Graphite Changelog [10/18/2023] The comprehensive guide to writing the best PR title of all time How 10,000 Developers All Contribute to the same Repo
Optimizing CI/CD workflows for trunk-based development
Greg Foster · 2023-11-30 · via Graphite blog

Almost all of us have some experience with continuous integration, continuous delivery (CI/CD) systems. Whether you use GitHub Actions, Jenkins, or are one of the five people in the world still using Concourse, CI/CD systems provide the backbone of how most organizations build and ship software. However, one question we hear a lot from Graphite users is: how do we optimize our CI/CD pipelines to balance speed, cost, and efficiency?

In this post we’ll cover common challenges in CI/CD workflows, as well as share insights and best practices that our team here at Graphite has gathered over their collective decades of experience working at organizations of all shapes and sizes.

Challenges in CI/CD

The two biggest potential problems in CI/CD flows are time and financial cost, which, if not managed properly, can quickly spiral out of control, grinding your eng team to a halt while running up a big compute bill in the process.

Time cost: Productive eng teams need fast CI processes. A slow CI pipeline can quickly become a bottleneck, delaying review feedback, slowing down merge queues, and hampering the overall pace of development. This is particularly painful for teams using trunk-based development, where short-lived branches and frequent merges are standard practice, meaning that CI disruptions can easily snowball as engineers add more and more PRs to the queue.

Financial Cost: The typical response to slow CI processes is increased parallelization, but this often comes with increased computational and hosting costs. An initially simple setup can, over time, morph into a complex array of parallel jobs. Because each of these jobs run on every revision of every PR, the associated costs can quickly balloon into tens or even hundreds of thousands of dollars in compute spend a month.

With these challenges in mind, fast-moving eng teams need to strike a delicate balance in their CI setups. Your CI process should ensure comprehensive test coverage, while at the same time balancing speed and resource requirements to keep costs in check. The 2nd half of this post delves into strategies and best practices for creating a time and cost-efficient CI/CD pipeline.

Strategies for optimizing CI/CD

Here are a few strategies that we use at Graphite to optimize our CI/CD pipelines:

Parallelization

It’s important to keep your CI runtime under control. Aim for a total CI time of under 10 minutes. Fast CI runtimes accelerate the time-to-merge and keep development momentum high.

Techniques for parallelizing unit tests:

  • Utilize testing libraries that support parallel execution. Match the parallelization level to the number of cores available on your test runner.

  • For example in GitHub Actions you can define matrices of different job configurations:

jobs:

parallelization_matrix:

strategy:

matrix:

version: [1, 3, 5]

os: [fedora-latest, ubuntu-latest]

Each possible combination of variables will trigger its own job run, so for this example a total of 6 jobs will run. Jobs will all run in parallel, depending on runner availability.

Strategies for dividing tests into sub-groups:

Split unit tests by module, sub-project, or hash of test file names. This allows for running multiple jobs or workflows in parallel.

Example of a test splitting configuration:

jobs:

test-module-A:

runs-on: ubuntu-latest

steps:

- name: Run module A tests

run: npm run test:module-A

test-module-B:

runs-on: ubuntu-latest

steps:

- name: Run module B tests

run: npm run test:module-B

Avoiding redundant work

Repetition in CI/CD flows is expensive. Avoid having each parallel job reinstall dependencies or rebuild the project. This can add significant time and cost to each CI run.

Best practices for caching and artifact management:

  • Use caching strategies to store and reuse build artifacts across jobs.

  • Recommended tools:

Example of efficient caching:

  • Cache your dependencies and build outputs to be reused in subsequent jobs.

  • Example GitHub Actions cache configuration:

steps:

- uses: actions/cache@v2

with:

path: |

node_modules

build-output

key: ${{ runner.os }}-build-${{ hashFiles('**/lockfiles') }}

Selective testing

Avoid re-testing everything on every code change. This is inefficient, especially in large projects and monorepos.

Approaches for building and testing based on selective changes:

  • Implement CI logic to detect and test only the changed components.

  • Use tools like Vercel’s Turbo to detect changes and trigger the necessary builds and tests.

  • Example of selective testing using GitHub Actions’ paths filter on push triggers:

on:

push:

paths:

- 'module-A/**'

- 'module-B/**'

Fail-fast principle

Halting CI workflows on failure:

  • Configure your CI to stop all subsequent jobs upon the first failure, saving time and resources.

  • Example of a fail-fast setup in GitHub Actions using the if conditional and this custom action that uses GitHub’s API to cancel the current job:

name: cancel_workflow

if: failure() || steps.lint_all.outcome == 'failure'

uses: andymckay/cancel-action@0.2

Configuring CI to cancel redundant executions:

  • Avoid running multiple CI executions for the same PR; you should cancel any in-progress runs when a new push is made, as all previous runs are now running on a deprecated version of the branch.

  • Example GitHub Actions configuration for canceling in-progress jobs using GitHub’s cancel-in-progress keyword.

concurrency:

group: ${{ github.workflow }}-${{ github.ref }}

cancel-in-progress: true

Set timeouts to prevent hanging jobs:

  • Implement a maximum timeout for CI jobs to avoid long-running or stalled jobs.

  • Example timeout configuration:

jobs:

build:

runs-on: ubuntu-latest

timeout-minutes: 20

Through these strategies and practices, you can significantly optimize your CI/CD pipelines, ensuring that they are not only robust and reliable but also cost-effective and time-efficient.

Additional considerations

When optimizing your CI/CD pipeline, you should make sure to consider your team’s development workflows & processes. For example, your team’s repo setup will greatly affect how you approach CI:

Monorepo vs. polyrepo:

  • Monorepo advantages: In a monorepo, all of your projects and libraries reside in a single repository, simplifying dependency management and ensuring consistency across the codebase. This setup can significantly benefit CI/CD as changes across multiple projects can be tested together, ensuring that integration points are always in sync.

  • Polyrepo considerations: Polyrepos, where each project or library has its own repository, naturally shard code, which introduces complexity in managing atomic changes across repositories. While it may make testing siloed feature sets easier, it ultimately complicates integrating these features.

Graphite's Recommendation: Use a monorepo, especially for larger teams. It simplifies CI/CD pipeline management and fosters a more integrated development environment.

Key takeaways

  1. Prioritize parallelization:

    • Assess opportunities: Regularly review your test suites and other CI jobs to identify opportunities for parallel execution.

    • Optimize resource allocation: Match the number of parallel jobs to your available computational resources to maximize efficiency without overloading the system.

    • Use parallel-friendly tools: Employ tools and frameworks that inherently support parallel execution of tasks.

  2. Avoid redundant work:

    • Implement efficient caching: Cache dependencies and build artifacts to reuse them across jobs, reducing the time spent in setup.

    • Optimize docker layers: If using Docker, structure your Dockerfiles to take advantage of layer caching.

    • Use smart build systems: Employ build systems that can intelligently skip unchanged parts of the codebase.

  3. Embrace selective testing:

    • Implement change detection: Use tools like Vercel’s Turbo to isolate testing on only the parts of the codebase that have changed.

    • Configure path-based triggers: Set up your CI to trigger different workflows based on the paths of changed files.

    • Shallow clone: Only checkout the code you need for testing, cutting out time spent pulling down extraneous data.

  4. Implement the fail-fast principle:

    • Early exit on failure: Configure your CI pipeline to stop subsequent steps immediately after a failure is detected.

    • Prioritize fast feedback loops: Run the quickest tests (like linters and static analysis) early in the CI process.

  5. Optimize dependency management:

    • Use dependency locking: Utilize lock files to ensure consistent dependency installation across all CI runs.

    • Optimize dependency retrieval: Use a package manager that supports efficient retrieval and caching of dependencies.

    • Prune unnecessary dependencies: Regularly audit your dependencies to remove or update those that are no longer needed or are outdated.

Optimizing your CI/CD pipeline is a juggling act of balancing efficiency, cost, and performance. By implementing strategies such as parallelization, avoiding redundant work, selective testing, and fast-failures, you can achieve significant improvements in your CI/CD processes. Make sure to consider the structure of your codebase (monorepo vs. polyrepo) and the limitations of your CI/CD tools as you think about these optimizations.

These approaches have worked well for us at Graphite, but obviously every company is different - we highly encourage you to experiment with these strategies, adapt them to your specific context, and continuously refine your CI/CD practices.

Let us know how these strategies work for you!

References and further reading

For more insights and detailed guides on optimizing CI/CD pipelines, check out the following resources: