rails_template_18f 0.1.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 (99) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.standard.yml +2 -0
  4. data/CHANGELOG.md +6 -0
  5. data/CODE_OF_CONDUCT.md +84 -0
  6. data/Gemfile +10 -0
  7. data/Gemfile.lock +132 -0
  8. data/LICENSE.md +21 -0
  9. data/README.md +140 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +16 -0
  12. data/bin/setup +8 -0
  13. data/lib/generators/rails_template18f/circleci/circleci_generator.rb +116 -0
  14. data/lib/generators/rails_template18f/circleci/templates/Dockerfile.tt +13 -0
  15. data/lib/generators/rails_template18f/circleci/templates/bin/ci-server-start +8 -0
  16. data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +413 -0
  17. data/lib/generators/rails_template18f/circleci/templates/docker-compose.ci.yml +26 -0
  18. data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +137 -0
  19. data/lib/generators/rails_template18f/github_actions/templates/github/actions/run-server/action.yml +28 -0
  20. data/lib/generators/rails_template18f/github_actions/templates/github/actions/setup-languages/action.yml.tt +20 -0
  21. data/lib/generators/rails_template18f/github_actions/templates/github/actions/setup-project/action.yml.tt +33 -0
  22. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/brakeman-analysis.yml +44 -0
  23. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/dependency-scans.yml +39 -0
  24. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml.tt +53 -0
  25. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml.tt +53 -0
  26. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/owasp-daily-scan.yml.tt +44 -0
  27. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/owasp-scan.yml.tt +47 -0
  28. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/pa11y.yml.tt +65 -0
  29. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/rspec.yml.tt +34 -0
  30. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-production.yml +79 -0
  31. data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-staging.yml +79 -0
  32. data/lib/rails_template18f/terraform_options.rb +68 -0
  33. data/lib/rails_template18f/version.rb +5 -0
  34. data/lib/rails_template_18f.rb +13 -0
  35. data/rails-template-18f.gemspec +40 -0
  36. data/railsrc +10 -0
  37. data/railsrc-hotwire +8 -0
  38. data/template.rb +506 -0
  39. data/templates/README.md.tt +213 -0
  40. data/templates/app/assets/images/uswds.js +5 -0
  41. data/templates/app/assets/stylesheets/uswds-settings.scss +7 -0
  42. data/templates/app/views/application/_banner_lock_icon.html.erb +19 -0
  43. data/templates/app/views/application/_demo_site_banner.html.erb +3 -0
  44. data/templates/app/views/application/_header.html.erb +26 -0
  45. data/templates/app/views/application/_usa_banner.html.erb +51 -0
  46. data/templates/bin/owasp-scan +49 -0
  47. data/templates/bin/pa11y-scan +10 -0
  48. data/templates/bin/with-server +35 -0
  49. data/templates/browserslistrc +5 -0
  50. data/templates/config/deployment/production.yml +3 -0
  51. data/templates/config/deployment/staging.yml +3 -0
  52. data/templates/config/environments/ci.rb +10 -0
  53. data/templates/config/environments/staging.rb +6 -0
  54. data/templates/config/locales/en.yml.tt +25 -0
  55. data/templates/config/locales/es.yml +19 -0
  56. data/templates/config/locales/fr.yml +22 -0
  57. data/templates/config/locales/zh.yml +16 -0
  58. data/templates/config/newrelic.yml +65 -0
  59. data/templates/doc/adr/0001-record-architecture-decisions.md.tt +21 -0
  60. data/templates/doc/adr/0002-initial-architecture-decisions.md.tt +24 -0
  61. data/templates/doc/adr/0003-security-scans.md.tt +44 -0
  62. data/templates/doc/adr/0004-rails-csp-compliant-script-tag-helpers.md.tt +53 -0
  63. data/templates/doc/compliance/README.md +37 -0
  64. data/templates/doc/compliance/apps/application.boundary.md.tt +80 -0
  65. data/templates/doc/compliance/apps/data.logical.md +21 -0
  66. data/templates/doc/compliance/rendered/apps/.keep +0 -0
  67. data/templates/editorconfig +5 -0
  68. data/templates/env +10 -0
  69. data/templates/githooks/pre-commit.tt +35 -0
  70. data/templates/lib/tasks/cf.rake +9 -0
  71. data/templates/lib/tasks/scanning.rake +63 -0
  72. data/templates/manifest.yml.tt +19 -0
  73. data/templates/pa11yci +9 -0
  74. data/templates/terraform/README.md.tt +148 -0
  75. data/templates/terraform/bootstrap/import.sh +12 -0
  76. data/templates/terraform/bootstrap/main.tf.tt +25 -0
  77. data/templates/terraform/bootstrap/providers.tf +16 -0
  78. data/templates/terraform/bootstrap/run.sh.tt +12 -0
  79. data/templates/terraform/bootstrap/teardown_creds.sh.tt +5 -0
  80. data/templates/terraform/bootstrap/variables.tf +2 -0
  81. data/templates/terraform/create_space_deployer.sh +33 -0
  82. data/templates/terraform/destroy_space_deployer.sh +19 -0
  83. data/templates/terraform/production/main.tf.tt +50 -0
  84. data/templates/terraform/production/providers.tf.tt +17 -0
  85. data/templates/terraform/production/variables.tf +2 -0
  86. data/templates/terraform/shared/database/main.tf.tt +23 -0
  87. data/templates/terraform/shared/database/providers.tf +16 -0
  88. data/templates/terraform/shared/database/variables.tf +42 -0
  89. data/templates/terraform/shared/domain/main.tf.tt +46 -0
  90. data/templates/terraform/shared/domain/providers.tf +16 -0
  91. data/templates/terraform/shared/domain/variables.tf +47 -0
  92. data/templates/terraform/shared/s3/main.tf +27 -0
  93. data/templates/terraform/shared/s3/providers.tf +16 -0
  94. data/templates/terraform/shared/s3/variables.tf +43 -0
  95. data/templates/terraform/staging/main.tf.tt +30 -0
  96. data/templates/terraform/staging/providers.tf.tt +17 -0
  97. data/templates/terraform/staging/variables.tf +2 -0
  98. data/templates/zap.conf +121 -0
  99. metadata +213 -0
data/railsrc-hotwire ADDED
@@ -0,0 +1,8 @@
1
+ --skip-active-storage
2
+ --skip-action-text
3
+ --skip-action-mailbox
4
+ --skip-test
5
+ --javascript=webpack
6
+ --css=postcss
7
+ --template=template.rb
8
+ --database=postgresql
data/template.rb ADDED
@@ -0,0 +1,506 @@
1
+ require "colorize"
2
+
3
+ ## Supporting methods
4
+ # tell our template to grab all files from the templates directory
5
+ def source_paths
6
+ ["#{__dir__}/templates"]
7
+ end
8
+
9
+ def skip_git?
10
+ !!options[:skip_git]
11
+ end
12
+
13
+ def webpack?
14
+ adjusted_javascript_option == "webpack"
15
+ end
16
+
17
+ def hotwire?
18
+ !options[:skip_hotwire]
19
+ end
20
+
21
+ def cloud_gov_org_tktk?
22
+ @cloud_gov_organization =~ /TKTK/
23
+ end
24
+
25
+ @announcements = Hash.new { |h, k| h[k] = [] }
26
+ def register_announcement(section_name, instructions)
27
+ @announcements[section_name.to_sym] << instructions
28
+ end
29
+
30
+ def print_announcements
31
+ $stdout.puts "\n============= Post-install announcements ============= ".red unless @announcements.none?
32
+ @announcements.each do |section_name, instructions|
33
+ $stdout.puts "\n============= #{section_name} ============= ".yellow
34
+ $stdout.puts instructions.join("\n")
35
+ end
36
+ end
37
+
38
+ unless Gem::Dependency.new("rails", "~> 7.0.0").match?("rails", Rails.gem_version)
39
+ warn "This template requires Rails 7.0.x"
40
+ if Gem::Dependency.new("rails", "~> 6.1.0").match?("rails", Rails.gem_version)
41
+ warn "See the rails-6 branch https://github.com/18f/rails-template/tree/rails-6"
42
+ elsif Gem::Dependency.new("rails", "~> 7.1.0").match?("rails", Rails.gem_version)
43
+ warn "Rails 7.1 is out! Please file an issue so we can get the template updated"
44
+ else
45
+ warn "We didn't recognize the version of Rails you are using: #{Rails.version}"
46
+ end
47
+ exit(1)
48
+ end
49
+
50
+ # ask setup questions
51
+ @terraform = yes?("Create terraform files for cloud.gov services? (y/n)")
52
+ @cloud_gov_organization = ask("What is your cloud.gov organization name? (Leave blank to fill in later)")
53
+ default_staging_space = "staging"
54
+ @cloud_gov_staging_space = ask("What is your cloud.gov staging space name? (Default: #{default_staging_space})")
55
+ default_prod_space = "prod"
56
+ @cloud_gov_production_space = ask("What is your cloud.gov production space name? (Default: #{default_prod_space})")
57
+ @cloud_gov_organization = "TKTK-cloud.gov-org-name" if @cloud_gov_organization.blank?
58
+ @cloud_gov_staging_space = default_staging_space if @cloud_gov_staging_space.blank?
59
+ @cloud_gov_production_space = default_prod_space if @cloud_gov_production_space.blank?
60
+
61
+ @github_actions = yes?("Create Github Actions? (y/n)")
62
+ @circleci_pipeline = yes?("Create CircleCI config? (y/n)")
63
+ @adrs = yes?("Create initial Architecture Decision Records? (y/n)")
64
+ @newrelic = yes?("Create FEDRAMP New Relic config files? (y/n)")
65
+ @dap = yes?("If this will be a public site, should we include Digital Analytics Program code? (y/n)")
66
+ @supported_languages = [:en]
67
+ @supported_languages.push(:es) if yes?("Add Spanish to supported locales, with starter es.yml? (y/n)")
68
+ @supported_languages.push(:fr) if yes?("Add French to supported locales, with starter fr.yml? (y/n)")
69
+ @supported_languages.push(:zh) if yes?("Add Simplified Chinese to supported locales, with starter zh.yml? (y/n)")
70
+
71
+ running_node_version = `node --version`.gsub(/^v/, "").strip
72
+ @node_version = ask("What version of NodeJS are you using? (Default: #{running_node_version})")
73
+ @node_version = running_node_version if @node_version.blank?
74
+
75
+ # copied from Rails' .ruby-version template implementation
76
+ @ruby_version = ENV["RBENV_VERSION"] || ENV["rvm_ruby_string"] || "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}"
77
+
78
+ run_db_setup = yes?("Run db setup steps? (y/n)")
79
+
80
+ ## Start of app customizations
81
+ template "README.md", force: true
82
+ register_announcement("Documentation", <<~EOM)
83
+ * Complete the project README by adding a quick summary of the project in the top section.
84
+ * Review any TBD sections of the README and update where appropriate.
85
+ EOM
86
+
87
+ # setup nvmrc
88
+ file ".nvmrc", @node_version
89
+
90
+ ## Get files from Open Source Policy
91
+ get "https://raw.githubusercontent.com/18F/open-source-policy/master/CONTRIBUTING.md"
92
+ get "https://raw.githubusercontent.com/18F/open-source-policy/master/LICENSE.md"
93
+
94
+ ## setup near-production CI environment
95
+ inside "config" do
96
+ copy_file "environments/ci.rb"
97
+ append_to_file "database.yml", <<~EOM
98
+
99
+ ci:
100
+ <<: *default
101
+ # db will be configured by DATABASE_URL in CI. Use dev db here for ease of local use
102
+ database: #{app_name}_development
103
+ EOM
104
+ end
105
+
106
+ ## setup near-production Staging environment
107
+ inside "config" do
108
+ copy_file "environments/staging.rb"
109
+ append_to_file "database.yml", <<~EOM
110
+
111
+ staging:
112
+ <<: *default
113
+ # db will be configured by DATABASE_URL in a "real" staging env. Use dev db here for ease of local use
114
+ database: #{app_name}_development
115
+ EOM
116
+ end
117
+
118
+ ## add x-config values to standard environment files
119
+ inside "config/environments" do
120
+ insert_into_file "production.rb", "\n config.x.show_demo_banner = false\n", before: /^end$/
121
+ insert_into_file "development.rb", "\n config.x.show_demo_banner = ENV[\"SHOW_DEMO_BANNER\"] == \"true\"\n", before: /^end$/
122
+ insert_into_file "test.rb", "\n config.x.show_demo_banner = false\n", before: /^end$/
123
+ end
124
+
125
+ # setup pa11y and owasp scanning
126
+ directory "bin", mode: :preserve
127
+ copy_file "pa11yci", ".pa11yci"
128
+ copy_file "editorconfig", ".editorconfig"
129
+ copy_file "zap.conf"
130
+ after_bundle do
131
+ run "yarn add --dev pa11y-ci"
132
+ end
133
+
134
+ # updates for OWASP scan to pass
135
+ gem "secure_headers", "~> 6.3"
136
+ initializer "secure_headers.rb", <<~EOM
137
+ SecureHeaders::Configuration.default do |config|
138
+ # CSP settings are handled by Rails
139
+ # see: content_security_policy.rb
140
+ config.csp = SecureHeaders::OPT_OUT
141
+ end
142
+ EOM
143
+ # Replace the default commented out block with our locked-down default
144
+ csp_initializer = "config/initializers/content_security_policy.rb"
145
+ style_policy = if hotwire?
146
+ <<~EOM
147
+ # 'unsafe-inline' is needed because Turbo uses inline CSS for at least the progress bar
148
+ policy.style_src :self, "'unsafe-inline'"
149
+ EOM
150
+ else
151
+ "policy.style_src :self"
152
+ end
153
+
154
+ script_policy = [":self"]
155
+ connect_policy = [":self"]
156
+ image_policy = [":self", ":data"]
157
+
158
+ if @newrelic
159
+ script_policy << '"https://js-agent.newrelic.com"'
160
+ script_policy << '"https://*.nr-data.net"'
161
+ connect_policy << '"https://*.nr-data.net"'
162
+ end
163
+
164
+ if @dap
165
+ image_policy << '"https://www.google-analytics.com"'
166
+ script_policy << '"https://dap.digitalgov.gov"'
167
+ script_policy << '"https://www.google-analytics.com"'
168
+ connect_policy << '"https://dap.digitalgov.gov"'
169
+ connect_policy << '"https://www.google-analytics.com"'
170
+ end
171
+
172
+ gsub_file csp_initializer, /^# config.*\|policy\|$.+^# end$/m, <<EOM
173
+ config.content_security_policy do |policy|
174
+ policy.default_src :self
175
+ policy.font_src :self
176
+ policy.form_action :self
177
+ policy.frame_ancestors :none
178
+ policy.img_src #{image_policy.join(", ")}
179
+ policy.object_src :none
180
+ policy.script_src #{script_policy.join(", ")}
181
+ policy.connect_src #{connect_policy.join(", ")}
182
+ #{style_policy}
183
+ end
184
+ EOM
185
+ # uncommenting the nonce generation lines is needed for any inline js we add
186
+ uncomment_lines csp_initializer, "Rails.application"
187
+ uncomment_lines csp_initializer, /end$/
188
+ uncomment_lines csp_initializer, "content_security_policy_nonce"
189
+
190
+ if @newrelic
191
+ gem "newrelic_rpm", "~> 8.4"
192
+ copy_file "config/newrelic.yml"
193
+
194
+ register_announcement("New Relic", <<~EOM)
195
+ A New Relic config file has been written to `config/newrelic.yml`
196
+
197
+ To get started sending metrics via New Relic APM:
198
+ 1. Replace `<APPNAME>` with what is registered for your application in New Relic
199
+ 2. Add your New Relic license key to the Rails credentials with key `new_relic_key`.
200
+ 3. Comment out the `agent_enabled: false` line
201
+
202
+ To enable browser monitoring:
203
+ 4. Embed the Javascript snippet provided by New Relic into `application.html.erb`.
204
+ It is recommended to vary this based on environment (i.e. include one snippet
205
+ for staging and another for production).
206
+ EOM
207
+ end
208
+
209
+ gem_group :development, :test do
210
+ gem "rspec-rails", "~> 5.1"
211
+ gem "dotenv-rails", "~> 2.7"
212
+ gem "brakeman", "~> 5.2"
213
+ gem "bundler-audit", "~> 0.9"
214
+ gem "standard", "~> 1.7"
215
+ gem "i18n-tasks", "~> 0.9"
216
+ end
217
+ if ENV["RT_DEV"] == "true"
218
+ gem "rails_template_18f", group: :development, path: ENV["PWD"]
219
+ else
220
+ gem "rails_template_18f", group: :development
221
+ end
222
+
223
+ copy_file "lib/tasks/scanning.rake"
224
+ copy_file "env", ".env"
225
+
226
+ unless skip_git?
227
+ rails_command "credentials:diff --enroll"
228
+ template "githooks/pre-commit", ".githooks/pre-commit"
229
+ chmod ".githooks/pre-commit", 0o755
230
+ append_to_file ".gitignore", <<~EOM
231
+
232
+ # Ignore local dotenv overrides
233
+ .env*.local
234
+
235
+ # Ignore OWASP files
236
+ /zap_report.html
237
+ /zap.yaml
238
+
239
+ # Ignore rspec examples status file
240
+ spec/examples.txt
241
+ EOM
242
+ end
243
+
244
+ # Setup translations
245
+ @supported_languages.each do |language|
246
+ template "config/locales/#{language}.yml", force: true
247
+ end
248
+ application "config.i18n.available_locales = #{@supported_languages}"
249
+ application "config.i18n.fallbacks = [:en]"
250
+ after_bundle do
251
+ # Recommended by i18n-tasks
252
+ run "cp $(i18n-tasks gem-path)/templates/config/i18n-tasks.yml config/"
253
+ end
254
+ insert_into_file "app/helpers/application_helper.rb", <<'EOH', before: /^end$/
255
+ def format_active_locale(locale_string)
256
+ link_classes = "usa-nav__link"
257
+ if locale_string.to_sym == I18n.locale
258
+ link_classes = "#{link_classes} usa-current"
259
+ end
260
+ link_to t("shared.languages.#{locale_string}"), root_path(locale: locale_string), class: link_classes
261
+ end
262
+ EOH
263
+
264
+ # setup USWDS
265
+ copy_file "browserslistrc", ".browserslistrc" if webpack?
266
+ uncomment_lines "Gemfile", "sassc-rails" # use sassc-rails for asset minification in prod
267
+ after_bundle do
268
+ js_startup = if webpack?
269
+ "webpack --config webpack.config.js"
270
+ else
271
+ "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds"
272
+ end
273
+ insert_into_file "package.json", <<-EOJSON, before: /^\s+"dependencies"/
274
+ "scripts": {
275
+ "build": "#{js_startup}",
276
+ "build:css": "postcss ./app/assets/stylesheets/application.postcss.css -o ./app/assets/builds/application.css"
277
+ },
278
+ EOJSON
279
+ # Replace postcss-nesting with sass since USWDS uses sass
280
+ run "yarn remove postcss-nesting"
281
+ # include fork of @csstools/postcss-sass until that library is updated for postcss 8
282
+ run "yarn add https://github.com/sinankeskin/postcss-sass"
283
+ run "yarn add postcss-scss"
284
+ insert_into_file "postcss.config.js", " syntax: 'postcss-scss',\n", before: /^\s+plugins/
285
+ gsub_file "postcss.config.js", "postcss-nesting", "@csstools/postcss-sass"
286
+ run "yarn add uswds"
287
+ appjs_file = "app/javascript/application.js"
288
+ append_to_file appjs_file, "\nimport \"uswds\"\n"
289
+ if hotwire?
290
+ append_to_file appjs_file, <<~EOJS
291
+
292
+ // make sure USWDS components are wired to their behavior after a Turbo navigation
293
+ import components from "uswds/src/js/components"
294
+ let initialLoad = true;
295
+ document.addEventListener("turbo:load", () => {
296
+ if (initialLoad) {
297
+ // initial domready is handled by `import "uswds"` code
298
+ initialLoad = false
299
+ return
300
+ }
301
+ const target = document.body
302
+ Object.keys(components).forEach((key) => {
303
+ const behavior = components[key]
304
+ behavior.on(target)
305
+ })
306
+ })
307
+ EOJS
308
+ end
309
+ directory "app/assets"
310
+ append_to_file "app/assets/stylesheets/application.postcss.css", <<~EOCSS
311
+ /* KNOWN ISSUE: only changes to application.postcss.css will trigger an automatic rebuild */
312
+ /* restart your server or run `yarn build:css` when changing other files */
313
+ @import "uswds-settings.scss";
314
+ @import "../../../node_modules/uswds/dist/scss/uswds.scss";
315
+ EOCSS
316
+ gsub_file "app/views/layouts/application.html.erb", "<html>", "<html lang=\"en\">"
317
+ gsub_file "app/views/layouts/application.html.erb", /^\s+<%= yield %>/, <<-EOHTML
318
+ <%= render "application/usa_banner" %>
319
+ <%= render "application/header" %>
320
+ <main id="main-content">
321
+ <div class="grid-container usa-section">
322
+ <%= yield %>
323
+ </div>
324
+ </main>
325
+ EOHTML
326
+ append_to_file "config/initializers/assets.rb", "Rails.application.config.assets.paths << Rails.root.join(\"node_modules\")"
327
+ end
328
+ directory "app/views/application"
329
+
330
+ after_bundle do
331
+ generate "rspec:install"
332
+ gsub_file "spec/spec_helper.rb", /^=(begin|end)$/, ""
333
+
334
+ # Setup the PagesController, locale routes, and home (root) route
335
+ generate :controller, "pages", "home", "--skip-routes", "--no-helper", "--no-assets"
336
+
337
+ if @supported_languages.count > 1
338
+ locale_switching = <<~EOM
339
+ around_action :switch_locale
340
+
341
+ def switch_locale(&action)
342
+ locale = params[:locale] || I18n.default_locale
343
+ I18n.with_locale(locale, &action)
344
+ end
345
+ EOM
346
+ insert_into_file "app/controllers/application_controller.rb", locale_switching, before: /^end/
347
+
348
+ route <<-'EOM'
349
+ scope "(:locale)", locale: /#{I18n.available_locales.join('|')}/ do
350
+ # Your application routes here
351
+ root 'pages#home'
352
+ end
353
+ EOM
354
+ else
355
+ route "root 'pages#home'"
356
+ end
357
+ gsub_file "spec/requests/pages_spec.rb", "/pages/home", "/"
358
+ gsub_file "spec/views/pages/home.html.erb_spec.rb", " pending \"add some examples to (or delete) \#{__FILE__}\"", <<-EOM
359
+ it "displays the gov banner" do
360
+ render template: "pages/home", layout: "layouts/application"
361
+ expect(rendered).to match "An official website of the United States government"
362
+ end
363
+ EOM
364
+
365
+ if run_db_setup
366
+ rails_command "db:create"
367
+ rails_command "db:migrate"
368
+ end
369
+ end
370
+
371
+ # infrastructure & deploy
372
+ template "manifest.yml"
373
+ copy_file "lib/tasks/cf.rake"
374
+ directory "config/deployment"
375
+ after_bundle do
376
+ run "cp .gitignore .cfignore" unless skip_git?
377
+ end
378
+
379
+ if @terraform
380
+ directory "terraform", mode: :preserve
381
+ chmod "terraform/bootstrap/run.sh", 0o755
382
+ chmod "terraform/bootstrap/teardown_creds.sh", 0o755
383
+ unless skip_git?
384
+ append_to_file ".gitignore", <<~EOM
385
+
386
+ # Terraform
387
+ .terraform.lock.hcl
388
+ **/.terraform/*
389
+ secrets.auto.tfvars
390
+ terraform.tfstate
391
+ terraform.tfstate.backup
392
+ EOM
393
+ end
394
+ if cloud_gov_org_tktk?
395
+ register_announcement("Terraform", <<~EOM)
396
+ Fill in the cloud.gov organization information in:
397
+ * terraform/bootstrap/main.tf
398
+ * terraform/staging/main.tf
399
+ * terraform/production/main.tf
400
+ EOM
401
+ end
402
+ register_announcement("Terraform", "Run the bootstrap script and update the appropriate CI/CD environment variables defined in the Deployment section of the README")
403
+ end
404
+
405
+ if @github_actions
406
+ after_bundle do
407
+ generator_arguments = [
408
+ (@terraform ? "--terraform" : "--no-terraform"),
409
+ "--cg-org=#{@cloud_gov_organization}",
410
+ "--cg-staging=#{@cloud_gov_staging_space}",
411
+ "--cg-prod=#{@cloud_gov_production_space}"
412
+ ]
413
+ generate "rails_template18f:github_actions", *generator_arguments
414
+ end
415
+ if cloud_gov_org_tktk?
416
+ register_announcement("Github Actions", <<~EOM)
417
+ * Fill in the cloud.gov organization information in .github/workflows/deploy-staging.yml
418
+ EOM
419
+ end
420
+ register_announcement("Github Actions", <<~EOM)
421
+ * Create environment variable secrets for deploy users as defined in the Deployment section of the README
422
+ EOM
423
+ end
424
+
425
+ if @circleci_pipeline
426
+ after_bundle do
427
+ generator_arguments = [
428
+ (@terraform ? "--terraform" : "--no-terraform"),
429
+ "--cg-org=#{@cloud_gov_organization}",
430
+ "--cg-staging=#{@cloud_gov_staging_space}",
431
+ "--cg-prod=#{@cloud_gov_production_space}"
432
+ ]
433
+ generate "rails_template18f:circleci", *generator_arguments
434
+ end
435
+ register_announcement("CircleCI", <<~EOM)
436
+ * Create project environment variables for deploy users as defined in the Deployment section of the README
437
+ EOM
438
+ end
439
+
440
+ if @adrs
441
+ directory "doc"
442
+ else
443
+ directory "doc/compliance"
444
+ end
445
+ register_announcement("Documentation", <<~EOM)
446
+ * Include a short description of your application in doc/compliance/apps/application.boundary.md
447
+ * Remember to keep your Logical Data Model up to date in doc/compliance/apps/data.logical.md
448
+ EOM
449
+
450
+ if @dap
451
+ after_bundle do
452
+ insert_into_file "app/views/layouts/application.html.erb", <<-EODAP, before: /^\s+<\/head>/
453
+
454
+ <% if Rails.env.production? %>
455
+ <!-- We participate in the US government's analytics program. See the data at analytics.usa.gov. -->
456
+ <%= javascript_include_tag "https://dap.digitalgov.gov/Universal-Federated-Analytics-Min.js?agency=GSA", async: true, id:"_fed_an_ua_tag" %>
457
+ <% end %>
458
+ EODAP
459
+ end
460
+ register_announcement("Digital Analytics Program", "Update the DAP agency code in app/views/layouts/application.html.erb")
461
+ end
462
+
463
+ # setup production credentials file
464
+ require "rails/generators"
465
+ require "rails/generators/rails/encryption_key_file/encryption_key_file_generator"
466
+ require "rails/generators/rails/encrypted_file/encrypted_file_generator"
467
+ key_file_generator = Rails::Generators::EncryptionKeyFileGenerator.new
468
+ key_file_path = Pathname.new "config/credentials/production.key"
469
+ key_file_generator.add_key_file_silently key_file_path
470
+ key_file_generator.ignore_key_file_silently key_file_path
471
+ Rails::Generators::EncryptedFileGenerator.new.add_encrypted_file_silently("config/credentials/production.yml.enc", key_file_path, <<~EOYAML)
472
+ # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
473
+ secret_key_base: #{SecureRandom.hex(64)}
474
+ EOYAML
475
+ register_announcement("Credentials", <<~EOM)
476
+ Two credentials files and keys have been generated:
477
+
478
+ * production
479
+ * config/credentials/production.yml.enc
480
+ * config/credentials/production.key
481
+ * all other environments
482
+ * config/credentials.yml.enc
483
+ * config/master.key
484
+
485
+ The contents of `config/master.key` should be shared with other developers running the application.
486
+ The contents of `config/credentials/production.key` must be limited to those developers who are authorized to have access to production.
487
+ EOM
488
+
489
+ # ensure this is the very last step
490
+ after_bundle do
491
+ # x86_64-linux is required to install gems on any linux system such as cloud.gov or CI pipelines
492
+ run "bundle lock --add-platform x86_64-linux"
493
+
494
+ # bring generated code into compliance with standard ruby: https://github.com/testdouble/standard
495
+ gsub_file "config/environments/production.rb", "(STDOUT)", "($stdout)"
496
+ gsub_file "config/puma.rb", /\) { (\S+) }/, ', \1)'
497
+ run "bundle exec standardrb --fix"
498
+
499
+ unless skip_git?
500
+ git add: "."
501
+ git commit: "-a -m 'Initial commit'"
502
+ end
503
+
504
+ # Post-install announcement
505
+ print_announcements
506
+ end