diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index 5db9b8b0c0..16b12afb4b 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -1,6 +1,8 @@ name: Build and deploy to AKS cluster on: + push: + branches: [master] pull_request: types: [labeled, opened, reopened, synchronize] @@ -13,7 +15,6 @@ permissions: jobs: build: runs-on: ubuntu-latest - if: ${{ contains(github.event.pull_request.labels.*.name, 'deploy') }} outputs: docker-image-tag: ${{ steps.build-image.outputs.tag }} @@ -33,6 +34,7 @@ jobs: name: Deploy to review environment concurrency: deploy_review_${{ github.event.pull_request.number }} runs-on: ubuntu-latest + if: ${{ contains(github.event.pull_request.labels.*.name, 'deploy') }} needs: [build] environment: name: review-aks @@ -78,3 +80,60 @@ jobs: | Additional Payments | <${{ env.APP_URL }}/additional-payments/claim> | | Student Loans | <${{ env.APP_URL }}/student-loans/claim> | | Admin | <${{ env.APP_URL }}/admin> | + + deploy_test: + name: Deploy to test environment + concurrency: deploy_test + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' && github.event_name == 'push' + needs: [build] + environment: + name: test-aks + url: ${{ steps.deploy.outputs.environment_url }} + outputs: + environment_url: ${{ steps.deploy.outputs.environment_url }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: azure/login@v2 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - uses: ./.github/actions/deploy-environment + id: deploy + with: + environment: test-aks + docker-image: ${{ needs.build.outputs.docker-image-tag }} + azure-credentials: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Run migrations + shell: bash + run: | + make ci test-aks get-cluster-credentials + kubectl exec -n srtl-test deployment/claim-additional-payments-for-teaching-test-worker -- sh -c "DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bin/prepare-database" + + - name: Install Ruby 3.2.4 + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + ruby-version: 3.2.4 + + - name: Run smoke tests + shell: bash + run: bundle exec rspec spec/smoke -t smoke:true -b + env: + RAILS_ENV: test + SMOKE_TEST_APP_HOST: ${{ env.APP_URL }} + BASIC_AUTH_USERNAME: ${{ secrets.BASIC_AUTH_USERNAME }} + BASIC_AUTH_PASSWORD: ${{ secrets.BASIC_AUTH_PASSWORD }} + + - name: Notify on failure + if: failure() + uses: rtCamp/action-slack-notify@master + env: + SLACK_COLOR: failure + SLACK_TITLE: Failure deploying release to test + SLACK_MESSAGE: Failure deploying release to test - Docker tag ${{ needs.build.outputs.docker-image-tag }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/Gemfile b/Gemfile index d2c52351c5..8fb7666f47 100644 --- a/Gemfile +++ b/Gemfile @@ -124,6 +124,8 @@ group :test do gem "launchy" gem "rack_session_access" gem "simplecov", require: false + # Return null object for active record connection rather than raising error + gem "activerecord-nulldb-adapter" end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/Gemfile.lock b/Gemfile.lock index 70444a0a99..be9e96cf8e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -73,6 +73,8 @@ GEM activesupport (= 7.0.8.4) activerecord-copy (1.1.0) activerecord (>= 3.1) + activerecord-nulldb-adapter (1.0.1) + activerecord (>= 5.2.0, < 7.2) activestorage (7.0.8.4) actionpack (= 7.0.8.4) activejob (= 7.0.8.4) @@ -552,6 +554,7 @@ PLATFORMS DEPENDENCIES activerecord-copy + activerecord-nulldb-adapter application_insights! bootsnap (>= 1.1.0) brakeman diff --git a/Makefile b/Makefile index 9e3a0efe35..211bb1a52f 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,6 @@ review-aks: test-cluster $(eval ENVIRONMENT=review-${PR_NUMBER}) $(eval export TF_VAR_environment=${ENVIRONMENT}) $(eval include global_config/review.sh) - echo https://claim-additional-payments-for-teaching-review-$(PR_NUMBER).test.teacherservices.cloud will be created in aks .PHONY: test-aks test-aks: test-cluster diff --git a/bin/slack-alert b/bin/slack-alert deleted file mode 100755 index 328e2651d0..0000000000 --- a/bin/slack-alert +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -ENVIRONMENT_NAME=$1 -BUILD_NUMBER=$2 -RELEASE_ID=$3 -WEBHOOK_URL=$4 -RESULT=$5 - -RELEASE_URL="https://dev.azure.com/dfe-ssp/S118-Teacher-Payments-Service/_releaseProgress?_a=release-pipeline-progress&releaseId=$RELEASE_ID" - -if [ "$RESULT" == "SUCCESS" ]; then - MESSAGE=":ship: Build $BUILD_NUMBER is deployed to $ENVIRONMENT_NAME! $RELEASE_URL :rocket:" -else - MESSAGE=":warning: Build $BUILD_NUMBER has failed for $ENVIRONMENT_NAME. More info $RELEASE_URL" -fi - - -curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$MESSAGE\"}" "$WEBHOOK_URL" diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index b85a68f593..8256c112ff 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -22,13 +22,17 @@ # Dir[Rails.root.join("spec", "support", "**", "*.rb")].sort.each { |f| require f } -# Checks for pending migrations and applies them before tests are run. -# If you are not using ActiveRecord, you can remove these lines. -begin - ActiveRecord::Migration.maintain_test_schema! -rescue ActiveRecord::PendingMigrationError => e - puts e.to_s.strip - exit 1 +if ENV["SMOKE_TEST_APP_HOST"].present? + ActiveRecord::Base.establish_connection adapter: :nulldb +else + # Checks for pending migrations and applies them before tests are run. + # If you are not using ActiveRecord, you can remove these lines. + begin + ActiveRecord::Migration.maintain_test_schema! + rescue ActiveRecord::PendingMigrationError => e + puts e.to_s.strip + exit 1 + end end RSpec.configure do |config| @@ -82,6 +86,7 @@ OmniAuth.config.mock_auth[:default] = nil end + config.filter_run_excluding :smoke config.filter_run_excluding flaky: true unless ENV["RUN_FLAKY_SPECS"] == "true" config.filter_run_excluding js: true unless ENV["RUN_JS_SPECS"] == "true" config.filter_run_excluding slow: true unless ENV["RUN_SLOW_SPECS"] == "true" diff --git a/spec/smoke/start_a_claim_spec.rb b/spec/smoke/start_a_claim_spec.rb new file mode 100644 index 0000000000..f334c41f75 --- /dev/null +++ b/spec/smoke/start_a_claim_spec.rb @@ -0,0 +1,24 @@ +require "rails_helper" + +RSpec.describe "Start a claim", :smoke, type: :feature do + # To test this locally you will need to add to your .env file: + # + # SMOKE_TEST_APP_HOST + # BASIC_AUTH_USERNAME + # BASIC_AUTH_PASSWORD + + scenario "User starts a claim" do + visit url_with_basic_auth + expect(page).to have_text("Teachers: claim back your student loan repayments") + end + + def url_with_basic_auth + host = ENV.fetch("SMOKE_TEST_APP_HOST") + path = new_claim_path(Journeys::TeacherStudentLoanReimbursement::ROUTING_NAME) + uri = URI.join(host, path) + + uri.user = ENV.fetch("BASIC_AUTH_USERNAME", nil) + uri.password = ENV.fetch("BASIC_AUTH_PASSWORD", nil) + uri.to_s + end +end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 8c3c34aac2..fc7a14e45e 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -27,3 +27,13 @@ end Capybara.automatic_label_click = true + +RSpec.configure do |config| + config.around(:each, :smoke) do |example| + Capybara.current_driver = Capybara.javascript_driver + Capybara.run_server = false + example.run + Capybara.run_server = true + Capybara.current_driver = Capybara.default_driver + end +end diff --git a/terraform/application/application.tf b/terraform/application/application.tf index 86e04a9e25..9818895f82 100644 --- a/terraform/application/application.tf +++ b/terraform/application/application.tf @@ -38,6 +38,8 @@ module "web_application" { docker_image = var.docker_image command = var.startup_command + + replicas = var.web_replicas } module "worker_application" { diff --git a/terraform/application/config/test.tfvars.json b/terraform/application/config/test.tfvars.json new file mode 100644 index 0000000000..31970e11c3 --- /dev/null +++ b/terraform/application/config/test.tfvars.json @@ -0,0 +1,10 @@ +{ + "cluster": "test", + "namespace": "srtl-test", + "config": "test", + "environment": "test", + "canonical_hostname": "claim-additional-payments-for-teaching-test-web.test.teacherservices.cloud", + "web_replicas": 2, + "startup_command": ["/bin/sh", "-c", "bin/rails server -b 0.0.0.0"], + "worker_command": ["/bin/sh", "-c", "bin/bundle exec bin/delayed_job run -n 1"] +} diff --git a/terraform/application/config/test_Terrafile b/terraform/application/config/test_Terrafile new file mode 100644 index 0000000000..b4c222c13d --- /dev/null +++ b/terraform/application/config/test_Terrafile @@ -0,0 +1,3 @@ +aks: + source: "https://github.com/DFE-Digital/terraform-modules" + version: "testing" diff --git a/terraform/application/config/test_app_env.yml b/terraform/application/config/test_app_env.yml new file mode 100644 index 0000000000..374baa4f9c --- /dev/null +++ b/terraform/application/config/test_app_env.yml @@ -0,0 +1,2 @@ +--- +SUPPRESS_DFE_ANALYTICS_INIT: true diff --git a/terraform/application/database.tf b/terraform/application/database.tf index 25dc1edae4..957b6c2b82 100644 --- a/terraform/application/database.tf +++ b/terraform/application/database.tf @@ -11,5 +11,6 @@ module "postgres" { use_azure = var.deploy_azure_backing_services azure_enable_monitoring = var.enable_monitoring azure_enable_backup_storage = var.enable_postgres_backup_storage + azure_extensions = ["pg_trgm", "pgcrypto", "plpgsql"] server_version = "16" } diff --git a/terraform/application/variables.tf b/terraform/application/variables.tf index 323f7aeab2..d2e6ae8677 100644 --- a/terraform/application/variables.tf +++ b/terraform/application/variables.tf @@ -60,6 +60,10 @@ variable "canonical_hostname" { description = "External domain name for the app service" default = null } +variable "web_replicas" { + description = "Number of replicas of the web app" + default = 1 +} locals { postgres_ssl_mode = var.enable_postgres_ssl ? "require" : "disable"