Skip to content

Commit ff4b0ae

Browse files
authored
Merge pull request #238 from fastruby/feature/docker-rubies-ci
Fix CI by running benchmarks in Docker
2 parents 2342b8a + 1464d01 commit ff4b0ae

5 files changed

Lines changed: 192 additions & 60 deletions

File tree

‎.github/workflows/benchmarks.yml‎

Lines changed: 12 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -9,73 +9,25 @@ on:
99
jobs:
1010
rake:
1111
runs-on: ubuntu-latest
12+
timeout-minutes: 60
1213

1314
strategy:
15+
fail-fast: false
1416
matrix:
15-
ruby-version: [
16-
'ruby-head', '3.2', '3.1', '3.0', '2.7', '2.6', '2.5', '2.4',
17-
'jruby-head',
18-
'truffleruby-head'
17+
# Service names from compose.yaml
18+
ruby: [
19+
'ruby_head', 'ruby_4.0', 'ruby_3.4', 'ruby_3.3', 'ruby_3.2', 'ruby_3.1',
20+
'ruby_3.0', 'ruby_2.7', 'ruby_2.6', 'ruby_2.5', 'ruby_2.4', 'ruby_2.3',
21+
'ruby_2.2', 'ruby_2.1',
22+
'jruby_head', 'jruby_9.1',
23+
'truffleruby_head', 'truffleruby_22'
1924
]
2025

2126
steps:
2227
- name: Set Share Env
2328
if: github.ref_name == 'main'
2429
run: |
2530
echo "SHARE=1" >> $GITHUB_ENV
26-
- uses: actions/checkout@v3
27-
- name: Set up Ruby ${{ matrix.ruby-version }}
28-
uses: ruby/setup-ruby@v1
29-
with:
30-
ruby-version: ${{ matrix.ruby-version }}
31-
- name: Install dependencies
32-
run: bundle install
33-
- name: Run benchmarks
34-
run: bundle exec rake
35-
36-
rake_old:
37-
runs-on: ubuntu-22.04
38-
39-
strategy:
40-
matrix:
41-
ruby-version: [
42-
'jruby-9.1',
43-
'truffleruby-22'
44-
]
45-
46-
steps:
47-
- name: Set Share Env
48-
if: github.ref_name == 'main'
49-
run: |
50-
echo "SHARE=1" >> $GITHUB_ENV
51-
- uses: actions/checkout@v3
52-
- name: Set up Ruby ${{ matrix.ruby-version }}
53-
uses: ruby/setup-ruby@v1
54-
with:
55-
ruby-version: ${{ matrix.ruby-version }}
56-
- name: Install dependencies
57-
run: bundle install
58-
- name: Run benchmarks
59-
run: bundle exec rake
60-
61-
rake_older:
62-
runs-on: ubuntu-20.04
63-
64-
strategy:
65-
matrix:
66-
ruby-version: ['2.3', '2.2', '2.1']
67-
68-
steps:
69-
- name: Set Share Env
70-
if: github.ref_name == 'main'
71-
run: |
72-
echo "SHARE=1" >> $GITHUB_ENV
73-
- uses: actions/checkout@v3
74-
- name: Set up Ruby ${{ matrix.ruby-version }}
75-
uses: ruby/setup-ruby@v1
76-
with:
77-
ruby-version: ${{ matrix.ruby-version }}
78-
- name: Install dependencies
79-
run: bundle install
80-
- name: Run benchmarks
81-
run: bundle exec rake
31+
- uses: actions/checkout@v4
32+
- name: Run benchmarks on ${{ matrix.ruby }}
33+
run: docker compose run --rm -T ${{ matrix.ruby }}

‎CONTRIBUTING.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,23 @@ Run your result:
3434
$ ruby -v code/your-new/entry.rb
3535
```
3636

37+
To run it on a Ruby you don't have installed, use Docker. There is one service
38+
per Ruby in the CI matrix (see `compose.yaml`):
39+
40+
```
41+
docker compose run --rm ruby_2.1 code/your-new/entry.rb
42+
docker compose run --rm truffleruby_head code/your-new/entry.rb
43+
```
44+
45+
Without a file argument, the service runs every benchmark, the same way CI does.
46+
47+
The `*_head` and `truffleruby_22` images are built once and then reused, so
48+
the head builds go stale. To get the latest nightly build:
49+
50+
```
51+
docker compose build --no-cache ruby_head
52+
```
53+
3754
Thanks in advance!!! Look forward to learning more from you!
3855

3956
<3 [JuanitoFatas](https://twitter.com/juanitofatas)

‎compose.yaml‎

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Run the benchmarks on any Ruby from the CI matrix without installing it:
2+
#
3+
# docker compose run --rm ruby_2.1
4+
#
5+
# CI runs the same services, see .github/workflows/benchmarks.yml.
6+
7+
x-benchmark: &benchmark
8+
volumes:
9+
- .:/app
10+
working_dir: /app
11+
environment:
12+
- SHARE
13+
entrypoint: ["/app/docker/run-benchmarks.sh"]
14+
15+
services:
16+
ruby_4.0:
17+
<<: *benchmark
18+
image: ruby:4.0
19+
20+
ruby_3.4:
21+
<<: *benchmark
22+
image: ruby:3.4
23+
24+
ruby_3.3:
25+
<<: *benchmark
26+
image: ruby:3.3
27+
28+
ruby_3.2:
29+
<<: *benchmark
30+
image: ruby:3.2
31+
32+
ruby_3.1:
33+
<<: *benchmark
34+
image: ruby:3.1
35+
36+
ruby_3.0:
37+
<<: *benchmark
38+
image: ruby:3.0
39+
40+
ruby_2.7:
41+
<<: *benchmark
42+
image: ruby:2.7
43+
44+
ruby_2.6:
45+
<<: *benchmark
46+
image: ruby:2.6
47+
48+
ruby_2.5:
49+
<<: *benchmark
50+
image: ruby:2.5
51+
52+
ruby_2.4:
53+
<<: *benchmark
54+
image: ruby:2.4
55+
56+
ruby_2.3:
57+
<<: *benchmark
58+
image: ruby:2.3
59+
60+
ruby_2.2:
61+
<<: *benchmark
62+
image: ruby:2.2
63+
64+
# Only amd64 images exist for these two; they run under emulation on arm64 hosts.
65+
ruby_2.1:
66+
<<: *benchmark
67+
image: ruby:2.1
68+
platform: linux/amd64
69+
70+
jruby_9.1:
71+
<<: *benchmark
72+
image: jruby:9.1
73+
platform: linux/amd64
74+
75+
# No official images for these, they are built from docker/Dockerfile.
76+
truffleruby_22:
77+
<<: *benchmark
78+
build:
79+
context: docker
80+
args:
81+
RUBY: truffleruby-22.3.1
82+
83+
ruby_head:
84+
<<: *benchmark
85+
build:
86+
context: docker
87+
args:
88+
RUBY: ruby-head
89+
90+
jruby_head:
91+
<<: *benchmark
92+
build:
93+
context: docker
94+
args:
95+
RUBY: jruby-head
96+
97+
truffleruby_head:
98+
<<: *benchmark
99+
build:
100+
context: docker
101+
args:
102+
RUBY: truffleruby-head

‎docker/Dockerfile‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Image for Rubies without an official Docker image: the nightly head builds
2+
# (the same ones ruby/setup-ruby uses) and TruffleRuby 22.
3+
FROM ubuntu:24.04
4+
5+
ARG RUBY=ruby-head
6+
ARG TARGETARCH
7+
8+
ENV DEBIAN_FRONTEND=noninteractive LANG=C.UTF-8
9+
10+
RUN apt-get update \
11+
&& apt-get install -y --no-install-recommends \
12+
ca-certificates curl build-essential git \
13+
libyaml-dev libssl-dev libffi-dev libgmp-dev libreadline-dev zlib1g-dev \
14+
&& case "$RUBY" in jruby-*) apt-get install -y --no-install-recommends openjdk-21-jre-headless ;; esac \
15+
&& rm -rf /var/lib/apt/lists/*
16+
17+
# The head builds are compiled with this prefix, so they must live here.
18+
WORKDIR /home/runner/.rubies
19+
20+
RUN case "$TARGETARCH" in \
21+
amd64) builder_arch=x64; oracle_arch=amd64 ;; \
22+
arm64) builder_arch=arm64; oracle_arch=aarch64 ;; \
23+
*) echo "unsupported arch: $TARGETARCH" >&2; exit 1 ;; \
24+
esac \
25+
&& case "$RUBY" in \
26+
ruby-head|jruby-head|truffleruby-head) \
27+
url="https://github.com/ruby/${RUBY%%-*}-dev-builder/releases/latest/download/$RUBY-ubuntu-24.04-$builder_arch.tar.gz" ;; \
28+
truffleruby-22.*) \
29+
version="${RUBY#truffleruby-}"; \
30+
url="https://github.com/oracle/truffleruby/releases/download/vm-$version/truffleruby-$version-linux-$oracle_arch.tar.gz" ;; \
31+
*) echo "unsupported RUBY: $RUBY" >&2; exit 1 ;; \
32+
esac \
33+
&& curl -fsSL "$url" | tar xz \
34+
&& if [ ! -d "$RUBY" ]; then mv truffleruby-* "$RUBY"; fi \
35+
&& if [ -x "$RUBY/lib/truffle/post_install_hook.sh" ]; then "$RUBY/lib/truffle/post_install_hook.sh"; fi
36+
37+
ENV PATH=/home/runner/.rubies/${RUBY}/bin:$PATH
38+
39+
RUN ruby -v
40+
41+
WORKDIR /app

‎docker/run-benchmarks.sh‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/sh
2+
# Runs the benchmarks inside a container: all of them by default, or only the
3+
# files passed as arguments. The Gemfile is copied out of the mounted repo so
4+
# each Ruby resolves its own Gemfile.lock and never touches the one on the host.
5+
set -e
6+
7+
mkdir -p /tmp/bundle
8+
cp /app/Gemfile /tmp/bundle/Gemfile
9+
export BUNDLE_GEMFILE=/tmp/bundle/Gemfile
10+
11+
bundle install
12+
13+
if [ "$#" -eq 0 ]; then
14+
exec bundle exec rake
15+
fi
16+
17+
for benchmark in "$@"; do
18+
echo "\$ ruby -v $benchmark"
19+
bundle exec ruby -v -W0 "$benchmark"
20+
done

0 commit comments

Comments
 (0)