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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.standard.yml +2 -0
- data/CHANGELOG.md +6 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +132 -0
- data/LICENSE.md +21 -0
- data/README.md +140 -0
- data/Rakefile +10 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/lib/generators/rails_template18f/circleci/circleci_generator.rb +116 -0
- data/lib/generators/rails_template18f/circleci/templates/Dockerfile.tt +13 -0
- data/lib/generators/rails_template18f/circleci/templates/bin/ci-server-start +8 -0
- data/lib/generators/rails_template18f/circleci/templates/circleci/config.yml.tt +413 -0
- data/lib/generators/rails_template18f/circleci/templates/docker-compose.ci.yml +26 -0
- data/lib/generators/rails_template18f/github_actions/github_actions_generator.rb +137 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/actions/run-server/action.yml +28 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/actions/setup-languages/action.yml.tt +20 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/actions/setup-project/action.yml.tt +33 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/brakeman-analysis.yml +44 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/dependency-scans.yml +39 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-production.yml.tt +53 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/deploy-staging.yml.tt +53 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/owasp-daily-scan.yml.tt +44 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/owasp-scan.yml.tt +47 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/pa11y.yml.tt +65 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/rspec.yml.tt +34 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-production.yml +79 -0
- data/lib/generators/rails_template18f/github_actions/templates/github/workflows/terraform-staging.yml +79 -0
- data/lib/rails_template18f/terraform_options.rb +68 -0
- data/lib/rails_template18f/version.rb +5 -0
- data/lib/rails_template_18f.rb +13 -0
- data/rails-template-18f.gemspec +40 -0
- data/railsrc +10 -0
- data/railsrc-hotwire +8 -0
- data/template.rb +506 -0
- data/templates/README.md.tt +213 -0
- data/templates/app/assets/images/uswds.js +5 -0
- data/templates/app/assets/stylesheets/uswds-settings.scss +7 -0
- data/templates/app/views/application/_banner_lock_icon.html.erb +19 -0
- data/templates/app/views/application/_demo_site_banner.html.erb +3 -0
- data/templates/app/views/application/_header.html.erb +26 -0
- data/templates/app/views/application/_usa_banner.html.erb +51 -0
- data/templates/bin/owasp-scan +49 -0
- data/templates/bin/pa11y-scan +10 -0
- data/templates/bin/with-server +35 -0
- data/templates/browserslistrc +5 -0
- data/templates/config/deployment/production.yml +3 -0
- data/templates/config/deployment/staging.yml +3 -0
- data/templates/config/environments/ci.rb +10 -0
- data/templates/config/environments/staging.rb +6 -0
- data/templates/config/locales/en.yml.tt +25 -0
- data/templates/config/locales/es.yml +19 -0
- data/templates/config/locales/fr.yml +22 -0
- data/templates/config/locales/zh.yml +16 -0
- data/templates/config/newrelic.yml +65 -0
- data/templates/doc/adr/0001-record-architecture-decisions.md.tt +21 -0
- data/templates/doc/adr/0002-initial-architecture-decisions.md.tt +24 -0
- data/templates/doc/adr/0003-security-scans.md.tt +44 -0
- data/templates/doc/adr/0004-rails-csp-compliant-script-tag-helpers.md.tt +53 -0
- data/templates/doc/compliance/README.md +37 -0
- data/templates/doc/compliance/apps/application.boundary.md.tt +80 -0
- data/templates/doc/compliance/apps/data.logical.md +21 -0
- data/templates/doc/compliance/rendered/apps/.keep +0 -0
- data/templates/editorconfig +5 -0
- data/templates/env +10 -0
- data/templates/githooks/pre-commit.tt +35 -0
- data/templates/lib/tasks/cf.rake +9 -0
- data/templates/lib/tasks/scanning.rake +63 -0
- data/templates/manifest.yml.tt +19 -0
- data/templates/pa11yci +9 -0
- data/templates/terraform/README.md.tt +148 -0
- data/templates/terraform/bootstrap/import.sh +12 -0
- data/templates/terraform/bootstrap/main.tf.tt +25 -0
- data/templates/terraform/bootstrap/providers.tf +16 -0
- data/templates/terraform/bootstrap/run.sh.tt +12 -0
- data/templates/terraform/bootstrap/teardown_creds.sh.tt +5 -0
- data/templates/terraform/bootstrap/variables.tf +2 -0
- data/templates/terraform/create_space_deployer.sh +33 -0
- data/templates/terraform/destroy_space_deployer.sh +19 -0
- data/templates/terraform/production/main.tf.tt +50 -0
- data/templates/terraform/production/providers.tf.tt +17 -0
- data/templates/terraform/production/variables.tf +2 -0
- data/templates/terraform/shared/database/main.tf.tt +23 -0
- data/templates/terraform/shared/database/providers.tf +16 -0
- data/templates/terraform/shared/database/variables.tf +42 -0
- data/templates/terraform/shared/domain/main.tf.tt +46 -0
- data/templates/terraform/shared/domain/providers.tf +16 -0
- data/templates/terraform/shared/domain/variables.tf +47 -0
- data/templates/terraform/shared/s3/main.tf +27 -0
- data/templates/terraform/shared/s3/providers.tf +16 -0
- data/templates/terraform/shared/s3/variables.tf +43 -0
- data/templates/terraform/staging/main.tf.tt +30 -0
- data/templates/terraform/staging/providers.tf.tt +17 -0
- data/templates/terraform/staging/variables.tf +2 -0
- data/templates/zap.conf +121 -0
- metadata +213 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
version: 2.1
|
|
2
|
+
|
|
3
|
+
orbs:
|
|
4
|
+
ruby: circleci/ruby@1.3.0
|
|
5
|
+
node: circleci/node@5.0.0
|
|
6
|
+
browser-tools: circleci/browser-tools@1.2.3<% if terraform? %>
|
|
7
|
+
terraform: circleci/terraform@3.0.0<% end %>
|
|
8
|
+
|
|
9
|
+
commands:
|
|
10
|
+
setup-project:
|
|
11
|
+
steps:
|
|
12
|
+
- checkout
|
|
13
|
+
- ruby/install-deps
|
|
14
|
+
- node/install:
|
|
15
|
+
install-yarn: true
|
|
16
|
+
- node/install-packages:
|
|
17
|
+
cache-only-lockfile: false
|
|
18
|
+
pkg-manager: yarn
|
|
19
|
+
cg-deploy:
|
|
20
|
+
description: "Login to cloud foundry space with service account credentials
|
|
21
|
+
and push application using deployment configuration file."
|
|
22
|
+
parameters:
|
|
23
|
+
cloudgov_username:
|
|
24
|
+
description: "Name of CircleCI project environment variable that
|
|
25
|
+
holdes deployer username for cloudgov space"
|
|
26
|
+
type: env_var_name
|
|
27
|
+
cloudgov_password:
|
|
28
|
+
description: "Name of CircleCI project environment variable that
|
|
29
|
+
holds deployer password for cloudgov space"
|
|
30
|
+
type: env_var_name
|
|
31
|
+
cloudgov_org:
|
|
32
|
+
description: "cloud.gov organization name"
|
|
33
|
+
type: string
|
|
34
|
+
cloudgov_space:
|
|
35
|
+
description: "cloud.gov space name"
|
|
36
|
+
type: string
|
|
37
|
+
deploy_config_file:
|
|
38
|
+
description: "Path to deployment configuration file"
|
|
39
|
+
type: string
|
|
40
|
+
rails_master_key:
|
|
41
|
+
description: "Name of CircleCI project environment variable holding the RAILS_MASTER_KEY"
|
|
42
|
+
type: env_var_name
|
|
43
|
+
steps:
|
|
44
|
+
- run:
|
|
45
|
+
name: Vendor gems
|
|
46
|
+
command: bundle cache --all
|
|
47
|
+
- run:
|
|
48
|
+
name: Install Cloud Foundry CLI
|
|
49
|
+
command: |
|
|
50
|
+
curl -v -L -o cf-cli_amd64.deb 'https://packages.cloudfoundry.org/stable?release=debian64&version=v7&source=github'
|
|
51
|
+
sudo dpkg -i cf-cli_amd64.deb
|
|
52
|
+
- run:
|
|
53
|
+
name: Login with service account
|
|
54
|
+
command: |
|
|
55
|
+
cf login -a api.fr.cloud.gov \
|
|
56
|
+
-u ${<< parameters.cloudgov_username >>} \
|
|
57
|
+
-p ${<< parameters.cloudgov_password >>} \
|
|
58
|
+
-o << parameters.cloudgov_org >> \
|
|
59
|
+
-s << parameters.cloudgov_space >>
|
|
60
|
+
- run:
|
|
61
|
+
name: Push application with deployment vars
|
|
62
|
+
command: |
|
|
63
|
+
cf push --strategy rolling \
|
|
64
|
+
--vars-file << parameters.deploy_config_file >> \
|
|
65
|
+
--var rails_master_key=${<< parameters.rails_master_key >>}
|
|
66
|
+
|
|
67
|
+
jobs:
|
|
68
|
+
build:
|
|
69
|
+
docker:
|
|
70
|
+
- image: cimg/ruby:<%= ruby_version %>
|
|
71
|
+
steps:
|
|
72
|
+
- setup-project
|
|
73
|
+
|
|
74
|
+
test:
|
|
75
|
+
parallelism: 3
|
|
76
|
+
docker:
|
|
77
|
+
- image: cimg/ruby:<%= ruby_version %>
|
|
78
|
+
- image: cimg/postgres:12.9
|
|
79
|
+
environment:
|
|
80
|
+
POSTGRES_USER: circleci
|
|
81
|
+
POSTGRES_DB: <%= app_name %>_test
|
|
82
|
+
POSTGRES_PASSWORD: ""
|
|
83
|
+
environment:
|
|
84
|
+
BUNDLE_JOBS: "3"
|
|
85
|
+
BUNDLE_RETRY: "3"
|
|
86
|
+
PGHOST: 127.0.0.1
|
|
87
|
+
PGUSER: circleci
|
|
88
|
+
PGPASSWORD: ""
|
|
89
|
+
RAILS_ENV: test
|
|
90
|
+
steps:
|
|
91
|
+
- setup-project
|
|
92
|
+
- browser-tools/install-chrome
|
|
93
|
+
- browser-tools/install-chromedriver
|
|
94
|
+
- run:
|
|
95
|
+
name: Wait for DB
|
|
96
|
+
command: dockerize -wait tcp://localhost:5432 -timeout 1m
|
|
97
|
+
- run:
|
|
98
|
+
name: Database setup
|
|
99
|
+
command: bundle exec rails db:schema:load --trace
|
|
100
|
+
|
|
101
|
+
# Precompile assets
|
|
102
|
+
# Load assets from cache if possible, precompile assets then save cache
|
|
103
|
+
# Multiple caches are used to increase the chance of a cache hit
|
|
104
|
+
# https://circleci.com/docs/2.0/caching/#full-example-of-saving-and-restoring-cache
|
|
105
|
+
- restore_cache:
|
|
106
|
+
keys:
|
|
107
|
+
- asset-cache-v1-{{ .Environment.RAILS_ENV }}-{{ arch }}-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
|
|
108
|
+
- asset-cache-v1-{{ .Environment.RAILS_ENV }}-{{ arch }}-{{ .Branch }}
|
|
109
|
+
- asset-cache-v1-{{ .Environment.RAILS_ENV }}
|
|
110
|
+
|
|
111
|
+
- run: bundle exec rake assets:precompile
|
|
112
|
+
|
|
113
|
+
- save_cache:
|
|
114
|
+
key: asset-cache-v1-{{ .Environment.RAILS_ENV }}-{{ arch }}-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
|
|
115
|
+
paths:
|
|
116
|
+
- public/assets
|
|
117
|
+
- tmp/cache/assets/sprockets
|
|
118
|
+
|
|
119
|
+
- ruby/rspec-test
|
|
120
|
+
|
|
121
|
+
static_security_scans:
|
|
122
|
+
docker:
|
|
123
|
+
- image: cimg/ruby:<%= ruby_version %>
|
|
124
|
+
steps:
|
|
125
|
+
- setup-project
|
|
126
|
+
- run:
|
|
127
|
+
name: Run Brakeman scan
|
|
128
|
+
command: bundle exec brakeman
|
|
129
|
+
- run:
|
|
130
|
+
name: Bundle audit
|
|
131
|
+
command: bundle exec rake bundler:audit
|
|
132
|
+
- run:
|
|
133
|
+
name: Yarn audit
|
|
134
|
+
command: bundle exec rake yarn:audit
|
|
135
|
+
|
|
136
|
+
owasp_scan:
|
|
137
|
+
machine:
|
|
138
|
+
image: ubuntu-2004:202111-02
|
|
139
|
+
steps:
|
|
140
|
+
- checkout
|
|
141
|
+
|
|
142
|
+
# attempt to restore cache from build step to speed up local server startup time
|
|
143
|
+
# This will need to be updated if the cache key for the `install-(deps|packages)` steps changes
|
|
144
|
+
- restore_cache:
|
|
145
|
+
keys:
|
|
146
|
+
- gems-v1-{{ checksum "Gemfile.lock" }}-{{ .Branch }}
|
|
147
|
+
- restore_cache:
|
|
148
|
+
keys:
|
|
149
|
+
- node-deps-{{ arch }}-v1-{{ .Branch }}-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
|
|
150
|
+
|
|
151
|
+
- run:
|
|
152
|
+
name: Start up local server
|
|
153
|
+
command: docker-compose -f docker-compose.ci.yml up -d
|
|
154
|
+
- run:
|
|
155
|
+
name: Create reports directory
|
|
156
|
+
command: mkdir reports
|
|
157
|
+
- run:
|
|
158
|
+
name: Run OWASP Zap
|
|
159
|
+
command: |
|
|
160
|
+
docker run -v $(pwd)/zap.conf:/zap/wrk/zap.conf:ro -v $(pwd)/reports:/zap/wrk:rw --rm \
|
|
161
|
+
--user zap:$(id -g) --network="project_ci_network" -t owasp/zap2docker-weekly \
|
|
162
|
+
zap-baseline.py -t http://web:3000 -c zap.conf -I -i -r owasp_report.html
|
|
163
|
+
- store_artifacts:
|
|
164
|
+
path: reports/owasp_report.html
|
|
165
|
+
|
|
166
|
+
owasp_full_scan:
|
|
167
|
+
machine:
|
|
168
|
+
image: ubuntu-2004:202111-02
|
|
169
|
+
steps:
|
|
170
|
+
- checkout
|
|
171
|
+
|
|
172
|
+
# attempt to restore cache from build step to speed up local server startup time
|
|
173
|
+
# This will need to be updated if the cache key for the `install-(deps|packages)` steps changes
|
|
174
|
+
- restore_cache:
|
|
175
|
+
keys:
|
|
176
|
+
- gems-v1-{{ checksum "Gemfile.lock" }}-{{ .Branch }}
|
|
177
|
+
- restore_cache:
|
|
178
|
+
keys:
|
|
179
|
+
- node-deps-{{ arch }}-v1-{{ .Branch }}-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
|
|
180
|
+
|
|
181
|
+
- run:
|
|
182
|
+
name: Start up local server
|
|
183
|
+
command: docker-compose -f docker-compose.ci.yml up -d
|
|
184
|
+
- run:
|
|
185
|
+
name: Create reports directory
|
|
186
|
+
command: mkdir reports
|
|
187
|
+
- run:
|
|
188
|
+
name: Run OWASP Zap
|
|
189
|
+
command: |
|
|
190
|
+
docker run -v $(pwd)/zap.conf:/zap/wrk/zap.conf:ro -v $(pwd)/reports:/zap/wrk:rw --rm \
|
|
191
|
+
--user zap:$(id -g) --network="project_ci_network" -t owasp/zap2docker-weekly \
|
|
192
|
+
zap-full-scan.py -t http://web:3000 -c zap.conf -I -i -r owasp_report.html
|
|
193
|
+
- store_artifacts:
|
|
194
|
+
path: reports/owasp_report.html
|
|
195
|
+
|
|
196
|
+
a11y_scan:
|
|
197
|
+
docker:
|
|
198
|
+
- image: cimg/ruby:<%= ruby_version %>
|
|
199
|
+
- image: cimg/postgres:12.9
|
|
200
|
+
environment:
|
|
201
|
+
POSTGRES_USER: circleci
|
|
202
|
+
POSTGRES_DB: <%= app_name %>_development
|
|
203
|
+
POSTGRES_PASSWORD: ""
|
|
204
|
+
environment:
|
|
205
|
+
BUNDLE_JOBS: "3"
|
|
206
|
+
BUNDLE_RETRY: "3"
|
|
207
|
+
PGHOST: 127.0.0.1
|
|
208
|
+
PGUSER: circleci
|
|
209
|
+
PGPASSWORD: ""
|
|
210
|
+
RAILS_ENV: ci
|
|
211
|
+
steps:
|
|
212
|
+
- setup-project
|
|
213
|
+
- browser-tools/install-chrome
|
|
214
|
+
- browser-tools/install-chromedriver
|
|
215
|
+
- run:
|
|
216
|
+
name: Wait for DB
|
|
217
|
+
command: dockerize -wait tcp://localhost:5432 -timeout 1m
|
|
218
|
+
- run:
|
|
219
|
+
name: Database setup
|
|
220
|
+
command: bundle exec rails db:schema:load --trace
|
|
221
|
+
|
|
222
|
+
# Precompile assets
|
|
223
|
+
# Load assets from cache if possible, precompile assets then save cache
|
|
224
|
+
# Multiple caches are used to increase the chance of a cache hit
|
|
225
|
+
# https://circleci.com/docs/2.0/caching/#full-example-of-saving-and-restoring-cache
|
|
226
|
+
- restore_cache:
|
|
227
|
+
keys:
|
|
228
|
+
- asset-cache-v1-{{ .Environment.RAILS_ENV }}-{{ arch }}-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
|
|
229
|
+
- asset-cache-v1-{{ .Environment.RAILS_ENV }}-{{ arch }}-{{ .Branch }}
|
|
230
|
+
- asset-cache-v1-{{ .Environment.RAILS_ENV }}
|
|
231
|
+
|
|
232
|
+
- run: bundle exec rake assets:precompile
|
|
233
|
+
|
|
234
|
+
- save_cache:
|
|
235
|
+
key: asset-cache-v1-{{ .Environment.RAILS_ENV }}-{{ arch }}-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
|
|
236
|
+
paths:
|
|
237
|
+
- public/assets
|
|
238
|
+
- tmp/cache/assets/sprockets
|
|
239
|
+
|
|
240
|
+
- run:
|
|
241
|
+
name: Start server
|
|
242
|
+
command: ./bin/rails server -p 3000
|
|
243
|
+
background: true
|
|
244
|
+
|
|
245
|
+
- run:
|
|
246
|
+
name: Wait for server
|
|
247
|
+
command: dockerize -wait http://localhost:3000 -timeout 1m
|
|
248
|
+
|
|
249
|
+
- run:
|
|
250
|
+
name: Run pa11y-ci
|
|
251
|
+
command: yarn run pa11y-ci
|
|
252
|
+
<% if terraform? %>
|
|
253
|
+
terraform_plan_staging:
|
|
254
|
+
executor: terraform/default
|
|
255
|
+
steps:
|
|
256
|
+
- checkout
|
|
257
|
+
- terraform/init:
|
|
258
|
+
path: terraform/staging
|
|
259
|
+
- terraform/validate:
|
|
260
|
+
path: terraform/staging
|
|
261
|
+
- terraform/fmt:
|
|
262
|
+
path: terraform/staging
|
|
263
|
+
- run:
|
|
264
|
+
name: Set terraform variables
|
|
265
|
+
working_directory: terraform/staging
|
|
266
|
+
command: echo -e "cf_user = \"$CF_STAGING_USERNAME\"\ncf_password = \"$CF_STAGING_PASSWORD\"" > secrets.auto.tfvars
|
|
267
|
+
- terraform/plan:
|
|
268
|
+
path: terraform/staging
|
|
269
|
+
- persist_to_workspace:
|
|
270
|
+
root: .
|
|
271
|
+
paths:
|
|
272
|
+
- ./terraform/staging
|
|
273
|
+
terraform_apply_staging:
|
|
274
|
+
executor: terraform/default
|
|
275
|
+
steps:
|
|
276
|
+
- checkout
|
|
277
|
+
- attach_workspace:
|
|
278
|
+
at: .
|
|
279
|
+
- terraform/apply
|
|
280
|
+
path: terraform/staging
|
|
281
|
+
terraform_plan_production:
|
|
282
|
+
executor: terraform/default
|
|
283
|
+
steps:
|
|
284
|
+
- checkout
|
|
285
|
+
- terraform/init:
|
|
286
|
+
path: terraform/production
|
|
287
|
+
- terraform/validate:
|
|
288
|
+
path: terraform/production
|
|
289
|
+
- terraform/fmt:
|
|
290
|
+
path: terraform/production
|
|
291
|
+
- run:
|
|
292
|
+
name: Set terraform variables
|
|
293
|
+
working_directory: terraform/production
|
|
294
|
+
command: echo -e "cf_user = \"$CF_PRODUCTION_USERNAME\"\ncf_password = \"$CF_PRODUCTION_PASSWORD\"" > secrets.auto.tfvars
|
|
295
|
+
- terraform/plan:
|
|
296
|
+
path: terraform/production
|
|
297
|
+
- persist_to_workspace:
|
|
298
|
+
root: .
|
|
299
|
+
paths:
|
|
300
|
+
- ./terraform/production
|
|
301
|
+
terraform_apply_production:
|
|
302
|
+
executor: terraform/default
|
|
303
|
+
steps:
|
|
304
|
+
- checkout
|
|
305
|
+
- attach_workspace:
|
|
306
|
+
at: .
|
|
307
|
+
- terraform/apply
|
|
308
|
+
path: terraform/production
|
|
309
|
+
<% end %>
|
|
310
|
+
deploy_staging:
|
|
311
|
+
docker:
|
|
312
|
+
- image: cimg/ruby:<%= ruby_version %>
|
|
313
|
+
steps:
|
|
314
|
+
- setup-project
|
|
315
|
+
- cg-deploy:
|
|
316
|
+
cloudgov_username: CF_STAGING_USERNAME
|
|
317
|
+
cloudgov_password: CF_STAGING_PASSWORD
|
|
318
|
+
cloudgov_org: <%= cloud_gov_organization %>
|
|
319
|
+
cloudgov_space: <%= cloud_gov_staging_space %>
|
|
320
|
+
deploy_config_file: config/deployment/staging.yml
|
|
321
|
+
rails_master_key: RAILS_MASTER_KEY
|
|
322
|
+
deploy_production:
|
|
323
|
+
docker:
|
|
324
|
+
- image: cimg/ruby:<%= ruby_version %>
|
|
325
|
+
steps:
|
|
326
|
+
- setup-project
|
|
327
|
+
- cg-deploy:
|
|
328
|
+
cloudgov_username: CF_PRODUCTION_USERNAME
|
|
329
|
+
cloudgov_password: CF_PRODUCTION_PASSWORD
|
|
330
|
+
cloudgov_org: <%= cloud_gov_organization %>
|
|
331
|
+
cloudgov_space: <%= cloud_gov_production_space %>
|
|
332
|
+
deploy_config_file: config/deployment/production.yml
|
|
333
|
+
rails_master_key: PRODUCTION_RAILS_MASTER_KEY
|
|
334
|
+
|
|
335
|
+
workflows:
|
|
336
|
+
version: 2.1
|
|
337
|
+
build_and_test:
|
|
338
|
+
jobs:
|
|
339
|
+
- build
|
|
340
|
+
- test:
|
|
341
|
+
requires:
|
|
342
|
+
- build
|
|
343
|
+
- static_security_scans:
|
|
344
|
+
requires:
|
|
345
|
+
- build
|
|
346
|
+
- owasp_scan:
|
|
347
|
+
requires:
|
|
348
|
+
- build
|
|
349
|
+
- a11y_scan:
|
|
350
|
+
requires:
|
|
351
|
+
- build<% if terraform? %>
|
|
352
|
+
- terraform_plan_staging:
|
|
353
|
+
filters:
|
|
354
|
+
branches:
|
|
355
|
+
ignore: production
|
|
356
|
+
- terraform_apply_staging:
|
|
357
|
+
filters:
|
|
358
|
+
branches:
|
|
359
|
+
only: main
|
|
360
|
+
requires:
|
|
361
|
+
- terraform_plan_staging
|
|
362
|
+
- terraform_plan_production
|
|
363
|
+
- approve_production_terraform:
|
|
364
|
+
type: approval
|
|
365
|
+
filters:
|
|
366
|
+
branches:
|
|
367
|
+
only: production
|
|
368
|
+
requires:
|
|
369
|
+
- terraform_plan_production
|
|
370
|
+
- terraform_apply_production:
|
|
371
|
+
filters:
|
|
372
|
+
branches:
|
|
373
|
+
only: production
|
|
374
|
+
requires:
|
|
375
|
+
- approve_production_terraform<% end %>
|
|
376
|
+
- deploy_staging:
|
|
377
|
+
filters:
|
|
378
|
+
branches:
|
|
379
|
+
only: main
|
|
380
|
+
requires:
|
|
381
|
+
- test
|
|
382
|
+
- static_security_scans
|
|
383
|
+
- owasp_scan
|
|
384
|
+
- a11y_scan<% if terraform? %>
|
|
385
|
+
- terraform_apply_staging<% end %>
|
|
386
|
+
- deploy_production:
|
|
387
|
+
filters:
|
|
388
|
+
branches:
|
|
389
|
+
only: production
|
|
390
|
+
requires:
|
|
391
|
+
- test
|
|
392
|
+
- static_security_scans
|
|
393
|
+
- owasp_scan
|
|
394
|
+
- a11y_scan<% if terraform? %>
|
|
395
|
+
- terraform_apply_production<% end %>
|
|
396
|
+
daily_scan:
|
|
397
|
+
triggers:
|
|
398
|
+
- schedule:
|
|
399
|
+
cron: "0 12 * * *"
|
|
400
|
+
filters:
|
|
401
|
+
branches:
|
|
402
|
+
only:
|
|
403
|
+
- dev
|
|
404
|
+
- main
|
|
405
|
+
- production
|
|
406
|
+
jobs:
|
|
407
|
+
- build
|
|
408
|
+
- static_security_scans:
|
|
409
|
+
requires:
|
|
410
|
+
- build
|
|
411
|
+
- owasp_full_scan:
|
|
412
|
+
requires:
|
|
413
|
+
- build
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
version: "3.2"
|
|
2
|
+
services:
|
|
3
|
+
web:
|
|
4
|
+
build:
|
|
5
|
+
context: .
|
|
6
|
+
user: ${CURRENT_USER:-root}
|
|
7
|
+
networks:
|
|
8
|
+
- ci_network
|
|
9
|
+
ports:
|
|
10
|
+
- "3000:3000"
|
|
11
|
+
depends_on:
|
|
12
|
+
- db
|
|
13
|
+
environment:
|
|
14
|
+
RAILS_ENV: ci
|
|
15
|
+
DATABASE_URL: postgres://circleci:notasecret@db:5432/ci_db
|
|
16
|
+
RAILS_MASTER_KEY: $RAILS_MASTER_KEY
|
|
17
|
+
db:
|
|
18
|
+
image: cimg/postgres:12.9
|
|
19
|
+
environment:
|
|
20
|
+
POSTGRES_USER: circleci
|
|
21
|
+
POSTGRES_DB: ci_db
|
|
22
|
+
POSTGRES_PASSWORD: notasecret
|
|
23
|
+
networks:
|
|
24
|
+
- ci_network
|
|
25
|
+
networks:
|
|
26
|
+
ci_network:
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsTemplate18f
|
|
4
|
+
module Generators
|
|
5
|
+
class GithubActionsGenerator < ::Rails::Generators::Base
|
|
6
|
+
include ::Rails::Generators::AppName
|
|
7
|
+
include RailsTemplate18f::TerraformOptions
|
|
8
|
+
|
|
9
|
+
class_option :node_version, desc: "Node version to test against in actions"
|
|
10
|
+
|
|
11
|
+
desc <<~DESC
|
|
12
|
+
Description:
|
|
13
|
+
Install Github Actions workflow files
|
|
14
|
+
DESC
|
|
15
|
+
|
|
16
|
+
def self.source_root
|
|
17
|
+
@source_root ||= File.expand_path("templates", __dir__)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def install_actions
|
|
21
|
+
directory "github", ".github"
|
|
22
|
+
if !terraform?
|
|
23
|
+
remove_file ".github/workflows/terraform-staging.yml"
|
|
24
|
+
remove_file ".github/workflows/terraform-production.yml"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def update_readme
|
|
29
|
+
insert_into_file "README.md", readme_cicd, after: "## CI/CD\n"
|
|
30
|
+
insert_into_file "README.md", readme_staging_deploy, after: "#### Staging\n"
|
|
31
|
+
insert_into_file "README.md", readme_prod_deploy, after: "#### Production\n"
|
|
32
|
+
insert_into_file "README.md", readme_credentials, after: "#### Credentials and other Secrets\n"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def update_boundary_diagram
|
|
36
|
+
boundary_filename = "doc/compliance/apps/application.boundary.md"
|
|
37
|
+
insert_into_file boundary_filename, <<EOB, after: "Boundary(cicd, \"CI/CD Pipeline\") {\n"
|
|
38
|
+
System_Ext(githuball, "GitHub w/ Github Actions", "GSA-controlled code repository and Continuous Integration Service")
|
|
39
|
+
EOB
|
|
40
|
+
insert_into_file boundary_filename, <<~EOB, before: "@enduml"
|
|
41
|
+
Rel(developer, githuball, "Publish code", "git ssh (22)")
|
|
42
|
+
Rel(githuball, cg_api, "Deploy App", "Auth: SpaceDeployer Service Account, https (443)")
|
|
43
|
+
EOB
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def update_terraform_readme
|
|
47
|
+
return unless terraform?
|
|
48
|
+
readme_filename = "terraform/README.md"
|
|
49
|
+
insert_into_file readme_filename, " |- .force-action-apply\n", after: " |- secrets.auto.tfvars\n"
|
|
50
|
+
insert_into_file readme_filename, <<~EOM, after: /- `secrets.auto.tfvars`.*$/
|
|
51
|
+
- `.force-action-apply` is a file that can be updated to force GitHub Actions to run `terraform apply` during the deploy phase
|
|
52
|
+
EOM
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
no_tasks do
|
|
56
|
+
def readme_cicd
|
|
57
|
+
<<~EOM
|
|
58
|
+
|
|
59
|
+
GitHub actions are used to run all tests and scans as part of pull requests.
|
|
60
|
+
|
|
61
|
+
Security scans are also run on a scheduled basis. Weekly for static code scans, and daily for dependency scans.
|
|
62
|
+
EOM
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def readme_staging_deploy
|
|
66
|
+
<<~EOM
|
|
67
|
+
|
|
68
|
+
Deploys to staging#{terraform? ? ", including applying changes in terraform," : ""} happen
|
|
69
|
+
on every push to the `main` branch in Github.
|
|
70
|
+
|
|
71
|
+
The following secrets must be set within the `staging` [environment secrets](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-an-environment)
|
|
72
|
+
to enable a deploy to work:
|
|
73
|
+
|
|
74
|
+
| Secret Name | Description |
|
|
75
|
+
| ----------- | ----------- |
|
|
76
|
+
| `CF_USERNAME` | cloud.gov SpaceDeployer username |
|
|
77
|
+
| `CF_PASSWORD` | cloud.gov SpaceDeployer password |
|
|
78
|
+
| `RAILS_MASTER_KEY` | `config/master.key` |
|
|
79
|
+
#{terraform_secret_values}
|
|
80
|
+
EOM
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def readme_prod_deploy
|
|
84
|
+
<<~EOM
|
|
85
|
+
|
|
86
|
+
Deploys to production#{terraform? ? ", including applying changes in terraform," : ""} happen
|
|
87
|
+
on every push to the `production` branch in Github.
|
|
88
|
+
|
|
89
|
+
The following secrets must be set within the `production` [environment secrets](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-an-environment)
|
|
90
|
+
to enable a deploy to work:
|
|
91
|
+
|
|
92
|
+
| Secret Name | Description |
|
|
93
|
+
| ----------- | ----------- |
|
|
94
|
+
| `CF_USERNAME` | cloud.gov SpaceDeployer username |
|
|
95
|
+
| `CF_PASSWORD` | cloud.gov SpaceDeployer password |
|
|
96
|
+
| `RAILS_MASTER_KEY` | `config/credentials/production.key` |
|
|
97
|
+
#{terraform_secret_values}
|
|
98
|
+
EOM
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def readme_credentials
|
|
102
|
+
<<~EOM
|
|
103
|
+
|
|
104
|
+
1. Store variables that must be secret using [GitHub Environment Secrets](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-an-environment)
|
|
105
|
+
1. Add the secret to the `env:` block of the deploy action [as in this example](https://github.com/OHS-Hosting-Infrastructure/complaint-tracker/blob/a9e8d22aae2023a0afb631a6182251c04f597f7e/.github/workflows/deploy-stage.yml#L20)
|
|
106
|
+
1. Add the appropriate `--var` addition to the `push_arguments` line on the deploy action [as in this example](https://github.com/OHS-Hosting-Infrastructure/complaint-tracker/blob/a9e8d22aae2023a0afb631a6182251c04f597f7e/.github/workflows/deploy-stage.yml#L27)
|
|
107
|
+
EOM
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
private
|
|
112
|
+
|
|
113
|
+
def terraform_secret_values
|
|
114
|
+
if terraform?
|
|
115
|
+
<<~EOM
|
|
116
|
+
| `TERRAFORM_STATE_ACCESS_KEY` | Access key for terraform state bucket |
|
|
117
|
+
| `TERRAFORM_STATE_SECRET_ACCESS_KEY` | Secret key for terraform state bucket |
|
|
118
|
+
EOM
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def node_version
|
|
123
|
+
if options[:node_version].present?
|
|
124
|
+
options[:node_version]
|
|
125
|
+
elsif File.exist?(nvmrc_path)
|
|
126
|
+
File.read(nvmrc_path).strip
|
|
127
|
+
else
|
|
128
|
+
"16.13"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def nvmrc_path
|
|
133
|
+
@nvmrc_path ||= File.expand_path(".nvmrc", destination_root)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
data/lib/generators/rails_template18f/github_actions/templates/github/actions/run-server/action.yml
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: "Run rails server"
|
|
2
|
+
description: "Run rails server in the background for scans to access"
|
|
3
|
+
inputs:
|
|
4
|
+
rails_env:
|
|
5
|
+
description: RAILS_ENV to set. Defaults to ci
|
|
6
|
+
required: false
|
|
7
|
+
default: ci
|
|
8
|
+
database_url:
|
|
9
|
+
description: DATABASE_URL to set
|
|
10
|
+
required: true
|
|
11
|
+
runs:
|
|
12
|
+
using: "composite"
|
|
13
|
+
steps:
|
|
14
|
+
- name: "Start server in background"
|
|
15
|
+
shell: bash
|
|
16
|
+
env:
|
|
17
|
+
RAILS_ENV: ${{ inputs.rails_env }}
|
|
18
|
+
DATABASE_URL: ${{ inputs.database_url }}
|
|
19
|
+
SECRET_KEY_BASE: not-actually-secret
|
|
20
|
+
run: bundle exec rails server &
|
|
21
|
+
|
|
22
|
+
- name: "Wait for startup"
|
|
23
|
+
shell: bash
|
|
24
|
+
run: sleep 5
|
|
25
|
+
|
|
26
|
+
- name: "Verify response working"
|
|
27
|
+
shell: bash
|
|
28
|
+
run: curl http://localhost:3000 -I
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Set up languages
|
|
2
|
+
description: Set up ruby, javascript, and dependencies
|
|
3
|
+
runs:
|
|
4
|
+
using: composite
|
|
5
|
+
steps:
|
|
6
|
+
- name: Set up Ruby
|
|
7
|
+
uses: ruby/setup-ruby@v1
|
|
8
|
+
with:
|
|
9
|
+
# bundler-cache automatically installs gems
|
|
10
|
+
bundler-cache: true
|
|
11
|
+
cache-version: 1
|
|
12
|
+
|
|
13
|
+
- name: Set up node
|
|
14
|
+
uses: actions/setup-node@v2
|
|
15
|
+
with:
|
|
16
|
+
node-version: '<%= node_version %>'
|
|
17
|
+
cache: 'yarn'
|
|
18
|
+
- name: Install yarn dependencies
|
|
19
|
+
shell: bash
|
|
20
|
+
run: yarn install --frozen-lockfile
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Set up project with database
|
|
2
|
+
description: Setup Ruby, Javascript, and load the database schema into a running postgres db
|
|
3
|
+
inputs:
|
|
4
|
+
rails_env:
|
|
5
|
+
description: RAILS_ENV to set. Defaults to ci
|
|
6
|
+
required: false
|
|
7
|
+
default: ci
|
|
8
|
+
database_url:
|
|
9
|
+
description: DATABASE_URL to set
|
|
10
|
+
required: false
|
|
11
|
+
default: postgres://cidbuser:postgres@localhost:5432/<%= app_name %>_test
|
|
12
|
+
outputs:
|
|
13
|
+
database_url:
|
|
14
|
+
value: ${{ inputs.database_url }}
|
|
15
|
+
runs:
|
|
16
|
+
using: composite
|
|
17
|
+
steps:
|
|
18
|
+
- name: Set up Ruby & Javascript
|
|
19
|
+
uses: ./.github/actions/setup-languages
|
|
20
|
+
|
|
21
|
+
- name: Precompile assets
|
|
22
|
+
env:
|
|
23
|
+
RAILS_ENV: ${{ inputs.rails_env }}
|
|
24
|
+
SECRET_KEY_BASE: not-actually-secret
|
|
25
|
+
shell: bash
|
|
26
|
+
run: bundle exec rake assets:precompile
|
|
27
|
+
|
|
28
|
+
- name: Set up database
|
|
29
|
+
env:
|
|
30
|
+
RAILS_ENV: ${{ inputs.rails_env }}
|
|
31
|
+
DATABASE_URL: ${{ inputs.database_url }}
|
|
32
|
+
shell: bash
|
|
33
|
+
run: bundle exec rake db:schema:load
|