We keep repeating "you have to pull first" (this is git and github by the way). Then you code a little, then get your tests to pass, then commit, then pull and push again. We give tutorial links, try firm / hard. The latest changes broke 2 dozen tests. We document everything. What other things can we do to help folks. We require passing tests. Right now we are tempted to rollback all of todays changes which wouldn't be popular. I'm not a big fan of that harsh an approach to management but perhaps a 'final' warning that we will do that next time is now required. Failing that it's clear they need to fix broken tests, right? We fixed them last time so that didn't 'take'...
Get your team to solve the problem and give them the autonomy to do so. Gather your team and do your best to state the problem or situation and goals clearly. State it like requirements, defining what needs to happen without specifying how. Developers are problem solvers so make this a problem to solve. This means you will have to listen and may have to give up on your ideal solution, but it your team owns the solution in they will be more likely to follow the solution they came up with.
Your requirements may be something like
1) Automated build runs each night a 9:00, so all tests have to pass by then. Ask the team how to enforce this (maybe if you break the build you have to bring in doughnuts :)
2) Builds are deployed every Wednesday, if tests do not pass by Tuesday then we miss the release and delay until the next window. How can we enforce this?
Whenever I do this with my team I find that they come up with a better solution than the one I've been dictating and they enforce it with each other which allows me to focus on more important things than enforcing the rules.
If the problem is that your team constantly break the build then you should all sit down and discuss the problem.
As a manager you should make it clear that if you don't have a buildable artifact at any time in the build server then you are not delivering anything. What would be the effects of not delivering anything? Then let the team try to solve the problem with what processes, practices and tools your team needs in order to have everything deliverable by the end of the day. Also make sure the team does not have any other pressing issues during this day or else those will take precedence by default.
There are multiple ways of doing this, but ultimately the team has to do it, so give the team enough time (like a day or two) to do this on their own.
... and if they still suck you need better programmers who have the discipline to do this kind of work.
Have you tried making failures more visible? A public build radiator? E-mail committer/team/company (well, the last one maybe isn't such a good idea unless you have a pretty small company..) when a build breaks, describing the commit contents and committer?
Try to make feedback loop as short as possible. If developer knows that she broke the build 15 minutes after the commit vs tomorrow, there is huge difference in terms of being able to react.
Sounds like you are doing it wrong - I mean the general git workflow. Here's a couple of suggestions:
We keep repeating "you have to pull first" (this is git and github by the way). Then you code a little, then get your tests to pass, then commit, then pull and push again.
Why is everyone committing into the same branch? That's so svn :). Let them develop in their own branches, specific for developer or feature. Don't worry about what they break in there, but demand that everything must pass tests and be top-notch in general once they merge their changes to production branch.
That way a programmer can develop isolated code in peace (even for a couple of days when working on a feature) and worry about integration and tests later, when he decides to put changes into production.
You can take it one step further - don't allow developers to push directly to production at all and give them a script instead which will allow them to push changes only if all tests pass. Simple.
Right now we are tempted to rollback all of todays changes which wouldn't be popular. I'm not a big fan of that harsh an approach to management but perhaps a 'final' warning that we will do that next time is now required.
Again, what are branches for? In this case you can:
create a "bugfix" branch from "production" branch
delete broken code from "production" branch
fix broken code in "bugfix" branch
merge "bugfix" back into "production"
What's so harsh about it?
In general, try to improve your version control workflow (perhaps hire a git consultant to help you with that?), that should stop programmers from committing broken code into production.
Of course, bad workflow isn't an excuse for committing broken code, but take it from a developer's perspective - it's very easy to break code when several people are working on the same app at once and everyone's committing to the same branch. Especially if they do a huge commits and tests are brittle, but I don't know if that's your case.