pddds

Latest things…

Deloying to the server

Jan 14 2017

This is part 3 of my – sometimes rambling – review of building the latest iteration of pddds. In part 1 I reviewed the tech, tools and features I used, in part 2 I covered the workflow I used to develop the site.


The last piece of the puzzle when building the website (other than actually making it) was to decide how to upload it. I could have just copied the files generated by jekyll onto the server using scp, but that’s fiddly and repetitive so why not automate it?

The logical way to do this was via git; I can push changes from git and use a server-side hook to rebuild the site.

Setting up the server

First you need a git repository on the server to push to. Although you’ll need to check out the repo to build it, you only need a bare repository, i.e. one without a checked out working copy.

Connect to the server using ssh and do:

git init --bare ~/path/to/repo

That will create create the folder ~/path/to/repo.git which will contain the git info. Then, from the local machine you can add it as a remote as deploy:

git remote add deploy peter@server-address.com:~/path/to/repo.git

and push the local master branch to the server

git push deploy master

With the bare repo setup, we can send the latest version to the server but we still need to add a hook to run jekyll, building the final website.

Deploying

Git has a number of hooks you can register, they are scripts that run on specific events. To build the site after receiving pushed changes, we can use the post-receive hook.

The post-receive hook should be created on the server, in the repo.git/hooks folder.

A simple post-receive hook, which just print to the terminal when changes are pushed, looks like:

#!/bin/bash

while read oldVal newVal refName; do
	echo "recieved branch $refName"
done

To build the site, we need the hook to checkout a working copy of the repository and run jekyll, outputting to the public html folder. I found this tricky to get right, but ended up with something similar to the following.

#!/bin/bash
set -e

TMP_CLONE="$TMPDIR/website-git-clone"
PUBLIC_WWW="/home/public"

build(){
	local branch="$1"
	branch="${branch#refs/}"
	branch="${branch#heads/}"

	local out="$PUBLIC_WWW"

	if [[ "$branch" != "master" ]]; then
		return
	fi

	local clone="$TMP_CLONE"

	echo checking out
	mkdir -p "$clone"
	git --work-tree="$clone" checkout -f "$branch"
	git --work-tree="$clone" reset --hard HEAD

	echo building
	JEKYLL_ENV=production jekyll build -s "$clone" -d "$out"
}

while read oldVal newVal refName; do
	build "$refName"
done

This will checkout and build the master branch when it is pushed. Everything else is ignored. That means the master branch is the “live” branch.

Note the use of JEKYLL_ENV=production, previously I mentioned using jekyll.environment in the base layout to determine if we’re in the live site. By setting JEKYLL_ENV before calling jekyll build, we change that variable from the default “development” to “production”. This will disable things like the live.js script.

Per-branch builds

Sometimes I wanted to push something that wasn’t the master branch, usually to show some in progress changes to a friend. To do this, I extended the script first by removing the check for master, then by changing the output directory to be in a folder /wip.

build(){
	# ...

	local out="$PUBLIC_WWW/wip/$branch"
	if [[ "$branch" == "master" ]]; then
		out="$PUBLIC_WWW"
	fi
	echo destination $out
	mkdir -p "$out"

	# ...
}

To avoid trashing /wip when rebuilding master, you also need to add the following to the jekyll _config.yml.

keep_files:
    - wip

When you push a branch, that should then build that branch into a wip folder of the same name.

Because the work-in-progress sites now reside as a subfolder of the website, when defining urls we need to make sure we use the correct baseurl, and we need to set it building on the server.

The best solution I found for setting the baseurl was to just inject it into the temporary checkout’s _config.yml:

build(){
	# ...

	if [[ "$branch" != "master" ]]; then
		echo "baseurl: \"/wip/$branch\"">>"$clone/_config.yml"
	fi

	# ...
}

It seems dirty, but it works.

Then in layouts and other website code, we need to use the baseurl variable.

<link rel="stylesheet" href="{{ site.baseurl }}/css/base.css" type="text/css" />

Now we can push any branch

git push deploy test-rebuild-layout

and see it at http://pddds.com/wip/test-rebuild-layout (in theory).

Full script

I did a couple more changes after that including avoiding building tags and cleaning up deleted branches. Instead of cover them all, you can just read through the final hook.

#!/bin/bash
set -e

TMP_CLONE="$TMPDIR/website-git-clone"
PUBLIC_WWW="/home/public"

build(){
	local branch="$1"
	branch="${branch#refs/}"
	branch="${branch#heads/}"

	local clone="$TMP_CLONE"

	if grep -q "^tags/" <<<"$branch"; then
		return
	fi

	local out="$PUBLIC_WWW/wip/$branch"
	if [[ "$branch" == "master" ]]; then
		out="$PUBLIC_WWW"
	fi
	echo destination $out
	mkdir -p "$out"

	echo checking out
	mkdir -p "$clone"
	git --work-tree="$clone" checkout -f "$branch"
	git --work-tree="$clone" reset --hard HEAD

	echo destination $out
	mkdir -p "$out"

	echo building
	if [[ "$branch" != "master" ]]; then
		echo "baseurl: \"/wip/$branch\"">>"$clone/_config.yml"
	fi

	JEKYLL_ENV=production jekyll build -s "$clone" -d "$out"
}

delete(){
	local branch="$1"
	branch="${branch#refs/}"
	branch="${branch#heads/}"

	echo deleting $branch
	rm -rf "$PUBLIC_WWW/wip/$branch"
}


while read oldVal newVal refName; do
	if grep -q '^0*$' <<<$newVal; then
		delete $refName
	else
		build "$refName"
	fi
done

That’s it. Plenty more to add to the site (firstly pagination, the front pages is getting pretty long), and some less technical posts to write.

- Peter


Building Things, Quickly

Jan 05 2017

This is part 2 of my – sometimes rambling – review of building the latest iteration of pddds. In part 1 I reviewed the tech, tools and features I used.


This time I’m going to cover workflow I used to rapidly develop the site.

I built the site in what scraps of spare time I could find, so I wanted to maximise the time I spent actually building the site. The first thing I did was streamline the dev process.

Live editing

My first goal is to make editing and previewing as fast as possible.

Previewing the work-in-progress site using Jekyll is easy out of the box:

$ jekyll server --watch --drafts

That builds starts the built the site and starts a simple webserver hosting the site at http://localhost:4000. The two additional flags make it possible to quickly edit the site; --watch tells jekyll to rebuild the website when files are edited so you don’t need to restart the server, and --drafts includes unfinished posts in the _drafts/ folder.

Jekyll now recommends you also use Bundler when building the site. This ensures you have all the required ruby packages. With bundler, it then looks like:

$ bundler exec jekyll server --watch --drafts

With that running, I’m able to preview the website in my browser, next to my text editor, as I change it. The only downside with this setup is I have to refresh the page to see my changes. That’s where the next step comes in.

Included at the end of each page is Live.js, a bit of javascript that watches for changes to the websites files and triggers a reload when they change:

<script type="text/javascript" src="http://livejs.com/live.js"></script>

Now, this isn’t the sort of script I want to run on the live site, so we need to only include it when previewing the site locally. We can use the variable jekyll.environment to detect if we’re in the live production site or just in the preview development site. Later, when I talk about deployment, I’ll show how to set the environment when building the live site.

In the base layout this code looks something like:

{% if jekyll.environment == "development" %}
<script type="text/javascript" src="http://livejs.com/live.js"></script>
{% endif %}

Now – with the text editor on my left, and the webbrowser on the right – as I save changes to pages, layouts, css, or any other file, and jekyll automatically rebuilds them, the web browser automatically refreshes to reflect the changes!

It’s not perfect, (I can’t easily save tweaks made in the browsers dev tools, back to the original css/scss files) but it’s relative simplicity and complete isolation from the specific tools is a major advantage. It will work with any text editor, and browser, and on any OS.

(It should even work mobiles/tablets previewing the development site, but you’d have to work out how to connect to the jekyll server across your network)

Getting up-and-running

Now I never needed to leave the text editor, another major sticking point was getting up-and-running. When you’ve just got just half an hour spare, I needed to be able to sit down and start work immediately.

First though, a disclaimer: I “work” inside bash and vim, but I work on Windows because I want to get work done. This leads to some odd environment-specific scripts and tools. So, sorry, the sample below probably won’t work for you, but maybe they’ll help?

I have a script checked in that I run before I do anything else. It’s very simple; it launches the sever and opens the web browser on the correct address. Work starts as so:

peter@my-pc MINGW64 /
$ cd ~/pddds

peter@hawthorne-pc MINGW64 ~/pddds (master)
$ ./run_server.sh

Open vim, off I go.

This is what run_server.sh looks like:

#!/bin/bash

# start the server in another window
start cmd /c"bundler exec jekyll server --watch --drafts"

# wait for server to start
while ! curl http://localhost:4000/ &>/dev/null; do sleep 1; done

# open the homepage
explorer http://localhost:4000/

Time logged

One of the surprising revelations I had at the end of 2016 was how useful time tracking would be at keeping on-task. I use Toggl, initially to keep track of how many non-development things I was having to do at work. As I started using it I found it had the additional benefit of giving my time focus. I decide what I’m going to do, hit Go and start work. I feel guilty if the timers running, but I’m not doing that thing, so I stay on-task and have a better idea how long I’ve been working on a thing. For that reason I started using it at home.

Anyway, back to the website.

A nice side effect is I know exactly how much time I spend building the site.

I think, considering I was re-learning many aspects, completing the site in roughly a work-week (i.e. 40 hr week) seems respectable.


Next time, deployment.

- Peter


Shiny

Dec 22 2016

The never ending march of progress! It’s been a bit over five years since I tried build my last site (which ended up shelved until now). Looking just at the little part of web tech I used, things have really moved on.

Last time I was doing this, Internet Explorer was still causing incompatibility issues. Now, with the release of Edge and IE 11 being mostly standards compliant, most of those concerns (for html/css) have gone away. And when something is causing a problem, even Internet Explorer has dev tools and an inspector! After using Firebug for many years, the in-built dev tools have just made it redundant.

I’ve also found some great resources which I either didn’t exist in 2010, or I just never knew about them. First is Can I use which really helps determine if a css feature you just found is universally accepted, a single-browser novelty, or hot-new-thing noone has implemented. The second is MDN, an invaluable reference and guide to html, css, and js. It’s by Mozilla, but it appears to be a good reference across browsers.

(If you’re a cool kid, and use ddg, you can quickly search both, in your address bar, by doing either !caniuse css-thing or !mdn webthing)

When I built the first version of pddds, the way things were, I didn’t get a chance to really use some of the modern web things. Partly because were was still patchy support, partly because I just didn’t have the time. This version has been different; from the outset I’ve been focusing on

Jekyll

Jekyll wasn’t one of the new things, I had used it on the first version, but with the amount it seems to have changed since 2011, it feels like a very different tool.

When I used it last, it was still a novel ruby project. Now it’s really matured into a solid framework. Looking through the contributions it looks like this all started happening in 2013 when parkr took over the project. It seems more streamlined, you can go from install to a blog in no time. Things that I had previously thought of building plugins to do now seem possible just using the vanilla tools, and that’s not to say it’s bloated. Running through the docs

Instead of spending time setting up jekyll, I’ve been able to get right to building the website.

Sass

I don’t remember if sass was shipped with jekyll previously; I remember reading about it, but it seemed like a hassle to set up with uncertain benefits. It also seemed like a toss up between sass and less.

Well that all changed. Sass is shipped with jekyll, sass appears to be the better choice over less, and I’m sold on it just by the tools for managing colours.

Previously I’d used jekyll to define reusable colours, which was ok, but was really just a hack. Now, using sass, I can do it in a css-like way:

$purple: #8D205A;
$green:#5f9252;

$lightwood:#9E713A;
$darkwood:#7B5030;

$linkCol:$green;
$linkHoverCol:$purple;
$linkVistedCol:darken($linkCol, 20%);
a {
    color: $linkCol;
    text-decoration:none;
    &:visited { color: $linkVistedCol; }
    &:hover {
        color: $linkHoverCol;
        text-decoration:underline;
    }
}

And then there are the mixins, which let you define reusable blocks or functions. For example, for the shadowed line I have:

@mixin border-shadow($highlight, $shadow) {
    border-#{$highlight}: 1px solid $highlightCol;
    border-#{$shadow}: 1px solid $shadowCol;
}

Which you can then include, setting which border is the highlight and which is the shadow:

hr {
    border: 0;
    height: 0;
    @include border-shadow(bottom, top);
}

There is more in there, but that’s all I’ve really needed so far.

Fonts

Web fonts (where you load the font from the server), as I remember them, were some combination of flash and javascript hacks. Things are pretty different now, although it still requires some javascript superglue to load the fonts.

I found a nice, clean, open source font; Fira by Mozilla. I use for all the headers on the site.

Now, the problem. Browsers support web fonts as part of the Css, but there are some issues. The main being “FOIT” (Flash of Invisible Text). The browser won’t render your text until the font is loaded, so you really need two fonts, and you need to switch between them once the font has loaded. This is where I use Font Face Observer to smooth over the cracks.

It’s a bit rough, but this is how it looks in the html:

<script type="text/javascript" src="/js/fontfaceobserver.js"></script>
<script type="text/javascript">
let font800 = new FontFaceObserver('Fira Sans', { weight: 800 });
let font700 = new FontFaceObserver('Fira Sans', { weight: 700 });
let font500 = new FontFaceObserver('Fira Sans', { weight: 500 });

Promise.all([font800.load(), font700.load(), font500.load()])
    .then( function(){
        document.documentElement.className += " fonts-loaded";
    });
</script>

Now, if you don’t run with javascript it won’t work (which makes me sad as a NoScript user) but the fallback font is not that different.

The main body just uses “traditional” fonts; specifying the already installed font to use. Nothing new with this, except now there are reliable modern system fonts. It’s good enough for Medium, why not me?

body {
    font-family:
        -apple-system,
        BlinkMacSystemFont,
        "Segoe UI",
        "Roboto",
        "Helvetica Neue",
        sans-serif;
}

I think it looks nice.

Responsive Layout

Leaving the best till last, I built the site “responsive first” or whatever therm term is. Once I had the infrastructure down, and I’d played around with the fonts, I started looking at how to build the site for mobile, tablet and desktop.

I went into this area completely blind and, like many of the new web tech I’ve learnt, was pleasantly surprised at how easy it was. There were a couple of articles about using css flex, but I was still mostly in the dark. The key was the MDN article “Using CSS flexible boxes” and specifically the “Holy Grail Layout example”, which had a clear clean example of how to use flex with media queries (also completely new to me) to get what I wanted.

With only a tiny bit of fighting with IE 11, the site worked on mobile and desktop!

From there I could start growing the website design.


Next time, the development process

- Peter


Autumn Playlist

Dec 09 2016
  1. Cargill - King Creosote
  2. Perpetuum Mobile - Penguin Cafe Orchestra
  3. My Dog’s Eyes - Zammuto
  4. Sunday Seance - Blockhead
  5. The Birds - Telefon Tel Aviv
  6. I’m Jim Morrison, I’m Dead - Mogwai
  7. 1st Century Pop Song - Hymie’s Basement
  8. Don’t Haunt This Place - The Rural Alberta Advantage
  9. Think Long - Mates of State
  10. Skyscraper - Julian Plenti
  11. Boo - Pinback
  12. Timber - Coldcut
  13. Building Steam With A Grain Of Salt - DJ Shadow
  14. The Box - Part 1 - Orbital
  15. Fred Jones, Pt. 2 - University A Cappella Version - Ben Folds Presents: The West Chester University Of Pennsylvania Gracenotes
  16. Do They Owe Us A Living? - Jeffrey Lewis
  17. Ticket Taker - The Low Anthem

- Peter


New Thing

Dec 06 2016

I’ve update the website with a new look and new content.

Last time I dug into the website code was around 2010, and it’s been interesting seeing how things have changed in html/css. I’ll put more details up later when I’ve got time to write it up.

Lots left to do on the site; pagination, post formatting, some illustrations maybe? I might finish it all, if a website is ever really finished.

In the meantime I’ve posted some music playlist from last year. Enjoy

- Peter


Summer Playlist

Sep 19 2016

June, July, and August

  1. Way Out - Ellen Allien, Apparat
  2. Palace - The Antlers
  3. Percussion Gun - White Rabbits
  4. Let Your Love Grow - Moderat, Paul St. Hilaire
  5. Darker - Doves
  6. I Heart L.A - Subtle
  7. Anthems For A Seventeen Year Old Girl - Broken Social Scene
  8. A True Story of a Story of True Love - The Books
  9. All The King’s Men - Wild Beasts
  10. Your Ex-Lover Is Dead - Stars
  11. Bottle - Texture Like Sun
  12. Double Shadow - Junior Boys
  13. Things I Don’t Remember - Ugly Casanova
  14. Turbo Dreams - Ellen Allien, Apparat
  15. Galaxies - Laura Veirs
  16. rr vs. d - Au
  17. Orphans - Beck
  18. Ladies and Gentlemen We Are Floating in Space - Spiritualized
  19. I’m Jim Morrison, I’m Dead - Mogwai
  20. Faded High - Gayngs
  21. Men Of Station - 13 & God
  22. Creep - Scala & Kolacny Brothers
  23. Rooks - Shearwater

- Peter


Spring Playlist

May 31 2016

March, April, and May

  1. Highway of Endless Dreams - M83
  2. Your Ex-Lover Is Dead - Stars
  3. Rooks - Shearwater
  4. Palaces Of Montezuma - Grinderman
  5. Exile Vilify (From the Game Portal 2) - The National
  6. I’m On Fire - Bat For Lashes
  7. Wish You Were Here - Sparklehorse
  8. Burn the Witch - Radiohead
  9. Tripoli - Pinback
  10. Herculean - The Good, the Bad & the Queen
  11. Finish Line - Fanfarlo
  12. The Trapeze Swinger - Iron & Wine
  13. Rain - Bishop Allen
  14. Don’t You Evah - Spoon
  15. I’m Aquarius - Metronomy
  16. A Perfect Day To Chase Tornados - Jim White
  17. Tech Romance - Her Space Holiday
  18. Blackout - British Sea Power
  19. Keep The Dog Quiet - Owen Pallett
  20. Horny Hippies - The Dodos
  21. Blah Blah Blah - Say Hi
  22. Warrant - Foster The People
  23. Soldier Girl - The Polyphonic Spree
  24. Afterlife - Arcade Fire
  25. Gold Guns Girls - Metric
  26. Santa Fe - Beirut
  27. Harrisburg - Josh Ritter

- Peter


Winter Playlist

Mar 02 2016
  1. It’s Never Over (Hey Orpheus) - Arcade Fire
  2. Old Time - Peter Broderick
  3. Hard to Find - The American Analog Set
  4. To Make a Portrait - Message To Bears
  5. New Slang - The Shins
  6. That Knot Unties? - David Karseten Daniels
  7. Bats In The Attic - King Creosote & Jon Hopkins
  8. Visions - Sea Wolf
  9. Bad As They Seem - Hayden
  10. Windstorm - School Of Seven Bells
  11. Lucky Like St. Sebastian - Momus
  12. Legions (War) - Zoë Keating
  13. Dragonfly Across An Ancient Sky - Helios
  14. Boy With a Coin - Iron & Wine
  15. Tenuousness - Andrew Bird
  16. Spill Yer Lungs - Julie Doiron
  17. It Will Find You - Maps
  18. Untitled #1 - Spain
  19. The Wrote & The Writ - Johnny Flynn
  20. The Actress - The Delgados
  21. Drain You - Horse Feathers
  22. Song For You - Alexi Murdoch
  23. Be Good or Be Gone - Fionn Regan
  24. Maps - Yeah Yeah Yeahs
  25. Awful Sound (Oh Eurydice) - Arcade Fire
  26. Things Behind The Sun - Nick Drake
  27. Nothing Like You - Frightened Rabbit
  28. John Tylor’s Month Away - King Creosote & Jon Hopkins
  29. Seoul - amiina
  30. Hand On Your Heart - José González
  31. Tokyo Moon - Windmill

- Peter


Autumn Playlist

Feb 13 2016

I’ve been organising my music on Spotify I enjoy listening to into 3-month lists of songs. These are the songs I liked enough to save, in the order I saved them. Most recent saved at the top.

Autumn’s music:

  1. One Read Thread - Blind Pilot
  2. Blur Oak - Bowbirds
  3. Radio cure - Wilco
  4. Hunters Map - Fionn Regan
  5. The Skin of My Yellow Country Teeth - Clap Your Hands Say Yeah
  6. The Stars of Track & Field - Belle & Sebastian
  7. Barriers - Aereogramme
  8. Birdhous In Your Soul - They Might Be Giants
  9. The End Of The Race - Willy Mason
  10. Upward Over The Mountain - Iron & Wine
  11. Expectations - Belle & Sebastian
  12. Far Away - José González
  13. Pretty In A Panic - My Latest Novel
  14. Measuring Cups - Andrew Bird
  15. 2080 - Yeasayer
  16. Who Named The Days? - Arab Strap
  17. Post-Tour, Pre-Judgement - Aereogramme
  18. The Hope Edition - My Latest Novel
  19. The Underwood Typewriter - Fionn Regan
  20. Free Translator - The Books
  21. Yet Again - Grizzly Bear
  22. Lover’s Spit - Broken Social Scene

- Peter