g5_sibling_deployer_engine 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +6 -0
  6. data/Guardfile +24 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +130 -0
  9. data/Rakefile +2 -0
  10. data/app/controllers/siblings/application_controller.rb +2 -0
  11. data/app/controllers/siblings/deploys_controller.rb +5 -0
  12. data/app/controllers/siblings/instructions_controller.rb +5 -0
  13. data/app/controllers/siblings_controller.rb +14 -0
  14. data/app/controllers/webhooks_controller.rb +6 -0
  15. data/app/models/sibling/deploy.rb +59 -0
  16. data/app/models/sibling/instruction.rb +60 -0
  17. data/app/models/sibling.rb +56 -0
  18. data/app/views/siblings/_nav.html.erb +5 -0
  19. data/app/views/siblings/deploys/index.html.erb +15 -0
  20. data/app/views/siblings/index.html.erb +16 -0
  21. data/app/views/siblings/instructions/index.html.erb +13 -0
  22. data/app/workers/sibling_consumer.rb +15 -0
  23. data/app/workers/sibling_deployer.rb +40 -0
  24. data/app/workers/sibling_instruction_consumer.rb +15 -0
  25. data/config/initializers/github_heroku_deployer.rb +7 -0
  26. data/config/initializers/resque.rb +12 -0
  27. data/config/initializers/table_cloth.rb +3 -0
  28. data/config/routes.rb +12 -0
  29. data/db/migrate/001_create_siblings.rb +14 -0
  30. data/db/migrate/002_create_sibling_deploys.rb +15 -0
  31. data/db/migrate/003_create_sibling_instructions.rb +11 -0
  32. data/g5_sibling_deployer_engine.gemspec +34 -0
  33. data/lib/g5_sibling_deployer_engine/engine.rb +4 -0
  34. data/lib/g5_sibling_deployer_engine/version.rb +3 -0
  35. data/lib/g5_sibling_deployer_engine.rb +12 -0
  36. data/lib/tasks/g5_sibling_deployer_engine_tasks.rake +16 -0
  37. data/lib/tasks/resque.rake +8 -0
  38. data/main_app_v2.html +38 -0
  39. data/spec/controllers/siblings/deploys_controller_spec.rb +12 -0
  40. data/spec/controllers/siblings/instructions_controller_spec.rb +12 -0
  41. data/spec/controllers/siblings_controller_spec.rb +28 -0
  42. data/spec/controllers/webhooks_controller_spec.rb +13 -0
  43. data/spec/dummy/README.rdoc +261 -0
  44. data/spec/dummy/Rakefile +7 -0
  45. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  46. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  47. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  48. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  49. data/spec/dummy/app/mailers/.gitkeep +0 -0
  50. data/spec/dummy/app/models/.gitkeep +0 -0
  51. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  52. data/spec/dummy/config/application.rb +65 -0
  53. data/spec/dummy/config/boot.rb +10 -0
  54. data/spec/dummy/config/database.yml +25 -0
  55. data/spec/dummy/config/environment.rb +5 -0
  56. data/spec/dummy/config/environments/development.rb +37 -0
  57. data/spec/dummy/config/environments/production.rb +67 -0
  58. data/spec/dummy/config/environments/test.rb +37 -0
  59. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  60. data/spec/dummy/config/initializers/inflections.rb +15 -0
  61. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  62. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  63. data/spec/dummy/config/initializers/session_store.rb +8 -0
  64. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  65. data/spec/dummy/config/locales/en.yml +5 -0
  66. data/spec/dummy/config/routes.rb +58 -0
  67. data/spec/dummy/config.ru +4 -0
  68. data/spec/dummy/db/development.sqlite3 +0 -0
  69. data/spec/dummy/db/schema.rb +47 -0
  70. data/spec/dummy/db/test.sqlite3 +0 -0
  71. data/spec/dummy/lib/assets/.gitkeep +0 -0
  72. data/spec/dummy/log/.gitkeep +0 -0
  73. data/spec/dummy/public/404.html +26 -0
  74. data/spec/dummy/public/422.html +26 -0
  75. data/spec/dummy/public/500.html +25 -0
  76. data/spec/dummy/public/favicon.ico +0 -0
  77. data/spec/dummy/script/rails +6 -0
  78. data/spec/lib/g5_sibling_deployer_engine_spec.rb +8 -0
  79. data/spec/models/sibling/deploy_spec.rb +61 -0
  80. data/spec/models/sibling/instruction_spec.rb +63 -0
  81. data/spec/models/sibling_spec.rb +73 -0
  82. data/spec/routing/routes_spec.rb +31 -0
  83. data/spec/spec_helper.rb +42 -0
  84. data/spec/support/g5-configurator-app.html +98 -0
  85. data/spec/support/g5-configurator-entries.html +387 -0
  86. data/spec/support/instructions.html +51 -0
  87. data/spec/support/main_app.html +87 -0
  88. data/spec/workers/sibling_consumer_spec.rb +21 -0
  89. data/spec/workers/sibling_deployer_spec.rb +45 -0
  90. data/spec/workers/sibling_instruction_consumer_spec.rb +15 -0
  91. metadata +352 -0
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Dummy::Application
Binary file
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended to check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(:version => 3) do
15
+
16
+ create_table "sibling_deploys", :force => true do |t|
17
+ t.integer "sibling_id"
18
+ t.integer "instruction_id"
19
+ t.boolean "manual"
20
+ t.string "state"
21
+ t.string "git_repo"
22
+ t.string "heroku_repo"
23
+ t.string "heroku_app_name"
24
+ t.datetime "created_at", :null => false
25
+ t.datetime "updated_at", :null => false
26
+ end
27
+
28
+ create_table "sibling_instructions", :force => true do |t|
29
+ t.string "uid"
30
+ t.string "name"
31
+ t.datetime "published_at"
32
+ t.datetime "created_at", :null => false
33
+ t.datetime "updated_at", :null => false
34
+ end
35
+
36
+ create_table "siblings", :force => true do |t|
37
+ t.string "uid"
38
+ t.string "name"
39
+ t.string "git_repo"
40
+ t.string "heroku_repo"
41
+ t.string "heroku_app_name"
42
+ t.boolean "main_app"
43
+ t.datetime "created_at", :null => false
44
+ t.datetime "updated_at", :null => false
45
+ end
46
+
47
+ end
Binary file
File without changes
File without changes
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/404.html -->
21
+ <div class="dialog">
22
+ <h1>The page you were looking for doesn't exist.</h1>
23
+ <p>You may have mistyped the address or the page may have moved.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/422.html -->
21
+ <div class="dialog">
22
+ <h1>The change you wanted was rejected.</h1>
23
+ <p>Maybe you tried to change something you didn't have access to.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/500.html -->
21
+ <div class="dialog">
22
+ <h1>We're sorry, but something went wrong.</h1>
23
+ </div>
24
+ </body>
25
+ </html>
File without changes
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'g5_sibling_deployer_engine'
3
+
4
+ describe SiblingDeployer do
5
+ it "is a module" do
6
+ SiblingDeployer.should be_a_kind_of Module
7
+ end
8
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sibling::Deploy do
4
+ before :each do
5
+ Resque.stub(:enqueue)
6
+ Sibling.stub(:main_app_uid).and_return("spec/support/g5-configurator-app.html")
7
+ Sibling.consume_main_app_hcard
8
+
9
+ @deploy = Sibling::Deploy.create!(
10
+ sibling_id: Sibling.first.id,
11
+ manual: false,
12
+ git_repo: "git@github",
13
+ heroku_repo: "git@heroku",
14
+ heroku_app_name: "mock"
15
+ )
16
+ end
17
+ subject { @deploy }
18
+
19
+ it { should be_valid }
20
+
21
+ describe "#async_deploy" do
22
+ before :each do
23
+ Resque.stub(:enqueue)
24
+ end
25
+ it "queues deploy" do
26
+ @deploy.stub(:queue!)
27
+ Resque.should_receive(:enqueue).once
28
+ @deploy.async_deploy
29
+ end
30
+ it "changes state to queued" do
31
+ @deploy.update_attributes(state: "new")
32
+ expect { @deploy.async_deploy }.to change(@deploy, :state).to("queued")
33
+ end
34
+ it "does not swallow errors" do
35
+ Resque.stub(:enqueue).and_raise(StandardError.new("Foo"))
36
+ lambda { @deploy.async_deploy }.should raise_error(StandardError, "Foo")
37
+ end
38
+ end
39
+
40
+ describe "#deploy" do
41
+ before :each do
42
+ GithubHerokuDeployer.stub(:deploy)
43
+ GithubHerokuDeployer.stub(:heroku_run)
44
+ end
45
+ it "deploys" do
46
+ GithubHerokuDeployer.should_receive(:deploy)
47
+ @deploy.deploy
48
+ end
49
+ it "migrates" do
50
+ GithubHerokuDeployer.should_receive(:heroku_run)
51
+ @deploy.deploy
52
+ end
53
+ it "changes state to succeeded" do
54
+ expect { @deploy.deploy }.to change(@deploy, :state).to("succeeded")
55
+ end
56
+ it "does not swallow errors" do
57
+ GithubHerokuDeployer.stub(:deploy).and_raise(StandardError.new("Foo"))
58
+ lambda { @deploy.deploy }.should raise_error(StandardError, "Foo")
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sibling::Instruction do
4
+ before :each do
5
+ Resque.stub(:enqueue)
6
+ Sibling.stub(:main_app_uid).and_return("spec/support/g5-configurator-app.html")
7
+ Sibling::Instruction.stub(:feed_url).and_return("spec/support/g5-configurator-entries.html")
8
+ Sibling.consume_main_app_hcard
9
+ Sibling.stub(:main_app_uid).and_return("http://g5-configurator.dev/apps/g5-chd-1-metro-self-storage")
10
+ end
11
+
12
+ describe ".feed" do
13
+ it "returns a Microformats2::Collection" do
14
+ Sibling::Instruction.feed.should be_kind_of Microformats2::Collection
15
+ end
16
+ end
17
+ describe ".consume_feed" do
18
+ it "returns an Array of created ActiveRecord Entries" do
19
+ Sibling::Instruction.consume_feed.first.should be_a_kind_of(Sibling::Instruction)
20
+ end
21
+ it "returns nil if not targeted" do
22
+ Sibling.stub(:main_app_uid).and_return("http://g5-configurator.dev/apps/g5-ch-1-metro-self-storage")
23
+ Sibling::Instruction.consume_feed.first.should be_nil
24
+ end
25
+ it "swallows 304 errors" do
26
+ error = OpenURI::HTTPError.new("304 Not Modified", nil)
27
+ Sibling::Instruction.stub(:find_or_create_from_hentry).and_raise(error)
28
+ Sibling::Instruction.consume_feed.should be_nil
29
+ end
30
+ end
31
+ describe ".async_consume_feed" do
32
+ it "enqueues Sibling::InstructionConsumer" do
33
+ Resque.stub(:enqueue)
34
+ Resque.should_receive(:enqueue).with(SiblingInstructionConsumer)
35
+ Sibling::Instruction.async_consume_feed
36
+ end
37
+ end
38
+ describe ".find_or_create_from_hentry" do
39
+ before do
40
+ @hentry = Sibling::Instruction.feed.entries.second
41
+ @instruction = Sibling::Instruction.instruction(@hentry)
42
+ end
43
+ it "creates an Sibling::Instruction" do
44
+ expect { Sibling::Instruction.find_or_create_from_hentry(@hentry) }.to(
45
+ change(Sibling::Instruction, :count).by(1))
46
+ end
47
+ it "creates a Deploy" do
48
+ expect { Sibling::Instruction.find_or_create_from_hentry(@hentry) }.to(
49
+ change(Sibling::Deploy, :count).by(1))
50
+ end
51
+ end
52
+ describe ".instruction" do
53
+ before do
54
+ @instruction = Sibling::Instruction.instruction(Sibling::Instruction.feed.entries.second)
55
+ end
56
+ it "has a uid" do
57
+ @instruction.uid.to_s.should == "http://g5-configurator.dev/instructions/5"
58
+ end
59
+ it "has a target uid" do
60
+ @instruction.g5_target.format.uid.to_s.should == "http://g5-configurator.dev/apps/g5-chd-1-metro-self-storage"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sibling do
4
+ before do
5
+ Sibling.stub(:main_app_uid).and_return("spec/support/g5-configurator-app.html")
6
+ end
7
+
8
+ describe ".main_app_hcard" do
9
+ it "returns an HCard" do
10
+ Sibling.main_app_hcard.should be_kind_of(HCard)
11
+ end
12
+ end
13
+ describe ".consume_main_app_hcard" do
14
+ it "returns an Array of created Siblings" do
15
+ Sibling.consume_main_app_hcard.first.should be_a_kind_of(Sibling)
16
+ end
17
+ it "returns nil if no Siblings created" do
18
+ Sibling.stub(:main_app_uid).and_return("spec/support/g5-configurator-no-app.html")
19
+ Sibling.consume_main_app_hcard.should be_nil
20
+ end
21
+ it "swallows 304 errors" do
22
+ error = OpenURI::HTTPError.new("304 Not Modified", nil)
23
+ Sibling.stub(:find_or_create_from_hcard).and_raise(error)
24
+ Sibling.consume_main_app_hcard.should be_nil
25
+ end
26
+ end
27
+ describe ".async_consume" do
28
+ it "enqueues SiblingConsumer" do
29
+ Resque.stub(:enqueue)
30
+ Resque.should_receive(:enqueue).with(SiblingConsumer)
31
+ Sibling.async_consume
32
+ end
33
+ end
34
+ describe ".find_or_create_from_hcard" do
35
+ before :each do
36
+ @hcard = Sibling.main_app_hcard.g5_sibling.format
37
+ end
38
+ it "creates Sibling if it does not already exist" do
39
+ expect { Sibling.find_or_create_from_hcard(@hcard) }.to(
40
+ change(Sibling, :count).by(1))
41
+ end
42
+ it "finds Sibling if it already exists" do
43
+ Sibling.find_or_create_from_hcard(@hcard)
44
+ expect { Sibling.find_or_create_from_hcard(@hcard) }.to(
45
+ change(Sibling, :count).by(0))
46
+ end
47
+ end
48
+ describe ".deploy_all" do
49
+ before :each do
50
+ Sibling.consume_main_app_hcard
51
+ Sibling.any_instance.stub(:deploy)
52
+ end
53
+ it "deploys sibling apps" do
54
+ Sibling.any_instance.should_receive(:deploy).exactly(1).times
55
+ Sibling.deploy_all
56
+ end
57
+ end
58
+ describe "#deploy" do
59
+ before :each do
60
+ Sibling::Deploy.any_instance.stub(:async_deploy)
61
+ Sibling.consume_main_app_hcard
62
+ @sibling = Sibling.first
63
+ end
64
+ it "creates a deploy" do
65
+ expect { @sibling.deploy }.to(
66
+ change(Sibling::Deploy, :count).by(1))
67
+ end
68
+ it "creates manual deploys when instruction is not present" do
69
+ expect { @sibling.deploy }.to(
70
+ change(Sibling::Deploy.manual, :count).by(1))
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe "routing" do
4
+ it "routes GET /siblings to siblings#index" do
5
+ expect(get: "/siblings").to route_to(
6
+ controller: "siblings",
7
+ action: "index",
8
+ )
9
+ end
10
+
11
+ it "routes GET /siblings/deploys to siblings/deploys#index" do
12
+ expect(get: "/siblings/deploys").to route_to(
13
+ controller: "siblings/deploys",
14
+ action: "index",
15
+ )
16
+ end
17
+
18
+ it "routes GET /siblings/instructions to siblings/instructions#index" do
19
+ expect(get: "/siblings/instructions").to route_to(
20
+ controller: "siblings/instructions",
21
+ action: "index",
22
+ )
23
+ end
24
+
25
+ it "routes POST /webhooks/g5-configurator to webhooks#g5_configurator" do
26
+ expect(post: "/webhooks/g5-configurator").to route_to(
27
+ controller: "webhooks",
28
+ action: "g5_configurator",
29
+ )
30
+ end
31
+ end
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'spork'
3
+
4
+ Spork.prefork do
5
+ unless ENV['DRB']
6
+ require 'simplecov'
7
+ SimpleCov.start 'rails'
8
+ require "codeclimate-test-reporter"
9
+ CodeClimate::TestReporter.start
10
+ end
11
+
12
+ ENV["RAILS_ENV"] ||= 'test'
13
+ # Load dummy app
14
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
15
+ require 'rspec/rails'
16
+ require 'rspec/autorun'
17
+
18
+ Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
19
+
20
+ RSpec.configure do |config|
21
+ config.use_transactional_fixtures = true
22
+ config.infer_base_class_for_anonymous_controllers = false
23
+ config.order = "random"
24
+ end
25
+
26
+ Spork.trap_method(Rails::Application, :eager_load!)
27
+ # Load dummy app
28
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
29
+ Rails.application.railties.all { |r| r.eager_load! }
30
+
31
+ # Show all of the backtraces
32
+ Rails.backtrace_cleaner.remove_silencers!
33
+ end
34
+
35
+ Spork.each_run do
36
+ if ENV['DRB']
37
+ require 'simplecov'
38
+ SimpleCov.start 'rails'
39
+ require "codeclimate-test-reporter"
40
+ CodeClimate::TestReporter.start
41
+ end
42
+ end
@@ -0,0 +1,98 @@
1
+
2
+ <!DOCTYPE html>
3
+ <html>
4
+ <head>
5
+ <title>G5 Configurator - App</title>
6
+ <link href="/assets/application.css?body=1" media="screen" rel="stylesheet" type="text/css" />
7
+ <script src="/assets/jquery.js?body=1" type="text/javascript"></script>
8
+ <script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
9
+ <script src="/assets/bootstrap-transition.js?body=1" type="text/javascript"></script>
10
+ <script src="/assets/bootstrap-affix.js?body=1" type="text/javascript"></script>
11
+ <script src="/assets/bootstrap-alert.js?body=1" type="text/javascript"></script>
12
+ <script src="/assets/bootstrap-button.js?body=1" type="text/javascript"></script>
13
+ <script src="/assets/bootstrap-carousel.js?body=1" type="text/javascript"></script>
14
+ <script src="/assets/bootstrap-collapse.js?body=1" type="text/javascript"></script>
15
+ <script src="/assets/bootstrap-dropdown.js?body=1" type="text/javascript"></script>
16
+ <script src="/assets/bootstrap-modal.js?body=1" type="text/javascript"></script>
17
+ <script src="/assets/bootstrap-scrollspy.js?body=1" type="text/javascript"></script>
18
+ <script src="/assets/bootstrap-tab.js?body=1" type="text/javascript"></script>
19
+ <script src="/assets/bootstrap-tooltip.js?body=1" type="text/javascript"></script>
20
+ <script src="/assets/bootstrap-popover.js?body=1" type="text/javascript"></script>
21
+ <script src="/assets/bootstrap-typeahead.js?body=1" type="text/javascript"></script>
22
+ <script src="/assets/bootstrap.js?body=1" type="text/javascript"></script>
23
+ <script src="/assets/instructions.js?body=1" type="text/javascript"></script>
24
+ <script src="/assets/application.js?body=1" type="text/javascript"></script>
25
+ <meta content="authenticity_token" name="csrf-param" />
26
+ <meta content="kexQqs7ANQ9OvyQxKxhWHQftuT8nRPmJmeR1LxbxkC4=" name="csrf-token" />
27
+ <meta charset="utf8" />
28
+
29
+ </head>
30
+ <body>
31
+ <div class="container-fluid">
32
+
33
+ <div class="navbar">
34
+ <div class="navbar-inner">
35
+ <div class="container">
36
+
37
+ <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
38
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
39
+ <span class="icon-bar"></span>
40
+ <span class="icon-bar"></span>
41
+ <span class="icon-bar"></span>
42
+ </a>
43
+
44
+ <!-- Be sure to leave the brand out there if you want it shown -->
45
+ <a class="brand" href="/">G5 Configurator</a>
46
+
47
+ <!-- Everything you want hidden at 940px or less, place within here -->
48
+ <div class="nav-collapse">
49
+ <ul class="nav">
50
+ <li class=""><a href="/entries">Entries</a></li>
51
+ <li class=""><a href="/instructions">Instructions</a></li>
52
+ <li class=""><a href="/apps">Apps</a></li>
53
+ <li><a href="/resque" target="_blank">Resque</a></li>
54
+ </ul>
55
+ </div>
56
+
57
+ </div>
58
+ </div>
59
+ </div>
60
+
61
+
62
+ <div class="row-fluid page-header">
63
+ <h1 class="span10">App</h1>
64
+ <span class="span2"><a href="/apps" class="btn">Apps</a></span>
65
+ </div>
66
+
67
+
68
+ <section class="well">
69
+ <div class="h-card">
70
+ <h2 class="p-name">
71
+ <a href="http://g5-configurator.dev/apps/g5-chd-1-metro-self-storage" class="u-uid u-url">g5-chd-1-metro-self-storage</a>
72
+ </h2>
73
+ <p class="p-org h-card">
74
+ <a href="http://g5-hub.dev/clients/g5-c-1-metro-self-storage" class="p-name u-uid u-url">Metro Self Storage</a>
75
+ </p>
76
+ <p>
77
+ <p><a href="git@github.com:g5search/g5-sibling-deployer.git" class="u-g5-git-repo u-url">git@github.com:g5search/g5-sibling-deployer.git</a></p>
78
+ <p><a href="git@heroku.com:g5-chd-1-metro-self-storage.git" class="u-g5-heroku-repo u-url">git@heroku.com:g5-chd-1-metro-self-storage.git</a></p>
79
+ <p><a href="http://g5-chd-1-metro-self-storage.herokuapp.com" class="p-g5-heroku-app-name u-g5-heroku-repo u-url">g5-chd-1-metro-self-storage</a></p>
80
+ <div class="p-g5-sibling h-card">
81
+ <h3>
82
+ sibling of <a href="http://g5-configurator.dev/apps/g5-chd-1-metro-self-storage" class="p-name u-uid u-url">g5-ch-1-metro-self-storage</a>
83
+ </h3>
84
+ <p class="p-org h-card">
85
+ <a href="http://g5-hub.dev/clients/g5-c-1-metro-self-storage" class="p-name u-uid u-url">Metro Self Storage</a>
86
+ </p>
87
+ <p><a href="git@github.com:g5search/g5-content-management-system.git" class="u-g5-git-repo u-url">git@github.com:g5search/g5-content-management-system.git</a></p>
88
+ <p><a href="git@heroku.com:g5-ch-1-metro-self-storage.git" class="u-g5-heroku-repo u-url">git@heroku.com:g5-ch-1-metro-self-storage.git</a></p>
89
+ <p><a href="http://g5-ch-1-metro-self-storage.herokuapp.com" class="p-g5-heroku-app-name u-g5-heroku-repo u-url">g5-ch-1-metro-self-storage</a></p>
90
+ </div>
91
+ </div>
92
+
93
+ </section>
94
+
95
+
96
+ </div>
97
+ </body>
98
+ </html>