Merge pull request #6606 from betagouv/faster-ci

Accélération du temps des tests sur la CI
This commit is contained in:
Pierre de La Morinerie 2021-11-09 11:06:44 +01:00 committed by GitHub
commit ad083aec70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 226 additions and 81 deletions

View file

@ -0,0 +1,17 @@
name: 'Save split-tests'
description: 'Save Junit test results and timing data, to better split future tests'
inputs:
results_path:
description: 'Glob pattern to the JUnit files to save'
required: true
# This should be run once the results from all runs are collected.
runs:
using: composite
steps:
- name: Save test reports
uses: actions/cache@v2
with:
path: ${{ inputs.results_path }}
key: tests-reports-${{ github.ref }}-${{ github.sha }}-${{ github.run_id }}

View file

@ -0,0 +1,26 @@
name: 'Setup Rails assets'
description: 'Pre-compile and cache the app assets'
runs:
using: composite
steps:
- name: Assets cache
uses: actions/cache@v2
with:
path: |
public/assets
public/packs-test
tmp/cache/webpacker
key: asset-cache-${{ runner.os }}-${{ github.ref }}-${{ github.sha }}
restore-keys: |
asset-cache-${{ runner.os }}-${{ github.ref }}-${{ github.sha }}
asset-cache-${{ runner.os }}-${{ github.ref }}-
asset-cache-${{ runner.os }}-
- name: Precompile assets
env:
RAILS_ENV: test
run: |
rm bin/yarn
bin/rails assets:precompile --trace
shell: bash

View file

@ -0,0 +1,31 @@
name: 'Setup Rails app'
description: 'Setup the environment for running the Rails app'
runs:
using: composite
steps:
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '14'
cache: 'yarn'
- name: Install Node modules
run: yarn install --frozen-lockfile
shell: bash
- name: Setup environment variables
run: cp config/env.example .env
shell: bash
- name: Setup test database
env:
RAILS_ENV: test
DATABASE_URL: "postgres://tps_test@localhost:5432/tps_test"
run: bin/rails db:create db:schema:load db:migrate
shell: bash

View file

@ -0,0 +1,46 @@
name: 'Setup split-tests'
description: 'Setup the environment for splitting tests'
inputs:
results_path:
description: 'Glob pattern to the JUnit files to save'
required: true
runs:
using: composite
steps:
- name: Setup split_tests binary
run: |
curl --no-progress-meter -L https://github.com/leonid-shevtsov/split_tests/releases/download/v0.3.0/split_tests.linux.gz | gunzip -c > split_tests
chmod +x split_tests
shell: bash
- name: Generate an unique random value
run: echo dummy_random_value=$RANDOM >> $GITHUB_ENV
shell: bash
# Restore previous runs timing from the cache.
#
# NB: at the end of the job, the `actions/cache@v2` action will attempt
# to save the results back to the same key. However at this stage only
# tests results for a single instance will be available.
#
# To avoid the cache being overwritten with this single result, we define
# a random cache key, which the action will use to save the single-instance
# report to a dummy location.
#
# The actual retrieval uses the `restore-keys` instead.
- name: Restore previous runs timings
uses: actions/cache@v2
with:
path: ${{ inputs.results_path }}
key: single-instance-report-${{ github.sha }}-${{ env.dummy_random_value }}
restore-keys: |
tests-reports-${{ github.ref }}-${{ github.sha }}-${{ github.run_id }}
tests-reports-${{ github.ref }}-${{ github.sha }}-
tests-reports-${{ github.ref }}-
tests-reports-
- name: Display previous runs timings used for splitting tests
run: ls ${{ inputs.results_path }} || true
shell: bash

View file

@ -9,39 +9,28 @@ jobs:
linters: linters:
name: Linters name: Linters
runs-on: ubuntu-latest runs-on: ubuntu-latest
services:
postgres:
image: postgres:12
env:
POSTGRES_USER: tps_test
POSTGRES_DB: tps_test
POSTGRES_PASSWORD: tps_test
ports: [ "5432:5432" ]
steps: steps:
- name: Checkout code - uses: actions/checkout@v2
uses: actions/checkout@v2
- name: Setup Ruby - name: Setup the app code and dependancies
uses: ruby/setup-ruby@v1 uses: ./.github/actions/ci-setup-rails
with:
bundler-cache: true
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Find yarn cache location
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: JS package cache
uses: actions/cache@v2
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install packages
run: |
yarn install --frozen-lockfile
- name: Run linters - name: Run linters
run: | run: |
bundle exec rake lint bundle exec rake lint
bundle exec rake zeitwerk:check
tests: unit_tests:
name: Tests name: Unit tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:
postgres: postgres:
@ -54,55 +43,91 @@ jobs:
strategy: strategy:
matrix: matrix:
pattern: instances: [0, 1, 2, 3, 4, 5]
- bin/rake zeitwerk:check
- bin/rspec spec/controllers/*_spec.rb
- bin/rspec spec/controllers/[a-l]**/*_spec.rb
- bin/rspec spec/controllers/[m-z]**/*_spec.rb
- bin/rspec spec/system
- bin/rspec spec/helpers spec/lib spec/middlewares
- bin/rspec spec/mailers spec/jobs spec/policies
- bin/rspec spec/models
- bin/rspec spec/serializers spec/services
- bin/rspec spec/views
steps: steps:
- name: Checkout code - uses: actions/checkout@v2
uses: actions/checkout@v2
- name: Setup Ruby - name: Setup the app runtime and dependencies
uses: ruby/setup-ruby@v1 uses: ./.github/actions/ci-setup-rails
- name: Pre-compile assets
uses: ./.github/actions/ci-setup-assets
- name: Setup split tests
uses: ./.github/actions/ci-setup-split-tests
with: with:
bundler-cache: true results_path: tmp/*.junit.xml
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Find yarn cache location
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: JS package cache
uses: actions/cache@v2
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install packages
run: |
yarn install --frozen-lockfile
- name: Setup test database
env:
RAILS_ENV: test
DATABASE_URL: "postgres://tps_test@localhost:5432/tps_test"
run: |
bundle exec rake db:create db:schema:load db:migrate
- name: Setup environment variables
run: |
cp config/env.example .env
- name: Run tests - name: Run tests
run: ${{ matrix.pattern }} run: |
SPEC_FILES=$(./split_tests -glob='spec/**/*_spec.rb' -exclude-glob='spec/system/**' -split-index=${{ strategy.job-index }} -split-total=${{ strategy.job-total }} -junit -junit-path=tmp/*.junit.xml)
echo "Running tests for bin/rspec $SPEC_FILES"
bin/rspec $SPEC_FILES --format progress --format RspecJunitFormatter --out tmp/rspec_${{ github.job }}_${{ strategy.job-index }}.junit.xml
- name: Upload test results for this instance
uses: actions/upload-artifact@v2
with:
name: test-reports
path: tmp/rspec_${{ github.job }}_${{ strategy.job-index }}.junit.xml
system_tests:
name: System tests
runs-on: ubuntu-latest
services:
postgres:
image: postgres:12
env:
POSTGRES_USER: tps_test
POSTGRES_DB: tps_test
POSTGRES_PASSWORD: tps_test
ports: ["5432:5432"]
strategy:
matrix:
instances: [0, 1]
steps:
- uses: actions/checkout@v2
- name: Setup the app runtime and dependencies
uses: ./.github/actions/ci-setup-rails
- name: Pre-compile assets
uses: ./.github/actions/ci-setup-assets
- name: Setup split tests
uses: ./.github/actions/ci-setup-split-tests
with:
results_path: tmp/*.junit.xml
- name: Run tests
run: |
SPEC_FILES=$(./split_tests -glob='spec/system/**/*_spec.rb' -split-index=${{ strategy.job-index }} -split-total=${{ strategy.job-total }} -junit -junit-path=tmp/*.junit.xml)
echo "Running tests for bin/rspec $SPEC_FILES"
bin/rspec $SPEC_FILES --format progress --format RspecJunitFormatter --out tmp/rspec_${{ github.job }}_${{ strategy.job-index }}.junit.xml
- name: Upload test results for this instance
uses: actions/upload-artifact@v2
with:
name: test-reports
path: tmp/rspec_${{ github.job }}_${{ strategy.job-index }}.junit.xml
save_test_reports:
name: Save test reports
needs: [unit_tests, system_tests]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Collect test results from all instances
uses: actions/download-artifact@v2
with:
name: test-reports
path: tmp
- name: Save test results and timing data, to better split future tests
uses: ./.github/actions/ci-save-split-tests
with:
results_path: tmp/*.junit.xml

1
.rspec
View file

@ -1,2 +1,3 @@
--color --color
--require rails_helper --require rails_helper
--profile

View file

@ -92,6 +92,7 @@ group :test do
gem 'factory_bot' gem 'factory_bot'
gem 'launchy' gem 'launchy'
gem 'rails-controller-testing' gem 'rails-controller-testing'
gem 'rspec_junit_formatter'
gem 'selenium-webdriver' gem 'selenium-webdriver'
gem 'shoulda-matchers', require: false gem 'shoulda-matchers', require: false
gem 'timecop' gem 'timecop'

View file

@ -596,6 +596,8 @@ GEM
rspec-mocks (~> 3.10) rspec-mocks (~> 3.10)
rspec-support (~> 3.10) rspec-support (~> 3.10)
rspec-support (3.10.2) rspec-support (3.10.2)
rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0)
rubocop (1.10.0) rubocop (1.10.0)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 3.0.0.0) parser (>= 3.0.0.0)
@ -856,6 +858,7 @@ DEPENDENCIES
rgeo-geojson rgeo-geojson
rqrcode rqrcode
rspec-rails rspec-rails
rspec_junit_formatter
rubocop rubocop
rubocop-rails_config rubocop-rails_config
rubocop-rspec-focused rubocop-rspec-focused

View file

@ -3525,15 +3525,10 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2" lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0" lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001039, caniuse-lite@^1.0.30001219: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001039, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001254:
version "1.0.30001228" version "1.0.30001271"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001271.tgz"
integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== integrity sha512-BBruZFWmt3HFdVPS8kceTBIguKxu4f99n5JNp06OlPD/luoAMIaIK5ieV5YjnBLH3Nysai9sxj9rpJj4ZisXOA==
caniuse-lite@^1.0.30001254:
version "1.0.30001257"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001257.tgz#150aaf649a48bee531104cfeda57f92ce587f6e5"
integrity sha512-JN49KplOgHSXpIsVSF+LUyhD8PUp6xPpAXeRrrcBh4KBeP7W864jHn6RvzJgDlrReyeVjMFJL3PLpPvKIxlIHA==
cardinal@^2.1.1: cardinal@^2.1.1:
version "2.1.1" version "2.1.1"