rails_template_18f 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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
@@ -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'
@@ -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,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsTemplate18f
4
+ VERSION = "0.1.0"
5
+ 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
data/railsrc ADDED
@@ -0,0 +1,10 @@
1
+ --skip-active-storage
2
+ --skip-action-text
3
+ --skip-action-cable
4
+ --skip-action-mailbox
5
+ --skip-hotwire
6
+ --skip-test
7
+ --javascript=webpack
8
+ --css=postcss
9
+ --template=template.rb
10
+ --database=postgresql