Skip to content

Commit dcf8392

Browse files
authored
Project harness for Ruby (#335)
## What was changed Adds `ruby/harness/` package, effectively a port of the same Python harness (`python/harness`). `ruby/harness is a standalone Ruby package that supports the same harness semantics, structure, and API as the existing Python harness. The test suite (`ruby/harness/tests`) similarly mimics the existing Python harness test suite. Notable, a significant portion of the change comes from making the harness a standalone Ruby package with linting support (RBS, Steepfile, etc.). ## Why? - load testing ergonomics / DX - Language parity
1 parent 4205d8b commit dcf8392

32 files changed

Lines changed: 1936 additions & 225 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ workers/python/**/__pycache__/
2424
workers/typescript/harness/dist/
2525
workers/typescript/harness/dist-test/
2626
workers/typescript/harness/src/generated/
27+
workers/**/.rubocop_cache/
2728
workers/*/omes-temp-*/
2829
workers/*/prepared/
2930
workers/**/project-build-*/

cmd/dev/install.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,13 @@ func installRuby(ctx context.Context) error {
224224
return err
225225
}
226226
fmt.Println("✅ Ruby worker dependencies installed successfully!")
227+
228+
harnessDir := targetDir + "/harness"
229+
fmt.Println("Installing Ruby harness dependencies...")
230+
if err := runCommandInDir(ctx, harnessDir, "bundle", "install"); err != nil {
231+
return err
232+
}
233+
fmt.Println("✅ Ruby harness dependencies installed successfully!")
227234
return nil
228235
}
229236

cmd/dev/lint_and_format.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,23 @@ func lintAndFormatRubyWorker(ctx context.Context, workerDir string) error {
228228
return err
229229
}
230230

231+
harnessDir := workerDir + "/harness"
232+
233+
fmt.Println("Formatting Ruby harness...")
234+
if err := runCommandInDir(ctx, harnessDir, "bundle", "exec", "rubocop", "-A"); err != nil {
235+
return err
236+
}
237+
238+
fmt.Println("Linting Ruby harness...")
239+
if err := runCommandInDir(ctx, harnessDir, "bundle", "exec", "rubocop"); err != nil {
240+
return err
241+
}
242+
243+
fmt.Println("Type checking Ruby harness...")
244+
if err := runCommandInDir(ctx, harnessDir, "bundle", "exec", "steep", "check"); err != nil {
245+
return err
246+
}
247+
231248
fmt.Println("✅ Ruby lint-and-format completed successfully!")
232249
return nil
233250
}

cmd/dev/test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ func runTestWorker(ctx context.Context, language string) error {
9292
return err
9393
}
9494
}
95+
if language == "ruby" {
96+
if err := runRubyHarnessTests(ctx, repoDir); err != nil {
97+
return err
98+
}
99+
}
95100
return testWorkerLocally(ctx, repoDir, language, sdkVersion)
96101
}
97102

@@ -125,6 +130,34 @@ func runTypeScriptHarnessTests(ctx context.Context, repoDir string) error {
125130
return nil
126131
}
127132

133+
func runRubyHarnessTests(ctx context.Context, repoDir string) error {
134+
harnessDir := filepath.Join(repoDir, "workers", "ruby", "harness")
135+
rubyVersion, err := getVersion("ruby")
136+
if err != nil {
137+
return err
138+
}
139+
if err := checkMise(); err != nil {
140+
return err
141+
}
142+
fmt.Println("Running Ruby harness tests...")
143+
if err := runCommandInDir(
144+
ctx,
145+
harnessDir,
146+
"mise",
147+
"exec",
148+
"ruby@"+rubyVersion,
149+
"--",
150+
"bundle",
151+
"exec",
152+
"rake",
153+
"test",
154+
); err != nil {
155+
return fmt.Errorf("failed Ruby harness tests: %w", err)
156+
}
157+
fmt.Println("✅ Ruby harness tests completed successfully!")
158+
return nil
159+
}
160+
128161
func testWorkerLocally(ctx context.Context, repoDir, language, sdkVersion string) error {
129162
args := []string{
130163
"go", "run", "./cmd", "run-scenario-with-worker",

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/spf13/cobra v1.7.0
1313
github.com/spf13/pflag v1.0.5
1414
github.com/stretchr/testify v1.11.1
15-
github.com/temporalio/features v0.0.0-20260331150122-757294c2a9e9
15+
github.com/temporalio/features v0.0.0-20260427223549-86e4c0deedd7
1616
github.com/temporalio/omes/workers/go/harness/api v0.0.0-00010101000000-000000000000
1717
go.temporal.io/api v1.62.7
1818
go.temporal.io/sdk v1.42.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
9797
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
9898
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
9999
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
100-
github.com/temporalio/features v0.0.0-20260331150122-757294c2a9e9 h1:9ifP6KcfPhf22qFb4t7L8M11nkWGD8cyAFQ3fUrLqFw=
101-
github.com/temporalio/features v0.0.0-20260331150122-757294c2a9e9/go.mod h1:LsZUh/AkCjnOKrEpnEklGmsJ3g758Hyq2X+hzMofMjw=
100+
github.com/temporalio/features v0.0.0-20260427223549-86e4c0deedd7 h1:gBLwgyi8xw0oqZgxMwxTRGIfP8RxtI7r1igm3G6aXGY=
101+
github.com/temporalio/features v0.0.0-20260427223549-86e4c0deedd7/go.mod h1:BUWwBMK+Ga5h9xPTS7+kmutSIfY4K1gfSH8eG7fSbU0=
102102
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
103103
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
104104
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=

workers/build.go

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -285,37 +285,22 @@ func (b *Builder) buildDotNet(ctx context.Context, baseDir string) (sdkbuild.Pro
285285
}
286286

287287
func (b *Builder) buildRuby(ctx context.Context, baseDir string) (sdkbuild.Program, error) {
288-
// If version not provided, read the version constraint from the gemspec.
289-
version := b.SdkOptions.Version
290-
if version == "" {
291-
gemspecBytes, err := os.ReadFile(filepath.Join(baseDir, "omes.gemspec"))
292-
if err != nil {
293-
return nil, fmt.Errorf("failed reading omes.gemspec: %w", err)
294-
}
295-
for _, line := range strings.Split(string(gemspecBytes), "\n") {
296-
line = strings.TrimSpace(line)
297-
if strings.Contains(line, "'temporalio'") || strings.Contains(line, `"temporalio"`) {
298-
parts := strings.Split(line, ",")
299-
if len(parts) >= 2 {
300-
version = strings.TrimSpace(parts[1])
301-
version = strings.Trim(version, `"'`)
302-
}
303-
break
304-
}
305-
}
306-
if version == "" {
307-
return nil, fmt.Errorf("version not found in omes.gemspec")
308-
}
309-
}
310-
311-
prog, err := sdkbuild.BuildRubyProgram(ctx, sdkbuild.BuildRubyProgramOptions{
288+
options := sdkbuild.BuildRubyProgramOptions{
312289
BaseDir: baseDir,
313290
SourceDir: baseDir,
314291
DirName: b.DirName,
315-
Version: version,
292+
Version: b.SdkOptions.Version,
316293
Stdout: b.stdout,
317294
Stderr: b.stderr,
318-
})
295+
}
296+
if b.ProjectName == "" {
297+
options.MoreDependencies = []sdkbuild.RubyDependency{{
298+
Name: "harness",
299+
Path: filepath.Join(baseDir, "harness"),
300+
}}
301+
}
302+
303+
prog, err := sdkbuild.BuildRubyProgram(ctx, options)
319304
if err != nil {
320305
return nil, fmt.Errorf("failed preparing: %w", err)
321306
}

workers/go/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
8888
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
8989
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
9090
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
91-
github.com/temporalio/features v0.0.0-20260331150122-757294c2a9e9 h1:9ifP6KcfPhf22qFb4t7L8M11nkWGD8cyAFQ3fUrLqFw=
92-
github.com/temporalio/features v0.0.0-20260331150122-757294c2a9e9/go.mod h1:LsZUh/AkCjnOKrEpnEklGmsJ3g758Hyq2X+hzMofMjw=
91+
github.com/temporalio/features v0.0.0-20260427223549-86e4c0deedd7 h1:gBLwgyi8xw0oqZgxMwxTRGIfP8RxtI7r1igm3G6aXGY=
92+
github.com/temporalio/features v0.0.0-20260427223549-86e4c0deedd7/go.mod h1:BUWwBMK+Ga5h9xPTS7+kmutSIfY4K1gfSH8eG7fSbU0=
9393
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
9494
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
9595
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=

workers/ruby/.rubocop.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
AllCops:
22
TargetRubyVersion: 3.3
33
NewCops: enable
4+
SuggestExtensions: false
45
Exclude:
6+
- "harness/**/*"
57
- "protos/**/*"
68
- "vendor/**/*"
79
- "omes-temp-*/**/*"
@@ -44,3 +46,6 @@ Metrics/PerceivedComplexity:
4446

4547
Metrics/AbcSize:
4648
Max: 25
49+
50+
Metrics/ParameterLists:
51+
CountKeywordArgs: false

workers/ruby/Gemfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
source 'https://rubygems.org'
22

33
gemspec
4+
gem 'harness', path: 'harness'
45

56
group :development do
7+
gem 'rbs', '~> 3.10'
68
gem 'rubocop', '~> 1.0'
9+
gem 'steep', '~> 1.10'
710
end

0 commit comments

Comments
 (0)