Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Looking forward: New release strategy #524

Closed
cobaltt7 opened this issue Jan 20, 2024 · 3 comments
Closed

Looking forward: New release strategy #524

cobaltt7 opened this issue Jan 20, 2024 · 3 comments

Comments

@cobaltt7
Copy link
Member

cobaltt7 commented Jan 20, 2024

The Problem

Currently, a 2.9.x patch release is honestly long overdue. Automod updates, /user-info and tickets bug fixes, maybe something for when #suggestions broke, etc. However, the main branch is full of changes for 3.0.0. If I were to release a patch, I'd have to create a new 2.9.x branch and cherry-pick individual changes, which is a lot of effort.

The Previous Solution

Originally, I developed 3.0.0 features on their branch (see #369). However, that had its challenges.

  • Any patch-level changes would have to be made on both the main branch and the 3.0.0 branch (see Node 20 #382 and Node 20 (v3.0) #383)
  • Merge conflicts were rampant
  • I had to remember which branch I was on constantly

Eventually, I gave up and merged #369, telling myself that certainly, I would certainly release 3.0.0 soon and another 2.9.x patch wouldn't be necessary. That turned out to be incorrect.

The Solution

Inspiration

Black (the uncompromising Python code formatter) has a Mode bitfield and a Preview enum. When the --preview flag is passed, the Mode bitfield is filled with all the values from Preview. Then people could write code like this:

if Preview.some_beta_feature in mode:
    # do beta feature
else:
    # do old behavior

I propose adding something similar to Scradd.

We'll have a file in common/ that exports flags, looking something like this:

const betaFeatures = ["feature1", "feature2", "feature3", /* ... */];
export const isBeta = process.env.NODE_ENV !== "production";
export default Object.fromEntries(betaFeatures.map((feature) => [feature, isBeta]));

In modules, we can write code like this:

if (betaFeatures.feature1) {
	// new behavior
} else {
	// old behavior
}

Whenever someone adds new behavior, we will require them to use this flags system. Patch-level fixes can be implemented without flags.
At release time, I will remove features I want to release from the array and remove all dead code.
This has some obvious cons. However, the pros heavily outweigh them.

Pros

  • It is much easier to see at a glance what is being developed for the next version.
  • We can release patches even after merging new features to the main branch.
  • We can merge in-development features to main and selectively pick what we want to release. This also leads to better collaboration.
  • All development is done on one branch.

Cons

  • This will make the code more complicated and probably a bit messier too.
    Clean code is important, people often make a big deal about it. But in the end, if the code doesn't work or if it's such a pain to release features and patches, it doesn't matter. Working code is more important than clean code in the end.
    Black passed mode around as a function parameter, we're just using a global module, it can always be worse :P
  • Would still add maintenance overhead, since we have to maintain both the beta and the stable features.
    This was a problem in my previous solution as well. At least now it's all in one place and there won't be merge conflicts.
    It would be harder to test both modes for every feature though, and there are always edge cases where new behavior may slip in. Hopefully, we won't run into these, but if we do, we can rethink things.
  • In my experience contributing to Black, it can be confusing when and where to add preview checks, but that may just be because I'm unfamiliar with the project.

Summary

I propose adding flags to toggle new behavior based on NODE_ENV. While this may make code messier if we're not careful, and while it will make development harder, it will allow releases to be much more efficient, often, and satisfying. It's a trade-off, but in the end, nothing matters if it doesn't get released. I believe this is the best solution because it keeps everything in one place and can still be clean if we try.

I plan to implement this system immediately following the 3.0.0 release.

@cobaltt7 cobaltt7 added this to the 3.1.0 milestone Jan 20, 2024
@cobaltt7 cobaltt7 self-assigned this Jan 20, 2024
@cobaltt7 cobaltt7 pinned this issue Jan 20, 2024
@Qualitical
Copy link

I don't know what any of this means but I assume you're having a hard time choosing between a major update and a few patches? I know I'm gonna sound stupid saying this, but let the community have what they want. I'm part of the community. Let us have the major update! If anything goes wrong, it doesn't matter! We want it!

@cobaltt7
Copy link
Member Author

@Qualitical My current problem is that it's very hard for me to release patch updates while I am actively developing big updates. I will release 3.0.0 as soon as I can, but in the meantime, there's a couple somewhat large bugs that ideally I would've patched by now. I haven't since it's rather difficult to only release some updates. In this issue, I detail a fix that should improve release quality and speed, starting with 3.1.0.

@CubesterYT
Copy link

CubesterYT commented Jan 20, 2024

This seems like our best way forward, as Scradd gets new features and (finally) constant testing. Put priority on bug fixes and needed updates. We can always use Black like functionality to test new features under the betafeatures flag and what not, and it's quite useful for anyone contributing to look at the code and understand what's happening better. This is the best way forward, there's no other option like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants