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,44 @@
|
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
|
2
|
+
# They are provided by a third-party and are governed by
|
|
3
|
+
# separate terms of service, privacy policy, and support
|
|
4
|
+
# documentation.
|
|
5
|
+
|
|
6
|
+
# This workflow integrates Brakeman with GitHub's Code Scanning feature
|
|
7
|
+
# Brakeman is a static analysis security vulnerability scanner for Ruby on Rails applications
|
|
8
|
+
|
|
9
|
+
name: Brakeman Scan
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
branches: [ main ]
|
|
14
|
+
paths-ignore:
|
|
15
|
+
- 'doc/**'
|
|
16
|
+
- 'README.md'
|
|
17
|
+
pull_request:
|
|
18
|
+
# The branches below must be a subset of the branches above
|
|
19
|
+
branches: [ main ]
|
|
20
|
+
schedule:
|
|
21
|
+
# cron format: 'minute hour dayofmonth month dayofweek'
|
|
22
|
+
# this will run at noon UTC each Monday (7am EST / 8am EDT)
|
|
23
|
+
- cron: '0 12 * * 1'
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
brakeman-scan:
|
|
27
|
+
name: Brakeman Scan
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v2
|
|
31
|
+
|
|
32
|
+
- uses: ./.github/actions/setup-languages
|
|
33
|
+
|
|
34
|
+
# Execute Brakeman CLI and generate a SARIF output with the security issues identified during the analysis
|
|
35
|
+
- name: Scan
|
|
36
|
+
continue-on-error: true
|
|
37
|
+
run: |
|
|
38
|
+
bundle exec brakeman -f sarif -o output.sarif.json .
|
|
39
|
+
|
|
40
|
+
# Upload the SARIF file generated in the previous step
|
|
41
|
+
- name: Upload SARIF
|
|
42
|
+
uses: github/codeql-action/upload-sarif@v1
|
|
43
|
+
with:
|
|
44
|
+
sarif_file: output.sarif.json
|
data/lib/generators/rails_template18f/github_actions/templates/github/workflows/dependency-scans.yml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Ruby and Javascript dependency scans
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
paths-ignore:
|
|
7
|
+
- 'doc/**'
|
|
8
|
+
- 'README.md'
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ main ]
|
|
11
|
+
schedule:
|
|
12
|
+
# cron format: 'minute hour dayofmonth month dayofweek'
|
|
13
|
+
# this will run at noon UTC every day (7am EST / 8am EDT)
|
|
14
|
+
- cron: '0 12 * * *'
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
bundle-audit:
|
|
18
|
+
name: Bundle audit
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v2
|
|
23
|
+
|
|
24
|
+
- uses: ./.github/actions/setup-languages
|
|
25
|
+
|
|
26
|
+
- name: Update advisory database and run checks
|
|
27
|
+
run: bundle exec rake bundler:audit
|
|
28
|
+
|
|
29
|
+
yarn-audit:
|
|
30
|
+
name: Yarn audit
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v2
|
|
35
|
+
|
|
36
|
+
- uses: ./.github/actions/setup-languages
|
|
37
|
+
|
|
38
|
+
- name: Run yarn audit
|
|
39
|
+
run: bundle exec rake yarn:audit
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Deploy Production
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ production ]
|
|
6
|
+
paths-ignore:
|
|
7
|
+
- 'doc/**'
|
|
8
|
+
- 'README.md'
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
deploy:
|
|
12
|
+
name: Deploy to production
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment: production
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v2
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 2
|
|
19
|
+
<% if terraform? %>
|
|
20
|
+
- name: Check for changes to Terraform
|
|
21
|
+
id: changed-terraform-files
|
|
22
|
+
uses: tj-actions/changed-files@v1.1.2
|
|
23
|
+
with:
|
|
24
|
+
files: |
|
|
25
|
+
terraform/shared
|
|
26
|
+
terraform/production
|
|
27
|
+
- name: Terraform init
|
|
28
|
+
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
|
29
|
+
working-directory: terraform/production
|
|
30
|
+
env:
|
|
31
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
|
32
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
|
33
|
+
run: terraform init
|
|
34
|
+
- name: Terraform apply
|
|
35
|
+
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
|
36
|
+
working-directory: terraform/production
|
|
37
|
+
env:
|
|
38
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
|
39
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
|
40
|
+
TF_VAR_cf_user: ${{ secrets.CF_USERNAME }}
|
|
41
|
+
TF_VAR_cf_password: ${{ secrets.CF_PASSWORD }}
|
|
42
|
+
run: terraform apply -auto-approve -input=false
|
|
43
|
+
<% end %>
|
|
44
|
+
- name: Deploy app
|
|
45
|
+
uses: 18F/cg-deploy-action@main
|
|
46
|
+
env:
|
|
47
|
+
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
|
|
48
|
+
with:
|
|
49
|
+
cf_username: ${{ secrets.CF_USERNAME }}
|
|
50
|
+
cf_password: ${{ secrets.CF_PASSWORD }}
|
|
51
|
+
cf_org: <%= cloud_gov_organization %>
|
|
52
|
+
cf_space: <%= cloud_gov_production_space %>
|
|
53
|
+
push_arguments: "--vars-file config/deployment/production.yml --var rails_master_key=$RAILS_MASTER_KEY"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Deploy Staging
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
paths-ignore:
|
|
7
|
+
- 'doc/**'
|
|
8
|
+
- 'README.md'
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
deploy:
|
|
12
|
+
name: Deploy to staging
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment: staging
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v2
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 2
|
|
19
|
+
<% if terraform? %>
|
|
20
|
+
- name: Check for changes to Terraform
|
|
21
|
+
id: changed-terraform-files
|
|
22
|
+
uses: tj-actions/changed-files@v1.1.2
|
|
23
|
+
with:
|
|
24
|
+
files: |
|
|
25
|
+
terraform/shared
|
|
26
|
+
terraform/staging
|
|
27
|
+
- name: Terraform init
|
|
28
|
+
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
|
29
|
+
working-directory: terraform/staging
|
|
30
|
+
env:
|
|
31
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
|
32
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
|
33
|
+
run: terraform init
|
|
34
|
+
- name: Terraform apply
|
|
35
|
+
if: steps.changed-terraform-files.outputs.any_changed == 'true'
|
|
36
|
+
working-directory: terraform/staging
|
|
37
|
+
env:
|
|
38
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
|
39
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
|
40
|
+
TF_VAR_cf_user: ${{ secrets.CF_USERNAME }}
|
|
41
|
+
TF_VAR_cf_password: ${{ secrets.CF_PASSWORD }}
|
|
42
|
+
run: terraform apply -auto-approve -input=false
|
|
43
|
+
<% end %>
|
|
44
|
+
- name: Deploy app
|
|
45
|
+
uses: 18F/cg-deploy-action@main
|
|
46
|
+
env:
|
|
47
|
+
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
|
|
48
|
+
with:
|
|
49
|
+
cf_username: ${{ secrets.CF_USERNAME }}
|
|
50
|
+
cf_password: ${{ secrets.CF_PASSWORD }}
|
|
51
|
+
cf_org: <%= cloud_gov_organization %>
|
|
52
|
+
cf_space: <%= cloud_gov_staging_space %>
|
|
53
|
+
push_arguments: "--vars-file config/deployment/staging.yml --var rails_master_key=$RAILS_MASTER_KEY"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: OWASP ZAP daily scan
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# cron format: 'minute hour dayofmonth month dayofweek'
|
|
6
|
+
# this will run at noon UTC every day (7am EST / 8am EDT)
|
|
7
|
+
- cron: '0 12 * * *'
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
owasp-scan:
|
|
11
|
+
name: OWASP ZAP Scan
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
services:
|
|
14
|
+
postgres:
|
|
15
|
+
image: postgres
|
|
16
|
+
options: >-
|
|
17
|
+
--health-cmd pg_isready
|
|
18
|
+
--health-interval 10s
|
|
19
|
+
--health-timeout 5s
|
|
20
|
+
--health-retries 5
|
|
21
|
+
ports: ["5432:5432"]
|
|
22
|
+
env:
|
|
23
|
+
POSTGRES_DB: <%= app_name %>_test
|
|
24
|
+
POSTGRES_USER: cidbuser
|
|
25
|
+
POSTGRES_PASSWORD: postgres
|
|
26
|
+
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v2
|
|
29
|
+
|
|
30
|
+
- id: setup
|
|
31
|
+
uses: ./.github/actions/setup-project
|
|
32
|
+
|
|
33
|
+
- uses: ./.github/actions/run-server
|
|
34
|
+
with:
|
|
35
|
+
database_url: ${{ steps.setup.outputs.database_url }}
|
|
36
|
+
|
|
37
|
+
- name: Run OWASP Full Scan
|
|
38
|
+
uses: zaproxy/action-full-scan@v0.3.0
|
|
39
|
+
with:
|
|
40
|
+
docker_name: 'owasp/zap2docker-weekly'
|
|
41
|
+
target: 'http://localhost:3000/'
|
|
42
|
+
fail_action: true
|
|
43
|
+
rules_file_name: 'zap.conf'
|
|
44
|
+
cmd_options: '-I'
|
data/lib/generators/rails_template18f/github_actions/templates/github/workflows/owasp-scan.yml.tt
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: OWASP ZAP scan
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
paths-ignore:
|
|
7
|
+
- 'doc/**'
|
|
8
|
+
- 'README.md'
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ main ]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
owasp-scan:
|
|
14
|
+
name: OWASP ZAP Scan
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
services:
|
|
17
|
+
postgres:
|
|
18
|
+
image: postgres
|
|
19
|
+
options: >-
|
|
20
|
+
--health-cmd pg_isready
|
|
21
|
+
--health-interval 10s
|
|
22
|
+
--health-timeout 5s
|
|
23
|
+
--health-retries 5
|
|
24
|
+
ports: ["5432:5432"]
|
|
25
|
+
env:
|
|
26
|
+
POSTGRES_DB: <%= app_name %>_test
|
|
27
|
+
POSTGRES_USER: cidbuser
|
|
28
|
+
POSTGRES_PASSWORD: postgres
|
|
29
|
+
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v2
|
|
32
|
+
|
|
33
|
+
- id: setup
|
|
34
|
+
uses: ./.github/actions/setup-project
|
|
35
|
+
|
|
36
|
+
- uses: ./.github/actions/run-server
|
|
37
|
+
with:
|
|
38
|
+
database_url: ${{ steps.setup.outputs.database_url }}
|
|
39
|
+
|
|
40
|
+
- name: Run OWASP Baseline Scan
|
|
41
|
+
uses: zaproxy/action-baseline@v0.6.1
|
|
42
|
+
with:
|
|
43
|
+
docker_name: 'owasp/zap2docker-weekly'
|
|
44
|
+
target: 'http://localhost:3000/'
|
|
45
|
+
fail_action: true
|
|
46
|
+
rules_file_name: 'zap.conf'
|
|
47
|
+
cmd_options: '-I'
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: pa11y tests
|
|
2
|
+
|
|
3
|
+
on: [pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
pa11y_scan:
|
|
7
|
+
name: Pa11y Scan
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
services:
|
|
10
|
+
postgres:
|
|
11
|
+
image: postgres
|
|
12
|
+
options: >-
|
|
13
|
+
--health-cmd pg_isready
|
|
14
|
+
--health-interval 10s
|
|
15
|
+
--health-timeout 5s
|
|
16
|
+
--health-retries 5
|
|
17
|
+
ports: ["5432:5432"]
|
|
18
|
+
env:
|
|
19
|
+
POSTGRES_DB: <%= app_name %>_test
|
|
20
|
+
POSTGRES_USER: cidbuser
|
|
21
|
+
POSTGRES_PASSWORD: postgres
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v2
|
|
25
|
+
|
|
26
|
+
- id: setup
|
|
27
|
+
uses: ./.github/actions/setup-project
|
|
28
|
+
|
|
29
|
+
- uses: ./.github/actions/run-server
|
|
30
|
+
with:
|
|
31
|
+
database_url: ${{ steps.setup.outputs.database_url }}
|
|
32
|
+
|
|
33
|
+
- name: Run pa11y-ci
|
|
34
|
+
shell: bash
|
|
35
|
+
run: |
|
|
36
|
+
set -o pipefail
|
|
37
|
+
yarn run pa11y-ci 2>&1 | tee pa11y_output.txt
|
|
38
|
+
|
|
39
|
+
- name: Read pa11y_output file.
|
|
40
|
+
if: failure()
|
|
41
|
+
id: pa11y_output
|
|
42
|
+
uses: juliangruber/read-file-action@v1
|
|
43
|
+
with:
|
|
44
|
+
path: ./pa11y_output.txt
|
|
45
|
+
|
|
46
|
+
- name: Comment on pull request
|
|
47
|
+
if: failure()
|
|
48
|
+
uses: actions/github-script@v4
|
|
49
|
+
with:
|
|
50
|
+
script: |
|
|
51
|
+
const output = `Pa11y Failures detected
|
|
52
|
+
|
|
53
|
+
<details><summary>Show failure message</summary>
|
|
54
|
+
|
|
55
|
+
\`\`\`\n
|
|
56
|
+
${{ steps.pa11y_output.outputs.content }}
|
|
57
|
+
\`\`\`
|
|
58
|
+
</details>`;
|
|
59
|
+
|
|
60
|
+
github.issues.createComment({
|
|
61
|
+
issue_number: context.issue.number,
|
|
62
|
+
owner: context.repo.owner,
|
|
63
|
+
repo: context.repo.repo,
|
|
64
|
+
body: output
|
|
65
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: rspec tests
|
|
2
|
+
|
|
3
|
+
on: [pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
rspec:
|
|
7
|
+
name: Rspec
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
services:
|
|
10
|
+
postgres:
|
|
11
|
+
image: postgres
|
|
12
|
+
options: >-
|
|
13
|
+
--health-cmd pg_isready
|
|
14
|
+
--health-interval 10s
|
|
15
|
+
--health-timeout 5s
|
|
16
|
+
--health-retries 5
|
|
17
|
+
ports: ["5432:5432"]
|
|
18
|
+
env:
|
|
19
|
+
POSTGRES_DB: <%= app_name %>_test
|
|
20
|
+
POSTGRES_USER: cidbuser
|
|
21
|
+
POSTGRES_PASSWORD: postgres
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v2
|
|
25
|
+
|
|
26
|
+
- id: setup
|
|
27
|
+
uses: ./.github/actions/setup-project
|
|
28
|
+
with:
|
|
29
|
+
rails_env: test
|
|
30
|
+
|
|
31
|
+
- name: Run rspec
|
|
32
|
+
env:
|
|
33
|
+
DATABASE_URL: ${{ steps.setup.outputs.database_url }}
|
|
34
|
+
run: bundle exec rspec
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: Run Terraform plan in production
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [ production ]
|
|
6
|
+
paths: [ 'terraform/**' ]
|
|
7
|
+
|
|
8
|
+
defaults:
|
|
9
|
+
run:
|
|
10
|
+
working-directory: terraform/production
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
terraform:
|
|
14
|
+
name: Terraform plan
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
environment: production
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout
|
|
19
|
+
uses: actions/checkout@v2
|
|
20
|
+
|
|
21
|
+
- name: Terraform format
|
|
22
|
+
id: format
|
|
23
|
+
run: terraform fmt -check
|
|
24
|
+
|
|
25
|
+
- name: Terraform init
|
|
26
|
+
id: init
|
|
27
|
+
env:
|
|
28
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
|
29
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
|
30
|
+
run: terraform init
|
|
31
|
+
|
|
32
|
+
- name: Terraform validate
|
|
33
|
+
id: validation
|
|
34
|
+
run: terraform validate -no-color
|
|
35
|
+
|
|
36
|
+
- name: Terraform plan
|
|
37
|
+
id: plan
|
|
38
|
+
env:
|
|
39
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
|
40
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
|
41
|
+
TF_VAR_cf_user: ${{ secrets.CF_USERNAME }}
|
|
42
|
+
TF_VAR_cf_password: ${{ secrets.CF_PASSWORD }}
|
|
43
|
+
run: terraform plan -no-color -input=false 2>&1 | tee plan_output.txt
|
|
44
|
+
|
|
45
|
+
- name: Read Terraform plan output file
|
|
46
|
+
id: terraform_output
|
|
47
|
+
uses: juliangruber/read-file-action@v1
|
|
48
|
+
if: ${{ always() }}
|
|
49
|
+
with:
|
|
50
|
+
path: ./terraform/production/plan_output.txt
|
|
51
|
+
|
|
52
|
+
# inspiration: https://learn.hashicorp.com/tutorials/terraform/github-actions#review-actions-workflow
|
|
53
|
+
- name: Update PR
|
|
54
|
+
uses: actions/github-script@v4
|
|
55
|
+
# we would like to update the PR even when a prior step failed
|
|
56
|
+
if: ${{ always() }}
|
|
57
|
+
with:
|
|
58
|
+
script: |
|
|
59
|
+
const output = `Terraform Format and Style: ${{ steps.format.outcome }}
|
|
60
|
+
Terraform Initialization: ${{ steps.init.outcome }}
|
|
61
|
+
Terraform Validation: ${{ steps.validation.outcome }}
|
|
62
|
+
Terraform Plan: ${{ steps.plan.outcome }}
|
|
63
|
+
|
|
64
|
+
<details><summary>Show Plan</summary>
|
|
65
|
+
|
|
66
|
+
\`\`\`\n
|
|
67
|
+
${{ steps.terraform_output.outputs.content }}
|
|
68
|
+
\`\`\`
|
|
69
|
+
|
|
70
|
+
</details>
|
|
71
|
+
|
|
72
|
+
*Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
|
|
73
|
+
|
|
74
|
+
github.issues.createComment({
|
|
75
|
+
issue_number: context.issue.number,
|
|
76
|
+
owner: context.repo.owner,
|
|
77
|
+
repo: context.repo.repo,
|
|
78
|
+
body: output
|
|
79
|
+
})
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: Run Terraform plan in staging
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
paths: [ 'terraform/**' ]
|
|
7
|
+
|
|
8
|
+
defaults:
|
|
9
|
+
run:
|
|
10
|
+
working-directory: terraform/staging
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
terraform:
|
|
14
|
+
name: Terraform plan
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
environment: staging
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout
|
|
19
|
+
uses: actions/checkout@v2
|
|
20
|
+
|
|
21
|
+
- name: Terraform format
|
|
22
|
+
id: format
|
|
23
|
+
run: terraform fmt -check
|
|
24
|
+
|
|
25
|
+
- name: Terraform init
|
|
26
|
+
id: init
|
|
27
|
+
env:
|
|
28
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
|
29
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
|
30
|
+
run: terraform init
|
|
31
|
+
|
|
32
|
+
- name: Terraform validate
|
|
33
|
+
id: validation
|
|
34
|
+
run: terraform validate -no-color
|
|
35
|
+
|
|
36
|
+
- name: Terraform plan
|
|
37
|
+
id: plan
|
|
38
|
+
env:
|
|
39
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
|
|
40
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
|
|
41
|
+
TF_VAR_cf_user: ${{ secrets.CF_USERNAME }}
|
|
42
|
+
TF_VAR_cf_password: ${{ secrets.CF_PASSWORD }}
|
|
43
|
+
run: terraform plan -no-color -input=false 2>&1 | tee plan_output.txt
|
|
44
|
+
|
|
45
|
+
- name: Read Terraform plan output file
|
|
46
|
+
id: terraform_output
|
|
47
|
+
uses: juliangruber/read-file-action@v1
|
|
48
|
+
if: ${{ always() }}
|
|
49
|
+
with:
|
|
50
|
+
path: ./terraform/staging/plan_output.txt
|
|
51
|
+
|
|
52
|
+
# inspiration: https://learn.hashicorp.com/tutorials/terraform/github-actions#review-actions-workflow
|
|
53
|
+
- name: Update PR
|
|
54
|
+
uses: actions/github-script@v4
|
|
55
|
+
# we would like to update the PR even when a prior step failed
|
|
56
|
+
if: ${{ always() }}
|
|
57
|
+
with:
|
|
58
|
+
script: |
|
|
59
|
+
const output = `Terraform Format and Style: ${{ steps.format.outcome }}
|
|
60
|
+
Terraform Initialization: ${{ steps.init.outcome }}
|
|
61
|
+
Terraform Validation: ${{ steps.validation.outcome }}
|
|
62
|
+
Terraform Plan: ${{ steps.plan.outcome }}
|
|
63
|
+
|
|
64
|
+
<details><summary>Show Plan</summary>
|
|
65
|
+
|
|
66
|
+
\`\`\`\n
|
|
67
|
+
${{ steps.terraform_output.outputs.content }}
|
|
68
|
+
\`\`\`
|
|
69
|
+
|
|
70
|
+
</details>
|
|
71
|
+
|
|
72
|
+
*Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
|
|
73
|
+
|
|
74
|
+
github.issues.createComment({
|
|
75
|
+
issue_number: context.issue.number,
|
|
76
|
+
owner: context.repo.owner,
|
|
77
|
+
repo: context.repo.repo,
|
|
78
|
+
body: output
|
|
79
|
+
})
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsTemplate18f
|
|
4
|
+
module TerraformOptions
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
class_option :cg_org, desc: "cloud.gov organization name"
|
|
9
|
+
class_option :cg_staging, desc: "cloud.gov space name for staging"
|
|
10
|
+
class_option :cg_prod, desc: "cloud.gov space name for production"
|
|
11
|
+
class_option :terraform, type: :boolean, desc: "Generate actions for planning and applying terraform"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def ruby_version
|
|
17
|
+
RUBY_VERSION
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def terraform?
|
|
21
|
+
options[:terraform].nil? ? terraform_dir_exists? : options[:terraform]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def cloud_gov_organization
|
|
25
|
+
if options[:cg_org].present?
|
|
26
|
+
return options[:cg_org]
|
|
27
|
+
elsif terraform_dir_exists?
|
|
28
|
+
staging_main = File.read(terraform_path.join("staging", "main.tf"))
|
|
29
|
+
if (matches = staging_main.match(/cf_org_name\s+= "(?<org_name>.*)"/))
|
|
30
|
+
return matches[:org_name]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
"TKTK-cloud.gov-org-name"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def cloud_gov_staging_space
|
|
37
|
+
if options[:cg_staging].present?
|
|
38
|
+
return options[:cg_staging]
|
|
39
|
+
elsif terraform_dir_exists?
|
|
40
|
+
staging_main = File.read(terraform_path.join("staging", "main.tf"))
|
|
41
|
+
if (matches = staging_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
|
|
42
|
+
return matches[:space_name]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
"staging"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def cloud_gov_production_space
|
|
49
|
+
if options[:cg_prod].present?
|
|
50
|
+
return options[:cg_prod]
|
|
51
|
+
elsif terraform_dir_exists?
|
|
52
|
+
prod_main = File.read(terraform_path.join("production", "main.tf"))
|
|
53
|
+
if (matches = prod_main.match(/cf_space_name\s+= "(?<space_name>.*)"/))
|
|
54
|
+
return matches[:space_name]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
"prod"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def terraform_path
|
|
61
|
+
Pathname.new File.expand_path("terraform", destination_root)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def terraform_dir_exists?
|
|
65
|
+
Dir.exist? terraform_path
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "rails_template18f/version"
|
|
4
|
+
|
|
5
|
+
module RailsTemplate18f
|
|
6
|
+
extend ActiveSupport::Autoload
|
|
7
|
+
|
|
8
|
+
autoload :TerraformOptions
|
|
9
|
+
|
|
10
|
+
class Error < StandardError; end
|
|
11
|
+
|
|
12
|
+
class Railtie < ::Rails::Railtie; end
|
|
13
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/rails_template18f/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "rails_template_18f"
|
|
7
|
+
spec.version = RailsTemplate18f::VERSION
|
|
8
|
+
spec.authors = ["Ryan Ahearn"]
|
|
9
|
+
spec.email = ["ryan.ahearn@gsa.gov"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Generators for creating an 18F-flavored Rails app"
|
|
12
|
+
spec.homepage = "https://github.com/18f/rails-template"
|
|
13
|
+
spec.required_ruby_version = ">= 2.7.5"
|
|
14
|
+
|
|
15
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
|
16
|
+
|
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/18f/rails-template"
|
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/18f/rails-template/blob/main/CHANGELOG.md"
|
|
20
|
+
|
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
25
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
spec.bindir = "exe"
|
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
30
|
+
spec.require_paths = ["lib"]
|
|
31
|
+
|
|
32
|
+
# For more information and examples about making a new gem, checkout our
|
|
33
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
|
34
|
+
spec.add_dependency "railties", "~> 7.0.0"
|
|
35
|
+
spec.add_dependency "activesupport", "~> 7.0.0"
|
|
36
|
+
|
|
37
|
+
spec.add_development_dependency "rspec", "~> 3.11"
|
|
38
|
+
spec.add_development_dependency "ammeter", "~> 1.1"
|
|
39
|
+
spec.add_development_dependency "standard", "~> 1.3"
|
|
40
|
+
end
|