diff --git a/.gitignore b/.gitignore
index e1cf205905d93c46016f27f9e4df6a1da11cfd86..ac22a07c44002b672ee90cf755356cc7bc54619d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,5 @@ __pycache__
 .vagrant/
 *.log
 *.retry
+id_rsa
+id_rsa.pub
diff --git a/README.rst b/README.rst
index edf5c4706215f0f88a982206ca521fc462fd3882..fa638874758e21c26bc40f4c950f97c5aad7e287 100644
--- a/README.rst
+++ b/README.rst
@@ -1,12 +1,9 @@
-Example
-#######
+pelican-gitreceive
+##################
 
-.. image:: https://travis-ci.org/adarnimrod/example.svg?branch=master
-    :target: https://travis-ci.org/adarnimrod/example
-
-An (empty) example Ansible role complete with working tests out of the box. For
-more information read the `blog post
-<https://www.shore.co.il/blog/ansible-example-role/>`_.
+Publish a Pelican blog with gitreceive. Run :code:`git remote add publish
+git@hostname:blog` to add the git remote and run :code:`git push publish` to
+publish changes. This role does not configure a webserver.
 
 Requirements
 ------------
@@ -61,3 +58,8 @@ Nimrod Adar, `contact me <nimrod@shore.co.il>`_ or visit my `website
 <https://www.shore.co.il/>`_. Patches are welcome via `git send-email
 <http://git-scm.com/book/en/v2/Git-Commands-Email>`_. The repository is located
 at: https://www.shore.co.il/git/.
+
+TODO
+----
+
+- Tests.
diff --git a/defaults/main.yml b/defaults/main.yml
index 0a97962c3b635cf908e8e45d5171b0aa8b7f3d92..2c126929058aad0aaaebb6082d109b1dceb49996 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -1,2 +1,4 @@
 ---
-# defaults file for example
+# defaults file for pelican-gitreceive
+pelican_gitreceive_output: '{{ pelican_gitreceive_www_root[ansible_os_family] }}/blog'
+pelican_gitreceive_public_keys: []
diff --git a/handlers/main.yml b/handlers/main.yml
index bd0df0d80d6094e097cca7760cd1b12a480df33c..61c6a849614474640cbd8565eabb54a25f3e8b7b 100644
--- a/handlers/main.yml
+++ b/handlers/main.yml
@@ -1,2 +1,2 @@
 ---
-# handlers file for example
+# handlers file for pelican-gitreceive
diff --git a/meta/main.yml b/meta/main.yml
index 2dea7f403f2774209b2935d8aecfe4e81d2379a8..b2bff06206d542f5a841bedb55f6c5d209aaa403 100644
--- a/meta/main.yml
+++ b/meta/main.yml
@@ -1,6 +1,6 @@
 galaxy_info:
   author: Nimrod Adar
-  description: An example Ansible role
+  description: Publish a Pelican blog with gitreceive
   company: Shore technologies
   license: MIT
   min_ansible_version: 2.0
@@ -11,5 +11,13 @@ galaxy_info:
   - name: Ubuntu
     versions:
     - xenial
+    - trusty
+  - name: Debian
+    versions:
+    - jessie
   galaxy_tags: [ ansible ]
-dependencies: []
+dependencies:
+    - src: adarnimrod.python27
+    - src: adarnimrod.gitreceive
+      gitreceive_receiver_script: "{{ lookup('template', 'receiver.sh') }}"
+      gitreceive_public_keys: '{{ pelican_gitreceive_public_keys }}'
diff --git a/molecule.yml b/molecule.yml
index 3b66af535f2b66c90c7b5d27c5d8f33b3055373c..8bf0adaadc6676bf56430c25e4a66f94ab3f0261 100644
--- a/molecule.yml
+++ b/molecule.yml
@@ -19,7 +19,7 @@ vagrant:
   - name: xenial
     box: ubuntu/xenial64
   instances:
-  - name: example
+  - name: pelican-gitreceive
     options:
         append_platform_to_hostname: yes
   raw_config_args:
@@ -30,7 +30,7 @@ vagrant:
 
 docker:
   containers:
-  - name: example-xenial
+  - name: pelican-gitreceive-xenial
     image: ubuntu
     image_version: xenial
     command: /sbin/init
@@ -42,3 +42,22 @@ docker:
     environment:
         DEBIAN_FRONTEND: noninteractive
         container: docker
+  - name: pelican-gitreceive-trusty
+    image: ubuntu-upstart
+    image_version: trusty
+    command: /sbin/init
+    environment:
+        DEBIAN_FRONTEND: noninteractive
+        container: docker
+  - name: pelican-gitreceive-jessie
+    image: debian
+    image_version: jessie
+    command: /sbin/init
+    cap_add:
+      - SYS_ADMIN
+    volume_mounts:
+      - /sys/fs/cgroup:/sys/fs/cgroup
+      - /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
+    environment:
+        DEBIAN_FRONTEND: noninteractive
+        container: docker
diff --git a/tasks/main.yml b/tasks/main.yml
index 6784821deee6cb0db41de18ee53b6e04ce43ea01..bb41a0d09d902c4f3da12e1de83d469d6698d7d9 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,8 +1,25 @@
 ---
-# tasks file for example
-
+# tasks file for pelican-gitreceive
 - name: Assertions
   assert:
     that:
         - ansible_os_family in ['OpenBSD', 'Debian']
-        - ansible_distribution_release in ['6.0', 'xenial']
+        - ansible_distribution_release in ['6.0', 'xenial', 'trusty', 'jessie']
+        - pelican_gitreceive_public_keys is iterable
+        - pelican_gitreceive_output is defined
+
+- name: pip install
+  with_items:
+      - pelican
+      - fabric
+  pip:
+      name: '{{ item }}'
+      state: present
+
+- name: Create directory structure
+  file:
+      path: /var/www/htdocs/www.shore.co.il/blog/
+      owner: git
+      group: git
+      state: directory
+      mode: 0o0755
diff --git a/templates/receiver.sh b/templates/receiver.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a7e9e8fa481958782a90a48d372a5eb3078f6f09
--- /dev/null
+++ b/templates/receiver.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+set -eu
+echo Recieving blog...
+tempdir="$(mktemp -d)"
+cd $tempdir
+tar -xf -
+echo Fetching Git submodules
+git submodule update --init --recursive
+echo Building blog...
+fab  build
+echo Syncing blog...
+rsync -Prv --delete --cvs-exclude output/ {{ pelican_gitreceive_output }}
+echo Cleanup...
+cd -
+rm -r "$tempdir"
+echo Successfully finished...
diff --git a/tests/files/.gitkeep b/tests/files/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/playbook.yml b/tests/playbook.yml
index 740afed352870f6fce7d9fdcf81d0fac95d2f431..57e3a41205448ebe72dd6054ee09ee89c761ea4e 100644
--- a/tests/playbook.yml
+++ b/tests/playbook.yml
@@ -1,12 +1,21 @@
 ---
-- hosts: example-openbsd
+- hosts: pelican-gitreceive-openbsd
   gather_facts: false
   roles: [adarnimrod.openbsd-bootstrap]
 
-- hosts: example-xenial
+- hosts: pelican-gitreceive-xenial
   gather_facts: false
   roles: [adarnimrod.debian-bootstrap]
 
 - hosts: all
+  pre_tasks:
+      - name: Create SSH keypair
+        become: False
+        local_action: command ssh-keygen -t rsa -N '' -f files/id_rsa
+        run_once: True
+        args:
+            creates: files/id_rsa
   roles:
-    - role: example
+    - role: adarnimrod.nginx
+    - role: pelican-gitreceive
+      pelican_gitreceive_public_keys: ['{{ lookup("file", "id_rsa.pub") }}']
diff --git a/tests/requirements.yml b/tests/requirements.yml
index cdc294cd67e8c5b70eed5178580e6edde25e10bb..96b7096f24f3423fd31d6fa6306a5f97446dfa0e 100644
--- a/tests/requirements.yml
+++ b/tests/requirements.yml
@@ -1,3 +1,4 @@
 ---
 - src: adarnimrod.openbsd-bootstrap
 - src: adarnimrod.debian-bootstrap
+- src: adarnimrod.nginx
diff --git a/vars/main.yml b/vars/main.yml
index 7542f3cf45dd754b408bd13b5c57af85bc3d0fc8..c9fd5f1e75efe97de89f76704bfc5df3876ed304 100644
--- a/vars/main.yml
+++ b/vars/main.yml
@@ -1,2 +1,5 @@
 ---
-# vars file for example
+# vars file for pelican-gitreceive
+pelican_gitreceive_www_root:
+    Debian: /var/www
+    OpenBSD: /var/www/htdocs