diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..f292eeaab --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,5 @@ +{ + "enabledPlugins": { + "dependency-track@skillwire": true + } +} diff --git a/.github/workflows/production_pipeline.yml b/.github/workflows/production_pipeline.yml index 45a31167f..6fc1c3b96 100644 --- a/.github/workflows/production_pipeline.yml +++ b/.github/workflows/production_pipeline.yml @@ -20,3 +20,14 @@ jobs: release_tag: ${{ needs.test.outputs.releasetag }} permissions: id-token: write + + sbom: + name: Upload SBOM + needs: [aws_deploy] + permissions: + contents: read + uses: ./.github/workflows/upload-sbom.yml + with: + projectversion: prod + secrets: + DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }} diff --git a/.github/workflows/staging_pipeline.yml b/.github/workflows/staging_pipeline.yml index a2e777db0..9187142d3 100644 --- a/.github/workflows/staging_pipeline.yml +++ b/.github/workflows/staging_pipeline.yml @@ -32,6 +32,15 @@ jobs: permissions: id-token: write + sbom: + name: Upload SBOM + needs: [aws_deploy] + uses: ./.github/workflows/upload-sbom.yml + with: + projectversion: staging + secrets: + DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }} + performance: needs: [aws_deploy] runs-on: ubuntu-latest diff --git a/.github/workflows/upload-sbom.yml b/.github/workflows/upload-sbom.yml new file mode 100644 index 000000000..da41affce --- /dev/null +++ b/.github/workflows/upload-sbom.yml @@ -0,0 +1,55 @@ +name: Upload SBOM + +# Generates a CycloneDX SBOM with Syft (auto-detects both the Ruby gems in +# Gemfile.lock and the Node packages in yarn.lock) and uploads it to +# Dependency-Track. Called from the staging and production pipelines after a +# successful deploy. + +on: + workflow_call: + inputs: + projectversion: + required: true + type: string + secrets: + DTRACK_API_KEY: + required: true + +permissions: + contents: read + +jobs: + sbom: + name: Generate and upload SBOM + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - run: | + echo "SYFT_VERSION=v1.45.0" >> "$GITHUB_ENV" + echo "SYFT_SCRIPT_SHA=9673f867e50398b5d25ec97ff051a451c46d262c" >> "$GITHUB_ENV" + + - uses: actions/cache@v4 + with: + path: /usr/local/bin/syft + key: syft-${{ env.SYFT_VERSION }} + + - name: Install Syft + run: | + [ -f /usr/local/bin/syft ] || \ + curl -sSfL "https://raw.githubusercontent.com/anchore/syft/${SYFT_SCRIPT_SHA}/install.sh" | sh -s -- -b /usr/local/bin "$SYFT_VERSION" + + - run: syft . -o cyclonedx-xml=bom.xml + + - name: Upload SBOM to Dependency-Track + env: + DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }} + SBOM_VERSION: ${{ inputs.projectversion }} + run: | + curl -sSf -X POST "https://api-deps.softwire.com/api/v1/bom" \ + -H "X-Api-Key: $DTRACK_API_KEY" \ + -F "autoCreate=true" \ + -F "projectName=CORE" \ + -F "projectVersion=$SBOM_VERSION" \ + -F "parentName=Support" \ + -F "bom=@bom.xml" diff --git a/Gemfile b/Gemfile index c76a48bec..0e5be060d 100644 --- a/Gemfile +++ b/Gemfile @@ -10,7 +10,7 @@ gem "rails", "~> 7.2.2" # Use postgresql as the database for Active Record gem "pg", "~> 1.1" # Use Puma as the app server -gem "puma", "~> 6.4" +gem "puma", "~> 7.2.1" # The modern asset pipeline for Rails [https://github.com/rails/propshaft] gem "propshaft" # Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails] @@ -18,7 +18,7 @@ gem "jsbundling-rails" # Reduces boot times through caching; required in config/boot.rb gem "bootsnap", ">= 1.4.4", require: false # GOV UK frontend components -gem "govuk-components", "~> 5.7" +gem "govuk-components", "~> 6.2" # GOV UK component form builder DSL gem "govuk_design_system_formbuilder", "~> 5.7" # Convert Markdown into GOV.UK frontend-styled HTML @@ -40,7 +40,7 @@ gem "devise_two_factor_authentication" gem "uk_postcode" # Get rich data from postcode lookups. Wraps postcodes.io # Use Ruby objects to build reusable markup. A React inspired evolution of the presenter pattern -gem "view_component", "~> 3.9" +gem "view_component", "~> 4.9" # Use the AWS S3 SDK as storage mechanism gem "aws-sdk-s3" # Track changes to models for auditing or versioning. @@ -67,7 +67,7 @@ gem "faker" gem "method_source", "~> 1.1" gem "rails_admin", "~> 3.1" gem "ruby-openai" -gem "sidekiq" +gem "sidekiq", "~> 7.2.4" gem "sidekiq-cron" gem "unread" diff --git a/Gemfile.lock b/Gemfile.lock index c83c95414..da3fe1c1f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -78,8 +78,8 @@ GEM minitest (>= 5.1, < 6) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) ast (2.4.3) auto_strip_attributes (2.6.0) activerecord (>= 4.0) @@ -123,7 +123,7 @@ GEM erubi (~> 1.4) parser (>= 2.4) smart_properties - bigdecimal (4.0.1) + bigdecimal (4.1.2) bindex (0.8.1) bootsnap (1.18.3) msgpack (~> 1.2) @@ -155,18 +155,21 @@ GEM coercible (1.0.0) descendants_tracker (~> 0.0.1) concurrent-ruby (1.3.6) - connection_pool (2.5.3) + connection_pool (2.5.5) crack (1.0.0) bigdecimal rexml crass (1.0.6) + cronex (0.15.0) + tzinfo + unicode (>= 0.4.4.5) cssbundling-rails (1.4.0) railties (>= 6.0.0) csv (3.3.2) date (3.5.1) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) - devise (5.0.3) + devise (5.0.4) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 7.0) @@ -187,7 +190,7 @@ GEM drb (2.2.3) dumb_delegator (1.0.0) encryptor (3.0.0) - erb (6.0.2) + erb (6.0.4) erb_lint (0.9.0) activesupport better_html (>= 2.0.1) @@ -196,7 +199,7 @@ GEM rubocop (>= 1) smart_properties erubi (1.13.1) - et-orbi (1.2.11) + et-orbi (1.4.0) tzinfo event_stream_parser (1.0.0) excon (0.111.0) @@ -207,24 +210,24 @@ GEM railties (>= 5.0.0) faker (3.2.3) i18n (>= 1.8.11, < 2) - faraday (2.14.1) + faraday (2.14.2) faraday-net_http (>= 2.0, < 3.5) json logger faraday-multipart (1.0.4) multipart-post (~> 2) - faraday-net_http (3.1.0) - net-http + faraday-net_http (3.4.3) + net-http (~> 0.5) ffi (1.16.3) - fugit (1.11.1) - et-orbi (~> 1, >= 1.2.11) + fugit (1.12.2) + et-orbi (~> 1.4) raabro (~> 1.4) - globalid (1.2.1) + globalid (1.3.0) activesupport (>= 6.1) - govuk-components (5.7.0) + govuk-components (6.2.0) html-attributes-utils (~> 1.0.0, >= 1.0.0) pagy (>= 6, < 10) - view_component (>= 3.9, < 3.17) + view_component (>= 4.9, < 4.10) govuk_design_system_formbuilder (5.7.1) actionview (>= 6.1) activemodel (>= 6.1) @@ -241,7 +244,7 @@ GEM ice_nine (0.11.2) iniparse (1.5.0) io-console (0.8.2) - irb (1.17.0) + irb (1.18.0) pp (>= 0.6.0) prism (>= 1.3.0) rdoc (>= 4.0.0) @@ -249,10 +252,10 @@ GEM jmespath (1.6.2) jsbundling-rails (1.3.0) railties (>= 6.0.0) - json (2.19.2) + json (2.19.8) json-schema (4.1.1) addressable (>= 2.8) - jwt (2.8.0) + jwt (3.2.0) base64 kaminari (1.2.2) activesupport (>= 4.1.0) @@ -290,9 +293,9 @@ GEM msgpack (1.7.2) multipart-post (2.4.1) nested_form (0.3.2) - net-http (0.4.1) - uri - net-imap (0.5.7) + net-http (0.9.1) + uri (>= 0.11.1) + net-imap (0.6.4.1) date net-protocol net-pop (0.1.2) @@ -301,23 +304,23 @@ GEM timeout net-smtp (0.5.1) net-protocol - nio4r (2.7.4) - nokogiri (1.19.1-arm64-darwin) + nio4r (2.7.5) + nokogiri (1.19.3-arm64-darwin) racc (~> 1.4) - nokogiri (1.19.1-x86_64-darwin) + nokogiri (1.19.3-x86_64-darwin) racc (~> 1.4) - nokogiri (1.19.1-x86_64-linux-gnu) + nokogiri (1.19.3-x86_64-linux-gnu) racc (~> 1.4) - nokogiri (1.19.1-x86_64-linux-musl) + nokogiri (1.19.3-x86_64-linux-musl) racc (~> 1.4) - notifications-ruby-client (6.0.0) - jwt (>= 1.5, < 3) + notifications-ruby-client (6.4.0) + jwt (>= 1.5, < 4) orm_adapter (0.5.0) overcommit (0.63.0) childprocess (>= 0.6.3, < 6) iniparse (~> 1.4) rexml (~> 3.2) - pagy (9.3.2) + pagy (9.4.0) paper_trail (15.2.0) activerecord (>= 6.1) request_store (~> 1.4) @@ -350,19 +353,19 @@ GEM psych (5.3.1) date stringio - public_suffix (5.0.4) - puma (6.5.0) + public_suffix (7.0.5) + puma (7.2.1) nio4r (~> 2.0) pundit (2.3.1) activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (3.1.20) + rack (3.1.21) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-mini-profiler (3.3.1) rack (>= 1.2.0) - rack-session (2.1.1) + rack-session (2.1.2) base64 (>= 0.1.0) rack (>= 3.0.0) rack-test (2.2.0) @@ -408,7 +411,7 @@ GEM tsort (>= 0.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.3.1) + rake (13.4.2) randexp (0.1.7) rb-fsevent (0.11.2) rb-inotify (0.10.1) @@ -419,7 +422,7 @@ GEM tsort redcarpet (3.6.0) redis (4.8.1) - redis-client (0.22.1) + redis-client (0.29.0) connection_pool regexp_parser (2.11.3) reline (0.6.3) @@ -513,10 +516,11 @@ GEM connection_pool (>= 2.3.0) rack (>= 2.2.4) redis-client (>= 0.19.0) - sidekiq-cron (1.12.0) - fugit (~> 1.8) + sidekiq-cron (2.4.0) + cronex (>= 0.13.0) + fugit (~> 1.8, >= 1.11.1) globalid (>= 1.0.1) - sidekiq (>= 6) + sidekiq (>= 6.5.0) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) @@ -530,7 +534,7 @@ GEM thor (1.4.0) thread_safe (0.3.6) timecop (0.9.8) - timeout (0.4.3) + timeout (0.6.1) tsort (0.2.0) turbo-rails (2.0.13) actionpack (>= 7.1.0) @@ -538,17 +542,18 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) uk_postcode (2.1.8) + unicode (0.4.4.5) unicode-display_width (3.2.0) unicode-emoji (~> 4.1) unicode-emoji (4.2.0) unread (0.14.0) activerecord (>= 6.1) - uri (1.0.4) + uri (1.1.1) useragent (0.16.11) - view_component (3.10.0) - activesupport (>= 5.2.0, < 8.0) - concurrent-ruby (~> 1.0) - method_source (~> 1.0) + view_component (4.9.0) + actionview (>= 7.1.0) + activesupport (>= 7.1.0) + concurrent-ruby (~> 1) virtus (2.0.0) axiom-types (~> 0.1) coercible (~> 1.0) @@ -571,7 +576,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.7.5) + zeitwerk (2.8.2) PLATFORMS arm64-darwin @@ -599,7 +604,7 @@ DEPENDENCIES factory_bot_rails faker faraday (>= 2.14.1) - govuk-components (~> 5.7) + govuk-components (~> 6.2) govuk_design_system_formbuilder (~> 5.7) govuk_markdown jsbundling-rails @@ -616,7 +621,7 @@ DEPENDENCIES possessive propshaft pry-byebug - puma (~> 6.4) + puma (~> 7.2.1) pundit rack (~> 3.1.20) rack-attack @@ -634,7 +639,7 @@ DEPENDENCIES selenium-webdriver sentry-rails sentry-ruby - sidekiq + sidekiq (~> 7.2.4) sidekiq-cron simplecov stimulus-rails @@ -643,7 +648,7 @@ DEPENDENCIES tzinfo-data uk_postcode unread - view_component (~> 3.9) + view_component (~> 4.9) web-console (>= 4.1.0) webmock diff --git a/app/components/bulk_upload_error_row_component.html.erb b/app/components/bulk_upload_error_row_component.html.erb index 8cfdb674e..4ce6e4f5c 100644 --- a/app/components/bulk_upload_error_row_component.html.erb +++ b/app/components/bulk_upload_error_row_component.html.erb @@ -13,7 +13,7 @@ <% if critical_errors.any? %>
These errors must be fixed to complete your logs.
- <%= govuk_table(html_attributes: { class: potential_errors.any? ? "" : "no-bottom-border" }) do |table| %> + <%= helpers.govuk_table(html_attributes: { class: potential_errors.any? ? "" : "no-bottom-border" }) do |table| %> <%= table.with_head do |head| %> <% head.with_row do |row| %> <% row.with_cell(header: true, text: "Cell") %> @@ -39,7 +39,7 @@ <% if potential_errors.any? %>Potential data discrepancies exist in the following cells.
Please resolve all critical errors and review the cells with data discrepancies before re-uploading the file. Bulk confirmation of potential discrepancies is accessible only after all critical errors have been resolved.