diff options
Diffstat (limited to '.github')
55 files changed, 2635 insertions, 810 deletions
diff --git a/.github/actions/capiext/action.yml b/.github/actions/capiext/action.yml new file mode 100644 index 0000000000..ed69c8ac5e --- /dev/null +++ b/.github/actions/capiext/action.yml @@ -0,0 +1,86 @@ +name: rubyspec C-API extensions + +inputs: + builddir: + required: false + default: '.' + make: + required: false + default: 'make -s' + +outputs: + key: + value: >- + ${{ + !steps.restore.outputs.cache-hit && + github.ref == 'refs/heads/master' && + steps.config.outputs.key + }} + +runs: + using: composite + + steps: + - id: config + shell: bash + run: | + eval $(grep -e '^arch *=' -e '^ruby_version *=' -e '^DLEXT *=' Makefile | + sed 's/ *= */=/') + case "${ruby_version}" in + *+*) key=capiexts-${arch}-${ruby_version}-${{ hashFiles('src/spec/ruby/optional/capi/ext/*.[ch]') }};; + *) key=;; + esac + echo version=$ruby_version >> $GITHUB_OUTPUT + echo key="$key" >> $GITHUB_OUTPUT + echo DLEXT=$DLEXT >> $GITHUB_OUTPUT + working-directory: ${{ inputs.builddir }} + + - name: Restore previous CAPI extensions + uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + id: cache + with: + path: ${{ inputs.builddir }}/spec/ruby/optional/capi/ext/ + key: ${{ steps.config.outputs.key }} + if: ${{ steps.config.outputs.key }} + + - name: Run test-spec with previous CAPI extension binaries + id: check + shell: bash + run: | # zizmor: ignore[template-injection] + touch spec/ruby/optional/capi/ext/*.$DLEXT + [ ! -f spec/ruby/optional/capi/ext/\*.$DLEXT ] + ${{ inputs.make }} SPECOPTS=optional/capi test-spec + env: + DLEXT: ${{ steps.config.outputs.DLEXT }} + working-directory: ${{ inputs.builddir }} + if: ${{ steps.cache.outputs.cache-hit }} + + - name: Strip CAPI extensions + id: strip + shell: bash + run: | + rm -f spec/ruby/optional/capi/ext/*.c + [ "$DLEXT" = bundle ] || # separated to .dSYM directories + strip spec/ruby/optional/capi/ext/*.$DLEXT + env: + DLEXT: ${{ steps.config.outputs.DLEXT }} + working-directory: ${{ inputs.builddir }} + if: >- + ${{true + && ! steps.cache.outputs.cache-hit + && github.ref_name == 'master' + }} + + - name: Save CAPI extensions + uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + with: + path: ${{ inputs.builddir }}/spec/ruby/optional/capi/ext/ + key: ${{ steps.config.outputs.key }} + if: ${{ steps.strip.outcome == 'success' }} + + - shell: bash + run: | + echo "::error::Change from ${prev} detected; bump up ABI version" + env: + prev: ${{ steps.config.outputs.version }} + if: ${{ always() && steps.check.outcome == 'failure' }} diff --git a/.github/actions/compilers/action.yml b/.github/actions/compilers/action.yml index 30ccd25a12..c700bbfe9e 100644 --- a/.github/actions/compilers/action.yml +++ b/.github/actions/compilers/action.yml @@ -5,7 +5,7 @@ description: >- inputs: tag: required: false - default: clang-18 + default: clang-20 description: >- container image tag to use in this run. @@ -60,11 +60,17 @@ inputs: description: >- Whether to run `make check` - mspecopt: + test_all: required: false default: '' description: >- - Additional options for mspec. + Whether to run `make test-all` with options for test-all. + + test_spec: + required: false + default: '' + description: >- + Whether to run `make test-spec` with options for mspec. static_exts: required: false @@ -75,7 +81,9 @@ runs: using: composite steps: - shell: bash - run: docker pull --quiet 'ghcr.io/ruby/ruby-ci-image:${{ inputs.tag }}' + run: docker pull --quiet "ghcr.io/ruby/ruby-ci-image:${INPUT_TAG}" + env: + INPUT_TAG: ${{ inputs.tag }} - name: Enable Launchable conditionally id: enable-launchable @@ -93,27 +101,28 @@ runs: docker run --rm --user=root - --volume '${{ github.workspace }}:/github/workspace:ro' + --volume "${GITHUB_WORKSPACE}:/github/workspace:ro" --workdir=/github/workspace --entrypoint=/github/workspace/.github/actions/compilers/entrypoint.sh --env CI --env GITHUB_ACTION - --env INPUT_WITH_GCC='${{ inputs.with_gcc || inputs.tag }}' - --env INPUT_CFLAGS='${{ inputs.CFLAGS }}' - --env INPUT_CXXFLAGS='${{ inputs.CXXFLAGS }}' - --env INPUT_OPTFLAGS='${{ inputs.OPTFLAGS }}' - --env INPUT_CPPFLAGS='${{ inputs.cppflags }}' - --env INPUT_APPEND_CONFIGURE='${{ inputs.append_configure }}' - --env INPUT_CHECK='${{ inputs.check }}' - --env INPUT_MSPECOPT='${{ inputs.mspecopt }}' - --env INPUT_ENABLE_SHARED='${{ inputs.enable_shared }}' - --env INPUT_STATIC_EXTS='${{ inputs.static_exts }}' - --env LAUNCHABLE_ORGANIZATION='${{ github.repository_owner }}' - --env LAUNCHABLE_WORKSPACE='${{ github.event.repository.name }}' - --env LAUNCHABLE_ENABLED='${{ steps.enable-launchable.outputs.enable-launchable || false }}' - --env GITHUB_PR_HEAD_SHA='${{ github.event.pull_request.head.sha || github.sha }}' - --env GITHUB_PULL_REQUEST_URL='${{ github.event.pull_request.html_url }}' - --env GITHUB_REF='${{ github.ref }}' + --env INPUT_WITH_GCC + --env INPUT_CFLAGS + --env INPUT_CXXFLAGS + --env INPUT_OPTFLAGS + --env INPUT_CPPFLAGS + --env INPUT_APPEND_CONFIGURE + --env INPUT_CHECK + --env INPUT_TEST_ALL + --env INPUT_TEST_SPEC + --env INPUT_ENABLE_SHARED + --env INPUT_STATIC_EXTS + --env LAUNCHABLE_ORGANIZATION + --env LAUNCHABLE_WORKSPACE + --env LAUNCHABLE_ENABLED + --env GITHUB_PR_HEAD_SHA + --env GITHUB_PULL_REQUEST_URL + --env GITHUB_REF --env GITHUB_ACTIONS --env GITHUB_RUN_ID --env GITHUB_REPOSITORY @@ -123,4 +132,33 @@ runs: --env GITHUB_SHA --env GITHUB_HEAD_REF --env GITHUB_SERVER_URL - 'ghcr.io/ruby/ruby-ci-image:${{ inputs.tag }}' + "ghcr.io/ruby/ruby-ci-image:${INPUT_TAG}" + env: + INPUT_TAG: ${{ inputs.tag }} + INPUT_WITH_GCC: ${{ inputs.with_gcc || inputs.tag }} + INPUT_CFLAGS: ${{ inputs.CFLAGS }} + INPUT_CXXFLAGS: ${{ inputs.CXXFLAGS }} + INPUT_OPTFLAGS: ${{ inputs.OPTFLAGS }} + INPUT_CPPFLAGS: ${{ inputs.cppflags }} + INPUT_APPEND_CONFIGURE: ${{ inputs.append_configure }} + INPUT_CHECK: ${{ inputs.check }} + INPUT_TEST_ALL: ${{ inputs.test_all }} + INPUT_TEST_SPEC: ${{ inputs.test_spec }} + INPUT_ENABLE_SHARED: ${{ inputs.enable_shared }} + INPUT_STATIC_EXTS: ${{ inputs.static_exts }} + LAUNCHABLE_ORGANIZATION: ${{ github.repository_owner }} + LAUNCHABLE_WORKSPACE: ${{ github.event.repository.name }} + LAUNCHABLE_ENABLED: ${{ steps.enable-launchable.outputs.enable-launchable || false }} + GITHUB_PR_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + GITHUB_PULL_REQUEST_URL: ${{ github.event.pull_request.html_url }} + GITHUB_REF: ${{ github.ref }} + + # Clean up non-default docker images to save disk space. + # The default image (clang-20) is reused across multiple steps + # within the same job, so we keep it to avoid redundant pulls. + - name: clean up docker image + shell: bash + run: docker rmi "ghcr.io/ruby/ruby-ci-image:${INPUT_TAG}" || true + if: ${{ always() && inputs.tag != 'clang-20' }} + env: + INPUT_TAG: ${{ inputs.tag }} diff --git a/.github/actions/compilers/entrypoint.sh b/.github/actions/compilers/entrypoint.sh index 17f749d69e..b554151091 100755 --- a/.github/actions/compilers/entrypoint.sh +++ b/.github/actions/compilers/entrypoint.sh @@ -26,7 +26,7 @@ export CONFIGURE_TTY='never' export RUBY_DEBUG='ci rgengc' export RUBY_TESTOPTS='-q --color=always --tty=no' export RUBY_DEBUG_COUNTER_DISABLE='1' -export GNUMAKEFLAGS="-j$((1 + $(nproc --all)))" +export GNUMAKEFLAGS="-j$((1 + $(nproc)))" case "x${INPUT_ENABLE_SHARED}" in x | xno | xfalse ) @@ -47,6 +47,7 @@ grouped ${srcdir}/configure \ --enable-debug-env \ --disable-install-doc \ --with-ext=-test-/cxxanyargs,+ \ + --without-git \ ${enable_shared} \ ${INPUT_APPEND_CONFIGURE} \ CFLAGS="${INPUT_CFLAGS}" \ @@ -70,25 +71,20 @@ if [[ -n "${INPUT_STATIC_EXTS}" ]]; then echo "::endgroup::" fi -btests='' -tests='' -spec_opts='' +if [ -n "$INPUT_TEST_ALL" ]; then + tests=" -- $INPUT_TEST_ALL" +else + tests=" -- ruby -ext-" +fi pushd ${builddir} grouped make showflags grouped make all -grouped make test BTESTS="${btests}" - -[[ -z "${INPUT_CHECK}" ]] && exit 0 - -if [ "$INPUT_CHECK" = "true" ]; then - tests+=" -- ruby -ext-" -else - tests+=" -- $INPUT_CHECK" -fi - # grouped make install -grouped make test-tool -grouped make test-all TESTS="$tests" -grouped env CHECK_LEAKS=true make test-spec MSPECOPT="$INPUT_MSPECOPT" SPECOPTS="${spec_opts}" + +# Run only `make test` by default. Run other tests if specified. +grouped make test +if [[ -n "$INPUT_CHECK" ]]; then grouped make test-tool; fi +if [[ -n "$INPUT_CHECK" || -n "$INPUT_TEST_ALL" ]]; then grouped make test-all TESTS="$tests"; fi +if [[ -n "$INPUT_CHECK" || -n "$INPUT_TEST_SPEC" ]]; then grouped env CHECK_LEAKS=true make test-spec MSPECOPT="$INPUT_TEST_SPEC"; fi diff --git a/.github/actions/launchable/setup/action.yml b/.github/actions/launchable/setup/action.yml index 54f1abd97a..305878492c 100644 --- a/.github/actions/launchable/setup/action.yml +++ b/.github/actions/launchable/setup/action.yml @@ -55,6 +55,12 @@ inputs: description: >- Whether this workflow is executed on YJIT. + is-zjit: + required: false + default: 'false' + description: >- + Whether this workflow is executed on ZJIT. + outputs: stdout_report_path: value: ${{ steps.global.outputs.stdout_report_path }} @@ -89,17 +95,41 @@ runs: # Launchable CLI requires Python and Java. # https://www.launchableinc.com/docs/resources/cli-reference/ - name: Set up Python - uses: actions/setup-python@871daa956ca9ea99f3c3e30acb424b7960676734 # v5.0.0 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: "3.x" - if: steps.enable-launchable.outputs.enable-launchable + if: >- + ${{ steps.enable-launchable.outputs.enable-launchable + && !endsWith(inputs.os, 'ppc64le') && !endsWith(inputs.os, 's390x') }} - name: Set up Java - uses: actions/setup-java@7a445ee88d4e23b52c33fdc7601e40278616c7f8 # v4.0.0 + uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0 with: distribution: 'temurin' java-version: '17' - if: steps.enable-launchable.outputs.enable-launchable + if: >- + ${{ steps.enable-launchable.outputs.enable-launchable + && !endsWith(inputs.os, 'ppc64le') && !endsWith(inputs.os, 's390x') }} + + - name: Set up Java ppc64le + uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0 + with: + distribution: 'semeru' + architecture: 'ppc64le' + java-version: '17' + if: >- + ${{ steps.enable-launchable.outputs.enable-launchable + && endsWith(inputs.os, 'ppc64le') }} + + - name: Set up Java s390x + uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0 + with: + distribution: 'semeru' + architecture: 's390x' + java-version: '17' + if: >- + ${{ steps.enable-launchable.outputs.enable-launchable + && endsWith(inputs.os, 's390x') }} - name: Set global vars id: global @@ -120,20 +150,26 @@ runs: - name: Set environment variables for Launchable shell: bash - run: | + run: | # zizmor: ignore[github-env] : # GITHUB_PULL_REQUEST_URL are used for commenting test reports in Launchable Github App. : # https://github.com/launchableinc/cli/blob/v1.80.1/launchable/utils/link.py#L42 - echo "GITHUB_PULL_REQUEST_URL=${{ github.event.pull_request.html_url }}" >> $GITHUB_ENV + echo "GITHUB_PULL_REQUEST_URL=${INPUT_PR_HTML_URL}" >> $GITHUB_ENV : # The following envs are necessary in Launchable tokenless authentication. : # https://github.com/launchableinc/cli/blob/v1.80.1/launchable/utils/authentication.py#L20 - echo "LAUNCHABLE_ORGANIZATION=${{ github.repository_owner }}" >> $GITHUB_ENV - echo "LAUNCHABLE_WORKSPACE=${{ github.event.repository.name }}" >> $GITHUB_ENV + echo "LAUNCHABLE_ORGANIZATION=${INPUT_REPOSITORY_OWNER}" >> $GITHUB_ENV + echo "LAUNCHABLE_WORKSPACE=${INPUT_REPOSITORY_NAME}" >> $GITHUB_ENV : # https://github.com/launchableinc/cli/blob/v1.80.1/launchable/utils/authentication.py#L71 - echo "GITHUB_PR_HEAD_SHA=${{ github.event.pull_request.head.sha || github.sha }}" >> $GITHUB_ENV - echo "LAUNCHABLE_TOKEN=${{ inputs.launchable-token }}" >> $GITHUB_ENV + echo "GITHUB_PR_HEAD_SHA=${INPUT_PR_HEAD_SHA}" >> $GITHUB_ENV + echo "LAUNCHABLE_TOKEN=${INPUT_LAUNCHABLE_TOKEN}" >> $GITHUB_ENV : # To prevent a slowdown in CI, disable request retries when the Launchable server is unstable. echo "LAUNCHABLE_SKIP_TIMEOUT_RETRY=1" >> $GITHUB_ENV echo "LAUNCHABLE_COMMIT_TIMEOUT=1" >> $GITHUB_ENV + env: + INPUT_PR_HTML_URL: ${{ github.event.pull_request.html_url }} + INPUT_REPOSITORY_OWNER: ${{ github.repository_owner }} + INPUT_REPOSITORY_NAME: ${{ github.event.repository.name }} + INPUT_PR_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + INPUT_LAUNCHABLE_TOKEN: ${{ inputs.launchable-token }} if: steps.enable-launchable.outputs.enable-launchable - name: Set up path @@ -141,33 +177,44 @@ runs: working-directory: ${{ inputs.srcdir }} # Since updated PATH variable will be available in only subsequent actions, we need to add the path beforehand. # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path - run: echo "$(python -msite --user-base)/bin" >> $GITHUB_PATH - if: steps.enable-launchable.outputs.enable-launchable && startsWith(inputs.os, 'macos') + run: echo "$(python -msite --user-base)/bin" >> $GITHUB_PATH # zizmor: ignore[github-env] + if: >- + ${{ + steps.enable-launchable.outputs.enable-launchable + && (startsWith(inputs.os, 'macos') + || endsWith(inputs.os, 'ppc64le') + || endsWith(inputs.os, 's390x')) + }} - name: Set up Launchable id: setup-launchable shell: bash working-directory: ${{ inputs.srcdir }} - run: | + run: | # zizmor: ignore[github-env] set -x pip install --user launchable : # The build name cannot include a slash, so we replace the string here. - github_ref="${{ github.ref }}" + github_ref="${INPUT_GITHUB_REF}" github_ref="${github_ref//\//_}" : # With the --name option, we need to configure a unique identifier for this build. : # To avoid setting the same build name as the CI which runs on other branches, we use the branch name here. build_name="${github_ref}_${GITHUB_PR_HEAD_SHA}" - test_opts="${{ inputs.test-opts }}" + test_opts="${INPUT_TEST_OPTS}" test_opts="${test_opts// /}" test_opts="${test_opts//=/:}" test_all_test_suite='test-all' btest_test_suite='btest' test_spec_test_suite='test-spec' - if [ "${{ inputs.is-yjit }}" = "true" ]; then + if [ "${INPUT_IS_YJIT}" = "true" ]; then test_all_test_suite="yjit-${test_all_test_suite}" btest_test_suite="yjit-${btest_test_suite}" test_spec_test_suite="yjit-${test_spec_test_suite}" fi + if [ "${INPUT_IS_ZJIT}" = "true" ]; then + test_all_test_suite="zjit-${test_all_test_suite}" + btest_test_suite="zjit-${btest_test_suite}" + test_spec_test_suite="zjit-${test_spec_test_suite}" + fi # launchable_setup target var -- refers ${target} prefixed variables launchable_setup() { local target=$1 session @@ -176,10 +223,10 @@ runs: session=$(launchable record session \ --build "${build_name}" \ --observation \ - --flavor os="${{ inputs.os }}" \ - --flavor test_task="${{ inputs.test-task }}" \ + --flavor os="${INPUT_OS}" \ + --flavor test_task="${INPUT_TEST_TASK}" \ --flavor test_opts="${test_opts}" \ - --flavor workflow="${{ github.workflow }}" \ + --flavor workflow="${INPUT_WORKFLOW}" \ --test-suite ${suite} \ ) echo "${target}_session=${session}" >> $GITHUB_OUTPUT @@ -200,6 +247,13 @@ runs: echo launchable_setup_dir=$(pwd) >> $GITHUB_OUTPUT if: steps.enable-launchable.outputs.enable-launchable env: + INPUT_GITHUB_REF: ${{ github.ref }} + INPUT_TEST_OPTS: ${{ inputs.test-opts }} + INPUT_IS_YJIT: ${{ inputs.is-yjit }} + INPUT_IS_ZJIT: ${{ inputs.is-zjit }} + INPUT_OS: ${{ inputs.os }} + INPUT_TEST_TASK: ${{ inputs.test-task }} + INPUT_WORKFLOW: ${{ github.workflow }} 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 }} @@ -216,7 +270,7 @@ runs: 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 + uses: gacts/run-and-post-run@81b6ce503cde93862cec047c54652e45c5dca991 # v1.4.3 with: shell: bash working-directory: ${{ inputs.builddir }} @@ -233,7 +287,7 @@ runs: 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 + uses: gacts/run-and-post-run@81b6ce503cde93862cec047c54652e45c5dca991 # v1.4.3 with: shell: bash working-directory: ${{ inputs.builddir }} diff --git a/.github/actions/make-snapshot/action.yml b/.github/actions/make-snapshot/action.yml new file mode 100644 index 0000000000..4552f0e067 --- /dev/null +++ b/.github/actions/make-snapshot/action.yml @@ -0,0 +1,77 @@ +name: 'make-snapshot' +description: 'Make snapshot tarballs' +inputs: + archname: + description: 'archname passed to tool/make-snapshot (e.g. snapshot-master)' + required: true + version: + description: 'Target Version' + required: false + shallow-since: + description: 'git fetch --shallow-since' + required: true + default: '2018-12-25 00:00:00' + fetch-branch: + description: 'fetch branch' + required: false + srcdir: + description: 'srcdir for tool/make-snapshot. Empty = clone ruby/ruby into ./ruby.' + required: false + default: '' + upload-artifact: + description: 'Upload Packages and Info as workflow artifacts. Pass "false" when callers run in a matrix that would collide on artifact names.' + required: false + default: 'true' + +runs: + using: "composite" + steps: + - name: Install libraries + run: | + set -x + sudo apt-get update -q || : + sudo apt-get install --no-install-recommends -q -y build-essential git bison autoconf ruby p7zip-full curl + shell: bash + - name: Checkout ruby/ruby for tool/make-snapshot + if: inputs.srcdir == '' + run: git clone --single-branch --depth=1 https://github.com/ruby/ruby ruby + shell: bash + - name: Fetch branches and notes (clone mode) + if: inputs.srcdir == '' + env: + SHALLOW_SINCE: ${{ inputs.shallow-since }} + FETCH_BRANCH: ${{ inputs.fetch-branch }} + run: | + set -x + cd ruby + git fetch --shallow-since="$SHALLOW_SINCE" + [ -n "$FETCH_BRANCH" ] && git fetch origin "+$FETCH_BRANCH:$FETCH_BRANCH" + git fetch origin '+refs/notes/commits:refs/notes/commits' + git fetch origin '+refs/notes/log-fix:refs/notes/log-fix' + shell: bash + - name: Fetch notes (local srcdir mode) + if: inputs.srcdir != '' + working-directory: ${{ inputs.srcdir }} + run: | + git fetch origin '+refs/notes/commits:refs/notes/commits' || : + git fetch origin '+refs/notes/log-fix:refs/notes/log-fix' || : + shell: bash + - name: Make snapshot + env: + ARCHNAME: ${{ inputs.archname }} + SRCDIR: ${{ inputs.srcdir }} + VERSION: ${{ inputs.version }} + run: | + [ -z "$SRCDIR" ] && SRCDIR=ruby + ruby "$SRCDIR/tool/make-snapshot" "-archname=$ARCHNAME" -srcdir="$SRCDIR" -packages=gzip,xz,zip pkg $VERSION + shell: bash + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: Packages + path: pkg + if: ${{ inputs.upload-artifact == 'true' }} + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: Info + path: pkg/info + if: ${{ inputs.upload-artifact == 'true' }} diff --git a/.github/actions/setup/baseruby/action.yml b/.github/actions/setup/baseruby/action.yml new file mode 100644 index 0000000000..76fe068897 --- /dev/null +++ b/.github/actions/setup/baseruby/action.yml @@ -0,0 +1,73 @@ +name: Setup directories etc. +description: >- + Build baseruby for cross-compiling + +inputs: + srcdir: + required: true + default: ${{ github.workspace }} + description: >- + Directory of source codes. + + builddir: + required: false + default: ${{ github.workspace }}/baseruby + description: >- + Where baseruby will be built. + + installdir: + required: false + default: install + description: >- + The path where the baseruby will be installed to. + This is relative from the workspace. + +outputs: + ruby: + value: ${{ steps.build.outputs.installdir }}/bin/ruby + description: >- + The path of the executable baseruby. + dump_ast: + value: ${{ steps.build.outputs.installdir }}/bin/dump_ast + description: >- + The path of the executable dump_ast. + +runs: + using: composite + + steps: + - name: Build baseruby + shell: bash + id: build + run: | + case "$installdir" in /*) ;; *) installdir="$PWD/$installdir";; esac + mkdir "$builddir" + ln -sr "$srcdir" "$builddir/.src" + pushd "$builddir" + .src/configure "--prefix=${installdir}" --disable-install-doc + CONFIGURE_ARGS=--with-out-ext=-test- make install + install dump_ast "${installdir}/bin" + { + echo "${installdir}/bin/dump_ast" + echo "${installdir}/.installed.list" + echo "${installdir}/" + } >> .installed.list + cp .installed.list "${installdir}/" + make distclean + rm .src + popd + rmdir "$builddir" + { + echo "installdir=${installdir}" + } | tee -a "$GITHUB_OUTPUT" + env: + srcdir: ${{ inputs.srcdir }} + builddir: ${{ inputs.builddir }} + installdir: ${{ inputs.installdir }} + + - name: clean + uses: gacts/run-and-post-run@598d7a875d5620e0457490555b5e18e46082aa47 # v1.4.4 + with: + working-directory: ${{ inputs.srcdir }} + post: | + ruby tool/rbuninstall.rb "${{ steps.build.outputs.installdir }}/.installed.list" > /dev/null diff --git a/.github/actions/setup/directories/action.yml b/.github/actions/setup/directories/action.yml index 728e082189..15dc097b6e 100644 --- a/.github/actions/setup/directories/action.yml +++ b/.github/actions/setup/directories/action.yml @@ -19,6 +19,13 @@ inputs: Where binaries and other generated contents go. This will be created if absent. + make-command: + required: false + type: string + default: 'make' + description: >- + The command of `make`. + makeup: required: false type: boolean @@ -67,8 +74,11 @@ runs: # their bash manually installed. - shell: bash run: | - mkdir -p ${{ inputs.srcdir }} - mkdir -p ${{ inputs.builddir }} + mkdir -p "${INPUT_SRCDIR}" + mkdir -p "${INPUT_BUILDDIR}" + env: + INPUT_SRCDIR: ${{ inputs.srcdir }} + INPUT_BUILDDIR: ${{ inputs.builddir }} # Did you know that actions/checkout works without git(1)? We are # checking that here. @@ -88,12 +98,13 @@ runs: git config --global init.defaultBranch garbage - if: inputs.checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: path: ${{ inputs.srcdir }} fetch-depth: ${{ inputs.fetch-depth }} + persist-credentials: false - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: ${{ inputs.srcdir }}/.downloaded-cache key: ${{ runner.os }}-${{ runner.arch }}-downloaded-cache @@ -106,16 +117,16 @@ runs: # This is for MinGW. - if: runner.os == 'Windows' shell: bash - run: echo "GNUMAKEFLAGS=-j$((2 * NUMBER_OF_PROCESSORS))" >> $GITHUB_ENV + run: echo "GNUMAKEFLAGS=-j$((2 * NUMBER_OF_PROCESSORS))" >> $GITHUB_ENV # zizmor: ignore[github-env] - if: runner.os == 'Linux' shell: bash - run: echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> "$GITHUB_ENV" + run: echo "GNUMAKEFLAGS=-sj$((1 + $(nproc)))" >> "$GITHUB_ENV" # zizmor: ignore[github-env] # macOS' GNU make is so old that they doesn't understand `GNUMAKEFLAGS`. - if: runner.os == 'macOS' shell: bash - run: echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> "$GITHUB_ENV" + run: echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> "$GITHUB_ENV" # zizmor: ignore[github-env] - if: inputs.makeup shell: bash @@ -134,6 +145,7 @@ runs: run: | rm -f config.status .rbconfig.time \ Makefile GNUmakefile uncommon.mk enc.mk noarch-fake.rb + rm -f prism/.time prism/util/.time - if: steps.which.outputs.sudo shell: bash @@ -163,19 +175,25 @@ runs: done # drop {a..z}.rb if case-insensitive filesystem grep -F A.rb a.rb > /dev/null && set "${@:27}" - echo clean="cd ${{ inputs.builddir }} && rm $*" >> $GITHUB_OUTPUT + echo clean="cd ${INPUT_BUILDDIR} && rm $*" >> $GITHUB_OUTPUT + env: + INPUT_BUILDDIR: ${{ inputs.builddir }} - if: inputs.clean == 'true' shell: bash id: clean run: | - echo distclean='make -C ${{ inputs.builddir }} distclean' >> $GITHUB_OUTPUT - echo remained-files='find ${{ inputs.builddir }} -ls' >> $GITHUB_OUTPUT - [ "${{ inputs.builddir }}" = "${{ inputs.srcdir }}" ] || - echo final='rmdir ${{ inputs.builddir }}' >> $GITHUB_OUTPUT + echo distclean="cd ${INPUT_BUILDDIR} && ${INPUT_MAKE_COMMAND} distclean" >> $GITHUB_OUTPUT + echo remained-files="find ${INPUT_BUILDDIR} -ls" >> $GITHUB_OUTPUT + [ "${INPUT_BUILDDIR}" = "${INPUT_SRCDIR}" ] || + echo final="rmdir ${INPUT_BUILDDIR}" >> $GITHUB_OUTPUT + env: + INPUT_BUILDDIR: ${{ inputs.builddir }} + INPUT_SRCDIR: ${{ inputs.srcdir }} + INPUT_MAKE_COMMAND: ${{ inputs.make-command }} - name: clean - uses: gacts/run-and-post-run@d803f6920adc9a47eeac4cb6c93dbc2e2890c684 # v1.4.2 + uses: gacts/run-and-post-run@598d7a875d5620e0457490555b5e18e46082aa47 # v1.4.4 with: working-directory: post: | diff --git a/.github/actions/setup/macos/action.yml b/.github/actions/setup/macos/action.yml index d0072ff828..9cd37a9b12 100644 --- a/.github/actions/setup/macos/action.yml +++ b/.github/actions/setup/macos/action.yml @@ -17,7 +17,7 @@ runs: - name: Set ENV shell: bash - run: | + run: | # zizmor: ignore[github-env] dir_config() { local args=() lib var="$1"; shift for lib in "$@"; do diff --git a/.github/actions/setup/ubuntu/action.yml b/.github/actions/setup/ubuntu/action.yml index a9e5b41951..5209ccc03f 100644 --- a/.github/actions/setup/ubuntu/action.yml +++ b/.github/actions/setup/ubuntu/action.yml @@ -24,18 +24,38 @@ runs: using: composite steps: + - id: uname + name: uname + shell: bash + env: + arch: ${{ inputs.arch }} + run: | + setarch="${arch:+setarch $arch --}" + # normalize `uname` + if uname=$(${setarch} uname -m 2> /dev/null); then + # `setarch` works, `$arch` is a valid architecture name. + echo "setarch=${setarch}" >> "$GITHUB_OUTPUT" + else + # if `setarch` failed, take the given `arch` as-is. + uname="${arch}" + setarch="" + fi + echo "uname=$uname" >> "$GITHUB_OUTPUT" + echo "dpkg=${uname/686/386}" >> "$GITHUB_OUTPUT" + - name: set SETARCH shell: bash - run: echo "SETARCH=${setarch}" >> "$GITHUB_ENV" + run: echo "SETARCH=${setarch}" >> "$GITHUB_ENV" # zizmor: ignore[github-env] env: - setarch: ${{ inputs.arch && format('setarch {0} --', inputs.arch) }} + setarch: ${{ steps.uname.outputs.setarch }} # validated - - id: uname - name: uname + - name: dpkg setup shell: bash - run: | - echo uname=`${SETARCH} uname -m` >> "$GITHUB_OUTPUT" - echo dpkg=`${SETARCH} uname -m | sed s/686/386/` >> "$GITHUB_OUTPUT" + run: sudo dpkg --add-architecture "${dpkg}" + # `dpkg` is valid, also `uname`. + if: ${{ inputs.arch }} + env: + dpkg: ${{ steps.uname.outputs.dpkg }} - name: apt-get shell: bash @@ -43,7 +63,6 @@ runs: arch: ${{ inputs.arch && format(':{0}', steps.uname.outputs.dpkg) || '' }} run: | set -x - ${arch:+sudo dpkg --add-architecture ${arch#:}} sudo apt-get update -qq || : sudo apt-get install --no-install-recommends -qq -y -o=Dpkg::Use-Pty=0 \ ${arch:+cross}build-essential${arch/:/-} \ diff --git a/.github/actions/slack/action.yml b/.github/actions/slack/action.yml index 98171efc5e..6f89bef11a 100644 --- a/.github/actions/slack/action.yml +++ b/.github/actions/slack/action.yml @@ -18,13 +18,24 @@ inputs: Human-readable description of the run, something like "DEBUG=1". This need not be unique among runs. + event_name: + required: false + default: 'push' + description: >- + Target event to trigger notification. Notify only push by default. + + extra_channel_id: + required: false + description: >- + Slack channel ID to notify besides #alerts and #alerts-emoji. + outputs: {} # Nothing? runs: using: composite steps: - - uses: ruby/action-slack@54175162371f1f7c8eb94d7c8644ee2479fcd375 # v3.2.2 + - uses: ruby/action-slack@d260b61aa817726d5bedd22dd6cc305787fa4cdd # v4.0.0 with: payload: | { @@ -33,7 +44,8 @@ runs: "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", "commit": "${{ github.sha }}", "branch": "${{ github.ref_name }}" + ${{ inputs.extra_channel_id && format(', "extra_channel_id": "{0}"', inputs.extra_channel_id) }} } env: SLACK_WEBHOOK_URL: ${{ inputs.SLACK_WEBHOOK_URL }} - if: ${{github.event_name == 'push' && startsWith(github.repository, 'ruby/')}} + if: ${{ github.event_name == inputs.event_name && startsWith(github.repository, 'ruby/') }} diff --git a/.github/auto_request_review.yml b/.github/auto_request_review.yml index 264e6ef177..9e20cb7459 100644 --- a/.github/auto_request_review.yml +++ b/.github/auto_request_review.yml @@ -2,19 +2,20 @@ files: 'yjit*': [team:jit] 'yjit/**/*': [team:jit] 'yjit/src/cruby_bindings.inc.rs': [] - 'doc/yjit/*': [team:jit] 'bootstraptest/test_yjit*': [team:jit] 'test/ruby/test_yjit*': [team:jit] 'zjit*': [team:jit] 'zjit/**/*': [team:jit] 'zjit/src/cruby_bindings.inc.rs': [] - 'doc/zjit*': [team:jit] 'test/ruby/test_zjit*': [team:jit] - 'test/.excludes-zjit/*': [team:jit] 'defs/jit.mk': [team:jit] + 'tool/zjit_bisect.rb': [team:jit] + 'doc/jit/*': [team:jit] + # Skip files updated by dependabot. It's noisy in notifications, and they're auto-merged anyway. + 'yjit/Cargo.lock': [] + 'zjit/Cargo.lock': [] + '.github/workflows/yjit-*.yml': [] + '.github/workflows/zjit-*.yml': [] options: ignore_draft: true - # This currently doesn't work as intended. We want to skip reviews when only - # cruby_bingings.inc.rs is modified, but this skips reviews even when other - # files are modified as well. To be enabled after fixing the behavior. - #last_files_match_only: true + last_files_match_only: true diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 0000000000..f5d33545c1 --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,22 @@ +paths-ignore: + - benchmark + - sample + - spec/ruby/command_line/fixtures + - spec/ruby/core/enumerable/shared/inject.rb + - spec/ruby/core/exception/fixtures + - spec/ruby/core/proc/parameters_spec.rb + - spec/ruby/core/proc/ruby2_keywords_spec.rb + - spec/ruby/core/range/reverse_each_spec.rb + - spec/ruby/language/fixtures + - spec/ruby/language/lambda_spec.rb + - spec/ruby/language/method_spec.rb + - spec/ruby/language/string_spec.rb + - test/error_highlight/test_error_highlight.rb + - test/prism/result/named_capture_test.rb + - test/ruby/test_call.rb + - test/ruby/test_signal.rb + - test/ruby/test_super.rb + - test/ruby/test_syntax.rb + - test/ruby/test_unicode_escape.rb + - test/rubygems/specifications/foo-0.0.1-x86-mswin32.gemspec + - trace_point.rb diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2c2982d1d4..57da742e5c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,21 +1,28 @@ version: 2 updates: - package-ecosystem: 'github-actions' - directory: '/' - schedule: - interval: 'daily' - - package-ecosystem: 'github-actions' - directory: '/.github/actions/slack' - schedule: - interval: 'daily' - - package-ecosystem: 'github-actions' - directory: '/.github/actions/setup/directories' + directories: + - '/' + - '/.github/actions/slack' + - '/.github/actions/setup/directories' schedule: interval: 'daily' + groups: + github-actions: + patterns: + - "*" - package-ecosystem: 'cargo' - directory: '/yjit' + directories: + - '/yjit' + - '/zjit' + exclude-paths: + - 'gc/mmtk/**' schedule: - interval: 'daily' + interval: 'monthly' + groups: + jit: + patterns: + - "*" - package-ecosystem: 'vcpkg' directory: '/' schedule: diff --git a/.github/labeler.yml b/.github/labeler.yml index e81aed8e98..f39fcec386 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -4,3 +4,4 @@ Documentation: Backport: - base-branch: 'ruby_3_\d' +- base-branch: 'ruby_4_\d' diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml index 304d216d68..5991165d43 100644 --- a/.github/workflows/annocheck.yml +++ b/.github/workflows/annocheck.yml @@ -41,7 +41,7 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} env: @@ -61,10 +61,11 @@ jobs: - run: id working-directory: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - uses: ./.github/actions/setup/directories with: @@ -72,7 +73,7 @@ jobs: builddir: build makeup: true - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.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 207315a084..80f2517eb5 100644 --- a/.github/workflows/auto_request_review.yml +++ b/.github/workflows/auto_request_review.yml @@ -14,7 +14,7 @@ jobs: 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 + uses: necojackarc/auto-request-review@035f049cb68460341ab744f19aa9f31aae685e36 # master with: # scope: public_repo token: ${{ secrets.MATZBOT_AUTO_REQUEST_REVIEW_TOKEN }} diff --git a/.github/workflows/auto_review_pr.yml b/.github/workflows/auto_review_pr.yml new file mode 100644 index 0000000000..bb84a51573 --- /dev/null +++ b/.github/workflows/auto_review_pr.yml @@ -0,0 +1,41 @@ +name: Auto Review PR +on: + pull_request_target: + types: [opened, ready_for_review, reopened] + branches: [master] + workflow_dispatch: + inputs: + pr_number: + description: 'PR number to review' + required: true + type: number + +permissions: + contents: read + +jobs: + auto-review-pr: + name: Auto Review PR + runs-on: ubuntu-latest + if: ${{ github.repository == 'ruby/ruby' && (github.base_ref == 'master' || github.event_name == 'workflow_dispatch') }} + + permissions: + pull-requests: write + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 + with: + ruby-version: '3.4' + bundler: none + + - name: Auto Review PR + run: ruby tool/auto_review_pr.rb "$GITHUB_PR_NUMBER" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_PR_NUMBER: ${{ github.event.pull_request.number || github.event.inputs.pr_number }} diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml index ffaec18b83..9e7720f659 100644 --- a/.github/workflows/baseruby.yml +++ b/.github/workflows/baseruby.yml @@ -37,7 +37,7 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} strategy: @@ -48,12 +48,14 @@ jobs: - ruby-3.3 steps: - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: ${{ matrix.ruby }} bundler: none - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - uses: ./.github/actions/setup/ubuntu diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml index 27ad55307b..d329ee9b4b 100644 --- a/.github/workflows/bundled_gems.yml +++ b/.github/workflows/bundled_gems.yml @@ -1,5 +1,8 @@ name: bundled_gems +env: + UPDATE_ENABLED: true + on: push: branches: ['master'] @@ -31,10 +34,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 + with: + ruby-version: 4.0 + - uses: ./.github/actions/setup/directories with: # Skip overwriting MATZBOT_AUTO_UPDATE_TOKEN @@ -49,24 +56,20 @@ jobs: mkdir -p .downloaded-cache for data in bundled_gems.json default_gems.json; do ln -s .downloaded-cache/$data . - curl -O -R -z ./$data https://stdgems.org/$data + curl --retry 5 --retry-connrefused --retry-delay 2 --retry-max-time 60 -O -R -z ./$data https://stdgems.org/$data done - name: Update bundled gems list id: bundled_gems run: | ruby -i~ tool/update-bundled_gems.rb gems/bundled_gems >> $GITHUB_OUTPUT - - - 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 + if: ${{ env.UPDATE_ENABLED == 'true' }} - name: Maintain updated gems list in NEWS run: | ruby tool/update-NEWS-gemlist.rb bundled + ruby tool/update-NEWS-github-release.rb --update + if: ${{ env.UPDATE_ENABLED == 'true' }} - name: Check diffs id: diff @@ -77,11 +80,71 @@ jobs: 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: Commit + id: commit + run: | + git pull --ff-only origin ${GITHUB_REF#refs/heads/} + message="Update bundled gems list" + if [ -z "${gems}" ]; then + git commit --message="[DOC] ${message} at ${GITHUB_SHA:0:30}" + else + git commit --message="${message} as of ${TODAY}" + fi + env: + TODAY: ${{ steps.bundled_gems.outputs.latest_date || env.TODAY }} + EMAIL: svn-admin@ruby-lang.org + GIT_AUTHOR_NAME: git + GIT_COMMITTER_NAME: git + gems: ${{ steps.diff.outputs.gems }} + if: ${{ steps.diff.outputs.update }} + + - name: Development revision of bundled gems + run: | + #!ruby + file = "gems/bundled_gems" + + SECONDS_IN_DAY = 86400 + today = Time.new("#{ENV['TODAY']}Z") + if !(december = today.month == 12) + days = 30 + elsif (days = 26 - today.day).positive? + days += 4 + else + puts "::info:: just after released" + exit + end + + since = "#{today.year-1}-12-26" + ref = ENV['GITHUB_REF'] + puts "::group::\e[94mfetching \e[1m#{file}\e[22m since \e[1m#{since}\e[22m from \e[1m#{ref}\e[m" + system(*%W[git fetch --shallow-since=#{since} --no-tags origin #{ref}], exception: true) + puts "::endgroup::" + + puts "\e[94mchecking development version bundled gems older than \e[1m#{days}\e[22m days\e[m" + limit = today.to_i - days * SECONDS_IN_DAY + old = 0 + IO.popen(%W"git blame --line-porcelain -- #{file}") do |blame| + while head = blame.gets("\n\t") and s = blame.gets + next unless (gem = s.split(/\s+|#.*/)).size > 3 + time = head[/^committer-time \K\d+/].to_i + next if (d = limit - time) <= 0 + d /= SECONDS_IN_DAY + line = head[/\A\h+ \d+ \K\d+/].to_i + level = if d < days; 'warning'; else old += 1; 'error'; end + d += days + puts "::#{level} file=#{file},line=#{line},title=Older than #{d} days::#{gem[0]} #{gem[3]}" + end + end + abort "::error title=Too long-standing gems::The release comes soon." if december and old.nonzero? + shell: ruby {0} + env: + file: ${{ steps.logs.outputs.file }} + days: ${{ steps.logs.outputs.days }} + - name: Install libraries uses: ./.github/actions/setup/ubuntu if: ${{ steps.diff.outputs.gems }} @@ -107,27 +170,14 @@ jobs: TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' if: ${{ steps.diff.outputs.gems }} - - name: Commit + - name: Push run: | - git pull --ff-only origin ${GITHUB_REF#refs/heads/} - message="Update bundled gems list" - if [ -z "${gems}" ]; then - git commit --message="[DOC] ${message} at ${GITHUB_SHA:0:30}" - 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 - gems: ${{ steps.diff.outputs.gems }} if: >- ${{ github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull') && - steps.diff.outputs.update + steps.commit.outcome == 'success' }} - uses: ./.github/actions/slack diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index db93e90efb..a120dde7e5 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -30,7 +30,9 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - uses: ./.github/actions/setup/ubuntu if: ${{ contains(matrix.os, 'ubuntu') }} @@ -40,7 +42,7 @@ jobs: - uses: ./.github/actions/setup/directories - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: '3.1' bundler: none @@ -50,7 +52,7 @@ jobs: - run: make fix-depends - - run: git diff --no-ext-diff --ignore-submodules --exit-code + - run: git diff --color --no-ext-diff --ignore-submodules --exit-code - uses: ./.github/actions/slack with: diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml index 54f8df66a2..cb1642b9e2 100644 --- a/.github/workflows/check_misc.yml +++ b/.github/workflows/check_misc.yml @@ -18,9 +18,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} + persist-credentials: false + + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 + with: + ruby-version: head - uses: ./.github/actions/setup/directories with: @@ -28,23 +33,34 @@ jobs: # 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 - - name: ${{ github.ref == 'refs/heads/master' && 'Auto-correct' || 'Check for' }} code styles + - name: Re-generate Makefiles + run: | + # config.status needs to run as a shell script + { echo ':&&exit'; cat tool/prereq.status; } > config.status + : # same as actions/setup/directories/action.yml + for mk in Makefile GNUmakefile; do + sed -f tool/prereq.status template/$mk.in > $mk + done + + - name: Check for code styles run: | set -x - ruby tool/auto-style.rb "$GITHUB_OLD_SHA" "$GITHUB_NEW_SHA" "$PUSH_REF" + ruby tool/auto-style.rb "$GITHUB_OLD_SHA" "$GITHUB_NEW_SHA" env: - EMAIL: svn-admin@ruby-lang.org - GIT_AUTHOR_NAME: git - GIT_COMMITTER_NAME: git GITHUB_OLD_SHA: ${{ github.event.pull_request.base.sha }} GITHUB_NEW_SHA: ${{ github.event.pull_request.merge_commit_sha }} - PUSH_REF: ${{ github.ref == 'refs/heads/master' && github.ref || '' }} + # Skip 'push' events because post_push.yml fixes them on push if: ${{ github.repository == 'ruby/ruby' && startsWith(github.event_name, 'pull') }} - - name: Check if C-sources are US-ASCII + - name: Check if date in man pages is up-to-date run: | - grep -r -n --include='*.[chyS]' --include='*.asm' $'[^\t-~]' -- . && exit 1 || : + git fetch origin --depth=1 "${GITHUB_OLD_SHA}" + git diff --exit-code --name-only "${GITHUB_OLD_SHA}" HEAD -- man || + make V=1 GIT=git BASERUBY=ruby update-man-date + git diff --color --no-ext-diff --ignore-submodules --exit-code -- man + env: + GITHUB_OLD_SHA: ${{ github.event.pull_request.base.sha }} + if: ${{ startsWith(github.event_name, 'pull') }} - name: Check for bash specific substitution in configure.ac run: | @@ -61,29 +77,38 @@ jobs: exit $fail working-directory: include + - id: now + run: | + date +"mon=%-m"%n"day=%-d" >> $GITHUB_OUTPUT + env: + TZ: Asia/Tokyo + + - id: deprecation + run: | + eval $(sed -n 's/^#define RUBY_API_VERSION_\(MAJOR\|MINOR\) /\1=/p' include/ruby/version.h) + if git --no-pager grep --color -o 'rb_warn_deprecated_to_remove_at('$MAJOR'\.'$MINOR',.*' -- '*.c' >&2; then + false + else + true + fi + continue-on-error: ${{ steps.now.outputs.mon < 12 }} + - name: Check if to generate documents id: rdoc run: | - ref=$(sed 's/#.*//;/^rdoc /!d' gems/bundled_gems | awk '{print $4}') - echo ref=$ref >> $GITHUB_OUTPUT - # Generate only when document commit/PR - if: >- - ${{false - || contains(github.event.head_commit.message, '[ruby/rdoc]') - || contains(github.event.head_commit.message, '[DOC]') - || contains(github.event.pull_request.title, '[DOC]') - || contains(github.event.pull_request.labels.*.name, 'Documentation') - }} + set -- $(sed 's/#.*//;/^rdoc /!d' gems/bundled_gems) + { echo version=$2; echo ref=$4; } >> $GITHUB_OUTPUT - name: Checkout rdoc - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: ruby/rdoc ref: ${{ steps.rdoc.outputs.ref }} - path: .bundle/gems/rdoc-0 + path: .bundle/gems/rdoc-${{ steps.rdoc.outputs.version }} + persist-credentials: false if: ${{ steps.rdoc.outputs.ref != '' }} - - name: Generate rdoc + - name: Generate rdoc scripts run: | set -x gempath=$(ruby -e 'print Gem.user_dir, "/bin"') @@ -92,21 +117,29 @@ jobs: bundle config --local path vendor/bundle bundle install --jobs 4 bundle exec rake generate - working-directory: .bundle/gems/rdoc-0 + working-directory: .bundle/gems/rdoc-${{ steps.rdoc.outputs.version }} if: ${{ steps.rdoc.outputs.ref != '' }} + - name: Core docs coverage + run: | + make XRUBY=ruby RDOC_DEPENDS= RBCONFIG=update-rbconfig rdoc-coverage + - name: Generate docs id: docs run: | - $RDOC -C -x ^ext -x ^lib . - $RDOC --op html . + make XRUBY=ruby RDOC_DEPENDS= RBCONFIG=update-rbconfig HTMLOUT=html html echo htmlout=ruby-html-${GITHUB_SHA:0:10} >> $GITHUB_OUTPUT - env: - RDOC: ruby -W0 --disable-gems tool/rdoc-srcdir -q - if: ${{ steps.rdoc.outcome == 'success' }} + # Generate only when document commit/PR + if: >- + ${{false + || contains(github.event.head_commit.message, '[ruby/rdoc]') + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Documentation') + }} - name: Upload docs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: html name: ${{ steps.docs.outputs.htmlout }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/check_sast.yml index 6968be5e02..c8db1103ed 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/check_sast.yml @@ -1,4 +1,4 @@ -name: 'CodeQL' +name: 'Check SAST tool' on: push: @@ -30,25 +30,40 @@ permissions: # added using https://github.com/step-security/secure-workflows contents: read jobs: + zizmor: + name: zizmor + + runs-on: ubuntu-latest + + permissions: + contents: read + security-events: write + + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - name: Run zizmor + uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 + continue-on-error: true + analyze: name: Analyze runs-on: ubuntu-latest 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 + security-events: write # for github/codeql-action/upload-sarif 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.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} - env: - enable_install_doc: no - strategy: fail-fast: false matrix: @@ -58,41 +73,26 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - 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: Remove an obsolete rubygems vendored file - if: ${{ matrix.os == 'ubuntu-latest' }} - run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 + uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 with: languages: ${{ matrix.language }} - trap-caching: false - debug: true - - - name: Autobuild - uses: github/codeql-action/autobuild@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 + build-mode: none + config-file: .github/codeql/codeql-config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 + uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 with: category: '/language:${{ matrix.language }}' upload: False output: sarif-results - name: filter-sarif - uses: advanced-security/filter-sarif@f3b8118a9349d88f7b1c0c488476411145b6270d # v1.0.1 + uses: advanced-security/filter-sarif@2da736ff05ef065cb2894ac6892e47b5eac2c3c0 # v1.1 with: patterns: | +**/*.rb @@ -100,6 +100,7 @@ jobs: -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 + -spec/ruby/core/regexp/timeout_spec.rb:rb/redos -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 @@ -114,8 +115,19 @@ jobs: if: ${{ matrix.language == 'ruby' }} continue-on-error: true + - name: filter-sarif + uses: advanced-security/filter-sarif@2da736ff05ef065cb2894ac6892e47b5eac2c3c0 # v1.1 + with: + patterns: | + +**/*.c + +**/*.h + input: sarif-results/${{ matrix.language }}.sarif + output: sarif-results/${{ matrix.language }}.sarif + if: ${{ matrix.language == 'cpp' }} + continue-on-error: true + - name: Upload SARIF - uses: github/codeql-action/upload-sarif@df409f7d9260372bd5f19e5b04e83cb3c43714ae # v3.27.9 + uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 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 3bad088613..f747b7fd03 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -37,7 +37,7 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: - run: true @@ -49,20 +49,21 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } # Set fetch-depth: 10 so that Launchable can receive commits information. - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - name: 'clang 18 LTO' + - name: 'clang 22 LTO' uses: './.github/actions/compilers' with: - tag: clang-18 - with_gcc: 'clang-18 -flto=auto' + tag: clang-22 + with_gcc: 'clang-22 -flto=auto' optflags: '-O2' enable_shared: false - - { uses: './.github/actions/compilers', name: '-O0', with: { optflags: '-O0 -march=x86-64 -mtune=generic' } } + timeout-minutes: 30 + - { uses: './.github/actions/compilers', name: '-O0', with: { optflags: '-O0 -march=x86-64 -mtune=generic' }, timeout-minutes: 5 } # - { uses: './.github/actions/compilers', name: '-O3', with: { optflags: '-O3 -march=x86-64 -mtune=generic', check: true } } compile2: @@ -71,10 +72,10 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - name: 'GCC 15 LTO' uses: './.github/actions/compilers' @@ -83,16 +84,15 @@ jobs: with_gcc: 'gcc-15 -flto=auto -ffat-lto-objects -Werror=lto-type-mismatch' optflags: '-O2' enable_shared: false - - { uses: './.github/actions/compilers', name: 'ext/Setup', with: { static_exts: 'etc json/* */escape' } } - - { uses: './.github/actions/compilers', name: 'GCC 15', with: { tag: 'gcc-15' } } - - { uses: './.github/actions/compilers', name: 'GCC 14', with: { tag: 'gcc-14' } } - - { uses: './.github/actions/compilers', name: 'GCC 13', with: { tag: 'gcc-13' } } - - { uses: './.github/actions/compilers', name: 'GCC 12', with: { tag: 'gcc-12' } } - - { uses: './.github/actions/compilers', name: 'GCC 11', with: { tag: 'gcc-11' } } - - { uses: './.github/actions/compilers', name: 'GCC 10', with: { tag: 'gcc-10' } } - - { uses: './.github/actions/compilers', name: 'GCC 9', with: { tag: 'gcc-9' } } - - { uses: './.github/actions/compilers', name: 'GCC 8', with: { tag: 'gcc-8' } } - - { uses: './.github/actions/compilers', name: 'GCC 7', with: { tag: 'gcc-7' } } + timeout-minutes: 10 + - { uses: './.github/actions/compilers', name: 'ext/Setup', with: { static_exts: 'etc json/* */escape' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GCC 15', with: { tag: 'gcc-15' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GCC 14', with: { tag: 'gcc-14' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GCC 13', with: { tag: 'gcc-13' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GCC 12', with: { tag: 'gcc-12' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GCC 11', with: { tag: 'gcc-11' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GCC 10', with: { tag: 'gcc-10' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GCC 9', with: { tag: 'gcc-9' }, timeout-minutes: 5 } compile3: name: 'omnibus compilations, #3' @@ -100,20 +100,18 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - { uses: './.github/actions/compilers', name: 'clang 22', with: { tag: 'clang-22' } } - - { uses: './.github/actions/compilers', name: 'clang 21', with: { tag: 'clang-21' } } - - { uses: './.github/actions/compilers', name: 'clang 20', with: { tag: 'clang-20' } } - - { uses: './.github/actions/compilers', name: 'clang 19', with: { tag: 'clang-19' } } - - { uses: './.github/actions/compilers', name: 'clang 18', with: { tag: 'clang-18' } } - - { uses: './.github/actions/compilers', name: 'clang 17', with: { tag: 'clang-17' } } - - { uses: './.github/actions/compilers', name: 'clang 16', with: { tag: 'clang-16' } } - - { uses: './.github/actions/compilers', name: 'clang 15', with: { tag: 'clang-15' } } - - { uses: './.github/actions/compilers', name: 'clang 14', with: { tag: 'clang-14' } } + - { uses: './.github/actions/compilers', name: 'clang 20', with: { tag: 'clang-20' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 19', with: { tag: 'clang-19' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 18', with: { tag: 'clang-18' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 17', with: { tag: 'clang-17' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 16', with: { tag: 'clang-16' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 15', with: { tag: 'clang-15' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 14', with: { tag: 'clang-14' }, timeout-minutes: 5 } compile4: name: 'omnibus compilations, #4' @@ -121,20 +119,20 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - { uses: './.github/actions/compilers', name: 'clang 13', with: { tag: 'clang-13' } } - - { uses: './.github/actions/compilers', name: 'clang 12', with: { tag: 'clang-12' } } - - { uses: './.github/actions/compilers', name: 'clang 11', with: { tag: 'clang-11' } } - - { uses: './.github/actions/compilers', name: 'clang 10', with: { tag: 'clang-10' } } - # llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o. - - { uses: './.github/actions/compilers', name: 'clang 9', with: { tag: 'clang-9', append_configure: '--disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'clang 8', with: { tag: 'clang-8', append_configure: '--disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'clang 7', with: { tag: 'clang-7', append_configure: '--disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'clang 6', with: { tag: 'clang-6.0', append_configure: '--disable-yjit' } } + - { uses: './.github/actions/compilers', name: 'clang 13', with: { tag: 'clang-13' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 12', with: { tag: 'clang-12' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 11', with: { tag: 'clang-11' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 10', with: { tag: 'clang-10' }, timeout-minutes: 5 } + # llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o and fail `make test-leaked-globals`. + - { uses: './.github/actions/compilers', name: 'clang 9', with: { tag: 'clang-9', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 8', with: { tag: 'clang-8', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 7', with: { tag: 'clang-7', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 6', with: { tag: 'clang-6.0', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } compile5: name: 'omnibus compilations, #5' @@ -142,10 +140,10 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } # -Wno-strict-prototypes is necessary with current clang-15 since # older autoconf generate functions without prototype and -pedantic @@ -153,14 +151,14 @@ jobs: # 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 - - { uses: './.github/actions/compilers', name: 'C99', with: { CFLAGS: '-std=c99 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } - - { uses: './.github/actions/compilers', name: 'C11', with: { CFLAGS: '-std=c11 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } - - { uses: './.github/actions/compilers', name: 'C17', with: { CFLAGS: '-std=c17 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } - - { uses: './.github/actions/compilers', name: 'C23', with: { CFLAGS: '-std=c2x -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } - - { uses: './.github/actions/compilers', name: 'C++98', with: { CXXFLAGS: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++11', with: { CXXFLAGS: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++14', with: { CXXFLAGS: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++17', with: { CXXFLAGS: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } + - { uses: './.github/actions/compilers', name: 'C99', with: { CFLAGS: '-std=c99 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'C11', with: { CFLAGS: '-std=c11 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'C17', with: { CFLAGS: '-std=c17 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'C23', with: { CFLAGS: '-std=c2x -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'C++98', with: { CXXFLAGS: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'C++11', with: { CXXFLAGS: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'C++14', with: { CXXFLAGS: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'C++17', with: { CXXFLAGS: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }, timeout-minutes: 5 } compile6: name: 'omnibus compilations, #6' @@ -168,19 +166,19 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - { uses: './.github/actions/compilers', name: 'C++20', with: { CXXFLAGS: '-std=c++20 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++23', with: { CXXFLAGS: '-std=c++23 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++26', with: { CXXFLAGS: '-std=c++26 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'gmp', with: { append_configure: '--with-gmp', check: 'ruby/test_bignum.rb', mspecopt: "/github/workspace/src/spec/ruby/core/integer" } } - - { uses: './.github/actions/compilers', name: 'jemalloc', with: { append_configure: '--with-jemalloc' } } - - { uses: './.github/actions/compilers', name: 'valgrind', with: { append_configure: '--with-valgrind' } } - - { uses: './.github/actions/compilers', name: 'coroutine=ucontext', with: { append_configure: '--with-coroutine=ucontext' } } - - { uses: './.github/actions/compilers', name: 'coroutine=pthread', with: { append_configure: '--with-coroutine=pthread' } } + - { uses: './.github/actions/compilers', name: 'C++20', with: { CXXFLAGS: '-std=c++20 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'C++23', with: { CXXFLAGS: '-std=c++23 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'C++26', with: { CXXFLAGS: '-std=c++26 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'gmp', with: { append_configure: '--with-gmp', test_all: 'ruby/test_bignum.rb', test_spec: "/github/workspace/src/spec/ruby/core/integer" }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'jemalloc', with: { append_configure: '--with-jemalloc' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'valgrind', with: { append_configure: '--with-valgrind' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'coroutine=ucontext', with: { append_configure: '--with-coroutine=ucontext' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'coroutine=pthread', with: { append_configure: '--with-coroutine=pthread' }, timeout-minutes: 5 } compile7: name: 'omnibus compilations, #7' @@ -188,21 +186,19 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - { uses: './.github/actions/compilers', name: 'disable-jit', with: { append_configure: '--disable-yjit --disable-zjit' } } - - { uses: './.github/actions/compilers', name: 'disable-yjit', with: { append_configure: '--disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'disable-zjit', with: { append_configure: '--disable-zjit' } } - - { uses: './.github/actions/compilers', name: 'disable-dln', with: { append_configure: '--disable-dln' } } - - { uses: './.github/actions/compilers', name: 'enable-mkmf-verbose', with: { append_configure: '--enable-mkmf-verbose' } } - - { uses: './.github/actions/compilers', name: 'disable-rubygems', with: { append_configure: '--disable-rubygems' } } - - { uses: './.github/actions/compilers', name: 'RUBY_DEVEL', with: { append_configure: '--enable-devel' } } - - { uses: './.github/actions/compilers', name: 'OPT_THREADED_CODE=0', with: { cppflags: '-DOPT_THREADED_CODE=0' } } - - { uses: './.github/actions/compilers', name: 'OPT_THREADED_CODE=1', with: { cppflags: '-DOPT_THREADED_CODE=1' } } - - { uses: './.github/actions/compilers', name: 'OPT_THREADED_CODE=2', with: { cppflags: '-DOPT_THREADED_CODE=2' } } + - { uses: './.github/actions/compilers', name: 'disable-jit', with: { append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'disable-yjit', with: { append_configure: '--disable-yjit' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'disable-zjit', with: { append_configure: '--disable-zjit' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'disable-dln', with: { append_configure: '--disable-dln' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'enable-mkmf-verbose', with: { append_configure: '--enable-mkmf-verbose' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'disable-rubygems', with: { append_configure: '--disable-rubygems' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'RUBY_DEVEL', with: { append_configure: '--enable-devel' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'OPT_THREADED_CODE=0', with: { cppflags: '-DOPT_THREADED_CODE=0' }, timeout-minutes: 5 } compile8: name: 'omnibus compilations, #8' @@ -210,19 +206,18 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - { uses: './.github/actions/compilers', name: 'NDEBUG', with: { cppflags: '-DNDEBUG' } } - - { uses: './.github/actions/compilers', name: 'RUBY_DEBUG', with: { cppflags: '-DRUBY_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'ARRAY_DEBUG', with: { cppflags: '-DARRAY_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'BIGNUM_DEBUG', with: { cppflags: '-DBIGNUM_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'CCAN_LIST_DEBUG', with: { cppflags: '-DCCAN_LIST_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'CPDEBUG=-1', with: { cppflags: '-DCPDEBUG=-1' } } - - { uses: './.github/actions/compilers', name: 'ENC_DEBUG', with: { cppflags: '-DENC_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'GC_DEBUG', with: { cppflags: '-DGC_DEBUG' } } + - { uses: './.github/actions/compilers', name: 'NDEBUG', with: { cppflags: '-DNDEBUG' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'RUBY_DEBUG', with: { cppflags: '-DRUBY_DEBUG' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'ARRAY_DEBUG', with: { cppflags: '-DARRAY_DEBUG' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'CCAN_LIST_DEBUG', with: { cppflags: '-DCCAN_LIST_DEBUG' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'CPDEBUG=-1', with: { cppflags: '-DCPDEBUG=-1' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'ENC_DEBUG', with: { cppflags: '-DENC_DEBUG' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GC_DEBUG', with: { cppflags: '-DGC_DEBUG' }, timeout-minutes: 5 } compile9: name: 'omnibus compilations, #9' @@ -230,19 +225,19 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - { uses: './.github/actions/compilers', name: 'HASH_DEBUG', with: { cppflags: '-DHASH_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'ID_TABLE_DEBUG', with: { cppflags: '-DID_TABLE_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'RGENGC_DEBUG=-1', with: { cppflags: '-DRGENGC_DEBUG=-1' } } - - { uses: './.github/actions/compilers', name: 'SYMBOL_DEBUG', with: { cppflags: '-DSYMBOL_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'RGENGC_CHECK_MODE', with: { cppflags: '-DRGENGC_CHECK_MODE' } } - - { uses: './.github/actions/compilers', name: 'VM_CHECK_MODE', with: { cppflags: '-DVM_CHECK_MODE' } } - - { uses: './.github/actions/compilers', name: 'USE_EMBED_CI=0', with: { cppflags: '-DUSE_EMBED_CI=0' } } - - { uses: './.github/actions/compilers', name: 'USE_FLONUM=0', with: { cppflags: '-DUSE_FLONUM=0', append_configure: '--disable-yjit' } } + - { uses: './.github/actions/compilers', name: 'HASH_DEBUG', with: { cppflags: '-DHASH_DEBUG' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'ID_TABLE_DEBUG', with: { cppflags: '-DID_TABLE_DEBUG' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'RGENGC_DEBUG=-1', with: { cppflags: '-DRGENGC_DEBUG=-1' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'SYMBOL_DEBUG', with: { cppflags: '-DSYMBOL_DEBUG' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'RGENGC_CHECK_MODE', with: { cppflags: '-DRGENGC_CHECK_MODE' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'VM_CHECK_MODE', with: { cppflags: '-DVM_CHECK_MODE' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'USE_EMBED_CI=0', with: { cppflags: '-DUSE_EMBED_CI=0' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'USE_FLONUM=0', with: { cppflags: '-DUSE_FLONUM=0', append_configure: '--disable-yjit --disable-zjit' }, timeout-minutes: 5 } compileX: name: 'omnibus compilations, #10' @@ -250,19 +245,20 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - { uses: './.github/actions/compilers', name: 'USE_LAZY_LOAD', with: { cppflags: '-DUSE_LAZY_LOAD' } } - - { uses: './.github/actions/compilers', name: 'USE_SYMBOL_GC=0', with: { cppflags: '-DUSE_SYMBOL_GC=0' } } - - { uses: './.github/actions/compilers', name: 'USE_THREAD_CACHE=0', with: { cppflags: '-DUSE_THREAD_CACHE=0' } } - - { uses: './.github/actions/compilers', name: 'USE_RUBY_DEBUG_LOG=1', with: { cppflags: '-DUSE_RUBY_DEBUG_LOG=1' } } - - { uses: './.github/actions/compilers', name: 'USE_DEBUG_COUNTER', with: { cppflags: '-DUSE_DEBUG_COUNTER=1' } } - - { uses: './.github/actions/compilers', name: 'SHARABLE_MIDDLE_SUBSTRING', with: { cppflags: '-DSHARABLE_MIDDLE_SUBSTRING=1' } } - - { uses: './.github/actions/compilers', name: 'DEBUG_FIND_TIME_NUMGUESS', with: { cppflags: '-DDEBUG_FIND_TIME_NUMGUESS' } } - - { uses: './.github/actions/compilers', name: 'DEBUG_INTEGER_PACK', with: { cppflags: '-DDEBUG_INTEGER_PACK' } } + - { uses: './.github/actions/compilers', name: 'USE_LAZY_LOAD', with: { cppflags: '-DUSE_LAZY_LOAD' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'USE_RUBY_DEBUG_LOG=1', with: { cppflags: '-DUSE_RUBY_DEBUG_LOG=1' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'USE_DEBUG_COUNTER', with: { cppflags: '-DUSE_DEBUG_COUNTER=1' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'SHARABLE_MIDDLE_SUBSTRING', with: { cppflags: '-DSHARABLE_MIDDLE_SUBSTRING=1' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'DEBUG_FIND_TIME_NUMGUESS', with: { cppflags: '-DDEBUG_FIND_TIME_NUMGUESS' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'DEBUG_INTEGER_PACK', with: { cppflags: '-DDEBUG_INTEGER_PACK' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'OPT_THREADED_CODE=1', with: { cppflags: '-DOPT_THREADED_CODE=1' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'OPT_THREADED_CODE=2', with: { cppflags: '-DOPT_THREADED_CODE=2' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 21', with: { tag: 'clang-21' }, timeout-minutes: 5 } compileB: name: 'omnibus compilations, #11' @@ -270,19 +266,18 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - { uses: './.github/actions/compilers', name: 'GC_DEBUG_STRESS_TO_CLASS', with: { cppflags: '-DGC_DEBUG_STRESS_TO_CLASS' } } - - { uses: './.github/actions/compilers', name: 'GC_ENABLE_LAZY_SWEEP=0', with: { cppflags: '-DGC_ENABLE_LAZY_SWEEP=0' } } - - { uses: './.github/actions/compilers', name: 'GC_PROFILE_DETAIL_MEMORY', with: { cppflags: '-DGC_PROFILE_DETAIL_MEMORY' } } - - { uses: './.github/actions/compilers', name: 'GC_PROFILE_MORE_DETAIL', with: { cppflags: '-DGC_PROFILE_MORE_DETAIL' } } - - { uses: './.github/actions/compilers', name: 'MALLOC_ALLOCATED_SIZE_CHECK', with: { cppflags: '-DMALLOC_ALLOCATED_SIZE_CHECK' } } - - { uses: './.github/actions/compilers', name: 'RGENGC_ESTIMATE_OLDMALLOC', with: { cppflags: '-DRGENGC_ESTIMATE_OLDMALLOC' } } - - { uses: './.github/actions/compilers', name: 'RGENGC_OBJ_INFO', with: { cppflags: '-DRGENGC_OBJ_INFO' } } - - { uses: './.github/actions/compilers', name: 'RGENGC_PROFILE', with: { cppflags: '-DRGENGC_PROFILE' } } + - { uses: './.github/actions/compilers', name: 'GC_DEBUG_STRESS_TO_CLASS', with: { cppflags: '-DGC_DEBUG_STRESS_TO_CLASS' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GC_ENABLE_LAZY_SWEEP=0', with: { cppflags: '-DGC_ENABLE_LAZY_SWEEP=0' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GC_PROFILE_DETAIL_MEMORY', with: { cppflags: '-DGC_PROFILE_DETAIL_MEMORY' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GC_PROFILE_MORE_DETAIL', with: { cppflags: '-DGC_PROFILE_MORE_DETAIL' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'MALLOC_ALLOCATED_SIZE_CHECK', with: { cppflags: '-DMALLOC_ALLOCATED_SIZE_CHECK' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'RGENGC_ESTIMATE_OLDMALLOC', with: { cppflags: '-DRGENGC_ESTIMATE_OLDMALLOC' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'RGENGC_PROFILE', with: { cppflags: '-DRGENGC_PROFILE' }, timeout-minutes: 5 } compileC: name: 'omnibus compilations, #12' @@ -290,18 +285,19 @@ jobs: needs: compile-if if: ${{ needs.compile-if.result == 'success' }} timeout-minutes: 60 - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } + steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } } - - { uses: './.github/actions/compilers', name: 'VM_DEBUG_BP_CHECK', with: { cppflags: '-DVM_DEBUG_BP_CHECK' } } - - { uses: './.github/actions/compilers', name: 'VM_DEBUG_VERIFY_METHOD_CACHE', with: { cppflags: '-DVM_DEBUG_VERIFY_METHOD_CACHE' } } - - { uses: './.github/actions/compilers', name: 'enable-yjit', with: { append_configure: '--enable-yjit' } } - - { uses: './.github/actions/compilers', name: 'enable-{y,z}jit', with: { append_configure: '--enable-yjit --enable-zjit' } } - - { uses: './.github/actions/compilers', name: 'enable-{y,z}jit=dev', with: { append_configure: '--enable-yjit=dev --enable-zjit' } } - - { uses: './.github/actions/compilers', name: 'YJIT_FORCE_ENABLE', with: { cppflags: '-DYJIT_FORCE_ENABLE' } } - - { uses: './.github/actions/compilers', name: 'UNIVERSAL_PARSER', with: { cppflags: '-DUNIVERSAL_PARSER' } } + - { uses: './.github/actions/compilers', name: 'VM_DEBUG_BP_CHECK', with: { cppflags: '-DVM_DEBUG_BP_CHECK' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'VM_DEBUG_VERIFY_METHOD_CACHE', with: { cppflags: '-DVM_DEBUG_VERIFY_METHOD_CACHE' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'YJIT_FORCE_ENABLE', with: { cppflags: '-DYJIT_FORCE_ENABLE' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'UNIVERSAL_PARSER', with: { cppflags: '-DUNIVERSAL_PARSER' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 23', with: { tag: 'clang-23' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'clang 22', with: { tag: 'clang-22' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GCC 8', with: { tag: 'gcc-8' }, timeout-minutes: 5 } + - { uses: './.github/actions/compilers', name: 'GCC 7', with: { tag: 'gcc-7' }, timeout-minutes: 5 } compilemax: name: 'omnibus compilations, result' @@ -321,8 +317,8 @@ jobs: - 'compileB' - 'compileC' steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github, persist-credentials: false } - uses: ./.github/actions/slack with: label: 'omnibus' diff --git a/.github/workflows/crosscompile.yml b/.github/workflows/crosscompile.yml new file mode 100644 index 0000000000..3ed6429a1e --- /dev/null +++ b/.github/workflows/crosscompile.yml @@ -0,0 +1,123 @@ +name: Cross compile +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 + 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: + name: make (${{ matrix.host }} host on ${{ matrix.build }}) + strategy: + matrix: + include: + - host: aarch64-linux-gnu + arch: arm64 + build: x86_64-linux-gnu + runs-on: ubuntu-24.04 + file_arch: ARM aarch64 + - host: x86_64-linux-gnu + arch: amd64 + build: aarch64-linux-gnu + runs-on: ubuntu-24.04-arm + file_arch: x86-64 + fail-fast: false + + env: + GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + + runs-on: ${{ matrix.runs-on }} + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Documentation') + || (github.event.pull_request.user.login == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + sparse-checkout-cone-mode: false + sparse-checkout: /.github + persist-credentials: false + + - uses: ./.github/actions/setup/directories + with: + srcdir: src + builddir: build + makeup: true + + - name: Setup cross-compilation toolchain sources + run: | + native_arch=$(dpkg --print-architecture) + # Restrict existing sources to native arch + sudo sed -i '/^Architectures:/d' /etc/apt/sources.list.d/ubuntu.sources + sudo sed -i "/^Types:/a Architectures: ${native_arch}" /etc/apt/sources.list.d/ubuntu.sources + # Add cross-arch sources + if [ "${{ matrix.arch }}" = "arm64" ]; then + cross_uri="http://ports.ubuntu.com/" + else + cross_uri="http://archive.ubuntu.com/ubuntu/" + fi + printf '%s\n' \ + "Types: deb" \ + "URIs: ${cross_uri}" \ + "Suites: noble noble-updates noble-security" \ + "Components: main universe" \ + "Architectures: ${{ matrix.arch }}" \ + | sudo tee /etc/apt/sources.list.d/cross-${{ matrix.arch }}.sources + + - uses: ./.github/actions/setup/ubuntu + with: + arch: ${{ matrix.arch }} + + - uses: ./.github/actions/setup/baseruby + id: baseruby + with: + srcdir: src + + - name: Run configure + run: >- + ../src/configure -C --disable-install-doc + --prefix=/usr + --build=${{ matrix.build }} + --host=${{ matrix.host }} + --with-baseruby="$baseruby" + env: + baseruby: ${{ steps.baseruby.outputs.ruby }} + + - run: make + + - run: make install DESTDIR=$PWD/install + + - name: Verify cross-compiled binary + run: | + file install/usr/bin/ruby + file install/usr/bin/ruby | grep -q '${{ matrix.file_arch }}' + + - uses: ./.github/actions/slack + with: + label: cross ${{ matrix.host }} + 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/cygwin.yml b/.github/workflows/cygwin.yml index d23261ddee..f1a6f79587 100644 --- a/.github/workflows/cygwin.yml +++ b/.github/workflows/cygwin.yml @@ -34,18 +34,22 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: - run: git config --global core.autocrlf input - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Setup Cygwin - uses: cygwin/cygwin-install-action@master + uses: cygwin/cygwin-install-action@711d29f3da23c9f4a1798e369a6f01198c13b11a # v6.1 with: - packages: ruby gcc-core make autoconf libtool libssl-devel libyaml-devel libffi-devel zlib-devel + packages: ruby gcc-core make autoconf libtool libssl-devel libyaml-devel libffi-devel zlib-devel rubygems + site: | + https://cygwin.osuosl.org/ - name: configure run: | @@ -63,3 +67,9 @@ jobs: timeout-minutes: 30 run: make -j4 V=1 shell: C:\cygwin\bin\bash.EXE --noprofile --norc -e -o igncr -o pipefail {0} + + - uses: ./.github/actions/slack + with: + label: Cygwin + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} diff --git a/.github/workflows/default_gems.yml b/.github/workflows/default_gems_list.yml index cd15e34229..68f2d18dd6 100644 --- a/.github/workflows/default_gems.yml +++ b/.github/workflows/default_gems_list.yml @@ -1,6 +1,9 @@ name: Update default gems list on: [push, pull_request, merge_group] +env: + UPDATE_NEWS_ENABLED: true + concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} @@ -9,7 +12,7 @@ permissions: contents: read jobs: - update_default_gems: + update_default_gems_list: name: Update default gems list permissions: @@ -20,7 +23,7 @@ jobs: if: ${{ github.repository == 'ruby/ruby' }} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} @@ -40,7 +43,7 @@ jobs: data=default_gems.json mkdir -p .downloaded-cache ln -s .downloaded-cache/$data . - curl -O -R -z ./$data https://stdgems.org/$data + curl --retry 5 --retry-connrefused --retry-delay 2 --retry-max-time 60 -O -R -z ./$data https://stdgems.org/$data if: ${{ steps.gems.outcome == 'success' }} - name: Make default gems list @@ -65,7 +68,7 @@ jobs: - name: Maintain updated gems list in NEWS run: | ruby tool/update-NEWS-gemlist.rb default - if: ${{ steps.gems.outcome == 'success' }} + if: ${{ steps.gems.outcome == 'success' && env.UPDATE_NEWS_ENABLED == 'true' }} - name: Check diffs id: diff diff --git a/.github/workflows/dependabot_automerge.yml b/.github/workflows/dependabot_automerge.yml index 3a2ba704ae..2e4dc8d7a2 100644 --- a/.github/workflows/dependabot_automerge.yml +++ b/.github/workflows/dependabot_automerge.yml @@ -13,11 +13,11 @@ jobs: if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'ruby/ruby' steps: - name: Dependabot metadata - uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0 + uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0 id: metadata - name: Wait for status checks - uses: lewagon/wait-on-check-action@0dceb95e7c4cad8cc7422aee3885998f5cab9c79 # v1.4.0 + uses: lewagon/wait-on-check-action@9312864dfbc9fd208e9c0417843430751c042800 # v1.7.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} ref: ${{ github.event.pull_request.head.sha || github.sha }} diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index e57cd86e2b..d0a8024b05 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -2,6 +2,9 @@ name: "Pull Request Labeler" on: - pull_request_target +permissions: + contents: read + jobs: labeler: permissions: @@ -9,4 +12,4 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/labeler@v5 + - uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index aab238ea47..4f1807121f 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -26,27 +26,29 @@ jobs: matrix: include: - test_task: check - os: macos-14 + os: macos-26 - test_task: check - os: macos-14 + os: macos-15 configure_args: '--with-gcc=gcc-14' - test_task: check - os: macos-14 + os: macos-26 configure_args: '--with-jemalloc --with-opt-dir=$(brew --prefix jemalloc)' - test_task: check - os: macos-14 + os: macos-26 configure_args: '--with-gmp' - test_task: test-all test_opts: --repeat-count=2 - os: macos-14 + os: macos-26 - test_task: test-bundler-parallel - os: macos-14 + os: macos-26 - test_task: test-bundled-gems - os: macos-14 + os: macos-26 - test_task: check os: macos-15 - test_task: check - os: macos-13 + os: macos-15-intel + - test_task: check + os: macos-14 fail-fast: false env: @@ -59,14 +61,15 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - name: Install libraries uses: ./.github/actions/setup/macos @@ -141,7 +144,7 @@ jobs: ulimit -c unlimited make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} - timeout-minutes: 60 + timeout-minutes: 90 env: RUBY_TESTOPTS: '-q --tty=no' TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' @@ -159,32 +162,24 @@ jobs: if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} continue-on-error: ${{ matrix.continue-on-skipped_tests || false }} + - name: CAPI extensions + uses: ./.github/actions/capiext + with: + builddir: build + env: + RUBY_TESTOPTS: '-v --tty=no' + if: ${{ contains(matrix.extra_checks, 'capi') }} + - 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() }} - - name: Resolve job ID - id: job_id - uses: actions/github-script@main - env: - matrix: ${{ toJson(matrix) }} - with: - script: | - const { data: workflow_run } = await github.rest.actions.listJobsForWorkflowRun({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.runId - }); - const matrix = JSON.parse(process.env.matrix); - const job_name = `${context.job}${matrix ? ` (${Object.values(matrix).join(", ")})` : ""}`; - return workflow_run.jobs.find((job) => job.name === job_name).id; - result: if: ${{ always() }} name: ${{ github.workflow }} result - runs-on: macos-latest + runs-on: ubuntu-latest needs: [make] steps: - run: exit 1 diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 773bb77503..9a47e70f8c 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -30,16 +30,32 @@ permissions: # jobs: make: - runs-on: windows-2022 + runs-on: windows-${{ matrix.os }} 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' - CXXFLAGS: '-march=x86-64 -mtune=generic -O3 -pipe' + MSYS2_ARCH: >- + ${{ case( + contains(matrix.msystem, 'arm64'), 'aarch64', + contains(matrix.msystem, '64'), 'x86_64', + 'i686' + ) }} + MINGW_PACKAGE_PREFIX: >- + mingw-w${{ + case(endsWith(matrix.msystem, '64'), '64', '32') + }}-${{ case( + startsWith(matrix.msystem, 'clang'), 'clang', + startsWith(matrix.msystem, 'ucrt'), 'ucrt', + 'mingw' + ) }}-${{ case( + contains(matrix.msystem, 'arm64'), 'aarch64', + endsWith(matrix.msystem, '64'), 'x86_64', + 'i686' + ) }} + CFLAGS: '-mtune=generic -O3 -pipe' + CXXFLAGS: '-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 }} @@ -50,8 +66,12 @@ jobs: # To mitigate flakiness of MinGW CI, we test only one runtime that newer MSYS2 uses. # Ruby 3.2 is the first Windows Ruby to use OpenSSL 3.x - msystem: 'UCRT64' + os: 2022 test_task: 'check' test-all-opts: '--name=!/TestObjSpace#test_reachable_objects_during_iteration/' + - msystem: 'CLANGARM64' + os: 11-arm + test_task: 'check' fail-fast: false if: >- @@ -59,32 +79,33 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/vcpkg')) )}} steps: - - uses: msys2/setup-msys2@40677d36a502eb2cf0fb808cc9dec31bf6152638 # v2.28.0 + - uses: msys2/setup-msys2@e9898307ac31d1a803454791be09ab9973336e1c # v2.31.1 id: msys2 with: - msystem: UCRT64 + msystem: ${{ matrix.msystem }} update: true install: >- git make ruby autoconf - mingw-w64-ucrt-x86_64-gcc - mingw-w64-ucrt-x86_64-ragel - mingw-w64-ucrt-x86_64-openssl - mingw-w64-ucrt-x86_64-libyaml - mingw-w64-ucrt-x86_64-libffi + ${{ env.MINGW_PACKAGE_PREFIX }}-gcc + ${{ env.MINGW_PACKAGE_PREFIX }}-ragel + ${{ env.MINGW_PACKAGE_PREFIX }}-openssl + ${{ env.MINGW_PACKAGE_PREFIX }}-libyaml + ${{ env.MINGW_PACKAGE_PREFIX }}-libffi - name: Set up env id: setup-env working-directory: run: | $msys2 = ${env:MSYS2_LOCATION} - echo $msys2\usr\bin $msys2\ucrt64\bin | + $msystem = ${env:MSYSTEM}.ToLower() + echo $msys2\usr\bin $msys2\$msystem\bin | Tee-Object ${env:GITHUB_PATH} -Append -Encoding utf-8 # Use the fast device for the temporary directory. @@ -96,6 +117,7 @@ jobs: shell: pwsh # cmd.exe does not strip spaces before `|`. env: MSYS2_LOCATION: ${{ steps.msys2.outputs.msys2-location }} + MSYSTEM: ${{ matrix.msystem }} - name: Remove Strawberry Perl pkg-config working-directory: @@ -140,16 +162,17 @@ jobs: I libssl-3-x64.dll group Packages - pacman -Qs mingw-w64-ucrt-x86_64-* | /bin/sed -n "s,local/mingw-w64-ucrt-x86_64-,,p" + pacman -Qs $MINGW_PACKAGE_PREFIX-* | /bin/sed -n "s,local/$MINGW_PACKAGE_PREFIX-,,p" endgroup [ ${#failed[@]} -eq 0 ] shell: sh - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - uses: ./.github/actions/setup/directories with: @@ -164,6 +187,8 @@ jobs: ../src/configure --disable-install-doc --prefix=/. --build=$CHOST --host=$CHOST --target=$CHOST shell: sh + env: + CHOST: ${{ env.MSYS2_ARCH }}-w64-mingw32 - name: make all timeout-minutes: 30 @@ -185,7 +210,7 @@ jobs: - name: test timeout-minutes: 30 - run: make test + run: make test test-tool env: GNUMAKEFLAGS: '' RUBY_TESTOPTS: '-v --tty=no' diff --git a/.github/workflows/modgc.yml b/.github/workflows/modgc.yml index 63c2d75d77..218127aad7 100644 --- a/.github/workflows/modgc.yml +++ b/.github/workflows/modgc.yml @@ -28,7 +28,7 @@ jobs: - name: default - name: mmtk mmtk_build: release - os: [macos-latest, ubuntu-latest] + os: [macos-26, ubuntu-latest] include: - test_task: check fail-fast: false @@ -44,14 +44,15 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - name: Install libraries (macOS) uses: ./.github/actions/setup/macos @@ -61,7 +62,7 @@ jobs: uses: ./.github/actions/setup/ubuntu if: ${{ contains(matrix.os, 'ubuntu') }} - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: '3.1' bundler: none @@ -100,18 +101,20 @@ jobs: - name: Run configure env: arch: ${{ matrix.arch }} - run: >- - $SETARCH ../src/configure -C --disable-install-doc --with-modular-gc=${{ env.MODULAR_GC_DIR }} + run: | + ${SETARCH} ../src/configure -C --disable-install-doc --with-modular-gc="${MODULAR_GC_DIR}" \ ${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE} - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1.16.1 + with: + cache-bin: false - name: Set MMTk environment variables run: | echo 'EXCLUDES=../src/test/.excludes-mmtk' >> $GITHUB_ENV echo 'MSPECOPT=-B../src/spec/mmtk.mspec' >> $GITHUB_ENV if: ${{ matrix.gc.name == 'mmtk' }} - - run: $SETARCH make + - run: ${SETARCH} make - name: Build Modular GC run: | @@ -119,7 +122,7 @@ jobs: make install-modular-gc MODULAR_GC=${{ matrix.gc.name }} MMTK_BUILD=${{ matrix.gc.mmtk_build }} make distclean-modular-gc MODULAR_GC=${{ matrix.gc.name }} - - run: $SETARCH make hello + - run: ${SETARCH} make hello - name: Set test options for skipped tests run: | @@ -145,7 +148,7 @@ jobs: test -n "${LAUNCHABLE_STDOUT}" && exec 1> >(tee "${LAUNCHABLE_STDOUT}") test -n "${LAUNCHABLE_STDERR}" && exec 2> >(tee "${LAUNCHABLE_STDERR}") - $SETARCH make -s ${{ matrix.test_task }} \ + ${SETARCH} make -s ${{ matrix.test_task }} \ ${TESTS:+TESTS="$TESTS"} \ ${{ !contains(matrix.test_task, 'bundle') && 'RUBYOPT=-w' || '' }} timeout-minutes: ${{ matrix.gc.timeout || 40 }} @@ -158,7 +161,7 @@ jobs: - name: make skipped tests run: | - $SETARCH make -s test-all TESTS="${TESTS//-n!\//-n/}" + ${SETARCH} make -s test-all TESTS="${TESTS//-n!\//-n/}" env: GNUMAKEFLAGS: '' RUBY_TESTOPTS: '-v --tty=no' diff --git a/.github/workflows/parse_y.yml b/.github/workflows/parse_y.yml index 5acf6ae4cb..7c26e87e57 100644 --- a/.github/workflows/parse_y.yml +++ b/.github/workflows/parse_y.yml @@ -47,18 +47,19 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: '3.1' bundler: none diff --git a/.github/workflows/post_push.yml b/.github/workflows/post_push.yml new file mode 100644 index 0000000000..e351c8c286 --- /dev/null +++ b/.github/workflows/post_push.yml @@ -0,0 +1,97 @@ +name: Post-push +on: + push: + branches: + - master + - 'ruby_*_*' + +permissions: + contents: read + +jobs: + hooks: + name: Post-push hooks + runs-on: ubuntu-latest + if: ${{ github.repository == 'ruby/ruby' }} + steps: + - name: Sync git.ruby-lang.org + id: sync-git + continue-on-error: true + run: | + mkdir -p ~/.ssh + (umask 066; printenv RUBY_GIT_SYNC_PRIVATE_KEY > ~/.ssh/id_ed25519) + ssh-keyscan -t ed25519 git.ruby-lang.org >> ~/.ssh/known_hosts + ssh -i ~/.ssh/id_ed25519 git-sync@git.ruby-lang.org "sudo -u git /home/git/git.ruby-lang.org/bin/update-ruby.sh $GITHUB_REF" + env: + GITHUB_REF: ${{ github.ref }} + RUBY_GIT_SYNC_PRIVATE_KEY: ${{ secrets.RUBY_GIT_SYNC_PRIVATE_KEY }} + if: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/ruby_') }} + + - name: Fetch changesets on bugs.ruby-lang.org + run: | + curl "https://bugs.ruby-lang.org/sys/fetch_changesets?key=${REDMINE_SYS_API_KEY}" -s --fail-with-body -w '* status: %{http_code}\n' + env: + REDMINE_SYS_API_KEY: ${{ secrets.REDMINE_SYS_API_KEY }} + if: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/ruby_') }} + + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + fetch-depth: 500 # for notify-slack-commits + token: ${{ secrets.MATZBOT_AUTO_UPDATE_TOKEN }} + + - name: Notify commit to Slack + run: ruby tool/notify-slack-commits.rb "$GITHUB_OLD_SHA" "$GITHUB_NEW_SHA" refs/heads/master + env: + GITHUB_OLD_SHA: ${{ github.event.before }} + GITHUB_NEW_SHA: ${{ github.event.after }} + SLACK_WEBHOOK_URL_ALERTS: ${{ secrets.SLACK_WEBHOOK_URL_ALERTS }} + SLACK_WEBHOOK_URL_COMMITS: ${{ secrets.SLACK_WEBHOOK_URL_COMMITS }} + SLACK_WEBHOOK_URL_RUBY_JP: ${{ secrets.SLACK_WEBHOOK_URL_RUBY_JP }} + if: ${{ github.ref == 'refs/heads/master' }} + + - name: Notify commit to ruby-cvs + run: | + SENDMAIL="ssh -i ${HOME}/.ssh/id_ed25519 git-sync@git.ruby-lang.org /usr/sbin/sendmail" \ + ruby tool/commit-email.rb . ruby-cvs@g.ruby-lang.org \ + "$GITHUB_OLD_SHA" "$GITHUB_NEW_SHA" "$GITHUB_REF" \ + --viewer-uri "https://github.com/ruby/ruby/commit/" \ + --error-to cvs-admin@ruby-lang.org + env: + GITHUB_OLD_SHA: ${{ github.event.before }} + GITHUB_NEW_SHA: ${{ github.event.after }} + GITHUB_REF: ${{ github.ref }} + if: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/ruby_') }} + + - name: Auto-correct code styles + run: | + set -x + ruby tool/auto-style.rb "$GITHUB_OLD_SHA" "$GITHUB_NEW_SHA" refs/heads/master + env: + GITHUB_OLD_SHA: ${{ github.event.before }} + GITHUB_NEW_SHA: ${{ github.event.after }} + GIT_AUTHOR_NAME: git + GIT_COMMITTER_NAME: git + EMAIL: svn-admin@ruby-lang.org + if: ${{ github.ref == 'refs/heads/master' }} + + - name: Push PR notes to GitHub + id: pr-notes + continue-on-error: true + run: ruby tool/notes-github-pr.rb "$(pwd)/.git" "$GITHUB_OLD_SHA" "$GITHUB_NEW_SHA" refs/heads/master + env: + GITHUB_OLD_SHA: ${{ github.event.before }} + GITHUB_NEW_SHA: ${{ github.event.after }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GIT_AUTHOR_NAME: git + GIT_COMMITTER_NAME: git + EMAIL: svn-admin@ruby-lang.org + if: ${{ github.ref == 'refs/heads/master' }} + + - name: Check for failures + run: exit 1 + if: ${{ steps.sync-git.outcome == 'failure' || steps.pr-notes.outcome == 'failure' }} + + - 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/pr-playground.yml b/.github/workflows/pr-playground.yml index cc06006142..dc4f075a38 100644 --- a/.github/workflows/pr-playground.yml +++ b/.github/workflows/pr-playground.yml @@ -6,6 +6,10 @@ on: workflows: ["WebAssembly"] types: [completed] +permissions: + contents: read + actions: read + jobs: post-summary: name: Post Playground link @@ -25,7 +29,7 @@ jobs: && github.event.workflow_run.event == 'pull_request') }} steps: - - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5d4474d978..5d4a31d287 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,18 +1,114 @@ -name: Start release workflow +name: Publish Ruby packages + on: - push: - tags: - - '*' + repository_dispatch: + types: + - release + workflow_dispatch: + inputs: + version: + description: 'Version of the Ruby package to release' + required: true + default: '4.0.0' + +permissions: + contents: read jobs: - notify: + release: runs-on: ubuntu-latest steps: - - name: Build release package + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 + with: + ruby-version: 3.3.4 + + - name: Store Ruby version + env: + RUBY_VERSION: ${{ github.event.client_payload.version || github.event.inputs.version }} + run: | + echo "RUBY_VERSION=${RUBY_VERSION}" >> $GITHUB_ENV + + - name: Store ABI version + run: echo "ABI_VERSION=$(echo ${RUBY_VERSION} | cut -d '.' -f 1-2)" >> $GITHUB_ENV + + - name: Copy draft package `/tmp` to `/pub` directory + run: tool/release.sh ${RUBY_VERSION} + env: + AWS_ACCESS_KEY_ID: ${{ secrets.FTP_R_L_O_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.FTP_R_L_O_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: us-west-2 + + - name: Purge URLs of release package + run: | + curl -X POST \ + -H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \ + https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${ABI_VERSION}/ruby-${RUBY_VERSION}.tar.gz + curl -X POST \ + -H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \ + https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${ABI_VERSION}/ruby-${RUBY_VERSION}.tar.xz + curl -X POST \ + -H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \ + https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${ABI_VERSION}/ruby-${RUBY_VERSION}.zip + + - name: Create a release on GitHub + run: | + RELEASE_TAG=$(ruby tool/ruby-version.rb tag "${RUBY_VERSION}") + echo $RELEASE_TAG + PREVIOUS_RELEASE_TAG=$(ruby tool/ruby-version.rb previous-tag "${RUBY_VERSION}") + echo $PREVIOUS_RELEASE_TAG + tool/gen-github-release.rb $PREVIOUS_RELEASE_TAG $RELEASE_TAG --no-dry-run + env: + GITHUB_TOKEN: ${{ secrets.MATZBOT_AUTO_UPDATE_TOKEN }} + + - name: Update versions index run: | curl -L -X POST \ -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/ruby/actions/dispatches \ - -d '{"event_type": "${{ github.ref }}"}' + -d '{"event_type": "update_index"}' + + - name: Build and push Docker images + run: | + curl -L -X POST \ + -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/ruby/docker-images/dispatches \ + -d "{\"event_type\": \"build\", \"client_payload\": {\"ruby_version\": \"${RUBY_VERSION}\"}}" + + - name: Build snapcraft packages + run: | + curl -L -X POST \ + -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/ruby/snap.ruby/dispatches \ + -d "{\"event_type\": \"build\", \"client_payload\": {\"ruby_version\": \"${RUBY_VERSION}\"}}" + + - name: Store the latest LTS version of OpenSSL + run: | + echo "OPENSSL_VERSION=`curl -s https://api.github.com/repos/openssl/openssl/releases | jq -r '.[].tag_name | select(startswith("openssl-3.0"))' | sort -Vr | head -n1 | cut -d'-' -f2`" >> $GITHUB_ENV + + - name: Update ruby-build definition + run: | + curl -L -X POST \ + -H "Authorization: Bearer ${{ secrets.RUBY_BUILD_WORKFLOW_TOKEN }}" \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/rbenv/ruby-build/dispatches \ + -d "{\"event_type\": \"update-ruby\", \"client_payload\": {\"ruby_version\": \"${RUBY_VERSION}\", \"openssl_version\": \"${OPENSSL_VERSION}\"}}" + + - name: Update all-ruby definition + run: | + curl -L -X POST \ + -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/ruby/all-ruby/dispatches \ + -d '{"event_type": "update"}' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 284e336a29..a35bcff99a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,107 +1,21 @@ -name: Publish Ruby packages - +name: Start release workflow on: - repository_dispatch: - types: - - release - workflow_dispatch: - inputs: - version: - description: 'Version of the Ruby package to release' - required: true - default: '3.3.4' + push: + tags: + - '*' + +permissions: + contents: read jobs: - release: + notify: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.3.4 - - - name: Store Ruby version - run: | - echo "RUBY_VERSION=${{ github.event.client_payload.version || github.event.inputs.version }}" >> $GITHUB_ENV - - - name: Store ABI version - run: echo "ABI_VERSION=$(echo ${{ env.RUBY_VERSION }} | cut -d '.' -f 1-2)" >> $GITHUB_ENV - - - name: Copy draft package `/tmp` to `/pub` directory - run: tool/release.sh ${{ env.RUBY_VERSION }} - env: - AWS_ACCESS_KEY_ID: ${{ secrets.FTP_R_L_O_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.FTP_R_L_O_AWS_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: us-west-2 - - - name: Purge URLs of release package - run: | - curl -X POST \ - -H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \ - https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.tar.gz - curl -X POST \ - -H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \ - https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.tar.xz - curl -X POST \ - -H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \ - https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.zip - - - name: Create a release on GitHub - run: | - RELEASE_TAG=$(echo v${{ env.RUBY_VERSION }} | sed 's/\./_/g') - echo $RELEASE_TAG - PREVIOUS_RELEASE_TAG=$(echo $RELEASE_TAG | awk 'BEGIN {FS="_"; OFS="_"}{ $NF=$NF-1; print }') - echo $PREVIOUS_RELEASE_TAG - tool/gen-github-release.rb $PREVIOUS_RELEASE_TAG $RELEASE_TAG --no-dry-run - env: - GITHUB_TOKEN: ${{ secrets.MATZBOT_AUTO_UPDATE_TOKEN }} - - - name: Update versions index + - name: Build release package run: | curl -L -X POST \ -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/ruby/actions/dispatches \ - -d '{"event_type": "update_index"}' - - - name: Build and push Docker images - run: | - curl -L -X POST \ - -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/ruby/docker-images/dispatches \ - -d '{"event_type": "build", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}"}}' - - - name: Build snapcraft packages - run: | - curl -L -X POST \ - -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/ruby/snap.ruby/dispatches \ - -d '{"event_type": "build", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}"}}' - - - name: Store the latest LTS version of OpenSSL - run: | - echo "OPENSSL_VERSION=`curl -s https://api.github.com/repos/openssl/openssl/releases | jq -r '.[].tag_name | select(startswith("openssl-3.0"))' | sort -Vr | head -n1 | cut -d'-' -f2`" >> $GITHUB_ENV - - - name: Update ruby-build definition - run: | - curl -L -X POST \ - -H "Authorization: Bearer ${{ secrets.RUBY_BUILD_WORKFLOW_TOKEN }}" \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/rbenv/ruby-build/dispatches \ - -d '{"event_type": "update-ruby", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}", "openssl_version": "${{ env.OPENSSL_VERSION }}"}}' - - - name: Update all-ruby definition - run: | - curl -L -X POST \ - -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/ruby/all-ruby/dispatches \ - -d '{"event_type": "update"}' + -d "{\"event_type\": \"$GITHUB_REF\"}" diff --git a/.github/workflows/rust-warnings.yml b/.github/workflows/rust-warnings.yml index 8fd78ea04b..7ea7d0c950 100644 --- a/.github/workflows/rust-warnings.yml +++ b/.github/workflows/rust-warnings.yml @@ -21,7 +21,7 @@ permissions: contents: read jobs: - make: + rust-warnings: env: GITPULLOPTIONS: --no-tags origin ${{ github.ref }} @@ -32,11 +32,13 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Install Rust run: rustup default beta @@ -46,6 +48,15 @@ jobs: run: | set -eu cargo check --quiet --all-features --message-format=json \ - | jq -r 'select(.message.level == "warning" or .message.level == "error") | .message.rendered' \ + | jq -r 'select(.message.level | IN("warning", "error")) | .message.rendered' \ + | tee messages.txt + (exit "${PIPESTATUS[0]}") && ! grep --quiet '[^[:space:]]' messages.txt + + - name: "📜 `rustdoc` warnings" + shell: bash + run: | + set -eu + cargo doc --document-private-items --all --no-deps --message-format=json \ + | jq -r 'select(.message.level | IN("warning", "error")) | .message.rendered' \ | tee messages.txt (exit "${PIPESTATUS[0]}") && ! grep --quiet '[^[:space:]]' messages.txt diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 8cc7e00c47..6dc4a7c6ad 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -34,12 +34,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: results.sarif results_format: sarif @@ -64,7 +64,7 @@ jobs: # 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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: SARIF file path: results.sarif @@ -73,6 +73,6 @@ jobs: # 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 + uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 with: sarif_file: results.sarif diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml index e952053891..39714b13a4 100644 --- a/.github/workflows/spec_guards.yml +++ b/.github/workflows/spec_guards.yml @@ -31,7 +31,7 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} strategy: @@ -39,14 +39,17 @@ jobs: # 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-3.2 - ruby-3.3 - ruby-3.4 + - ruby-4.0 + fail-fast: false steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/sync_default_gems.yml b/.github/workflows/sync_default_gems.yml new file mode 100644 index 0000000000..3aaae5864f --- /dev/null +++ b/.github/workflows/sync_default_gems.yml @@ -0,0 +1,80 @@ +name: Sync default gems + +env: + DEFAULT_GEM_SYNC_ENABLED: true + +on: + workflow_dispatch: + inputs: + gem: + required: true + description: 'Name of the gem to be synchronized' + type: string + before: + required: true + description: 'Gem commit SHA before sync' + type: string + after: + required: true + description: 'Gem commit SHA after sync' + type: string + +permissions: + contents: read + +jobs: + sync_default_gems: + name: Sync default gem ${{ github.event.inputs.gem }} + + permissions: + contents: write # for Git to git push + + runs-on: ubuntu-latest + + if: ${{ github.repository == 'ruby/ruby' }} + + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + name: Check out ruby/ruby + with: + token: ${{ github.repository == 'ruby/ruby' && secrets.MATZBOT_AUTO_UPDATE_TOKEN || secrets.GITHUB_TOKEN }} + + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 + with: + ruby-version: '3.4' + bundler: none + + - name: Run tool/sync_default_gems.rb + id: sync + run: | + ruby_before=$(git rev-parse HEAD) + set -x + ruby tool/sync_default_gems.rb "${gem_name}" "${gem_before}..${gem_after}" + if [[ "$(git rev-parse HEAD)" != "$ruby_before" ]]; then + echo update=true >> $GITHUB_OUTPUT + fi + env: + gem_name: ${{ github.event.inputs.gem }} + gem_before: ${{ github.event.inputs.before }} + gem_after: ${{ github.event.inputs.after }} + EMAIL: svn-admin@ruby-lang.org + GIT_AUTHOR_NAME: git + GIT_COMMITTER_NAME: git + + - name: Push + run: | + git pull --rebase origin ${GITHUB_REF#refs/heads/} + git push origin ${GITHUB_REF#refs/heads/} + if: ${{ steps.sync.outputs.update && env.DEFAULT_GEM_SYNC_ENABLED == 'true' }} + env: + EMAIL: svn-admin@ruby-lang.org + GIT_AUTHOR_NAME: git + GIT_COMMITTER_NAME: git + + - uses: ./.github/actions/slack + with: + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + label: "${{ github.event.inputs.gem }} (<https://github.com/${{ github.event.inputs.gem == 'rubygems' && 'rubygems' || 'ruby' }}/${{ github.event.inputs.gem }}/compare/${{ github.event.inputs.before }}...${{ github.event.inputs.after }}|diff>)" + event_name: workflow_dispatch + extra_channel_id: C05FPKAU743 # alerts-sync + if: ${{ failure() }} diff --git a/.github/workflows/tarball-macos.yml b/.github/workflows/tarball-macos.yml new file mode 100644 index 0000000000..0d02cf6ae1 --- /dev/null +++ b/.github/workflows/tarball-macos.yml @@ -0,0 +1,101 @@ +name: tarball-macos (reusable) + +on: + workflow_call: + inputs: + archname: + description: 'archname (e.g. snapshot-master, snapshot-ruby_3_3)' + required: true + type: string + notify-release-channel: + description: 'Also send failure notifications to SNAPSHOT_SLACK_WEBHOOK_URL (schedule/release builds).' + required: false + type: boolean + default: false + secrets: + SIMPLER_ALERTS_URL: + required: false + SNAPSHOT_SLACK_WEBHOOK_URL: + required: false + +permissions: + contents: read + +jobs: + macos: + strategy: + matrix: + test_task: [check, test-bundled-gems, test-bundler-parallel] + os: [macos-26, macos-15, macos-14] + include: + - os: macos-15-intel + test_task: check + fail-fast: false + runs-on: ${{ matrix.os }} + env: + ARCHNAME: ${{ inputs.archname }} + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: Packages + path: pkg + - name: Extract + run: tar xf pkg/*.tar.xz + - name: Install libraries + run: | + with_retry () { + "$@" || { sleep 5 && "$@"; } || { sleep 60 && "$@"; } + } + set -x + with_retry brew install gmp libffi openssl zlib autoconf automake libtool libyaml + - name: Set ENV + run: | + echo "JOBS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV + - name: configure + run: cd "$ARCHNAME/" && ./configure --with-openssl-dir=$(brew --prefix openssl) --with-libyaml-dir=$(brew --prefix libyaml) + - name: make + run: cd "$ARCHNAME/" && make $JOBS + - name: Tests + run: cd "$ARCHNAME/" && make $JOBS -s ${{ matrix.test_task }} + env: + RUBY_TESTOPTS: "-q --tty=no" + RUBY_DEBUG_TEST_NO_REMOTE: "1" + # leaked-globals since 2.7 + - name: Leaked Globals + run: cd "$ARCHNAME/" && make -s leaked-globals + if: matrix.test_task == 'check' + - name: make install without root privilege + run: cd "$ARCHNAME/" && make $JOBS install DESTDIR="/tmp/destdir" + if: matrix.test_task == 'check' + - name: make install + run: cd "$ARCHNAME/" && sudo make $JOBS install + if: matrix.test_task == 'check' + - name: Verify installed binaries + run: | + /usr/local/bin/ruby -v + /usr/local/bin/gem -v + /usr/local/bin/bundle -v + if: matrix.test_task == 'check' + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + sparse-checkout: .github/actions/slack + sparse-checkout-cone-mode: false + persist-credentials: false + if: ${{ failure() }} + - 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() }} + - uses: ruby/action-slack@d260b61aa817726d5bedd22dd6cc305787fa4cdd # v4.0.0 + with: + payload: | + { + "attachments": [{ + "text": "${{ job.status }}: ${{ matrix.os }} / ${{ matrix.test_task }} <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ inputs.archname }}>", + "color": "danger" + }] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SNAPSHOT_SLACK_WEBHOOK_URL }} + if: failure() && inputs.notify-release-channel diff --git a/.github/workflows/tarball-non-development.yml b/.github/workflows/tarball-non-development.yml new file mode 100644 index 0000000000..db6230b301 --- /dev/null +++ b/.github/workflows/tarball-non-development.yml @@ -0,0 +1,87 @@ +name: tarball-non-development (reusable) + +on: + workflow_call: {} + +permissions: + contents: read + +jobs: + non_development: + strategy: + fail-fast: false + matrix: + include: + - { variant: default, remove_ruby: false, configure_extra: '' } + - { variant: no-ruby, remove_ruby: true, configure_extra: '' } + - { variant: baseruby-no, remove_ruby: false, configure_extra: '--with-baseruby=no' } + runs-on: ubuntu-24.04 + env: + ruby_prefix: /tmp/ruby-snapshot + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: Packages + path: pkg + - name: Extract + run: tar xf pkg/*.tar.xz + - name: Substitute patchlevel + run: | + set -x + cd snapshot-*/ + sed -i.orig 's/^\( *# *define *RUBY_PATCHLEVEL\) *-.*/\1 0/' version.h + diff -u version.h.orig version.h || : + rm -f version.h.orig + - 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 zlib1g-dev libffi-dev libgmp-dev bison- autoconf- + - name: Remove host ruby + if: matrix.remove_ruby + run: | + set -x + sudo apt-get purge -y -q 'ruby*' || : + sudo rm -rf /opt/hostedtoolcache/Ruby + ! command -v ruby + - name: Set ENV + run: | + echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV + - name: configure + run: cd snapshot-*/ && ./configure --prefix="${ruby_prefix}" ${{ matrix.configure_extra }} + - name: make + run: cd snapshot-*/ && make $JOBS + - name: Leaked Globals + run: cd snapshot-*/ && make -s leaked-globals + - name: make install + run: cd snapshot-*/ && make $JOBS install + - name: Set PATH + run: echo "PATH=${ruby_prefix}/bin:$PATH" >> $GITHUB_ENV + - name: Check patchlevel + id: check-patchlevel + run: | + exec "${ruby_prefix}/bin/ruby" -vx "$0" + #!ruby + puts "RUBY_PATCHLEVEL=#{RUBY_PATCHLEVEL.inspect}" + abort unless RUBY_PATCHLEVEL >= 0 + working-directory: ${{ env.ruby_prefix }} + continue-on-error: true + - name: Check LOADPATH + id: check-loadpath + run: | + exec ${ruby_prefix}/bin/ruby -vx "$0" + #!ruby + paths = $:.grep(/\+/) + pp paths + abort unless paths.empty? + working-directory: ${{ env.ruby_prefix }} + continue-on-error: true + - name: Check pathnames + id: check-pathnames + run: | + ! find -name '*+*' | grep + + working-directory: ${{ env.ruby_prefix }} + continue-on-error: true + - name: result + run: false + if: ${{ contains(steps.*.outcome, 'failure') }} diff --git a/.github/workflows/tarball-test-schedule.yml b/.github/workflows/tarball-test-schedule.yml new file mode 100644 index 0000000000..6684b09edb --- /dev/null +++ b/.github/workflows/tarball-test-schedule.yml @@ -0,0 +1,26 @@ +name: tarball-test-schedule +on: + schedule: + - cron: '30 18 * * *' # Daily at 18:30 UTC + workflow_dispatch: + +permissions: {} + +jobs: + dispatch: + if: ${{ github.event_name != 'schedule' || github.repository == 'ruby/ruby' }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + branch: + - master + - ruby_4_0 + - ruby_3_4 + - ruby_3_3 + steps: + - name: Trigger tarball-test on ${{ matrix.branch }} + run: gh workflow run tarball-test.yml --ref "$BRANCH" --repo "$GITHUB_REPOSITORY" -f notify-release-channel=true + env: + BRANCH: ${{ matrix.branch }} + GH_TOKEN: ${{ secrets.MATZBOT_GITHUB_ACTION_TOKEN }} diff --git a/.github/workflows/tarball-test.yml b/.github/workflows/tarball-test.yml new file mode 100644 index 0000000000..f75d76761a --- /dev/null +++ b/.github/workflows/tarball-test.yml @@ -0,0 +1,104 @@ +name: tarball-test +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: + workflow_dispatch: + inputs: + notify-release-channel: + description: 'Also send failure notifications to SNAPSHOT_SLACK_WEBHOOK_URL (set by tarball-test-schedule).' + type: boolean + default: false + +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: + tarball: + runs-on: ubuntu-latest + # Cherry-pick to maintenance branches by changing only env.BRANCH below; + # archname / branch-label / Materialize all derive from it. + env: + BRANCH: master + outputs: + branch: ${{ env.BRANCH }} + skip: ${{ steps.skipping.outputs.skip }} + steps: + - id: skipping + run: echo 'skip=true' >> $GITHUB_OUTPUT + if: >- + ${{(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Documentation') + || (github.event.pull_request.user.login == 'dependabot[bot]') + )}} + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + fetch-depth: 1 # actions/checkout fetches all heads/tags unless > 0 + persist-credentials: false + # tool/make-snapshot derives the branch name from HEAD and looks up + # the upstream during ChangeLog generation. Detached checkouts + # (pull_request, merge_group) lack a local branch with tracking, so + # pin one to HEAD and connect it to the matching origin ref. + - name: Materialize local branch + run: | + git fetch --no-tags --depth=1 origin "+refs/heads/$BASE:refs/remotes/origin/$BASE" + git checkout -B "$BRANCH" HEAD + git branch --set-upstream-to="origin/$BASE" "$BRANCH" + env: + BASE: ${{ github.base_ref || env.BRANCH }} + - uses: ./.github/actions/make-snapshot + with: + archname: snapshot-${{ env.BRANCH }} + srcdir: '.' + + ubuntu: + needs: tarball + if: ${{ ! needs.tarball.outputs.skip }} + uses: ./.github/workflows/tarball-ubuntu.yml + with: + archname: snapshot-${{ needs.tarball.outputs.branch }} + notify-release-channel: ${{ github.event_name == 'workflow_dispatch' && inputs.notify-release-channel || false }} + secrets: + SIMPLER_ALERTS_URL: ${{ secrets.SIMPLER_ALERTS_URL }} + SNAPSHOT_SLACK_WEBHOOK_URL: ${{ secrets.SNAPSHOT_SLACK_WEBHOOK_URL }} + + macos: + needs: tarball + if: ${{ ! needs.tarball.outputs.skip }} + uses: ./.github/workflows/tarball-macos.yml + with: + archname: snapshot-${{ needs.tarball.outputs.branch }} + notify-release-channel: ${{ github.event_name == 'workflow_dispatch' && inputs.notify-release-channel || false }} + secrets: + SIMPLER_ALERTS_URL: ${{ secrets.SIMPLER_ALERTS_URL }} + SNAPSHOT_SLACK_WEBHOOK_URL: ${{ secrets.SNAPSHOT_SLACK_WEBHOOK_URL }} + + windows: + needs: tarball + if: ${{ ! needs.tarball.outputs.skip }} + uses: ./.github/workflows/tarball-windows.yml + with: + archname: snapshot-${{ needs.tarball.outputs.branch }} + notify-release-channel: ${{ github.event_name == 'workflow_dispatch' && inputs.notify-release-channel || false }} + secrets: + SIMPLER_ALERTS_URL: ${{ secrets.SIMPLER_ALERTS_URL }} + SNAPSHOT_SLACK_WEBHOOK_URL: ${{ secrets.SNAPSHOT_SLACK_WEBHOOK_URL }} + + non_development: + needs: tarball + uses: ./.github/workflows/tarball-non-development.yml diff --git a/.github/workflows/tarball-ubuntu.yml b/.github/workflows/tarball-ubuntu.yml new file mode 100644 index 0000000000..0482db3c7f --- /dev/null +++ b/.github/workflows/tarball-ubuntu.yml @@ -0,0 +1,151 @@ +name: tarball-ubuntu (reusable) + +on: + workflow_call: + inputs: + archname: + description: 'archname (e.g. snapshot-master, snapshot-ruby_3_3)' + required: true + type: string + notify-release-channel: + description: 'Also send failure notifications to SNAPSHOT_SLACK_WEBHOOK_URL (schedule/release builds).' + required: false + type: boolean + default: false + secrets: + SIMPLER_ALERTS_URL: + required: false + SNAPSHOT_SLACK_WEBHOOK_URL: + required: false + +permissions: + contents: read + +jobs: + ubuntu: + strategy: + matrix: + test_task: [check, test-bundler-parallel, test-bundled-gems] + os: [ubuntu-24.04, ubuntu-22.04] + fail-fast: false + runs-on: ${{ matrix.os }} + env: + ARCHNAME: ${{ inputs.archname }} + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: Packages + path: pkg + - name: Extract + run: tar xf pkg/*.tar.xz + - 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 zlib1g-dev libffi-dev libgmp-dev bison- autoconf- + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 + with: + ruby-version: '3.2' + # test-bundled-gems requires executable host ruby + if: matrix.test_task == 'test-bundled-gems' + - name: Fixed world writable dirs + run: | + mkdir -p $HOME/.local/share + mkdir -p $HOME/.cache/gem/specs + mkdir -p $HOME/.bundle/cache + mkdir -p $HOME/.ssh + chmod a-w $HOME/.bundle + # chmod a-w $HOME + # allow to write $HOME and check stats of HOME around tests (see below) + chmod -v a-w $HOME/.config + sudo chmod -R a-w /usr/share + sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v a-w $d; done' || : + - name: Set ENV + run: | + echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV + - name: configure + run: cd "$ARCHNAME/" && ./configure + - name: make + run: cd "$ARCHNAME/" && make $JOBS + - name: Save stats of HOME + run: | + set -euxo pipefail + cat >"$ARCHNAME/save-stats.rb" <<'EOF' + require 'pathname' + require 'digest' + out = [] + [ + Dir.home, + ].each do |dir| + Dir.each_child(dir) do |name| + pn = File.join(dir, name) + st = File.stat(pn) + if st.file? + content = Digest::SHA1.file(pn).hexdigest + elsif st.directory? && st.nlink <= 10 + content = Dir.children(pn).sort + end + out << [pn, "%o"%st.mode, st.nlink, st.uid, st.gid, st.size, content].to_s + rescue + out << [pn, $!.inspect].to_s + end + end + File.open(ARGV.shift, "w") do |io| + io.puts out.sort + end + EOF + make -C "$ARCHNAME" TESTRUN_SCRIPT=save-stats.rb RUNOPT=/tmp/stat-before-tests.txt runruby + - name: Tests + run: cd "$ARCHNAME/" && make $JOBS -s ${{ matrix.test_task }} + env: + RUBY_TESTOPTS: "-q --tty=no" + # test_sync_default_gems triggers gpg, whose agent processes leave + # $HOME/.gnupg around even when GNUPGHOME points elsewhere. + - name: Forcibly remove ~/.gnupg + run: rm -rf $HOME/.gnupg + - name: Diff stats of HOME + run: | + make -C "$ARCHNAME" TESTRUN_SCRIPT=save-stats.rb RUNOPT=/tmp/stat-after-tests.txt runruby + rm -f "$ARCHNAME/save-stats.rb" + diff -u /tmp/stat-before-tests.txt /tmp/stat-after-tests.txt + # leaked-globals since 2.7 + - name: Leaked Globals + run: cd "$ARCHNAME/" && make -s leaked-globals + if: matrix.test_task == 'check' + - name: make install without root privilege + run: cd "$ARCHNAME/" && make $JOBS install DESTDIR="/tmp/destdir" + if: matrix.test_task == 'check' + - name: make install + run: cd "$ARCHNAME/" && sudo make $JOBS install + if: matrix.test_task == 'check' + - name: Verify installed binaries + run: | + /usr/local/bin/ruby -v + /usr/local/bin/gem -v + /usr/local/bin/bundle -v + if: matrix.test_task == 'check' + - name: Show .local + run: find $HOME/.local -ls + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + sparse-checkout: .github/actions/slack + sparse-checkout-cone-mode: false + persist-credentials: false + if: ${{ failure() }} + - 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() }} + - uses: ruby/action-slack@d260b61aa817726d5bedd22dd6cc305787fa4cdd # v4.0.0 + with: + payload: | + { + "attachments": [{ + "text": "${{ job.status }}: ${{ matrix.os }} / ${{ matrix.test_task }} <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ inputs.archname }}>", + "color": "danger" + }] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SNAPSHOT_SLACK_WEBHOOK_URL }} + if: failure() && inputs.notify-release-channel diff --git a/.github/workflows/tarball-windows.yml b/.github/workflows/tarball-windows.yml new file mode 100644 index 0000000000..a66cdf729d --- /dev/null +++ b/.github/workflows/tarball-windows.yml @@ -0,0 +1,163 @@ +name: tarball-windows (reusable) + +on: + workflow_call: + inputs: + archname: + description: 'archname (e.g. snapshot-master)' + required: true + type: string + notify-release-channel: + description: 'Also send failure notifications to SNAPSHOT_SLACK_WEBHOOK_URL (schedule/release builds).' + required: false + type: boolean + default: false + secrets: + SIMPLER_ALERTS_URL: + required: false + SNAPSHOT_SLACK_WEBHOOK_URL: + required: false + +permissions: + contents: read + +jobs: + windows: + strategy: + matrix: + include: + - os: '2022' + test_task: check + - os: '2025-vs2026' + test_task: check + fail-fast: false + runs-on: windows-${{ matrix.os }} + defaults: + run: + shell: cmd + working-directory: build + name: Windows ${{ matrix.os }} (${{ matrix.test_task }}) + env: + GITPULLOPTIONS: --no-tags origin ${{github.ref}} + PATCH: C:\msys64\usr\bin\patch.exe + OS_VER: windows-${{ matrix.os }} + # see https://github.com/ruby/ruby/commit/9ff4399decef0036897d3cfb9ac2c710dea913ca + OPENSSL_MODULES: C:\vcpkg\installed\x64-windows\bin + steps: + - run: md build + working-directory: + + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 + with: + ruby-version: '3.2' + bundler: none + windows-toolchain: none + + - uses: msys2/setup-msys2@e9898307ac31d1a803454791be09ab9973336e1c # v2.31.1 + id: setup-msys2 + with: + update: true + install: >- + patch + - 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@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: C:\vcpkg\installed + key: ${{ runner.os }}-vcpkg-installed-${{ env.OS_VER }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-vcpkg-installed-${{ env.OS_VER }}- + ${{ runner.os }}-vcpkg-installed- + - name: Install libraries with vcpkg + run: | + vcpkg --triplet x64-windows install gmp libffi libyaml openssl zlib + + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: Packages + path: pkg + - name: Extract + run: 7z x pkg/*.zip + working-directory: + + - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: snapshot-*/.downloaded-cache + key: downloaded-cache + + - name: setup env + # %TEMP% is inconsistent with %TMP% and test-all expects they are consistent. + # https://github.com/actions/virtual-environments/issues/712#issuecomment-613004302 + env: + ARCHNAME: ${{ inputs.archname }} + run: | + set > old.env + call ..\%ARCHNAME%\win32\vssetup.cmd + set TMP=%USERPROFILE%\AppData\Local\Temp + set TEMP=%USERPROFILE%\AppData\Local\Temp + set /a TEST_JOBS=(15 * %NUMBER_OF_PROCESSORS% / 10) > nul + set > new.env + + - name: update env + shell: pwsh + run: | + $old = (Get-Content old.env); $new = (Get-Content new.env) + del *.env + Compare-Object $old $new | + Where-Object { $_.SideIndicator -eq '=>' } | + Select-Object -ExpandProperty InputObject | + Add-Content -Path $env:GITHUB_ENV + - name: link libraries + run: | + for %%I in (C:\vcpkg\installed\x64-windows\bin\*.dll) do ( + mklink %%~nxI %%I + ) + - name: Configure + env: + ARCHNAME: ${{ inputs.archname }} + run: >- + ../%ARCHNAME%/win32/configure.bat --disable-install-doc + --with-opt-dir=C:/vcpkg/installed/x64-windows + - run: nmake incs + - run: nmake extract-extlibs + - run: nmake + env: + YACC: win_bison + + - name: ruby -v + run: .\ruby -v + + - run: nmake test + timeout-minutes: 5 + + - run: nmake ${{ matrix.test_task }} + env: + RUBY_TESTOPTS: -j${{env.TEST_JOBS}} + timeout-minutes: 70 + continue-on-error: ${{ matrix.continue-on-error || false }} + + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + sparse-checkout: .github/actions/slack + sparse-checkout-cone-mode: false + persist-credentials: false + if: ${{ failure() }} + - uses: ./.github/actions/slack + with: + label: "${{ env.OS_VER }} / ${{ matrix.test_task }}" + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} + - uses: ruby/action-slack@d260b61aa817726d5bedd22dd6cc305787fa4cdd # v4.0.0 + with: + payload: | + { + "attachments": [{ + "text": "${{ job.status }}: ${{ env.OS_VER }} / ${{ matrix.test_task }} <https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|${{ inputs.archname }}>", + "color": "danger" + }] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SNAPSHOT_SLACK_WEBHOOK_URL }} + if: failure() && inputs.notify-release-channel diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 8955ea91d4..c887ae3811 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -24,22 +24,7 @@ jobs: make: strategy: matrix: - test_task: [check] - configure: [''] - arch: [''] - os: - - ubuntu-24.04 - - ubuntu-24.04-arm - # FIXME Comment out ppc64le due to failing tests on GitHub Actions - # ppc64le - # https://bugs.ruby-lang.org/issues/21534 - # - ubuntu-24.04-ppc64le - - ubuntu-24.04-s390x - # The ppc64le/s390x runners work only in the registered repositories. - # They don't work in forked repositories. - # https://github.com/IBM/actionspz/blob/main/docs/FAQ.md#what-about-forked-repos - upstream: - - ${{ github.repository == 'ruby/ruby' }} + # We enumerate every job in matrix.include to save build time include: - test_task: check configure: 'cppflags=-DVM_CHECK_MODE' @@ -52,14 +37,15 @@ jobs: - test_task: test-bundler-parallel timeout: 50 - test_task: test-bundled-gems - exclude: - - os: ubuntu-24.04-ppc64le - upstream: false - - os: ubuntu-24.04-s390x - upstream: false + - test_task: check + os: ubuntu-24.04 + extra_checks: [capi] + # ubuntu-24.04-arm jobs don't start on ruby/ruby as of 2025-10-29 + #- test_task: check + # os: ubuntu-24.04-arm fail-fast: false - env: + env: &make-env GITPULLOPTIONS: --no-tags origin ${{ github.ref }} RUBY_DEBUG: ci @@ -70,42 +56,27 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + steps: &make-steps + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - uses: ./.github/actions/setup/ubuntu with: arch: ${{ matrix.arch }} - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: '3.1' bundler: none - if: ${{ !endsWith(matrix.os, 'arm') && !endsWith(matrix.os, 'ppc64le') && !endsWith(matrix.os, 's390x') }} - - # Avoid possible test failures with the zlib applying the following patch - # on s390x CPU architecture. - # https://github.com/madler/zlib/pull/410 - - name: Disable DFLTCC - run: echo "DFLTCC=0" >> $GITHUB_ENV - working-directory: - if: ${{ endsWith(matrix.os, 's390x') }} - - # A temporary workaround: Set HOME env to pass the step - # ./.github/actions/setup/directories. - # https://github.com/IBM/actionspz/issues/30 - - name: Set HOME env - run: | - echo "HOME: #{HOME}" - echo "HOME=$(ls -d ~)" >> $GITHUB_ENV - working-directory: - if: ${{ endsWith(matrix.os, 'ppc64le') || endsWith(matrix.os, 's390x') }} + if: >- + ${{ !endsWith(matrix.os, 'arm') + && !endsWith(matrix.os, 'ppc64le') && !endsWith(matrix.os, 's390x') }} - uses: ./.github/actions/setup/directories with: @@ -122,7 +93,7 @@ jobs: arch: ${{ matrix.arch }} configure: ${{ matrix.configure }} run: >- - $SETARCH ../src/configure -C --disable-install-doc ${configure:-cppflags=-DRUBY_DEBUG} + $SETARCH ../src/configure -C --disable-install-doc ${configure:- --enable-debug-env cppflags=-DRUBY_DEBUG} ${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE} - run: $SETARCH make prepare-gems @@ -155,16 +126,12 @@ jobs: continue-on-error: true timeout-minutes: 3 - # A temporary workaround: Skip user ground id test - # There is a mismatch between the group IDs of "id -g" and C function - # getpwuid(uid_t uid) pw_gid. - # https://github.com/IBM/actionspz/issues/31 - - name: Skip user group id test - run: | - sed -i.orig '/^ it "returns user group id" do/a\ skip' \ - ../src/spec/ruby/library/etc/struct_passwd_spec.rb - diff -u ../src/spec/ruby/library/etc/struct_passwd_spec.rb{.orig,} || : - if: ${{ endsWith(matrix.os, 'ppc64le') || endsWith(matrix.os, 's390x') }} + # Avoid possible test failures with the zlib applying the following patch + # on s390x CPU architecture. + # https://github.com/madler/zlib/pull/410 + - name: Disable DFLTCC + run: echo "DFLTCC=0" >> $GITHUB_ENV + if: ${{ endsWith(matrix.os, 's390x') }} - name: make ${{ matrix.test_task }} run: | @@ -196,9 +163,100 @@ jobs: DESTDIR=${RUNNER_TEMP-${TMPDIR-/tmp}}/installed $SETARCH make test-pc "DESTDIR=$DESTDIR" + - name: CAPI extensions + uses: ./.github/actions/capiext + with: + builddir: build + make: '$SETARCH make' + env: + RUBY_TESTOPTS: '-v --tty=no' + if: ${{ contains(matrix.extra_checks, 'capi') }} + + - uses: ./.github/actions/slack + with: + label: ${{ matrix.test_task }} ${{ matrix.configure }}${{ matrix.arch }}${{ matrix.os }} + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() }} + + make-ibm: + strategy: + matrix: + include: + - test_task: check + os: ubuntu-24.04-ppc64le + - test_task: check + os: ubuntu-24.04-s390x + fail-fast: false + + env: *make-env + + runs-on: ${{ matrix.os }} + + if: >- + ${{github.repository == 'ruby/ruby' + && !(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Documentation') + || (github.event.pull_request.user.login == 'dependabot[bot]') + )}} + + steps: *make-steps + + # Separated from `make` job to avoid making it a required status check + ruby-bench: + strategy: + matrix: + include: + # Using the same setup as ZJIT jobs + - bench_opts: '--warmup=1 --bench=1 --excludes=shipit' + + runs-on: ubuntu-24.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Documentation') + || (github.event.pull_request.user.login == 'dependabot[bot]') + )}} + + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - 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" + + - run: make install + + - name: Checkout ruby-bench + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + repository: ruby/ruby-bench + persist-credentials: false + path: ruby-bench + + # If you want to skip failing benchmark, consider using `--excludes`. + # e.g. `bench_opts: '--warmup=1 --bench=1 --excludes=railsbench,lobsters'` + - name: Run ruby-bench + run: ruby run_benchmarks.rb -e "ruby::../build/install/bin/ruby" ${{ matrix.bench_opts }} + working-directory: ruby-bench + env: + BUNDLER_VERSION: 0 + - uses: ./.github/actions/slack with: - label: ${{ matrix.test_task }} ${{ matrix.configure }}${{ matrix.arch }} + label: ruby-bench ${{ matrix.bench_opts }} ${{ matrix.ruby_opts }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot if: ${{ failure() }} diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 1d1e4bc5a2..f0263de5ef 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -55,14 +55,20 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false + + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 + with: + ruby-version: '3.1' + bundler: none - uses: ./.github/actions/setup/directories with: @@ -98,19 +104,10 @@ jobs: run: | echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ./.github/actions/setup/baseruby + id: baseruby with: - ruby-version: '3.1' - bundler: none - - - name: Build baseruby - run: | - set -ex - mkdir ../baseruby - pushd ../baseruby - ../src/configure --prefix=$PWD/install - make - make install + srcdir: src - name: Download config.guess with wasi version run: | @@ -119,19 +116,38 @@ jobs: working-directory: src - 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 }}" + run: >- + ../src/configure + --host wasm32-unknown-wasi + --with-baseruby="${{ steps.baseruby.outputs.ruby }}" + --with-dump-ast="${{ steps.baseruby.outputs.dump_ast }}" + --with-static-linked-ext + --with-ext=${EXTS// /,} + 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 }}" + env: + EXTS: + cgi/escape + continuation + coverage + date + digest + digest/* + erb/escape + etc + fcntl + json + json/* + objspace + rbconfig/sizeof + ripper + stringio + strscan # miniruby may not be built when cross-compling - run: make mini ruby @@ -140,7 +156,7 @@ jobs: - run: tar cfz ../install.tar.gz -C ../install . - name: Upload artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ruby-wasm-install path: ${{ github.workspace }}/install.tar.gz @@ -168,7 +184,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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: ${{ github.event_name == 'pull_request' }} with: name: github-pr-info diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 3e85f7a1c5..03e75ad445 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -26,17 +26,16 @@ jobs: matrix: include: - os: 2022 - vc: 2022 test_task: check - - os: 2025 - vc: 2022 + - os: 2022 + test_task: test-bundled-gems + - os: 2025-vs2026 test_task: check + - os: 2025-vs2026 + test_task: test-bundled-gems - os: 11-arm test_task: 'btest test-basic test-tool' # check and test-spec are broken yet. target: arm64 - - os: 2025 - vc: 2022 - test_task: test-bundled-gems fail-fast: false runs-on: windows-${{ matrix.os }} @@ -46,10 +45,10 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/vcpkg')) )}} - name: Windows ${{ matrix.os }}/Visual C++ ${{ matrix.vc }} (${{ matrix.test_task }}) + name: Windows ${{ matrix.os }} (${{ matrix.test_task }}) env: GITPULLOPTIONS: --no-tags origin ${{ github.ref }} @@ -59,15 +58,16 @@ jobs: - run: md build working-directory: - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.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' }} bundler: none windows-toolchain: none - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: + persist-credentials: false sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -75,42 +75,52 @@ jobs: with: srcdir: src builddir: build + make-command: nmake + clean: true - name: Install tools with scoop run: | + if ((vcpkg.exe help install) -match "manifest") { exit } Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser iwr -useb get.scoop.sh | iex Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH - scoop install vcpkg uutils-coreutils cmake@3.31.6 + scoop install vcpkg shell: pwsh - name: Restore vcpkg artifact id: restore-vcpkg - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: src\vcpkg_installed key: windows-${{ matrix.os }}-vcpkg-${{ hashFiles('src/vcpkg.json') }} - name: Install libraries with vcpkg + id: build-vcpkg run: | - vcpkg install --vcpkg-root=%USERPROFILE%\scoop\apps\vcpkg\current + git -C "%VCPKG_INSTALLATION_ROOT%" pull --quiet + vcpkg install working-directory: src if: ${{ ! steps.restore-vcpkg.outputs.cache-hit }} - name: Save vcpkg artifact - uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: src\vcpkg_installed key: windows-${{ matrix.os }}-vcpkg-${{ hashFiles('src/vcpkg.json') }} - if: ${{ ! steps.restore-vcpkg.outputs.cache-hit && (github.ref_name == 'master' || startsWith(github.ref_name, 'ruby_')) }} + if: >- + steps.build-vcpkg.outcome == 'success' && + ( github.ref_name == 'master' + || startsWith(github.ref_name, 'ruby_') + || ( github.event.pull_request.user.login == 'dependabot[bot]' + && startsWith(github.head_ref || github.ref_name, 'dependabot/vcpkg')) + ) - 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 up VC ${{ matrix.vc }} - set | uutils sort > old.env + set > old.env call ..\src\win32\vssetup.cmd ^ -arch=${{ matrix.target || 'amd64' }} ^ ${{ matrix.vcvars && '-vcvars_ver=' || '' }}${{ matrix.vcvars }} @@ -120,9 +130,17 @@ jobs: set MAKEFLAGS=l set /a TEST_JOBS=(15 * %NUMBER_OF_PROCESSORS% / 10) > nul set RUBY_OPT_DIR=%GITHUB_WORKSPACE:\=/%/src/vcpkg_installed/%VCPKG_DEFAULT_TRIPLET% - set | uutils sort > new.env - uutils comm -13 old.env new.env >> %GITHUB_ENV% + set > new.env + + - name: update env + shell: pwsh + run: | + $old = (Get-Content old.env); $new = (Get-Content new.env) del *.env + Compare-Object $old $new | + Where-Object { $_.SideIndicator -eq '=>' } | + Select-Object -ExpandProperty InputObject | + Add-Content -Path $env:GITHUB_ENV - name: baseruby version run: ruby -v @@ -154,30 +172,9 @@ jobs: # windows-11-arm runner cannot run `ruby tool/file2lastrev.rb --revision.h --output=revision.h` - name: make revision.h run: | - if not exist revision.h ( - for /f "tokens=1-3" %%I in ('git log -1 "--date=format-local:%%F %%T" "--format=%%H %%cd" @') do ( - set rev=%%I - set dt=%%J - set tm=%%K - ) - call set yy=%%dt:~0,4%% - call set /a mm=100%%dt:~5,2%% %%%% 100 - call set /a dd=100%%dt:~8,2%% %%%% 100 - call set branch=%%GITHUB_REF:refs/heads/=%% - ( - call echo #define RUBY_REVISION "%%rev:~,10%%" - call echo #define RUBY_FULL_REVISION "%%rev%%" - call echo #define RUBY_BRANCH_NAME "%%branch%%" - call echo #define RUBY_RELEASE_DATETIME "%%dt%%T%%tm%%" - call echo #define RUBY_RELEASE_YEAR %%yy%% - call echo #define RUBY_RELEASE_MONTH %%mm%% - call echo #define RUBY_RELEASE_DAY %%dd%% - ) > revision.h - copy /y NUL .revision.time - ) + win32\lastrev.bat | win32\ifchange.bat --timestamp=.revision.time revision.h - type revision.h - env: - TZ: UTC + working-directory: src - run: nmake @@ -200,14 +197,14 @@ jobs: - uses: ./.github/actions/slack with: - label: Windows ${{ matrix.os }} / VC ${{ matrix.vc }} / ${{ matrix.test_task || 'check' }} + label: Windows ${{ matrix.os }} / ${{ matrix.test_task || 'check' }} 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: windows-latest + runs-on: windows-2025-vs2026 needs: [make] steps: - run: exit 1 diff --git a/.github/workflows/wsl.yml b/.github/workflows/wsl.yml index 640f18ce42..470b68fe66 100644 --- a/.github/workflows/wsl.yml +++ b/.github/workflows/wsl.yml @@ -14,16 +14,19 @@ on: # 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: +permissions: + contents: read + jobs: wsl: - runs-on: windows-2025 + runs-on: windows-2025-vs2026 if: >- ${{!(false || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: diff --git a/.github/workflows/yjit-macos.yml b/.github/workflows/yjit-macos.yml index 72ef599a39..e11de6bc51 100644 --- a/.github/workflows/yjit-macos.yml +++ b/.github/workflows/yjit-macos.yml @@ -1,4 +1,4 @@ -name: YJIT macOS Arm64 +name: YJIT macOS on: push: branches: @@ -30,18 +30,20 @@ jobs: cargo: name: cargo test - runs-on: macos-14 + runs-on: macos-26 if: >- ${{!(false || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - run: RUST_BACKTRACE=1 cargo test working-directory: yjit @@ -72,21 +74,22 @@ jobs: RUN_OPTS: ${{ matrix.yjit_opts }} SPECOPTS: ${{ matrix.specopts }} - runs-on: macos-14 + runs-on: macos-26 if: >- ${{!(false || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - name: Install libraries uses: ./.github/actions/setup/macos @@ -115,8 +118,10 @@ jobs: ruby -ne 'raise "Disassembly seems broken in dev build (output has too few lines)" unless $_.to_i > 10' if: ${{ contains(matrix.configure, 'jit=dev') }} - - name: Enable YJIT through ENV - run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV + - name: Set ENV for YJIT + run: | + echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV + echo "RUBY_CRASH_REPORT=$(pwd)/rb_crash_%p.txt" >> $GITHUB_ENV - name: Set test options for skipped tests run: | @@ -129,7 +134,7 @@ jobs: id: launchable uses: ./.github/actions/launchable/setup with: - os: macos-14 + os: macos-26 test-opts: ${{ matrix.configure }} launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} builddir: build @@ -143,6 +148,7 @@ jobs: test -n "${LAUNCHABLE_STDOUT}" && exec 1> >(tee "${LAUNCHABLE_STDOUT}") test -n "${LAUNCHABLE_STDERR}" && exec 2> >(tee "${LAUNCHABLE_STDERR}") + set -x make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} \ RUN_OPTS="$RUN_OPTS" \ SPECOPTS="$SPECOPTS" @@ -166,6 +172,13 @@ jobs: if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} continue-on-error: ${{ matrix.continue-on-skipped_tests || false }} + - name: Dump crash logs + if: ${{ failure() }} + continue-on-error: true + run: | + tail --verbose --lines=+1 rb_crash_*.txt + exit 1 + - uses: ./.github/actions/slack with: label: ${{ matrix.test_task }} ${{ matrix.configure }} ${{ matrix.yjit_opts }} @@ -175,7 +188,7 @@ jobs: result: if: ${{ always() }} name: ${{ github.workflow }} result - runs-on: macos-14 + runs-on: ubuntu-latest needs: [make] steps: - name: ${{ github.workflow }} jobs have failed diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml index 3b3b75faac..ab816940f4 100644 --- a/.github/workflows/yjit-ubuntu.yml +++ b/.github/workflows/yjit-ubuntu.yml @@ -32,11 +32,13 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false # For now we can't run cargo test --offline because it complains about the # capstone dependency, even though the dependency is optional @@ -64,11 +66,13 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false # Check that we don't have linting errors in release mode, too - run: cargo clippy --all-targets --all-features @@ -81,7 +85,8 @@ jobs: include: - test_task: 'yjit-bindgen' hint: 'To fix: use patch in logs' - configure: '--with-gcc=clang-14 --enable-yjit=dev' + # Build with YJIT+ZJIT for output that works in the most number of configurations + configure: '--with-gcc=clang-14 --enable-yjit=dev --enable-zjit' libclang_path: '/usr/lib/llvm-14/lib/libclang.so.1' - test_task: 'check' @@ -101,18 +106,12 @@ jobs: - 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 }} SPECOPTS: ${{ matrix.specopts }} RUBY_DEBUG: ci - BUNDLE_JOBS: 8 # for yjit-bench RUST_BACKTRACE: 1 runs-on: ubuntu-22.04 @@ -122,18 +121,19 @@ jobs: || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: '3.1' bundler: none @@ -151,6 +151,12 @@ jobs: if: ${{ matrix.rust_version }} run: rustup install ${{ matrix.rust_version }} --profile minimal + - name: Remove cargo + # Since this tests a `rustc` build for release, remove `cargo` to ensure + # that only `rustc` is used. + if: ${{ contains(matrix.configure, 'rustc') }} + run: sudo rm $(which -a cargo | uniq) + - name: Run configure run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install ${{ matrix.configure }} @@ -168,8 +174,10 @@ jobs: ruby -ne 'raise "Disassembly seems broken in dev build (output has too few lines)" unless $_.to_i > 10' if: ${{ contains(matrix.configure, 'jit=dev') }} - - name: Enable YJIT through ENV - run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV + - name: Set ENV for YJIT + run: | + echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV + echo "RUBY_CRASH_REPORT=$(pwd)/rb_crash_%p.txt" >> $GITHUB_ENV # Check that the binary was built with YJIT - name: Check YJIT enabled @@ -193,6 +201,7 @@ jobs: test -n "${LAUNCHABLE_STDOUT}" && exec 1> >(tee "${LAUNCHABLE_STDOUT}") test -n "${LAUNCHABLE_STDERR}" && exec 2> >(tee "${LAUNCHABLE_STDERR}") + set -x make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} \ RUN_OPTS="$RUN_OPTS" MSPECOPT=--debug SPECOPTS="$SPECOPTS" \ YJIT_BENCH_OPTS="$YJIT_BENCH_OPTS" YJIT_BINDGEN_DIFF_OPTS="$YJIT_BINDGEN_DIFF_OPTS" @@ -208,12 +217,12 @@ jobs: LAUNCHABLE_STDERR: ${{ steps.launchable.outputs.stderr_report_path }} 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') }} + - name: Dump crash logs + if: ${{ failure() }} + continue-on-error: true + run: | + tail --verbose --lines=+1 rb_crash_*.txt + exit 1 - uses: ./.github/actions/slack with: diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml index 41ff382382..707e50e36b 100644 --- a/.github/workflows/zjit-macos.yml +++ b/.github/workflows/zjit-macos.yml @@ -1,4 +1,4 @@ -name: ZJIT macOS Arm64 +name: ZJIT macOS on: push: branches: @@ -32,41 +32,48 @@ jobs: fail-fast: false matrix: include: - - test_task: 'zjit-check' + - test_task: 'check' + run_opts: '--zjit-call-threshold=1' + specopts: '-T --zjit-call-threshold=1' + configure: '--enable-zjit=dev' + + - test_task: 'check' + run_opts: '--zjit-disable-hir-opt --zjit-call-threshold=1' + specopts: '-T --zjit-disable-hir-opt -T --zjit-call-threshold=1' + configure: '--enable-zjit=dev' + + - test_task: 'zjit-check' # zjit-test + quick feedback of test_zjit.rb configure: '--enable-yjit=dev --enable-zjit' rust_version: "1.85.0" - - test_task: 'ruby' # build test for combo build + - test_task: 'ruby' + hint: 'combo build test' configure: '--enable-yjit --enable-zjit' - - test_task: 'zjit-test-all' - configure: '--enable-zjit=dev' - testopts: '--seed=11831' - - - test_task: 'btest' - configure: '--enable-zjit=dev' - env: GITPULLOPTIONS: --no-tags origin ${{ github.ref }} - RUN_OPTS: ${{ matrix.zjit_opts }} + RUN_OPTS: ${{ matrix.run_opts }} SPECOPTS: ${{ matrix.specopts }} TESTOPTS: ${{ matrix.testopts }} + RUST_BACKTRACE: 1 + ZJIT_RB_BUG: 1 - runs-on: macos-14 + runs-on: macos-26 if: >- ${{!(false || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - name: Install libraries uses: ./.github/actions/setup/macos @@ -86,7 +93,7 @@ jobs: rustup install ${{ matrix.rust_version }} --profile minimal rustup default ${{ matrix.rust_version }} - - uses: taiki-e/install-action@v2 + - uses: taiki-e/install-action@4bc351f7f2614e48088386e2a0ad917ca3a7e4ba # v2.81.5 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} @@ -94,9 +101,6 @@ jobs: - 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: Verify that --zjit-dump-disasm works @@ -106,71 +110,130 @@ jobs: ruby -ne 'raise "Disassembly seems broken in dev build (output has too few lines)" unless $_.to_i > 10' if: ${{ contains(matrix.configure, 'jit=dev') }} - - name: btest + - name: Set ENV for ZJIT run: | - RUST_BACKTRACE=1 ruby --disable=gems ../src/bootstraptest/runner.rb --ruby="./miniruby -I../src/lib -I. -I.ext/common --zjit-call-threshold=1" \ - ../src/bootstraptest/test_attr.rb \ - ../src/bootstraptest/test_autoload.rb \ - ../src/bootstraptest/test_block.rb \ - ../src/bootstraptest/test_class.rb \ - ../src/bootstraptest/test_constant_cache.rb \ - ../src/bootstraptest/test_env.rb \ - ../src/bootstraptest/test_eval.rb \ - ../src/bootstraptest/test_exception.rb \ - ../src/bootstraptest/test_fiber.rb \ - ../src/bootstraptest/test_finalizer.rb \ - ../src/bootstraptest/test_flip.rb \ - ../src/bootstraptest/test_flow.rb \ - ../src/bootstraptest/test_fork.rb \ - ../src/bootstraptest/test_gc.rb \ - ../src/bootstraptest/test_insns.rb \ - ../src/bootstraptest/test_io.rb \ - ../src/bootstraptest/test_jump.rb \ - ../src/bootstraptest/test_literal.rb \ - ../src/bootstraptest/test_literal_suffix.rb \ - ../src/bootstraptest/test_load.rb \ - ../src/bootstraptest/test_marshal.rb \ - ../src/bootstraptest/test_massign.rb \ - ../src/bootstraptest/test_method.rb \ - ../src/bootstraptest/test_objectspace.rb \ - ../src/bootstraptest/test_proc.rb \ - ../src/bootstraptest/test_ractor.rb \ - ../src/bootstraptest/test_string.rb \ - ../src/bootstraptest/test_struct.rb \ - ../src/bootstraptest/test_syntax.rb \ - ../src/bootstraptest/test_thread.rb \ - ../src/bootstraptest/test_yjit_30k_ifelse.rb \ - ../src/bootstraptest/test_yjit_30k_methods.rb \ - ../src/bootstraptest/test_yjit_rust_port.rb - # ../src/bootstraptest/test_yjit.rb \ - if: ${{ matrix.test_task == 'btest' }} + echo "RUBY_CRASH_REPORT=$(pwd)/rb_crash_%p.txt" >> $GITHUB_ENV + + - name: Set up Launchable + id: launchable + uses: ./.github/actions/launchable/setup + with: + os: macos-26 + test-opts: ${{ matrix.configure }} + launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} + builddir: build + srcdir: src + is-zjit: true + continue-on-error: true + timeout-minutes: 3 - name: make ${{ matrix.test_task }} - run: >- - make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} - RUN_OPTS="$RUN_OPTS" - SPECOPTS="$SPECOPTS" - TESTOPTS="$TESTOPTS" + run: | + test -n "${LAUNCHABLE_STDOUT}" && exec 1> >(tee "${LAUNCHABLE_STDOUT}") + test -n "${LAUNCHABLE_STDERR}" && exec 2> >(tee "${LAUNCHABLE_STDERR}") + + set -x + make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} \ + RUN_OPTS="$RUN_OPTS" \ + SPECOPTS="$SPECOPTS" \ + TESTOPTS="$TESTOPTS" timeout-minutes: 60 env: RUBY_TESTOPTS: '-q --tty=no' + EXCLUDES: '../src/test/.excludes-zjit' TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' - SYNTAX_SUGGEST_TIMEOUT: '5' + SYNTAX_SUGGEST_TIMEOUT: '30' PRECHECK_BUNDLED_GEMS: 'no' - TESTS: ${{ matrix.tests }} + LAUNCHABLE_STDOUT: ${{ steps.launchable.outputs.stdout_report_path }} + LAUNCHABLE_STDERR: ${{ steps.launchable.outputs.stderr_report_path }} continue-on-error: ${{ matrix.continue-on-test_task || false }} - if: ${{ matrix.test_task != 'btest' }} + + - name: Dump crash logs + if: ${{ failure() }} + continue-on-error: true + run: | + tail --verbose --lines=+1 rb_crash_*.txt + exit 1 + + - 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: macos-14 + runs-on: ubuntu-latest needs: [make] steps: - run: exit 1 working-directory: if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + # Separated from `make` job to avoid making it a required status check for now + ruby-bench: + strategy: + matrix: + include: + # Test --call-threshold=2 with 2 iterations in total + - ruby_opts: '--zjit-call-threshold=2' + bench_opts: '--warmup=1 --bench=1 --excludes=shipit' + configure: '--enable-zjit=dev_nodebug' # --enable-zjit=dev is too slow + + runs-on: macos-26 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Documentation') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) + )}} + + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - uses: ./.github/actions/setup/macos + + - 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" ${{ matrix.configure }} + + - run: make install + + # setup/directories set MAKEFLAGS=-j4 for macOS, which randomly fails sqlite3.gem builds + - name: Unset MAKEFLAGS + run: echo "MAKEFLAGS=" >> "$GITHUB_ENV" + + - name: Checkout ruby-bench + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + repository: ruby/ruby-bench + path: ruby-bench + + # If you want to skip failing benchmark, consider using `--excludes`. + # e.g. `bench_opts: '--warmup=1 --bench=1 --excludes=railsbench,lobsters'` + - name: Run ruby-bench + run: ruby run_benchmarks.rb -e "zjit::../build/install/bin/ruby ${{ matrix.ruby_opts }}" ${{ matrix.bench_opts }} + working-directory: ruby-bench + env: + BUNDLER_VERSION: 0 + + - uses: ./.github/actions/slack + with: + label: ruby-bench ${{ matrix.bench_opts }} ${{ matrix.ruby_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/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index 4b0e0dbd5c..1c3e3f6531 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -27,66 +27,103 @@ permissions: contents: read jobs: + lint: + name: cargo clippy + + runs-on: ubuntu-22.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Documentation') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) + )}} + + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - run: cargo clippy --all-targets --all-features + working-directory: zjit + make: strategy: fail-fast: false matrix: include: - - test_task: 'zjit-bindgen' - hint: 'To fix: use patch in logs' - configure: '--enable-zjit=dev --with-gcc=clang-14' - libclang_path: '/usr/lib/llvm-14/lib/libclang.so.1' + - test_task: 'check' + run_opts: '--zjit-call-threshold=1' + specopts: '-T --zjit-call-threshold=1' + configure: '--enable-zjit=dev' - - test_task: 'zjit-check' + - test_task: 'check' + run_opts: '--zjit-disable-hir-opt --zjit-call-threshold=1' + specopts: '-T --zjit-disable-hir-opt -T --zjit-call-threshold=1' + configure: '--enable-zjit=dev' + + # The optimizer benefits from at least 1 iteration of profiling. Also, many + # regression tests in bootstraptest/test_yjit.rb assume call-threshold=2. + - test_task: 'btest' + run_opts: '--zjit-call-threshold=2' + configure: '--enable-zjit=dev' + + - test_task: 'zjit-check' # zjit-test + quick feedback of test_zjit.rb configure: '--enable-yjit --enable-zjit=dev' rust_version: '1.85.0' - - test_task: 'zjit-test-all' - configure: '--enable-zjit=dev' - testopts: '--seed=18140' + - test_task: 'zjit-bindgen' + hint: 'To fix: use patch in logs' + # Build with YJIT+ZJIT for output that works in the most number of configurations + configure: '--enable-zjit=dev --enable-yjit --with-gcc=clang-16' + clang_path: '/usr/bin/clang-16' + runs-on: 'ubuntu-24.04' # for clang-16 - - test_task: 'btest' + - test_task: 'test-bundled-gems' configure: '--enable-zjit=dev' + run_opts: '--zjit-call-threshold=1' env: GITPULLOPTIONS: --no-tags origin ${{ github.ref }} - RUN_OPTS: ${{ matrix.zjit_opts }} + RUN_OPTS: ${{ matrix.run_opts }} YJIT_BENCH_OPTS: ${{ matrix.yjit_bench_opts }} SPECOPTS: ${{ matrix.specopts }} TESTOPTS: ${{ matrix.testopts }} RUBY_DEBUG: ci BUNDLE_JOBS: 8 # for yjit-bench RUST_BACKTRACE: 1 + ZJIT_RB_BUG: 1 - runs-on: ubuntu-22.04 + runs-on: ${{ matrix.runs-on || 'ubuntu-22.04' }} if: >- ${{!(false || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) )}} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: sparse-checkout-cone-mode: false sparse-checkout: /.github + persist-credentials: false - uses: ./.github/actions/setup/ubuntu - - uses: ruby/setup-ruby@a9bfc2ecf3dd40734a9418f89a7e9d484c32b990 # v1.248.0 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: '3.1' bundler: none - - uses: taiki-e/install-action@v2 + - uses: taiki-e/install-action@4bc351f7f2614e48088386e2a0ad917ca3a7e4ba # v2.81.5 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} - - uses: ./.github/actions/setup/directories with: srcdir: src @@ -128,62 +165,58 @@ jobs: run: ./miniruby --zjit -v | grep "+ZJIT" if: ${{ matrix.configure != '--disable-zjit' }} - - name: btest + - name: Set ENV for ZJIT run: | - RUST_BACKTRACE=1 ruby --disable=gems ../src/bootstraptest/runner.rb --ruby="./miniruby -I../src/lib -I. -I.ext/common --zjit-call-threshold=1" \ - ../src/bootstraptest/test_attr.rb \ - ../src/bootstraptest/test_autoload.rb \ - ../src/bootstraptest/test_block.rb \ - ../src/bootstraptest/test_class.rb \ - ../src/bootstraptest/test_constant_cache.rb \ - ../src/bootstraptest/test_env.rb \ - ../src/bootstraptest/test_env.rb \ - ../src/bootstraptest/test_exception.rb \ - ../src/bootstraptest/test_fiber.rb \ - ../src/bootstraptest/test_finalizer.rb \ - ../src/bootstraptest/test_flip.rb \ - ../src/bootstraptest/test_flow.rb \ - ../src/bootstraptest/test_fork.rb \ - ../src/bootstraptest/test_gc.rb \ - ../src/bootstraptest/test_insns.rb \ - ../src/bootstraptest/test_io.rb \ - ../src/bootstraptest/test_jump.rb \ - ../src/bootstraptest/test_literal.rb \ - ../src/bootstraptest/test_literal_suffix.rb \ - ../src/bootstraptest/test_load.rb \ - ../src/bootstraptest/test_marshal.rb \ - ../src/bootstraptest/test_massign.rb \ - ../src/bootstraptest/test_method.rb \ - ../src/bootstraptest/test_objectspace.rb \ - ../src/bootstraptest/test_proc.rb \ - ../src/bootstraptest/test_ractor.rb \ - ../src/bootstraptest/test_string.rb \ - ../src/bootstraptest/test_struct.rb \ - ../src/bootstraptest/test_syntax.rb \ - ../src/bootstraptest/test_thread.rb \ - ../src/bootstraptest/test_yjit_30k_ifelse.rb \ - ../src/bootstraptest/test_yjit_30k_methods.rb \ - ../src/bootstraptest/test_yjit_rust_port.rb - # ../src/bootstraptest/test_yjit.rb \ - if: ${{ matrix.test_task == 'btest' }} + echo "RUBY_CRASH_REPORT=$(pwd)/rb_crash_%p.txt" >> $GITHUB_ENV + + - name: Set up Launchable + id: launchable + uses: ./.github/actions/launchable/setup + with: + os: ${{ matrix.runs-on || 'ubuntu-22.04' }} + test-opts: ${{ matrix.configure }} + launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} + builddir: build + srcdir: src + is-zjit: true + continue-on-error: true + timeout-minutes: 3 - name: make ${{ matrix.test_task }} - run: >- - make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} - RUN_OPTS="$RUN_OPTS" MSPECOPT=--debug SPECOPTS="$SPECOPTS" - TESTOPTS="$TESTOPTS" - ZJIT_BINDGEN_DIFF_OPTS="$ZJIT_BINDGEN_DIFF_OPTS" + run: | + test -n "${LAUNCHABLE_STDOUT}" && exec 1> >(tee "${LAUNCHABLE_STDOUT}") + test -n "${LAUNCHABLE_STDERR}" && exec 2> >(tee "${LAUNCHABLE_STDERR}") + + set -x + make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} \ + RUN_OPTS="$RUN_OPTS" MSPECOPT=--debug SPECOPTS="$SPECOPTS" \ + TESTOPTS="$TESTOPTS" \ + ZJIT_BINDGEN_DIFF_OPTS="$ZJIT_BINDGEN_DIFF_OPTS" timeout-minutes: 90 env: RUBY_TESTOPTS: '-q --tty=no' + EXCLUDES: '../src/test/.excludes-zjit' TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' PRECHECK_BUNDLED_GEMS: 'no' - SYNTAX_SUGGEST_TIMEOUT: '5' + SYNTAX_SUGGEST_TIMEOUT: '30' ZJIT_BINDGEN_DIFF_OPTS: '--exit-code' - LIBCLANG_PATH: ${{ matrix.libclang_path }} - TESTS: ${{ matrix.tests }} + CLANG_PATH: ${{ matrix.clang_path }} + LAUNCHABLE_STDOUT: ${{ steps.launchable.outputs.stdout_report_path }} + LAUNCHABLE_STDERR: ${{ steps.launchable.outputs.stderr_report_path }} continue-on-error: ${{ matrix.continue-on-test_task || false }} - if: ${{ matrix.test_task != 'btest' }} + + - name: Dump crash logs + if: ${{ failure() }} + continue-on-error: true + run: | + tail --verbose --lines=+1 rb_crash_*.txt + exit 1 + + - 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() }} @@ -196,6 +229,65 @@ jobs: working-directory: if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + # Separated from `make` job to avoid making it a required status check for now + ruby-bench: + strategy: + matrix: + include: + # Test --call-threshold=2 with 2 iterations in total + - ruby_opts: '--zjit-call-threshold=2' + bench_opts: '--warmup=1 --bench=1 --excludes=shipit' + configure: '--enable-zjit=dev_nodebug' # --enable-zjit=dev is too slow + + runs-on: ubuntu-24.04 + + if: >- + ${{!(false + || contains(github.event.head_commit.message, '[DOC]') + || contains(github.event.pull_request.title, '[DOC]') + || contains(github.event.pull_request.labels.*.name, 'Documentation') + || (github.event.pull_request.user.login == 'dependabot[bot]' && !startsWith(github.head_ref, 'dependabot/cargo')) + )}} + + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - 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" ${{ matrix.configure }} + + - run: make install + + - name: Checkout ruby-bench + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + repository: ruby/ruby-bench + persist-credentials: false + path: ruby-bench + + # If you want to skip failing benchmark, consider using `--excludes`. + # e.g. `bench_opts: '--warmup=1 --bench=1 --excludes=railsbench,lobsters'` + - name: Run ruby-bench + run: ruby run_benchmarks.rb -e "zjit::../build/install/bin/ruby ${{ matrix.ruby_opts }}" ${{ matrix.bench_opts }} + working-directory: ruby-bench + env: + BUNDLER_VERSION: 0 + + - uses: ./.github/actions/slack + with: + label: ruby-bench ${{ matrix.bench_opts }} ${{ matrix.ruby_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/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000000..2a8cad1d5c --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,33 @@ +# Ignore existing findings (baseline) +# Composite action findings are suppressed inline with # zizmor: ignore +rules: + artipacked: + # These jobs push back to the repo and need persisted credentials. + ignore: + - bundled_gems.yml + - default_gems_list.yml + - post_push.yml + - sync_default_gems.yml + dangerous-triggers: + ignore: + - auto_request_review.yml + - auto_review_pr.yml + - labeler.yml + - pr-playground.yml + dependabot-cooldown: + ignore: + - dependabot.yml + misfeature: + ignore: + - mingw.yml + - tarball-windows.yml + - windows.yml + unpinned-images: + ignore: + - compilers.yml + secrets-outside-env: + # All committers with write access are trusted; no need for environment-scoped secrets. + disable: true + unpinned-uses: + ignore: + - wsl.yml |
