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
@@ -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