CRuby Dev Builds #1638
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CRuby Dev Builds | |
on: | |
workflow_dispatch: | |
push: | |
tags: | |
- '*' | |
schedule: | |
- cron: '0 19 * * *' | |
jobs: | |
prepare: | |
name: Check if the latest ruby commit is already built | |
runs-on: ubuntu-latest | |
outputs: | |
should_build: ${{ steps.check_commit.outputs.result }} | |
commit: ${{ steps.latest_commit.outputs.commit }} | |
steps: | |
- name: Clone ruby | |
uses: actions/checkout@v4 | |
with: | |
repository: ruby/ruby | |
path: ruby | |
- name: Set latest_commit | |
id: latest_commit | |
working-directory: ruby | |
run: echo "commit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT | |
- name: Check if latest commit already built | |
uses: actions/github-script@v7 | |
id: check_commit | |
with: | |
script: | | |
const latestDevCommit = "${{ steps.latest_commit.outputs.commit }}" | |
const { owner, repo } = context.repo | |
let { data: release } = await github.rest.repos.getLatestRelease({ owner, repo }) | |
const latestReleaseCommit = release.body.split('@')[1] | |
console.log(`Latest release commit: ${latestReleaseCommit}`) | |
console.log(`Latest ruby commit: ${latestDevCommit}`) | |
if (latestReleaseCommit === latestDevCommit) { | |
return 'false' | |
} else { | |
return 'true' | |
} | |
result-encoding: string | |
release: | |
name: Create GitHub Release | |
needs: [prepare] | |
if: needs.prepare.outputs.should_build == 'true' | |
runs-on: ubuntu-latest | |
outputs: | |
tag: ${{ steps.tag.outputs.tag }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
if: github.event_name != 'push' | |
- name: Set tag name | |
id: tag | |
run: | | |
if [[ "${{ github.event_name }}" != "push" ]]; then | |
tag=v$(date +%Y%m%d.%H%M%S) | |
else | |
tag=$(basename "${{ github.ref }}") | |
fi | |
echo "tag=$tag" >> $GITHUB_OUTPUT | |
- name: Create Release | |
env: | |
GH_TOKEN: ${{ github.token }} | |
GH_REPO: ${{ github.repository }} | |
run: | | |
tag="${{ steps.tag.outputs.tag }}" | |
body="ruby/ruby@${{ needs.prepare.outputs.commit }}" | |
gh release create --draft "$tag" --title "$tag" --notes "$body" | |
build: | |
needs: [prepare, release] | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, macos-11, macos-arm-oss ] | |
name: [ head, debug ] | |
include: | |
- { os: ubuntu-24.04, name: asan } | |
runs-on: ${{ matrix.os }} | |
steps: | |
- name: Clone ruby | |
uses: actions/checkout@v4 | |
with: | |
repository: ruby/ruby | |
ref: ${{ needs.prepare.outputs.commit }} | |
- name: Clone ruby-dev-builder | |
uses: actions/checkout@v4 | |
with: | |
path: ruby-dev-builder | |
- name: Set platform | |
id: platform | |
run: | | |
platform=${{ matrix.os }} | |
platform=${platform/macos-11/macos-latest} | |
platform=${platform/macos-arm-oss/macos-13-arm64} | |
echo "platform=$platform" >> $GITHUB_OUTPUT | |
# Build | |
- name: apt-get update on Ubuntu | |
run: sudo apt-get update | |
if: startsWith(matrix.os, 'ubuntu') | |
- run: sudo apt-get install -y --no-install-recommends ruby bison libyaml-dev libgdbm-dev libreadline-dev libncurses5-dev | |
if: startsWith(matrix.os, 'ubuntu') | |
- run: brew install autoconf automake bison | |
if: startsWith(matrix.os, 'macos') | |
- run: echo "PATH=/usr/local/opt/bison/bin:$PATH" >> $GITHUB_ENV | |
if: startsWith(matrix.os, 'macos') | |
- name: Disable Firewall # Needed for TestSocket#test_udp_server in test-all | |
if: startsWith(matrix.os, 'macos') | |
run: | | |
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off | |
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate | |
# Check | |
- name: Setup BASERUBY | |
uses: ruby/setup-ruby@master | |
with: | |
ruby-version: 3.2 | |
# ENABLE_PATH_CHECK=0: https://github.com/actions/virtual-environments/issues/267 | |
- name: Set configure flags (head) | |
run: | | |
echo "cppflags=-DENABLE_PATH_CHECK=0" >> $GITHUB_ENV | |
if: matrix.name == 'head' | |
- name: Set configure flags (debug) | |
run: | | |
echo "cppflags=-DENABLE_PATH_CHECK=0 -DRUBY_DEBUG=1" >> $GITHUB_ENV | |
echo "optflags=-O3 -fno-inline" >> $GITHUB_ENV | |
if: matrix.name == 'debug' | |
- name: Build dependencies and set configure flags (asan) | |
run: | | |
set -ex | |
# We only test ASAN with Clang. The version of Clang needs to be > 18, which the version in | |
# Ubuntu 24.04's repo is | |
sudo apt-get install -y clang | |
# ASAN builds need to compile (some of) their own dependencies with ASAN enabled, so that it can | |
# catch memory errors caused by passing invalid parameters into other libraries. | |
ASAN_LIB_PREFIX="$HOME/.rubies/ruby-${{ matrix.name }}" | |
./ruby-dev-builder/asan_libs.rb \ | |
--prefix="$ASAN_LIB_PREFIX" \ | |
--cc=clang \ | |
--cflags="-fsanitize=address -fno-omit-frame-pointer -ggdb3 -O3" \ | |
--ldflags="-Wl,-rpath=$ASAN_LIB_PREFIX/lib" \ | |
--makeopts="-j4" | |
# Set Ruby configure flags | |
# Clang > 17 does not work with M:N threading, so we disable it: https://bugs.ruby-lang.org/issues/20243 | |
echo "cppflags=-DENABLE_PATH_CHECK=0 -DRUBY_DEBUG=1 -DVM_CHECK_MODE=1 -DUSE_MN_THREADS=0" >> $GITHUB_ENV | |
echo "optflags=-O3 -fno-omit-frame-pointer" >> $GITHUB_ENV | |
echo "debugflags=-fsanitize=address -ggdb3" >> $GITHUB_ENV | |
echo "CC=clang" >> $GITHUB_ENV | |
# Make sure we link against the ASAN libs we built | |
echo "cflags=-I$ASAN_LIB_PREFIX/include" >> $GITHUB_ENV | |
echo "LDFLAGS=-L$ASAN_LIB_PREFIX/lib -Wl,-rpath=$ASAN_LIB_PREFIX/lib" >> $GITHUB_ENV | |
# Make the test timeouts more generous too (ASAN is slower) | |
echo "RUBY_TEST_TIMEOUT_SCALE=5" >> $GITHUB_ENV | |
echo "SYNTAX_SUGGEST_TIMEOUT=600" >> $GITHUB_ENV | |
if: matrix.name == 'asan' | |
# Build | |
- run: mkdir -p ~/.rubies | |
- run: ./autogen.sh | |
- run: ./configure --prefix=$HOME/.rubies/ruby-${{ matrix.name }} --enable-shared --disable-install-doc --enable-yjit | |
if: startsWith(matrix.os, 'ubuntu') | |
- run: ./configure --prefix=$HOME/.rubies/ruby-${{ matrix.name }} --enable-shared --disable-install-doc --enable-yjit --with-openssl-dir=$(brew --prefix openssl@1.1) --with-readline-dir=$(brew --prefix readline) | |
if: startsWith(matrix.os, 'macos') | |
- run: make -j4 | |
- run: make install | |
- name: Create archive | |
run: tar czf ruby-${{ matrix.name }}-${{ steps.platform.outputs.platform }}.tar.gz -C ~/.rubies ruby-${{ matrix.name }} | |
# Test | |
- run: make test-spec MSPECOPT=-j | |
- run: make test-all TESTS="-j4" | |
- run: echo "$HOME/.rubies/ruby-${{ matrix.name }}/bin" >> $GITHUB_PATH | |
- uses: actions/checkout@v4 | |
with: | |
path: test_files | |
- name: CLI Test | |
run: ruby test_files/cli_test.rb | |
- run: mv test_files/Gemfile . | |
- run: ruby -e 'pp RbConfig::CONFIG' | |
- run: ruby --yjit -e 'exit RubyVM::YJIT.enabled?' | |
- run: ruby -ropen-uri -e 'puts URI.send(:open, "https://rubygems.org/") { |f| f.read(1024) }' | |
- run: gem install json:2.2.0 --no-document | |
- run: bundle install | |
- run: bundle exec rake --version | |
- name: Subprocess test | |
run: ruby -e 'p RbConfig::CONFIG["cppflags"]; def Warning.warn(s); raise s; end; system RbConfig.ruby, "-e", "p :OK"' | |
- name: Upload Built Ruby | |
env: | |
GH_TOKEN: ${{ github.token }} | |
GH_REPO: ${{ github.repository }} | |
run: gh release upload "${{ needs.release.outputs.tag }}" "ruby-${{ matrix.name }}-${{ steps.platform.outputs.platform }}.tar.gz" | |
publish: | |
name: Publish Release | |
needs: [release, build] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Publish Release | |
env: | |
GH_TOKEN: ${{ github.token }} | |
GH_REPO: ${{ github.repository }} | |
run: gh release edit "${{ needs.release.outputs.tag }}" --draft=false | |
- uses: eregon/keep-last-n-releases@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
n: 3 | |
remove_tags_without_release: true |