diff --git a/.githooks/common.sh b/.githooks/common.sh new file mode 100644 index 0000000..a293608 --- /dev/null +++ b/.githooks/common.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# Common utilities and functions for git hooks +# +# Environment variables: +# NO_COLOR - Set to any value to disable colored output (e.g., NO_COLOR=1 git commit) + +# Check if color output is disabled (set NO_COLOR=1 to disable) +: "${NO_COLOR:=}" + +# Initialize branch name from filtered branch list +init_branch_name() { + local list="issue spike task" + local listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/" + + BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //') +} + +# Check if hook should be skipped based on branch, reflog action, or flags +should_skip_hook() { + # Skip on specific branches + if echo "$BRANCH_NAME" | grep -qE '^(hotfix|rebase|prod(uction)?)$'; then + return 0 + fi + + # Skip if Git reflog indicates an amend (reliable for GUI flows) + if [ "${GIT_REFLOG_ACTION:-}" = "commit (amend)" ]; then + return 0 + fi + + # Fallback: check parent process for --no-verify or --amend flags + local ppid_cmd + ppid_cmd=$(ps -ocommand= -p $PPID 2>/dev/null || echo "") + if [[ "$ppid_cmd" == *"--no-verify"* ]] || [[ "$ppid_cmd" == *"--amend"* ]]; then + return 0 + fi + + return 1 +} + +# Print colored status messages (respects NO_COLOR environment variable) +print_header() { + if [ -z "$NO_COLOR" ]; then + printf '\n\033[0;105m%s\033[0m\n' "$1" + else + printf '\n%s\n' "$1" + fi +} + +print_success() { + if [ -z "$NO_COLOR" ]; then + printf '\n\033[0;32m%s\033[0m\n' "$1" + else + printf '\n%s\n' "$1" + fi +} + +print_warning() { + if [ -z "$NO_COLOR" ]; then + printf '\n\033[0;33m%s\033[0m\n' "$1" + else + printf '\n%s\n' "$1" + fi +} + +print_error() { + if [ -z "$NO_COLOR" ]; then + printf '\n\033[0;31m%s\033[0m\n' "$1" + else + printf '\n%s\n' "$1" + fi +} + +print_info() { + if [ -z "$NO_COLOR" ]; then + printf '\033[0;33m%s\033[0m\n' "$1" + else + printf '%s\n' "$1" + fi +} diff --git a/.githooks/post-commit b/.githooks/post-commit index 3c5ce5c..770a10e 100755 --- a/.githooks/post-commit +++ b/.githooks/post-commit @@ -5,27 +5,18 @@ # aborted. The hook can be bypassed by using the --no-verify option # when running "git commit". -# ! This could ask for user input to sign the commit as it's now using -# ! the `git commit` command instead of `git commit -m` which is -# ! the default behavior of the `git commit` command. This could be -# ! a problem if the user is not expecting it. This should be fixed -# ! in the future. -if [[ $(ps -ocommand= -p $PPID) == *"git"*"commit"*"--no-verify"* ]] || [[ $(ps -ocommand= -p $PPID) == *"git"*"commit"*"--amend"* ]]; then - printf '\n\033[0;33mSkipping post-commit hook... 🀨\033[0m\n' - exit 0 -fi - -list="issue spike task" - -listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/" +# Source common hook utilities +. "$(dirname "$0")/common.sh" -BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //') +# Initialize branch name +init_branch_name -printf '\n\033[0;105mChecking "%s"... \033[0m\n' "$BRANCH_NAME" +print_header "Checking \"$BRANCH_NAME\"..." -if echo "$BRANCH_NAME" | grep -q '^(hotfix)|(rebase)|(production)*$'; then - printf '\n\033[0;32mNo checks necessary on "%s", skipping hooks... πŸŽ‰\033[0m\n' "$BRANCH_NAME" - exit 0 +# Skip if on specific branches, or when amending or --no-verify flag is set +if should_skip_hook; then + print_warning "Skipping post-commit hook... 🀨" + exit 0 fi # Check for existence of "new or modified" test files @@ -33,56 +24,47 @@ NEW_TEST_FILES="$(git diff --diff-filter=ACDM --name-only --cached | grep -E '(. # Get all test files to run tests CURRENT_TEST_FILES="$(git ls-files | grep -i -E '(_test\.rb)$')" +RAILS_TEST_EXIT_CODE=0 WORK_DONE=0 -if [ -z "$NEW_TEST_FILES" ]; then - printf '\n\033[0;31mThere are currently no new tests found in "%s". 🀨\033[0m\n' "$BRANCH_NAME" - printf '\n\033[0;31mContinuing without new tests... πŸ˜–\033[0m\n' -fi - if [ -n "$NEW_TEST_FILES" ]; then #Count the number of new test files file_count=$(echo "$NEW_TEST_FILES" | wc -l) # Check if there are any new test files if [ "$file_count" -ne 0 ]; then - printf '\n\033[0;33mFound %d new test files in "%s" πŸŽ‰.\033[0m\n' "$file_count" "$BRANCH_NAME" + print_warning "Found $file_count new test files in \"$BRANCH_NAME\" πŸŽ‰." fi for file in $NEW_TEST_FILES; do # if file is system test file run rake test:system filename if [[ "$file" == *"./test/system/*_test.rb" ]]; then - printf '\n\033[0;33mRunning system test for "%s"...\033[0m\n', "$file" + print_warning "Running system test for \"$file\"..." bundle exec rake test:system "$file" else - printf '\n\033[0;33mRunning unit test on "%s"...\033[0m\n', "$file" + print_warning "Running unit test on \"$file\"..." bundle exec rake test "$file" fi + # Capture the exit code from the test command to determine if it passed or failed + if [ $? -ne 0 ]; then + RAILS_TEST_EXIT_CODE=1 + fi done + WORK_DONE=1 +elif [ -n "$CURRENT_TEST_FILES" ]; then + print_warning "No new tests found, running all Rails Tests ..." + make test RAILS_TEST_EXIT_CODE=$? WORK_DONE=1 -fi - -if [ -n "$CURRENT_TEST_FILES" ] && [ "$WORK_DONE" -eq 0 ]; then - printf '\nRunning all Rails Tests ...\n' - # make test - # RAILS_TEST_EXIT_CODE=$? - WORK_DONE=2 else - RAILS_TEST_EXIT_CODE=0 + print_error "No tests found in \"$BRANCH_NAME\". 🀨" + RAILS_TEST_EXIT_CODE=1 fi if [ ! "$RAILS_TEST_EXIT_CODE" -eq 0 ]; then git reset HEAD~ - printf '\n\033[0;31mCannot commit, tests are failing. Use --no-verify to force commit. πŸ˜–\033[0m\n' + print_error "Cannot commit, tests are failing. Use --no-verify to force commit. πŸ˜–" exit 1 fi -if [ "$WORK_DONE" -eq 1 ]; then - printf '\n\033[0;32mAll tests are green, committing... πŸŽ‰\033[0m\n' - exit 0 -fi - -if [ "$WORK_DONE" -eq 2 ]; then - printf '\n\033[0;41mCurrently skipping broken tests found on "%s". 🀨\033[0m\n' "$BRANCH_NAME" - exit 0 -fi +print_success "All tests are green, committing... πŸŽ‰" +exit 0 diff --git a/.githooks/pre-commit b/.githooks/pre-commit index e4f6a98..02d6ab2 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -3,45 +3,46 @@ # beware if you are in the habit of committing only partial modifications to a file: # THIS HOOK WILL ADD ALL MODIFICATIONS TO A FILE TO THE COMMIT IF ANY FILE WAS CHANGED BY LINTING -list="issue spike task" +# Source common hook utilities +. "$(dirname "$0")/common.sh" -listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/" +# Initialize branch name +init_branch_name -BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //') +print_header "Checking \"$BRANCH_NAME\"..." -printf '\n\033[0;105mChecking "%s"... \033[0m\n' "$BRANCH_NAME" - -if echo "$BRANCH_NAME" | grep -q '^(hotfix)|(rebase)|(production)*$'; then - printf '\n\033[0;32mNo checks necessary on "%s", skipping hooks... πŸŽ‰\033[0m\n' "$BRANCH_NAME" +if should_skip_hook; then + print_success "No checks necessary on \"$BRANCH_NAME\", pushing now... πŸŽ‰" exit 0 fi +# Identify staged Ruby-related files (including Gemfile/Rakefile) to lint before commit. RUBY_FILES="$(git diff --diff-filter=d --name-only --cached | grep -E '(Gemfile|Rakefile|\.(rb|rake|ru))$')" PRE_STATUS="$(git status | wc -l)" +# Initialise exit code variables to track success (0 = success) +RUBOCOP_EXIT_CODE=0 WORK_DONE=0 if [ -z "$RUBY_FILES" ]; then - printf '\n\033[0;31mThere are currently no updated files in "%s". 🀨\033[0m\n' "$BRANCH_NAME" -fi - -if [ -n "$RUBY_FILES" ]; then - printf '\n\033[0;33mRunning Rubocop...\033[0m\n' - for file in $RUBY_FILES; do - git show :"$file" | bundle exec rubocop -A --stdin "$file" - done + print_error "There are currently no updated files in \"$BRANCH_NAME\". 🀨" +else + print_warning "Running Rubocop..." + # Convert space-separated file list into positional parameters for safe argument passing + set -- $RUBY_FILES + # Execute RuboCop with auto-fix enabled on the staged files that have been set + bundle exec rubocop -a --force-exclusion -- "$@" + # Capture the exit code from RuboCop command (0 = success, non-zero = errors) RUBOCOP_EXIT_CODE=$? + # Flag that linting ran so we can report result and re-add files if needed. WORK_DONE=1 -else - printf '\n\033[0;32mContinuing as there are no changes to check... πŸŽ‰\033[0m\n' - RUBOCOP_EXIT_CODE=0 fi POST_STATUS="$(git status | wc -l)" if [ ! $RUBOCOP_EXIT_CODE -eq 0 ]; then git reset HEAD - printf '\n\033[0;31mLinting has uncorrectable errors; please fix and restage your commit. πŸ˜–\033[0m\n' + print_error "Linting has uncorrectable errors; please fix and restage your commit. πŸ˜–" exit 1 fi @@ -49,8 +50,8 @@ if [ "$PRE_STATUS" != "$POST_STATUS" ]; then git add "$RUBY_FILES" fi -if [ $WORK_DONE -eq 1 ]; then - printf '\n\033[0;32mLinting completed successfully! πŸŽ‰\033[0m\n' +if [ ! $WORK_DONE -eq 0 ]; then + print_success "Linting completed successfully! πŸŽ‰" fi exit 0 diff --git a/.githooks/pre-push b/.githooks/pre-push index baf4f2b..49bf372 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -1,64 +1,64 @@ #!/bin/bash +# Source common hook utilities +. "$(dirname "$0")/common.sh" + : "${CLIENT_PROFILE:=hmlr}" : "${API_SERVICE_URL:=http://data-api:8080}" : "${RUN_VARS:=--detach --publish}" -list="issue spike task" - -listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/" - -BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //') - -printf '\n\033[0;105mChecking "%s"... \033[0m\n' "$BRANCH_NAME" - -if echo "$BRANCH_NAME" | grep -q '^(hotfix)|(rebase)|(production)*$'; then - printf '\n\033[0;32mNo checks necessary on "%s", skipping hooks... πŸŽ‰\033[0m\n' "$BRANCH_NAME" - exit 0 -fi +# Initialize branch name +init_branch_name -# Skip hook if all staged files only markdown (.md) files -files=$(git diff --cached --name-only) -files_to_check=$(echo "$files" | grep '\.md$') +print_header "Checking \"$BRANCH_NAME\"..." -if [ -n "$files_to_check" ] && [ -z "$(echo "$files" | grep -v '\.md$')" ]; then - printf '\n\033[0;32mOnly markdown files staged (%s), skipping hook.\033[0m\n' "$files_to_check" +# Skip on specific branches, with --no-verify flag, or when amending +if should_skip_hook; then + print_success "Skipping pre-push hook... πŸŽ‰" exit 0 fi -# Check for existence of "new or modified" files +DOCKER_BUILD_EXIT_CODE=0 +DOCKER_RUN_EXIT_CODE=0 + if ! git update-index -q --ignore-submodules --refresh; then - printf '\n\033[0;31mUp-to-date check failedπŸ˜–\033[0m\n' + print_error "Up-to-date check failed πŸ˜–" DOCKER_BUILD_EXIT_CODE=1 else - printf '\n\033[0;33mBuilding Docker image with "%s" profile... \033[0m\n' "$CLIENT_PROFILE" + print_warning "Building Docker image with \"$CLIENT_PROFILE\" profile... " AWS_PROFILE=$CLIENT_PROFILE make image DOCKER_BUILD_EXIT_CODE=$? fi if [ $DOCKER_BUILD_EXIT_CODE -ne 0 ]; then - printf '\n\033[0;31mDocker image build failed. Please check your changes. πŸ˜–\033[0m\n' + print_error "Docker image build failed. Please check your changes. πŸ˜–" exit 1 -else - printf '\n\033[0;32mDocker image build succeeded. πŸŽ‰\033[0m\n' - CONTAINER_ID=$(make name) - printf '\n\033[0;33mRunning Docker image %s ... \033[0m\n' "$CONTAINER_ID" - AWS_PROFILE=$CLIENT_PROFILE API_SERVICE_URL=$API_SERVICE_URL RUN_VARS=$RUN_VARS make run - secs=5 - while [ $secs -gt -1 ]; do - echo -ne "$secs\033[0K\r" - sleep 1 - : $((secs--)) - done - docker inspect --format="{{.State.Running}}" "$CONTAINER_ID" | grep 'true' -q - DOCKER_RUN_EXIT_CODE=$? - printf '\n\033[0;33mStopping Docker image with exit code %s ... \033[0m\n' "$DOCKER_RUN_EXIT_CODE" - make stop fi +# Build succeeded, now run the container +print_success "Docker image build succeeded. πŸŽ‰" +CONTAINER_ID=$(make name) +print_warning "Running Docker image $CONTAINER_ID ... " +AWS_PROFILE=$CLIENT_PROFILE API_SERVICE_URL=$API_SERVICE_URL RUN_VARS=$RUN_VARS make run + +# Wait for container to stabilize +secs=5 +while [ $secs -gt -1 ]; do + echo -ne "$secs\033[0K\r" + sleep 1 + : $((secs--)) +done + +# Check if container is running +docker inspect --format="{{.State.Running}}" "$CONTAINER_ID" | grep 'true' -q +DOCKER_RUN_EXIT_CODE=$? + +print_warning "Stopping Docker image with exit code $DOCKER_RUN_EXIT_CODE ... " +make stop + if [ $DOCKER_RUN_EXIT_CODE -ne 0 ]; then - printf '\n\033[0;31mDocker image run failed. Please check your changes. πŸ˜–\033[0m\n' + print_error "Docker image run failed. Please check your changes. πŸ˜–" exit 1 else - printf '\n\033[0;32mDocker image run succeeded. πŸŽ‰\033[0m\n' + print_success "Docker image run succeeded. πŸŽ‰" exit 0 fi diff --git a/.gitignore b/.gitignore index b14c8df..23f37ea 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ tags # Ignore local configuration files .env* !.env.development + +# Ignore local TODO files +TODO.md diff --git a/.rubocop.yml b/.rubocop.yml index 4aca5fc..ee50283 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,11 +2,11 @@ plugins: - rubocop-rails AllCops: - TargetRubyVersion: 3.3 Exclude: - "Gemfile" NewCops: enable +# Customised rules Layout/LineLength: Max: 100 AllowedPatterns: ['^(\s*#)'] @@ -42,6 +42,10 @@ Naming/MethodParameterName: Exclude: - test/**/* +Style/Documentation: + Exclude: + - test/**/* + Style/FormatStringToken: Enabled: false @@ -49,9 +53,6 @@ Style/OptionalBooleanParameter: Enabled: false Style/ClassAndModuleChildren: - Exclude: - - test/**/* - -Style/Documentation: + EnforcedStyle: nested Exclude: - test/**/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 643bdcc..5fc0e46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added test coverage reporting with SimpleCov and a `coverage` Makefile target. + [#207](https://github.com/epimorphics/lr-landing/issues/207) + +### Changed + +- Upgraded `rubocop` and updated linting configuration. + [#208](https://github.com/epimorphics/lr-landing/issues/208) +- Bumped development tooling: `byebug`, `solargraph`, and `ruby-lsp`. + [#208](https://github.com/epimorphics/lr-landing/issues/208) +- Bumped runtime libraries including `jquery-rails`, `puma`, and Rails for + compatibility and stability. + [#201](https://github.com/epimorphics/lr-landing/issues/201) +- Refactored Sentry initialisation and updated logger configuration. +- Unified Makefile targets and modernised build behaviour. +- Updated asset pipeline precompile messaging. +- Reconciled divergent branches and consolidated dependency updates. + [#206](https://github.com/epimorphics/lr-landing/issues/206) + +### Fixed + +- Handled non-zero exit codes from `bundle outdated` during dependency checks. +- Updated git hooks to improve pre-commit / pre-push workflow. +- Corrected exception message wording and improved error logging. +- Fixed hooks API SERVICE URL default value. + +### Security + +- Updated several third-party libraries to address security and compatibility + issues. + ## [2.3.0] - 2026-01 ### Changed diff --git a/Gemfile b/Gemfile index 243b528..c08b313 100644 --- a/Gemfile +++ b/Gemfile @@ -21,6 +21,13 @@ gem 'dartsass-sprockets', '~> 3.2' gem 'haml-rails' +# The Qonsole Rails gem depends on a forked version of jquery-datatables-rails +# to include a fix that has not yet been merged into the main repo. See: +# https://stackoverflow.com/a/68001592/5760177 +gem 'jquery-datatables-rails', '~> 3.5.0', + github: 'marlinpierce/jquery-datatables-rails', + branch: 'master-3.5' + gem 'get_process_mem' gem 'http_accept_language' gem 'prometheus-client' @@ -38,6 +45,11 @@ group :development, :test do gem 'rubocop-rails' end +group :test do + gem 'simplecov', require: false +end + + group :development do gem 'derailed_benchmarks' gem 'ruby-lsp' diff --git a/Gemfile.lock b/Gemfile.lock index d6c096e..2322c05 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,34 +7,45 @@ GIT rack-contrib (>= 1.1, < 3) railties (>= 3.0.0, < 9) +GIT + remote: https://github.com/marlinpierce/jquery-datatables-rails.git + revision: ff67ccfd7b064e0512465186e962e0078d570517 + branch: master-3.5 + specs: + jquery-datatables-rails (3.5.0) + actionpack (>= 3.1) + jquery-rails (~> 4.3) + railties (>= 3.1) + sassc-rails (~> 2.0) + GEM remote: https://rubygems.org/ specs: - action_text-trix (2.1.15) + action_text-trix (2.1.16) railties - actioncable (8.1.1) - actionpack (= 8.1.1) - activesupport (= 8.1.1) + actioncable (8.1.2) + actionpack (= 8.1.2) + activesupport (= 8.1.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (8.1.1) - actionpack (= 8.1.1) - activejob (= 8.1.1) - activerecord (= 8.1.1) - activestorage (= 8.1.1) - activesupport (= 8.1.1) + actionmailbox (8.1.2) + actionpack (= 8.1.2) + activejob (= 8.1.2) + activerecord (= 8.1.2) + activestorage (= 8.1.2) + activesupport (= 8.1.2) mail (>= 2.8.0) - actionmailer (8.1.1) - actionpack (= 8.1.1) - actionview (= 8.1.1) - activejob (= 8.1.1) - activesupport (= 8.1.1) + actionmailer (8.1.2) + actionpack (= 8.1.2) + actionview (= 8.1.2) + activejob (= 8.1.2) + activesupport (= 8.1.2) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (8.1.1) - actionview (= 8.1.1) - activesupport (= 8.1.1) + actionpack (8.1.2) + actionview (= 8.1.2) + activesupport (= 8.1.2) nokogiri (>= 1.8.5) rack (>= 2.2.4) rack-session (>= 1.0.1) @@ -42,36 +53,36 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (8.1.1) + actiontext (8.1.2) action_text-trix (~> 2.1.15) - actionpack (= 8.1.1) - activerecord (= 8.1.1) - activestorage (= 8.1.1) - activesupport (= 8.1.1) + actionpack (= 8.1.2) + activerecord (= 8.1.2) + activestorage (= 8.1.2) + activesupport (= 8.1.2) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (8.1.1) - activesupport (= 8.1.1) + actionview (8.1.2) + activesupport (= 8.1.2) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (8.1.1) - activesupport (= 8.1.1) + activejob (8.1.2) + activesupport (= 8.1.2) globalid (>= 0.3.6) - activemodel (8.1.1) - activesupport (= 8.1.1) - activerecord (8.1.1) - activemodel (= 8.1.1) - activesupport (= 8.1.1) + activemodel (8.1.2) + activesupport (= 8.1.2) + activerecord (8.1.2) + activemodel (= 8.1.2) + activesupport (= 8.1.2) timeout (>= 0.4.0) - activestorage (8.1.1) - actionpack (= 8.1.1) - activejob (= 8.1.1) - activerecord (= 8.1.1) - activesupport (= 8.1.1) + activestorage (8.1.2) + actionpack (= 8.1.2) + activejob (= 8.1.2) + activerecord (= 8.1.2) + activesupport (= 8.1.2) marcel (~> 1.0) - activesupport (8.1.1) + activesupport (8.1.2) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) @@ -91,14 +102,15 @@ GEM base64 (0.3.0) benchmark (0.5.0) benchmark-ips (2.14.0) - bigdecimal (3.3.1) + bigdecimal (4.0.1) bindex (0.8.1) - bootstrap (5.3.5) + bootstrap (5.3.8) popper_js (>= 2.11.8, < 3) builder (3.3.0) - byebug (12.0.0) - concurrent-ruby (1.3.5) - connection_pool (2.5.4) + byebug (13.0.0) + reline (>= 0.6.0) + concurrent-ruby (1.3.6) + connection_pool (3.0.2) crass (1.0.6) dartsass-sprockets (3.2.1) railties (>= 4.0.0) @@ -106,7 +118,7 @@ GEM sprockets (> 3.0) sprockets-rails tilt - date (3.5.0) + date (3.5.1) derailed_benchmarks (2.2.1) base64 benchmark-ips (~> 2) @@ -126,9 +138,10 @@ GEM ruby2_keywords thor (>= 0.19, < 2) diff-lcs (1.6.2) + docile (1.4.1) dotenv (3.2.0) drb (2.2.3) - erb (5.1.3) + erb (6.0.1) erubi (1.13.1) execjs (2.10.0) faraday (2.14.0) @@ -143,14 +156,14 @@ GEM net-http (~> 0.5) faraday-retry (2.4.0) faraday (~> 2.0) - ffi (1.17.2-aarch64-linux-gnu) - ffi (1.17.2-aarch64-linux-musl) - ffi (1.17.2-arm-linux-gnu) - ffi (1.17.2-arm-linux-musl) - ffi (1.17.2-arm64-darwin) - ffi (1.17.2-x86_64-darwin) - ffi (1.17.2-x86_64-linux-gnu) - ffi (1.17.2-x86_64-linux-musl) + ffi (1.17.3-aarch64-linux-gnu) + ffi (1.17.3-aarch64-linux-musl) + ffi (1.17.3-arm-linux-gnu) + ffi (1.17.3-arm-linux-musl) + ffi (1.17.3-arm64-darwin) + ffi (1.17.3-x86_64-darwin) + ffi (1.17.3-x86_64-linux-gnu) + ffi (1.17.3-x86_64-linux-musl) font-awesome-rails (4.7.0.9) railties (>= 3.2, < 9.0) get_process_mem (1.0.0) @@ -158,25 +171,25 @@ GEM ffi (~> 1.0) globalid (1.3.0) activesupport (>= 6.1) - google-protobuf (4.33.2) + google-protobuf (4.33.4) bigdecimal rake (>= 13) - google-protobuf (4.33.2-aarch64-linux-gnu) + google-protobuf (4.33.4-aarch64-linux-gnu) bigdecimal rake (>= 13) - google-protobuf (4.33.2-aarch64-linux-musl) + google-protobuf (4.33.4-aarch64-linux-musl) bigdecimal rake (>= 13) - google-protobuf (4.33.2-arm64-darwin) + google-protobuf (4.33.4-arm64-darwin) bigdecimal rake (>= 13) - google-protobuf (4.33.2-x86_64-darwin) + google-protobuf (4.33.4-x86_64-darwin) bigdecimal rake (>= 13) - google-protobuf (4.33.2-x86_64-linux-gnu) + google-protobuf (4.33.4-x86_64-linux-gnu) bigdecimal rake (>= 13) - google-protobuf (4.33.2-x86_64-linux-musl) + google-protobuf (4.33.4-x86_64-linux-musl) bigdecimal rake (>= 13) govuk_elements_rails (3.0.2) @@ -187,7 +200,7 @@ GEM railties (>= 3.1.0) govuk_template (0.26.0) rails (>= 3.1) - haml (6.3.0) + haml (7.2.0) temple (>= 0.8.2) thor tilt @@ -199,10 +212,10 @@ GEM heapy (0.2.0) thor http_accept_language (2.1.1) - i18n (1.14.7) + i18n (1.14.8) concurrent-ruby (~> 1.0) - io-console (0.8.1) - irb (1.15.2) + io-console (0.8.2) + irb (1.16.0) pp (>= 0.6.0) rdoc (>= 4.0.0) reline (>= 0.4.2) @@ -210,18 +223,13 @@ GEM jbuilder (2.14.1) actionview (>= 7.0.0) activesupport (>= 7.0.0) - jquery-datatables-rails (3.4.0) - actionpack (>= 3.1) - jquery-rails - railties (>= 3.1) - sass-rails - jquery-rails (4.6.0) + jquery-rails (4.6.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - json (2.15.2) - kramdown (2.5.1) - rexml (>= 3.3.9) + json (2.18.0) + kramdown (2.5.2) + rexml (>= 3.4.4) kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) language_server-protocol (3.17.0.5) @@ -234,7 +242,7 @@ GEM activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.24.1) + loofah (2.25.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.9.0) @@ -247,14 +255,15 @@ GEM memory_profiler (1.1.0) mini_histogram (0.3.1) mini_mime (1.1.5) - minitest (5.26.0) + minitest (6.0.1) + prism (~> 1.5) modernizr-rails (2.7.1) modulejs-rails (2.2.0.0) railties (>= 4.0) mutex_m (0.3.0) net-http (0.9.1) uri (>= 0.11.1) - net-imap (0.5.12) + net-imap (0.6.2) date net-protocol net-pop (0.1.2) @@ -264,45 +273,46 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.5) - nokogiri (1.18.10-aarch64-linux-gnu) + nokogiri (1.19.0-aarch64-linux-gnu) racc (~> 1.4) - nokogiri (1.18.10-aarch64-linux-musl) + nokogiri (1.19.0-aarch64-linux-musl) racc (~> 1.4) - nokogiri (1.18.10-arm-linux-gnu) + nokogiri (1.19.0-arm-linux-gnu) racc (~> 1.4) - nokogiri (1.18.10-arm-linux-musl) + nokogiri (1.19.0-arm-linux-musl) racc (~> 1.4) - nokogiri (1.18.10-arm64-darwin) + nokogiri (1.19.0-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.10-x86_64-darwin) + nokogiri (1.19.0-x86_64-darwin) racc (~> 1.4) - nokogiri (1.18.10-x86_64-linux-gnu) + nokogiri (1.19.0-x86_64-linux-gnu) racc (~> 1.4) - nokogiri (1.18.10-x86_64-linux-musl) + nokogiri (1.19.0-x86_64-linux-musl) racc (~> 1.4) observer (0.1.2) + open3 (0.2.1) ostruct (0.6.3) parallel (1.27.0) - parser (3.3.9.0) + parser (3.3.10.1) ast (~> 2.4.1) racc popper_js (2.11.8) pp (0.6.3) prettyprint prettyprint (0.2.0) - prism (1.4.0) + prism (1.9.0) prometheus-client (4.2.5) base64 - psych (5.2.6) + psych (5.3.1) date stringio - puma (6.6.1) + puma (7.2.0) nio4r (~> 2.0) - puma-metrics (1.4.0) + puma-metrics (1.5.0) prometheus-client (>= 0.10) - puma (>= 6.0) + puma (>= 6.6.0, != 7.0.0) racc (1.8.1) - rack (3.2.3) + rack (3.2.4) rack-contrib (2.5.0) rack (< 4) rack-session (2.1.1) @@ -310,22 +320,22 @@ GEM rack (>= 3.0.0) rack-test (2.2.0) rack (>= 1.3) - rackup (2.2.1) + rackup (2.3.1) rack (>= 3) - rails (8.1.1) - actioncable (= 8.1.1) - actionmailbox (= 8.1.1) - actionmailer (= 8.1.1) - actionpack (= 8.1.1) - actiontext (= 8.1.1) - actionview (= 8.1.1) - activejob (= 8.1.1) - activemodel (= 8.1.1) - activerecord (= 8.1.1) - activestorage (= 8.1.1) - activesupport (= 8.1.1) + rails (8.1.2) + actioncable (= 8.1.2) + actionmailbox (= 8.1.2) + actionmailer (= 8.1.2) + actionpack (= 8.1.2) + actiontext (= 8.1.2) + actionview (= 8.1.2) + activejob (= 8.1.2) + activemodel (= 8.1.2) + activerecord (= 8.1.2) + activestorage (= 8.1.2) + activesupport (= 8.1.2) bundler (>= 1.15.0) - railties (= 8.1.1) + railties (= 8.1.2) rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest @@ -333,9 +343,9 @@ GEM rails-html-sanitizer (1.6.2) loofah (~> 2.21) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (8.1.1) - actionpack (= 8.1.1) - activesupport (= 8.1.1) + railties (8.1.2) + actionpack (= 8.1.2) + activesupport (= 8.1.2) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -347,21 +357,22 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rbs (3.6.1) + rbs (3.10.3) logger - rdoc (6.15.0) + tsort + rdoc (7.1.0) erb psych (>= 4.0.0) tsort - regexp_parser (2.11.2) - reline (0.6.2) + regexp_parser (2.11.3) + reline (0.6.3) io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) - reverse_markdown (3.0.0) + reverse_markdown (3.0.2) nokogiri - rexml (3.4.2) - rubocop (1.80.1) + rexml (3.4.4) + rubocop (1.84.0) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -369,19 +380,19 @@ GEM parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.46.0, < 2.0) + rubocop-ast (>= 1.49.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.46.0) + rubocop-ast (1.49.0) parser (>= 3.3.7.2) - prism (~> 1.4) - rubocop-rails (2.33.3) + prism (~> 1.7) + rubocop-rails (2.34.3) activesupport (>= 4.2.0) lint_roller (~> 1.1) rack (>= 1.1) rubocop (>= 1.75.0, < 2.0) rubocop-ast (>= 1.44.0, < 2.0) - ruby-lsp (0.26.1) + ruby-lsp (0.26.5) language_server-protocol (~> 3.17.0) prism (>= 1.2, < 2.0) rbs (>= 3, < 5) @@ -390,27 +401,25 @@ GEM ruby2_keywords (0.0.5) sass (3.7.4) sass-listen (~> 4.0.0) - sass-embedded (1.97.1-aarch64-linux-gnu) + sass-embedded (1.97.3-aarch64-linux-gnu) google-protobuf (~> 4.31) - sass-embedded (1.97.1-aarch64-linux-musl) + sass-embedded (1.97.3-aarch64-linux-musl) google-protobuf (~> 4.31) - sass-embedded (1.97.1-arm-linux-gnueabihf) + sass-embedded (1.97.3-arm-linux-gnueabihf) google-protobuf (~> 4.31) - sass-embedded (1.97.1-arm-linux-musleabihf) + sass-embedded (1.97.3-arm-linux-musleabihf) google-protobuf (~> 4.31) - sass-embedded (1.97.1-arm64-darwin) + sass-embedded (1.97.3-arm64-darwin) google-protobuf (~> 4.31) - sass-embedded (1.97.1-x86_64-darwin) + sass-embedded (1.97.3-x86_64-darwin) google-protobuf (~> 4.31) - sass-embedded (1.97.1-x86_64-linux-gnu) + sass-embedded (1.97.3-x86_64-linux-gnu) google-protobuf (~> 4.31) - sass-embedded (1.97.1-x86_64-linux-musl) + sass-embedded (1.97.3-x86_64-linux-musl) google-protobuf (~> 4.31) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sass-rails (6.0.0) - sassc-rails (~> 2.1, >= 2.1.1) sassc (2.4.0) ffi (~> 1.9) sassc-embedded (1.80.8) @@ -422,31 +431,40 @@ GEM sprockets-rails tilt securerandom (0.4.1) - sentry-rails (5.26.0) - railties (>= 5.0) - sentry-ruby (~> 5.26.0) - sentry-ruby (5.26.0) + sentry-rails (6.3.0) + railties (>= 5.2.0) + sentry-ruby (~> 6.3.0) + sentry-ruby (6.3.0) bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) - solargraph (0.56.2) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.13.2) + simplecov_json_formatter (0.1.4) + solargraph (0.58.2) + ast (~> 2.4.3) backport (~> 1.2) benchmark (~> 0.4) - bundler (~> 2.0) + bundler (>= 2.0) diff-lcs (~> 1.4) jaro_winkler (~> 1.6, >= 1.6.1) kramdown (~> 2.3) kramdown-parser-gfm (~> 1.1) logger (~> 1.6) observer (~> 0.1) + open3 (~> 0.2.1) ostruct (~> 0.6) parser (~> 3.0) prism (~> 1.4) - rbs (~> 3.6.1) + rbs (>= 3.6.1, <= 4.0.0.dev.4) reverse_markdown (~> 3.0) - rubocop (~> 1.38) + rubocop (~> 1.76) thor (~> 1.0) tilt (~> 2.0) yard (~> 0.9, >= 0.9.24) + yard-activesupport-concern (~> 0.0) yard-solargraph (~> 0.1) sprockets (4.2.2) concurrent-ruby (~> 1.0) @@ -457,20 +475,20 @@ GEM activesupport (>= 6.1) sprockets (>= 3.0.0) stackprof (0.2.27) - stringio (3.1.7) - temple (0.10.3) + stringio (3.2.0) + temple (0.10.4) terser (1.2.6) execjs (>= 0.3.0, < 3) - thor (1.4.0) - tilt (2.6.1) - timeout (0.4.4) + thor (1.5.0) + tilt (2.7.0) + timeout (0.6.0) tsort (0.2.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (3.1.5) - unicode-emoji (~> 4.0, >= 4.0.4) - unicode-emoji (4.0.4) - uri (1.1.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) + uri (1.1.1) useragent (0.16.11) web-console (4.2.1) actionview (>= 6.0.0) @@ -481,10 +499,12 @@ GEM base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - yard (0.9.37) + yard (0.9.38) + yard-activesupport-concern (0.0.1) + yard (>= 0.8) yard-solargraph (0.1.0) yard (~> 0.9) - zeitwerk (2.7.3) + zeitwerk (2.7.4) GEM remote: https://rubygems.pkg.github.com/epimorphics/ @@ -493,7 +513,7 @@ GEM json lograge railties - lr_common_styles (3.0.0) + lr_common_styles (3.0.1) bootstrap (~> 5.3.2) font-awesome-rails (~> 4.7.0) govuk_elements_rails (= 3.0.2) @@ -505,14 +525,14 @@ GEM modernizr-rails (~> 2.7) modulejs-rails (~> 2.2.0) rails (~> 8.0) - qonsole_rails (2.4.0) + qonsole_rails (2.4.1) faraday (~> 2.13) faraday-encoding (~> 0.0, >= 0.0.6) faraday-follow_redirects (~> 0.3, >= 0.3.0) faraday-retry (~> 2.0) font-awesome-rails (~> 4.7.0) haml-rails (~> 3.0) - jquery-datatables-rails (~> 3.4) + jquery-datatables-rails (= 3.5.0) jquery-rails (~> 4.6) lodash-rails (~> 4.17) modulejs-rails (~> 2.2.0) @@ -522,7 +542,9 @@ PLATFORMS aarch64-linux-gnu aarch64-linux-musl arm-linux-gnu + arm-linux-gnueabihf arm-linux-musl + arm-linux-musleabihf arm64-darwin x86_64-darwin x86_64-linux-gnu @@ -538,6 +560,7 @@ DEPENDENCIES haml-rails http_accept_language jbuilder + jquery-datatables-rails (~> 3.5.0)! jquery-rails json_rails_logger! lr_common_styles! @@ -551,10 +574,11 @@ DEPENDENCIES rubocop-rails ruby-lsp sentry-rails + simplecov solargraph stackprof terser web-console BUNDLED WITH - 2.7.2 + 4.0.5 diff --git a/Makefile b/Makefile index 9f0f594..fe89fbd 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: assets auth check clean image lint publish realclean run tag test update vars +.PHONY: all assets auth bundles check checks clean compiled coverage forceclean help image lint local name publish realclean rubocop run server start stop tag test update vars version ALPINE_VERSION?=3.22 BUNDLER_VERSION?=$(shell tail -1 Gemfile.lock | tr -d ' ') @@ -38,7 +38,7 @@ ${GITHUB_TOKEN}: all: image ## Default target: build the Docker image -assets: bundles compiled ## Compile assets for serving +assets: bundles compiled ## Compile static assets for serving @echo assets completed. auth: ${GITHUB_TOKEN} ${BUNDLE_CFG} ## Set up authentication for GitHub and Bundler @@ -49,7 +49,6 @@ bundles: ## Install Ruby gems via Bundler @${BUNDLE} install check: checks ## Alias for `checks` target - @echo "All checks passed." checks: lint test ## Run all checks: linting and tests @echo "All checks passed." @@ -64,9 +63,13 @@ clean: ## Clean up temporary and compiled files @@ rm -rf bundle coverage log node_modules tmp compiled: ## Compile assets for production - @echo "Removing old compiled assets and compiling ..." + @echo "Cleaning and precompiling static assets ..." @${RAILS} assets:clobber assets:precompile +coverage: ## Display test coverage report + @open coverage/index.html + @echo "Displaying test coverage report in browser..." + forceclean: realclean ## Remove all bundled files @${BUNDLE} clean --force || : @@ -74,8 +77,14 @@ help: ## Display this message @echo "Available make targets:" @grep -hE '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-20s %s\n", $$1, $$2}' @echo "" + @echo "" +ifdef AWS_PROFILE @echo "Environment variables (optional: all variables have defaults):" @make vars +else + @echo "Warning: AWS_PROFILE environment variable is not set. AWS CLI commands may fail." + @echo "Re-run with AWS_PROFILE set to see all variables" +endif image: auth ## Build the Docker image @echo Building ${REPO}:${TAG} ... @@ -141,12 +150,13 @@ test: ## Run unit tests update: ## Review and update dependencies interactively @echo "Checking for outdated dependencies..." - @if command -v yarn &> /dev/null; then \ + @if [ -f package.json ]; then \ echo "Running yarn upgrade-interactive..."; \ yarn upgrade-interactive; \ fi @echo "Running bundle outdated to check Ruby gems..." - @bundle outdated +# Let bundler handle output; treat this as informational even if deps are outdated + @${BUNDLE} outdated --only-explicit || true vars: ## Display environment variables @echo "Docker: ${REPO}:${TAG}" diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 41b4a70..547bfcd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # :nodoc: -class ApplicationController < ActionController::Base +class ApplicationController < ActionController::Base # rubocop:disable Metrics/ClassLength include Log # Prevent CSRF attacks by raising an exception. @@ -59,15 +59,15 @@ def log_response # or attempt to render a generic error page if no specific error page exists unless Rails.application.config.consider_all_requests_local rescue_from StandardError do |e| - puts "[ApplicationController] Caught exception: #{e.class}: #{e.message}" + Rails.logger.error "[ApplicationController] Caught exception: #{e.class}: #{e.message}" # Trigger the appropriate error handling method based on the exception case e.class when ActionController::RoutingError, ActionView::MissingTemplate - :render_404 + :render404 when ActionController::InvalidCrossOriginRequest - :render_403 + :render403 when ActionController::BadRequest, ActionController::ParameterMissing - :render_400 + :render400 else :handle_internal_error end @@ -86,9 +86,7 @@ def handle_internal_error(exception) # rubocop:disable Metrics/MethodLength logged_fields = { status: Rack::Utils::HTTP_STATUS_CODES[exception] } - if Rails.logger.debug? - logged_fields[:backtrace] = exception.backtrace.join("\n") - end + logged_fields[:backtrace] = exception.backtrace.join("\n") if Rails.logger.debug? Log.error( "No explicit error page for #{exception.class.name} - #{exception}", logged_fields @@ -100,19 +98,19 @@ def handle_internal_error(exception) # rubocop:disable Metrics/MethodLength end end - def render_400(_exception = nil) # rubocop:disable Naming/VariableNumber + def render400(_exception = nil) render_error(400) end - def render_403(_exception = nil) # rubocop:disable Naming/VariableNumber + def render403(_exception = nil) render_error(403) end - def render_404(_exception = nil) # rubocop:disable Naming/VariableNumber + def render404(_exception = nil) render_error(404) end - def render_500(_exception = nil) # rubocop:disable Naming/VariableNumber + def render500(_exception = nil) render_error(500) end @@ -144,7 +142,7 @@ def version private - #! UNUSED METHOD - kept for reference + # ! UNUSED METHOD - kept for reference # Set the Sentry user context for error tracking def set_sentry_user return unless signed_in? && Rails.env.production? @@ -193,17 +191,18 @@ def instrument_application_error(exc) # rubocop:disable Metrics/CyclomaticComple # Source: https://discuss.rubyonrails.org/t/how-to-reduce-memory-footprint-of-a-rails-app/39388/6 # Reference: https://man7.org/linux/man-pages/man1/ps.1.html def log_resource_usage - if Rails.env.production? # && Rails.logger.debug? - x,psr,etime,pcpu,pmem,rss,vsz = `ps -o psr,etime,pcpu,pmem,rss,vsz -p #{Process.pid}`&.split('\n')[1]&.split(/\s+/) - resources = { psr:, etime:, pcpu:, pmem:, rss:, vsz: } - Rails.logger.info( - "***DEBUG: resource_usage: + return unless Rails.env.development? || Rails.logger.debug? + + psr, etime, pcpu, pmem, rss, vsz = `ps -o psr,etime,pcpu,pmem,rss,vsz -p #{Process.pid}`.split('\n')&.[](1)&.split(/\s+/) # rubocop:disable Layout/LineLength + resources = { psr:, etime:, pcpu:, pmem:, rss:, vsz: } + Rails.logger.info( + "***DEBUG: resource_usage: rails_env=#{Rails.env} pid=#{Process.pid} #{resources.compact!.map { |k, v| "#{k}=#{v}" }.join(' ')} req_method=#{request.method} req_uri=#{request.url} - ") - end + " + ) end end diff --git a/app/views/exceptions/error_page.html.haml b/app/views/exceptions/error_page.html.haml index b6d1282..1288379 100644 --- a/app/views/exceptions/error_page.html.haml +++ b/app/views/exceptions/error_page.html.haml @@ -10,8 +10,8 @@ %p We're sorry, but the request you made was not understood. If you are requesting data via a script or program, please check the URL parameters. If you see this - message as a result of using the HPI or PPD applications, please let us - know so that we can correct the problem. + message as a result of using the House Price Index or Price Paid Data applications, + please let usknow so that we can correct the problem. - elsif status == 403 %h1.o-heading--1 Request denied @@ -41,9 +41,9 @@ %h1.o-heading--1 Application error %p - We're very sorry, but the request you just made resulted in an internal - error in the UKHPI application. If this problem persists, please use one of the contact - methods below to report the problem to us so that we can resolve it and + We're very sorry, but the request you just made resulted in an internal error + in the application. If this problem persists, please use one of the contact + methods below to report the problem to us, so that we can resolve it and help you get the data you require. - if sentry_code diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb index 43e7162..ffadc2f 100644 --- a/config/initializers/sentry.rb +++ b/config/initializers/sentry.rb @@ -3,43 +3,41 @@ require 'version' Rails.application.reloader.to_prepare do - if ENV['SENTRY_API_KEY'] - Sentry.init do |config| - # https://docs.sentry.io/platforms/ruby/configuration/options/#breadcrumbs-logger - config.breadcrumbs_logger = %i[sentry_logger monotonic_active_support_logger http_logger] - # * The DSN tells the SDK where to send events. - config.dsn = ENV['SENTRY_API_KEY'] - # ! Only report errors in these environments: - config.enabled_environments = %w[production prod preprod dev] - # ! Ignore exceptions that are not useful to us - config.excluded_exceptions += [ - 'ActionController::BadRequest', - 'ActionController::RoutingError', - 'ActiveRecord::RecordNotFound' - ] - # * Set the environment name from the SENTRY_ENVIRONMENT configuration value - config.environment = ENV.fetch('SENTRY_ENVIRONMENT', Rails.env) - # ^ Default to only reporting info, warnings and errors to Sentry - config.logger.level = Rails.application.config.log_level || :info - # * Set the release version to the current version - config.release = Version::VERSION - # * Set traces_sample_rate to 1.0 to capture 100% of transactions for tracing. - config.traces_sample_rate = Rails.env.development? ? 1.0 : 0.1 - # ! Sentry recommends adjusting this value in production hence the ternary operator. - # * Set profiles_sample_rate to profile 100% of sampled transactions. - config.profiles_sample_rate = Rails.env.production? ? 1.0 : 0.1 - # ! Sentry recommends adjusting this value in production hence the ternary operator. - end - - # * Set additional tags for the Sentry event to allow for better filtering in the Sentry UI - # ? These tags are set in either a local .env file or the instance configuration - # ! Remove any nil values from the sentry_tags hash before setting the tags - sentry_tags = { - 'band' => ENV.fetch('SENTRY_BAND', nil), - 'enabled' => ENV.fetch('SENTRY_ENABLED', nil), - 'hostname' => ENV.fetch('SENTRY_HOSTNAME', nil) - }.compact! - # * Set the tags in the Sentry event with remaining values but only if there are any - sentry_tags&.each { |k, v| Sentry.set_tags(k.to_s => v) } + Sentry.init do |config| + # https://docs.sentry.io/platforms/ruby/configuration/options/#breadcrumbs-logger + config.breadcrumbs_logger = %i[sentry_logger monotonic_active_support_logger http_logger] + # * The DSN tells the SDK where to send events. + config.dsn = ENV.fetch('SENTRY_API_KEY', nil) + # ! Only report errors in these environments: + config.enabled_environments = %w[production prod preprod dev] + # ! Ignore exceptions that are not useful to us + config.excluded_exceptions += [ + 'ActionController::BadRequest', + 'ActionController::RoutingError', + 'ActiveRecord::RecordNotFound' + ] + # * Set the environment name from the SENTRY_ENVIRONMENT configuration value + config.environment = ENV.fetch('SENTRY_ENVIRONMENT', Rails.env) + # ^ Default to only reporting info, warnings and errors to Sentry + config.sdk_logger.level = Rails.application.config.log_level || :info + # * Set the release version to the current version + config.release = Version::VERSION + # * Set traces_sample_rate to 1.0 to capture 100% of transactions for tracing. + config.traces_sample_rate = Rails.env.development? ? 1.0 : 0.1 + # ! Sentry recommends adjusting this value in production hence the ternary operator. + # * Set profiles_sample_rate to profile 100% of sampled transactions. + config.profiles_sample_rate = Rails.env.production? ? 1.0 : 0.1 + # ! Sentry recommends adjusting this value in production hence the ternary operator. end + + # * Set additional tags for the Sentry event to allow for better filtering in the Sentry UI + # ? These tags are set in either a local .env file or the instance configuration + # ! Remove any nil values from the sentry_tags hash before setting the tags + sentry_tags = { + 'band' => ENV.fetch('SENTRY_BAND', nil), + 'enabled' => ENV.fetch('SENTRY_ENABLED', nil), + 'hostname' => ENV.fetch('SENTRY_HOSTNAME', nil) + }.compact! + # * Set the tags in the Sentry event with remaining values but only if there are any + sentry_tags&.each { |k, v| Sentry.set_tags(k.to_s => v) } end diff --git a/test/test_helper.rb b/test/test_helper.rb index 1170ba0..8cf21a6 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -3,6 +3,13 @@ ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../config/environment', __dir__) +require 'simplecov' +SimpleCov.start 'rails' do + add_filter '/test/' + add_filter '/config/' + add_filter '/vendor/' +end + # Removed link to rails/test_help since it's causing an error initialising # ActiveRecord, which we don't need. So I've just transcluded the contents # of that file