diff options
25 files changed, 244 insertions, 128 deletions
diff --git a/.github/actions/launchable/setup/action.yml b/.github/actions/launchable/setup/action.yml index 1cd28bf2d7..3a939452a3 100644 --- a/.github/actions/launchable/setup/action.yml +++ b/.github/actions/launchable/setup/action.yml @@ -57,12 +57,12 @@ inputs: outputs: stdout_report_path: - value: ${{ steps.variables.outputs.stdout_report_path }} + value: ${{ steps.global.outputs.stdout_report_path }} description: >- Report file path for standard output. stderr_report_path: - value: ${{ steps.variables.outputs.stderr_report_path }} + value: ${{ steps.global.outputs.stderr_report_path }} description: >- Report file path for standard error. @@ -114,6 +114,8 @@ runs: echo test_all_report_file='launchable_test_all_report.json' >> $GITHUB_OUTPUT echo btest_report_file='launchable_btest_report.json' >> $GITHUB_OUTPUT echo test_spec_report_dir='launchable_test_spec_report' >> $GITHUB_OUTPUT + echo stdout_report_path="launchable_stdout.log" >> $GITHUB_OUTPUT + echo stderr_report_path="launchable_stderr.log" >> $GITHUB_OUTPUT if: steps.enable-launchable.outputs.enable-launchable - name: Set environment variables for Launchable @@ -198,7 +200,10 @@ runs: fi if launchable_setup test_spec; then echo "SPECOPTS=${SPECOPTS:$SPECOPTS }--launchable-test-reports=${test_spec_report_dir}" >> $GITHUB_ENV + echo test_spec_enabled=true >> $GITHUB_OUTPUT fi + + echo launchable_setup_dir=$(pwd) >> $GITHUB_OUTPUT if: steps.enable-launchable.outputs.enable-launchable env: test_all_enabled: ${{ steps.global.outputs.test_all_enabled }} @@ -208,6 +213,14 @@ runs: btest_report_file: ${{ steps.global.outputs.btest_report_file }} test_spec_report_dir: ${{ steps.global.outputs.test_spec_report_dir }} + - name: make test-spec report directory in build directory + shell: bash + working-directory: ${{ inputs.builddir }} + run: mkdir "${test_spec_report_dir}" + if: ${{ steps.setup-launchable.outputs.test_spec_enabled == 'true' }} + env: + test_spec_report_dir: ${{ steps.global.outputs.test_spec_report_dir }} + - name: Clean up test results in Launchable uses: gacts/run-and-post-run@674528335da98a7afc80915ff2b4b860a0b3553a # v1.4.0 with: @@ -225,52 +238,11 @@ runs: btest_report_file: ${{ steps.global.outputs.btest_report_file }} test_spec_report_dir: ${{ steps.global.outputs.test_spec_report_dir }} - - name: Variables to report Launchable - id: variables - shell: bash - working-directory: ${{ inputs.srcdir }} - run: | - set -x - : # report-path from srcdir - if [ "${srcdir}" = "${{ github.workspace }}" ]; then - dir= - else - # srcdir must be equal to or under workspace - dir=$(echo ${srcdir:+${srcdir}/} | sed 's:[^/][^/]*/:../:g') - fi - if [ "${test_all_enabled}" = "true" ]; then - test_report_path="${dir}${builddir:+${builddir}/}${test_all_report_file}" - echo test_report_path="${test_report_path}" >> $GITHUB_OUTPUT - fi - if [ "${btest_enabled}" = "true" ]; then - btest_report_path="${dir}${builddir:+${builddir}/}${btest_report_file}" - echo btest_report_path="${btest_report_path}" >> $GITHUB_OUTPUT - fi - if [ "${test_spec_enabled}" = "true" ]; then - test_spec_report_path="${dir}${builddir:+${builddir}/}${test_spec_report_dir}" - mkdir "${test_spec_report_path}" - echo test_spec_report_path="${test_spec_report_path}" >> $GITHUB_OUTPUT - fi - stdout_report_path="${dir}${builddir:+${builddir}/}launchable_stdout.log" - stderr_report_path="${dir}${builddir:+${builddir}/}launchable_stderr.log" - echo stdout_report_path="${stdout_report_path}" >> $GITHUB_OUTPUT - echo stderr_report_path="${stderr_report_path}" >> $GITHUB_OUTPUT - if: steps.enable-launchable.outputs.enable-launchable - env: - srcdir: ${{ inputs.srcdir }} - builddir: ${{ inputs.builddir }} - test_all_enabled: ${{ steps.global.outputs.test_all_enabled }} - btest_enabled: ${{ steps.global.outputs.btest_enabled }} - test_spec_enabled: ${{ steps.global.outputs.test_spec_enabled }} - test_all_report_file: ${{ steps.global.outputs.test_all_report_file }} - btest_report_file: ${{ steps.global.outputs.btest_report_file }} - test_spec_report_dir: ${{ steps.global.outputs.test_spec_report_dir }} - - name: Record test results in Launchable uses: gacts/run-and-post-run@674528335da98a7afc80915ff2b4b860a0b3553a # v1.4.0 with: shell: bash - working-directory: ${{ inputs.srcdir }} + working-directory: ${{ inputs.builddir }} post: | if [[ "${test_all_enabled}" = "true" ]]; then \ launchable record attachment \ @@ -279,7 +251,7 @@ runs: "${stderr_report_path}"; \ launchable record tests \ --session "${test_all_session}" \ - raw "${test_report_path}" || true; \ + raw "${test_all_report_file}" || true; \ fi if [[ "${btest_enabled}" = "true" ]]; then \ @@ -289,7 +261,7 @@ runs: "${stderr_report_path}"; \ launchable record tests \ --session "${btest_session}" \ - raw "${btest_report_path}" || true; \ + raw "${btest_report_file}" || true; \ fi if [[ "${test_spec_enabled}" = "true" ]]; then \ @@ -299,18 +271,19 @@ runs: "${stderr_report_path}"; \ launchable record tests \ --session "${test_spec_session}" \ - raw ${test_spec_report_path}/* || true; \ + raw ${test_spec_report_dir}/* || true; \ fi - if: ${{ always() && steps.enable-launchable.outputs.enable-launchable }} + if: ${{ always() && steps.setup-launchable.outcome == 'success' }} env: - test_report_path: ${{ steps.variables.outputs.test_report_path }} - btest_report_path: ${{ steps.variables.outputs.btest_report_path }} - test_spec_report_path: ${{ steps.variables.outputs.test_spec_report_path }} + test_all_report_file: ${{ steps.global.outputs.test_all_report_file }} + btest_report_file: ${{ steps.global.outputs.btest_report_file }} + test_spec_report_dir: ${{ steps.global.outputs.test_spec_report_dir }} test_all_enabled: ${{ steps.global.outputs.test_all_enabled }} btest_enabled: ${{ steps.global.outputs.btest_enabled }} test_spec_enabled: ${{ steps.global.outputs.test_spec_enabled }} test_all_session: ${{ steps.setup-launchable.outputs.test_all_session }} btest_session: ${{ steps.setup-launchable.outputs.btest_session }} test_spec_session: ${{ steps.setup-launchable.outputs.test_spec_session }} - stdout_report_path: ${{ steps.variables.outputs.stdout_report_path }} - stderr_report_path: ${{ steps.variables.outputs.stderr_report_path }} + stdout_report_path: ${{ steps.global.outputs.stdout_report_path }} + stderr_report_path: ${{ steps.global.outputs.stderr_report_path }} + LAUNCHABLE_SETUP_DIR: ${{ steps.setup-launchable.outputs.launchable_setup_dir }} diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml index dcff2d699a..a890fc442f 100644 --- a/.github/workflows/annocheck.yml +++ b/.github/workflows/annocheck.yml @@ -74,7 +74,7 @@ jobs: builddir: build makeup: true - - uses: ruby/setup-ruby@d8d83c3960843afb664e821fed6be52f37da5267 # v1.231.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/auto_request_review.yml b/.github/workflows/auto_request_review.yml index a6c81c78cd..207315a084 100644 --- a/.github/workflows/auto_request_review.yml +++ b/.github/workflows/auto_request_review.yml @@ -17,4 +17,4 @@ jobs: uses: necojackarc/auto-request-review@e89da1a8cd7c8c16d9de9c6e763290b6b0e3d424 # v0.13.0 with: # scope: public_repo - token: ${{ secrets.MATZBOT_GITHUB_TOKEN }} + token: ${{ secrets.MATZBOT_AUTO_REQUEST_REVIEW_TOKEN }} diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml index 6b3974bc5b..8b77b01889 100644 --- a/.github/workflows/baseruby.yml +++ b/.github/workflows/baseruby.yml @@ -50,7 +50,7 @@ jobs: - ruby-3.3 steps: - - uses: ruby/setup-ruby@d8d83c3960843afb664e821fed6be52f37da5267 # v1.231.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml index 233f624453..788fd9be8d 100644 --- a/.github/workflows/bundled_gems.yml +++ b/.github/workflows/bundled_gems.yml @@ -33,11 +33,11 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - uses: ./.github/actions/setup/directories with: - # Skip overwriting MATZBOT_GITHUB_TOKEN + # Skip overwriting MATZBOT_AUTO_UPDATE_TOKEN checkout: '' # false (ref: https://github.com/actions/runner/issues/2238) - name: Set ENV diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index aa3882c165..22452a3b9e 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -40,7 +40,7 @@ jobs: - uses: ./.github/actions/setup/directories - - uses: ruby/setup-ruby@d8d83c3960843afb664e821fed6be52f37da5267 # v1.231.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml index 2d73e1771a..630ba3e4dc 100644 --- a/.github/workflows/check_misc.yml +++ b/.github/workflows/check_misc.yml @@ -20,12 +20,12 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - uses: ./.github/actions/setup/directories with: makeup: true - # Skip overwriting MATZBOT_GITHUB_TOKEN + # Skip overwriting MATZBOT_AUTO_UPDATE_TOKEN checkout: '' # false (ref: https://github.com/actions/runner/issues/2238) # Run this step first to make sure auto-style commits are pushed diff --git a/.github/workflows/default_gems.yml b/.github/workflows/default_gems.yml index 89a4c7dd3a..cd15e34229 100644 --- a/.github/workflows/default_gems.yml +++ b/.github/workflows/default_gems.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} - id: gems run: true @@ -31,7 +31,7 @@ jobs: - uses: ./.github/actions/setup/directories with: makeup: true - # Skip overwriting MATZBOT_GITHUB_TOKEN + # Skip overwriting MATZBOT_AUTO_UPDATE_TOKEN checkout: '' # false (ref: https://github.com/actions/runner/issues/2238) if: ${{ steps.gems.outcome == 'success' }} diff --git a/.github/workflows/dependabot_automerge.yml b/.github/workflows/dependabot_automerge.yml index dd1f1bcdaa..09fdba7b2b 100644 --- a/.github/workflows/dependabot_automerge.yml +++ b/.github/workflows/dependabot_automerge.yml @@ -13,7 +13,7 @@ jobs: if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'ruby/ruby' steps: - name: Dependabot metadata - uses: dependabot/fetch-metadata@d7267f607e9d3fb96fc2fbe83e0af444713e90b7 # v2.3.0 + uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0 id: metadata - name: Wait for status checks @@ -29,4 +29,4 @@ jobs: run: gh pr merge --auto --rebase "$PR_URL" env: PR_URL: ${{ github.event.pull_request.html_url }} - GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.MATZBOT_DEPENDABOT_MERGE_TOKEN }} diff --git a/.github/workflows/modgc.yml b/.github/workflows/modgc.yml index e6ec8f3523..5b29da7516 100644 --- a/.github/workflows/modgc.yml +++ b/.github/workflows/modgc.yml @@ -63,7 +63,7 @@ jobs: uses: ./.github/actions/setup/ubuntu if: ${{ contains(matrix.os, 'ubuntu') }} - - uses: ruby/setup-ruby@d8d83c3960843afb664e821fed6be52f37da5267 # v1.231.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/parse_y.yml b/.github/workflows/parse_y.yml index 824dea5d32..e9c41923a3 100644 --- a/.github/workflows/parse_y.yml +++ b/.github/workflows/parse_y.yml @@ -60,7 +60,7 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@d8d83c3960843afb664e821fed6be52f37da5267 # v1.231.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25916066d6..284e336a29 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,7 +55,7 @@ jobs: echo $PREVIOUS_RELEASE_TAG tool/gen-github-release.rb $PREVIOUS_RELEASE_TAG $RELEASE_TAG --no-dry-run env: - GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }} + GITHUB_TOKEN: ${{ secrets.MATZBOT_AUTO_UPDATE_TOKEN }} - name: Update versions index run: | diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index ef36e55c16..3b43080201 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -2,7 +2,7 @@ # by a third-party and are governed by separate terms of service, privacy # policy, and support documentation. -name: Scorecards supply-chain security +name: Scorecard 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 @@ -10,7 +10,7 @@ on: # To guarantee Maintained check is occasionally updated. See # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained schedule: - - cron: '22 4 * * 2' + - cron: '39 3 * * 5' # push: # branches: [ "master" ] @@ -19,8 +19,10 @@ permissions: read-all jobs: analysis: - name: Scorecards analysis + name: Scorecard analysis runs-on: ubuntu-latest + # `publish_results: true` only works when run from the default branch. conditional can be removed if disabled. + if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request' permissions: # Needed to upload the results to code-scanning dashboard. security-events: write @@ -31,21 +33,21 @@ jobs: # actions: read steps: - - name: 'Checkout code' + - name: "Checkout code" uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - name: 'Run analysis' - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + - name: "Run analysis" + uses: ossf/scorecard-action@f2ea147fec3c2f0d459703eba7405b5e9bcd8c8f # v2.4.2 with: results_file: results.sarif results_format: sarif - # (Optional) Read-only PAT token. Uncomment the `repo_token` line below if: + # (Optional) "write" 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 }} + # - you are installing Scorecard on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} # Public repositories: # - Publish results to OpenSSF REST API for easy access by consumers @@ -56,17 +58,21 @@ jobs: # of the value entered here. publish_results: true + # (Optional) Uncomment file_mode if you have a .gitattributes with files marked export-ignore + # file_mode: git + # 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 + - name: "Upload artifact" + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.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@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 + # Upload the results to GitHub's code scanning dashboard (optional). + # Commenting out will disable upload of results to your repo's Code Scanning dashboard + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml index ef67e1a505..d723abde21 100644 --- a/.github/workflows/spec_guards.yml +++ b/.github/workflows/spec_guards.yml @@ -48,7 +48,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: ruby/setup-ruby@d8d83c3960843afb664e821fed6be52f37da5267 # v1.231.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 041cb412fd..f1c185f4c1 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -68,7 +68,7 @@ jobs: with: arch: ${{ matrix.arch }} - - uses: ruby/setup-ruby@d8d83c3960843afb664e821fed6be52f37da5267 # v1.231.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 047288cb8d..2c49d99071 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -100,7 +100,7 @@ jobs: run: | echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV - - uses: ruby/setup-ruby@d8d83c3960843afb664e821fed6be52f37da5267 # v1.231.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: '3.1' bundler: none @@ -142,7 +142,7 @@ jobs: - run: tar cfz ../install.tar.gz -C ../install . - name: Upload artifacts - uses: actions/upload-artifact@604373da6381bf24206979c74d06a550515601b9 # v4.4.1 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ruby-wasm-install path: ${{ github.workspace }}/install.tar.gz @@ -170,7 +170,7 @@ jobs: - 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@604373da6381bf24206979c74d06a550515601b9 # v4.4.1 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 if: ${{ github.event_name == 'pull_request' }} with: name: github-pr-info diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e0719118b4..39f67abdc4 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -64,7 +64,7 @@ jobs: - run: md build working-directory: - - uses: ruby/setup-ruby@e34163cd15f4bb403dcd72d98e295997e6a55798 # v1.238.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: # windows-11-arm has only 3.4.1, 3.4.2, 3.4.3, head ruby-version: ${{ !endsWith(matrix.os, 'arm') && '3.1' || '3.4' }} diff --git a/.github/workflows/wsl.yml b/.github/workflows/wsl.yml index e6b4133b76..af490dffd7 100644 --- a/.github/workflows/wsl.yml +++ b/.github/workflows/wsl.yml @@ -16,7 +16,7 @@ on: jobs: wsl: - runs-on: windows-latest + runs-on: windows-2025 if: >- ${{!(false @@ -29,9 +29,6 @@ jobs: )}} steps: - - name: Install winget - uses: Cyberboss/install-winget@v1 - - name: Install or update WSL uses: Ubuntu/WSL/.github/actions/wsl-install@main with: diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml index ee6c7cb5ed..252ffb9e54 100644 --- a/.github/workflows/yjit-ubuntu.yml +++ b/.github/workflows/yjit-ubuntu.yml @@ -135,7 +135,7 @@ jobs: - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@d8d83c3960843afb664e821fed6be52f37da5267 # v1.231.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml index fa161b31a2..2bbcf6e831 100644 --- a/.github/workflows/zjit-macos.yml +++ b/.github/workflows/zjit-macos.yml @@ -63,7 +63,7 @@ jobs: )}} steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: sparse-checkout-cone-mode: false sparse-checkout: /.github diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index 7a6c1dfe0b..d120372979 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -69,14 +69,14 @@ jobs: )}} steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: sparse-checkout-cone-mode: false sparse-checkout: /.github - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + - uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0 with: ruby-version: '3.1' bundler: none @@ -154,7 +154,7 @@ The following bundled gems are updated. * rake 13.3.0 * test-unit 3.6.8 * rexml 3.4.1 -* net-imap 0.5.8 +* net-imap 0.5.9 * net-smtp 0.5.1 * matrix 0.4.3 * prime 0.1.4 diff --git a/gems/bundled_gems b/gems/bundled_gems index 15a9df6cce..d00124cf37 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -13,7 +13,7 @@ test-unit 3.6.8 https://github.com/test-unit/test-unit rexml 3.4.1 https://github.com/ruby/rexml rss 0.3.1 https://github.com/ruby/rss net-ftp 0.3.8 https://github.com/ruby/net-ftp -net-imap 0.5.8 https://github.com/ruby/net-imap +net-imap 0.5.9 https://github.com/ruby/net-imap net-pop 0.1.2 https://github.com/ruby/net-pop net-smtp 0.5.1 https://github.com/ruby/net-smtp matrix 0.4.3 https://github.com/ruby/matrix diff --git a/tool/auto-style.rb b/tool/auto-style.rb index 0c6ce6848a..71139c8eb8 100755 --- a/tool/auto-style.rb +++ b/tool/auto-style.rb @@ -15,8 +15,10 @@ class Git @branch = branch # GitHub may not fetch github.event.pull_request.base.sha at checkout - git('fetch', '--depth=1', 'origin', @oldrev) - git('fetch', '--depth=100', 'origin', @newrev) + git('log', '--format=%H', '-1', @oldrev, out: IO::NULL, err: [:child, :out]) or + git('fetch', '--depth=1', 'origin', @oldrev) + git('log', '--format=%H', '-1', "#@newrev~99", out: IO::NULL, err: [:child, :out]) or + git('fetch', '--depth=100', 'origin', @newrev) with_clean_env do @revs = {} @@ -66,12 +68,14 @@ class Git private - def git(*args) + def git(*args, **opts) cmd = ['git', *args].shelljoin puts "+ #{cmd}" - unless with_clean_env { system('git', *args) } + ret = with_clean_env { system('git', *args, **opts) } + unless ret or opts[:err] abort "Failed to run: #{cmd}" end + ret end def with_clean_env @@ -233,8 +237,8 @@ edited_files = files.select do |f| if File.fnmatch?("*.[ch]", f, File::FNM_PATHNAME) && !DIFFERENT_STYLE_FILES.any? {|pat| File.fnmatch?(pat, f, File::FNM_PATHNAME)} - indent0 = true if src.gsub!(/^\w+\([^(\n)]*?\)\K[ \t]*(?=\{$)/, "\n") - indent0 = true if src.gsub!(/^([ \t]*)\}\K[ \t]*(?=else\b)/, "\n" '\1') + indent0 = true if src.gsub!(/^\w+\([^\n]*?\)\K[ \t]*(?=\{( *\\)?$)/, '\1' "\n") + indent0 = true if src.gsub!(/^([ \t]*)\}\K[ \t]*(?=else\b.*?( *\\)?$)/, '\2' "\n" '\1') indent0 = true if src.gsub!(/^[ \t]*\}\n\K\n+(?=[ \t]*else\b)/, '') indent ||= indent0 end diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 2be6031805..7a9bb132aa 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -496,6 +496,9 @@ pub enum Insn { FixnumGt { left: InsnId, right: InsnId }, FixnumGe { left: InsnId, right: InsnId }, + // Distinct from `SendWithoutBlock` with `mid:to_s` because does not have a patch point for String to_s being redefined + ObjToString { val: InsnId, call_info: CallInfo, cd: *const rb_call_data, state: InsnId }, + /// Side-exit if val doesn't have the expected type. GuardType { val: InsnId, guard_type: Type, state: InsnId }, /// Side-exit if val is not the expected VALUE. @@ -695,6 +698,7 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::ToNewArray { val, .. } => write!(f, "ToNewArray {val}"), Insn::ArrayExtend { left, right, .. } => write!(f, "ArrayExtend {left}, {right}"), Insn::ArrayPush { array, val, .. } => write!(f, "ArrayPush {array}, {val}"), + Insn::ObjToString { val, .. } => { write!(f, "ObjToString {val}") }, Insn::SideExit { .. } => write!(f, "SideExit"), Insn::PutSpecialObject { value_type } => { write!(f, "PutSpecialObject {}", value_type) @@ -1013,6 +1017,12 @@ impl Function { FixnumLt { left, right } => FixnumLt { left: find!(*left), right: find!(*right) }, FixnumLe { left, right } => FixnumLe { left: find!(*left), right: find!(*right) }, PutSpecialObject { value_type } => PutSpecialObject { value_type: *value_type }, + ObjToString { val, call_info, cd, state } => ObjToString { + val: find!(*val), + call_info: call_info.clone(), + cd: *cd, + state: *state, + }, SendWithoutBlock { self_val, call_info, cd, args, state } => SendWithoutBlock { self_val: find!(*self_val), call_info: call_info.clone(), @@ -1143,6 +1153,7 @@ impl Function { Insn::GetIvar { .. } => types::BasicObject, Insn::ToNewArray { .. } => types::ArrayExact, Insn::ToArray { .. } => types::ArrayExact, + Insn::ObjToString { .. } => types::BasicObject, } } @@ -1386,6 +1397,15 @@ impl Function { let replacement = self.push_insn(block, Insn::Const { val: Const::Value(unsafe { (*ice).value }) }); self.make_equal_to(insn_id, replacement); } + Insn::ObjToString { val, call_info, cd, state, .. } => { + if self.is_a(val, types::StringExact) { + // behaves differently from `SendWithoutBlock` with `mid:to_s` because ObjToString should not have a patch point for String to_s being redefined + self.make_equal_to(insn_id, val); + } else { + let replacement = self.push_insn(block, Insn::SendWithoutBlock { self_val: val, call_info, cd, args: vec![], state }); + self.make_equal_to(insn_id, replacement) + } + } _ => { self.push_insn_id(block, insn_id); } } } @@ -1758,6 +1778,10 @@ impl Function { worklist.push_back(val); worklist.push_back(state); } + Insn::ObjToString { val, state, .. } => { + worklist.push_back(val); + worklist.push_back(state); + } Insn::GetGlobal { state, .. } | Insn::SideExit { state } => worklist.push_back(state), } @@ -1768,6 +1792,67 @@ impl Function { } } + fn absorb_dst_block(&mut self, num_in_edges: &Vec<u32>, block: BlockId) -> bool { + let Some(terminator_id) = self.blocks[block.0].insns.last() + else { return false }; + let Insn::Jump(BranchEdge { target, args }) = self.find(*terminator_id) + else { return false }; + if target == block { + // Can't absorb self + return false; + } + if num_in_edges[target.0] != 1 { + // Can't absorb block if it's the target of more than one branch + return false; + } + // Link up params with block args + let params = std::mem::take(&mut self.blocks[target.0].params); + assert_eq!(args.len(), params.len()); + for (arg, param) in args.iter().zip(params) { + self.make_equal_to(param, *arg); + } + // Remove branch instruction + self.blocks[block.0].insns.pop(); + // Move target instructions into block + let target_insns = std::mem::take(&mut self.blocks[target.0].insns); + self.blocks[block.0].insns.extend(target_insns); + true + } + + /// Clean up linked lists of blocks A -> B -> C into A (with B's and C's instructions). + fn clean_cfg(&mut self) { + // num_in_edges is invariant throughout cleaning the CFG: + // * we don't allocate new blocks + // * blocks that get absorbed are not in RPO anymore + // * blocks pointed to by blocks that get absorbed retain the same number of in-edges + let mut num_in_edges = vec![0; self.blocks.len()]; + for block in self.rpo() { + for &insn in &self.blocks[block.0].insns { + if let Insn::IfTrue { target, .. } | Insn::IfFalse { target, .. } | Insn::Jump(target) = self.find(insn) { + num_in_edges[target.target.0] += 1; + } + } + } + let mut changed = false; + loop { + let mut iter_changed = false; + for block in self.rpo() { + // Ignore transient empty blocks + if self.blocks[block.0].insns.is_empty() { continue; } + loop { + let absorbed = self.absorb_dst_block(&num_in_edges, block); + if !absorbed { break; } + iter_changed = true; + } + } + if !iter_changed { break; } + changed = true; + } + if changed { + self.infer_types(); + } + } + /// Return a traversal of the `Function`'s `BlockId`s in reverse post-order. pub fn rpo(&self) -> Vec<BlockId> { let mut result = self.po_from(self.entry_block); @@ -1807,6 +1892,7 @@ impl Function { self.optimize_direct_sends(); self.optimize_c_calls(); self.fold_constants(); + self.clean_cfg(); self.eliminate_dead_code(); // Dump HIR after optimization @@ -2677,6 +2763,26 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> { let insn_id = fun.push_insn(block, Insn::InvokeBuiltin { bf, args, state: exit_id }); state.stack_push(insn_id); } + YARVINSN_objtostring => { + let cd: *const rb_call_data = get_arg(pc, 0).as_ptr(); + let call_info = unsafe { rb_get_call_data_ci(cd) }; + + if unknown_call_type(unsafe { rb_vm_ci_flag(call_info) }) { + assert!(false, "objtostring should not have unknown call type"); + } + let argc = unsafe { vm_ci_argc((*cd).ci) }; + assert_eq!(0, argc, "objtostring should not have args"); + + let method_name: String = unsafe { + let mid = rb_vm_ci_mid(call_info); + mid.contents_lossy().into_owned() + }; + + let recv = state.stack_pop()?; + let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state }); + let objtostring = fun.push_insn(block, Insn::ObjToString { val: recv, call_info: CallInfo { method_name }, cd, state: exit_id }); + state.stack_push(objtostring) + } _ => { // Unknown opcode; side-exit into the interpreter let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state }); @@ -4344,6 +4450,21 @@ mod tests { Return v20 "#]]); } + + #[test] + fn test_objtostring() { + eval(" + def test = \"#{1}\" + "); + assert_method_hir_with_opcode("test", YARVINSN_objtostring, expect![[r#" + fn test: + bb0(v0:BasicObject): + v2:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v3:Fixnum[1] = Const Value(1) + v5:BasicObject = ObjToString v3 + SideExit + "#]]); + } } #[cfg(test)] @@ -4396,9 +4517,6 @@ mod opt_tests { assert_optimized_method_hir("test", expect![[r#" fn test: bb0(v0:BasicObject): - v3:FalseClassExact = Const Value(false) - Jump bb1(v0, v3) - bb1(v8:BasicObject, v9:FalseClassExact): v11:Fixnum[4] = Const Value(4) Return v11 "#]]); @@ -4575,8 +4693,6 @@ mod opt_tests { fn test: bb0(v0:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_EQ) - Jump bb1(v0) - bb1(v10:BasicObject): v12:Fixnum[4] = Const Value(4) Return v12 "#]]); @@ -4639,8 +4755,6 @@ mod opt_tests { bb0(v0:BasicObject): PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_EQ) PatchPoint BOPRedefined(INTEGER_REDEFINED_OP_FLAG, BOP_NEQ) - Jump bb1(v0) - bb1(v10:BasicObject): v12:Fixnum[4] = Const Value(4) Return v12 "#]]); @@ -5585,12 +5699,8 @@ mod opt_tests { PatchPoint StableConstantNames(0x1000, C) v20:BasicObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) v4:NilClassExact = Const Value(nil) - Jump bb1(v0, v4, v20) - bb1(v6:BasicObject, v7:NilClassExact, v8:BasicObject[VALUE(0x1008)]): - v11:BasicObject = SendWithoutBlock v8, :new - Jump bb2(v6, v11, v7) - bb2(v13:BasicObject, v14:BasicObject, v15:NilClassExact): - Return v14 + v11:BasicObject = SendWithoutBlock v20, :new + Return v11 "#]]); } @@ -5613,12 +5723,8 @@ mod opt_tests { v22:BasicObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) v4:NilClassExact = Const Value(nil) v5:Fixnum[1] = Const Value(1) - Jump bb1(v0, v4, v22, v5) - bb1(v7:BasicObject, v8:NilClassExact, v9:BasicObject[VALUE(0x1008)], v10:Fixnum[1]): - v13:BasicObject = SendWithoutBlock v9, :new, v10 - Jump bb2(v7, v13, v8) - bb2(v15:BasicObject, v16:BasicObject, v17:NilClassExact): - Return v16 + v13:BasicObject = SendWithoutBlock v22, :new, v5 + Return v13 "#]]); } @@ -5902,4 +6008,34 @@ mod opt_tests { Return v7 "#]]); } + + #[test] + fn test_objtostring_string() { + eval(r##" + def test = "#{('foo')}" + "##); + assert_optimized_method_hir("test", expect![[r#" + fn test: + bb0(v0:BasicObject): + v2:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v3:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v4:StringExact = StringCopy v3 + SideExit + "#]]); + } + + #[test] + fn test_objtostring_with_non_string() { + eval(r##" + def test = "#{1}" + "##); + assert_optimized_method_hir("test", expect![[r#" + fn test: + bb0(v0:BasicObject): + v2:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000)) + v3:Fixnum[1] = Const Value(1) + v8:BasicObject = SendWithoutBlock v3, :to_s + SideExit + "#]]); + } } |