diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000000..653d0b0d144
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+.jekyll-metadata
+_site/
+.bundle
+bin
+vendor
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000000..27d72641bff
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,12 @@
+# Contributing
+
+## Running the site locally
+
+This site is powered by [Jekyll](jekyllrb.com). Running it on your local machine requires a working [Ruby](https://www.ruby-lang.org/en/) installation with [Bundler](http://bundler.io/).
+
+Once you have that set up, run:
+
+ script/bootstrap
+ script/server
+
+…and open http://localhost:4000 in our web browser.
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 00000000000..3ca8d7baf67
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,4 @@
+source "https://rubygems.org"
+
+gem "github-pages"
+gem "rake"
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 00000000000..46a90afccbb
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,132 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ activesupport (4.2.7)
+ i18n (~> 0.7)
+ json (~> 1.7, >= 1.7.7)
+ minitest (~> 5.1)
+ thread_safe (~> 0.3, >= 0.3.4)
+ tzinfo (~> 1.1)
+ addressable (2.4.0)
+ coffee-script (2.4.1)
+ coffee-script-source
+ execjs
+ coffee-script-source (1.10.0)
+ colorator (0.1)
+ ethon (0.9.0)
+ ffi (>= 1.3.0)
+ execjs (2.7.0)
+ faraday (0.9.2)
+ multipart-post (>= 1.2, < 3)
+ ffi (1.9.14)
+ gemoji (2.1.0)
+ github-pages (90)
+ activesupport (= 4.2.7)
+ github-pages-health-check (= 1.1.2)
+ jekyll (= 3.1.6)
+ jekyll-coffeescript (= 1.0.1)
+ jekyll-feed (= 0.5.1)
+ jekyll-gist (= 1.4.0)
+ jekyll-github-metadata (= 2.0.2)
+ jekyll-mentions (= 1.1.3)
+ jekyll-paginate (= 1.1.0)
+ jekyll-redirect-from (= 0.11.0)
+ jekyll-sass-converter (= 1.3.0)
+ jekyll-seo-tag (= 2.0.0)
+ jekyll-sitemap (= 0.10.0)
+ jemoji (= 0.7.0)
+ kramdown (= 1.11.1)
+ liquid (= 3.0.6)
+ listen (= 3.0.6)
+ mercenary (~> 0.3)
+ rouge (= 1.11.1)
+ terminal-table (~> 1.4)
+ github-pages-health-check (1.1.2)
+ addressable (~> 2.3)
+ net-dns (~> 0.8)
+ octokit (~> 4.0)
+ public_suffix (~> 1.4)
+ typhoeus (~> 0.7)
+ html-pipeline (2.4.2)
+ activesupport (>= 2)
+ nokogiri (>= 1.4)
+ i18n (0.7.0)
+ jekyll (3.1.6)
+ colorator (~> 0.1)
+ jekyll-sass-converter (~> 1.0)
+ jekyll-watch (~> 1.1)
+ kramdown (~> 1.3)
+ liquid (~> 3.0)
+ mercenary (~> 0.3.3)
+ rouge (~> 1.7)
+ safe_yaml (~> 1.0)
+ jekyll-coffeescript (1.0.1)
+ coffee-script (~> 2.2)
+ jekyll-feed (0.5.1)
+ jekyll-gist (1.4.0)
+ octokit (~> 4.2)
+ jekyll-github-metadata (2.0.2)
+ jekyll (~> 3.1)
+ octokit (~> 4.0)
+ jekyll-mentions (1.1.3)
+ html-pipeline (~> 2.3)
+ jekyll (~> 3.0)
+ jekyll-paginate (1.1.0)
+ jekyll-redirect-from (0.11.0)
+ jekyll (>= 2.0)
+ jekyll-sass-converter (1.3.0)
+ sass (~> 3.2)
+ jekyll-seo-tag (2.0.0)
+ jekyll (~> 3.1)
+ jekyll-sitemap (0.10.0)
+ jekyll-watch (1.5.0)
+ listen (~> 3.0, < 3.1)
+ jemoji (0.7.0)
+ activesupport (~> 4.0)
+ gemoji (~> 2.0)
+ html-pipeline (~> 2.2)
+ jekyll (>= 3.0)
+ json (1.8.3)
+ kramdown (1.11.1)
+ liquid (3.0.6)
+ listen (3.0.6)
+ rb-fsevent (>= 0.9.3)
+ rb-inotify (>= 0.9.7)
+ mercenary (0.3.6)
+ mini_portile2 (2.1.0)
+ minitest (5.9.0)
+ multipart-post (2.0.0)
+ net-dns (0.8.0)
+ nokogiri (1.6.8)
+ mini_portile2 (~> 2.1.0)
+ pkg-config (~> 1.1.7)
+ octokit (4.3.0)
+ sawyer (~> 0.7.0, >= 0.5.3)
+ pkg-config (1.1.7)
+ public_suffix (1.5.3)
+ rake (11.2.2)
+ rb-fsevent (0.9.7)
+ rb-inotify (0.9.7)
+ ffi (>= 0.5.0)
+ rouge (1.11.1)
+ safe_yaml (1.0.4)
+ sass (3.4.22)
+ sawyer (0.7.0)
+ addressable (>= 2.3.5, < 2.5)
+ faraday (~> 0.8, < 0.10)
+ terminal-table (1.6.0)
+ thread_safe (0.3.5)
+ typhoeus (0.8.0)
+ ethon (>= 0.8.0)
+ tzinfo (1.2.2)
+ thread_safe (~> 0.1)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ github-pages
+ rake
+
+BUNDLED WITH
+ 1.12.5
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 00000000000..6ed77b0653d
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,9 @@
+require "rake/testtask"
+Rake::TestTask.new do |t|
+ t.libs << "test"
+ t.test_files = FileList["test/*_test.rb"]
+ t.warning = false
+ t.verbose = false
+end
+
+task :default => :test
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 00000000000..7bb0deb670d
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,19 @@
+baseurl: "/open-source-handbook"
+
+exclude:
+ - bin
+ - docs
+ - Gemfile*
+ - Rakefile
+ - README.md
+ - script
+ - test
+ - vendor
+
+permalink: /:path/
+
+defaults:
+ - scope:
+ path: ""
+ values:
+ layout: article
diff --git a/_data/fields.yml b/_data/fields.yml
new file mode 100644
index 00000000000..b5b19857661
--- /dev/null
+++ b/_data/fields.yml
@@ -0,0 +1,7 @@
+# Each piece of content has YAML front matter with these properties:
+
+title:
+ required: true
+
+next:
+ type: String
diff --git a/_layouts/article.html b/_layouts/article.html
new file mode 100644
index 00000000000..43da259ed0d
--- /dev/null
+++ b/_layouts/article.html
@@ -0,0 +1,13 @@
+
{{ page.title }}
+
+{{ content }}
+
+{% assign previous = site.pages | where: "next", page.path | first %}
+{% if previous %}
+ Previous: {{ previous.title }} |
+{% endif %}
+
+{% if page.next %}
+ {% assign next = site.pages | where: "path", page.next | first %}
+ Next: {{ next.title }}
+{% endif %}
diff --git a/_content/getting-started/branding.md b/getting-started/branding.md
similarity index 98%
rename from _content/getting-started/branding.md
rename to getting-started/branding.md
index d54d5e9e2df..7b492c417e8 100644
--- a/_content/getting-started/branding.md
+++ b/getting-started/branding.md
@@ -1,4 +1,7 @@
-# **Branding**
+---
+title: Branding
+next: getting-started/preparing.md
+---
You’ve thought about who your users are, what they need from you, and what you might be able to offer them. Next, we’ll put that research into practice as we consider the brand of your project.
@@ -24,7 +27,7 @@ Make sure that your project’s name doesn’t infringe upon any trademarks. A c
-You’ll also want to look for open source projects with a similar name, especially if you share the same language or ecosystem. If your name overlaps with a popular existing project, you will confuse your audience and make it less likely that anyone will use what you’ve created. You can check for similar project names here: [http://ivantomic.com/projects/ospnc/](http://ivantomic.com/projects/ospnc/)
+You’ll also want to look for open source projects with a similar name, especially if you share the same language or ecosystem. If your name overlaps with a popular existing project, you will confuse your audience and make it less likely that anyone will use what you’ve created. You can check for similar project names here: [http://ivantomic.com/projects/ospnc/](http://ivantomic.com/projects/ospnc/)
@@ -69,5 +72,3 @@ We’re almost there! Next, we’ll walk you through a few components that every
### Further reading
* [http://producingoss.com/en/getting-started.html#choosing-a-name](http://producingoss.com/en/getting-started.html#choosing-a-name)
-
-[Previous](setting-expecations.md) | [Next](preparing.md)
diff --git a/_content/getting-started/index.md b/getting-started/index.md
similarity index 97%
rename from _content/getting-started/index.md
rename to getting-started/index.md
index 4f89facdc79..cc22b89f5de 100644
--- a/_content/getting-started/index.md
+++ b/getting-started/index.md
@@ -1,4 +1,7 @@
-# Before You Get Started
+---
+title: Before you Get Started
+next: getting-started/setting-expectations.md
+---
## What does it mean to open source a project?
@@ -31,5 +34,3 @@ Remember: open source isn’t just for software! You can open source everything
When you open source a project, you open yourself to feedback and suggestions from other people who are engaged with your work. It might feel intimidating to open source a project for the first time, but remember that you’re not alone.
In the next section, we’ll help you figure out your goals around open sourcing your project. Understanding these goals beforehand will make it easier to manage your and others’ expectations later on.
-
-[Previous](../index.md) | [Next](setting-expectations.md)
diff --git a/_content/getting-started/legal.md b/getting-started/legal.md
similarity index 98%
rename from _content/getting-started/legal.md
rename to getting-started/legal.md
index acb40671234..8b7d3b45a94 100644
--- a/_content/getting-started/legal.md
+++ b/getting-started/legal.md
@@ -1,4 +1,6 @@
-# **The legal side of open source**
+---
+title: The legal side of open source
+---
Sharing your creative work with the world can be an exciting and rewarding experience. It can also mean a bunch of legal things you didn’t know you had to worry about.
@@ -100,7 +102,7 @@ If you use others’ open source code to create anything that could be considere
-To learn more about the implications of different open source licenses, check out: [https://tldrlegal.com/](https://tldrlegal.com/)
+To learn more about the implications of different open source licenses, check out: [https://tldrlegal.com/](https://tldrlegal.com/)
@@ -108,6 +110,6 @@ To learn more about the implications of different open source licenses, check ou
* [http://choosealicense.com](http://choosealicense.com)
* [https://tldrlegal.com/](https://tldrlegal.com/)
-* [https://processmechanics.com/2015/07/23/a-model-ip-and-open-source-contribution-policy/](https://processmechanics.com/2015/07/23/a-model-ip-and-open-source-contribution-policy/)
+* [https://processmechanics.com/2015/07/23/a-model-ip-and-open-source-contribution-policy/](https://processmechanics.com/2015/07/23/a-model-ip-and-open-source-contribution-policy/)
* [https://blog.docker.com/2014/01/docker-code-contributions-require-developer-certificate-of-origin/](https://blog.docker.com/2014/01/docker-code-contributions-require-developer-certificate-of-origin/)
-* [https://www.joyent.com/blog/broadening-node-js-contributions](https://www.joyent.com/blog/broadening-node-js-contributions)
+* [https://www.joyent.com/blog/broadening-node-js-contributions](https://www.joyent.com/blog/broadening-node-js-contributions)
diff --git a/_content/getting-started/preparing.md b/getting-started/preparing.md
similarity index 96%
rename from _content/getting-started/preparing.md
rename to getting-started/preparing.md
index e0c001a7a47..b2219f7cc24 100644
--- a/_content/getting-started/preparing.md
+++ b/getting-started/preparing.md
@@ -1,4 +1,7 @@
-# **Preparing for launch**
+---
+title: Preparing for launch
+next: marketing/index.md
+---
You’re almost ready to launch your project! In this section, we’ll talk about what to include in an open source project before releasing it to the world.
@@ -87,25 +90,20 @@ Sometimes, it will take a long time before people notice your open source projec
* Licenses
* [https://github.com/blog/1530-choosing-an-open-source-license](https://github.com/blog/1530-choosing-an-open-source-license)
- * [http://choosealicense.com](http://choosealicense.com)
+ * [http://choosealicense.com](http://choosealicense.com)
* READMEs
* [http://tom.preston-werner.com/2010/08/23/readme-driven-development.html](http://tom.preston-werner.com/2010/08/23/readme-driven-development.html)
* [https://github.com/matiassingers/awesome-readme](https://github.com/matiassingers/awesome-readme)
* [https://pages.18f.gov/open-source-guide/making-readmes-readable/](https://pages.18f.gov/open-source-guide/making-readmes-readable/)
* [https://changelog.com/a-beginners-guide-to-creating-a-readme/](https://changelog.com/a-beginners-guide-to-creating-a-readme/)
- * [https://gist.github.com/jxson/1784669](https://gist.github.com/jxson/1784669)
+ * [https://gist.github.com/jxson/1784669](https://gist.github.com/jxson/1784669)
* Contributing guides
* [https://github.com/blog/1184-contributing-guidelines](https://github.com/blog/1184-contributing-guidelines)
- * [http://www.contribution-guide.org/](http://www.contribution-guide.org/)
- * [https://github.com/nayafia/contributing-template](https://github.com/nayafia/contributing-template)
+ * [http://www.contribution-guide.org/](http://www.contribution-guide.org/)
+ * [https://github.com/nayafia/contributing-template](https://github.com/nayafia/contributing-template)
* [http://mozillascience.github.io/working-open-workshop/contributing/](http://mozillascience.github.io/working-open-workshop/contributing/)
* Codes of conduct
- * [http://contributor-covenant.org/](http://contributor-covenant.org/)
- * [https://github.com/django/code-of-conduct](https://github.com/django/code-of-conduct)
- * [https://adainitiative.org/2014/02/18/howto-design-a-code-of-conduct-for-your-community/](https://adainitiative.org/2014/02/18/howto-design-a-code-of-conduct-for-your-community/)
+ * [http://contributor-covenant.org/](http://contributor-covenant.org/)
+ * [https://github.com/django/code-of-conduct](https://github.com/django/code-of-conduct)
+ * [https://adainitiative.org/2014/02/18/howto-design-a-code-of-conduct-for-your-community/](https://adainitiative.org/2014/02/18/howto-design-a-code-of-conduct-for-your-community/)
* [https://github.com/docker/docker/blob/master/CONTRIBUTING.md#docker-community-guidelines/](https://github.com/docker/docker/blob/master/CONTRIBUTING.md#docker-community-guidelines/)
-
-
-[Previous](branding.md) | [Next](../marketing/index.md)
-
-
diff --git a/_content/getting-started/setting-expectations.md b/getting-started/setting-expectations.md
similarity index 97%
rename from _content/getting-started/setting-expectations.md
rename to getting-started/setting-expectations.md
index bbf1fe6a3f1..6d575bfa8a0 100644
--- a/_content/getting-started/setting-expectations.md
+++ b/getting-started/setting-expectations.md
@@ -1,4 +1,7 @@
-# Setting expectations
+---
+title: Setting expectations
+next: getting-started/branding.md
+---
There are many reasons to open source a project. It’s a good idea to figure out yours before going public with your project. What you want to get out of the experience will guide how you manage your project and help you figure out where to say yes (and no!).
@@ -36,7 +39,7 @@ If you’re hoping to get feedback on something you’ve created, consider askin
## Figure out what others need from you
-Finally, open sourcing a project is a two-way street. People who use your project will probably ask you for things, too.
+Finally, open sourcing a project is a two-way street. People who use your project will probably ask you for things, too.
Try to anticipate these needs beforehand so you can add them to your project from the beginning. Successful open source projects try to document as much as they can in public. Much like reusable pieces of code, reusable information means less people need to ask you the same questions over and over again. (That means less work for you!)
@@ -60,5 +63,3 @@ We’ll also use these answers in the next section, as you consider the brand of
* http://mozillascience.github.io/working-open-workshop/personas_pathways/
* http://tom.preston-werner.com/2010/08/23/readme-driven-development.html
-
-[Previous](index.md) | [Next](branding.md)
diff --git a/_content/index.md b/index.md
similarity index 91%
rename from _content/index.md
rename to index.md
index 3f62a5a5081..efc8b3f71ba 100644
--- a/_content/index.md
+++ b/index.md
@@ -1,4 +1,7 @@
-# Welcome
+---
+title: Welcome
+next: getting-started/index.md
+---
Welcome to the Open Source Handbook! We created this handbook to help creators like you successfully release and grow your projects.
diff --git a/_content/marketing/building-community.md b/marketing/building-community.md
similarity index 98%
rename from _content/marketing/building-community.md
rename to marketing/building-community.md
index 46509155fc1..b3bff2bb5f4 100644
--- a/_content/marketing/building-community.md
+++ b/marketing/building-community.md
@@ -1,4 +1,7 @@
-# **Building a Community**
+---
+title: Building a community
+next: marketing/measuring.md
+---
You’ve launched your project, you’re spreading the word, and people are checking out your project. Awesome! Now, how do you get them to stick around? In this section, we’ll discuss ways to encourage people to use, contribute to, and evangelize your project.
@@ -54,13 +57,10 @@ You’re doing great so far! Now that you’re promoting your project and growin
### Further reading
-* [http://radek.io/2015/10/12/marketing-for-open-source-projects-5/](http://radek.io/2015/10/12/marketing-for-open-source-projects-5/)
+* [http://radek.io/2015/10/12/marketing-for-open-source-projects-5/](http://radek.io/2015/10/12/marketing-for-open-source-projects-5/)
-* [http://hood.ie/blog/welcoming-communities.html](http://hood.ie/blog/welcoming-communities.html)
+* [http://hood.ie/blog/welcoming-communities.html](http://hood.ie/blog/welcoming-communities.html)
* [https://ashfurrow.com/blog/building-popular-projects/](https://ashfurrow.com/blog/building-popular-projects/)
-* [http://sarah.thesharps.us/2015/10/06/what-makes-a-good-community/](http://sarah.thesharps.us/2015/10/06/what-makes-a-good-community/)
-
-
-[Previous](spreading-word.md) | [Next](measuring.md)
+* [http://sarah.thesharps.us/2015/10/06/what-makes-a-good-community/](http://sarah.thesharps.us/2015/10/06/what-makes-a-good-community/)
diff --git a/_content/marketing/index.md b/marketing/index.md
similarity index 80%
rename from _content/marketing/index.md
rename to marketing/index.md
index c19dfeadc99..7acc76cbde0 100644
--- a/_content/marketing/index.md
+++ b/marketing/index.md
@@ -1,7 +1,8 @@
-# **Marketing your project**
+---
+title: Marketing your project
+next: marketing/spreading-word.md
+---
This section of the handbook will help you spread the word about your project and grow your initial community of users and contributors. If you’re looking for feedback on your project, or want people to use and share your work, this part is for you.
Remember, reaching your audience takes time. It may take months or years for you to grow a community around your project. Don’t give up! It’s all part of the process.
-
-[Previous](../getting-started/preparing.md) | [Next](spreading-word.md)
diff --git a/_content/marketing/measuring.md b/marketing/measuring.md
similarity index 97%
rename from _content/marketing/measuring.md
rename to marketing/measuring.md
index a647f3f2cb5..a781a68a35b 100644
--- a/_content/marketing/measuring.md
+++ b/marketing/measuring.md
@@ -1,4 +1,6 @@
-# **Measuring Success**
+---
+title: Measuring Success
+---
Your project is starting to grow.🌱 Well, you think it’s growing. Is it growing? In this section, we’ll talk about how to measure and track the success of your open source project.
@@ -54,11 +56,11 @@ Here are a few types of contributor metrics you may want to regularly keep track
### Further reading
-* [http://blog.smartbear.com/news/measuring-success-in-an-open-source-project/](http://blog.smartbear.com/news/measuring-success-in-an-open-source-project/)
+* [http://blog.smartbear.com/news/measuring-success-in-an-open-source-project/](http://blog.smartbear.com/news/measuring-success-in-an-open-source-project/)
-* [https://opensource.com/business/16/6/pirate-metrics](https://opensource.com/business/16/6/pirate-metrics)
+* [https://opensource.com/business/16/6/pirate-metrics](https://opensource.com/business/16/6/pirate-metrics)
-* [https://speakerdeck.com/mikemcquaid/the-open-source-contributor-funnel](https://speakerdeck.com/mikemcquaid/the-open-source-contributor-funnel)
+* [https://speakerdeck.com/mikemcquaid/the-open-source-contributor-funnel](https://speakerdeck.com/mikemcquaid/the-open-source-contributor-funnel)
* [https://github.com/blog/2195-the-shape-of-open-source](https://github.com/blog/2195-the-shape-of-open-source)
diff --git a/_content/marketing/spreading-word.md b/marketing/spreading-word.md
similarity index 97%
rename from _content/marketing/spreading-word.md
rename to marketing/spreading-word.md
index f1fa0539469..a644d6f13ca 100644
--- a/_content/marketing/spreading-word.md
+++ b/marketing/spreading-word.md
@@ -1,4 +1,7 @@
-# **Spreading the word**
+---
+title: Spreading the word
+next: marketing/building-community.md
+---
You’ve just published your project–what’s next? It’s time to tell everybody about your hard work!
@@ -44,19 +47,17 @@ Spreading the word is an important step in growing the popularity of your projec
In the next section, we’ll talk about how to retain those early enthusiasts and grow an engaged community around your project.
-[Previous](index.md) | [Next](building-community.md)
-
### Footnotes
-[1] [https://news.ycombinator.com/item?id=7531689](https://news.ycombinator.com/item?id=7531689)
+[1] [https://news.ycombinator.com/item?id=7531689](https://news.ycombinator.com/item?id=7531689)
[2] [https://github.com/swinton/codeconf/blob/master/the-hashicorp-formula-to-open-source.md](https://github.com/swinton/codeconf/blob/master/the-hashicorp-formula-to-open-source.md)
### Further reading
-* [https://hacks.mozilla.org/2013/05/how-to-spread-the-word-about-your-code/](https://hacks.mozilla.org/2013/05/how-to-spread-the-word-about-your-code/)
+* [https://hacks.mozilla.org/2013/05/how-to-spread-the-word-about-your-code/](https://hacks.mozilla.org/2013/05/how-to-spread-the-word-about-your-code/)
-* [https://zachholman.com/posts/open-source-marketing/](https://zachholman.com/posts/open-source-marketing/)
+* [https://zachholman.com/posts/open-source-marketing/](https://zachholman.com/posts/open-source-marketing/)
* [http://readwrite.com/2014/10/10/open-source-marketing-apache-storm-nathan-merz/](http://readwrite.com/2014/10/10/open-source-marketing-apache-storm-nathan-merz/)
diff --git a/script/bootstrap b/script/bootstrap
new file mode 100755
index 00000000000..599f07e2e7d
--- /dev/null
+++ b/script/bootstrap
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+set -e
+export CC=gcc
+
+echo "==> Installing gem dependencies…"
+bundle check --path vendor/gems 2>&1 > /dev/null || {
+ time bundle install --binstubs bin --path vendor/gems
+}
diff --git a/script/cibuild b/script/cibuild
new file mode 100755
index 00000000000..ecb1ca01868
--- /dev/null
+++ b/script/cibuild
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -e
+
+export PATH="/usr/share/rbenv/shims:$PATH"
+export RBENV_VERSION="2.1.7-github"
+# clean out the ruby environment
+export RUBYLIB=
+export RUBYOPT=
+
+script/bootstrap
+script/test
diff --git a/script/server b/script/server
new file mode 100755
index 00000000000..68cfe8ec499
--- /dev/null
+++ b/script/server
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+set -e
+
+bundle exec jekyll serve --watch --incremental --baseurl ''
diff --git a/script/test b/script/test
new file mode 100755
index 00000000000..f8fd975cc1e
--- /dev/null
+++ b/script/test
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+set -e
+
+bundle exec rake
diff --git a/test/helper.rb b/test/helper.rb
new file mode 100644
index 00000000000..8f522361386
--- /dev/null
+++ b/test/helper.rb
@@ -0,0 +1,29 @@
+require "minitest/autorun"
+require "jekyll"
+
+module Helper
+ class << self
+ attr_accessor :config, :site
+ end
+end
+
+def source
+ File.expand_path('../', File.dirname(__FILE__))
+end
+
+def config
+ Helper.config ||= Jekyll.configuration("source" => source)
+end
+
+def pages
+ site.pages.map { |doc| doc.to_liquid }
+end
+
+def site
+ Helper.site ||= begin
+ site = Jekyll::Site.new(config)
+ site.reset
+ site.read
+ site
+ end
+end
diff --git a/test/lint_test.rb b/test/lint_test.rb
new file mode 100644
index 00000000000..fb17ade9ad5
--- /dev/null
+++ b/test/lint_test.rb
@@ -0,0 +1,38 @@
+require_relative "./helper"
+
+describe "lint test" do
+
+ pages.each do |page|
+
+ describe page["path"] do
+
+ describe "frontmatter" do
+
+ before do
+ # Load raw metadata to skip defaults
+ @data = SafeYAML.load_file(page["path"])
+ end
+
+ it "contains supported fields" do
+ extra_fields = @data.keys - site.data["fields"].keys
+ assert extra_fields.empty?, "Unexpected metadata in #{page["path"]}: #{extra_fields.inspect}"
+ end
+
+ site.data["fields"].each do |name, attrs|
+ it "#{name} is required" do
+ assert @data.key?(name), "#{name} is required"
+ end if attrs["required"]
+
+ it "#{name} should be of type #{attrs["type"]}" do
+ assert_kind_of Kernel.const_get(attrs["type"]), @data[name] if @data[name]
+ end if attrs["type"]
+ end
+
+ it "`next` points to a page that exists" do
+ assert pages.detect {|p| p["path"] == page["next"] },
+ "Could not find page with path #{page["next"]}"
+ end if page["next"]
+ end
+ end
+ end
+end