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
25 changes: 25 additions & 0 deletions .github/workflows/prune-stale-images.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: prune-stale-images

on:
schedule:
- cron: '37 4 * * *'
workflow_dispatch:

jobs:
prune:
runs-on: ubuntu-latest
permissions:
packages: write

steps:
- name: Prune old temporary FIT performer images
uses: vlaurin/action-ghcr-prune@v0.6.0
with:
token: ${{ github.token }}
organization: ${{ github.repository_owner }}
container: ruby-fit-performer
keep-younger-than: 7 # days
prune-untagged: true
prune-tags-regexes: |
^refs-
^sha-
47 changes: 47 additions & 0 deletions .github/workflows/publish-fit-performer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: publish-fit-performer
permissions: {}

run-name: ${{ inputs.ref }}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.ref }}
cancel-in-progress: true

on:
push:
branches:
- main
- release*

tags:
- '*'

paths-ignore:
- '.gitignore'
- '**/*.md'
- '**/.rubocop.yml'
- '**/.rubocop_todo.yml'
- 'examples/**'
- 'LICENSE.txt'

workflow_dispatch:
inputs:
ref:
description: "Performer version. Specify a branch, tag, full commit hash, GitHub PR like 'refs/pull/37/merge', or Gerrit change like 'refs/changes/58/240858/6'"
required: true

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- uses: couchbaselabs/sdk-docker-build-action@v1
with:
sdk: ruby
ref: ${{ inputs.ref }}
dockerfile: ./fit-performer/Dockerfile
env:
DOCKER_BUILD_SUMMARY: false
27 changes: 27 additions & 0 deletions .github/workflows/validate-fit-performer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: validate-fit-performer
permissions: {}

on:
pull_request:
branches:
- main
- release*

paths:
- 'fit-performer/**'
- '.github/workflows/validate-fit-performer.yml'

jobs:
build:
runs-on: ubuntu-latest
if: github.event_name != 'push'

steps:
- uses: actions/checkout@v6
with:
submodules: recursive
fetch-depth: 0
fetch-tags: true

- run: |
docker build -f fit-performer/Dockerfile .
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@
Gemfile.lock
Makefile
mkmf.log

# Generated FIT performer protobuf code
fit-performer/lib/fit/protocol/**/*
/release-*
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ AllCops:
- 'vendor/**/*'
- 'ext/**/*'
- 'lib/couchbase/protostellar/generated/**/*'
- 'fit-performer/lib/fit/protocol/**/*'
# Copied from Rails v6.1.0-38-gbf165e3e19
- 'test/active_support/behaviors/*.rb'
- 'test/active_support/behaviors.rb'
Expand Down
11 changes: 8 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,28 @@ gemspec path: "couchbase-opentelemetry"

gem "rake"

group :fit_performer, :development do
gem "grpc-tools", "~> 1.59"
gem 'opentelemetry-exporter-otlp', '~> 0.31.1'
gem "opentelemetry-exporter-otlp-metrics", '~> 0.6.1'
gem "opentelemetry-metrics-sdk", "~> 0.11.2"
gem "opentelemetry-sdk", "~> 1.10"
end

group :development do
gem "activesupport", "~> 7.0.3"
gem "drb"
gem "faker"
gem "flay"
gem "flog"
gem "gem-compiler"
gem "grpc-tools", "~> 1.59"
gem "heckle"
gem "irb"
# TODO(SA): review https://minite.st/docs/History_rdoc.html#label-6.0.0+-2F+2025-12-17
gem "minitest", "~> 6.0"
gem "minitest-mock"
gem "minitest-reporters"
gem "mutex_m"
gem "opentelemetry-metrics-sdk", "~> 0.11.2"
gem "opentelemetry-sdk", "~> 1.10"
gem "rack"
gem "reek"
gem "rubocop", require: false
Expand Down
20 changes: 20 additions & 0 deletions bin/update-fit-protocol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash

# Copyright 2026-Present Couchbase, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

rm -rf fit-performer/proto
mkdir -p fit-performer/proto
curl --location --fail https://github.com/couchbaselabs/fit-protocol/archive/refs/heads/main.tar.gz \
| tar -xz --strip-components=2 -C fit-performer/proto fit-protocol-main/operational
1 change: 1 addition & 0 deletions fit-performer/.rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
inherit_from: ../.rubocop.yml
15 changes: 15 additions & 0 deletions fit-performer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM ruby:4.0-trixie

WORKDIR /app
COPY ./ ./

RUN apt-get update && apt-get install -y cmake build-essential libssl-dev protobuf-compiler

RUN bundle install
RUN bundle exec rake compile

WORKDIR /app/fit-performer

RUN bundle exec rake generate

ENTRYPOINT ["bundle", "exec", "ruby", "server.rb"]
35 changes: 35 additions & 0 deletions fit-performer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Couchbase Ruby FIT performer

This is the FIT performer for the Couchbase Ruby Client.

## Setup

### Generated code

To generate the Ruby code corresponding to the Protocol Buffers and gRPC definitions:

```shell
bundle exec rake generate
```

### Updating the protocol

The FIT protocol is hosted in https://github.com/couchbaselabs/fit-protocol. There is a copy of the protocol in this repository (in `/fit-performer/proto`) the performer is built against.

The latest version of the protocol can be fetched by running:
```shell
bundle exec rake update_protocol
```

## Starting the performer

```shell
bundle exec ruby server.rb
```

## Docker

We provide a dockerfile to build and run the performer with Docker. You can build the image from the root of this repository as follows:
```shell
docker build -f fit-performer/Dockerfile .
```
50 changes: 50 additions & 0 deletions fit-performer/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

# Copyright 2026-Present Couchbase, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require "rubocop/rake_task"

require "mkmf"

RuboCop::RakeTask.new

desc "Re-generate gRPC server implementation"
task :generate_grpc_server do
protoc_binary = find_executable("grpc_tools_ruby_protoc")
grpc_dir = File.expand_path("proto", __dir__)
proto_files = Dir["#{grpc_dir}/*.proto"]
output_dir = File.expand_path("lib/fit/protocol", __dir__)
rm_rf(output_dir)
mkdir(output_dir)
sh(protoc_binary,
"--proto_path=#{grpc_dir.shellescape}",
"--grpc_out=#{output_dir.shellescape}",
"--ruby_out=#{output_dir.shellescape}",
*proto_files)
Dir["#{output_dir}/*_pb.rb"].each do |file|
content = File.read(file)
.gsub(/^require ["']([\w.]+)_pb['"]/, "require_relative '\\1_pb'")
File.write(file, content)
end
end

desc "Re-generate gRPC server implementation and reformat using Rubocop"
task generate: %w[generate_grpc_server rubocop:autocorrect_all]

desc "Fetch the latest FIT protocol"
task :update_protocol do
root_dir = File.expand_path("..", __dir__)
sh(File.join(root_dir, "bin", "update-fit-protocol"), chdir: root_dir)
end
18 changes: 18 additions & 0 deletions fit-performer/lib/fit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

# Copyright 2026-Present Couchbase, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

module FIT
end
20 changes: 20 additions & 0 deletions fit-performer/lib/fit/performer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

# Copyright 2026-Present Couchbase, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

module FIT
module Performer
end
end
Loading
Loading