Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: Benchmark

on:
push:
branches: [master, main]
pull_request:
branches: [master, main]

jobs:
benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Ruby and Rust
uses: oxidize-rb/actions/setup-ruby-and-rust@v1
with:
ruby-version: "3.4"
bundler-cache: true
cargo-cache: true

- name: Build extension
run: bundle exec rake compile

- name: Run benchmarks with YJIT
run: |
bundle exec ruby --yjit bin/benchmark --json > benchmark_results.json

- name: Format results as markdown
run: |
cat > format_results.rb << 'EOF'
#!/usr/bin/env ruby
require 'json'

data = JSON.parse(File.read('benchmark_results.json'))

output = "## 🚀 Benchmark Results\n\n"
output += "_Benchmarks run with YJIT enabled on Ruby #{data['ruby_version']}_\n\n"

# Writing benchmark
if data['benchmarks']['writing']
output += "### 📝 CSV Writing Performance\n\n"
output += "| Library | Iterations/sec | Std Dev |\n"
output += "|---------|----------------|----------|\n"

writing = data['benchmarks']['writing']
sorted_writing = writing.sort_by { |_, v| -v['ips'] }

sorted_writing.each do |name, stats|
output += "| #{name} | #{stats['ips'].round(1)} | ±#{stats['stddev_percentage'].round(1)}% |\n"
end

# Add comparison
if sorted_writing.length > 1
fastest = sorted_writing.first
output += "\n**Comparison:**\n\n"
sorted_writing.each do |name, stats|
if name == fastest[0]
output += "- **#{name}**: #{stats['ips'].round(1)} i/s (fastest)\n"
else
slowdown = fastest[1]['ips'] / stats['ips']
output += "- **#{name}**: #{stats['ips'].round(1)} i/s - #{slowdown.round(2)}x slower\n"
end
end
end
output += "\n"
end

# Reading benchmark
if data['benchmarks']['reading']
output += "### 📖 CSV Reading Performance\n\n"
output += "| Library | Iterations/sec | Std Dev |\n"
output += "|---------|----------------|----------|\n"

reading = data['benchmarks']['reading']
sorted_reading = reading.sort_by { |_, v| -v['ips'] }

sorted_reading.each do |name, stats|
output += "| #{name} | #{stats['ips'].round(1)} | ±#{stats['stddev_percentage'].round(1)}% |\n"
end

# Add comparison
if sorted_reading.length > 1
fastest = sorted_reading.first
output += "\n**Comparison:**\n\n"
sorted_reading.each do |name, stats|
if name == fastest[0]
output += "- **#{name}**: #{stats['ips'].round(1)} i/s (fastest)\n"
else
slowdown = fastest[1]['ips'] / stats['ips']
output += "- **#{name}**: #{stats['ips'].round(1)} i/s - #{slowdown.round(2)}x slower\n"
end
end
end
output += "\n"
end

# Write to GitHub Step Summary
if ENV['GITHUB_STEP_SUMMARY']
File.write(ENV['GITHUB_STEP_SUMMARY'], output)
puts "✅ Results written to GitHub Actions summary"
end

# Also print to stdout
puts output
EOF

ruby format_results.rb

- name: Upload benchmark results
uses: actions/upload-artifact@v4
if: always()
with:
name: benchmark-results
path: benchmark_results.json
retention-days: 30
105 changes: 105 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Build Gems

on:
workflow_call:
inputs:
upload-artifacts:
description: "Whether to upload gem artifacts"
type: boolean
default: true
required: false
ruby-versions:
description: "Ruby versions to test and build for (JSON array)"
type: string
default: '["3.0", "3.1", "3.2", "3.3", "3.4"]'
required: false

jobs:
# Test on multiple Ruby versions and platforms
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
ruby: ${{ fromJSON(inputs.ruby-versions) }}

steps:
- uses: actions/checkout@v4

- name: Set up Ruby and Rust
uses: oxidize-rb/actions/setup-ruby-and-rust@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
cargo-cache: true

- name: Build extension
run: bundle exec rake compile

- name: Run tests
run: bundle exec rake spec

# Build native gems for different platforms using oxidize-rb/cross-gem
cross-gem:
name: Build native gem for ${{ matrix.platform }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- x86_64-linux
- x86_64-linux-musl
- aarch64-linux
- aarch64-linux-musl
- x86_64-darwin
- arm64-darwin
- x64-mingw-ucrt
- x64-mingw32
steps:
- uses: actions/checkout@v4

- name: Set up Ruby and Rust
uses: oxidize-rb/actions/setup-ruby-and-rust@v1
with:
ruby-version: "3.3"
bundler-cache: true
cargo-cache: true

- name: Build native gem
uses: oxidize-rb/actions/cross-gem@v1
with:
platform: ${{ matrix.platform }}
ruby-versions: ${{ join(fromJSON(inputs.ruby-versions), ', ') }}

- name: Upload gem artifact
if: inputs.upload-artifacts
uses: actions/upload-artifact@v4
with:
name: native-gem-${{ matrix.platform }}
path: pkg/*-${{ matrix.platform }}.gem
retention-days: 1

# Build the source gem (no pre-built binary)
source-gem:
name: Build source gem
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
bundler-cache: true

- name: Build source gem
run: gem build rscsv.gemspec

- name: Upload gem artifact
if: inputs.upload-artifacts
uses: actions/upload-artifact@v4
with:
name: source-gem
path: "rscsv-*.gem"
retention-days: 1
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: CI

on:
push:
branches: [master, main]
pull_request:
branches: [master, main]

jobs:
build:
uses: ./.github/workflows/build.yml
with:
upload-artifacts: true
47 changes: 47 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Release

on:
push:
tags:
- "v*"

jobs:
# Build all gems using the reusable workflow
build:
uses: ./.github/workflows/build.yml
with:
upload-artifacts: true

# Publish all gems to RubyGems
publish:
name: Publish gems to RubyGems
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
environment: release
steps:
- uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"

- name: Download all gem artifacts
uses: actions/download-artifact@v4
with:
path: pkg
pattern: "*-gem*"
merge-multiple: true

- name: List gems to publish
run: ls -la pkg/

- name: Publish gems to RubyGems (with trusted publishing)
run: |
for gem in pkg/*.gem; do
echo "Publishing $gem"
gem push "$gem"
done
45 changes: 0 additions & 45 deletions .travis.yml

This file was deleted.

Loading
Loading