Closed micahalcorn closed 6 years ago
I'm in extremely strong agreement that we should use the "master" branch as our test-passing, latest-work branch instead of our current "develop".
This is the part that gives me pause, re doing releases:
• Either only merge into
master
what will be included in the next release or build a full suite of integration tests.
Building a full suite of integration tests is a must, but our system is so complex with multiple interacting repos that (I think) it will be a serious project to get this built out. This will take time. In the mean while, it's pretty shaky to rely on contributors to know which commits "will be included in the next release." So we could be left in the same position of having to cherry-pick commits to be included in a release.
Re docker: While I agree origin-box is the way to get people started, we should maintain a good effort to make things run-able without it.
I hate Docker now requires a user account, and that we are thus implicitly saying, "If you want to code on Origin, you need to give trackable personal information to the California company, Docker, Inc."
@wanderingstan I agree that the merge solution is a bit shaky. While it doesn't necessarily resolve your concern, a point of clarification is that random contributors don't have to (but they're welcome to) know what will be included in the next release. Only admins who merge the code need to be cognizant. And the larger PRs - the ones that are likely to cause problems or be deferred until the next release - are more likely to come from core/extended team members who should be aware of when their features will be released. Also, one might make the case that we should allow any code to be merged into the default branch at anytime if it doesn't break the integration (aka is compatible with the last stable, released version of the other repos). That's actually our current intent, but it's difficult to do without integration tests.
Regarding the Docker concern, I actually think this branching/release model is still consistent with that effort. We would now be explicitly claiming that the tagged versions should work with one another. Whether someone wants the convenience of the box with Docker or they want to roll their own multiple processes, they would use the same tagged/LTS commits in each. I think it's reasonable to ask privacy-sensitive users to either deal with potential instability or checkout the right tags.
A few thoughts on top of @micahalcorn's proposal:
One idea that may be worth considering is moving to a monorepo architecture, as used by React, Babel, Meteor and various other projects. I know that Google, Facebook and Twitter also use monorepos internally. Babel describes some of the pros and cons:
Pros:
Cons:
For our purposes, this would allow us to submit pull requests that touch multiple modules at the same time while keeping all tests passing. I believe it would allow us to hit all of the objectives outlined by Micah, switch to using the master branch and ease on boarding for new developers (no more npm link).
To be clear, I'm not suggesting we have one single repo for everything... but we could probably bring origin-js, origin-dapp, origin-bridge and origin-box into a single repo. The npm release of origin-js would still be a standalone module.
It turns out that Truffle have also recently moved to a Lerna monorepo architecture. I'm not sure we need Lerna as it's geared towards releasing multiple JS packages whereas we have just one (for now) - but interesting nonetheless.
Thanks, @nick, we might actually have multiple JS packages sooner rather than later. Messaging could naturally be its own module, some JS code has already crept into the bridge repo, and there's more on the way. I suspect that we want there to be a clear delineation so that, for example, people understand that they don't have to use our bridge server. But there might be a strong case that multiple repos isn't necessary (or practical) long-term.
Given that most new features cut across repos, I'm a big fan of merging origin-js, origin-bridge, origin-dapp, and origin-box into a monorepo. This will make feature development so much easier.
I'm keen on the monorepo idea too. I think it'll be quite hard for origin-box to always produce a working development environment for contributors with the compatibility between the three different develop branches getting out of sync. There is enough dependencies between the repos to make it a worthwhile change.
A monorepo would certainly would make things simpler for the core team, but I'm not sure it would make things easier for the thousands of developers we hope will someday start building on top of our platform.
I don't think it'd have an impact on developers building on our system as we'd still be releasing a standalone OriginJS module to npm as we do today, which will hopefully be the self-contained "jQuery" like library that anyone can drop into their project and get a nice API for a blockchain backed marketplace. That piece will remain the same for developers: use npm, download the standalone zip, or include it directly via CDN (or IPFS). We can also do standalone releases for the bridge server and demo-dapp (and other modules?).
For developers who want the bleeding edge or want to work on contracts or OriginJS itself, development could be eased significantly by a monorepo:
Apologies for my late thoughts. I've been very heads down for the last few days.
Agree with @nick here. JS developers would would use npm. Python developers (when we have support for them) would use pip. There exists a package manager for almost every language in use with blockchain technologies.
I like the monorepo idea. It'd make things simpler for more than just the core team.
Regarding the branching & release strategy, what we did at my previous job (creating an open-source database) worked fine for relatively infrequent releases. I haven't fully thought through what it means for more frequent releases, but I'll put it here for reference:
master
always contains working code and is the default branch people seemaster
must be cherry picked into the release branch if they're truly neededmaster
to minimize merge conflicts when cherry picking into the release branchOne if bigger disadvantages is that refactors are constrained to a relatively narrow window (after the previous release branch stabilizes and before bug fixing starts for the current release).
Regardless of what we pick, these points hold true:
master
should be the default branch and buzzing with commit activityHere's a rough plan of action if we wanted to go ahead with a monorepo:
origin-dapp
repo to just origin
(so we get all the stars) OR start a new repo?js
, dapp
, bridge
and box
(and possibly docs
, playground
, mobile
and schemas
)Going forward we can:
origin
repostable
branches when we do a major release (eg 0.1-stable
) that we can merge in security or other critical updates to if neededOther questions:
It seems that we have consensus on moving to a monorepo, but I think that should be step two. The branching and release strategy is somewhat of a separate and more pressing concern. Once we are ready to build integration testing, then we will have a real motivation to consolidate the codebases. Let's wrap up the discussion on the branching/merging procedures and change that workflow first.
Stan and I are planning a release for +/- next Wednesday (8/8). It will include the following:
develop
branches include Tyler's fractional work in origin-js (with no UI)Please let us know if there is something else that should be included or should be reverted. ⚠️
Sometime after we complete that release next week, I will remove the develop
s and update THE BOX to setup from master
s. Then I will formally document the new workflow somewhere and disseminate it.
Probably somewhere around the end of Q3 or before then if there is a compelling reason (and some available time), we can move to a monorepo and start writing integration tests.
Any final thoughts on how we manage what gets merged into master?
We had a system that worked pretty well in the last company that I worked for. The main branch everyone worked off of was master
. Main rules of committing to master:
Every 14 days we had a release where a staging
branch would be fast forwarded from master. QA team would setup staging servers from that branch and run all the tests (unit / integration). What could not be automatically tested was manually tested by the QA team. If release was solid the production
branch was fast forwarded from staging
and a release tag was made. That branch was then deployed.
Because there were not force pushes to master branch history of master
, staging
and production
never changes and it is easier to fallback on a previous release commit in case production is broken.
In case of large feature releases we broke them down into smaller releases and deployed them in across multiple sprints. For features where that was not possible the feature branch existed as long as it was not ready to be merged in master (and ready for production).
I think if things are developed that are not ready to go into production then we shouldn't merge them into master. If multiple developers need to share a branch they can work on a feature_x
branch and create extra branches out of feature_x
branch and then create Pull Requests to merge those extra branches back into feature_x
branch. And when work is done feature_x
is then merged to master.
For all the not production ready features we wanted to showcase to others sysops in my previous company setup a script that would spin up a new AWS instance and setup the whole stack on the specified commit (in a specific branch). And everyone inside the company could access that stack and test the feature. This script was also used by the QA team when setting up staging. The fact that we used monorepo made this process easier.
After seeing what the onboarding experience is like cloning from tags rather than branches, we've decided to create stable
branches to use as reference points for cloning and hotfixing.
Here is what we've ended up with (basically Git Flow with different branch names):
I'm new to the monorepo concept but I quickly skimmed google for existing opinions and projects to get up to speed.
I'm warming up to the idea of a monorepo. I do see how it could really make it easier for us to sync work across highly interdependent repos. It does seem like the pros outweigh the cons at the moment.
I will say that the open source projects that @nick mentioned as using monorepos seem, from what I can tell, to be entirely javascript-based projects. As opposed to having a server in ruby on rails and a client in react, for example.
I'll throw my support behind the monorepo move with the additional request that we eventually try to move all of our code in this repo to a single language and package manager (node and npm). So we'd need to move the bridge server from python to node (something that I think is already a great idea for a number of other reasons). And once that is done, I think lerna could be a solution worth exploring.
I think if we switch to a monorepo and then move the bridge server to node, we'll be set up nicely for a clean package structure and smooth development process.
Amen to more JS 🙏
More JS :cry:
I agree it is a good idea to have a single language - and we are quite close. Soon origin-bridge
will only be responsible for attestations, and the only other Python floating around is the pinner which isn't too much code. It might even be something worth doing prior to a move to a monorepo.
Agreed that at the current stage of the company, for team velocity it makes sense to have JS as our primary language.
For the future though, I don't think mono-repo is incompatible with using multi-languages. At my previous job we used 6 languages (python, Go, Rust, JS, Java, Swift) and the codebase for those projects co-existed happily in the same mono-repo. If later on we decide to support another language in addition to JS, we can make it happen. My 2 francs :)
Hmm ok, maybe my fears aren't well founded then. I've never used a mono-repo structure so I'll defer to those with experience.
I believe we also have a JavaScript version of most of our attestations thanks for @nick's original implementation of that.
Closing, as the develop
branches have been merged and deleted 🔥 But feel free to continue this discussion here or in #30.
@tomlinton and I agreed to keep a long-running staging
branch in place for continuous integration to watch. This will tentatively take the place of the release
branch, but the future might hold a scenario wherein we have multiple release candidate branches at one time and merge them into staging
.
Here is what we've ended up with (basically Git Flow with different branch names):
@micahalcorn I would appreciate if you could specify the main branch renames relative to Git Flow.
master
became stable
, develop
became master
and we added staging
as an intermittent branch between those two. 🎋
Thank you @micahalcorn
The Problem(s)
We have been loosely following the Gitflow branching model, but we have also been merging feature branches into
develop
without any concern for what will or will not be included in the next release. This often results in broken integrations and/or unfinished features living indevelop
that are not ready for public consumption - particularly in the case of the DApp. The consequence is that, when we create a release branch (or prepare to deploy fromdevelop
), we have to carefully select points in each repo's commit history where everything works together and undo or hide some DApp code.Since our repos don't default to
develop
, our project looks stale to anyone who glances at our GitHub code without digging into our branches and issues. This is a regular occurrence. If someone wants to contribute, they need to read the contributing process deeply buried in our docs to know that they should branch fromdevelop
, which is more critical than pointing a PR todevelop
(since we can more easily change their target than their base). This has been an ongoing source of frustration for new contributors and those of us who want to enable them.Our Objectives
Here is a list of concerns that I'm aware of. I've listed them in descending order of priority from my perspective.
Make it simple and intuitive for partners and developers to run a working version of our project.
master
branches separate fromdevelop
. But isn't this now accomplished (even better) by Origin Box?Show that we are actively working and shipping code.
Easily create deployable releases in a matter of minutes or a couple of hours using an established and predictable process.
Have a seamless, low-friction process for contributing.
Avoid merge conflicts.
Discourage long-running feature branches.
Follow open-source conventions.
Possible Solution(s)
I don't know that we can perfectly check all the boxes, but here's a thought:
master
as the default branch.develop
and start merging tomaster
.master
what will be included in the next release or build a full suite of integration tests. We can merge PRs into feature branches along the way, and they shouldn't live too long if we are doing regular releases every two weeks. There are plenty of other reasons to add integration tests too.Please feel free to weigh in @cuongdo @franckc @crazybuster @tyleryasaka @wanderingstan @joshfraser @matthewliu (and others).