-
Notifications
You must be signed in to change notification settings - Fork 0
Description
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.
DoneJS-next:
- Dedicated repo!
- Singular
master
branch, set as the GitHub Pages branch of the dedicated repo. - The main DoneJS repo owns the documentation in a
docs
folder, and ignores the built files. - Users are instructed to manually copy built files into
master
of the dedicated repo, like so:
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.
CanJS:
- No dedicated repo.
- The main CanJS repo houses a
gh-pages
branch in addition tomaster
. - The main CanJS repo owns the documentation in a
docs
folder while also pulling in docs from variousnode_modules
, and ignores the built files. - The built files are not presently mixed in with main repo, but I think they used to be.
- CanJS takes the approach of using this
Makefile
to build and push togh-pages
:
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
orgit 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 thegit 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.
- This would allow the
StealJS:
- Dedicated repo!
- However, the repo name
stealjs/stealjs
can be confusing. - Perhaps
stealjs/website
would be more obvious.
- However, the repo name
- Has two branches:
master
andgh-pages
.- The
gh-pages
branch contains a mix of source and built files.- This is bad for the
gh-pages
branch because you can do silly things like visit http://stealjs.com/package.json and http://stealjs.com/doc/steal-topics/migrating-1.md. - Ideally, the
gh-pages
branch would contain only the necessary built files.
- This is bad for the
- The
- The StealJS org repos own their documentation in respective
doc
folders (not the usualdocs
).- Note: This breaks convention with what
bit-docs
does by default, by using thedest
option to essentially swap the default ofdoc
fordocs
, so source is now looked for indoc
and generated files are output todocs
. This is fine, just something to take note of.
- Note: This breaks convention with what
- It's not entirely clear how the generated files are pushed to the
gh-pages
branch, but probably a force add (similar to the CanJSMakefile
) 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.
Document CSS:
- No dedicated repo.
- The main Document CSS repo houses a
gh-pages
branch in addition tomaster
. - The built files get mixed in with the source and configuration files.
- This is a bit silly, since you can do things like visit http://documentcss.com/Gruntfile.js
- I suggested using a
grunt
plugin to quarantine the built files into agh-pages
branch.- No built files get commit to
master
. - No source files get commit to
gh-pages
. - The
master
andgh-pages
would be completely separate.- Separation of concerns makes the purpose of each branch obvious.
- No confusion of source files in generated website branch.
- No confusion of built files in source code branch.
- No built files get commit to
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
- Some set
master
as the GitHub Pages branch (see first GitHub Pages pic up top). - Some set
gh-pages
as the Default Branch and removemaster
. - Some have
master
hold the configuration and dependencies, then build togh-pages
.- This seems to be the most versatile solution.
- Some have
master
withdocs
folder (second option in first GitHub Pages pic up top).- This would be particularly confusing with the current bit-docs default of
docs
for sources.
- This would be particularly confusing with the current bit-docs default of
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.
- Probably not, because this requires built directory to be in
- Copies this logic.
- Creates a git repo in the built directory:
git init
- Adds the remote:
git remote add remote-ee0138 [email protected]:xxx/yyy.git
- 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 (ifgh-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.
- Creates a git repo in the built directory:
- Wraps this npm package (will try first).
Whatever best accomplishes the suggested Take Aways.
Then, use this plugin in bit-docs/website
.