Ugh. Pull requests again? OK, look, unless your team is so large that you can't effectively communicate otherwise, pull requests are just friction. Use feature branches, then merge them when they are ready. Trying to pretend like your two person team is a huge open source project with many distributed part-time and full-time developers is cargo cult at its worst.
I couldn't disagree with this more. Pull requests provide a quick and relatively pain less code review tool. Unless you are suggesting that code review is a bad practice, which in that case I'm pretty well dumb founded as I think it's a requirement for intelligent modern development.
They are a great tool for when you don't have any other way to communicate with the other developers. Code reviews are a great practice, and we all should do more of them. I do it when I get an email like "hey, could you review my code in feature-branch-xyz before I merge it?" It's less friction than doing GitHub-proprietary pull requests, and involves much less pompousness.
I guess different environments lead to different flows being better but managing code reviews via email sound really horrible to me. There is no good way to track who has actually reviewed the code, no easy way to annotate the code, and no easy way to give the code a seal of approval. Both Bitbucket and github provide good methods that are easily tracked for this. It' one thing to send an email saying please look at this code but It's much more difficult to track who on that email has done the review and who approves the code.
We use feature branches and issue pull requests/code reviews from those feature branches in BitBucket and it's been a universally well received tool and definitely increased the quality of our code reviews and overall code base.
In my original comment I mentioned a setup with a two person team. You know exactly who is reviewing or not reviewing your code in this setup: the other person. The two of you cannot possibly produce so many feature branches that you don't remember your own code that has not yet been reviewed.
If the PR method works for your team, that's great. In my experience, it leads to more friction and the reasons to implement it are usually "best practices" articles like TFA, not actual needs of the team.
I really like having code review persisted right there in the repository. I often go back and look at discussions on old pull requests to figure out why we decided to do something one way or another. It's even "higher resolution" than commit messages (which should also be good).
We are a trusting team and don't do pull requests with our closed source repos either.
To avert chaos it's much better to have an orderly branching model in place e.g. feature branches! My fellow partners made us go all "git flow" last year and the result has been a really tidy and satisfying workflow:
We have been using Git Flow in our team too. One advantage I se is that using git-flow specific hooks we add some metadata to every time a feature/ branch is finished. This metadata goes into an automatic Release notes file which is automatically added to the repo (as an amend of the flow's last commit).
Similarly, hotfixes have metadata which goes to their own hotfix.csv file.
A deploy script processes the hotfixes and feature files to create a Release notes.
We've got a very smooth release documentation process which is difficult for Dev's to hate and skip.
Or don't use branches at all. Develop on trunk/master with continuous integration. It reduces work-in-progress, exposes conflicts sooner and has a host of other knock-on benefits.
To 'CI' [per se] I say "yes, of course." It's a best practice. But it is not a substitute for branching! I want to choose when I'm exposed to conflicts. "Sooner" is usually -- but not always -- "better". Summary: strong disagreement on this radical approach.
I don't consider not-branching to be a radical approach. If you are using branches you really aren't doing CI, because you aren't integrating continuously.
> If you are using branches you really aren't doing CI, because you aren't integrating continuously.
Perhaps this is just a terminology issue, but I strongly disagree with this. You can always merge/rebase the latest version of master into your feature branch.
That will integrate other people's changes into your branch. But until you also merge your branch into master (and/or all other branches), you are not integrating your changes.
So there are projects where I don't branch: ones where I am the only committer, and there are no features. For example, my puppet manifests for all the servers I manage. It either works, or I roll it back.
However, feature branches are just multi-stage commits. Sure you can invest hours of your life setting up CI, then writing code, not testing it locally before pushing it to master, getting an obscure error from the test/deploy process, fixing it again, pushing again, getting another error, etc. But you probably want to, you know, ship the product.
Having said that, if your workflow actually resulted in you writing better code faster and you ended up shipping earlier and making more money, I'd love to read about it.
"Sure you can invest hours of your life setting up CI, then writing code, not testing it locally[...]"
Maybe I've misunderstood, but why aren't you testing it locally? With trunk based development you make your changes, run a local build and push if it passes. Everyone (including any CI servers) runs the same build process.
The trick is that you have to be able to push to master without breaking it, which is scary to many developers and usually requires a shift in thinking. How do I do large refactorings? (you don't - do many small refactorings instead). How do I add a half-finished feature? (break the feature into many smaller features, use feature toggles, etc.)
Of course. And this relies on your CI system having 100% unit and system test coverage, including testing external API's, CSS bugs, browser compatibility, etc. Are you certain that your system does that? More importantly, are you certain that investing the time into testing that your checkout button is not covered up by some random element due to a missing ";" character in your CSS file or a missing 0 in the width percentage value will eventually pay off? It should be scary to push to master if you hold master to be deployable at all times. Unit/system testing or not, you will never have guaranteed test coverage, and even if you try to get to it, you will spend infinitely more time doing that, than doing a reasonable amount of unit/system automated testing + good human QA.
That's really a function of your QA process, not anything specific to branching strategies. If you can automate everything such that continuous delivery (or even deployment) is possible - great. If not, deliver at whatever pace your QA allows (and strive to increase that pace). Trunk based development does not imply a diminished QA process.
Yes, there is always going to be a feedback delay between you making a change and the full impact of that change being known (even if your feature is bug free, will the customer want to use it?), but we should be bringing that feedback forward by moving changes through the pipeline as early as possible. Feature branching delays feedback, which is why I reject it.
Both Google and Facebook use trunk-based development. If Google can get away with a single trunk and 15,000 or so committers, chances are your organization can too.
The reason for trunk-based development over feature branches is that the time required to integrate a patch usually increases proportional to the square of the time since last integration. With trunk-based development, most commits reflect about 1-2 days worth of work, and they go in with minimal conflicts. Branches (and patches that sit idle for a month or two) often take forever to integrate, because as you are trying to update your code to the new master, the master is itself changing. At some point, the process doesn't converge, and you can spend forever trying to update a branch.
This is my preferred method too. But a lot of developers struggle with the discipline of small, discrete, incremental changes, plus the dependence on solid testing skills. It also requires a culture that can support it. No blame, in particular.
However, if you have a team that is comfortable working this way -- and is only occasionally breaking things; it happens -- then it is a wonderfully creative, frictionless, and flexible way to develop.
Meh, it doesn't have to be friction. If the goal is to ensure your other team member sees the changes you're making before they're merged in a pull request both accomplishes that and gives you both a place to put some notes related to that process.
I think you're ascribing too much ceremony to this. It's useful to have something written down for any discussion about these changes, and a pull request is as good of a place as any for that. Plus it ensures everything is all set up to merge once you're both satisfied with the changes.
While I'm often lazy about this, I think that there are advantages to doing this with this once your team is over just a solo developer. Encouraging your fellow developers to read (and at least understand, if not internalize) your code has some bus-proofing to it, and I don't think it's that much friction if done well.
The "12 Factor App" manifesto http://12factor.net/ is in the same vein as this, perhaps a bit more in-depth.
I like the idea of these guides generally. I think it'd be more valuable if they linked to example production code that followed the principles however, since there's no substitute for the real thing.
Come to think of it, I've never seen anybody write up any kind of index of (for example) Github projects that exemplify good design patterns for people to look at. Or some kind of recommended code reference list.
I like that idea too, but I suspect that there are pretty much zero non-trivial projects that actually follow best practices like these consistently. Maybe I'm wrong.
I disagree with "Keep the master branch deployable at all times." Both my CSS framework Min (http://minfwk.com) and several other popular GitHub projects use the strategy of 'only use one branch, and use tags to mark stable versions'.
Min's only branch (gh-pages, so we can serve the site with GitHub) is usually "unstable" (in the sense that a CSS framework can be unstable.) If someone wants a stable release, that's what Git's tag system is for.
I think the idea is sound, but the reasoning isn't. Keeping master deployable at all times forces breaking changes off into feature branches so unrelated pieces of functionality can't interfere with each other's release schedules.
Keeping master deployable for bug fixes doesn't make sense to me, though. Are you going to deploy new features sitting in master because something else had a bug? Just go look up the last release tag, make your bug fixes there, then merge them into master.
I've been bitten too many times by unstable features holding up releases on master (both my features and other team member's). Feature branches do a wonderful job of solving this and the required merge back into master gives you a nudge to prevent scope creep.
This didn't cover anything useful it just said what everyone was already aware of, the only useful part was the links. Everything else was like saying to spread butter on toast use a butter knife.
What you mean is it just said what you were already aware of.
Not everyone does know all of these things, a list of things with generalised statements along with links to more detailed information is incredibly useful to someone who is just getting into the field, which I guess is exactly who this article is aimed at.
I wouldn't call the part about configurations (in the post and in the 12 factor app reference) a best practice. Using environment variables is a hack that has negative side effects including security side effects.
This statement is just silly: "A good goal is that the application can be open sourced at any time without compromising any credentials." It's silly because the use of environment variables doesn't prevent anybody from putting them in a shell script that gets committed to git...
I think they made a mistake by making the "gets configuration parameters from the environment" specific to a UNIX/system environment. You can accomplish the same effect in a much more elegant manner using a tool like etcd or consul.
But the important part is really that the deployable unit pulls its configuration from the environment where it's deployed. There are a ton of ways to accomplish this...environment variables are one way, etcd/consul is another, you can use something language-specific like JNDI or you can even use a file with configs in a well-known location, but you really need to be deploying the same artifact to QA, E2E testing, production and whatever other environments you might have.
You're reversing the "goal" and "practice". It's not that Environment Vars allow you to "open source / credentials".
It's (goal) "be able to open source any time without compromising any credentials". One method (practice), use Environment Vars. Evars being a poor choice in your and somewhat my opinion, does not translate into the goal being poor. It's a laudable goal.
Being able to open source code without compromising any credentials is a great goal, but using environment variables doesn't really accomplish it UNLESS your code only runs on a PaaS, which will always supply all of your app's env vars, but it's unrealistic for a number of reasons.
First, there'll be extra vars that your PaaS won't fully manage, so you'll have to keep track of them yourself and then later configure the PaaS environment, so your app can access them. Second, for non-PaaS applications/deployments you still need to manage the environment variables.
The variables don't magically appear by themselves :-) They need to be stored somewhere... This "somewhere" is likely to be the git repo (for the app), so you are back to square one on this.
First of all, use git for version control. It is modern, works great and the majority of developers are either comfortable in using it or want to start using it.
Its a pain in the arse to learn, overcomplicated for 90% of the cases it is used in. How many people actually need a distributed version control."
(I use Git. It is powerful and useful, but the justification for using it in the article isn't really great. No mention of Mercurial or other version control systems).
The fact of the matter is that love it or hate it, Git is now the most widely used VCS on the market in corporate settings (see e.g. http://www.itjobswatch.co.uk/). More importantly though, it is also the de facto standard for version control -- the lingua franca of source code management, communication and collaboration. Subversion and TFS still have significant market share, but everything else has pretty much fallen off a cliff in the past couple of years.
Also, many of Git's most powerful features have nothing to do with being distributed. Easy branching and merging, private versioning, bisect, rewritable changesets, stash, and the ability to cherry-pick individual changes within a file to commit, back out or stash could all theoretically be built into a centralised system.
The benefit of standardizing on a tool that is "good enough" is worth it imo. Learning git is easier than learning svn, darcs, hg, perforce and git and juggling between them when you want to submit patches to open source projects or get new clients.
The world's inconsistent internet connections are a great reason to require distributed version control. I'm often trying to work from a location without a reliable connection to the internet, be it a plane, train or bus, a coffee shop with spotty internet or a meetup. Requiring a connection to a server kills productivity in those situations.
Perhaps there is something to be said for Mercurial, but unless you were previously on Subversion it's certainly not that it's easy to learn.
Your imagination ignores days where you WFH (like I am right now), it ignores remote workers, it ignores work while traveling, it ignores outsourcing, it ignores open source development.
But who cares, because Git or Mercurial can be used in a centralized manner if you want. But it doesn't have to be. That's why it's good.
He's not ignoring anything; he said non-distributed would handle 90% of use cases and that's probably somewhat true. Saying hey I'm one of those 10% isn't a rebuttal to what he said.
I definitely want to see some substantiation that everything I just enumerated is less than 10% of software development, by whatever metrics he wants: number of projects, lines of code, whatever.
Those things don't require distributed source control; they simply require remote access. Substantiation simply isn't necessary, you haven't given scenarios that demand distribution and you can't, because honestly there aren't any. Distributed source control is a preference, a style, not a necessity. Central repositories with remote access handle all of those use cases. Other than perhaps the Linux kernel, there's very little software that can't be written just fine with remote works and centralized repositories.
- Central repositories handle me working from a coffee shop with spotty wi-fi. No, I am not going to wait to commit until I get home, because I want a set of commits as I go so I can revert if I screw up.
- Central repositories handle me working on a plane. Same thing.
- Central repositories handle your Chinese subsidiary being constrained to a slow and spotty pipe (they actually exported our tree with git-svn and used git on their end--this was at a NASDAQ company, it's not like anyone was cheaping out, it was the best available).
That you are willing to work around the deficiencies of centralization does not mean they are not deficient. Don't be ridiculous.
My bad, I was overly huperbolic; of course there are situations situations in which distributed is clearly better. I use git. But I'd say those easily fall in the small minority of situations. Most of the time for most programmers I think, internet access is not an issue.
No worries. But I'd turn that around: is it not an issue because it's not an issue, or is it not an issue because we are trained to alleviate it? 'Cause I enjoy working from the park, too, and I wouldn't even want to trust tethered 4G to not be a pain in my ass while doing it.
The park... me thinks you live in a bubble and don't know what the average developer day is; believe it or not, most developers don't use git or any kind of distributed source control because most developers aren't working for cool startup's in the valley or on open source projects. Most developers are banging out Java and .Net apps for corporations using some form of centralized version control and not being able to work from 4G in the park isn't a problem they ever face.
All of this really covers the primary thing I preach when working with new devs. "You shouldn't be the only one who knows how to set this up and run it."
One thing that might be missing is good code documentation. Using DocBlock for PHP, for example. Ideally this is maintained in code, but that can get bloaty. At the very least, a git repo of markdown files. Even the built-in github wikis would suffice.
>Serve these through a CDN that is optimised for serving static files to ensure high transfer speeds and therefore increased user happiness.
I was not aware this was that common or even considered always the best practice. Is this really the best practice for any website? How exactly is a CDN more optimized than nginx on a dedicated server with 1GB connection?
I personally don't find much use for a CDN when dealing with a typical website's CSS, JS, images until you have very large traffic. You can concat and minify your CSS and JS files, and add a cache control header to all static content. That should be good enough until you get very large traffic.
But like anything, it depends on the use case. If the product is primarily a file server like Dropbox then maybe using a CDN early makes sense. Or your smallish number of users are spread across the world might be another use case.
The very nature of the kind of content you're serving over a CDN seems to indicate that unless you're extremely high traffic, the benefits are few: most of your clients are going to grab the static content from you once at a cost of a few hundred extra ms, and then rarely need it again.
I think having CDN as a basic requirement for all projects is... ill-considered. Remember, using a CDN is giving away data about your users' browsing practices without their consent.
Is it worth it if you have a US specific website that doesn't get that many users (~3 sessions at once)?
Also, another website I administer has a lot of user uploaded content that's constantly changing. I've not dealt with a CDN before, so I don't know how CDN helps with that? I think only a fraction of the data is static in this case.
PS
Why the hell would someone downmod my honest question?
Not sure about the down mod, but I think the point of the OP is to address projects that have the goal of driving a "startup" business.
In addition, with mobile, getting rid of any network latency you can is going to help.
In general, though, I think you are right to ask the fundamental question. That said, it's something a lot of people end up needing anyway and it helps if you design for it up front.
tl;dr - If you're building a low-volume site, the OP probably doesn't apply to you.
Look at CloudFront from AWS. CloudFiles from Rackspace used to also include built-in (no additional charge) distribution over Akamai as well, though it had limitations on the number of purges you could do, I think.
Fastly can easily be setup on top of s3 and we have been super happy with their basic layout and then their advanced features as we needed more (ssl content delivery, selective purging, etc)
Honest question: what are the benefits of using environment variables over having an actual configuration file (that is obviously not added to version control) ?
Unless your environment demands it, it doesn't matter. In fact, it can be a bit of a pain in the ass to implement on your own, if you are not using Heroku or some such. The main point there is to not put secrets into your git repo. How you accomplish that for the most part doesn't matter.
No idea how this is getting so many points. There's absolutely nothing of any practical interest here. Use version control and documentation... End of post. I'd say these are more industry standard practices than leading edge.
There will always be a new freshman class. Every year, someone joins HN (or the community at large) knowing next to nothing. We should welcome those people, not make them feel bad for being new.
Because the basics have to be pointed out again ... and again.
I think the upvotes don't primarily mean "omg I never thought to do this" but rather "will someone please staple this to the foreheads of all the clueless devs I've had to clean up after."
> I'd say these are more industry standard practices than leading edge.
Yeah, that's sort of what "best practices" are all about. They are for teaching outsiders what insiders have learned through practice. The intended audience is everyone who doesn't already know this.
If you consider the article of no practical interest for a seasoned insider, that's about the highest praise you can give.
It's best practices, not new practices, and a very clear concise write up at that. I wish if read this 6 months ago, rather than learning it the hard way.
>First of all, use git for version control. It is modern, works great and the majority of developers are either comfortable in using it or want to start using it.
Not to mention those points were mainly subjective. Don't get me wrong, I like and use Git myself but statements like "Use this, most people use it so you must use it too!" are just horrible.
True, although you'd be surprised to see how many people fail to provide proper docs, or use git for source control, still in 2014. I agree with others in here, maybe the title is just misleading more than anything else.
Failing to use git as your source control mechanism is not an actual problem; failing to use any source control is a problem, you don't have to use git.