Why open source matters: what my first upstream contribution taught me
← Back to Blog
August 2026·Open Source·7 min read

Why open source matters: what my first upstream contribution taught me

Building Dawn taught me how to publish open-source software. Contributing real CodeBuild execution to MiniStack taught me what open source actually means: turning a private frustration into a shared improvement.

For a long time, I understood open source mainly as a way to access code.

You find a library, install it, inspect how it works and perhaps open an issue when something breaks. That alone is valuable, but it misses the most important part.

Open source does not only give you access. It gives you agency.

When a tool almost solves your problem, you do not have to wait indefinitely, build another workaround or accept that this is just how it works. You can understand the limitation, fix it and offer the solution back to everyone.

That became real to me while working on two projects: Dawn, my own open-source package, and MiniStack, a local AWS emulator to which I made my first upstream contribution.

Publishing Code And Contributing Upstream Are Different Experiences

I built Dawn to solve a problem I knew from Laravel projects: browser tests written with Laravel Dusk are useful, but the WebDriver and ChromeDriver layer adds operational overhead and can make test suites unnecessarily flaky.

Dawn reimplements Dusk's public Browser API on top of Playwright. Existing test bodies can stay unchanged while Playwright provides native auto-waiting and removes the need to manage ChromeDriver. The package now covers roughly 95% of the Dusk Browser API, with the unsupported edge cases documented instead of silently approximated.

Publishing Dawn taught me one side of open source.

I controlled the architecture, roadmap and release process. I decided what belonged in scope, wrote the documentation and defined the compatibility guarantees. The responsibility was mine, but so were all the decisions.

Contributing to an existing project was different.

The code had to solve my problem while still fitting somebody else's architecture, conventions and product philosophy. That is where the real lesson started.

A Green Build That Did Not Build Anything

I was using MiniStack to rehearse an AWS CodeBuild project locally.

The project was not trivial. It used Terraform, privileged containers and a buildspec that started a Postgres database, an API and a web application before running browser tests.

MiniStack already implemented the CodeBuild API, but there was an important limitation: calling StartBuild immediately returned a successful build.

No build phases were executed. No application was started. No tests ran.

The result was green, but it proved nothing.

In fact, this was worse than an explicit “not supported” response. A buildspec that would fail on AWS could appear successful locally. Unless you noticed that no container had been created, the emulator gave you false confidence.

The easiest response would have been to keep this logic outside MiniStack: write a local script, add another CI-specific workaround or bypass the emulator entirely.

Instead, I opened the code.

Turning A Local Need Into A Reusable Feature

I opened MiniStack pull request #1273. My proposal added an opt-in execution mode behind one flag: MINISTACK_CODEBUILD_EXECUTE=1.

With the flag enabled, MiniStack hands the buildspec to the official AWS CodeBuild local agent rather than implementing its own build executor.

The goal was not merely to start a Docker container. The feature needed to behave like part of the existing emulator:

  • StartBuild should return IN_PROGRESS.
  • CodeBuild phases should be visible through BatchGetBuilds.
  • The container's exit code should produce a real SUCCEEDED or FAILED result.
  • Build output should reach the emulated CloudWatch Logs.
  • timeoutInMinutes and StopBuild should work.
  • AWS calls made inside the build should point back to MiniStack.
  • The default metadata-only behaviour should remain unchanged.

The final change added 685 lines across implementation, tests, documentation and the changelog. But the number of lines was not the interesting part.

The review was.

Review Made The Contribution Better

An automated review noticed a race condition in my implementation of StopBuild.

The API could mark a build as stopped and remove its container while the worker thread was still following the container's logs. The worker could then interpret the removed container as a failure and overwrite STOPPED with FAULT.

That was a real concurrency bug, not a cosmetic suggestion.

I fixed it by recording the stop intent before touching the container, making the worker respect that state in every completion path and adding a test that reproduced the failing sequence. I also documented the exact failure and the fix in the PR discussion.

Then the maintainer asked me to simplify the configuration.

My first version exposed several environment variables for the agent image, workspace, source path, AWS endpoint and log limits. The maintainer pointed out that most of them were internal implementation details rather than choices that existed in AWS.

The feedback was clear: keep one meaningful flag and make the rest internal.

So I removed the extra knobs, aligned log behaviour with the rest of MiniStack, moved the tests into the existing CodeBuild test module and rebased the branch. My follow-up listed each simplification so the reviewer could verify the result without reconstructing it from the diff.

The result was smaller, more consistent and easier to maintain.

That exchange changed how I think about code review. A good review is not a gate placed between the author and the merge button. It is part of the design process.

The Contribution Did Not End At “It Works On My Machine”

The pull request was opened on August 4, 2026. After six commits, review, simplification and another test cycle, it was approved and merged three days later. The merged commit is public, including the implementation, tests, documentation and changelog entry.

My local problem had become part of a public project.

Someone else can now rehearse a CodeBuild pipeline locally and get an honest result instead of an immediate synthetic success. They may never know who implemented it, and that is perfectly fine.

The improvement is now part of the commons.

Why Open Source Matters

Open source matters because knowledge can move in both directions.

I used MiniStack because somebody had already spent time building an AWS emulator and releasing it under an open licence. That work saved me from starting at zero.

When I found a missing capability, the same model allowed me to contribute the next layer.

Dawn follows the same principle. It exists because Laravel Dusk, Playwright and many other open-source projects exposed enough ideas, code and interfaces to make a different integration possible. Dawn can now become a starting point for somebody else.

This is the compounding effect of open source:

  1. Someone publishes a useful foundation.
  2. Another developer encounters a real limitation.
  3. That developer contributes a solution.
  4. The improved foundation becomes available to everyone.
  5. The next person starts from a better place.

Not every contribution needs to contain hundreds of lines or implement a new execution engine. Documentation, reproducible bug reports, small fixes and careful reviews all move a project forward.

The important step is crossing the line from consumer to participant.

My first upstream contribution was not perfect on the first attempt. It contained too much configuration and a race condition. Review exposed both. I changed the implementation, learned from the project's conventions and shipped something better than my original proposal.

That is precisely why open source works.

You do not need to arrive with perfect code.

You need to arrive with a real problem, a serious attempt to solve it and a willingness to collaborate.

Sources And Project Links

Open source turns frustration into agency: fix the problem for yourself, then leave the tool better for the next person.
Igor Gawrys
Igor Gawrys
AI Engineer & IT Consultant · Katowice, Poland