Staging Is a Trap
tylercipriani.com
tylercipriani.com
I just can't imagine stuff done without staging. I get that staging loosens discipline -- you will definitely put more effort if you know that nobody else is going to see it before it hits prod.
But at the same time the changes we were doing were extremely complex and if we had to break it up into constant stream of small updates that each had to work perfectly we would be in a state of analysis paralysis.
As expensive as the staging is, it makes development cheaper by allowing people to work in parallel and lessen the cost of their mistakes.
And before somebody points out that companies do successfully deploy things without staging -- I will say that these are a bit different systems. Large scale systems tend to not be very complex -- they are just large scale. But each component of the system tends to be reasonably understandable by a single person.
The systems I worked on tended to be more internal systems with less scale but had domain models consisting of up to tens of thousands of different domain objects with very complex interactions.
Practically, having no staging is such a hard concept for people to get their heads around.
It’s one more safety net gone, but it’s a good one.
Maturity of the business, team and product play a big part in this decision.
So they can see development happening, can check or approve changes or can see if the api change they made breaks anything.
They are usually very happy about this and keeps away tons of problems in prod.
What would be the best way of approaching that without staging?
Alternatively (since you said “prior to pull request”) local builds, screen sharing, and live conversations with stakeholders.
Alternatively (if you don’t want to screen share) continuous deployment, feature flags, and a PR-free review technique such as pairing or mobbing.
Alternatively (if you don’t want pairing or mobbing) continuous deployment, feature flags, robust automated tests, and post-deployment code review.
Edit: Parent comment has been edited, originally it was just "Feature flags tied to user accounts." To address the rest: screen recording is sadly not always enough; screen sharing, pairing and mobbing are not ideal either, the stakeholders want to spend more time with the feature than I'm willing to spend on a call.
Your original question was, paraphrased, "how do we give non-tech product owners early access without a staging environment?"
The canonical answer, from organizations that do this, is to use feature flags that are tied to user accounts. But this requires a certain level of engineering maturity—specifically, something that looks a lot like continuous deployment.
There's a bunch of things that go along with continuous deployment, but one of them is continuous integration (the practice, not the poorly-named build servers), which is a combination of trunk-based development and frequent merges to the trunk. This requires programmers to hide incomplete work behind feature flags (or keystones¹). There's an associated set of practices for dealing with schema changes that I'd be happy to describe.
People who are using feature flags (and associated practices) don't have "code that's not ready to merge." That's the whole point of the feature flags—to allow them to merge and deploy unfinished code.
So when you put the constraint of "our code isn't ready to merge" on my "use feature flags" answer, I thought you weren't engaging in good faith, because it's kind of nonsensical—like saying risk of sunburn prevents you from using sunscreen lotion. I apologize for misconstruing. I assume what you really meant was, "We aren't able to use feature flags to merge and deploy incomplete code."
That's a perfectly fine answer! But you asked how people share incomplete work when they don't have a staging environment, and the answer is, "feature flags."² Specifically, they deploy incomplete work to production and use feature flags to selectively hide and show it. If you can't do that, then it's probably best to keep your staging environment.
¹Keystones: https://martinfowler.com/bliki/KeystoneInterface.html
²For teams that use keystones, but not feature flags, pairing with stakeholders (screen sharing) is another approach I've seen used. It has the advantage of being simpler. But I agree that it's more constraining.
Then after patting yourself on the back and buying yourself a drink, have a very painful conversation with your CFO explaining why your AWS bill doubled....
Except for, you know, the real user data and continuous traffic.
That way, if the changes work for a week in staging, they'll probably work for years in production.
We support data warehouses and not trying things out in staging is root cause for many P0 cases. Especially on the weekend because a lot of companies do upgrades Saturday night. I had to deal with this exact scenario last weekend in Istanbul Airport at 9am Sunday morning over a janky LTE connection. It was not a pretty sight.
If you are running databases the null hypothesis for any mission critical system is that you must have staging to test upgrade as well as out-of-band activities like restoring from backup.
Edit: And to test performance too. Use real data.
Staging hides bugs. Staging tends to be manually altered in ways that CD doesn't do. Staging for testing means likely collisions. Not to mention cleanup so that the environment can continue to be used.
Favor ephemeral environments instead. Need to demo? Spin one up. Need to do some end-to-end exploring? Spin one up.
Spot a problem in an ephemeral environment? Keep it up so someone can investigate.
All done with it? Spin it down.
Can't do that because of all your special snowflake infra code? Well, that's a problem waiting to happen anyway. Fix it so that you can spin up ephemeral environments.
I don't see much point in staging anything but business logic. I don't see the point in staging in any way that isn't "live."
Normally employees would be sent to that kind of staging environment which is very much prod.
If you have tightly coupled microservices, staging has a lot of opportunity to catch bugs before they get to prod and cause outages.
The canary / break prod / rollback attitude is why developers are constantly putting out fires instead of getting things done.
Having a team solely responsible for rollbacks and failed builds is immensely helpful. If you frequently have code that passes tests but fails in prod, then a team must "regulate" the commons (the shared code base).
If you have one database, you only need one staging database. It's easy to sync them. I've worked at a company where this worked awesomely. I also worked at a company trying to follow Netflix and staging was a nightmare.
It sounds like you work at small companies and haven't ran into the kinds of problems microservices and database-per-service patterns solve.