You may have heard that we use GitHub to build GitHub. But our company isn’t built on just code: there’s strategy and HR policies and internal communications and a multitude of other documents that need to get written, too. All of which we can use GitHub to write as well.

Now, we’re a bit of an oddball company. You’ll have a tough time finding another organization with so many lawyers who know Git. But much of our code workflow can be easily applied elsewhere in the company, too: like writing our blog posts.

The Blog Post

The very first rule of GitHub, which has been the rule of law since day one: if you’ve built a new feature, you get to write the announcement post for it.

Letting a team write their own announcement is a nice nod to all the work they’ve put into the project. This habit is similar to the author shout-outs Apple would tuck into the About windows of early Macintosh apps. Celebrating each other’s successes is a really important facet of a successful culture: shipping is contagious, after all.

Like code, though, you want the work you’re putting out into the world to be approachable and to make sense. A great way to do that is to solicit outside opinions. So, also like code, our blog posts go through the pull request pipeline as well. Cut a new branch on our blog posts repository, write a new draft, and open a pull request to start the discussion (all of which you can do without leaving github.com).

Continuous Integration

The first thing that happens when we normally open a pull request is to run the tests with continuous integration. Blog posts don’t need to be too different, surprisingly enough. Think of this process like a syntax linter for your words: breaking the build isn’t necessarily bad, per se, but it might give you suggestions you might want to incorporate. It gives you immediate feedback without requiring a lot of additional overhead by our blog editors.

For example, here’s the current small suite of tests that run on push:

Image alt tags . All images in your Markdown should have ’alt’ tags for accessibility purposes.

. All images in your Markdown should have ’alt’ tags for accessibility purposes. Image size . All images used should be less than a megabyte in size. Helps prevent accidental screenshots that might be massive and slow down the mobile experience.

. All images used should be less than a megabyte in size. Helps prevent accidental screenshots that might be massive and slow down the mobile experience. Image promotions . All images should look good on high-density displays. Currently this just means the width should be twice the size of the width of the content on-page.

. All images should look good on high-density displays. Currently this just means the width should be twice the size of the width of the content on-page. CDN-hosted images . All images should be hosted on our CDN, for performance, security, and longevity reasons.

. All images should be hosted on our CDN, for performance, security, and longevity reasons. No emoji . We use Emoji all over the place internally, but they’re usually not quite the right tone in external communications.

. We use Emoji all over the place internally, but they’re usually not quite the right tone in external communications. No “Today, “. We’ve suddenly started realizing that we had gajillions of posts in the past that started out like “Today, we’re pleased to announce x”. This is just a silly style thing, but we decided to avoid this common intro in future posts for the sake of variety and sounding like a human.

Failing any of these tests will break the build for your specific pull request. You can still merge it and publish the post… CI in this repository is really just used as a suggestion rather than a hard-and-fast rule. The important part is that running these spot checks reduces the amount of work and time needed for someone else to manually inspect the size of your images, for example.

Merging a red pull request won’t break the overall repository since these particular tests are only run on files changed in each branch:

diffable_files = `git diff --name-only --diff-filter=ACMRTUXB origin/master... | grep .md` . split ( "

" )

The tests themselves are just a few lines of straightforward Ruby. Simple tests shouldn’t require complex code. Here’s a Gist of what we use currently, if you’re interested.

Collaborating

With your draft up and running with CI, it’s time to actually fix your egregious sentence structure problems.

The first step is to get the right eyeballs on your draft. Most of the people who are interested in helping edit your drafts probably have already watched the repository and have gotten a notification about your post, so you’ll usually only have to wait a few hours to start getting meaningful copy edits suggested to you (or applied directly to your pull request, if they’re non-controversial and simple changes).

It’s also helpful to mention a team in the pull request, of course. We have a bunch of writers on @github/copy that love to help out, and it’s also helpful to ping the relevant team who worked on the feature with you for their input as well:

Editing

At that point, we can rely upon some of the cool stuff we’ve already built into GitHub: prose diffs, for example, takes our Markdown and renders it to something closer to what the final result will look like on the blog. We use inline diff commenting for more specific word changes, and normal comments in a pull request for high-level “how about taking the end of this post in this direction?” thoughts.

Since it’s all versioned, we have a good history of changes from the initial draft to the final draft. Can’t tell you the number of times I’ve been happy I could go back and fish out some phrasing from earlier revisions of a draft.

Sharing

The way we write blog posts is definitely a stretch of dogfooding, probably moreso than other approaches we’ve taken at GitHub. Whether this jives with how your company operates is up to you. If not, be sure to check out some other collaborative writing tools, like Google Docs. (My favorite is @natekontny’s Draft, by the way.)

There’s two reasons why I wanted to share this workflow, though. The first is CI for prose, which I think is hilarious and actually has saved us a bit of time here and there.

The second, though, is the same reason why I dig sharing code on GitHub: it makes information accessible. I want more of the company to have access to more of itself. Marketing tends to stereotypically be sealed away in an ivory tower in most companies, and I think that’s what helps make it feel icky and inauthentic in a lot of cases.

By writing communications in an accessible manner internally, you benefit from a voice that’s hopefully more diverse, more impactful, and more genuine. And that’s the type of marketing that people appreciate.