Generally speaking, sounds good to me. I'm not aware of all the places in the workflow that this will disrupt but it makes sense to me to switch sooner rather than later.
We should apply this to all our repos on whetstone, presumably (and then look at repos elsewhere)? If you want to look into the logistics, go ahead. Let me know if there are steps that require admin intervention (eg GitLab re-config, I guess) and/or when you're ready to flip the switch.
I should be able to do most of the rest, if not, I'll let you know. Most important is communicating the change to everyone also sync their local repo copies.
I'd like to do away with master and main completely, rename master to production, and create a new, un-protected branch develop and make that the default.
Would it make it more or less complicated to also have a branch staging so we can merge something without breaking staging? I like the idea that the production env would always run production and the staging env would run staging. Pushing to the respective branches would cause an automatic deployment to the respective environment.
I'd like to do away with master and main completely, rename master to production
This seems pretty reasonable. production leaves a lot less room for confusion about what it controls :)
and create a new, un-protected branch develop and make that the default.
Considering protected is mostly about enforcing development workflow constraints, what do we gain by having an un-protected long-lived workflow branch like this? If "protected" means "you have to submit an MR to change it and pipelines have(*) to pass" then having a protected "develop" branch seems like a good thing to me.
(*) or an admin can choose to merge even with a failing pipeline
Would it make it more or less complicated to also have a branch staging so we can merge something without breaking staging? I like the idea that the production env would always run production and the staging env would run staging. Pushing to the respective branches would cause an automatic deployment to the respective environment.
The develop/production deployment workflow would look like:
make a feature branch, develop develop develop, make an MR merge it into "develop" branch
automation updates staging deployment to the latest develop@HEAD
eventually someone feels good about staging deployment and/or branch (or maybe "every Monday morning"?) and merges (maybe fast-forwards?) "production" branch to be even with "staging" branch
automation updates production deployment to the latest production@HEAD
And with the extra "staging" branch:
make a feature branch, develop develop develop, make an MR merge it into "develop" branch
eventually someone feels like they want to stage some changes,
merges (or fast-forwards) "staging" branch to be even with "develop" branch
automation updates staging deployment to the latest staging@HEAD
rest of workflow as above
Does that match your thinking? I suppose we might eventually find that the staging deployment churns faster than we'd prefer. This might be wasteful of resources or disruptive of anyone trying to do QA on the staging deployment. Ideally we could de-couple the decision about when to merge a feature branch from any QA schedule (at least mostly)?
The flip side is that it's nice to see that some changes actually work or don't work right away ... OTOH that may just be what our test suite is for. And if we find that we're regularly breaking staging when our test suite is passing then we know we need to improve the test suite.
So ... I'd lean towards with develop / staging / production, I think.
Thanks @jcalderone , yes, that workflow was exactly what I was thinking of.
I think having one more permanent branch gives a little more room for confusion, but that is more than made up by the very clear naming (branch name = environment) in my opinion.
We could use the permanent staging branch for bug-fixing when develop has already moved on with new features, like a release candidate branch in the nvie git workflow model, but without having to change which branch our staging env is running for every release. (I.e. by having the "next release" always be staging instead of release-1.2.3 we can spare us reconfiguring CI for every new release branch). We could also do both of course, bugfixing on temporary release branches, and merging the release branches onto staging for further manual inspection of the running thing. 👀
We could also make the pipeline automatic: I like the idea of having a develop that can have failing tests, but the CI will write the committer a very nice email when they broke the build (no 🍻, I know!). But only a develop with all tests green will automatically be merged (ff) onto staging and thusly automatically deployed. That way, if you ace the merge, you get instant gratification by having staging run your new stuff. If you screw up, you get ample time to fix w/o having broken an env that is running somewhere.
Considering protected is mostly about enforcing development workflow constraints, what do we gain by having an un-protected long-lived workflow branch like this? If "protected" means "you have to submit an MR to change it and pipelines have(*) to pass" then having a protected "develop" branch seems like a good thing to me.
By having an un-protected common long-lived branch, we gain flexibility, freedom, and development speed. The lower the barrier to commit to develop, the easier it is to actually provide value. (Quick fixes aren't helped by a committee looking over it all.) And if s.o. breaks the CI system with their passing commit, they can now also fix it again.
Also fits with one of my core beliefs: Never allow a computer to have the final decision about anything.
Don't Be A Slave To No Computer ~ Grandmaster Flash, 1984
I propose to protect the first two - production and staging - since they will deploy stuff - and leave develop unprotected. I would make develop the default branch.
I changed the default branch to "develop" and deleted "master". I can configure "protection" for develop / staging / production separately but I cannot configure "Pipelines must succeed" separately :(
So for now, pipelines are not required to succeed but all three branches are "protected" - but this only means you cannot push directly to them, you have to make an MR. Not sure if this is ideal configuration but also not sure if we can do better.
So for now, pipelines are not required to succeed but all three branches are "protected" - but this only means you cannot push directly to them, you have to make an MR. Not sure if this is ideal configuration but also not sure if we can do better.
Wouldn't it be better just the other way around: Make pipelines required to succeed globally but only protect staging and production ? Maybe I'm still confused.
Hm. I assumed that the pipeline check is completely independent of the "protected" status. The UI for pipeline check config says nothing at all about "protection". So I assumed that whether a branch is protected or not, the "Pipeline must succeed" setting would apply to an MR targeting that branch. This might be wrong.