Skip to content

Commit 3218803

Browse files
committedNov 21, 2024
Separate Appraisal runs from primary test runs
With Rails 8, the minimum version of Ruby becomes 3.2. Unless we drop support for prior Ruby versions (and also Rails versions), the way in which we were approaching CI can't work. Maintaining support for older Rails is not difficult because of Administrate itself, but how we approach testing so it feels unreasonable to drop support (which if we didn't test against it, we would effectively be doing) because it made CI harder to do. And we _can_ make it work, so we will. Previously, we ran the setup for the project as usual, and then ran setup for the Appraisals. This served two functions: 1. Make Appraisal available in the bundle, 2. Setup the database for running tests against However, in the CI matrix, we support multiple different versions of Ruby (3.0 and up to 3.3). As we try and add Rails 8.0, this means we can't run `bundle install` on those versions of Ruby below 3.2 as it's a dependency constraint on Rails itself. From experiments, we also can't: 1. Install Appraisal outside of the bundle, because it references gems in a way that Bundler is there to solve, 2. Load newer `schema.rb` files in older versions of Rails. Rails 7 introduced versioned schemas, and future schema versions can't be run with older versions of Rails. Instead, what we _can_ do is run the project setup inside a container configured to use the database in the CI environment, then manually do what Appraisal is doing to avoid issues bundling. This container will always use the current development version of Ruby (3.2.2, at the time of this commit) taken from the `.ruby-version` file, in which we run just enough to setup the database and ensure the later tests can run against it. It's unlikely that Administrate would do something which wasn't supported at the database level, but not impossible. However these tests would catch that (from experience: Rails falls back to a string on unknown types, so it's even less likely to fail). We also need to remove the Ruby version specification from the generated Appraisal gemfiles, as otherwise these won't install. Whilst they seemed to be valid outside of this way of running things, here, they are not. We just use `sed` to remove it in place, as it can be discarded later and removing it would cause problems with Heroku deployment of the demo app. Finally, we inline the previously extracted Action from #2524. The intent was to reduce duplication, but the order of operations are now so different it's not worth it and it would only be used in one place. Extracted from #2705. Re-inline extracted Action
1 parent d504990 commit 3218803

File tree

3 files changed

+83
-42
lines changed

3 files changed

+83
-42
lines changed
 

‎.github/actions/setup/action.yml

-38
This file was deleted.

‎.github/workflows/main.yml

+46-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
push:
55
branches:
66
- 'main'
7+
- 'nc-prepare-ci-for-rails-8'
78
pull_request:
89
types: [opened, synchronize, reopened]
910

@@ -34,9 +35,28 @@ jobs:
3435
--health-retries 5
3536
steps:
3637
- uses: actions/checkout@v4
37-
- uses: ./.github/actions/setup
38+
- name: Set up Ruby ${{ matrix.ruby }}
39+
uses: ruby/setup-ruby@v1
3840
with:
3941
ruby-version: ${{ matrix.ruby }}
42+
bundler-cache: true
43+
- name: Set up JS
44+
uses: actions/setup-node@v4
45+
with:
46+
cache: yarn
47+
- name: Install Ruby dependencies
48+
run: bundle install
49+
- name: Install Appraisal dependencies
50+
run: bundle exec appraisal install
51+
- name: Install JS dependencies
52+
run: yarn install
53+
- name: Setup the environment
54+
run: cp .sample.env .env
55+
- run: cp spec/example_app/config/database.yml.sample spec/example_app/config/database.yml
56+
- name: Setup the database
57+
run: bundle exec rake db:setup
58+
- name: Build assets
59+
run: yarn run build && yarn run build:css
4060
- name: Run tests
4161
run: bundle exec rspec
4262

@@ -70,8 +90,30 @@ jobs:
7090
--health-retries 5
7191
steps:
7292
- uses: actions/checkout@v4
73-
- uses: ./.github/actions/setup
93+
- name: Setup the environment
94+
run: cp .sample.env .env
95+
- run: cp spec/example_app/config/database.yml.sample spec/example_app/config/database.yml
96+
- name: Prepare main database schema
97+
run: bin/generate-database-schema
98+
- name: Set up Ruby ${{ matrix.ruby }}
99+
uses: ruby/setup-ruby@v1
74100
with:
75101
ruby-version: ${{ matrix.ruby }}
76-
- name: Appraise Rails ${{ matrix.appraisal }}
77-
run: bundle exec appraisal ${{ matrix.appraisal }} rspec
102+
- name: Set up JS
103+
uses: actions/setup-node@v4
104+
with:
105+
cache: yarn
106+
- name: Remove Ruby version specification
107+
run: sed -i 's/^ruby\(.*\)//g' gemfiles/${{ matrix.appraisal }}.gemfile
108+
- name: Install Ruby dependencies
109+
run: bundle install
110+
env:
111+
BUNDLE_GEMFILE: gemfiles/${{ matrix.appraisal }}.gemfile
112+
- name: Install JS dependencies
113+
run: yarn install
114+
- name: Build assets
115+
run: yarn run build && yarn run build:css
116+
- name: Run tests
117+
run: bundle exec rspec
118+
env:
119+
BUNDLE_GEMFILE: gemfiles/${{ matrix.appraisal }}.gemfile

‎bin/generate-database-schema

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
run_in_container() {
6+
container_id=$1
7+
shift
8+
cmd=$*
9+
10+
docker exec --workdir /app "$container_id" bash -c "$cmd"
11+
}
12+
13+
ruby_version=$(cat .ruby-version)
14+
owner=$(whoami)
15+
16+
echo "Starting container using Ruby $ruby_version..."
17+
container_id=$(
18+
docker run --network="host" \
19+
--env PGHOST --env PGUSER --env PGPASSWORD \
20+
-d -v .:/app ruby:"$ruby_version" sleep infinity
21+
)
22+
23+
echo "Check the environment is correct..."
24+
run_in_container "$container_id" "env"
25+
26+
echo "Run bundle install..."
27+
run_in_container "$container_id" "bundle install"
28+
29+
echo "Running db:setup..."
30+
run_in_container "$container_id" "bundle exec rake db:setup"
31+
32+
echo "Tidying up container..."
33+
docker stop "$container_id" > /dev/null
34+
docker rm "$container_id" > /dev/null
35+
36+
echo "Restoring file permissions..."
37+
sudo chown -R "$owner" .

0 commit comments

Comments
 (0)