Announcing GoReleaser v2.11
This version consists mostly of improvements to the Homebrew Cask feature introduced in the …
In this post, I want to share the history behind GoReleaser, how we got here, lessons I’ve learned along the way, and what’s ahead.
Tip This is a blog post based on a talk I gave at Codecon Summit 2025. The slides are at the end of the post.
If you’ve stumbled upon this post without knowing what GoReleaser is, here’s a quick summary:
GoReleaser is a release automation tool. You configure it with YAML, and it handles building binaries, creating archives and packages, publishing releases, pushing installers, signing artifacts… - basically everything you need to release software.
The story behind it is pretty interesting.
I promise I’ll try to be as brief as possible…
It all started in June 2015. I was working on another project at the time: a ZSH plugin manager.
Note That ZSH plugin manager was my first “real” Go project. It has been abandoned/archived for many years now, but the repository is still there.
After manually creating releases a few times, I got tired of the repetition and
did what millions before me had done: I wrote a release.sh
script.
Nothing fancy - just go build
, tar
, creating a GitHub release with
the API, and uploading the archives.
It was good enough for a while.
By March 2016, almost one year later, I had a dozen Go projects, all of them needed releasing.
So I did the next obvious thing: moved that script into its own repository, and made it “configurable” using flags.
It sucked, but it scratched the itch and was also good enough for a while.
By December, instead of enjoying the holidays like a normal person, I was nerding out on my open source projects.
I wanted to add Homebrew releases to my projects, but quickly realized it would be almost criminal to keep adding features to that shell script. I also disliked the “configuration via flags” approach and the distribution method.
By then I had a little more Go experience, and a thought crossed my mind: “What if I rewrote this in Go and made it configurable with YAML?” That question turned out to be one of the most important I’ve ever asked myself, career-wise.
I hacked something together - and honestly, it wasn’t great at first. After a day or two, it was decent enough that I decided to share it on Twitter and Reddit.
To my surprise, people loved it.
Turns out nobody really wants to maintain their release.sh
scripts!
That year, my wife drew the logo and mascot (which is still being used):
I kept working on it in my free time - adding features, improving things, the usual.
I also did a major internal architecture rework based on what I’d learned, and started sharing some of these learnings online.
I gave my first talk about it at a meetup, and by year’s end the repository had over 1000 stars.
In 2018, I created the first spinoff project: nFPM (nFPM is not FPM),
which lets us create .rpm
and .deb
packages without requiring rpm
or
deb
/dpkg
in $PATH
.
While not nearly as successful as GoReleaser, it became an important piece of its infrastructure.
Speaking of infrastructure, I also reworked the core build functionality to eventually support more languages. The idea was to use plugins, but I ended up giving up on it, due to the method having many drawbacks, including non supporting Windows.
I also spoke about GoReleaser in more Meetups, created an OpenCollective for it, and talked about it at GopherCon Brazil.
That year we also crossed 1000 public repositories on GitHub with
.goreleaser.yaml
files - which honestly sounded completely insane to me at the
time.
And then… I burned out.
Important I have no psychiatric training whatsoever. What I say here is based on my experience and observations.
Burning out is no joke, and I want to share some of my experience here, in case it somehow helps someone.
I used to think that, when this happens, your job is to blame, but I now think it’s a bit more complicated than that.
In my case, I don’t think GoReleaser or my day job alone caused it. My best guess is it was a combination of:
Honestly, I was a mess, and while I’d like to think I could spot it earlier now, I’m not sure that I can.
By the way, if your partner, friends, or family keep saying you’re working too much, they’re probably right. Please, listen to them.
Another warning sign is if you are consistently wondering if you’re burn out. It seems to me the only people who wonder if they have burn out are either people that are burnt out or people that have been burnt out in the past and are afraid of having it again.
Anyway, one thing I did to “fix” it was going to therapy, and eventually realizing I needed to change jobs, since it seemed to be the best ROI.
I also worked on fixing my diet, cut alcohol to 0 for ~9 months or so, and after that I only drink occasionally, and improved my routine the most I could.
Also worth noting that I’m not so sure that you can 100% fix burnout. I feel like I never got some parts of me back, which maybe makes sense, as everything that happens with present you, shapes future you, or, in the words of someone way smarter than me:
“No man ever steps in the same river twice, for it’s not the same river and he’s not the same man.”
– Heraclitus
That all being said: please, take care of yourself. Go touch some grass. No joking, it helps.
The following year, I started talking about releasing the first major version - v1.0.0 - and we also crossed the 5000 stars mark.
It was a slow year though, as I was still recovering from the burnout.
And then 2020 was… Well, 2020.
In all fairness, I did ship a few small features here and there, but mostly I was too worried about not dying, like most of us, I guess.
2021 was incredibly busy.
I appeared on the GoTime Podcast - which, for a nobody from rural Brazil, felt like the biggest deal ever.
I finally released v1.0.0, and started doing proper announcements for feature releases.
I also became one of the first people in Brazil (maybe South America) to be sponsorable in GitHub Sponsors.
Despite being happy with these milestones, I was still working constantly between my daily job and the open source stuff, and I was terrified of burning out again.
GitHub Sponsors and OpenCollective provided some income - and let me just say that I’m very grateful to everyone, and not complaining in any sense - but it wasn’t enough money to live off of.
But I loved (and still do love) working on open source, and didn’t want to abandon the project.
So, as a last resort, I decided to try the old-fashioned approach: selling something - in this case, licenses.
That’s how GoReleaser Pro was born - a paid version with additional features. And to my surprise, it kind of worked!
2022 started with another job change: I joined Charm in January.
Once again, I worked my ass off on both fronts. Added some important features to GoReleaser Pro, like “split & merge” and nightly builds. Also, GoReleaser crossed 10000 stars.
And then, at some point of the year, I realized: I was working with OSS full time, which was a dream years ago - a dream that I thought to be impossible.
I’m constantly going from “dude, we made it!” to “I don’t really deserve all this” in my head, though.
Everyday I thank God for it.
By 2023, based on user feedback, I shifted to less frequent releases, about monthly, instead of “whenever we have something to release”, and defined which versions are supported or not.
In 2024, I finally launched the second major version: v2.0.0!
Thanks largely to my friend & coworker Rapha constantly bugging me about it, I finally finished the work I started in 2018, and added support for Rust and Zig, with Rio Terminal being the first Rust project to use it.
Mascot Party
Back in 2018, I had planned to make builders into plugins, as mentioned before. It felt increasingly crazier every time I thought about it, and all the problems from years ago were still there. So I decided to do it inside GoReleaser’s codebase itself.
GoReleaser also got many new feaatures: support for Ko, upx, nix, Winget, DMGs, MSIs, App Bundles, notarization, and more.
Oh, and we passed 14000 stars, and with over 100 customers, GoReleaser Pro started paying off!
Which brings us to 2025 - the year of Linux on the desktop, the year of gaming on Arch Linux handhelds, we’re 3 months away of being replaced by AI 8 months ago… What a time to be alive!
So far this year, I’ve added support for Bun, Deno, Poetry, and UV, a MCP server, NPM support, AI in the changelogs, Homebrew Casks, and many other smaller features and improvements.
I’ve also talked about GoReleaser in two podcasts: Cup o’ Go and Fallthrough.
GoReleaser Pro now has around 200 customers, we’re approaching 15000 stars, and we’re close to 7000 commits!
This took me longer to realize than it should have: when it comes to release pipelines, people want predictability and stability, not novelty.
Think about it: when you run your release pipeline, what do you feel? If you are anything like me, the answer is anxiety. You worry if people will enjoy the new features, if you created any new bugs, etc.
If all of that is already worrisome, imagine also having to worry about whether your release pipeline will actually work.
My philosophy has been about being reliable first, innovative second. Users don’t want their CI to fail because we decided to experiment with some shiny new thing.
They want the same predictable output every time: binaries that work, packages that install correctly, releases that publish without drama. In summary, they want it to be as boring as it can be.
Boring is predictable. Boring is good. Boring gets the job done.
The most valuable feedback I get isn’t “wow, this new feature is amazing!” - it’s “I’ve been using GoReleaser for years and it just works.”
The reality is that everyone wants to work on “cool” things, which leave all sorts of boring problems behind, and releasing software is just one of them.
For an unknown person, I wager that the hardest part of making a product popular is the distribution.
You can somewhat game it - for example, by sharing your work in the right subreddits/socials at the right time. Having cool art/logo/mascot, a memorable name, and a solid README all help as well. But most importantly, you need software that people actually like to use, so they share it, talk about it, use it at work, etc.
It’s also incredibly easy to get it wrong: if your “marketing” feels forced, it usually don’t pass the vibe checks, and people ignore it, or worse: create a bad opinion instantly, without even trying.
Still, you may do all that right and it still not work out. It might be that the right people just didn’t see it, or you launched at the same day some big news got out, or any other million things. Luck definitely plays a role here.
Then, once your software becomes relatively popular, you might face different problems: Creator and creation often get conflated - I should know, since I’m often called “the GoReleaser guy” in the wild 😂. It’s not necessarily bad, just something to be mindful of. Anything you say might affect your product image as well.
Incidentally, once you have enough visibility, distribution becomes quite easy. If you have millions of followers in relevant social networks, anything you make and share will get attention.
And if you are that influential, I imagine you might have yet another problem: at some point, you are gonna have to ask yourself whether this new thing you made is doing numbers because it is actually good, or if it’s just because you did it. PS: it is usually a combination of the two.
There are people out there that could make something like this and still have more ARR that anything you or me could make, and it’s not because it’s good or useful, it’s just because they stick their name to it.
I know this sounds like I resent them, but I don’t. I’m merely telling you how I see things, and I confess that I get a bit annoyed when they try to tell you that anyone can do it, which is just not true.
I didn’t think much about the name at the time.
I had a release.sh
script that released Go software.
I rewrote it in Go, so now it was a Go software releasing Go software.
“Oh, it’s a Go-Releaser!”
– Me, circa 2016, after thinking about it for a grand total of five seconds.
Every now and then...
You’d think it would occur to me that people might read it as “gore leaser”. Well, it didn’t.
New band in the area!
In fact, it became kind of a running joke, with its own art and everything.
I also didn’t know there was already a gorelease
tool in the Go ecosystem,
and I imagine it created some confusion.
But in hindsight, I think the biggest mistake of all was the “Go” prefix.
Even though I can now rationalize and say it’s because the tool is written in Go, and not because it only releases Go, most people searching for “how to release {some language}” will see that Go prefix in “GoReleaser” and skip right to the next result.
In my defense, I had no idea GoReleaser would become this big. I thought it would end up like most of my projects - maybe a couple hundred stars before dying off.
I’m glad I was wrong about the outcome, and sad I thought that way at the time.
Anyway, naming things is hard.
Pricing software is, in my experience, a guessing game. There’s more and less informed guessing, of course, but in the end, I feel like it’s still quite different than estimating the price for a “hard” product (which you can usually derive from the price of raw materials, work time spent on it, etc).
Somehow, pricing software feels alien compared to that. And my case is even worse: if you’re a SaaS, you know you need to charge more than you expend on services, so you’ll calculate your cost per user and go from there. I don’t have any servers.
Basically, I try to guess a price that I think is fair given all the work I put into it, and wait to see if people agree (if someone buy it, or if someone complains about the price, etc).
In my experience, it’s easier to get it right for individuals and small businesses, probably because I am an individual and at this point GoReleaser is a small business, but for enterprises it is very different.
For starters, they’ll likely ask you to fill out extensive paperwork about your product, processes, and company. It can take hours of your time, and possibly a lawyer.
They do this for plausible deniability I think - if something goes wrong and your software is to blame, they can say “we did our due diligence, here’s the proof”.
Since I’m handling this solo in my free time, if I’m going to spend hours on paperwork, it better be worth it. After all, those are hours I could be putting into adding more features, or doing crazy things like resting.
So charge enterprises more. They understand why you need to, and they usually don’t mind, as when they come to you with the forms, the budget is usually already approved.
GoReleaser uses the MIT license, which is very permissive.
This means, among other things, that I have no legal way to prevent someone from forking, rebranding, and selling it as their own - and we all have seen similar things happen more than once, especially with things that can be sold as a service.
Now, almost a decade later, with ~15000 stars, changing the license feels like a bait-and-switch, so I probably never will.
Maybe at 1 year and 1000 stars it wouldn’t have been so bad? I guess we’ll never know.
If I started a new thing now that I could classify as a product, I would probably choose a less-permissive license.
We, programmers, love flexibility, and we are not alone.
See spreadsheet software for example. People make entire systems on that thing. It’s crazy, and only possible because spreadsheets are so flexible.
I guess I’m more scarred of this than most, since GoReleaser’s API is a YAML file, but my advice to you would be to mind how flexible you want your software to be.
Because - and trust me on this, if something can be done, doesn’t matter how crazy it is, or how easy it would be to do it in any other way, someone will do it. And because it is crazy, it will inevitably break at some point. When that happens, you’ll get an issue about it, and you will have to understand someone else’s madness, and we all know how fun that can be.
We also often talk about simplicity. I don’t want to go deep down in this rabbit hole here today. All I want to say is that, the older and bigger some system gets, the more scope creeps in, which will inevitably lead to some accidental complexity.
We have to stay vigilant, so we can reduce the amount of damage as much as possible. That said, sometimes we’ll have to make compromises.
For example, a little complexity here enabled an awesome feature there, and as much as it hurts to do it this way, making it “the right way” means a breaking change for all your users. So, what’s the right option there? Like most interesting questions, the answer starts with “it depends”.
So, keep all that in mind, and try to find the right balance - there’s no definitive answer or formula to any of this, unfortunately. I’d recommend trusting your gut, it is usually right.
This might be obvious to most people, but here it goes: I start most of my projects by identifying and trying to solve a problem I already have, instead of trying to find a problem for a solution I think would be fun to build.
Don’t get me wrong - building things for fun is, well, fun. I still do it quite a bit, my GitHub is a full of things I thought would be fun and/or educative to build, and I have no regrets there.
But, if you’re trying to build something for other people to use (a product), I’d venture to say you’d have a much better shot at creating something successful if you start from a problem.
The world is a big place. Chances are, other people have the same problems you do.
Building GoReleaser over these past years has been nothing short of a wild ride, and I plan to work on it for many years to come!
I have plenty of features and improvements planned, but none will be groundbreaking innovations, probably - and that’s good. Remember: boring software.
My main goals are adding support for more languages and distribution channels. A secondary goal is to improve the configuration, docs, and everything around it, so it’s easier for users to use it and to figure things out themselves.
Finally, if any of this sounds interesting to you, check out GoReleaser Pro, or feel free to e-mail me.
See you next time!