diff options
Diffstat (limited to '.github/workflows')
23 files changed, 2464 insertions, 645 deletions
diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml new file mode 100644 index 0000000000..589672b4bb --- /dev/null +++ b/.github/workflows/annocheck.yml @@ -0,0 +1,112 @@ +name: Annocheck + +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + +jobs: + compile: + name: test-annocheck + + runs-on: ubuntu-latest + + container: + image: ghcr.io/ruby/ruby-ci-image:gcc-11 + options: --user root + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + env: + CONFIGURE_TTY: never + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + RUBY_DEBUG: ci rgengc + RUBY_TESTOPTS: >- + -q + --color=always + --tty=no + # FIXME: Drop skipping options + # https://bugs.ruby-lang.org/issues/18061 + # https://sourceware.org/annobin/annobin.html/Test-pie.html + TEST_ANNOCHECK_OPTS: '--skip-pie --skip-gaps' + + steps: + - run: id + working-directory: + + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + + - uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 + with: + ruby-version: '3.0' + bundler: none + + # Minimal flags to pass the check. + # -g0 disables backtraces when SEGV. Do not set that. + - name: Run configure + run: > + ../src/configure -C + --enable-debug-env + --disable-install-doc + --with-ext=-test-/cxxanyargs,+ + --without-valgrind + --without-jemalloc + --without-gmp + --with-gcc="gcc-11 -fcf-protection -Wa,--generate-missing-build-notes=yes" + --enable-shared + debugflags=-ggdb3 + optflags=-O2 + LDFLAGS=-Wl,-z,now + + - run: make showflags + + - run: make + + - run: make test-annocheck + + - uses: ./.github/actions/slack + with: + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} + +defaults: + run: + working-directory: build diff --git a/.github/workflows/auto_request_review.yml b/.github/workflows/auto_request_review.yml new file mode 100644 index 0000000000..ca27244b46 --- /dev/null +++ b/.github/workflows/auto_request_review.yml @@ -0,0 +1,19 @@ +name: Auto Request Review +on: + pull_request_target: + types: [opened, ready_for_review, reopened] + +permissions: + contents: read + +jobs: + auto-request-review: + name: Auto Request Review + runs-on: ubuntu-latest + if: ${{ github.repository == 'ruby/ruby' && github.base_ref == 'master' }} + steps: + - name: Request review based on files changes and/or groups the author belongs to + uses: necojackarc/auto-request-review@e89da1a8cd7c8c16d9de9c6e763290b6b0e3d424 # v0.13.0 + with: + # scope: public_repo + token: ${{ secrets.MATZBOT_GITHUB_TOKEN }} diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml index 788ca8f474..ac0d5f967f 100644 --- a/.github/workflows/baseruby.yml +++ b/.github/workflows/baseruby.yml @@ -1,46 +1,77 @@ name: BASERUBY Check -on: [push, pull_request] +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read jobs: baseruby: name: BASERUBY + runs-on: ubuntu-20.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + strategy: matrix: ruby: - - ruby-2.2 -# - ruby-2.3 -# - ruby-2.4 -# - ruby-2.5 -# - ruby-2.6 - - ruby-2.7 - ruby-3.0 + - ruby-3.1 + - ruby-3.2 + - ruby-3.3 steps: - - uses: actions/checkout@v2 - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 with: ruby-version: ${{ matrix.ruby }} bundler: none - - run: echo "make=make -sj$((1 + $(nproc --all)))" >> $GITHUB_ENV - - run: sudo apt-get install build-essential autoconf bison - - run: ./autogen.sh + + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + - uses: ./.github/actions/setup/ubuntu + + - uses: ./.github/actions/setup/directories + with: + makeup: true + - run: ./configure --disable-install-doc - - run: $make common-srcs - - run: $make incs - - run: $make all - - run: $make test - - uses: k0kubun/action-slack@v2.0.0 + + - run: make all + + - run: make test + + - uses: ./.github/actions/slack with: - payload: | - { - "ci": "GitHub Actions", - "env": "${{ github.workflow }} / BASERUBY @ ${{ matrix.ruby }}", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref }}".split('/').reverse()[0] - } - env: + label: ${{ matrix.ruby }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml index d46c0704cd..fcc005239b 100644 --- a/.github/workflows/bundled_gems.yml +++ b/.github/workflows/bundled_gems.yml @@ -1,66 +1,135 @@ name: bundled_gems on: + push: + branches: ['master'] + paths: + - '.github/workflows/bundled_gems.yml' + - 'gems/bundled_gems' + pull_request: + branches: ['master'] + paths: + - '.github/workflows/bundled_gems.yml' + - 'gems/bundled_gems' + merge_group: schedule: - cron: '45 6 * * *' + workflow_dispatch: + +permissions: # added using https://github.com/step-security/secure-workflows + contents: read jobs: update: - if: ${{ github.repository == 'ruby/ruby' }} + permissions: + contents: write # for Git to git push + + if: ${{ github.event_name != 'schedule' || github.repository == 'ruby/ruby' }} + name: update ${{ github.workflow }} + runs-on: ubuntu-latest + steps: - - name: git config - run: | - git config --global advice.detachedHead 0 - git config --global init.defaultBranch garbage + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + + - uses: ./.github/actions/setup/directories + with: + # Skip overwriting MATZBOT_GITHUB_TOKEN + checkout: '' # false (ref: https://github.com/actions/runner/issues/2238) - name: Set ENV run: | - echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV + echo "TODAY=$(date +%F)" >> $GITHUB_ENV + + - name: Download previous gems list + run: | + data=bundled_gems.json + mkdir -p .downloaded-cache + ln -s .downloaded-cache/$data . + curl -O -R -z ./$data https://stdgems.org/$data + + - name: Update bundled gems list + id: bundled_gems + run: | + ruby -i~ tool/update-bundled_gems.rb gems/bundled_gems >> $GITHUB_OUTPUT - - uses: actions/checkout@v2 + - name: Update spec/bundler/support/builders.rb + run: | + #!ruby + rake_version = File.read("gems/bundled_gems")[/^rake\s+(\S+)/, 1] + print ARGF.read.sub(/^ *def rake_version\s*\K".*?"/) {rake_version.dump} + shell: ruby -i~ {0} spec/bundler/support/builders.rb - - name: Update ${{ github.workflow }} + - name: Maintain updated gems list in NEWS run: | - ruby -i~ tool/update-bundled_gems.rb gems/${{ github.workflow }} + ruby tool/update-NEWS-gemlist.rb bundled - name: Check diffs id: diff run: | - git diff --no-ext-diff --ignore-submodules --exit-code - continue-on-error: true + news= gems= + git diff --color --no-ext-diff --ignore-submodules --exit-code -- NEWS.md || + news=true + git diff --color --no-ext-diff --ignore-submodules --exit-code -- gems/bundled_gems || + gems=true + git add -- NEWS.md gems/bundled_gems + git add -- spec/bundler/support/builders.rb + echo news=$news >> $GITHUB_OUTPUT + echo gems=$gems >> $GITHUB_OUTPUT + echo update=${news:-$gems} >> $GITHUB_OUTPUT - name: Install libraries - run: | - set -x - sudo apt-get update -q || : - sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby - if: ${{ steps.diff.outcome == 'failure' }} + uses: ./.github/actions/setup/ubuntu + if: ${{ steps.diff.outputs.gems }} - name: Build run: | ./autogen.sh ./configure -C --disable-install-doc - make $JOBS - if: ${{ steps.diff.outcome == 'failure' }} + make + if: ${{ steps.diff.outputs.gems }} + + - name: Prepare bundled gems + run: | + make -s prepare-gems + if: ${{ steps.diff.outputs.gems }} - name: Test bundled gems run: | - make $JOBS -s test-bundled-gems + make -s test-bundled-gems timeout-minutes: 30 env: - RUBY_TESTOPTS: "-q --tty=no" - TEST_BUNDLED_GEMS_ALLOW_FAILURES: "" - if: ${{ steps.diff.outcome == 'failure' }} + RUBY_TESTOPTS: '-q --tty=no' + TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' + if: ${{ steps.diff.outputs.gems }} - name: Commit run: | - git commit --message="Update ${{ github.workflow }} at $(date +%F)" gems/${{ github.workflow }} git pull --ff-only origin ${GITHUB_REF#refs/heads/} + message="Update bundled gems list" + if [ -z "${gems}" ]; then + git commit --message="${message} at ${GITHUB_SHA:0:30} [ci skip]" + else + git commit --message="${message} as of ${TODAY}" + fi git push origin ${GITHUB_REF#refs/heads/} env: + TODAY: ${{ steps.bundled_gems.outputs.latest_date || env.TODAY }} EMAIL: svn-admin@ruby-lang.org GIT_AUTHOR_NAME: git GIT_COMMITTER_NAME: git - if: ${{ steps.diff.outcome == 'failure' }} + gems: ${{ steps.diff.outputs.gems }} + if: >- + ${{ + github.repository == 'ruby/ruby' && + !startsWith(github.event_name, 'pull') && + steps.diff.outputs.update + }} + + - uses: ./.github/actions/slack + with: + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index e6b4abbe98..076af08aed 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -1,45 +1,76 @@ name: Check Dependencies -on: [push, pull_request] +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + jobs: update-deps: strategy: matrix: - os: [ubuntu-20.04, macos-11] + os: [ubuntu-20.04] fail-fast: true + runs-on: ${{ matrix.os }} + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + steps: - - name: Install libraries - run: | - set -x - sudo apt-get update -q || : - sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + - uses: ./.github/actions/setup/ubuntu if: ${{ contains(matrix.os, 'ubuntu') }} - - name: Install libraries - run: | - brew upgrade - brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline + + - uses: ./.github/actions/setup/macos if: ${{ contains(matrix.os, 'macos') }} - - name: git config - run: | - git config --global advice.detachedHead 0 - git config --global init.defaultBranch garbage - - uses: actions/checkout@v2 - - run: ./autogen.sh + + - uses: ./.github/actions/setup/directories + + - uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 + with: + ruby-version: '3.0' + bundler: none + - name: Run configure run: ./configure -C --disable-install-doc --disable-rubygems --with-gcc 'optflags=-O0' 'debugflags=-save-temps=obj -g' + - run: make all golf + - run: ruby tool/update-deps --fix + - run: git diff --no-ext-diff --ignore-submodules --exit-code - - uses: k0kubun/action-slack@v2.0.0 + + - uses: ./.github/actions/slack with: - payload: | - { - "ci": "GitHub Actions", - "env": "${{ matrix.os }} / Dependencies need to update", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref }}".split('/').reverse()[0] - } - env: + label: ${{ matrix.os }} / Dependencies need to update SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml index c116011d86..48434a47a9 100644 --- a/.github/workflows/check_misc.yml +++ b/.github/workflows/check_misc.yml @@ -1,20 +1,117 @@ -name: Miscellaneous checks -on: [push, pull_request] +name: Misc +on: [push, pull_request, merge_group] + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read jobs: checks: + name: Miscellaneous checks + + permissions: + contents: write # for Git to git push + runs-on: ubuntu-latest + steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + + - uses: ./.github/actions/setup/directories + with: + makeup: true + # Skip overwriting MATZBOT_GITHUB_TOKEN + checkout: '' # false (ref: https://github.com/actions/runner/issues/2238) + - name: Check if C-sources are US-ASCII run: | - ! grep -r -n '[^ -~]' *.[chy] include internal win32/*.[ch] + grep -r -n --include='*.[chyS]' --include='*.asm' $'[^\t-~]' -- . && exit 1 || : + - name: Check for trailing spaces run: | - ! git grep -n '[ ]$' '*.rb' '*.[chy]' + git grep -I -n $'[\t ]$' -- '*.rb' '*.[chy]' '*.rs' '*.yml' && exit 1 || : + git grep -n $'^[\t ][\t ]*$' -- '*.md' && exit 1 || : + + - name: Check for bash specific substitution in configure.ac + run: | + git grep -n '\${[A-Za-z_0-9]*/' -- configure.ac && exit 1 || : + - name: Check for header macros run: | - ! for header in ruby/*.h; do \ - git grep -l -F -e $header -e HAVE_`echo $header | tr a-z./ A-Z__` -- . > /dev/null || echo $header - done | grep -F . + fail= + for header in ruby/*.h; do + git grep -l -F -e $header -e HAVE_`echo $header | tr a-z./ A-Z__` -- . > /dev/null && continue + fail=1 + echo $header + done + exit $fail working-directory: include + + - id: gems + run: true + if: ${{ github.ref == 'refs/heads/master' }} + + - name: Download previous gems list + run: | + data=default_gems.json + mkdir -p .downloaded-cache + ln -s .downloaded-cache/$data . + curl -O -R -z ./$data https://stdgems.org/$data + if: ${{ steps.gems.outcome == 'success' }} + + - name: Make default gems list + run: | + #!ruby + require 'rubygems' + $:.unshift "lib" + rgver = File.foreach("lib/rubygems.rb") do |line| + break $1 if /^\s*VERSION\s*=\s*"([^"]+)"/ =~ line + end + gems = Dir.glob("{ext,lib}/**/*.gemspec").map do |f| + spec = Gem::Specification.load(f) + "#{spec.name} #{spec.version}" + end.sort + File.open("gems/default_gems", "w") do |f| + f.puts "RubyGems #{rgver}" + f.puts gems + end + shell: ruby --disable=gems {0} + if: ${{ steps.gems.outcome == 'success' }} + + - name: Maintain updated gems list in NEWS + run: | + ruby tool/update-NEWS-gemlist.rb default + if: ${{ steps.gems.outcome == 'success' }} + + - name: Check diffs + id: diff + run: | + git diff --color --no-ext-diff --ignore-submodules --exit-code NEWS.md || + echo update=true >> $GITHUB_OUTPUT + if: ${{ steps.gems.outcome == 'success' }} + + - name: Commit + run: | + git pull --ff-only origin ${GITHUB_REF#refs/heads/} + git commit --message="Update default gems list at ${GITHUB_SHA:0:30} [ci skip]" NEWS.md + git push origin ${GITHUB_REF#refs/heads/} + env: + EMAIL: svn-admin@ruby-lang.org + GIT_AUTHOR_NAME: git + GIT_COMMITTER_NAME: git + if: >- + ${{ + github.repository == 'ruby/ruby' && + !startsWith(github.event_name, 'pull') && + steps.diff.outputs.update + }} + + - uses: ./.github/actions/slack + with: + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5897c5d37e..c7d0def7ae 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,43 +1,124 @@ -name: "Code scanning - action" +name: 'CodeQL' on: push: + branches: ['master'] + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' schedule: - - cron: '0 12 * * 4' + - cron: '0 12 * * *' + workflow_dispatch: -jobs: - CodeQL-Build: +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: # added using https://github.com/step-security/secure-workflows + contents: read - # CodeQL runs on ubuntu-latest and windows-latest - runs-on: ubuntu-latest +jobs: + analyze: + name: Analyze + runs-on: ${{ matrix.os }} + permissions: + actions: read # for github/codeql-action/init to get workflow details + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/autobuild to send a status report + # CodeQL fails to run pull requests from dependabot due to missing write access to upload results. + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} env: enable_install_doc: no + strategy: + fail-fast: false + matrix: + include: + - language: cpp + os: ubuntu-latest + # ruby analysis used large memory. We need to use a larger runner. + - language: ruby + os: ${{ github.repository == 'ruby/ruby' && 'macos-arm-oss' || 'ubuntu-latest' }} + steps: - - name: Install libraries - run: | - set -x - sudo apt-get update -q || : - sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby + - name: Checkout repository + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + - name: Install libraries + if: ${{ contains(matrix.os, 'macos') }} + uses: ./.github/actions/setup/macos + + - name: Install libraries + if : ${{ matrix.os == 'ubuntu-latest' }} + uses: ./.github/actions/setup/ubuntu + + - uses: ./.github/actions/setup/directories - - name: Checkout repository - uses: actions/checkout@v2 + - name: Remove an obsolete rubygems vendored file + if: ${{ matrix.os == 'ubuntu-latest' }} + run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb - - name: Remove an obsolete rubygems vendored file - run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb + - name: Initialize CodeQL + uses: github/codeql-action/init@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 + with: + languages: ${{ matrix.language }} - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - config-file: ./.github/codeql/codeql-config.yml + - name: Autobuild + uses: github/codeql-action/autobuild@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 - - name: Set ENV - run: echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 + with: + category: '/language:${{ matrix.language }}' + upload: False + output: sarif-results - - name: Autobuild - uses: github/codeql-action/autobuild@v1 + - name: filter-sarif + uses: advanced-security/filter-sarif@f3b8118a9349d88f7b1c0c488476411145b6270d # v1.0.1 + with: + patterns: | + +**/*.rb + -lib/uri/mailto.rb:rb/overly-large-range + -lib/uri/rfc3986_parser.rb:rb/overly-large-range + -lib/bundler/vendor/uri/lib/uri/mailto.rb:rb/overly-large-range + -lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb:rb/overly-large-range + -test/ruby/test_io.rb:rb/non-constant-kernel-open + -test/open-uri/test_open-uri.rb:rb/non-constant-kernel-open + -test/open-uri/test_ssl.rb:rb/non-constant-kernel-open + -spec/ruby/core/io/binread_spec.rb:rb/non-constant-kernel-open + -spec/ruby/core/io/readlines_spec.rb:rb/non-constant-kernel-open + -spec/ruby/core/io/foreach_spec.rb:rb/non-constant-kernel-open + -spec/ruby/core/io/write_spec.rb:rb/non-constant-kernel-open + -spec/ruby/core/io/read_spec.rb:rb/non-constant-kernel-open + -spec/ruby/core/kernel/open_spec.rb:rb/non-constant-kernel-open + input: sarif-results/${{ matrix.language }}.sarif + output: sarif-results/${{ matrix.language }}.sarif + if: ${{ matrix.language == 'ruby' }} + continue-on-error: true - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 + with: + sarif_file: sarif-results/${{ matrix.language }}.sarif + continue-on-error: true diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml index 6ddfba05db..5e5eb69b6f 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -1,17 +1,37 @@ name: Compilations -on: [push, pull_request] +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + merge_group: -# Github actions does not support YAML anchors. This creative use of +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +# GitHub actions does not support YAML anchors. This creative use of # environment variables (plus the "echo $GITHUB_ENV" hack) is to reroute that # restriction. env: - default_cc: clang-14 + default_cc: clang-18 append_cc: '' - crosshost: '' # -O1 is faster than -O3 in our tests... Majority of time are consumed trying - # to optimize binaries. Also Github Actions run on relatively modern CPUs + # to optimize binaries. Also GitHub Actions run on relatively modern CPUs # compared to, say, GCC 4 or Clang 3. We don't specify `-march=native` # because compilers tend not understand what the CPU is. optflags: '-O1' @@ -28,199 +48,256 @@ env: --without-jemalloc --without-gmp - UPDATE_UNICODE: >- - UNICODE_FILES=. - UNICODE_PROPERTY_FILES=. - UNICODE_AUXILIARY_FILES=. - UNICODE_EMOJI_FILES=. CONFIGURE_TTY: never - GITPULLOPTIONS: --no-tags origin ${{github.ref}} + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} RUBY_DEBUG: ci rgengc RUBY_TESTOPTS: >- -q --color=always --tty=no +permissions: + contents: read + jobs: compile: strategy: fail-fast: false matrix: + env: + - {} entry: - - { key: default_cc, name: gcc-11, value: gcc-11, container: gcc-11 } - - { key: default_cc, name: gcc-10, value: gcc-10, container: gcc-10 } - - { key: default_cc, name: gcc-9, value: gcc-9, container: gcc-9 } - - { key: default_cc, name: gcc-8, value: gcc-8, container: gcc-8 } - - { key: default_cc, name: gcc-7, value: gcc-7, container: gcc-7 } - - { key: default_cc, name: gcc-6, value: gcc-6, container: gcc-6 } - - { key: default_cc, name: gcc-5, value: gcc-5, container: gcc-5 } - - { key: default_cc, name: gcc-4.8, value: gcc-4.8, container: gcc-4.8 } - - key: default_cc - name: 'gcc-11 LTO' - value: 'gcc-11 -O2 -flto=auto -ffat-lto-objects' - container: gcc-11 - shared: '--disable-shared' + - { name: gcc-13, env: { default_cc: gcc-13 } } + - { name: gcc-12, env: { default_cc: gcc-12 } } + - { name: gcc-11, env: { default_cc: gcc-11 } } + - { name: gcc-10, env: { default_cc: gcc-10 } } + - { name: gcc-9, env: { default_cc: gcc-9 } } + - { name: gcc-8, env: { default_cc: gcc-8 } } + - { name: gcc-7, env: { default_cc: gcc-7 } } + - name: 'gcc-13 LTO' + container: gcc-13 + env: + default_cc: 'gcc-13 -flto=auto -ffat-lto-objects -Werror=lto-type-mismatch' + optflags: '-O2' + shared: disable # check: true - - { key: default_cc, name: clang-14, value: clang-14, container: clang-14 } - - { key: default_cc, name: clang-13, value: clang-13, container: clang-13 } - - { key: default_cc, name: clang-12, value: clang-12, container: clang-12 } - - { key: default_cc, name: clang-11, value: clang-11, container: clang-11 } - - { key: default_cc, name: clang-10, value: clang-10, container: clang-10 } - - { key: default_cc, name: clang-9, value: clang-9, container: clang-9 } - - { key: default_cc, name: clang-8, value: clang-8, container: clang-8 } - - { key: default_cc, name: clang-7, value: clang-7, container: clang-7 } - - { key: default_cc, name: clang-6.0, value: clang-6.0, container: clang-6.0 } - - { key: default_cc, name: clang-5.0, value: clang-5.0, container: clang-5.0 } - - { key: default_cc, name: clang-4.0, value: clang-4.0, container: clang-4.0 } - - { key: default_cc, name: clang-3.9, value: clang-3.9, container: clang-3.9 } - - key: default_cc - name: 'clang-14 LTO' - value: 'clang-14 -O2 -flto=auto' - container: clang-14 - shared: '--disable-shared' + - { name: clang-19, env: { default_cc: clang-19 } } + - { name: clang-18, env: { default_cc: clang-18 } } + - { name: clang-17, env: { default_cc: clang-17 } } + - { name: clang-16, env: { default_cc: clang-16 } } + - { name: clang-15, env: { default_cc: clang-15 } } + - { name: clang-14, env: { default_cc: clang-14 } } + - { name: clang-13, env: { default_cc: clang-13 } } + - { name: clang-12, env: { default_cc: clang-12 } } + - { name: clang-11, env: { default_cc: clang-11 } } + - { name: clang-10, env: { default_cc: clang-10 } } + # llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o. + - { name: clang-9, env: { default_cc: clang-9, append_configure: '--disable-yjit' } } + - { name: clang-8, env: { default_cc: clang-8, append_configure: '--disable-yjit' } } + - { name: clang-7, env: { default_cc: clang-7, append_configure: '--disable-yjit' } } + - { name: clang-6.0, env: { default_cc: clang-6.0, append_configure: '--disable-yjit' } } + - name: 'clang-16 LTO' + container: clang-16 + env: + default_cc: 'clang-16 -flto=auto' + optflags: '-O2' + shared: disable # check: true - - { key: crosshost, name: aarch64-linux-gnu, value: aarch64-linux-gnu, container: crossbuild-essential-arm64 } -# - { key: crosshost, name: arm-linux-gnueabi, value: arm-linux-gnueabi } -# - { key: crosshost, name: arm-linux-gnueabihf, value: arm-linux-gnueabihf } -# - { key: crosshost, name: i686-w64-mingw32, value: i686-w64-mingw32 } -# - { key: crosshost, name: powerpc-linux-gnu, value: powerpc-linux-gnu } - - { key: crosshost, name: powerpc64le-linux-gnu, value: powerpc64le-linux-gnu, container: crossbuild-essential-ppc64el } - - { key: crosshost, name: s390x-linux-gnu, value: s390x-linux-gnu, container: crossbuild-essential-s390x } - - { key: crosshost, name: x86_64-w64-mingw32, value: x86_64-w64-mingw32, container: mingw-w64 } - - - { key: append_cc, name: c99, value: '-std=c99 -Werror=pedantic -pedantic-errors' } -# - { key: append_cc, name: c11, value: '-std=c11 -Werror=pedantic -pedantic-errors' } -# - { key: append_cc, name: c17, value: '-std=c17 -Werror=pedantic -pedantic-errors' } - - { key: append_cc, name: c2x, value: '-std=c2x -Werror=pedantic -pedantic-errors' } - - { key: CXXFLAGS, name: c++98, value: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } -# - { key: CXXFLAGS, name: c++11, value: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } -# - { key: CXXFLAGS, name: c++14, value: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } -# - { key: CXXFLAGS, name: c++17, value: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } - - { key: CXXFLAGS, name: c++2a, value: '-std=c++2a -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } - - - { key: optflags, name: '-O0', value: '-O0 -march=x86-64 -mtune=generic' } -# - { key: optflags, name: '-O3', value: '-O3 -march=x86-64 -mtune=generic', check: true } - - - { key: append_configure, name: gmp, value: '--with-gmp' } - - { key: append_configure, name: jemalloc, value: '--with-jemalloc' } - - { key: append_configure, name: valgrind, value: '--with-valgrind' } - - { key: append_configure, name: 'coroutine=ucontext', value: '--with-coroutine=ucontext' } - - { key: append_configure, name: 'coroutine=pthread', value: '--with-coroutine=pthread' } - - { key: append_configure, name: disable-jit-support, value: '--disable-jit-support' } - - { key: append_configure, name: disable-dln, value: '--disable-dln' } - - { key: append_configure, name: disable-rubygems, value: '--disable-rubygems' } - - - { key: cppflags, name: OPT_THREADED_CODE=1, value: '-DOPT_THREADED_CODE=1' } - - { key: cppflags, name: OPT_THREADED_CODE=2, value: '-DOPT_THREADED_CODE=2' } - - { key: cppflags, name: OPT_THREADED_CODE=3, value: '-DOPT_THREADED_CODE=3' } - - - { key: cppflags, name: NDEBUG, value: '-DNDEBUG' } - - { key: cppflags, name: RUBY_DEBUG, value: '-DRUBY_DEBUG' } -# - { key: cppflags, name: ARRAY_DEBUG, value: '-DARRAY_DEBUG' } -# - { key: cppflags, name: BIGNUM_DEBUG, value: '-DBIGNUM_DEBUG' } -# - { key: cppflags, name: CCAN_LIST_DEBUG, value: '-DCCAN_LIST_DEBUG' } -# - { key: cppflags, name: CPDEBUG=-1, value: '-DCPDEBUG=-1' } -# - { key: cppflags, name: ENC_DEBUG, value: '-DENC_DEBUG' } -# - { key: cppflags, name: GC_DEBUG, value: '-DGC_DEBUG' } -# - { key: cppflags, name: HASH_DEBUG, value: '-DHASH_DEBUG' } -# - { key: cppflags, name: ID_TABLE_DEBUG, value: '-DID_TABLE_DEBUG' } -# - { key: cppflags, name: RGENGC_DEBUG=-1, value: '-DRGENGC_DEBUG=-1' } -# - { key: cppflags, name: SYMBOL_DEBUG, value: '-DSYMBOL_DEBUG' } -# - { key: cppflags, name: THREAD_DEBUG=-1, value: '-DTHREAD_DEBUG=-1' } - -# - { key: cppflags, name: RGENGC_CHECK_MODE, value: '-DRGENGC_CHECK_MODE' } -# - { key: cppflags, name: TRANSIENT_HEAP_CHECK_MODE, value: '-DTRANSIENT_HEAP_CHECK_MODE' } -# - { key: cppflags, name: VM_CHECK_MODE, value: '-DVM_CHECK_MODE' } - - - { key: cppflags, name: USE_EMBED_CI=0, value: '-DUSE_EMBED_CI=0' } - - { key: cppflags, name: USE_FLONUM=0, value: '-DUSE_FLONUM=0' } -# - { key: cppflags, name: USE_GC_MALLOC_OBJ_INFO_DETAILS, value: '-DUSE_GC_MALLOC_OBJ_INFO_DETAILS' } - - { key: cppflags, name: USE_LAZY_LOAD, value: '-DUSE_LAZY_LOAD' } -# - { key: cppflags, name: USE_RINCGC=0, value: '-DUSE_RINCGC=0' } -# - { key: cppflags, name: USE_SYMBOL_GC=0, value: '-DUSE_SYMBOL_GC=0' } -# - { key: cppflags, name: USE_THREAD_CACHE=0, value: '-DUSE_THREAD_CACHE=0' } -# - { key: cppflags, name: USE_TRANSIENT_HEAP=0, value: '-DUSE_TRANSIENT_HEAP=0' } -# - { key: cppflags, name: USE_RUBY_DEBUG_LOG=1, value: '-DUSE_RUBY_DEBUG_LOG=1' } - - - { key: cppflags, name: DEBUG_FIND_TIME_NUMGUESS, value: '-DDEBUG_FIND_TIME_NUMGUESS' } - - { key: cppflags, name: DEBUG_INTEGER_PACK, value: '-DDEBUG_INTEGER_PACK' } -# - { key: cppflags, name: ENABLE_PATH_CHECK, value: '-DENABLE_PATH_CHECK' } - - - { key: cppflags, name: GC_DEBUG_STRESS_TO_CLASS, value: '-DGC_DEBUG_STRESS_TO_CLASS' } -# - { key: cppflags, name: GC_ENABLE_LAZY_SWEEP=0, value: '-DGC_ENABLE_LAZY_SWEEP=0' } -# - { key: cppflags, name: GC_PROFILE_DETAIL_MEMOTY, value: '-DGC_PROFILE_DETAIL_MEMOTY' } -# - { key: cppflags, name: GC_PROFILE_MORE_DETAIL, value: '-DGC_PROFILE_MORE_DETAIL' } - -# - { key: cppflags, name: CALC_EXACT_MALLOC_SIZE, value: '-DCALC_EXACT_MALLOC_SIZE' } -# - { key: cppflags, name: MALLOC_ALLOCATED_SIZE_CHECK, value: '-DMALLOC_ALLOCATED_SIZE_CHECK' } - -# - { key: cppflags, name: IBF_ISEQ_ENABLE_LOCAL_BUFFER, value: '-DIBF_ISEQ_ENABLE_LOCAL_BUFFER' } - -# - { key: cppflags, name: RGENGC_ESTIMATE_OLDMALLOC, value: '-DRGENGC_ESTIMATE_OLDMALLOC' } -# - { key: cppflags, name: RGENGC_FORCE_MAJOR_GC, value: '-DRGENGC_FORCE_MAJOR_GC' } -# - { key: cppflags, name: RGENGC_OBJ_INFO, value: '-DRGENGC_OBJ_INFO' } -# - { key: cppflags, name: RGENGC_OLD_NEWOBJ_CHECK, value: '-DRGENGC_OLD_NEWOBJ_CHECK' } -# - { key: cppflags, name: RGENGC_PROFILE, value: '-DRGENGC_PROFILE' } - -# - { key: cppflags, name: VM_DEBUG_BP_CHECK, value: '-DVM_DEBUG_BP_CHECK' } -# - { key: cppflags, name: VM_DEBUG_VERIFY_METHOD_CACHE, value: '-DVM_DEBUG_VERIFY_METHOD_CACHE' } - - - { key: cppflags, name: MJIT_FORCE_ENABLE, value: '-DMJIT_FORCE_ENABLE' } + - { name: ext/Setup, static-exts: 'etc,json/*,*/escape' } + +# - { name: aarch64-linux-gnu, crosshost: aarch64-linux-gnu, container: crossbuild-essential-arm64 } +# - { name: arm-linux-gnueabi, crosshost: arm-linux-gnueabi } +# - { name: arm-linux-gnueabihf, crosshost: arm-linux-gnueabihf } +# - { name: i686-w64-mingw32, crosshost: i686-w64-mingw32 } +# - { name: powerpc-linux-gnu, crosshost: powerpc-linux-gnu } +# - { name: powerpc64le-linux-gnu, crosshost: powerpc64le-linux-gnu, container: crossbuild-essential-ppc64el } +# - { name: s390x-linux-gnu, crosshost: s390x-linux-gnu, container: crossbuild-essential-s390x } +# - { name: x86_64-w64-mingw32, crosshost: x86_64-w64-mingw32, container: mingw-w64 } + + # -Wno-strict-prototypes is necessary with current clang-15 since + # older autoconf generate functions without prototype and -pedantic + # now implies strict-prototypes. Disabling the error but leaving the + # warning generates a lot of noise from use of ANYARGS in + # rb_define_method() and friends. + # See: https://github.com/llvm/llvm-project/commit/11da1b53d8cd3507959022cd790d5a7ad4573d94 + - { name: c99, env: { CFLAGS: '-std=c99 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } +# - { name: c11, env: { CFLAGS: '-std=c11 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } +# - { name: c17, env: { CFLAGS: '-std=c17 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } + - { name: c23, env: { CFLAGS: '-std=c2x -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } + - { name: c++98, env: { CXXFLAGS: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } +# - { name: c++11, env: { CXXFLAGS: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } +# - { name: c++14, env: { CXXFLAGS: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } +# - { name: c++17, env: { CXXFLAGS: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } +# - { name: c++20, env: { CXXFLAGS: '-std=c++20 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } +# - { name: c++23, env: { CXXFLAGS: '-std=c++23 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } + - { name: c++26, env: { CXXFLAGS: '-std=c++26 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } + + - { name: '-O0', env: { optflags: '-O0 -march=x86-64 -mtune=generic' } } +# - { name: '-O3', env: { optflags: '-O3 -march=x86-64 -mtune=generic' }, check: true } + + - { name: gmp, env: { append_configure: '--with-gmp' } } + - { name: jemalloc, env: { append_configure: '--with-jemalloc' } } + - { name: valgrind, env: { append_configure: '--with-valgrind' } } + - { name: 'coroutine=ucontext', env: { append_configure: '--with-coroutine=ucontext' } } + - { name: 'coroutine=pthread', env: { append_configure: '--with-coroutine=pthread' } } + - { name: disable-jit, env: { append_configure: '--disable-yjit --disable-rjit' } } + - { name: disable-dln, env: { append_configure: '--disable-dln' } } + - { name: enable-mkmf-verbose, env: { append_configure: '--enable-mkmf-verbose' } } + - { name: disable-rubygems, env: { append_configure: '--disable-rubygems' } } + - { name: RUBY_DEVEL, env: { append_configure: '--enable-devel' } } + + - { name: OPT_THREADED_CODE=0, env: { cppflags: '-DOPT_THREADED_CODE=0' } } + - { name: OPT_THREADED_CODE=1, env: { cppflags: '-DOPT_THREADED_CODE=1' } } + - { name: OPT_THREADED_CODE=2, env: { cppflags: '-DOPT_THREADED_CODE=2' } } + + - { name: NDEBUG, env: { cppflags: '-DNDEBUG' } } + - { name: RUBY_DEBUG, env: { cppflags: '-DRUBY_DEBUG' } } +# - { name: ARRAY_DEBUG, env: { cppflags: '-DARRAY_DEBUG' } } +# - { name: BIGNUM_DEBUG, env: { cppflags: '-DBIGNUM_DEBUG' } } +# - { name: CCAN_LIST_DEBUG, env: { cppflags: '-DCCAN_LIST_DEBUG' } } +# - { name: CPDEBUG=-1, env: { cppflags: '-DCPDEBUG=-1' } } +# - { name: ENC_DEBUG, env: { cppflags: '-DENC_DEBUG' } } +# - { name: GC_DEBUG, env: { cppflags: '-DGC_DEBUG' } } +# - { name: HASH_DEBUG, env: { cppflags: '-DHASH_DEBUG' } } +# - { name: ID_TABLE_DEBUG, env: { cppflags: '-DID_TABLE_DEBUG' } } +# - { name: RGENGC_DEBUG=-1, env: { cppflags: '-DRGENGC_DEBUG=-1' } } +# - { name: SYMBOL_DEBUG, env: { cppflags: '-DSYMBOL_DEBUG' } } + +# - { name: RGENGC_CHECK_MODE, env: { cppflags: '-DRGENGC_CHECK_MODE' } } +# - { name: VM_CHECK_MODE, env: { cppflags: '-DVM_CHECK_MODE' } } + +# - { name: USE_EMBED_CI=0, env: { cppflags: '-DUSE_EMBED_CI=0' } } + - name: USE_FLONUM=0 + env: + cppflags: '-DUSE_FLONUM=0' + # yjit requires FLONUM for the pointer tagging scheme + append_configure: '--disable-yjit' +# - { name: USE_GC_MALLOC_OBJ_INFO_DETAILS, env: { cppflags: '-DUSE_GC_MALLOC_OBJ_INFO_DETAILS' } } +# - { name: USE_LAZY_LOAD, env: { cppflags: '-DUSE_LAZY_LOAD' } } +# - { name: USE_SYMBOL_GC=0, env: { cppflags: '-DUSE_SYMBOL_GC=0' } } +# - { name: USE_THREAD_CACHE=0, env: { cppflags: '-DUSE_THREAD_CACHE=0' } } + - { name: USE_RUBY_DEBUG_LOG=1, env: { cppflags: '-DUSE_RUBY_DEBUG_LOG=1' } } +# - { name: USE_DEBUG_COUNTER, env: { cppflags: '-DUSE_DEBUG_COUNTER=1', RUBY_DEBUG_COUNTER_DISABLE: '1' } } + - { name: SHARABLE_MIDDLE_SUBSTRING, env: { cppflags: '-DSHARABLE_MIDDLE_SUBSTRING=1' } } + +# - { name: DEBUG_FIND_TIME_NUMGUESS, env: { cppflags: '-DDEBUG_FIND_TIME_NUMGUESS' } } +# - { name: DEBUG_INTEGER_PACK, env: { cppflags: '-DDEBUG_INTEGER_PACK' } } +# - { name: ENABLE_PATH_CHECK, env: { cppflags: '-DENABLE_PATH_CHECK' } } + +# - { name: GC_DEBUG_STRESS_TO_CLASS, env: { cppflags: '-DGC_DEBUG_STRESS_TO_CLASS' } } +# - { name: GC_ENABLE_LAZY_SWEEP=0, env: { cppflags: '-DGC_ENABLE_LAZY_SWEEP=0' } } +# - { name: GC_PROFILE_DETAIL_MEMOTY, env: { cppflags: '-DGC_PROFILE_DETAIL_MEMOTY' } } +# - { name: GC_PROFILE_MORE_DETAIL, env: { cppflags: '-DGC_PROFILE_MORE_DETAIL' } } + +# - { name: CALC_EXACT_MALLOC_SIZE, env: { cppflags: '-DCALC_EXACT_MALLOC_SIZE' } } +# - { name: MALLOC_ALLOCATED_SIZE_CHECK, env: { cppflags: '-DMALLOC_ALLOCATED_SIZE_CHECK' } } + +# - { name: IBF_ISEQ_ENABLE_LOCAL_BUFFER, env: { cppflags: '-DIBF_ISEQ_ENABLE_LOCAL_BUFFER' } } + +# - { name: RGENGC_ESTIMATE_OLDMALLOC, env: { cppflags: '-DRGENGC_ESTIMATE_OLDMALLOC' } } +# - { name: RGENGC_FORCE_MAJOR_GC, env: { cppflags: '-DRGENGC_FORCE_MAJOR_GC' } } +# - { name: RGENGC_OBJ_INFO, env: { cppflags: '-DRGENGC_OBJ_INFO' } } +# - { name: RGENGC_PROFILE, env: { cppflags: '-DRGENGC_PROFILE' } } + +# - { name: VM_DEBUG_BP_CHECK, env: { cppflags: '-DVM_DEBUG_BP_CHECK' } } +# - { name: VM_DEBUG_VERIFY_METHOD_CACHE, env: { cppflags: '-DVM_DEBUG_VERIFY_METHOD_CACHE' } } + + - { name: enable-yjit, env: { append_configure: '--enable-yjit --disable-rjit' } } + - { name: enable-rjit, env: { append_configure: '--enable-rjit --disable-yjit' } } + - { name: YJIT_FORCE_ENABLE, env: { cppflags: '-DYJIT_FORCE_ENABLE' } } +# - { name: RJIT_FORCE_ENABLE, env: { cppflags: '-DRJIT_FORCE_ENABLE' } } + - { name: UNIVERSAL_PARSER, env: { cppflags: '-DUNIVERSAL_PARSER' } } name: ${{ matrix.entry.name }} + runs-on: ubuntu-latest + container: - image: ghcr.io/ruby/ruby-ci-image:${{ matrix.entry.container || 'clang-14' }} + image: ghcr.io/ruby/ruby-ci-image:${{ matrix.entry.container || matrix.entry.env.default_cc || 'clang-18' }} options: --user root + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + env: ${{ matrix.entry.env || matrix.env }} + steps: - run: id working-directory: - - run: mkdir build - working-directory: - - name: setenv - run: | - echo "${{ matrix.entry.key }}=${{ matrix.entry.value }}" >> $GITHUB_ENV - echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> $GITHUB_ENV - - uses: actions/checkout@v2 + + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - uses: ./.github/actions/setup/directories with: - path: src - - run: ./autogen.sh - working-directory: src + srcdir: src + builddir: build + makeup: true + clean: true + - name: Run configure run: > ../src/configure -C ${default_configure} ${append_configure} - ${{ matrix.entry.key == 'crosshost' && '--host="${crosshost}"' || '--with-gcc="${default_cc} ${append_cc}"' }} - ${{ matrix.entry.shared || '--enable-shared' }} - - run: make extract-extlibs - - run: make incs + --${{ + matrix.entry.crosshost && 'host' || 'with-gcc' + }}=${{ + matrix.entry.crosshost || '"${default_cc}${append_cc:+ $append_cc}"' + }} + --${{ matrix.entry.shared || 'enable' }}-shared + + - name: Add to ext/Setup + id: ext-setup + run: | + mkdir ext + cd ext + for ext in {${{ matrix.entry.static-exts }}}; do + echo "${ext}" + done >> Setup + if: ${{ (matrix.entry.static-exts || '') != '' }} + + - name: Clean up ext/Setup + uses: gacts/run-and-post-run@7aec950f3b114c4fcf6012070c3709ecff0eb6f8 # v1.4.0 + with: + shell: bash + working-directory: build + post: rm ext/Setup + if: ${{ steps.ext-setup.outcome == 'success' }} + + - run: make showflags + - run: make - - run: make leaked-globals + - run: make test + - run: make install if: ${{ matrix.entry.check }} - - run: /usr/local/bin/gem install --no-doc timezone tzinfo - if: ${{ matrix.entry.check }} + - run: make test-tool if: ${{ matrix.entry.check }} + - run: make test-all TESTS='-- ruby -ext-' if: ${{ matrix.entry.check }} + - run: make test-spec + env: + CHECK_LEAKS: true if: ${{ matrix.entry.check }} - - uses: k0kubun/action-slack@v2.0.0 + - uses: ./.github/actions/slack with: - payload: | - { - "ci": "GitHub Actions", - "env": "${{ github.workflow }} / ${{ matrix.entry.name }}", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref }}".split('/').reverse()[0] - } - env: + label: ${{ matrix.entry.name }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/dependabot_automerge.yml b/.github/workflows/dependabot_automerge.yml new file mode 100644 index 0000000000..80112a0af3 --- /dev/null +++ b/.github/workflows/dependabot_automerge.yml @@ -0,0 +1,30 @@ +# from https://github.com/gofiber/swagger/blob/main/.github/workflows/dependabot_automerge.yml +name: Dependabot auto-merge +on: + pull_request_target: + +jobs: + automerge: + runs-on: ubuntu-latest + + if: ${{ github.actor == 'dependabot[bot]' }} + + steps: + - name: Dependabot metadata + uses: dependabot/fetch-metadata@5e5f99653a5b510e8555840e80cbf1514ad4af38 # v2.1.0 + id: metadata + + - name: Wait for status checks + uses: lewagon/wait-on-check-action@ccfb013c15c8afb7bf2b7c028fb74dc5a068cccc # v1.3.4 + with: + repo-token: ${{ secrets.MATZBOT_GITHUB_TOKEN }} + ref: ${{ github.event.pull_request.head.sha || github.sha }} + check-regexp: 'make \(check, .*\)' + wait-interval: 30 + + - name: Auto-merge for Dependabot PRs + if: ${{ steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch' }} + run: gh pr merge --auto --rebase "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_TOKEN }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7c3f19f55b..54e30129e4 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,61 +1,138 @@ name: macOS -on: [push, pull_request] +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + # Do not use paths-ignore for required status checks + # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + jobs: make: strategy: matrix: - os: [macos-10.15, macos-11] - test_task: [ "check", "test-bundler-parallel" ] #, "test-bundled-gems" ] matrix tests has unknown issues + include: + - test_task: check + - test_task: test-all + test_opts: --repeat-count=2 + - test_task: test-bundler-parallel + - test_task: test-bundled-gems + - test_task: check + os: macos-12 + - test_task: check + os: macos-13 fail-fast: false + env: - GITPULLOPTIONS: --no-tags origin ${{github.ref}} - runs-on: ${{ matrix.os }} + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + + runs-on: ${{ matrix.os || (github.repository == 'ruby/ruby' && 'macos-arm-oss' || 'macos-14')}} + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + steps: - - run: mkdir build - working-directory: - - name: git config - run: | - git config --global advice.detachedHead 0 - git config --global init.defaultBranch garbage - - uses: actions/checkout@v2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: - path: src + sparse-checkout-cone-mode: false + sparse-checkout: /.github + - name: Install libraries - run: | - brew upgrade - brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline - working-directory: src - - name: Set ENV - run: | - echo "JOBS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV - - run: ./autogen.sh - working-directory: src + uses: ./.github/actions/setup/macos + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + clean: true + dummy-files: ${{ matrix.test_task == 'check' }} + # Set fetch-depth: 0 so that Launchable can receive commits information. + fetch-depth: 10 + - name: Run configure - run: ../src/configure -C --disable-install-doc --with-openssl-dir=$(brew --prefix openssl@1.1) --with-readline-dir=$(brew --prefix readline) - - run: make $JOBS incs - - run: make $JOBS - - run: make leaked-globals - if: ${{ matrix.test_task == 'check' }} + run: ../src/configure -C --disable-install-doc + - run: make prepare-gems - if: ${{ matrix.test_task == 'check' }} - - run: make $JOBS -s ${{ matrix.test_task }} - timeout-minutes: ${{ matrix.test_task == 'check' && 15 || 40 }} - env: - RUBY_TESTOPTS: "-q --tty=no" - TEST_BUNDLED_GEMS_ALLOW_FAILURES: "rexml" - - uses: k0kubun/action-slack@v2.0.0 + if: ${{ matrix.test_task == 'test-bundled-gems' }} + + - run: make + + - name: Set test options for skipped tests + run: | + set -x + TESTS="$(echo "${{ matrix.skipped_tests }}" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|')" + echo "TESTS=${TESTS}" >> $GITHUB_ENV + if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} + + - name: Set up Launchable + uses: ./.github/actions/launchable/setup with: - payload: | - { - "ci": "GitHub Actions", - "env": "${{ github.workflow }} / ${{ matrix.test_task }}", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref }}".split('/').reverse()[0] - } + os: ${{ matrix.os || (github.repository == 'ruby/ruby' && 'macos-arm-oss' || 'macos-14')}} + test-opts: ${{ matrix.test_opts }} + launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} + builddir: build + srcdir: src + continue-on-error: true + + - name: Set extra test options + run: echo "TESTS=$TESTS ${{ matrix.test_opts }}" >> $GITHUB_ENV + if: matrix.test_opts + + - name: make ${{ matrix.test_task }} + run: | + make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} + timeout-minutes: 60 env: + RUBY_TESTOPTS: '-q --tty=no' + TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' + PRECHECK_BUNDLED_GEMS: 'no' + + - name: make skipped tests + run: | + make -s test-all TESTS="${TESTS//-n!\//-n/}" + env: + GNUMAKEFLAGS: '' + RUBY_TESTOPTS: '-v --tty=no' + PRECHECK_BUNDLED_GEMS: 'no' + if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} + continue-on-error: ${{ matrix.continue-on-skipped_tests || false }} + + - uses: ./.github/actions/slack + with: + label: ${{ matrix.os }} / ${{ matrix.test_task }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} + + result: + if: ${{ always() }} + name: ${{ github.workflow }} result + runs-on: macos-latest + needs: [make] + steps: + - run: exit 1 + working-directory: + if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} defaults: run: diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 7ccf5f0b61..75cdfbab65 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -1,149 +1,160 @@ name: MinGW -on: [push, pull_request] +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read # Notes: # Actions console encoding causes issues, see test-all & test-spec steps # jobs: make: - runs-on: windows-2019 + runs-on: windows-2022 + + name: ${{ github.workflow }} (${{ matrix.msystem }}) + env: MSYSTEM: ${{ matrix.msystem }} MSYS2_ARCH: x86_64 - CHOST: "x86_64-w64-mingw32" - CFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe -fstack-protector-strong" - CXXFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe" - CPPFLAGS: "-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048" - LDFLAGS: "-pipe -fstack-protector-strong" - UPDATE_UNICODE: "UNICODE_FILES=. UNICODE_PROPERTY_FILES=. UNICODE_AUXILIARY_FILES=. UNICODE_EMOJI_FILES=." - GITPULLOPTIONS: --no-tags origin ${{github.ref}} + CHOST: 'x86_64-w64-mingw32' + CFLAGS: '-march=x86-64 -mtune=generic -O3 -pipe' + CXXFLAGS: '-march=x86-64 -mtune=generic -O3 -pipe' + CPPFLAGS: '-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048' + LDFLAGS: '-pipe' + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + strategy: matrix: include: - - msystem: "MINGW64" - base_ruby: 2.6 - test_task: [ "check" ] # to make job names consistent - - msystem: "UCRT64" - base_ruby: head - test_task: [ "check" ] # to make job names consistent + # To mitigate flakiness of MinGW CI, we test only one runtime that newer MSYS2 uses. + - msystem: 'UCRT64' + baseruby: '3.0' + test_task: 'check' + test-all-opts: '--name=!/TestObjSpace#test_reachable_objects_during_iteration/' fail-fast: false + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + steps: - - run: mkdir build - working-directory: - - name: git config - run: | - git config --global core.autocrlf false - git config --global core.eol lf - git config --global advice.detachedHead 0 - git config --global init.defaultBranch garbage - - uses: actions/checkout@v2 - with: - path: src - name: Set up Ruby & MSYS2 - uses: MSP-Greg/setup-ruby-pkgs@ucrt + uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 with: - ruby-version: ${{ matrix.base_ruby }} - setup-ruby-ref: MSP-Greg/ruby-setup-ruby/00-win-ucrt - mingw: _upgrade_ gmp libffi libyaml openssl ragel readline gcc - msys2: automake1.16 bison + ruby-version: ${{ matrix.baseruby }} + - name: where check run: | # show where - Write-Host - $where = 'gcc.exe', 'ragel.exe', 'make.exe', 'bison.exe', 'libcrypto-1_1-x64.dll', 'libssl-1_1-x64.dll' - foreach ($e in $where) { - $rslt = where.exe $e 2>&1 | Out-String - if ($rslt.contains($e)) { Write-Host $rslt } - else { Write-Host "`nCan't find $e" } - } - - name: misc setup, autoreconf - run: | - mkdir install - mkdir temp - cd src - sh -c "autoreconf -fi" + mv /c/Windows/System32/libcrypto-1_1-x64.dll /c/Windows/System32/libcrypto-1_1-x64.dll_ + mv /c/Windows/System32/libssl-1_1-x64.dll /c/Windows/System32/libssl-1_1-x64.dll_ + result=true + for e in gcc.exe ragel.exe make.exe libcrypto-1_1-x64.dll libssl-1_1-x64.dll; do + echo ::group::$'\033[93m'$e$'\033[m' + where $e || result=false + echo ::endgroup:: + done + $result working-directory: - - name: configure - run: | - # Actions uses UTF8, causes test failures, similar to normal OS setup - $PSDefaultParameterValues['*:Encoding'] = 'utf8' - [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437") - [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437") - $config_args = "--build=$env:CHOST --host=$env:CHOST --target=$env:CHOST" - Write-Host $config_args - sh -c "../src/configure --disable-install-doc --prefix=/install $config_args" - # Write-Host "-------------------------------------- config.log" - # Get-Content ./config.log | foreach {Write-Output $_} - - - name: update + - name: version check run: | - $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS) - make -j $jobs incs + # show version + result=true + for e in gcc ragel make "openssl version"; do + case "$e" in *" "*) ;; *) e="$e --version";; esac + echo ::group::$'\033[93m'$e$'\033[m' + $e || result=false + echo ::endgroup:: + done + $result + working-directory: - - name: download gems - run: | - $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS) - make -j $jobs update-gems + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github - - name: make all - timeout-minutes: 20 - run: | - $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS) - make -j $jobs + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true - - run: make leaked-globals + - name: configure + run: > + ../src/configure --disable-install-doc --prefix=/. + --build=$CHOST --host=$CHOST --target=$CHOST + + - name: make all + timeout-minutes: 30 + run: make - name: make install - run: | - # Actions uses UTF8, causes test failures, similar to normal OS setup - $PSDefaultParameterValues['*:Encoding'] = 'utf8' - [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437") - [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437") - make DESTDIR=.. install-nodoc + run: make DESTDIR=../install install-nodoc - name: test - timeout-minutes: 5 - run: | - make test + timeout-minutes: 30 + run: make test + shell: cmd + env: + GNUMAKEFLAGS: '' + RUBY_TESTOPTS: '-v --tty=no' + if: ${{ matrix.test_task == 'check' || matrix.test_task == 'test' }} - name: test-all - timeout-minutes: 30 + timeout-minutes: 45 + shell: cmd run: | - # Actions uses UTF8, causes test failures, similar to normal OS setup - $PSDefaultParameterValues['*:Encoding'] = 'utf8' - [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437") - [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437") - $jobs = [int](1.5 * $env:NUMBER_OF_PROCESSORS) - if ($env:BUNDLER_VERSION) { Remove-Item env:\BUNDLER_VERSION } - make test-all TESTOPTS="-j $jobs --retry --job-status=normal --show-skip --timeout-scale=1.5" + make ${{ StartsWith(matrix.test_task, 'test/') && matrix.test_task || 'test-all' }} + env: + RUBY_TESTOPTS: >- + --retry --job-status=normal --show-skip --timeout-scale=1.5 + ${{ matrix.test-all-opts }} + BUNDLER_VERSION: + if: ${{ matrix.test_task == 'check' || matrix.test_task == 'test-all' || StartsWith(matrix.test_task, 'test/') }} - name: test-spec timeout-minutes: 10 - working-directory: src/spec/ruby run: | - $env:Path = "$pwd/../../../install/bin;$env:Path" - # Actions uses UTF8, causes test failures, similar to normal OS setup - $PSDefaultParameterValues['*:Encoding'] = 'utf8' - [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("IBM437") - [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding("IBM437") - ruby -v - ruby ../mspec/bin/mspec -I../../tool/lib -j --timeout 60 - - - uses: k0kubun/action-slack@v2.0.0 + make ${{ StartsWith(matrix.test_task, 'spec/') && matrix.test_task || 'test-spec' }} + shell: cmd + if: ${{ matrix.test_task == 'check' || matrix.test_task == 'test-spec' || StartsWith(matrix.test_task, 'spec/') }} + + - uses: ./src/.github/actions/slack with: - payload: | - { - "ci": "GitHub Actions", - "env": "${{ github.workflow }} / ${{ matrix.test_task }}", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref }}".split('/').reverse()[0] - } - env: + label: ${{ matrix.msystem }} / ${{ matrix.test_task }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: working-directory: build + shell: sh diff --git a/.github/workflows/mjit.yml b/.github/workflows/mjit.yml deleted file mode 100644 index 63011e78d0..0000000000 --- a/.github/workflows/mjit.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: MJIT -on: [push, pull_request] -jobs: - make: - strategy: - matrix: - test_task: [ "check" ] # to make job names consistent - jit_opts: [ "--jit", "--jit-wait" ] - fail-fast: false - runs-on: ubuntu-latest - env: - TESTOPTS: '-q --tty=no' - RUN_OPTS: '--disable-gems ${{ matrix.jit_opts }} --jit-debug=-ggdb3' - GITPULLOPTIONS: --no-tags origin ${{github.ref}} - steps: - - run: mkdir build - working-directory: - - name: Install libraries - run: | - set -x - sudo apt-get update -q || : - sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby - - name: git config - run: | - git config --global advice.detachedHead 0 - git config --global init.defaultBranch garbage - - uses: actions/checkout@v2 - with: - path: src - - name: Fixed world writable dirs - run: | - chmod -v go-w $HOME $HOME/.config - sudo chmod -R go-w /usr/share - sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || : - - name: Set ENV - run: | - echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV - - run: ./autogen.sh - working-directory: src - - name: Run configure - run: ../src/configure -C --disable-install-doc cppflags=-DVM_CHECK_MODE - - run: make $JOBS incs - - run: make $JOBS - - run: sudo make $JOBS -s install - - run: sudo apt-get install gdb # used by test / test-all failure - - name: Run test - run: | - ulimit -c unlimited - make $JOBS -s test RUN_OPTS="$RUN_OPTS" - timeout-minutes: 60 - - name: Run test-all - run: | - ulimit -c unlimited - make $JOBS -s test-all RUN_OPTS="$RUN_OPTS" - timeout-minutes: 60 - - name: Run test-spec - run: | - ulimit -c unlimited - make $JOBS -s test-spec RUN_OPTS="$RUN_OPTS" - timeout-minutes: 60 - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "ci": "GitHub Actions", - "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.jit_opts }}", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref }}".split('/').reverse()[0] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} - -defaults: - run: - working-directory: build diff --git a/.github/workflows/pr-playground.yml b/.github/workflows/pr-playground.yml new file mode 100644 index 0000000000..cc06006142 --- /dev/null +++ b/.github/workflows/pr-playground.yml @@ -0,0 +1,127 @@ +name: Post Playground link to PR +on: + pull_request_target: + types: [labeled] + workflow_run: + workflows: ["WebAssembly"] + types: [completed] + +jobs: + post-summary: + name: Post Playground link + runs-on: ubuntu-latest + permissions: + pull-requests: write + # Post a comment only if the PR status check is passed and the PR is labeled with `Playground`. + # Triggered twice: when the PR is labeled and when PR build is passed. + if: >- + ${{ false + || (true + && github.event_name == 'pull_request_target' + && contains(github.event.pull_request.labels.*.name, 'Playground')) + || (true + && github.event_name == 'workflow_run' + && github.event.workflow_run.conclusion == 'success' + && github.event.workflow_run.event == 'pull_request') + }} + steps: + - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs/promises'); + + const buildWorkflowPath = '.github/workflows/wasm.yml'; + const findSuccessfuBuildRun = async (pr) => { + const opts = github.rest.actions.listWorkflowRunsForRepo.endpoint.merge({ + owner: context.repo.owner, + repo: context.repo.repo, + status: 'success', + branch: pr.head.ref, + }); + const runs = await github.paginate(opts); + const buildRun = runs.find(run => run.path == buildWorkflowPath); + return buildRun; + } + + const postComment = async (body, pr) => { + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + }); + + const commentOpts = { owner: context.repo.owner, repo: context.repo.repo, body: comment }; + + const existingComment = comments.find(comment => comment.body.startsWith(magicComment)); + if (existingComment) { + core.info(`Updating existing comment: ${existingComment.html_url}`); + await github.rest.issues.updateComment({ + ...commentOpts, comment_id: existingComment.id + }); + } else { + await github.rest.issues.createComment({ + ...commentOpts, issue_number: pr.number + }); + } + } + + const derivePRNumber = async () => { + if (context.payload.pull_request) { + return context.payload.pull_request.number; + } + // Workaround for https://github.com/orgs/community/discussions/25220 + + const { data: { artifacts } } = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + const artifact = artifacts.find(artifact => artifact.name == 'github-pr-info'); + if (!artifact) { + throw new Error('Cannot find github-pr-info.txt artifact'); + } + + const { data } = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: artifact.id, + archive_format: 'zip', + }); + + await fs.writeFile('pr-info.zip', Buffer.from(data)); + await exec.exec('unzip', ['pr-info.zip']); + return await fs.readFile('github-pr-info.txt', 'utf8'); + } + + const prNumber = await derivePRNumber(); + + const { data: pr } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber, + }); + + core.info(`Checking if the PR ${prNumber} is labeled with Playground...`); + if (!pr.labels.some(label => label.name == 'Playground')) { + core.info(`The PR is not labeled with Playground.`); + return; + } + + core.info(`Checking if the build is successful for ${pr.head.ref} in ${pr.head.repo.owner.login}/${pr.head.repo.name}...`); + const buildRun = await findSuccessfuBuildRun(pr); + if (!buildRun) { + core.info(`No successful build run found for ${buildWorkflowPath} on ${pr.head.ref} yet.`); + return; + } + core.info(`Found a successful build run: ${buildRun.html_url}`); + + const runLink = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; + const magicComment = `<!-- AUTO-GENERATED-COMMENT-PR-PLAYGROUND -->`; + const comment = `${magicComment} + **Try on Playground**: https://ruby.github.io/play-ruby?run=${buildRun.id} + This is an automated comment by [\`pr-playground.yml\`](${runLink}) workflow. + `; + core.info(`Comment: ${comment}`); + await postComment(comment, pr); + diff --git a/.github/workflows/prism.yml b/.github/workflows/prism.yml new file mode 100644 index 0000000000..95a36f1634 --- /dev/null +++ b/.github/workflows/prism.yml @@ -0,0 +1,114 @@ +name: Prism +on: + push: + paths-ignore: + - 'doc/**' + - '**.md' + - '**.rdoc' + - '**/.document' + - '**.[1-8]' + - '**.ronn' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**.md' + - '**.rdoc' + - '**/.document' + - '**.[1-8]' + - '**.ronn' + - '.*.yml' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + +jobs: + make: + strategy: + matrix: + # main variables included in the job name + test_task: [check] + run_opts: ['--parser=prism'] + arch: [''] + fail-fast: false + + env: + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + RUBY_DEBUG: ci + SETARCH: ${{ matrix.arch && format('setarch {0}', matrix.arch) }} + + runs-on: ubuntu-22.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - uses: ./.github/actions/setup/ubuntu + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + + - name: Run configure + env: + arch: ${{ matrix.arch }} + run: >- + $SETARCH ../src/configure -C --disable-install-doc cppflags=-DRUBY_DEBUG + ${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE} + + - run: $SETARCH make + + - name: make test + run: | + $SETARCH make -s test RUN_OPTS="$RUN_OPTS" + timeout-minutes: 30 + env: + GNUMAKEFLAGS: '' + RUBY_TESTOPTS: '-v --tty=no' + RUN_OPTS: ${{ matrix.run_opts }} + + - name: make test-all + run: | + $SETARCH make -s test-all RUN_OPTS="$RUN_OPTS" + timeout-minutes: 40 + env: + GNUMAKEFLAGS: '' + RUBY_TESTOPTS: '-q --tty=no --excludes-dir="../src/test/.excludes-prism" --exclude="test_ast.rb" --exclude="error_highlight/test_error_highlight.rb" --exclude="prism/encoding_test.rb" --exclude="prism/locals_test.rb" --exclude="prism/newline_test.rb"' + RUN_OPTS: ${{ matrix.run_opts }} + + - name: make test-prism-spec + run: | + $SETARCH make -s test-prism-spec SPECOPTS="$SPECOPTS" + timeout-minutes: 10 + env: + GNUMAKEFLAGS: '' + SPECOPTS: "-T -W:no-experimental -T --parser=prism" + + - uses: ./.github/actions/slack + with: + label: ${{ matrix.run_opts }} + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} + +defaults: + run: + working-directory: build diff --git a/.github/workflows/rjit-bindgen.yml b/.github/workflows/rjit-bindgen.yml new file mode 100644 index 0000000000..1263c20505 --- /dev/null +++ b/.github/workflows/rjit-bindgen.yml @@ -0,0 +1,86 @@ +name: RJIT bindgen +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + +jobs: + make: + strategy: + matrix: + include: + - task: rjit-bindgen + fail-fast: false + + runs-on: ubuntu-20.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + steps: + - name: Set up Ruby + uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 + with: + ruby-version: '3.1' + + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - uses: ./.github/actions/setup/ubuntu + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + + - name: Run configure + run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install --enable-yjit=dev_nodebug + + - run: make + + - run: make install + + - run: make ${{ matrix.task }} + + - run: git diff --exit-code + working-directory: src + + - uses: ./.github/actions/slack + with: + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} + +defaults: + run: + working-directory: build diff --git a/.github/workflows/rjit.yml b/.github/workflows/rjit.yml new file mode 100644 index 0000000000..7a5e6cf7c0 --- /dev/null +++ b/.github/workflows/rjit.yml @@ -0,0 +1,114 @@ +name: RJIT +on: + push: + paths-ignore: + - 'doc/**' + - '**.md' + - '**.rdoc' + - '**/.document' + - '**.[1-8]' + - '**.ronn' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**.md' + - '**.rdoc' + - '**/.document' + - '**.[1-8]' + - '**.ronn' + - '.*.yml' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + +jobs: + make: + strategy: + matrix: + # main variables included in the job name + test_task: [check] + run_opts: ['--rjit-call-threshold=1'] + arch: [''] + fail-fast: false + + env: + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + RUBY_DEBUG: ci + SETARCH: ${{ matrix.arch && format('setarch {0}', matrix.arch) }} + + runs-on: ubuntu-22.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - uses: ./.github/actions/setup/ubuntu + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + + - name: Run configure + env: + arch: ${{ matrix.arch }} + run: >- + $SETARCH ../src/configure -C --disable-install-doc cppflags=-DRUBY_DEBUG + ${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE} + + - run: $SETARCH make + + - name: make test + run: | + $SETARCH make -s test RUN_OPTS="$RUN_OPTS" + timeout-minutes: 30 + env: + GNUMAKEFLAGS: '' + RUBY_TESTOPTS: '-v --tty=no' + RUN_OPTS: ${{ matrix.run_opts }} + + - name: make test-all + run: | + $SETARCH make -s test-all RUN_OPTS="$RUN_OPTS" + timeout-minutes: 40 + env: + GNUMAKEFLAGS: '' + RUBY_TESTOPTS: '-q --tty=no' + RUN_OPTS: ${{ matrix.run_opts }} + + - name: make test-spec + run: | + $SETARCH make -s test-spec RUN_OPTS="$RUN_OPTS" + timeout-minutes: 10 + env: + GNUMAKEFLAGS: '' + RUN_OPTS: ${{ matrix.run_opts }} + + - uses: ./.github/actions/slack + with: + label: ${{ matrix.run_opts }} + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} + +defaults: + run: + working-directory: build diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml new file mode 100644 index 0000000000..00a0638e96 --- /dev/null +++ b/.github/workflows/scorecards.yml @@ -0,0 +1,72 @@ +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +name: Scorecards supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '22 4 * * 2' + # push: + # branches: [ "master" ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecards analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + # Uncomment the permissions below if installing in a private repository. + # contents: read + # actions: read + + steps: + - name: 'Checkout code' + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + persist-credentials: false + + - name: 'Run analysis' + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + with: + results_file: results.sarif + results_format: sarif + # (Optional) Read-only PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecards on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. + repo_token: ${{ secrets.SCORECARD_READ_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + # - name: "Upload artifact" + # uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + # with: + # name: SARIF file + # path: results.sarif + # retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: 'Upload to code-scanning' + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v2.1.27 + with: + sarif_file: results.sarif diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml index 61ebeb33c1..165a0150b5 100644 --- a/.github/workflows/spec_guards.yml +++ b/.github/workflows/spec_guards.yml @@ -1,38 +1,66 @@ name: Rubyspec Version Guards Check -on: [push, pull_request] +on: + push: + paths: + - 'spec/**' + - '!spec/*.md' + pull_request: + paths: + - 'spec/**' + - '!spec/*.md' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read jobs: rubyspec: name: Rubyspec + runs-on: ubuntu-20.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + strategy: matrix: # Specs from ruby/spec should still run on all supported Ruby versions. # This also ensures the needed ruby_version_is guards are there, see spec/README.md. ruby: - - ruby-2.7 - ruby-3.0 + - ruby-3.1 + - ruby-3.2 + - ruby-3.3 steps: - - uses: actions/checkout@v2 - - uses: ruby/setup-ruby@v1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + - uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 with: ruby-version: ${{ matrix.ruby }} bundler: none + - run: gem install webrick + - run: ruby ../mspec/bin/mspec working-directory: spec/ruby - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "ci": "GitHub Actions", - "env": "${{ github.workflow }} / rubyspec @ ${{ matrix.ruby }}", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref }}".split('/').reverse()[0] - } env: + CHECK_LEAKS: true + + - uses: ./.github/actions/slack + with: + label: ${{ matrix.ruby }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index e148b76cbe..b6f989a03d 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -1,78 +1,152 @@ name: Ubuntu -on: [push, pull_request] +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + # Do not use paths-ignore for required status checks + # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + jobs: make: strategy: matrix: - test_task: ["check", "test-bundler-parallel", "test-bundled-gems"] - os: - - ubuntu-20.04 -# - ubuntu-18.04 - configure: ["", "cppflags=-DRUBY_DEBUG"] include: - - test_task: "test-all TESTS=--repeat-count=2" + - test_task: check + configure: 'cppflags=-DVM_CHECK_MODE' + - test_task: check + arch: i686 + - test_task: check + configure: '--disable-yjit' + - test_task: check + configure: '--enable-shared --enable-load-relative' + - test_task: check + configure: '--with-shared-gc' + - test_task: test-bundler-parallel + - test_task: test-bundled-gems + - test_task: check os: ubuntu-20.04 - configure: "" fail-fast: false + env: - GITPULLOPTIONS: --no-tags origin ${{github.ref}} + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} RUBY_DEBUG: ci - runs-on: ${{ matrix.os }} + + runs-on: ${{ matrix.os || 'ubuntu-22.04' }} + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + steps: - - run: mkdir build - working-directory: - - name: Install libraries + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - uses: ./.github/actions/setup/ubuntu + with: + arch: ${{ matrix.arch }} + + - uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 + with: + ruby-version: '3.0' + bundler: none + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + clean: true + dummy-files: ${{ matrix.test_task == 'check' }} + # Set fetch-depth: 10 so that Launchable can receive commits information. + fetch-depth: 10 + + - name: Run configure + env: + arch: ${{ matrix.arch }} + configure: ${{ matrix.configure }} + run: >- + $SETARCH ../src/configure -C --disable-install-doc ${configure:-cppflags=-DRUBY_DEBUG} + ${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE} + + - run: $SETARCH make prepare-gems + if: ${{ matrix.test_task == 'test-bundled-gems' }} + + - run: $SETARCH make + + - name: Set test options for skipped tests run: | set -x - sudo apt-get update -q || : - sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby - - name: git config - run: | - git config --global advice.detachedHead 0 - git config --global init.defaultBranch garbage - - uses: actions/checkout@v2 + TESTS="$(echo "${{ matrix.skipped_tests }}" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|')" + echo "TESTS=${TESTS}" >> $GITHUB_ENV + if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} + + - name: Set up Launchable + uses: ./.github/actions/launchable/setup with: - path: src - - name: Fixed world writable dirs - run: | - chmod -v go-w $HOME $HOME/.config - sudo chmod -R go-w /usr/share - sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || : - - name: Set ENV - run: | - echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV - - run: ./autogen.sh - working-directory: src - - name: Run configure - run: ../src/configure -C --disable-install-doc ${{ matrix.configure }} - - run: make $JOBS incs - - run: make $JOBS - - run: make leaked-globals - if: ${{ matrix.test_task == 'check' }} - - run: make prepare-gems - if: ${{ matrix.test_task == 'check' }} - - name: Create dummy files in build dir + os: ${{ matrix.os || 'ubuntu-22.04' }} + test-opts: ${{ matrix.configure }} + launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} + builddir: build + srcdir: src + continue-on-error: true + + - name: make ${{ matrix.test_task }} + run: >- + $SETARCH make -s ${{ matrix.test_task }} + ${TESTS:+TESTS="$TESTS"} + ${{ !contains(matrix.test_task, 'bundle') && 'RUBYOPT=-w' || '' }} + timeout-minutes: 40 + env: + RUBY_TESTOPTS: '-q --tty=no' + TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' + PRECHECK_BUNDLED_GEMS: 'no' + + - name: make skipped tests run: | - ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}' - if: ${{ matrix.test_task == 'check' }} - - run: make $JOBS -s ${{ matrix.test_task }} - timeout-minutes: 30 + $SETARCH make -s test-all TESTS="${TESTS//-n!\//-n/}" env: - RUBY_TESTOPTS: "-q --tty=no" - TEST_BUNDLED_GEMS_ALLOW_FAILURES: "" - - uses: k0kubun/action-slack@v2.0.0 + GNUMAKEFLAGS: '' + RUBY_TESTOPTS: '-v --tty=no' + if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} + continue-on-error: ${{ matrix.continue-on-skipped_tests || false }} + + - uses: ./.github/actions/slack with: - payload: | - { - "ci": "GitHub Actions", - "env": "${{ matrix.os }} / ${{ matrix.test_task }}${{ matrix.configure }}", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref }}".split('/').reverse()[0] - } - env: + label: ${{ matrix.test_task }} ${{ matrix.configure }}${{ matrix.arch }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} + + result: + if: ${{ always() }} + name: ${{ github.workflow }} result + runs-on: ubuntu-latest + needs: [make] + steps: + - run: exit 1 + working-directory: + if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} defaults: run: diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml new file mode 100644 index 0000000000..e0b67496ac --- /dev/null +++ b/.github/workflows/wasm.yml @@ -0,0 +1,175 @@ +name: WebAssembly +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: # added using https://github.com/step-security/secure-workflows + contents: read + +jobs: + make: + strategy: + matrix: + entry: +# # wasmtime can't compile non-optimized Asyncified binary due to locals explosion +# - { name: O0-debuginfo, optflags: '-O0', debugflags: '-g', wasmoptflags: '-O1' } +# - { name: O1, optflags: '-O1', debugflags: '' , wasmoptflags: '-O1' } + - { name: O2, optflags: '-O2', debugflags: '', wasmoptflags: '-O2' } +# - { name: O3, optflags: '-O3', debugflags: '' , wasmoptflags: '-O3' } +# # -O4 is equivalent to -O3 in clang, but it's different in wasm-opt +# - { name: O4, optflags: '-O3', debugflags: '' , wasmoptflags: '-O4' } +# - { name: Oz, optflags: '-Oz', debugflags: '' , wasmoptflags: '-Oz' } + fail-fast: false + + env: + RUBY_TESTOPTS: '-q --tty=no' + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + WASI_SDK_VERSION_MAJOR: 20 + WASI_SDK_VERSION_MINOR: 0 + BINARYEN_VERSION: 113 + WASMTIME_VERSION: v15.0.0 + + runs-on: ubuntu-20.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + + - name: Install libraries + run: | + set -ex + sudo apt-get update -q || : + sudo apt-get install --no-install-recommends -q -y ruby make autoconf git wget + + wasi_sdk_deb="wasi-sdk_${WASI_SDK_VERSION_MAJOR}.${WASI_SDK_VERSION_MINOR}_amd64.deb" + wget "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION_MAJOR}/${wasi_sdk_deb}" + sudo dpkg -i "$wasi_sdk_deb" + rm -f "$wasi_sdk_deb" + + mkdir build-sdk + pushd build-sdk + + wasmtime_url="https://github.com/bytecodealliance/wasmtime/releases/download/${WASMTIME_VERSION}/wasmtime-${WASMTIME_VERSION}-x86_64-linux.tar.xz" + wget -O - "$wasmtime_url" | tar xJf - + sudo ln -fs "$PWD/wasmtime-${WASMTIME_VERSION}-x86_64-linux/wasmtime" /usr/local/bin/wasmtime + + binaryen_tarball="binaryen-version_${BINARYEN_VERSION}-x86_64-linux.tar.gz" + binaryen_url="https://github.com/WebAssembly/binaryen/releases/download/version_${BINARYEN_VERSION}/${binaryen_tarball}" + wget -O - "$binaryen_url" | tar xfz - + sudo ln -fs "$PWD/binaryen-version_${BINARYEN_VERSION}/bin/wasm-opt" /usr/local/bin/wasm-opt + working-directory: src + + - name: Set ENV + run: | + echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV + + - uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 + with: + ruby-version: '3.0' + bundler: none + + - name: Build baseruby + run: | + set -ex + mkdir ../baseruby + pushd ../baseruby + ../src/configure --prefix=$PWD/install + make + make install + + - name: Run configure + run: | + ../src/configure \ + --host wasm32-unknown-wasi \ + --with-baseruby=$PWD/../baseruby/install/bin/ruby \ + --with-static-linked-ext \ + --with-ext=cgi/escape,continuation,coverage,date,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,json,json/generator,json/parser,objspace,pathname,rbconfig/sizeof,ripper,stringio,strscan,monitor \ + LDFLAGS=" \ + -Xlinker --stack-first \ + -Xlinker -z -Xlinker stack-size=16777216 \ + " \ + optflags="${{ matrix.entry.optflags }}" \ + debugflags="${{ matrix.entry.debugflags }}" \ + wasmoptflags="${{ matrix.entry.wasmoptflags }} ${{ matrix.entry.debugflags }}" + + # miniruby may not be built when cross-compling + - run: make mini ruby + + - run: make install DESTDIR=$PWD/../install + - run: tar cfz ../install.tar.gz -C ../install . + + - name: Upload artifacts + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: ruby-wasm-install + path: ${{ github.workspace }}/install.tar.gz + - name: Show Playground URL to try the build + run: | + echo "Try on Playground: https://ruby.github.io/play-ruby?run=$GITHUB_RUN_ID" >> $GITHUB_STEP_SUMMARY + + - name: Run basictest + run: wasmtime run ./../build/miniruby --mapdir /::./ -- basictest/test.rb + working-directory: src + + - name: Run bootstraptest (no thread) + run: | + NO_THREAD_TESTS="$(grep -L Thread -R ./bootstraptest | awk -F/ '{ print $NF }' | uniq | sed -n 's/test_\(.*\).rb/\1/p' | paste -s -d, -)" + ruby ./bootstraptest/runner.rb --ruby="$(which wasmtime) run $PWD/../build/ruby --mapdir /::./ -- " --verbose "--sets=$NO_THREAD_TESTS" + working-directory: src + + - uses: ./.github/actions/slack + with: + label: ${{ matrix.entry.name }} + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} + + # Workaround for https://github.com/orgs/community/discussions/25220 + - name: Save Pull Request number + if: ${{ github.event_name == 'pull_request' }} + run: echo "${{ github.event.pull_request.number }}" >> ${{ github.workspace }}/github-pr-info.txt + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + if: ${{ github.event_name == 'pull_request' }} + with: + name: github-pr-info + path: ${{ github.workspace }}/github-pr-info.txt + +defaults: + run: + working-directory: build diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 66b2992049..67cca44fa6 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -1,122 +1,208 @@ name: Windows -on: [push, pull_request] +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + jobs: make: strategy: matrix: include: + - vc: 2015 + vs: 2019 + vcvars: '10.0.14393.0 -vcvars_ver=14.0' # The oldest Windows 10 SDK w/ VC++ 2015 toolset (v140) - vs: 2019 - os: windows-2019 - vcvars: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"' - # - vs: 2022 - # os: windows-2022 - # vcvars: '"C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Auxiliary\Build\vcvars64.bat"' + - vs: 2022 fail-fast: false - runs-on: ${{ matrix.os }} - name: VisualStudio ${{ matrix.vs }} + + runs-on: windows-${{ matrix.vs < 2022 && '2019' || matrix.vs }} + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + name: VisualStudio ${{ matrix.vc || matrix.vs }} + env: - GITPULLOPTIONS: --no-tags origin ${{github.ref}} - VCVARS: ${{ matrix.vcvars }} - PATCH: C:\msys64\usr\bin\patch.exe + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + OS_VER: windows-${{ matrix.vs < 2022 && '2019' || matrix.vs }} + # FIXME: This is a workaround for the vcpkg's issue present as of openssl 3.1.1 + # where OpenSSL's default modules directory is incorrectly set to C:\vcpkg\packages\openssl_x64-windows\bin + # cf. https://github.com/ruby/openssl/pull/635#issuecomment-1596833720 + OPENSSL_MODULES: C:\vcpkg\installed\x64-windows\bin + steps: - run: md build working-directory: - - uses: msys2/setup-msys2@v2 + + - name: find tools + id: find-tools + run: | + ::- find needed tools + set NEEDS= + for %%I in (%NEEDED_TOOLS%) do if "%%~$PATH:I" == "" ( + call set NEEDS=%%NEEDS%% %%~nI + ) else ( + echo %%I: %%~$PATH:I + ) + echo.needs=%NEEDS%>>%GITHUB_OUTPUT% + if "%NEEDS%" == "" ( + echo [debug] All needed tools found + ) else ( + echo [warning^]Needs%NEEDS% + ) + env: + NEEDED_TOOLS: >- + patch.exe + + - uses: msys2/setup-msys2@d40200dc2db4c351366b048a9565ad82919e1c24 # v2 id: setup-msys2 with: update: true install: >- - patch - if: ${{ matrix.os != 'windows-2019' }} - - name: patch path - shell: msys2 {0} - run: echo PATCH=$(cygpath -wa $(command -v patch)) >> $GITHUB_ENV - if: ${{ steps.setup-msys2.outcome == 'success' }} - - uses: actions/cache@v2 + ${{ steps.find-tools.outputs.needs }} + if: ${{ steps.find-tools.outputs.needs != '' }} + + - uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 + with: + ruby-version: '3.0' + bundler: none + windows-toolchain: none + + - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: C:\vcpkg\downloads - key: ${{ runner.os }}-vcpkg-download-${{ matrix.os }}-${{ github.sha }} + key: ${{ runner.os }}-vcpkg-download-${{ env.OS_VER }}-${{ github.sha }} restore-keys: | - ${{ runner.os }}-vcpkg-download-${{ matrix.os }}- + ${{ runner.os }}-vcpkg-download-${{ env.OS_VER }}- ${{ runner.os }}-vcpkg-download- - - name: Install libraries with vcpkg - run: | - vcpkg --triplet x64-windows install readline zlib - - uses: actions/cache@v2 + + - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: - path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey - key: ${{ runner.os }}-chocolatey-${{ matrix.os }}-${{ github.sha }} + path: C:\vcpkg\installed + key: ${{ runner.os }}-vcpkg-installed-${{ env.OS_VER }}-${{ github.sha }} restore-keys: | - ${{ runner.os }}-chocolatey-${{ matrix.os }}- - ${{ runner.os }}-chocolatey- - - name: Install libraries with chocolatey + ${{ runner.os }}-vcpkg-installed-${{ env.OS_VER }}- + ${{ runner.os }}-vcpkg-installed- + + - name: Install libraries with vcpkg run: | - # Using Choco-Install for retries, but it doesn't detect failures properly - # if you pass multiple package names in a single command. - Choco-Install -PackageName openssl - Choco-Install -PackageName winflexbison3 - shell: pwsh - - name: git config + vcpkg --triplet x64-windows install libffi libyaml openssl readline zlib + + - name: Install libraries with scoop run: | - git config --global core.autocrlf false - git config --global core.eol lf - git config --global advice.detachedHead 0 - git config --global init.defaultBranch garbage - - uses: actions/checkout@v2 + iex "& {$(irm get.scoop.sh)} -RunAsAdmin" + Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH + shell: pwsh + + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: - path: src + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + - name: setup env + # Available Ruby versions: https://github.com/actions/runner-images/blob/main/images/windows/Windows2019-Readme.md#ruby # %TEMP% is inconsistent with %TMP% and test-all expects they are consistent. # https://github.com/actions/virtual-environments/issues/712#issuecomment-613004302 run: | + set VS=${{ matrix.vs }} + set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + if not exist %VCVARS% set VCVARS="C:\Program Files\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvars64.bat" set | C:\msys64\usr\bin\sort > old.env - call %VCVARS% + call %VCVARS% ${{ matrix.vcvars || '' }} + nmake -f nul set TMP=%USERPROFILE%\AppData\Local\Temp set TEMP=%USERPROFILE%\AppData\Local\Temp + set MAKEFLAGS=l + set /a TEST_JOBS=(15 * %NUMBER_OF_PROCESSORS% / 10) > nul set | C:\msys64\usr\bin\sort > new.env C:\msys64\usr\bin\comm -13 old.env new.env >> %GITHUB_ENV% del *.env - - name: Configure + + - name: baseruby version + run: ruby -v + + - name: compiler version + run: cl + + - name: link libraries run: | - ../src/win32/configure.bat --disable-install-doc --enable-bundled-libffi --with-opt-dir=C:/vcpkg/installed/x64-windows --with-openssl-dir="C:/Program Files/OpenSSL-Win64" - - name: nmake + for %%I in (C:\vcpkg\installed\x64-windows\bin\*.dll) do ( + if not %%~nI == readline mklink %%~nxI %%I + ) + # We use OpenSSL instealled by vcpkg instead + - name: disable system OpenSSL run: | - echo ^#^#[group]incs - nmake incs - echo ^#^#[endgroup] - echo ^#^#[group]extract-extlibs - nmake extract-extlibs - echo ^#^#[endgroup] - nmake - env: - YACC: win_bison - - name: nmake test + for %%I in (libcrypto-1_1-x64 libssl-1_1-x64) do ( + ren c:\Windows\System32\%%I.dll %%I.dll_ + ) + # windows-2019 image doesn't have OpenSSL as of 2023/9/14 + if: ${{ matrix.vs != 2019 }} + + - name: Configure + run: >- + ../src/win32/configure.bat --disable-install-doc + --with-opt-dir=C:/vcpkg/installed/x64-windows + + - run: nmake incs + + - run: nmake extract-extlibs + + # On all other platforms, test-spec depending on extract-gems (in common.mk) is enough. + # But not for this Visual Studio workflow. So here we extract gems before building. + - run: nmake extract-gems + + - run: nmake + + - run: nmake test timeout-minutes: 5 - run: | - nmake test - - name: nmake test-all - timeout-minutes: 60 - run: | - nmake test-all TESTOPTS="-j%NUMBER_OF_PROCESSORS% --job-status=normal" - continue-on-error: ${{ matrix.continue-on-error || false }} - - name: nmake test-spec + + - run: nmake test-spec timeout-minutes: 10 - run: | - nmake test-spec - continue-on-error: ${{ matrix.continue-on-error || false }} - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "ci": "GitHub Actions", - "env": "VS${{ matrix.vs }} / ${{ matrix.test_task || 'check' }}", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref }}".split('/').reverse()[0] - } + + - run: nmake test-all env: + RUBY_TESTOPTS: -j${{ env.TEST_JOBS || 4 }} --job-status=normal + timeout-minutes: 60 + + - uses: ./.github/actions/slack + with: + label: VS${{ matrix.vc || matrix.vs }} / ${{ matrix.test_task || 'check' }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/yjit-macos.yml b/.github/workflows/yjit-macos.yml new file mode 100644 index 0000000000..948644d06e --- /dev/null +++ b/.github/workflows/yjit-macos.yml @@ -0,0 +1,166 @@ +name: YJIT macOS Arm64 +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + # Do not use paths-ignore for required status checks + # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + +jobs: + cargo: + name: cargo test + + runs-on: ${{ github.repository == 'ruby/ruby' && 'macos-arm-oss' || 'macos-14' }} + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + - run: RUST_BACKTRACE=1 cargo test + working-directory: yjit + + # Also compile and test with all features enabled + - run: RUST_BACKTRACE=1 cargo test --all-features + working-directory: yjit + + # Check that we can build in release mode too + - run: cargo build --release + working-directory: yjit + + make: + strategy: + matrix: + include: + - test_task: 'check' + configure: '--enable-yjit' + yjit_opts: '--yjit' + - test_task: 'check' + configure: '--enable-yjit=dev' + yjit_opts: '--yjit-call-threshold=1 --yjit-verify-ctx --yjit-code-gc' + fail-fast: false + + env: + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + RUN_OPTS: ${{ matrix.yjit_opts }} + + runs-on: ${{ github.repository == 'ruby/ruby' && 'macos-arm-oss' || 'macos-14' }} + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - name: Install libraries + uses: ./.github/actions/setup/macos + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + dummy-files: ${{ matrix.test_task == 'check' }} + # Set fetch-depth: 10 so that Launchable can receive commits information. + fetch-depth: 10 + + - name: Run configure + run: ../src/configure -C --disable-install-doc ${{ matrix.configure }} + + - run: make prepare-gems + if: ${{ matrix.test_task == 'test-bundled-gems' }} + + - run: make + + - name: Enable YJIT through ENV + run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV + + - name: Set test options for skipped tests + run: | + set -x + TESTS="$(echo "${{ matrix.skipped_tests }}" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|')" + echo "TESTS=${TESTS}" >> $GITHUB_ENV + if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} + + - name: Set up Launchable + uses: ./.github/actions/launchable/setup + with: + os: ${{ github.repository == 'ruby/ruby' && 'macos-arm-oss' || 'macos-14' }} + test-opts: ${{ matrix.configure }} + launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} + builddir: build + srcdir: src + continue-on-error: true + + - name: make ${{ matrix.test_task }} + run: >- + make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} + RUN_OPTS="$RUN_OPTS" + timeout-minutes: 60 + env: + RUBY_TESTOPTS: '-q --tty=no' + TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' + PRECHECK_BUNDLED_GEMS: 'no' + continue-on-error: ${{ matrix.continue-on-test_task || false }} + + - name: make skipped tests + run: | + make -s test-all TESTS="${TESTS//-n!\//-n/}" + env: + GNUMAKEFLAGS: '' + RUBY_TESTOPTS: '-v --tty=no' + PRECHECK_BUNDLED_GEMS: 'no' + if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} + continue-on-error: ${{ matrix.continue-on-skipped_tests || false }} + + - uses: ./.github/actions/slack + with: + label: ${{ matrix.test_task }} ${{ matrix.configure }} ${{ matrix.yjit_opts }} + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} + + result: + if: ${{ always() }} + name: ${{ github.workflow }} result + runs-on: ${{ github.repository == 'ruby/ruby' && 'macos-arm-oss' || 'macos-14' }} + needs: [make] + steps: + - run: exit 1 + working-directory: + if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + +defaults: + run: + working-directory: build diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml new file mode 100644 index 0000000000..02d0ac7536 --- /dev/null +++ b/.github/workflows/yjit-ubuntu.yml @@ -0,0 +1,219 @@ +name: YJIT Ubuntu +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '.*.yml' + pull_request: + # Do not use paths-ignore for required status checks + # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks + merge_group: + +concurrency: + group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} + cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} + +permissions: + contents: read + +jobs: + cargo: + name: cargo test + + # GitHub Action's image seems to already contain a Rust 1.58.0. + runs-on: ubuntu-20.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + # For now we can't run cargo test --offline because it complains about the + # capstone dependency, even though the dependency is optional + #- run: cargo test --offline + + - run: RUST_BACKTRACE=1 cargo test + working-directory: yjit + + # Also compile and test with all features enabled + - run: RUST_BACKTRACE=1 cargo test --all-features + working-directory: yjit + + # Check that we can build in release mode too + - run: cargo build --release + working-directory: yjit + + lint: + name: cargo clippy + + # GitHub Action's image seems to already contain a Rust 1.58.0. + runs-on: ubuntu-20.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + # Check that we don't have linting errors in release mode, too + - run: cargo clippy --all-targets --all-features + working-directory: yjit + + make: + strategy: + fail-fast: false + matrix: + include: + - test_task: 'yjit-bindgen' + hint: 'To fix: use patch in logs' + configure: '--with-gcc=clang-12 --enable-yjit=dev' + + - test_task: 'check' + # YJIT should be automatically built in release mode on x86-64 Linux with rustc present + #configure: "--enable-yjit RUSTC='rustc +1.58.0'" + configure: "RUSTC='rustc +1.58.0'" + rust_version: '1.58.0' + + - test_task: 'check' + configure: '--enable-yjit=dev' + + - test_task: 'check' + configure: '--enable-yjit=dev' + yjit_opts: '--yjit-call-threshold=1 --yjit-verify-ctx --yjit-code-gc' + + - test_task: 'test-bundled-gems' + configure: '--enable-yjit=dev' + + - test_task: 'yjit-bench' + configure: '--enable-yjit=dev' + yjit_bench_opts: '--yjit-stats' + continue-on-test_task: true + + env: + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + RUN_OPTS: ${{ matrix.yjit_opts }} + YJIT_BENCH_OPTS: ${{ matrix.yjit_bench_opts }} + RUBY_DEBUG: ci + BUNDLE_JOBS: 8 # for yjit-bench + RUST_BACKTRACE: 1 + + runs-on: ubuntu-20.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.head_commit.message, 'Document') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.title, 'Document') + || contains(github.event.pull_request.labels.*.name, 'Document') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + + - uses: ./.github/actions/setup/ubuntu + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + dummy-files: ${{ matrix.test_task == 'check' }} + # Set fetch-depth: 10 so that Launchable can receive commits information. + fetch-depth: 10 + + - name: Install Rust + if: ${{ matrix.rust_version }} + run: rustup install ${{ matrix.rust_version }} --profile minimal + + - uses: ruby/setup-ruby@70da3bbf44ac06db1b0547ce2acc9380a5270d1e # v1.175.0 + with: + ruby-version: '3.0' + bundler: none + + - name: Run configure + run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install ${{ matrix.configure }} + + - run: make incs + + - run: make prepare-gems + if: ${{ matrix.test_task == 'test-bundled-gems' }} + + - run: make + + - name: Enable YJIT through ENV + run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV + + # Check that the binary was built with YJIT + - name: Check YJIT enabled + run: ./miniruby --yjit -v | grep "+YJIT" + + - name: Set up Launchable + uses: ./.github/actions/launchable/setup + with: + os: ubuntu-20.04 + test-opts: ${{ matrix.configure }} + launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} + builddir: build + srcdir: src + continue-on-error: true + + - name: make ${{ matrix.test_task }} + run: >- + make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} + RUN_OPTS="$RUN_OPTS" MSPECOPT=--debug + YJIT_BENCH_OPTS="$YJIT_BENCH_OPTS" YJIT_BINDGEN_DIFF_OPTS="$YJIT_BINDGEN_DIFF_OPTS" + timeout-minutes: 90 + env: + RUBY_TESTOPTS: '-q --tty=no' + TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' + PRECHECK_BUNDLED_GEMS: 'no' + SYNTAX_SUGGEST_TIMEOUT: '5' + YJIT_BINDGEN_DIFF_OPTS: '--exit-code' + continue-on-error: ${{ matrix.continue-on-test_task || false }} + + - name: Show ${{ github.event.pull_request.base.ref }} GitHub URL for yjit-bench comparison + run: echo "https://github.com/${BASE_REPO}/commit/${BASE_SHA}" + env: + BASE_REPO: ${{ github.event.pull_request.base.repo.full_name }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} + if: ${{ matrix.test_task == 'yjit-bench' && startsWith(github.event_name, 'pull') }} + + - uses: ./.github/actions/slack + with: + label: ${{ matrix.test_task }} ${{ matrix.configure }} + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} + + result: + if: ${{ always() }} + name: ${{ github.workflow }} result + runs-on: ubuntu-latest + needs: [make] + steps: + - run: exit 1 + working-directory: + if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + +defaults: + run: + working-directory: build |