I'm in the process of building a GitHub Pages website for the bit-docs organization.
However, there isn't a standardized methodology for using GitHub Pages across our organizations, and there are sizable deviations between the various implementations.
This post serves to document and compare the different strategies currently being implemented by each organization, in order to help decide on the best method for use within the bit-docs org.
It may also benefit the analyzed organizations by giving them an idea of how they might improve. Lastly, it should help someone who is new to these organizations navigate the projects.
Available Settings
These are the relevant settings and options that can be used in whatever way is seen to be fit.
"GitHub Pages"
What this means: Any branch can be set as the "GitHub Pages" branch.
"Default Branch"
What this means: Any branch can be set as the "Default Branch".
Current Paradigms
Each organization (DoneJS, CanJS, StealJS, etc) has taken a unique approach to generating their respective documentation websites.
The following section will investigate the facts, and evaluate the pros or cons of each approach.
cd path/to/donejs
npm run document
cp -r site/* path/to/donejs-next
cd path/to/donejs-next
git add -A
git commit -am 'updating site'
git push
Analysis of the DoneJS-next approach
This is nice and clean, but requires too much user interaction. Setup could be tedious/error prone.
Proves that it's possible to have a GitHub Pages repo with a single master
branch, but not so sure about the paradigm of pushing from the main repo towards the website repo; having the website repo pulling from the main repo towards itself is probably better because it would be more versatile if it was needing to pull from multiple sources.
To enable the website repo pulling in, rather than the current paradigm of being pushed towards, would require a second branch to hold the configuration that does the pulling in. So, then, the current master
would become gh-pages
, and master
would be repurposed to hold configuration.
publish-docs:
npm install
git checkout -b gh-pages
./node_modules/.bin/bit-docs -fd
rm -rf test/builders/
git add -f test/
git add -f doc/
git add -f index.html
git add -f node_modules/can-*
git add -f node_modules/es6-promise
git add -f node_modules/steal
git add -f node_modules/steal-*
git add -f node_modules/when
git add -f node_modules/jquery
git add -f node_modules/jquery-ui
git add -f node_modules/funcunit
git add -f node_modules/syn
git add -f node_modules/socket.io-client
git add -f node_modules/feathers/package.json
git add -f node_modules/feathers-authentication-client/package.json
git add -f node_modules/feathers-hooks/package.json
git add -f node_modules/feathers-rest/package.json
git add -f node_modules/feathers-socketio/package.json
git checkout origin/gh-pages -- CNAME
git checkout origin/gh-pages -- release/
git commit -m "Publish docs"
git push -f origin gh-pages
git rm -q -r --cached node_modules
git checkout -
git branch -D gh-pages
Analysis of the CanJS approach
This might not be an ideal setup because the Makefile treats the main repo as a scratch directory, pulls in files from the remote instead of using the local copies, force pushes, and automates the deletion of files and branches. This script is a good start but seems a bit fragile.
To improve this, I would:
- Avoid that kind of straightforward branch checkout.
- May need to add some logic.
- There may be more subtle ways of doing this that don't affect the current index.
- Avoid
git checkout origin/gh-pages --
if possible.
- Avoid any kind of automated
rm -rf
or git branch -D
.
- Build and copy files to a single output directory (wisdom from Yeoman)
- This would allow the
.gitignore
to be simplified, and would replace the git add -f
calls with harmless copy commands that don't modify the index against .gitignore
's will.
- Consolidating all built files to a single location makes it easier to see what is included, for debugging, and to package up for sharing (we're interested in "sharing" to
gh-pages
).
- Aside: Take note of this trick.
- Dedicated repo!
- However, the repo name
stealjs/stealjs
can be confusing.
- Perhaps
stealjs/website
would be more obvious.
- Has two branches:
master
and gh-pages
.
- The
gh-pages
branch contains a mix of source and built files.
- The StealJS org repos own their documentation in respective
doc
folders (not the usual docs
).
- Note: This breaks convention with what
bit-docs
does by default, by using the dest
option to essentially swap the default of doc
for docs
, so source is now looked for in doc
and generated files are output to docs
. This is fine, just something to take note of.
- It's not entirely clear how the generated files are pushed to the
gh-pages
branch, but probably a force add (similar to the CanJS Makefile
) to subvert the .gitignore
.
Analysis of the StealJS approach
Mixing source and built files (on the gh-pages
branch) is bad. The repo name stealjs/stealjs
is somewhat misleading because, for all the other organizations, the redundantly-named repo (f.ex: canjs/canjs
or donejs/donejs
) is the main repo for the product, not just the product's website.
Compared to how CanJS and DoneJS do GitHub Pages, this is the most straightforward approach, but it is lacking instructions or a build script for pushing to gh-pages
, and would be better if it didn't mix source files into the gh-pages
branch.
Analysis of the Document CSS approach
The Grunt plugin is a nice abstraction, and would be a clean and useable solution.
Branching Strategies: master
and/or gh-pages
Take Aways
Due to the fact that most organizations will need the ability to pull in multiple sources for generating to a single website, it would seem the best option would be to always create a separate, dedicated repository for holding the website so this dedicated repo can have two branches; one for holding configuration that pulls in and builds the sources, and one that holds the generated output only.
It is best practice to compile all built files to a single directory, and to commit that directory to the appropriate website repo branch in a non-destructive manner. It is imperative that the branch containing the source files is not polluted with built files in commit history, and vice versa. This means the source branch should .gitignore
the directory containing built files, and the built branch should contain nothing but the contents of that generated directory. A final recommendation would be to give the dedicated repository an obvious name, such as YourOrg/website
.
Recommended Solution
Create a bit-docs plugin that essentially:
- Does subtree push.
- Probably not, because this requires built directory to be in
master
's history.
- Copies this logic.
- Creates a git repo in the built directory:
- Adds the remote:
- Creates branch
gh-pages
if it does not exist:
git checkout --orphan gh-pages
git symbolic-ref HEAD refs/heads/gh-pages
git reset
- Fetches
gh-pages
history from the remote (if gh-pages
exists):
git fetch --update-head-ok --progress --verbose remote-ee0138 gh-pages
- Commits changes to
gh-pages
:
git add -A .
git commit --file=commitFile-184a81
- Pushes
gh-pages
to remote:
git push remote-ee0138 gh-pages
- Warns if there are uncommitted changes in your working directory.
- If a file is removed from the built directory, it is successfully removed on
gh-pages
remote.
- This alleviates the need to force push.
- This means the
gh-pages
history can remain intact.
- Wraps this npm package (will try first).
Whatever best accomplishes the suggested Take Aways.
Then, use this plugin in bit-docs/website
.