diff --git a/.github/actions/setup-mise/action.yml b/.github/actions/setup-mise/action.yml new file mode 100644 index 000000000..4eeae03a6 --- /dev/null +++ b/.github/actions/setup-mise/action.yml @@ -0,0 +1,25 @@ +name: Set up mise Ruby toolchain +description: >- + Install all the CI matrix Rubies via mise with the per-version bundler pins from + .mise.ci.toml (MISE_ENV=ci) — the same toolchain bin/test and bin/relock use. + Config + cache key are shared across every caller (the *_test workflows and + update_lockfiles), so they all restore the one weekly-populated cache. + +runs: + using: composite + steps: + - uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0 + env: + MISE_ENV: ci + MISE_JOBS: "2" + with: + install: true + cache: true + + # Precompiled rubies bake a nonexistent build path into RbConfig["PKG_CONFIG"] + # (jdx/ruby#48), breaking native gems like sqlite3. Reset it to PATH's pkg-config. + - name: Fix baked PKG_CONFIG path in precompiled rubies + shell: bash + run: | + find ~/.local/share/mise/installs/ruby -name rbconfig.rb \ + -exec sed -i 's#\(CONFIG\["PKG_CONFIG"\] = \).*#\1"pkg-config"#' {} + diff --git a/.github/workflows/gem_test.yml b/.github/workflows/gem_test.yml new file mode 100644 index 000000000..9a883767c --- /dev/null +++ b/.github/workflows/gem_test.yml @@ -0,0 +1,73 @@ +name: Gem Test + +# Reusable, gem-agnostic test workflow. tests.yml invokes it once per gem via a +# central matrix, passing the gem dir plus whatever optional service/packages +# that gem needs. The per-cell matrix still comes from each gem's +# test-matrix.json (the single source of truth), expanded here and run via +# bin/test — so adding/removing a cell never touches this file. + +on: + workflow_call: + inputs: + gem: + description: Gem directory to test (e.g. sentry-ruby). + required: true + type: string + apt: + description: Space-separated apt packages to install before testing. + type: string + default: "" + +jobs: + matrix: + runs-on: ubuntu-latest + outputs: + include: ${{ steps.set.outputs.include }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - id: set + run: echo "include=$(jq -c . ${{ inputs.gem }}/test-matrix.json)" >> "$GITHUB_OUTPUT" + + test: + needs: matrix + defaults: + run: + working-directory: ${{ inputs.gem }} + name: ${{ toJson(matrix) }} + runs-on: ubuntu-latest + timeout-minutes: 10 + services: + redis: + image: ghcr.io/getsentry/image-mirror-library-redis:7.0.8-bullseye + ports: + - 6379:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.matrix.outputs.include) }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Install apt packages + if: inputs.apt != '' + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends ${{ inputs.apt }} + + - name: Set up Ruby + uses: ./.github/actions/setup-mise + + - name: Run specs + env: + MATRIX_ENTRY: ${{ toJson(matrix) }} + run: ruby ../bin/test --entry "$MATRIX_ENTRY" --rake + + - name: Upload Coverage + uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/sentry_delayed_job_test.yml b/.github/workflows/sentry_delayed_job_test.yml deleted file mode 100644 index 6fb7f7f09..000000000 --- a/.github/workflows/sentry_delayed_job_test.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: sentry-delayed_job Test - -on: - workflow_dispatch: - workflow_call: - outputs: - matrix-result: - description: "Matrix job result" - value: ${{ jobs.test.outputs.matrix-result }} -# Cancel in progress workflows on pull_requests. -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: sentry-delayed-job-test-${{ github.head_ref || github.run_id }} - cancel-in-progress: true -jobs: - matrix: - runs-on: ubuntu-latest - outputs: - include: ${{ steps.set.outputs.include }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # test-matrix.json is the single source of truth for this gem's matrix. - - id: set - run: echo "include=$(jq -c . sentry-delayed_job/test-matrix.json)" >> "$GITHUB_OUTPUT" - - test: - needs: matrix - defaults: - run: - working-directory: sentry-delayed_job - name: Ruby ${{ matrix.ruby_version }}, options - ${{ toJson(matrix.options) }} - runs-on: ubuntu-latest - timeout-minutes: 10 - env: - RUBYOPT: ${{ matrix.options.rubyopt }} - # Pin via the wrapper gemfile + its sibling .gemfile.lock (BUNDLE_LOCKFILE is unsupported on older bundlers). - BUNDLE_GEMFILE: ${{ github.workspace }}/sentry-delayed_job/gemfiles/ruby-${{ matrix.ruby_version }}.gemfile - BUNDLE_FROZEN: "true" - BUNDLE_WITHOUT: rubocop - JRUBY_OPTS: "--debug" # for more accurate test coverage - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.matrix.outputs.include) }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - name: Install sqlite - run: | - # See https://github.community/t5/GitHub-Actions/ubuntu-latest-Apt-repository-list-issues/td-p/41122/page/2 - for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - sudo apt-get update - sudo apt-get install libsqlite3-dev - - # Wrapper keys the lock to this cell (.gemfile -> .gemfile.lock); must exist before setup-ruby. - - name: Write wrapper gemfile - run: | - mkdir -p gemfiles - echo 'eval_gemfile "../Gemfile"' > "$BUNDLE_GEMFILE" - - - name: Set up Ruby ${{ matrix.ruby_version }} - uses: ruby/setup-ruby@319994f95fa847cf3fb3cd3dbe89f6dcde9f178f # v1 - with: - ruby-version: ${{ matrix.ruby_version }} - bundler: latest - bundler-cache: true - - - name: Run specs - run: bundle exec rake - - - name: Upload Coverage - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/sentry_opentelemetry_test.yml b/.github/workflows/sentry_opentelemetry_test.yml deleted file mode 100644 index 4c95762b7..000000000 --- a/.github/workflows/sentry_opentelemetry_test.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: sentry-opentelemetry Test - -on: - workflow_dispatch: - workflow_call: - outputs: - matrix-result: - description: "Matrix job result" - value: ${{ jobs.test.outputs.matrix-result }} -# Cancel in progress workflows on pull_requests. -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: sentry-opentelemetry-test-${{ github.head_ref || github.run_id }} - cancel-in-progress: true -jobs: - matrix: - runs-on: ubuntu-latest - outputs: - include: ${{ steps.set.outputs.include }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # test-matrix.json is the single source of truth for this gem's matrix. - - id: set - run: echo "include=$(jq -c . sentry-opentelemetry/test-matrix.json)" >> "$GITHUB_OUTPUT" - - test: - needs: matrix - defaults: - run: - working-directory: sentry-opentelemetry - name: Ruby ${{ matrix.ruby_version }} & OpenTelemetry ${{ matrix.opentelemetry_version }}, options - ${{ toJson(matrix.options) }} - runs-on: ubuntu-latest - timeout-minutes: 10 - env: - RUBYOPT: ${{ matrix.options.rubyopt }} - # Pin via the wrapper gemfile + its sibling .gemfile.lock (BUNDLE_LOCKFILE is unsupported on older bundlers). - BUNDLE_GEMFILE: ${{ github.workspace }}/sentry-opentelemetry/gemfiles/ruby-${{ matrix.ruby_version }}.gemfile - BUNDLE_FROZEN: "true" - BUNDLE_WITHOUT: rubocop - OPENTELEMETRY_VERSION: ${{ matrix.opentelemetry_version }} - JRUBY_OPTS: "--debug" # for more accurate test coverage - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.matrix.outputs.include) }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - # Wrapper keys the lock to this cell (.gemfile -> .gemfile.lock); must exist before setup-ruby. - - name: Write wrapper gemfile - run: | - mkdir -p gemfiles - echo 'eval_gemfile "../Gemfile"' > "$BUNDLE_GEMFILE" - - - name: Set up Ruby ${{ matrix.ruby_version }} - uses: ruby/setup-ruby@319994f95fa847cf3fb3cd3dbe89f6dcde9f178f # v1 - with: - ruby-version: ${{ matrix.ruby_version }} - bundler: latest - bundler-cache: true - - - name: Run specs - run: bundle exec rake - - - name: Upload Coverage - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/sentry_rails_test.yml b/.github/workflows/sentry_rails_test.yml deleted file mode 100644 index caa869a08..000000000 --- a/.github/workflows/sentry_rails_test.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: sentry-rails Test - -on: - workflow_dispatch: - workflow_call: -# Cancel in progress workflows on pull_requests. -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: sentry-rails-test-${{ github.head_ref || github.run_id }} - cancel-in-progress: true -jobs: - matrix: - runs-on: ubuntu-latest - outputs: - include: ${{ steps.set.outputs.include }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # test-matrix.json is the single source of truth for this gem's matrix. - - id: set - run: echo "include=$(jq -c . sentry-rails/test-matrix.json)" >> "$GITHUB_OUTPUT" - - test: - needs: matrix - defaults: - run: - working-directory: sentry-rails - name: Ruby ${{ matrix.ruby_version }} & Rails ${{ matrix.rails_version }}, options - ${{ toJson(matrix.options) }} - runs-on: ubuntu-latest - timeout-minutes: 10 - env: - RUBYOPT: ${{ matrix.options.rubyopt }} - # Pin via the wrapper gemfile + its sibling .gemfile.lock (BUNDLE_LOCKFILE is unsupported on older bundlers). - BUNDLE_GEMFILE: ${{ github.workspace }}/sentry-rails/gemfiles/ruby-${{ matrix.ruby_version }}_rails-${{ matrix.rails_version }}.gemfile - BUNDLE_FROZEN: "true" - BUNDLE_WITHOUT: rubocop - RAILS_VERSION: ${{ matrix.rails_version }} - JRUBY_OPTS: "--debug" # for more accurate test coverage - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.matrix.outputs.include) }} - - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - name: Install sqlite and ImageMagick - run: | - # See https://github.community/t5/GitHub-Actions/ubuntu-latest-Apt-repository-list-issues/td-p/41122/page/2 - for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - sudo apt-get update - sudo apt-get install --no-install-recommends libsqlite3-dev imagemagick - # Wrapper keys the lock to this cell (.gemfile -> .gemfile.lock); must exist before setup-ruby. - - name: Write wrapper gemfile - run: | - mkdir -p gemfiles - echo 'eval_gemfile "../Gemfile"' > "$BUNDLE_GEMFILE" - - name: Set up Ruby ${{ matrix.ruby_version }} - uses: ruby/setup-ruby@319994f95fa847cf3fb3cd3dbe89f6dcde9f178f # v1 - with: - ruby-version: ${{ matrix.ruby_version }} - bundler: latest - bundler-cache: true - - - name: Build with Rails ${{ matrix.rails_version }} - run: bundle exec rake - - - name: Upload Coverage - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/sentry_resque_test.yml b/.github/workflows/sentry_resque_test.yml deleted file mode 100644 index de40c61ff..000000000 --- a/.github/workflows/sentry_resque_test.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: sentry-resque Test - -on: - workflow_dispatch: - workflow_call: - outputs: - matrix-result: - description: "Matrix job result" - value: ${{ jobs.test.outputs.matrix-result }} -# Cancel in progress workflows on pull_requests. -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: sentry-resque-test-${{ github.head_ref || github.run_id }} - cancel-in-progress: true -jobs: - matrix: - runs-on: ubuntu-latest - outputs: - include: ${{ steps.set.outputs.include }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # test-matrix.json is the single source of truth for this gem's matrix. - - id: set - run: echo "include=$(jq -c . sentry-resque/test-matrix.json)" >> "$GITHUB_OUTPUT" - - test: - needs: matrix - defaults: - run: - working-directory: sentry-resque - name: Ruby ${{ matrix.ruby_version }}, options - ${{ toJson(matrix.options) }} - runs-on: ubuntu-latest - timeout-minutes: 10 - services: - redis: - image: ghcr.io/getsentry/image-mirror-library-redis:7.0.8-bullseye - ports: - - 6379:6379 - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - env: - RUBYOPT: ${{ matrix.options.rubyopt }} - # Pin via the wrapper gemfile + its sibling .gemfile.lock (BUNDLE_LOCKFILE is unsupported on older bundlers). - BUNDLE_GEMFILE: ${{ github.workspace }}/sentry-resque/gemfiles/ruby-${{ matrix.ruby_version }}.gemfile - BUNDLE_FROZEN: "true" - BUNDLE_WITHOUT: rubocop - JRUBY_OPTS: "--debug" # for more accurate test coverage - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.matrix.outputs.include) }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # Wrapper keys the lock to this cell (.gemfile -> .gemfile.lock); must exist before setup-ruby. - - name: Write wrapper gemfile - run: | - mkdir -p gemfiles - echo 'eval_gemfile "../Gemfile"' > "$BUNDLE_GEMFILE" - - name: Set up Ruby ${{ matrix.ruby_version }} - uses: ruby/setup-ruby@319994f95fa847cf3fb3cd3dbe89f6dcde9f178f # v1 - with: - ruby-version: ${{ matrix.ruby_version }} - bundler: latest - bundler-cache: true - - - name: Run specs without Rails - env: - RUBYOPT: ${{ matrix.options.rubyopt }} - run: BUNDLE_WITHOUT="rubocop rails" bundle exec rake - - - name: Run specs with Rails - env: - RUBYOPT: ${{ matrix.options.rubyopt }} - run: bundle exec rake - - - name: Upload Coverage - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/sentry_ruby_test.yml b/.github/workflows/sentry_ruby_test.yml deleted file mode 100644 index b150da809..000000000 --- a/.github/workflows/sentry_ruby_test.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: sentry-ruby Test - -on: - workflow_dispatch: - workflow_call: -# Cancel in progress workflows on pull_requests. -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: sentry-ruby-test-${{ github.head_ref || github.run_id }} - cancel-in-progress: true -jobs: - matrix: - runs-on: ubuntu-latest - outputs: - include: ${{ steps.set.outputs.include }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # test-matrix.json is the single source of truth for this gem's matrix. - - id: set - run: echo "include=$(jq -c . sentry-ruby/test-matrix.json)" >> "$GITHUB_OUTPUT" - - test: - needs: matrix - defaults: - run: - working-directory: sentry-ruby - name: Ruby ${{ matrix.ruby_version }} & Rack ${{ matrix.rack_version }}, options - ${{ toJson(matrix.options) }} - runs-on: ubuntu-latest - timeout-minutes: 10 - services: - redis: - image: ghcr.io/getsentry/image-mirror-library-redis:7.0.8-bullseye - ports: - - 6379:6379 - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - env: - RUBYOPT: ${{ matrix.options.rubyopt }} - # Pin via the wrapper gemfile + its sibling .gemfile.lock (BUNDLE_LOCKFILE is unsupported on older bundlers). - BUNDLE_GEMFILE: ${{ github.workspace }}/sentry-ruby/gemfiles/ruby-${{ matrix.ruby_version }}_rack-${{ matrix.rack_version }}_redis-${{ matrix.redis_rb_version }}.gemfile - BUNDLE_FROZEN: "true" - BUNDLE_WITHOUT: rubocop - RACK_VERSION: ${{ matrix.rack_version }} - REDIS_RB_VERSION: ${{ matrix.redis_rb_version }} - JRUBY_OPTS: "--debug" # for more accurate test coverage - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.matrix.outputs.include) }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - # Wrapper keys the lock to this cell (.gemfile -> .gemfile.lock); must exist before setup-ruby. - - name: Write wrapper gemfile - run: | - mkdir -p gemfiles - echo 'eval_gemfile "../Gemfile"' > "$BUNDLE_GEMFILE" - - - name: Set up Ruby ${{ matrix.ruby_version }} - uses: ruby/setup-ruby@319994f95fa847cf3fb3cd3dbe89f6dcde9f178f # v1 - with: - ruby-version: ${{ matrix.ruby_version }} - bundler: latest - bundler-cache: true - - - name: Run specs with Rack ${{ matrix.rack_version }} and redis-rb ${{ matrix.redis_rb_version }} - run: bundle exec rake - - - name: Upload Coverage - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/sentry_sidekiq_test.yml b/.github/workflows/sentry_sidekiq_test.yml deleted file mode 100644 index 2bc17add6..000000000 --- a/.github/workflows/sentry_sidekiq_test.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: sentry-sidekiq Test - -on: - workflow_dispatch: - workflow_call: - outputs: - matrix-result: - description: "Matrix job result" - value: ${{ jobs.test.outputs.matrix-result }} -# Cancel in progress workflows on pull_requests. -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true -jobs: - matrix: - runs-on: ubuntu-latest - outputs: - include: ${{ steps.set.outputs.include }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # test-matrix.json is the single source of truth for this gem's matrix. - - id: set - run: echo "include=$(jq -c . sentry-sidekiq/test-matrix.json)" >> "$GITHUB_OUTPUT" - - test: - needs: matrix - defaults: - run: - working-directory: sentry-sidekiq - name: Ruby ${{ matrix.ruby_version }} & Sidekiq ${{ matrix.sidekiq_version }}, options - ${{ toJson(matrix.options) }} - runs-on: ubuntu-latest - timeout-minutes: 10 - services: - redis: - image: ghcr.io/getsentry/image-mirror-library-redis:7.0.8-bullseye - ports: - - 6379:6379 - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - env: - RUBYOPT: ${{ matrix.options.rubyopt }} - # Pin via the wrapper gemfile + its sibling .gemfile.lock (BUNDLE_LOCKFILE is unsupported on older bundlers). - BUNDLE_GEMFILE: ${{ github.workspace }}/sentry-sidekiq/gemfiles/ruby-${{ matrix.ruby_version }}_sidekiq-${{ matrix.sidekiq_version }}.gemfile - BUNDLE_FROZEN: "true" - BUNDLE_WITHOUT: rubocop - SIDEKIQ_VERSION: ${{ matrix.sidekiq_version }} - JRUBY_OPTS: "--debug" # for more accurate test coverage - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.matrix.outputs.include) }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - # Wrapper keys the lock to this cell (.gemfile -> .gemfile.lock); must exist before setup-ruby. - - name: Write wrapper gemfile - run: | - mkdir -p gemfiles - echo 'eval_gemfile "../Gemfile"' > "$BUNDLE_GEMFILE" - - - name: Set up Ruby ${{ matrix.ruby_version }} - uses: ruby/setup-ruby@319994f95fa847cf3fb3cd3dbe89f6dcde9f178f # v1 - with: - ruby-version: ${{ matrix.ruby_version }} - bundler: latest - bundler-cache: true - - - name: Run specs with Sidekiq ${{ matrix.sidekiq_version }} - run: bundle exec rake - - - name: Upload Coverage - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/sentry_yabeda_test.yml b/.github/workflows/sentry_yabeda_test.yml deleted file mode 100644 index e14d1d217..000000000 --- a/.github/workflows/sentry_yabeda_test.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: sentry-yabeda Test - -on: - workflow_dispatch: - workflow_call: - outputs: - matrix-result: - description: "Matrix job result" - value: ${{ jobs.test.outputs.matrix-result }} -# Cancel in progress workflows on pull_requests. -# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value -concurrency: - group: sentry-yabeda-test-${{ github.head_ref || github.run_id }} - cancel-in-progress: true -jobs: - matrix: - runs-on: ubuntu-latest - outputs: - include: ${{ steps.set.outputs.include }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # test-matrix.json is the single source of truth for this gem's matrix. - - id: set - run: echo "include=$(jq -c . sentry-yabeda/test-matrix.json)" >> "$GITHUB_OUTPUT" - - test: - needs: matrix - defaults: - run: - working-directory: sentry-yabeda - name: Ruby ${{ matrix.ruby_version }}, options - ${{ toJson(matrix.options) }} - runs-on: ubuntu-latest - timeout-minutes: 10 - env: - RUBYOPT: ${{ matrix.options.rubyopt }} - # Pin via the wrapper gemfile + its sibling .gemfile.lock (BUNDLE_LOCKFILE is unsupported on older bundlers). - BUNDLE_GEMFILE: ${{ github.workspace }}/sentry-yabeda/gemfiles/ruby-${{ matrix.ruby_version }}.gemfile - BUNDLE_FROZEN: "true" - BUNDLE_WITHOUT: rubocop - JRUBY_OPTS: "--debug" # for more accurate test coverage - strategy: - fail-fast: false - matrix: - include: ${{ fromJson(needs.matrix.outputs.include) }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - # Wrapper keys the lock to this cell (.gemfile -> .gemfile.lock); must exist before setup-ruby. - - name: Write wrapper gemfile - run: | - mkdir -p gemfiles - echo 'eval_gemfile "../Gemfile"' > "$BUNDLE_GEMFILE" - - - name: Set up Ruby ${{ matrix.ruby_version }} - uses: ruby/setup-ruby@319994f95fa847cf3fb3cd3dbe89f6dcde9f178f # v1 - with: - ruby-version: ${{ matrix.ruby_version }} - bundler: latest - bundler-cache: true - - - name: Run specs - run: bundle exec rake - - - name: Upload Coverage - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 95b31f45b..da2841de0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,45 +13,39 @@ concurrency: cancel-in-progress: true jobs: - delayed_job-tests: - uses: ./.github/workflows/sentry_delayed_job_test.yml - secrets: inherit - - opentelemetry-tests: - uses: ./.github/workflows/sentry_opentelemetry_test.yml - secrets: inherit - - rails-tests: - uses: ./.github/workflows/sentry_rails_test.yml - secrets: inherit - - resque-tests: - uses: ./.github/workflows/sentry_resque_test.yml - secrets: inherit - - ruby-tests: - uses: ./.github/workflows/sentry_ruby_test.yml - secrets: inherit - - sidekiq-tests: - uses: ./.github/workflows/sentry_sidekiq_test.yml - secrets: inherit - - yabeda-tests: - uses: ./.github/workflows/sentry_yabeda_test.yml + # Prewarm mise cache in case it was evicted recently. + # Each specific test needs this to exist. + setup-mise: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: ./.github/actions/setup-mise + + test: + needs: setup-mise + strategy: + fail-fast: false + matrix: + include: + - gem: sentry-ruby + - gem: sentry-rails + apt: libsqlite3-dev imagemagick + - gem: sentry-sidekiq + - gem: sentry-delayed_job + apt: libsqlite3-dev + - gem: sentry-resque + - gem: sentry-opentelemetry + - gem: sentry-yabeda + uses: ./.github/workflows/gem_test.yml + with: + gem: ${{ matrix.gem }} + apt: ${{ matrix.apt || '' }} secrets: inherit codecov: name: CodeCov runs-on: ubuntu-latest - needs: - - ruby-tests - - rails-tests - - sidekiq-tests - - delayed_job-tests - - resque-tests - - opentelemetry-tests - - yabeda-tests + needs: test steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 diff --git a/.github/workflows/update_lockfiles.yml b/.github/workflows/update_lockfiles.yml index 443d9fd32..200211e1c 100644 --- a/.github/workflows/update_lockfiles.yml +++ b/.github/workflows/update_lockfiles.yml @@ -32,18 +32,10 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} - # mise installs every Ruby declared in .mise.ci.toml (ruby.compile=false -> - # prebuilt binaries where available); bin/relock then resolves each cell - # against its matching Ruby. MISE_ENV scopes the install to the ci profile; - # it also keys the action's tool cache, so the matrix Rubies are cached and - # restored across runs. - - uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0 - env: - MISE_ENV: ci - MISE_JOBS: "2" - with: - install: true - cache: true + # Install every Ruby in .mise.ci.toml and restore the shared cache; bin/relock + # then resolves each cell against its matching Ruby. Same setup the *_test + # workflows use, so they all share one mise tool cache. + - uses: ./.github/actions/setup-mise - name: Regenerate lockfiles run: ruby bin/relock diff --git a/bin/lib/matrix.rb b/bin/lib/matrix.rb index a362dd18b..c0ef028c3 100644 --- a/bin/lib/matrix.rb +++ b/bin/lib/matrix.rb @@ -44,19 +44,22 @@ def label # -> ruby-3.2_rack-2_redis-4, {RACK_VERSION=2, REDIS_RB_VERSION=4} def cell_from_entry(gem, entry) ruby = entry.fetch("ruby_version") - segments = ["ruby-#{ruby}"] env = {} - entry.each do |key, value| + axes = entry.filter_map do |key, value| next if key == "ruby_version" || key == "options" name = key.split("_").first var = GEM_ENV_MAPPING[name] abort "Unknown matrix key: '#{key}' in #{gem}/test-matrix.json" unless var - segments << "#{name}-#{value}" env[var] = value + [name, value] end + # Sort axes by name so the wrapper/lock filename is canonical regardless of + # key order in the source entry — CI hands us the matrix object verbatim. + segments = ["ruby-#{ruby}"] + axes.sort_by(&:first).map { |name, value| "#{name}-#{value}" } + Cell.new(gem: gem, base: segments.join("_"), ruby: ruby, diff --git a/bin/test b/bin/test index bba0d113a..bf36f8663 100755 --- a/bin/test +++ b/bin/test @@ -52,16 +52,31 @@ def cell_for_gem(gem) [cell, gem] end +# Build the cell straight from a test-matrix.json entry. CI already holds the +# entry as its matrix context, so the workflow can hand us `toJson(matrix)` +# verbatim instead of re-deriving a --cell path. Uses the same cell_from_entry as +# bin/relock, so the wrapper/lock name and rubyopt resolve identically. Gem comes +# from --gem, else the working directory (CI runs from the gem dir). +def cell_from_entry_arg(json, gem) + gem ||= File.basename(Dir.pwd) + abort "No test-matrix.json for gem '#{gem}'; pass --gem or run from a gem dir." unless all_gems.include?(gem) + [cell_from_entry(gem, JSON.parse(json)), gem] +rescue JSON::ParserError => e + abort "--entry is not valid JSON: #{e.message}" +end + opts = { cell: nil, + entry: nil, gem: nil, rake: false, list: false } parser = OptionParser.new do |o| - o.banner = "Usage: bin/test (--cell PATH | --gem NAME) [options] [rspec args]" + o.banner = "Usage: bin/test (--cell PATH | --entry JSON | --gem NAME) [options] [rspec args]" o.on("--cell PATH", "Cell to run, by its wrapper/lock path (see -l).") { |v| opts[:cell] = v } + o.on("--entry JSON", "Cell to run, from a test-matrix.json entry (pairs with --gem/cwd).") { |v| opts[:entry] = v } o.on("--gem NAME", "Gem to run (auto-picks newest installed Ruby cell); scopes -l.") { |v| opts[:gem] = v } o.on("--rake", "Run `bundle exec rake` (full CI task) instead of rspec.") { opts[:rake] = true } o.on("-l", "--list", "List every cell's wrapper path, one per line; do nothing.") { opts[:list] = true } @@ -91,12 +106,14 @@ if opts[:list] end cell, gem = - if opts[:cell] + if opts[:entry] + cell_from_entry_arg(opts[:entry], opts[:gem]) + elsif opts[:cell] cell_from_path(opts[:cell], opts[:gem]) elsif opts[:gem] cell_for_gem(opts[:gem]) else - abort "Pass --cell PATH or --gem NAME (see `bin/test -l`)." + abort "Pass --cell PATH, --entry JSON, or --gem NAME (see `bin/test -l`)." end ensure_installed([cell]) diff --git a/sentry-delayed_job/README.md b/sentry-delayed_job/README.md index ab616229f..6d2013cb9 100644 --- a/sentry-delayed_job/README.md +++ b/sentry-delayed_job/README.md @@ -11,7 +11,7 @@ [![Gem Version](https://img.shields.io/gem/v/sentry-delayed_job.svg)](https://rubygems.org/gems/sentry-delayed_job) -![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_delayed_job_test.yml/badge.svg) +![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg) [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) [![Gem](https://img.shields.io/gem/dt/sentry-delayed_job.svg)](https://rubygems.org/gems/sentry-delayed_job/) [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sentry-delayed_job&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sentry-delayed_job&package-manager=bundler&version-scheme=semver) diff --git a/sentry-opentelemetry/README.md b/sentry-opentelemetry/README.md index 2d3f72016..179f8eae7 100644 --- a/sentry-opentelemetry/README.md +++ b/sentry-opentelemetry/README.md @@ -11,7 +11,7 @@ [![Gem Version](https://img.shields.io/gem/v/sentry-opentelemetry.svg)](https://rubygems.org/gems/sentry-opentelemetry) -![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_opentelemetry_test.yml/badge.svg) +![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg) [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) [![Gem](https://img.shields.io/gem/dt/sentry-opentelemetry.svg)](https://rubygems.org/gems/sentry-opentelemetry/) [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sentry-opentelemetry&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sentry-opentelemetry&package-manager=bundler&version-scheme=semver) diff --git a/sentry-rails/README.md b/sentry-rails/README.md index c8d1f2a19..6e97368fd 100644 --- a/sentry-rails/README.md +++ b/sentry-rails/README.md @@ -11,7 +11,7 @@ [![Gem Version](https://img.shields.io/gem/v/sentry-rails.svg)](https://rubygems.org/gems/sentry-rails) -![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_rails_test.yml/badge.svg) +![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg) [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) [![Gem](https://img.shields.io/gem/dt/sentry-rails.svg)](https://rubygems.org/gems/sentry-rails/) [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sentry-rails&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sentry-rails&package-manager=bundler&version-scheme=semver) diff --git a/sentry-resque/Gemfile b/sentry-resque/Gemfile index f3b188d0d..b099a260b 100644 --- a/sentry-resque/Gemfile +++ b/sentry-resque/Gemfile @@ -12,7 +12,5 @@ gem "sentry-ruby", path: "../sentry-ruby" gem "resque-retry", "~> 1.8" -group :rails do - gem "sentry-rails", path: "../sentry-rails" - gem "rails", "> 5.2.0" -end +gem "sentry-rails", path: "../sentry-rails" +gem "rails", "> 5.2.0" diff --git a/sentry-resque/README.md b/sentry-resque/README.md index a6aab404c..f325b027d 100644 --- a/sentry-resque/README.md +++ b/sentry-resque/README.md @@ -11,7 +11,7 @@ [![Gem Version](https://img.shields.io/gem/v/sentry-resque.svg)](https://rubygems.org/gems/sentry-resque) -![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_resque_test.yml/badge.svg) +![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg) [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) [![Gem](https://img.shields.io/gem/dt/sentry-resque.svg)](https://rubygems.org/gems/sentry-resque/) [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sentry-resque&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sentry-resque&package-manager=bundler&version-scheme=semver) diff --git a/sentry-sidekiq/README.md b/sentry-sidekiq/README.md index 30da6ebe1..939b2e9a8 100644 --- a/sentry-sidekiq/README.md +++ b/sentry-sidekiq/README.md @@ -11,7 +11,7 @@ [![Gem Version](https://img.shields.io/gem/v/sentry-sidekiq.svg)](https://rubygems.org/gems/sentry-sidekiq) -![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_sidekiq_test.yml/badge.svg) +![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg) [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) [![Gem](https://img.shields.io/gem/dt/sentry-sidekiq.svg)](https://rubygems.org/gems/sentry-sidekiq/) [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sentry-sidekiq&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sentry-sidekiq&package-manager=bundler&version-scheme=semver) diff --git a/sentry-yabeda/README.md b/sentry-yabeda/README.md index 4ff7fd76f..dbd2c3b80 100644 --- a/sentry-yabeda/README.md +++ b/sentry-yabeda/README.md @@ -10,7 +10,7 @@ --- [![Gem Version](https://img.shields.io/gem/v/sentry-yabeda.svg)](https://rubygems.org/gems/sentry-yabeda) -![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/sentry_yabeda_test.yml/badge.svg) +![Build Status](https://github.com/getsentry/sentry-ruby/actions/workflows/tests.yml/badge.svg) [![Coverage Status](https://img.shields.io/codecov/c/github/getsentry/sentry-ruby/master?logo=codecov)](https://codecov.io/gh/getsentry/sentry-ruby/branch/master) [![Gem](https://img.shields.io/gem/dt/sentry-yabeda.svg)](https://rubygems.org/gems/sentry-yabeda/)