diff --git a/README.rst b/README.rst
index 34a183ad58fbe7885dd7b5b86002a93961f7abbe..8a37a318a78cd0df910cfa209342eca1dd9060b4 100644
--- a/README.rst
+++ b/README.rst
@@ -1,9 +1,9 @@
-Example
-#######
+gitreceive
+##########
 
-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/>`_.
+An Ansible to install and configure `gitreceive
+<https://github.com/progrium/gitreceive>`_. Take care to have the receiver
+script capture all of stdin (the git archive tarball).
 
 Requirements
 ------------
diff --git a/defaults/main.yml b/defaults/main.yml
index 25ca86f325b131ae189e74bc108bcc2bc403501e..8b20ac1c3e393d9b6cde96b81f934f274a68873c 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -1,2 +1,7 @@
 ---
-# defaults file for ansible-role-example
+# defaults file for ansible-role-gitreceive
+
+gitreceive_public_keys:
+#    - '{{ lookup("file", "id_rsa.pub" ) }}'
+
+gitreceive_receiver_script: # The contents of the receiver script.
diff --git a/handlers/main.yml b/handlers/main.yml
index 1d74a03c15eb4a405872128a9f81f91ecf354f2e..cd6bdcb019bb16de79a2bc6278e79dbe980cc01d 100644
--- a/handlers/main.yml
+++ b/handlers/main.yml
@@ -1,2 +1,2 @@
 ---
-# handlers file for ansible-role-example
+# handlers file for ansible-role-gitreceive
diff --git a/meta/main.yml b/meta/main.yml
index e22f4e836a3c46a95e906533a0fd5976a885775c..ffa3292ab7ac98515e4e81f95765df7a21534e35 100644
--- a/meta/main.yml
+++ b/meta/main.yml
@@ -1,6 +1,6 @@
 galaxy_info:
   author: Nimrod Adar
-  description: An example Ansible role
+  description: Install and configure gitreceive.
   company: Shore technologies
   license: MIT
   min_ansible_version: 2.0
@@ -8,8 +8,8 @@ galaxy_info:
   - name: OpenBSD
     versions:
     - 5.9
-  galaxy_tags: [ ansible ]
-dependencies:
-    - src: https://www.shore.co.il/git/ansible-role-openbsd-bootstrap
-      scm: git
-      name: bootstrap
+  - name: Debian
+    versions:
+    - jessie
+  galaxy_tags: [ ci, git ]
+dependencies: []
diff --git a/molecule.yml b/molecule.yml
index c92d8059cc617f3750c77c8bd7ea51ffe5453068..d7d1ed7be4d2a0e3eff2d6ce56fe6c038c986204 100644
--- a/molecule.yml
+++ b/molecule.yml
@@ -12,8 +12,10 @@ vagrant:
   platforms:
   - name: openbsd
     box: kaorimatz/openbsd-5.9-amd64
+  - name: debian
+    box: debian/jessie64
   instances:
-  - name: ansible-role-example
+  - name: ansible-role-gitreceive
     options:
         append_platform_to_hostname: yes
   raw_config_args:
diff --git a/tasks/main.yml b/tasks/main.yml
index 066751cb957b869527eef43b28af7dbd81ba96d2..2050beddf1062d708130f29edc16e328d7db7ea1 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,7 +1,71 @@
 ---
-# tasks file for ansible-role-example
+# tasks file for ansible-role-gitreceive
 
 - assert:
     that:
-        - ansible_os_family == 'OpenBSD'
-        - ansible_distribution_release == '5.9'
+        - ansible_os_family in ['Debian', 'OpenBSD']
+
+- name: APT install prequisites
+  when: ansible_pkg_mgr == 'apt'
+  with_items:
+      - bash
+      - apt
+      - git
+      - build-essential
+  apt:
+      name: '{{ item }}'
+      state: present
+      update_cache: yes
+      cache_valid_time: 3600
+
+- name: pkg install prerequisites
+  when: ansible_pkg_mgr == 'openbsd_pkg'
+  with_items:
+      - git
+      - bash
+  openbsd_pkg:
+      name: '{{ item }}'
+      state: present
+
+- name: Symlink /bin/bash -> /usr/local/bin/bash for OpenBSD
+  when: ansible_os_family == 'OpenBSD'
+  file:
+      path: /bin/bash
+      src: /usr/local/bin/bash
+      state: link
+
+- name: git fetch
+  git:
+      dest: /root/gitreceive
+      force: yes
+      update: yes
+      repo: https://github.com/progrium/gitreceive
+      version: master
+  register: gitreceive_fetch
+
+- name: Install
+  when: gitreceive_fetch.changed
+  command: /usr/bin/make
+  args:
+      chdir: /root/gitreceive
+
+- name: Init
+  when: gitreceive_fetch.changed
+  command: /usr/local/bin/gitreceive init
+
+- name: Add public keys
+  with_items: '{{ gitreceive_public_keys }}'
+  authorized_key:
+      key: '{{ item }}'
+      key_options: "{{ gitrecive_key_options | format(item.split()[2], lookup('pipe', 'echo ' + item + ' | ' + gitreceive_generate_fingerprint)) }}"
+      user: git
+      state: present
+
+- name: Copy reciever script
+  when: gitreceive_receiver_script is defined
+  template:
+      src: gitreceive_receiver.j2
+      dest: /home/git/receiver
+      owner: git
+      group: git
+      mode: 0o0750
diff --git a/templates/gitreceive_receiver.j2 b/templates/gitreceive_receiver.j2
new file mode 100644
index 0000000000000000000000000000000000000000..cf9de56f987a4aa3364d6aab5c995d4022f300e3
--- /dev/null
+++ b/templates/gitreceive_receiver.j2
@@ -0,0 +1 @@
+{{ gitreceive_receiver_script }}
diff --git a/tests/files/id_rsa b/tests/files/id_rsa
new file mode 100644
index 0000000000000000000000000000000000000000..4b781c44f1b74a609a6ea29cf07141e2349b22b9
--- /dev/null
+++ b/tests/files/id_rsa
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAoSJcYqXgO8B8L34QtsdGjC0mlF8Ee9avR3M91G6B+ki8PURd
+8iBJCsAUlue+I/ojUbQet2YjMYmRKB6vjRTOSSmc9BujkDKrM2UU+edpnbL7q/N2
+Hyhh/t07zRi1OIDl+08mcBRdPNrR5uk3t3J5iNPD5xqoUt4XftBBjcRU7IEA7vOR
+WljPfYkvdY8VmHaivD61N9LQLbCkXUXlwJRj6GctMSGrwabCQuYbIw4yCvVHdJm9
+bOcdMrbuHd+cfZUHHUWt/YKGMuzNpLprSHt5Miy/XixDdD6CcyZ3s6sG3PNAb+c0
+/S86Q3MFZNNRNGXIQYwHqHcHM4Kp2qOa2Z+I8QIDAQABAoIBAFnctNMbGOuZ1GgU
+ETQt/E0OnRZfyztZJhVd0pyXKIuxZrFwYEg48yM4rgLeqO6dgHb/UaYMIxJsWvSZ
+8GNouAabW3nTtCsl5s5Z0BHymbcl6y8hLr3/om8laEVgQyiI0jmOEayt3rWify8c
+30LCZ78EApvvBPJ6A3ZopDZwyL+/635Mgblu43VK1cLQSJjGBFJDM6Z27JHjLyqV
+mDPrhrIL3K/HwNTIrigi43jqUdNI+1LKa7tszjgiwqUvI+ECWMjCk1hnp86SNC7Z
+GTennRUvrQ/0jg1LUxx8kzvId95LMWgNLBJrPaPlKW4uBPeWB4Pf4LM7g8fZI05U
+IdK9THUCgYEAzQIokPvxYZ17np2rkjuQh6D0wg7Y8iNpSWINb7OOQyHksLo2Ovw7
+38LLfyGQfJJ95cQi1yhTncsd59eNIkV/g9/AARa05oYfJ7wNZGoAE2SxoTPgAzTl
+xQPVeclCvLE73mwzK6sEWnzGU5MDKMH48uGMfLqiDnZfalZ03Scdov8CgYEAyTaG
+9igsJxFIvNqQZbTP/h7xAoltnPNXZRVJA4br7XqdQGCPE9zHv4Wxa+/Mtk6N0bCJ
+SgKXiN4uPRHXKpYQ61ZgvbKw9e5rYvRX03y+ya9w8iOIzZTIS2f9+M6YbPoOMjq9
+LRhCwiPTe2v9D77eusmQb8BoVb1Dq3+QTYKpBA8CgYBCy4Y+Huh5vp7tgj/JiIDB
+wA6fP8kts531W+42y9D5TIy/jBxpQY+ci1JUXLI/9FbyyuHzKl98FRbsWA3S8cPn
+Srq7YBOW3HJANwRCCEt4BiHd/RHq2YxXkbU3VfzZkAGKqcROYQ0tEmRoDIlF+VVM
+hXKJnSF6BtV1xy+SctE0LwKBgEPjgeXL6BnGWyRdGhs2xnaXOfoBJFqwP+x7Igdu
+nmuh0yzFZ4DsHPkhwpsIbamVF4SIa8ns1fP4AuHYAyD7QPomSr22bL6Nku3wQzG4
+BSdHanRISQAUEwBeNfKcwhECzYdlCi8M4HlgXRpndRq666taFsGdyZYkJZDXmXiN
+fTlBAoGBAJ5GPrG5fpTmo1Pcot4MU3iA2L0/auc9qtXDARJpBJdXYF/a3KWGLmvT
++G0PHQ82z1Yn9qIgc4cD3A9FpUnEY8kPagpTHpwLCjGBpx5VPRmIwpGPy6zuP1gQ
+w1GRFfHjaWq16KKomhVFkxBuMKwAs8v1rGXMQ2DZsDXB8GssP6Cu
+-----END RSA PRIVATE KEY-----
diff --git a/tests/files/id_rsa.pub b/tests/files/id_rsa.pub
new file mode 100644
index 0000000000000000000000000000000000000000..a9590de544b5ae7dd4998c99c3c6e0723b97dea4
--- /dev/null
+++ b/tests/files/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQChIlxipeA7wHwvfhC2x0aMLSaUXwR71q9Hcz3UboH6SLw9RF3yIEkKwBSW574j+iNRtB63ZiMxiZEoHq+NFM5JKZz0G6OQMqszZRT552mdsvur83YfKGH+3TvNGLU4gOX7TyZwFF082tHm6Te3cnmI08PnGqhS3hd+0EGNxFTsgQDu85FaWM99iS91jxWYdqK8PrU30tAtsKRdReXAlGPoZy0xIavBpsJC5hsjDjIK9Ud0mb1s5x0ytu4d35x9lQcdRa39goYy7M2kumtIe3kyLL9eLEN0PoJzJnezqwbc80Bv5zT9LzpDcwVk01E0ZchBjAeodwczgqnao5rZn4jx nimrod@nimrod
diff --git a/tests/files/receiver.sh b/tests/files/receiver.sh
new file mode 100644
index 0000000000000000000000000000000000000000..466983c9f9cb47152a37c86c538104faf07dc322
--- /dev/null
+++ b/tests/files/receiver.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+set -eu
+mkdir -p /tmp/gitreceive
+tar -xC /tmp/gitreceive -f -
+echo "OK"
diff --git a/tests/playbook.yml b/tests/playbook.yml
index e739a2b8827a164702a059f09277dd60fa516e36..74f5903a5dcae27b8a0a4c3b1c7b2709c09dcede 100644
--- a/tests/playbook.yml
+++ b/tests/playbook.yml
@@ -1,5 +1,43 @@
 ---
-- hosts: all
+- hosts: ansible-role-gitreceive-openbsd
   gather_facts: false
-  roles:
-    - role: ansible-role-example
+  roles: [ansible-role-openbsd-bootstrap]
+
+- hosts: all
+  vars:
+      gitreceive_public_keys:
+          - '{{ lookup("file", "id_rsa.pub") }}'
+      gitreceive_receiver_script: '{{ lookup("file", "files/receiver.sh") }}'
+  roles: [ansible-role-gitreceive]
+  post_tasks:
+      - name: Create .ssh directory
+        file:
+            path: /root/.ssh
+            owner: root
+            group: 0
+            mode: 0o0700
+            state: directory
+
+      - name: Copy SSH keypair
+        with_items:
+            - id_rsa
+            - id_rsa.pub
+        copy:
+            src: '{{ item }}'
+            dest: '/root/.ssh/{{ item }}'
+            owner: root
+            group: 0
+            mode: 0o0400
+
+      - name: Add localhost host keys to known hosts
+        shell: ssh-keyscan localhost > /root/.ssh/known_hosts
+        args:
+            creates: /root/.ssh/known_hosts
+
+      - name: Add localhost as a git remote
+        command: git remote add test git@localhost:test
+        args:
+            chdir: /root/gitreceive
+        register: gitreceive_add_remote
+        changed_when: gitreceive_add_remote.rc == 0
+        failed_when: gitreceive_add_remote.rc != 0 and not 'already exists' in gitreceive_add_remote.stderr
diff --git a/tests/test_example.py b/tests/test_example.py
deleted file mode 100644
index 9cabf2420fa3923bf417ecdafbe499552ce5c530..0000000000000000000000000000000000000000
--- a/tests/test_example.py
+++ /dev/null
@@ -1,2 +0,0 @@
-def test_example(Command):
-    assert Command('uname').rc == 0
diff --git a/tests/test_gitreceive.py b/tests/test_gitreceive.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9c6f8245e591c6d62e8dc343649ad454a4d4bb7
--- /dev/null
+++ b/tests/test_gitreceive.py
@@ -0,0 +1,8 @@
+def test_gitreceive(Command, Ansible):
+    Command('rm -rf /home/git/test /tmp/gitreceive')
+    push = Command('git -C /root/gitreceive push test master')
+    assert push.rc == 0
+    assert 'OK' in push.stderr
+    second_push = Command('git -C /root/gitreceive push test master')
+    assert second_push.rc == 0
+    assert 'Everything up-to-date' == second_push.stderr
diff --git a/vars/main.yml b/vars/main.yml
index 241750308ae0dc5fd6fc0d21108c47746696d808..8fbc2e13cbe5500788e9742bf74cb33436b74efd 100644
--- a/vars/main.yml
+++ b/vars/main.yml
@@ -1,2 +1,6 @@
 ---
-# vars file for ansible-role-example
+# vars file for ansible-role-gitreceive
+
+# Copied from the gitrecieve script.
+gitreceive_generate_fingerprint: "awk '{print $2}' | base64 -d | md5sum | awk '{print $1}' | sed -e 's/../:&/2g'"
+gitrecive_key_options: 'command="GITUSER=git /usr/local/bin/gitreceive run %s %s",no-agent-forwarding,no-pty,no-user-rc,no-X11-forwarding,no-port-forwarding'