tpt-rails 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +127 -0
  3. data/Rakefile +32 -0
  4. data/app/assets/config/tpt_rails_manifest.js +1 -0
  5. data/app/assets/stylesheets/tpt/rails/application.css +15 -0
  6. data/app/controllers/tpt/rails/application_controller.rb +5 -0
  7. data/app/controllers/tpt/rails/error_tests_controller.rb +21 -0
  8. data/app/controllers/tpt/rails/health_checks_controller.rb +18 -0
  9. data/app/helpers/tpt/rails/application_helper.rb +4 -0
  10. data/app/jobs/tpt/rails/application_job.rb +4 -0
  11. data/app/mailers/tpt/rails/application_mailer.rb +6 -0
  12. data/app/models/tpt/rails/application_record.rb +5 -0
  13. data/app/views/layouts/tpt/rails/application.html.erb +15 -0
  14. data/config/routes.rb +6 -0
  15. data/lib/generators/tpt_rails/configuration/configuration_generator.rb +10 -0
  16. data/lib/generators/tpt_rails/configuration/templates/config/initializers/tpt_rails.rb +10 -0
  17. data/lib/generators/tpt_rails/continuous_integration/continuous_integration_generator.rb +17 -0
  18. data/lib/generators/tpt_rails/continuous_integration/templates/ci/Dockerfile.tt +31 -0
  19. data/lib/generators/tpt_rails/continuous_integration/templates/ci/docker-compose.yaml.tt +26 -0
  20. data/lib/generators/tpt_rails/continuous_integration/templates/ci/tasks/project.test.unit +12 -0
  21. data/lib/generators/tpt_rails/continuous_integration/templates/ci/test.Jenkinsfile.tt +40 -0
  22. data/lib/generators/tpt_rails/continuous_integration/templates/ci/test.config.xml.tt +76 -0
  23. data/lib/generators/tpt_rails/continuous_integration/templates/ci/tptcd.Jenkinsfile.tt +7 -0
  24. data/lib/generators/tpt_rails/continuous_integration/templates/ci/tptci.Jenkinsfile.tt +7 -0
  25. data/lib/generators/tpt_rails/kubernetes/kubernetes_generator.rb +156 -0
  26. data/lib/generators/tpt_rails/kubernetes/templates/Dockerfile.tt +41 -0
  27. data/lib/generators/tpt_rails/kubernetes/templates/entrypoint.sh +13 -0
  28. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/Chart.yaml.tt +16 -0
  29. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/README.md +142 -0
  30. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/requirements.yaml.tt +8 -0
  31. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/templates/NOTES.txt.tt +8 -0
  32. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/templates/_env.yaml +15 -0
  33. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/templates/_helpers.tpl.tt +63 -0
  34. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/templates/autoscaler.yaml.tt +21 -0
  35. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/templates/deployment.yaml.tt +96 -0
  36. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/templates/hooks/db-migrate.yaml.tt +59 -0
  37. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/templates/service.yaml.tt +52 -0
  38. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/values.prod.yaml.tt +52 -0
  39. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/values.staging.yaml.tt +52 -0
  40. data/lib/generators/tpt_rails/kubernetes/templates/kubernetes/helm/values.yaml.tt +171 -0
  41. data/lib/generators/tpt_rails/postman/postman.yaml.tt +2 -0
  42. data/lib/tasks/tpt/rails_tasks.rake +23 -0
  43. data/lib/tpt/rails.rb +65 -0
  44. data/lib/tpt/rails/config.rb +77 -0
  45. data/lib/tpt/rails/engine.rb +7 -0
  46. data/lib/tpt/rails/internal.rb +3 -0
  47. data/lib/tpt/rails/internal/datadog.rb +66 -0
  48. data/lib/tpt/rails/internal/error_reporter.rb +68 -0
  49. data/lib/tpt/rails/internal/health_checks.rb +32 -0
  50. data/lib/tpt/rails/version.rb +5 -0
  51. metadata +153 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 98d683342ba1f15d5e4aa733de08516198e9190c2642c9c50b37ef6c3d0d8821
4
+ data.tar.gz: c640bd28429845a2ccb0b2ef40594f48543e073f334e2787f6f8e13e5bdd9983
5
+ SHA512:
6
+ metadata.gz: f7601dd782766cab7efbd7e96439c1b668b7b371e77c9a53e0f4d796adb2fb4bc0b63306e0af9b540cefa1c1d17600a2a9979e54697b40f7c2bfa1fcb709b347
7
+ data.tar.gz: beceb38da7ec528021393471200330c2a4c59e8759ec64a9914479dc1027521ca1c23c6582bad5fa2d404241bd6f35749dfb43cab904cc2c698fbb234d6ed65b
data/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # Tpt::Rails
2
+
3
+ This library helps integrate Rails projects into TpT infrastructure (e.g. Datadog, Bugsnag, etc).
4
+
5
+ ## Usage
6
+
7
+ ### Adding to your app
8
+
9
+ **NOTE: The [TpT Rails Template](https://github.com/TeachersPayTeachers/rails-template) will
10
+ automatically do the following for you.**
11
+
12
+ ```sh
13
+ bundle add tpt-rails --git 'git@github.com:TeachersPayTeachers/tpt-rails'
14
+ rails generate tpt_rails:configure
15
+ ```
16
+
17
+ ### Configuration
18
+
19
+ Running `rails generate tpt_rails:configure` will generate `config/initializers/tpt_rails.rb`. You
20
+ can configure this gem and enable optional features in that file.
21
+
22
+ See the documentation in [lib/tpt/rails.rb](lib/tpt/rails.rb).
23
+
24
+ For Kubernetes configuration:
25
+ ```sh
26
+ rails generate tpt_rails:kubernetes
27
+ ```
28
+
29
+ For CI/CD configuration:
30
+ ```sh
31
+ rails generate tpt_rails:continuous_integration
32
+ ```
33
+
34
+ ### Overview
35
+
36
+ This gem provides the following features:
37
+
38
+ - Datadog
39
+ - Instruments your app for tracing and provides `Tpt::Rails.statsd` for custom metrics
40
+ - Bugsnag/Rollbar
41
+ - Configures your app to report exceptions and provides `Tpt::Rails.report` for handled errors
42
+ - Health check endpoint
43
+ - Adds a health check at `/internal/health-check`, including built-in DB and Redis health checks
44
+ - Error test endpoint
45
+ - Adds an error test at `/internal/error-test` that reports an error and emits a metric
46
+ - Kubernetes/Helm configuration
47
+ - CI/CD configuration
48
+
49
+ See below for more details.
50
+
51
+ ### Datadog
52
+
53
+ If you configure `datadog_trace_url` then your project will be automatically instrumented.
54
+
55
+ If you configure `datadog_statsd_url` then you can also generate custom metrics:
56
+
57
+ ```ruby
58
+ Tpt::Rails.statsd.increment('foo', tags: ['a:b', 'c:d'])
59
+ ```
60
+
61
+ See the documentation in [lib/tpt/rails.rb](lib/tpt/rails.rb).
62
+
63
+ ### Error reporting (e.g. Bugsnag/Rollbar)
64
+
65
+ If you configure `rollbar_access_token` or `bugsnag_api_key` then your project will be automatically
66
+ configured to report unhandled exceptions.
67
+
68
+ To report handled exceptions:
69
+
70
+ ```ruby
71
+ rescue => e
72
+ Tpt::Rails.report(e)
73
+ ```
74
+
75
+ See the documentation in [lib/tpt/rails.rb](lib/tpt/rails.rb).
76
+
77
+ ### Health check endpoint
78
+
79
+ Tpt::Rails provides the following endpoint:
80
+
81
+ /internal/health-check
82
+
83
+ Two checks are added automatically:
84
+ - An ActiveRecord database check is performed if ActiveRecord is used in the app.
85
+ - A Redis check is performed if Redis is used in the app.
86
+
87
+ You may add more health checks as follows:
88
+ ```ruby
89
+ config.health_check(:foo) { 1 == 1 }
90
+ ```
91
+
92
+ See the documentation for `Tpt::Rails::Config#health_check` in
93
+ [lib/tpt/rails/config.rb](lib/tpt/rails/config.rb) for more details.
94
+
95
+ ### Error test endpoint
96
+
97
+ Tpt::Rails provides the following endpoint:
98
+
99
+ /internal/error-test
100
+
101
+ This endpoint reports an error via `Tpt::Rails.report` and emits a metric to Datadog.
102
+
103
+ ## Developing this Gem
104
+
105
+ ### Running tests
106
+
107
+ 1. Start `docker-compose up` (provides a real Redis instance for tests)
108
+ 2. Run `rails test`
109
+
110
+ ### Using your local version of this gem in a local app
111
+
112
+ Change your Gemfile to:
113
+
114
+ ```ruby
115
+ gem 'tpt-rails', path: '/your/local/path/to/tpt/rails'
116
+ ```
117
+
118
+ ### Publishing a new version of this gem
119
+
120
+ First ensure you have permissions to publish to rubygems.org.
121
+
122
+ Then execute:
123
+ ```sh
124
+ bundle exec gem bump --push --tag --version patch # patch/minor/major/X.X.X
125
+ bundle exec gem release
126
+ ```
127
+
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Tpt::Rails'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/tpt/rails .css
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,5 @@
1
+ module Tpt::Rails
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ require_dependency "tpt/rails/application_controller"
2
+
3
+ class Tpt::Rails::ErrorTestsController < Tpt::Rails::ApplicationController
4
+ def index
5
+ emit_metric
6
+ report_error
7
+ render json: { message: "metric emitted and error reported" }
8
+ end
9
+
10
+ private
11
+
12
+ def emit_metric
13
+ Tpt::Rails.statsd.increment("error_test")
14
+ end
15
+
16
+ def report_error
17
+ raise "just testing"
18
+ rescue => e
19
+ Tpt::Rails.report(e)
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ require_dependency "tpt/rails/application_controller"
2
+
3
+ class Tpt::Rails::HealthChecksController < ApplicationController
4
+ def index
5
+ results = Tpt::Rails.config.health_checks.check
6
+
7
+ healthy = results.values.all?
8
+ code = healthy ? 200 : 500
9
+
10
+ render(
11
+ status: code,
12
+ json: {
13
+ healthy: healthy,
14
+ checks: results,
15
+ },
16
+ )
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ module Tpt::Rails
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Tpt::Rails
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Tpt::Rails
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Tpt::Rails
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Tpt rails</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "tpt/rails/application", media: "all" %>
9
+ </head>
10
+ <body>
11
+
12
+ <%= yield %>
13
+
14
+ </body>
15
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,6 @@
1
+ Tpt::Rails::Engine.routes.draw do
2
+ scope 'internal' do
3
+ get 'health-check', to: 'health_checks#index'
4
+ get 'error-test', to: 'error_tests#index'
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ class Tpt::Rails::ConfigurationGenerator < ::Rails::Generators::Base
2
+ source_root File.expand_path('templates', __dir__)
3
+
4
+ desc 'Configure the app to use tpt-rails shared functionality'
5
+
6
+ def configure
7
+ route "mount Tpt::Rails::Engine => '/'"
8
+ template 'config/initializers/tpt_rails.rb'
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ Tpt::Rails.configure do |config|
2
+ config.app_name = ENV.fetch('APP_NAME')
3
+ config.app_env = ENV.fetch('APP_ENV')
4
+ if ENV['DOGSTATSD_URL'].present?
5
+ config.datadog_statsd_url = ENV.fetch('DOGSTATSD_URL')
6
+ end
7
+ if ENV['DATADOG_TRACE_URL'].present?
8
+ config.datadog_trace_url = ENV.fetch('DATADOG_TRACE_URL')
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ class Tpt::Rails::ContinuousIntegrationGenerator < ::Rails::Generators::Base
2
+ source_root File.expand_path('templates', __dir__)
3
+
4
+ def setup_continuous_integration
5
+ # TODO: should we run tpt cli to generate `test.config.xml`?
6
+ # TODO: ask nathan about the test/tptcd/tptci files
7
+ directory('ci')
8
+
9
+ say(<<~MESSAGE)
10
+ …note about running `tpt ci run protect.test.unit` to run tests
11
+
12
+ You need to ask dev tools to create a credential in jenkins. Example ticket:
13
+ https://teacherspayteachers.atlassian.net/browse/DEVT-710
14
+
15
+ MESSAGE
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ FROM teacherspayteachers/tptci as tptci
2
+ FROM ruby:<%= RUBY_VERSION %>
3
+
4
+ RUN mkdir -p /app
5
+ WORKDIR /app
6
+
7
+ RUN curl -sL https://deb.nodesource.com/setup_12.x | bash \
8
+ && apt-get update && apt-get install -y nodejs && rm -rf /var/lib/apt/lists/* \
9
+ && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
10
+ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
11
+ && apt-get update && apt-get install -y yarn && apt-get install -y netcat && rm -rf /var/lib/apt/lists/*
12
+
13
+ COPY package.json yarn.lock /app/
14
+ RUN yarn install --check-files
15
+
16
+ ENV RAILS_ENV test
17
+ ENV APP_ENV test
18
+ ENV APP_NAME <%= Tpt::Rails.app_name %>
19
+
20
+ # GITHUB_TOKEN allows accessing our private tpt-rails gem on Github
21
+ ARG GITHUB_TOKEN
22
+
23
+ COPY Gemfile /app/Gemfile
24
+ COPY Gemfile.lock /app/Gemfile.lock
25
+ # TODO: Do we need this? Can we move it into a base image?
26
+ RUN gem update bundler
27
+ RUN BUNDLE_GITHUB__COM="${GITHUB_TOKEN}:x-oauth-basic" bundle install
28
+
29
+ COPY . .
30
+
31
+ COPY --from=tptci /usr/bin/tptci /usr/bin/tptci
@@ -0,0 +1,26 @@
1
+ version: '3'
2
+ services:
3
+ db:
4
+ image: mysql:5.7
5
+ ports:
6
+ - '3306:3306'
7
+ environment:
8
+ MYSQL_ROOT_PASSWORD: ''
9
+ MYSQL_ALLOW_EMPTY_PASSWORD: '1'
10
+
11
+ tests:
12
+ build:
13
+ context: ../
14
+ dockerfile: ci/Dockerfile
15
+ args:
16
+ GITHUB_TOKEN: ${GITHUB_TOKEN}
17
+ links:
18
+ - db
19
+ depends_on:
20
+ - db
21
+ environment:
22
+ MYSQL_HOSTNAME: db
23
+ MYSQL_PORT: 3306
24
+ RAILS_LOG_TO_STDOUT: '1'
25
+ DATABASE_URL: 'mysql2://root:@db:3306/<%= Tpt::Rails.app_name %>_test'
26
+ DISABLE_SPRING: '1'
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+
3
+ until nc -z -v ${MYSQL_HOSTNAME} ${MYSQL_PORT}
4
+ do
5
+ echo "Waiting for database connection..."
6
+ sleep 5
7
+ done
8
+
9
+ exec bin/rails db:prepare test
10
+
11
+ # Uncomment to run system tests
12
+ # exec bin/rails test:system
@@ -0,0 +1,40 @@
1
+ @Library('tpt-pipeline-library') _
2
+
3
+ def ci = new tpt.CI(this)
4
+ ci.project = '<%= Tpt::Rails.app_name %>'
5
+
6
+ pipeline {
7
+ agent {
8
+ label 'docker-node'
9
+ }
10
+
11
+ environment {
12
+ GITHUB_TOKEN = credentials('24caddab-590e-467f-a1d2-1c0c1864d628')
13
+ }
14
+
15
+ stages {
16
+ stage('Start') {
17
+ steps {
18
+ startBuild(ci)
19
+ }
20
+ }
21
+
22
+ stage('Build') {
23
+ steps {
24
+ dockerComposeBuild(ci)
25
+ }
26
+ }
27
+
28
+ stage('Unit Test') {
29
+ steps {
30
+ dockerComposeRun(ci, "tests", './ci/tasks/project.test.unit')
31
+ }
32
+ }
33
+ }
34
+
35
+ post {
36
+ always {
37
+ finishBuild(ci, currentBuild.currentResult)
38
+ }
39
+ }
40
+ }