Skip to content

Conversation

@deviantintegral
Copy link
Contributor

The Issue

I'm following up from the suggestion at ddev/ddev#7054 (comment).

How This PR Solves The Issue

It documents what we've done to effectively use DDEV in GitHub Actions.

Comment on lines +3 to +4
pubDate: 2026-01-01
modifiedDate: 2026-01-03
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These need bumping before publishing.

@github-actions
Copy link

🌐 Fork Preview for PR #515

https://pr-515.ddev-com-fork-previews.pages.dev

This preview updates automatically when you push changes to your fork.

@rfay
Copy link
Member

rfay commented Jan 20, 2026

Looking forward to trying it out, thanks!

Copy link
Member

@rfay rfay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the great work on this! Made a few suggestions, will also ask Copilot to take a pass.

- Performance
---

For most developers, DDEV solves a common challenge: making sure that each developer as a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For most developers, DDEV solves a common challenge: making sure that each developer as a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?
For most developers, DDEV solves a common challenge: making sure that each developer has a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, but another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?

- Performance
---

For most developers, DDEV solves a common challenge: making sure that each developer as a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For most developers, DDEV solves a common challenge: making sure that each developer as a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?
For most developers, DDEV solves a common challenge: making sure that each developer has a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, but another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?

"how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges" seems pretty vague, can you make that stronger?


For most developers, DDEV solves a common challenge: making sure that each developer as a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?

A typical CI/CD pipeline is implemented using the tools and systems provided by the CI service itself. For example, at a basic level you can place shell commands inside configuration files to run tests and tools. Running those commands locally in DDEV is possible, but it's a painful copypaste process. If you're a back-end or DevOps engineer, odds are high you've wasted hours trying to figure out why a test you wrote locally isn't passing in CI – or vice versa!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A typical CI/CD pipeline is implemented using the tools and systems provided by the CI service itself. For example, at a basic level you can place shell commands inside configuration files to run tests and tools. Running those commands locally in DDEV is possible, but it's a painful copypaste process. If you're a back-end or DevOps engineer, odds are high you've wasted hours trying to figure out why a test you wrote locally isn't passing in CI – or vice versa!
A typical CI/CD pipeline is implemented using the tools and systems provided by the CI service itself. For example, at a basic level you can place shell commands inside configuration files to run tests and tools. Running those commands locally in DDEV is possible, but it's a painful copy/paste process. If you're a back-end or DevOps engineer, odds are high you've wasted hours trying to figure out why a test you wrote locally isn't passing in CI – or vice versa!


Unlike using a CI-provider's built-in tooling, DDEV is not typically cached or included in CI runners. Just running the [setup-ddev](https://github.com/ddev/github-action-setup-ddev) action can take up to a minute on a bad day. That doesn't include any additional packages or Dockerfile customizations a project may include. At Lullabot, we use [ddev-playwright](https://github.com/Lullabot/ddev-playwright) to run end-to-end tests. Browser engines and their dependencies are heavy! System dependencies can be north of 1GB of compressed packages (that then have to be installed), and browsers themselves can be several hundred MB. This was adding several minutes of setup time just to run a single test.

Luckily, based on our experience building [Tugboat](https://tugboatqa.com/), we knew that the technology to improve startup performance existed. When [WarpBuild](https://www.warpbuild.com/) was announced with Snapshot support in 2024, we immediately started testing it out. Our theory was that Snapshots would be fast enough to create and restore that we'd see significant improvements in startup time. Let's show how we set it up!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Luckily, based on our experience building [Tugboat](https://tugboatqa.com/), we knew that the technology to improve startup performance existed. When [WarpBuild](https://www.warpbuild.com/) was announced with Snapshot support in 2024, we immediately started testing it out. Our theory was that Snapshots would be fast enough to create and restore that we'd see significant improvements in startup time. Let's show how we set it up!
Luckily, based on our experience building [Tugboat](https://tugboatqa.com/), we knew that the technology to improve startup performance existed. When [WarpBuild](https://www.warpbuild.com/) was announced with Snapshot support in 2024, we immediately started testing it out. We theorized that the performance improvement of snapshots would result in significant startup time improvement. Here's how we set it up!

fail-on-error: true
wait-timeout-minutes: 60
```
It was important to include the DDEV version in the snapshot name so we could clear it when updating DDEV. We also had a version number in case we messed up the cache. We recommend using Renovate Custom Managers to keep it in sync with other ddev versions in your project.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be indented to become part of 5, but I think it ends up looking wrong (and overlooked by the reader) as a result. Maybe put it above the code?

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a blog post documenting how Lullabot uses WarpBuild to significantly improve DDEV startup performance in CI environments, specifically for GitHub Actions workflows. The post shares practical implementation details and performance results from using WarpBuild's Snapshot feature to cache DDEV environments.

Changes:

  • New blog post describing WarpBuild integration with DDEV for CI performance optimization
  • New author profile for Andrew Berry
  • Minor cleanup removing unused "Resources" category from README documentation

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 5 comments.

File Description
src/content/blog/ddev-ci-warpbuild.md Technical blog post explaining WarpBuild setup, configuration, and performance results for DDEV in CI
src/content/authors/andrew-berry.md Author profile for the blog post author
README.md Removes unused "Resources" category from blog category list

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Performance
---

For most developers, DDEV solves a common challenge: making sure that each developer as a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a grammatical error in this sentence. "each developer as a consistent" should be "each developer has a consistent" - the verb should be "has" not "as".

Suggested change
For most developers, DDEV solves a common challenge: making sure that each developer as a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?
For most developers, DDEV solves a common challenge: making sure that each developer has a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?

Copilot uses AI. Check for mistakes.

For most developers, DDEV solves a common challenge: making sure that each developer as a consistent, stable local environment for building their web application. At Lullabot, as we had more and more success with DDEV, another related issue kept coming up: how do we grow and develop our use of continuous integration and automated testing while avoiding similar challenges?

A typical CI/CD pipeline is implemented using the tools and systems provided by the CI service itself. For example, at a basic level you can place shell commands inside configuration files to run tests and tools. Running those commands locally in DDEV is possible, but it's a painful copypaste process. If you're a back-end or DevOps engineer, odds are high you've wasted hours trying to figure out why a test you wrote locally isn't passing in CI – or vice versa!
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a grammatical error. The sentence "Running those commands locally in DDEV is possible, but it's a painful copypaste process" uses "copypaste" which should be "copy-paste" (hyphenated) or "copy and paste" to be grammatically correct.

Suggested change
A typical CI/CD pipeline is implemented using the tools and systems provided by the CI service itself. For example, at a basic level you can place shell commands inside configuration files to run tests and tools. Running those commands locally in DDEV is possible, but it's a painful copypaste process. If you're a back-end or DevOps engineer, odds are high you've wasted hours trying to figure out why a test you wrote locally isn't passing in CI – or vice versa!
A typical CI/CD pipeline is implemented using the tools and systems provided by the CI service itself. For example, at a basic level you can place shell commands inside configuration files to run tests and tools. Running those commands locally in DDEV is possible, but it's a painful copy-paste process. If you're a back-end or DevOps engineer, odds are high you've wasted hours trying to figure out why a test you wrote locally isn't passing in CI – or vice versa!

Copilot uses AI. Check for mistakes.
```
It was important to include the DDEV version in the snapshot name so we could clear it when updating DDEV. We also had a version number in case we messed up the cache. We recommend using Renovate Custom Managers to keep it in sync with other ddev versions in your project.

We don't pin actions to hashes in these examples for easy copypaste, but for security we always [use Renovate to pin hashes for us](https://docs.renovatebot.com/modules/manager/github-actions/#digest-pinning-and-updating).
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo in "copypaste" which should be "copy-paste" (hyphenated) or "copy and paste" for readability.

Suggested change
We don't pin actions to hashes in these examples for easy copypaste, but for security we always [use Renovate to pin hashes for us](https://docs.renovatebot.com/modules/manager/github-actions/#digest-pinning-and-updating).
We don't pin actions to hashes in these examples for easy copy-paste, but for security we always [use Renovate to pin hashes for us](https://docs.renovatebot.com/modules/manager/github-actions/#digest-pinning-and-updating).

Copilot uses AI. Check for mistakes.
Comment on lines +61 to +67
- name: Determine Snapshot Base
id: snapshot-base
run: |
set -x
hash=$(cat .github/actions/ddev/action.yml test/playwright/.yarnrc.yml test/playwright/yarn.lock | md5sum | cut -c 1-8)
echo "snapshot=$hash" >> $GITHUB_OUTPUT
shell: bash
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a potential confusion in the workflow logic. The runs-on configuration at line 46 references "inputs.snapshot", but the "Determine Snapshot Base" step that creates this value doesn't run until later (lines 61-68). In GitHub Actions, the runs-on selector is evaluated before any steps run. This suggests either: (1) this should be a reusable workflow where "inputs.snapshot" is a workflow input, or (2) the code snippets are shown out of order, or (3) there's a logic error. Consider clarifying how the snapshot value is provided to the runs-on selector, perhaps by explaining this needs to be in a separate job or by showing the complete workflow structure.

Suggested change
- name: Determine Snapshot Base
id: snapshot-base
run: |
set -x
hash=$(cat .github/actions/ddev/action.yml test/playwright/.yarnrc.yml test/playwright/yarn.lock | md5sum | cut -c 1-8)
echo "snapshot=$hash" >> $GITHUB_OUTPUT
shell: bash
jobs:
snapshot-base:
runs-on: ubuntu-latest
outputs:
snapshot: ${{ steps.snapshot-base.outputs.snapshot }}
steps:
- name: Determine Snapshot Base
id: snapshot-base
run: |
set -x
hash=$(cat .github/actions/ddev/action.yml test/playwright/.yarnrc.yml test/playwright/yarn.lock | md5sum | cut -c 1-8)
echo "snapshot=$hash" >> $GITHUB_OUTPUT
shell: bash
playwright-tests:
needs: snapshot-base
uses: ./.github/workflows/playwright-tests.yml
with:
snapshot: ${{ needs.snapshot-base.outputs.snapshot }}

Copilot uses AI. Check for mistakes.
- _Guides_ (how-to style posts)
- _Newsletters_ (monthly newsletters)
- _Podcasts_ (podcasts)
- _Releases_ (new features, bug fixes, etc.)
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of the "Resources" category from the README appears to be an unrelated cleanup change that is not mentioned in the PR description. While this may be a valid cleanup if the category is indeed unused, it would be better to either include this change in a separate PR or document it in the PR description to explain why this category is being removed.

Suggested change
- _Releases_ (new features, bug fixes, etc.)
- _Releases_ (new features, bug fixes, etc.)
- _Resources_ (helpful documentation, links, and other reference material)

Copilot uses AI. Check for mistakes.
@rfay rfay requested review from stasadev and tyler36 January 22, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants