diff --git a/.gitignore b/.gitignore
index 6d3aa824fcaa94a9c5474334e6bd9c82c6ede267..a08e2c1dd06c663863866131582949a63e49f30e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ site
 .DS_Store
 
 /.envrc
+repos/*
diff --git a/.travis.yml b/.travis.yml
index f2e12fee7a2d10d112b3ed1534aa24a7e5fb45e7..9bdc47a5d2a2106d7a7d50e713faad297182da22 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,25 +1,42 @@
-language: bash
+language: ruby
 dist: trusty
+rvm:
+- 2.4.4
+before_script:
+  - gem install bundler -v 1.16.2
+  - bundle exec rake hatchet:setup_travis
+addons:
+  apt:
+    sources:
+    - heroku
+    packages:
+    - heroku-toolbelt
 jobs:
   include:
-    - stage: "Bash linting (shellcheck)"
-      sudo: false
-      before_install:
-        - wget -c https://goo.gl/ZzKHFv -O - | tar -xvJ -C /tmp/
-        - PATH="/tmp/shellcheck-latest:$PATH"
-      script: make check
-
-    - stage: "Stack Tests"
-      services: docker
-      env: STACK=heroku-18
-      script: ./tests.sh
-
-    - stage: "Stack Tests"
-      services: docker
-      env: STACK=heroku-16
-      script: ./tests.sh
-
-    - stage: "Stack Tests"
-      services: docker
-      env: STACK=cedar-14
-      script: ./tests.sh
+  - stage: Bash linting (shellcheck)
+    sudo: false
+    before_install:
+    - wget -c https://goo.gl/ZzKHFv -O - | tar -xvJ -C /tmp/
+    - PATH="/tmp/shellcheck-latest:$PATH"
+    script: make check
+  - stage: Stack Unit Tests
+    services: docker
+    env: STACK=heroku-18
+    script: "./tests.sh"
+  - stage: Stack Unit Tests
+    services: docker
+    env: STACK=heroku-16
+    script: "./tests.sh"
+  - stage: Stack Unit Tests
+    services: docker
+    env: STACK=cedar-14
+    script: "./tests.sh"
+  - stage: Hatchet Integration
+    script: "bundle exec rspec"
+env:
+  global:
+  - HATCHET_RETRIES=3
+  - IS_RUNNING_ON_CI=true
+  - HATCHET_APP_LIMIT=5
+  - secure: yjtlPE5FbVxTKnjUy/tZUBgSEf4qADD3QOxtgziuid73S0U/1IEXlMGFULsQzIjtlHKmHeywZqpVVEpthIH4RuT7uoX1Pb7SSM/g0T8fT3VoEFbFK1uYl0oZQbUS4Klxv9tPiumj8if3m6ULEGIz1X0wZcMOC0tMLwVCnwmap0E=
+  - secure: ZeFTHWwnpIKE9nAqs88ocmiQh7bKce84lilGm5J23nf3N6V4wNyLwqlkvsM008WGBCaOg9AUx7ZunasT0ANsR5gLP3eV2UUg7ILdRgV2Gy13eNRFheC4PHdN92RqQ3aKoqlIv2K999xlhVjod0NzhkQQXB6PddfQINbuU7ks6As=
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000000000000000000000000000000000000..9b336245f1b63947c5d38bdada2bdd19d2c99c65
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,6 @@
+source "https://rubygems.org"
+
+gem "rspec"
+gem "heroku_hatchet"
+gem "rspec-retry"
+gem "rake"
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000000000000000000000000000000000000..621cd725af7a845fad9b193a293b6ef5bfe78976
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,71 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    activesupport (5.2.1)
+      concurrent-ruby (~> 1.0, >= 1.0.2)
+      i18n (>= 0.7, < 2)
+      minitest (~> 5.1)
+      tzinfo (~> 1.1)
+    concurrent-ruby (1.0.5)
+    diff-lcs (1.3)
+    erubis (2.7.0)
+    excon (0.62.0)
+    heroics (0.0.24)
+      erubis (~> 2.0)
+      excon
+      moneta
+      multi_json (>= 1.9.2)
+    heroku_hatchet (4.0.2)
+      excon (~> 0)
+      minitest-retry (~> 0.1.9)
+      platform-api (~> 2)
+      repl_runner (~> 0.0.3)
+      rrrretry (~> 1)
+      thor (~> 0)
+      threaded (~> 0)
+    i18n (1.1.0)
+      concurrent-ruby (~> 1.0)
+    minitest (5.11.3)
+    minitest-retry (0.1.9)
+      minitest (>= 5.0)
+    moneta (0.8.1)
+    multi_json (1.13.1)
+    platform-api (2.1.0)
+      heroics (~> 0.0.23)
+      moneta (~> 0.8.1)
+    rake (12.3.1)
+    repl_runner (0.0.3)
+      activesupport
+    rrrretry (1.0.0)
+    rspec (3.8.0)
+      rspec-core (~> 3.8.0)
+      rspec-expectations (~> 3.8.0)
+      rspec-mocks (~> 3.8.0)
+    rspec-core (3.8.0)
+      rspec-support (~> 3.8.0)
+    rspec-expectations (3.8.1)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.8.0)
+    rspec-mocks (3.8.0)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.8.0)
+    rspec-retry (0.6.1)
+      rspec-core (> 3.3)
+    rspec-support (3.8.0)
+    thor (0.20.0)
+    thread_safe (0.3.6)
+    threaded (0.0.4)
+    tzinfo (1.2.5)
+      thread_safe (~> 0.1)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  heroku_hatchet
+  rake
+  rspec
+  rspec-retry
+
+BUNDLED WITH
+   1.16.3
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000000000000000000000000000000000000..72c0f9e0365f30e0520d292dab9b54f506f3ea7a
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1 @@
+require 'hatchet/tasks'
\ No newline at end of file
diff --git a/hatchet.json b/hatchet.json
new file mode 100644
index 0000000000000000000000000000000000000000..20ed7dabd8c81ebee2149bef8801ed4f7d186626
--- /dev/null
+++ b/hatchet.json
@@ -0,0 +1,5 @@
+{
+  "python": [
+    "heroku/python-getting-started"
+  ]
+}
diff --git a/hatchet.lock b/hatchet.lock
new file mode 100644
index 0000000000000000000000000000000000000000..1e334cb0d2e70a9746690bcb7b808f000d68cd52
--- /dev/null
+++ b/hatchet.lock
@@ -0,0 +1,3 @@
+---
+- - "./repos/python/python-getting-started"
+  - f56b90499ec11e1c9576da2f8c7331300e189db3
diff --git a/spec/hatchet/python_spec.rb b/spec/hatchet/python_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5ae95ed1b24d51f0d979559f7640ddbe048edeb4
--- /dev/null
+++ b/spec/hatchet/python_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../spec_helper'
+
+describe "Python!!!!!!!!!!!" do
+  it "🐍" do
+    Hatchet::Runner.new('python-getting-started', stack: DEFAULT_STACK).deploy do |app|
+      expect(app.output).to           match(/Installing pip/)
+      expect(app.run('python -V')).to match(/3.6.6/)
+    end
+  end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d8a55da7a3c99c51047a61a1d3fa327949539001
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,23 @@
+ENV['HATCHET_BUILDPACK_BASE'] = 'https://github.com/heroku/heroku-buildpack-python.git'
+
+require 'rspec/core'
+require 'rspec/retry'
+require 'hatchet'
+
+require 'date'
+
+RSpec.configure do |config|
+  config.full_backtrace      = true
+  config.verbose_retry       = true # show retry status in spec process
+  config.default_retry_count = 2 if ENV['IS_RUNNING_ON_CI'] # retry all tests that fail again
+  config.expect_with :rspec do |c|
+    c.syntax = :expect
+  end
+end
+
+if ENV['TRAVIS']
+  # Don't execute tests against "merge" commits
+  exit 0 if ENV['TRAVIS_PULL_REQUEST'] != 'false' && ENV['TRAVIS_BRANCH'] == 'master'
+end
+
+DEFAULT_STACK = 'heroku-16'