Showing posts with label GitHub. Show all posts
Showing posts with label GitHub. Show all posts

21 March 2015

CI Saves My Bacon

One production pattern I've found indispensable is Continuous Integration. CI saves my bacon.

Recently I've found continuous delivery used on top of CI is a production pattern that helps me and my teammates produce working software.

Continuous Integration

Continuous integration or CI is
The practice of running tests on a non-developer server every time a developer pushes potential change sets to a shared source code repository
Florian Motlik, CTO of the CI/CD cloud service CodeShip wrote in Quora:
"This has the tremendous advantage of always knowing if all tests work and getting fast feedback. The fast feedback is important so you always know right after you broke the build (introduced changes that made either the compile/build cycle or the tests fail) what you did that failed and how to revert it."
Pushing code to a remote repository which in turn awakens the CI server to grab your new code and run your test suite, enables you to continue working without waiting for the test suite to complete on your local machine. When tests are run every time a developer pushes code, red flags might pop up, but tend to get fixed in short order. That feedback is reassuring.

One observable behavioral pattern is that many developers, including me, fail to consistently run the test-suite before pushing code. This is particularly true as the code base grows larger, the corresponding test suite grows proportionally larger, and the act of running the test suite exceeds a 5 minute threshold. I've worked gigs where running backend unit tests, front-end UI unit tests, and headless browser integration tests, took over 30 minutes to complete.

Yesterday I made a Rails schema migration to change a column name and to subsequently make it non-nullable. I fixed a controller test because I knew the schema update would have caused it to fail. I generally tend to make frequent commits following small changes. I committed and pushed the new code to our GitHub repository and continued working on the subsequent non-nullable migration. A few minutes later, the CI server reported back red-colored cackage (see below).

CodeShip's CI server indicating bobmacneal pushed code with broken tests
Drilling into the failure notification, I was given a handle to four other tests my schema change broke. I fixed the failing tests, committed, and re-pushed.

Test-driven developers, and their purist brethren test-first developers, would protest that if I was doing things right, I wouldn't be pushing code with failing tests. They're right. Sometimes I cut corners. Like many developers, I'm frequently not the perfect craftsman.

Knowing I'm flawed, I like having a safety net so I can continue the uninterrupted flow of my task knowing the CI server has my back.

I prefer the convenience of hosted continuous integration over standalone continuous integration (see a comparison of continuous integration software).

Continuous Deployment

Built on top of continuous integration is CD (continuous delivery or continuous deployment). Continuous delivery is
The practice of releasing the latest version of your code to a production, or production-like environment, every time new code is merged to a designated branch after a successful run through the CI gauntlet.
Once configured, a cloud-based continuous delivery service makes deployment to any environment frictionless. Continuous delivery supports the agile principle of producing working software.

I like CodeShip. CodeShip is a well-executed, visually attractive, easy-to-configure, cloud-hosted service that provides seamless continuous integration and continuous delivery.


REFERENCES

07 December 2014

Start Slackin

The infrastructure supporting the flow of communication has become an iteration zero concern. For software developers, a team chat application is becoming as fundamental as a GitHub repository.

Slack is a San Francisco based chat startup with a well-executed product that's rocketing in popularity. Slack's marketing pitch is
We’re on a mission to make your working life simpler, more pleasant and more productive.
Slack Chat Client
After a few months having used it with a few product teams, I'm convinced Slack is delivering on their pitch.

At the moment I'm using Slack with two product teams for different customers. In the past I have used other chat applications like:
Slack fills a niche by being less geek-centric than Colloquy and by being spiffier and more feature-rich than HipChat. Colloquy and HipChat remain fine products, but I've a growing preference for Slack.

Wildly Imagined Vintage Slack Poster

Using Slack, I like that:
  • One can easily configure different client gigs and then switch between them on the handy left nav;
  • One can easily create new team channels;
  • One can easily toggle between team and private channels;
  • Individual teammates may chat privately in the private channels; and
  • GitHub Commit Stream
  • Developers reap the benefits from the information stream via GitHub, Heroku, and Jira integration.

Chat is a forum for knowledge sharing. It has the potential to build team camaraderie even when your teammates work from a remote location.
"Contextual conversation is likely to become the dominant social motif of the next generation of work-technology apps."
— Stowe Boyd, tweet @stoweboyd

REFERENCES

Pair Programming in Perspective

Annual Mermaid Parade
Coney Island, 2012

I offered my 2¢ on this question from another developer:
Would you consider joining a company where pair programming is an essential part of software development?
One long-standing lesson from Extreme Programming is:
Programming in pairs improves quality. 
With qualifiers, few dispute this assertion.

Recently I've learned of mandates for pair programming which is mildly alarming. A team at BestBuy does pair programming ...all the time. This particular pair-programming-all-the-time initiative had the unintended consequence of chasing off one of the most test-driven, quality-focused craftsman I have pair programmed with, and learned from, in years past.

Let me state this:
Paired programming mandates are a bad idea.
Mandates in general are a bad idea. Producing software is a creative act. Mandates stifle and demoralize.
Pair programming is most helpful when on-boarding new team members, or when intentionally pairing an experienced developer with an inexperienced developer.
Software produced in pairs is typically superior, but not always the smoothest tack. Sometimes pairing is jarring to the soloist's creative flow. At times, pairing is downright inefficient.

It's common to achieve quality results on par with pairing by having peer reviews and team discussions. I'm an enthusiastic cheerleader for the Pull Request Workflow popular on GitHub and BitBucket (see Pull Requests for Teams). Pull Requests allow for collegial discussions that lead, more often than not, to quality improvements.

Mandates are a red-flag for team and organizational inflexibility. My answer to the developer's question "Would you consider joining a company where pair programming is an essential part of software development?" is a qualified no.
Two heads are usually better than one, but not always.
The development community has realized significant strides from XP and Agile, but shouldn't we be judicious about — and mindful of — how we apply what we've learned?

More ain't better, particularly when it's dictated over pragmatism or common sense.
Not every arrow in the quiver suits a situation.

REFERENCES

27 April 2014

The Learning Team

A Learning Organization seems so obviously desirable as to be ubiquitous yet most of us will never experience one.
Learning Organization
A term for an organization that fosters ongoing learning among its members. Because learning is ongoing, the organization continuously transforms itself.
If we can't fix our inept organization, perhaps we can influence our team.
All politics is local.
Tip O'Neill
All politics is local means that our success is tied to our ability to understand and influence our constituents.

My constituents are my teammates.

We owe ourselves the courtesy of modeling the kind of behavior we want to see in our teammates. We owe ourselves the courtesy of striving to be good learners and aspiring to be good teachers.
“You cannot force commitment, what you can do…You nudge a little here, inspire a little there, and provide a role model. Your primary influence is the environment you create.”
Peter Senge
Fun teams cultivate learning. The rest suffered from varying degrees of toxicity. I resolve to choose fun. I urge you to join me.
People unfamiliar with the nuts & bolts of software development imagine it's an engineering process, but it's a profoundly human activity.
Alan Cooper
A Learning Team

The closest I've been to a learning organization has been flashes of a learning team practiced by me and my teammates.
If your teammate responds to a question by affirming, "That's a good question", all indicators point to a learning team.
A well-tended and searchable wiki  ― thanks Ward ― that has up-to-date on-boarding instructions, and frequently used command sequences, is one sign of a learning team. On the other hand, admonishing a teammate to "look it up on the wiki" is a red flag your teammate is missing a teaching opportunity. Such opportunities occur whenever a teammate asks a question.
Missed teaching opportunities occur whenever a teammate stops asking or regrets asking.
A few red flags that you're falling short of a learning team are:
  1. Defensive Postures
  2. Shaming Mechanisms
  3. Cynicism
Defensive Postures:

We often recognize defensive postures in ourselves and in our teammates. Defensiveness is a burden and a buzz-kill. Excise it.
“It is not the absence of defensiveness that characterizes learning teams but the way defensiveness is faced”
Peter Senge
Your teammate doesn't want a knife in the back. He wants to you have his back. When your teammate is defensive, she's probably not pro-active.

Shaming Mechanisms:

Sometimes the original idea for a practice, or the spirit of an idea, gets lost over time.
Practices should never devolve into a mechanism for shaming.
Examples of sound practices that have gone toxic:
  • Continuous integration is a highly recommended, ongoing health-check, BUT never shame a teammate for breaking the build, or for failed functional tests. I suffered through an immature team that handed around a stuffed Build Monkey to anyone who broke the build. I deep-sixed the monkey.
  • Test-First is a valuable learning tool, as is Test-Driven. Both play a role in ensuring quality. BUT avoid shaming a teammate for not adopting them as a matter of course. If one or the other is an agreed upon team practice, then reward good behavior rather than shaming people for slip-ups or for regressing under pressure.
  • Estimation and burn-down charts, once handy tools to make wild-ass-guesses at story sizes and to make progress visible, have become blunt instruments for flogging in the hands of command-and-control managers. NEVER use a tool or a process to hurt people.
Process alone is usually innocent. It is converting ideals into expectations that can be toxic. For more on shaming, see Say No To Brogrammers.

Cynicism:

Cynicism grows from the loam of unmet expectations. One tip:
Don't romanticize your teammate's abilities to be a "craftsman" ― particularly if he must measure up to a poorly articulated definition of craftsmanship.
By avoiding romanticizing the notion that developers are craftsman, you'll be better equipped to avoid the psychological baggage of unmet expectations.
“In combating cynicism, it helps to know its source. Scratch the surface of most cynics and you find a frustrated idealist – someone who made the mistake of converting his ideals into expectations.”
― Peter Senge
Cynicism grows from trying to change too much. Forget about the larger broken organization for now. Remember all politics is local.

Get to root causes. If it's something the team can fix, fix it before it devours all optimism.

Lastly, try modeling vulnerability rather than oozing cynicism. Your teammates will appreciate it.

Getting to the Learning Team
A learning team, like a happy family, requires practice and vigilance. A learning team gets sustenance from people expressing ideas and opinions with reckless abandon.
Remember everyone has a different take. The spectrum might range from Michelangelo to Cowboy Coder.
To voice an opinion or posit an idea we need to feel comfortable speaking up and we need to be practiced at listening. A learning team starts by modeling listening, practicing Beginner's Mind, and aspiring to teach.
"In the beginner's mind there are many possibilities, but in the expert's mind there are few"
Shunryu Suzuki
Learning frequently calls upon us to step out into the vast unfamiliar. Learning can make us uncomfortable because it means exposing our weaknesses. But humility goes a long way toward learning. Practice humility.

The place I'd start to cultivate a learning team is a distributed source control system that supports the Pull Request Workflow.

Pull Request Workflow:

If you use no other means to get to a learning team, try the Pull Request Workflow on GitHub and Bitbucket. The PR Workflow encourages you and your teammates to:
  • publicly view proposed code changes,
  • publicly offer options or discuss alternatives, and
  • approve all changes ― shared responsibility.
Two outcomes of the PR workflow are:
  1. Quality - Under the assumption that two-plus heads are better than one, quality invariably improves from peer-reviewed code; and
  2. Learning - Newbies can view other's code before it's merged and benefit from the public dialogue about how the code might be improved. Old hand's are given the golden opportunity to learn and the golden opportunity to teach. Double gold. Be respectful. No one loses.

See Pull Requests for Teams for more details.

An ideal teammate teaches you something and wants to learn from you. Seek or grow a learning team. Resolve to choose fun.

REFERENCES

ACKNOWLEDGEMENT

Hat tip to Chris Bartling for introducing me to aspects of the learning environment and for nudging me into the vast unfamiliar of open source.

28 August 2013

Pull Requests for Teams

Sunflowers, 1887
Vincent van Gogh
If you recognize a measure of truth in the proverb:
Two heads are better than one,
you will want to experiment with the Pull Request workflow with your next software team.

Pull Request Workflow

The Pull Request workflow, implemented by popular shared source code repositories like GitHub and Bitbucket, is an excellent means to spark team discussions and improve code quality.

Like a classic Greek ode, the Pull Request Workflow has three call & response parts:
  1. Branch;
  2. Discussion; and
  3. Merge
Pull Request Workflow: 1. Branch; 2. Discussion; and 3. Merge

Following is a sample workflow for a hypothetical feature called more_cowbell.

1. Branch

Assuming you have already cloned (downloaded) a shared repository to your local machine, the first step is to create a branch off of the trunk (often called master).

Following are series of git terminal commands that will get you to the point where you can modify code. Typically you will create a local branch from the shared repository to work on a new feature or a bug.

Create the more_cowbell branch as follows:

(master) $ git checkout -b more_cowbell

Then checkout the newly created local branch as follows:

$ git checkout more_cowbell

Think of more_cowbell as your local sandbox. Now make additions, deletions, or changes, then create/run unit tests and integration tests, and commit your changes. Or if you prefer test-first, do the tests first, then commit.

(more_cowbell) $ git commit -am "Add more cowbell"

Finally you're ready to push your changes back to the shared repository for review, discussion, and a potential merge back to master.

(more_cowbell) $ git push -u origin more_cowbell

2. Discussion

Go to your shared repository on GitHub, Bitbucket, or other. Locate the more_cowbell branch you pushed in Step #1.

GitHub and Bitbucket both have side-by-side comparison tools. Use the compare tools to carefully inspect the proposed changes by comparing more_cowbell with master.

When you're ready to open your proposed more_cowbell changes to a team discussion, locate and click the Pull Request link (or button).

Your teammates will be notified of your Pull Request. They will then review your changes, post comments on individual lines of code, or post general comments on the Pull Request. Typical comments might involve issues with formatting, the location of a method, notification of code duplication, suggestions for refactoring, etc.

It is courteous to respond to the comments posted on your Pull Request in a timely and respectful fashion. A concise and courteous response from you following a "you might want to..." comment might be:
"Good catch. Will do."
Some teams use round-robin to determine who reviews a given Pull Request with each developer assuming the role of reviewer. Other teams assign one or more lead developers to review all the Pull Requests. Most teams encourage the entire team to look at and comment on Pull Requests as time permits.

Others may add commits to your branch by doing a fetch and a checkout of more_cowbell on their local machines. They would follow the same workflow of modify, commit, and push back to the shared repository. Presumably more discussion would ensue.

3. Merge

After ample discussion, and perhaps following some additional changes or tweaks that have been suggested to you, someone other than you will merge your changes to master.

Summary

For me, the essence of a Pull Request is:
  • to learn from my teammates, and
  • to agree upon what constitutes a worthy addition or an incremental improvement.
Like me, most developers readily agree that code reviews improve quality. And like me, most developers dread the traditional code review because it often means an uncomfortable one-on-one encounter with a high-ranking alpha developer where one is made to feel defensive or worse, incompetent.

Pull Requests feel less authoritarian and more democratic. It is a lightweight quality improvment process more in the mode of discussion and edification, than in the mode of admonishment. It has been my experience that Pull Requests spark discussions about the code and the craft which, in turn, tends to improve the quality of the code.
I'm all in favor of the democratic principle that one idiot is as good as one genius, but I draw the line when someone takes the next step and concludes that two idiots are better than one genius.
-Leo Szilard
References