Earlier quoted context omitted.
You NEVER do that in one go, you need to split it in several deployments. Dropping a column is relatively straightforward, in two steps. First deploy a version of the code that doesn’t use the column, then release the migration dropping the column. The typical example is the renaming of a column, which needs to be done in several steps: 1. Create the new column, copying the data from the old column (DB migration) bot…
I see. Thanks for the clarifications. And these DB migrations, did your team keep a history of them? If so, did you manage them yourselves, or did you use some tools like flyway? I'm asking because I'm starting a project where we will manage the persistence SQL layer without any ORM (always did it so far with Django's migrations), but might consider some third party tools for DB migrations.
When deployments are easy, code becomes simpler
101–110 of 124 posts
Re: When deployments are easy, code becomes simpler
#102« When developer are clever, codes become better »
Re: When deployments are easy, code becomes simpler
#103Earlier quoted context omitted.
Somewhere along the way, a new generation of developers thought that 'Continuous Integration' means "automated builds". I wonder what they think that 'integration' word is doing there? Since you're here, I'll ask you. What do you think 'integration' means in this context?
"Passing CI" is a low bar -- it is only a single layer of defense. Moreover, code has syntactic properties that aren't necessarily evaluated by CI. My comment claimed that there are readability and usability concerns with unfinished code. This is why we have code review. CI is a signal that the code is good to merge, but as a code reviewer, I have the final say. I don't merge unfinished code. If CI passes on your bra…
That’s the problem, which I already stated before the question. That’s not integration, that’s a build. Integration is testing your changes with all the code around it.
Specifically, it’s about testing your changes with changes that started after you began writing your code.
Only small changes land in anything like chronological order. On real codebases, even with low to moderate coupling, the rug can get pulled out from underneath of you without you even noticing until something bad starts happening. CI is about exposing your code to feedback at the earliest possible moment, so you 1) don’t continue to build on violated assumptions, 2) you do lots of small merge operations instead of one big one and 3) the thoughts that began the trouble are still fresh in your head. Consequences of decisions become abstract over time. Nobody changes their behavior based on 1 year old bugs found in their code.
Long lived branches are a crutch. It’s avoidant behavior. If you can’t figure out how to make your code work with everyone else’s, why do you think waiting longer will make things better? It doesn’t. The mess just gets bigger. I’ve seen it over and over again. The guys who won’t merge early are full of delusions about their own work that doesn’t match up with the bug and incident count. They call it bad luck.
Re: When deployments are easy, code becomes simpler
#104> I did an inventory of my recent feature flags and realized that about 80% of them aren’t there to roll things out to specific populations, or do any sort of A/B testing, but to hide unfinished code. Maybe it’s just me but having unfinished, dead, or scratch code in a production codebase really annoys me. Either finish your work or delete the unneeded code. More than a few times I’ve sunk time out of my day into inv…
If the code is toggled off for a ticket in progress, great. If it’s toggled off for an epic in progress, okay. If it’s toggled off and the epic is complete/abandoned, then it’s not dark code, it’s dead code. Fire up the chainsaws.
The old code behind a toggle should be deleted before the feature is Done. If it isn’t then someone screwed up.
Re: When deployments are easy, code becomes simpler
#105As an aside, those “feature flags as a service” tools have some neat features, but are just way too expensive for what most apps probably need: simple binary flags that can change at runtime. Example: just use a database table. Query and cache in memory for 60s. If you want, build a simple internal web page or tool to toggle flags. This works, and scales (from experience). Do many apps really need A/B testing or segm…
Re: When deployments are easy, code becomes simpler
#106Feature flags give you orthogonality. When you have an `if False:` or equivalent in code, you have to deploy to enable a new feature, so if the current state in the test environment isn't good, you either have to wait for it to be fixed, or to roll back all possibly bad new commits before you can enable the feature. Another feature of feature flags is that a non-coder can toggle them. If you need neither of these, su…
This is not a feature, and it will get you called in during the weekend at some point.
Re: When deployments are easy, code becomes simpler
#107Earlier quoted context omitted.
"Just use a database table" solves for the simplest cases - a single monolithic app. It works incredibly well in this case. It falls apart when I need to turn features on across multiple apps together.
Multiple apps can access a single database, so where's the problem?
Re: When deployments are easy, code becomes simpler
#108> Much of the time I’m using flags so I can commit unfinished code There are two interpretations of this, and I find one of them horrifying 1. I'm working on a feature, I need to update multiple components, so I make small changes for each component and feature flag those (this is fine! Totally normal) 2. I commit code that doesn't work because I'm unwilling to use or understand git The second of these scares the cra…
Most language compilers and JITs eliminate the unreachable code within a constant false branch sooner or later and the code isn't even technically "deployed" even though it exists in source control for that deployment.
Re: When deployments are easy, code becomes simpler
#109Earlier quoted context omitted.
The system can only move forwards. Just like a `git revert`, it's a new commit to an immutable history. This is why I've never used or understood the value of the "downgrade" feature in some database migration tools. If you need to revert, make a _new_ migration that fixes the problem. Your tooling/code/logs should reflect the true history of the system without cooking the books.
>> This is why I've never used or understood the value of the "downgrade" feature in some database migration tools It's technically a roll forward, while to most users it's more nature to say rollback/revert
Re: When deployments are easy, code becomes simpler
#110Earlier quoted context omitted.
You NEVER do that in one go, you need to split it in several deployments. Dropping a column is relatively straightforward, in two steps. First deploy a version of the code that doesn’t use the column, then release the migration dropping the column. The typical example is the renaming of a column, which needs to be done in several steps: 1. Create the new column, copying the data from the old column (DB migration) bot…
I see. Thanks for the clarifications. And these DB migrations, did your team keep a history of them? If so, did you manage them yourselves, or did you use some tools like flyway? I'm asking because I'm starting a project where we will manage the persistence SQL layer without any ORM (always did it so far with Django's migrations), but might consider some third party tools for DB migrations.