robot_lab 0.0.11 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -0
- data/README.md +180 -0
- data/docs/api/core/result.md +123 -0
- data/docs/api/errors.md +185 -0
- data/docs/api/messages/index.md +21 -0
- data/docs/getting-started/configuration.md +1 -1
- data/docs/guides/building-robots.md +125 -0
- data/docs/guides/creating-networks.md +23 -0
- data/docs/guides/rails-integration.md +52 -13
- data/examples/18_rails/app/jobs/robot_run_job.rb +15 -75
- data/examples/31_launch_assessment.rb +248 -0
- data/examples/README.md +9 -0
- data/lib/generators/robot_lab/job_generator.rb +40 -0
- data/lib/generators/robot_lab/templates/job.rb.tt +10 -81
- data/lib/generators/robot_lab/templates/robot_job.rb.tt +18 -0
- data/lib/robot_lab/message.rb +1 -1
- data/lib/robot_lab/network.rb +1 -1
- data/lib/robot_lab/rails_integration/job.rb +158 -0
- data/lib/robot_lab/rails_integration/railtie.rb +9 -0
- data/lib/robot_lab/run_config.rb +1 -1
- data/lib/robot_lab/version.rb +1 -1
- data/lib/robot_lab.rb +4 -0
- metadata +9 -4
- data/.github/workflows/deploy-yard-docs.yml +0 -52
|
@@ -1,92 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Generic background job for executing any robot asynchronously.
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# Inherits from RobotLab::Job — Turbo Stream wiring, thread persistence,
|
|
6
|
+
# and completion/error broadcasting are all handled by the base class.
|
|
7
|
+
#
|
|
8
|
+
# Pass robot_class: at enqueue time to select which robot to run, or
|
|
9
|
+
# generate a dedicated job with `rails generate robot_lab:job NAME` to
|
|
10
|
+
# bind a job class to a specific robot via the robot_class DSL.
|
|
8
11
|
#
|
|
9
12
|
# @example Enqueue from a controller
|
|
10
13
|
# RobotRunJob.perform_later(
|
|
11
14
|
# robot_class: "SupportRobot",
|
|
12
|
-
# message:
|
|
13
|
-
# thread_id:
|
|
15
|
+
# message: params[:message],
|
|
16
|
+
# thread_id: session_id
|
|
14
17
|
# )
|
|
15
18
|
#
|
|
16
|
-
class RobotRunJob <
|
|
19
|
+
class RobotRunJob < RobotLab::Job
|
|
17
20
|
queue_as :default
|
|
18
|
-
|
|
19
|
-
retry_on StandardError, wait: 5.seconds, attempts: 3
|
|
20
|
-
discard_on ActiveJob::DeserializationError
|
|
21
|
-
|
|
22
|
-
def perform(robot_class:, message:, thread_id:, **context)
|
|
23
|
-
thread = RobotLabThread.find_or_create_by_session_id(thread_id)
|
|
24
|
-
thread.update!(last_user_message: message, last_user_message_at: Time.current)
|
|
25
|
-
|
|
26
|
-
robot = resolve_robot(robot_class, thread_id)
|
|
27
|
-
result = robot.run(message, **context)
|
|
28
|
-
|
|
29
|
-
persist_result(thread, result)
|
|
30
|
-
broadcast_completion(thread_id)
|
|
31
|
-
rescue StandardError => e
|
|
32
|
-
broadcast_error(thread_id, e)
|
|
33
|
-
raise
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
def resolve_robot(robot_class, thread_id)
|
|
39
|
-
klass = robot_class.to_s.constantize
|
|
40
|
-
stream_name = "robot_lab_thread_#{thread_id}"
|
|
41
|
-
|
|
42
|
-
if turbo_available?
|
|
43
|
-
on_content = RobotLab::RailsIntegration::TurboStreamCallbacks.build_content_callback(
|
|
44
|
-
stream_name: stream_name
|
|
45
|
-
)
|
|
46
|
-
on_tool_call = RobotLab::RailsIntegration::TurboStreamCallbacks.build_tool_call_callback(
|
|
47
|
-
stream_name: stream_name
|
|
48
|
-
)
|
|
49
|
-
klass.build(on_content: on_content, on_tool_call: on_tool_call)
|
|
50
|
-
else
|
|
51
|
-
klass.build
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def persist_result(thread, result)
|
|
56
|
-
sequence = thread.results.maximum(:sequence_number).to_i + 1
|
|
57
|
-
exported = result.export
|
|
58
|
-
|
|
59
|
-
thread.results.create!(
|
|
60
|
-
robot_name: result.robot_name,
|
|
61
|
-
sequence_number: sequence,
|
|
62
|
-
output_data: exported[:output],
|
|
63
|
-
tool_calls_data: exported[:tool_calls],
|
|
64
|
-
stop_reason: result.stop_reason,
|
|
65
|
-
checksum: result.checksum
|
|
66
|
-
)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def broadcast_completion(thread_id)
|
|
70
|
-
return unless turbo_available?
|
|
71
|
-
|
|
72
|
-
Turbo::StreamsChannel.broadcast_replace_to(
|
|
73
|
-
"robot_lab_thread_#{thread_id}",
|
|
74
|
-
target: "robot_status",
|
|
75
|
-
html: "<span class=\"robot-status-complete\">Complete</span>"
|
|
76
|
-
)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def broadcast_error(thread_id, error)
|
|
80
|
-
return unless turbo_available?
|
|
81
|
-
|
|
82
|
-
Turbo::StreamsChannel.broadcast_append_to(
|
|
83
|
-
"robot_lab_thread_#{thread_id}",
|
|
84
|
-
target: "robot_errors",
|
|
85
|
-
html: "<div class=\"robot-error\">#{ERB::Util.html_escape(error.message)}</div>"
|
|
86
|
-
)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def turbo_available?
|
|
90
|
-
defined?(Turbo::StreamsChannel)
|
|
91
|
-
end
|
|
92
21
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Background job that runs <%= robot_class_name %> asynchronously.
|
|
4
|
+
#
|
|
5
|
+
# Inherits from RobotLab::Job — Turbo Stream wiring, thread persistence,
|
|
6
|
+
# and completion/error broadcasting are all handled by the base class.
|
|
7
|
+
#
|
|
8
|
+
# @example Enqueue from a controller
|
|
9
|
+
# <%= class_name %>Job.perform_later(
|
|
10
|
+
# message: params[:message],
|
|
11
|
+
# thread_id: session_id
|
|
12
|
+
# )
|
|
13
|
+
#
|
|
14
|
+
class <%= class_name %>Job < RobotLab::Job
|
|
15
|
+
queue_as :<%= queue_name %>
|
|
16
|
+
|
|
17
|
+
robot_class <%= robot_class_name %>
|
|
18
|
+
end
|
data/lib/robot_lab/message.rb
CHANGED
data/lib/robot_lab/network.rb
CHANGED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RobotLab
|
|
4
|
+
module RailsIntegration
|
|
5
|
+
# Base class for RobotLab background jobs.
|
|
6
|
+
#
|
|
7
|
+
# Encapsulates the full robot-run lifecycle: robot class resolution,
|
|
8
|
+
# Turbo Stream callback wiring, thread-record persistence, and
|
|
9
|
+
# completion/error broadcasting. Suitable for fiber-safe execution
|
|
10
|
+
# under Solid Queue's fiber mode (see issue #20 for SQ version details).
|
|
11
|
+
#
|
|
12
|
+
# @example Minimal subclass using the robot_class DSL
|
|
13
|
+
# class SupportRobotJob < RobotLab::Job
|
|
14
|
+
# queue_as :default
|
|
15
|
+
# robot_class SupportRobot
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# # Enqueue (no robot_class: needed — taken from DSL):
|
|
19
|
+
# SupportRobotJob.perform_later(message: "Hello", thread_id: session_id)
|
|
20
|
+
#
|
|
21
|
+
# @example Generic job accepting robot_class at enqueue time
|
|
22
|
+
# class RobotRunJob < RobotLab::Job
|
|
23
|
+
# queue_as :default
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# RobotRunJob.perform_later(
|
|
27
|
+
# robot_class: "SupportRobot",
|
|
28
|
+
# message: params[:message],
|
|
29
|
+
# thread_id: session_id
|
|
30
|
+
# )
|
|
31
|
+
#
|
|
32
|
+
class Job < ActiveJob::Base
|
|
33
|
+
# Set or get the default robot class for this job subclass.
|
|
34
|
+
#
|
|
35
|
+
# @overload robot_class
|
|
36
|
+
# @return [Class, nil] the configured robot class
|
|
37
|
+
# @overload robot_class(klass)
|
|
38
|
+
# @param klass [Class] the robot class (must respond to .build)
|
|
39
|
+
# @return [Class]
|
|
40
|
+
def self.robot_class(klass = nil)
|
|
41
|
+
klass ? @robot_class = klass : @robot_class
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
retry_on StandardError, wait: 5.seconds, attempts: 3
|
|
45
|
+
discard_on ActiveJob::DeserializationError
|
|
46
|
+
|
|
47
|
+
# Run a robot as a background job.
|
|
48
|
+
#
|
|
49
|
+
# When +thread_id+ is provided the job:
|
|
50
|
+
# - Finds or creates a +RobotLabThread+ record and updates its last-message fields
|
|
51
|
+
# - Wires +TurboStreamCallbacks+ onto the robot (when turbo-rails is present)
|
|
52
|
+
# - Persists the +RobotResult+ to +RobotLabResult+
|
|
53
|
+
# - Broadcasts a completion or error event via Turbo Streams
|
|
54
|
+
#
|
|
55
|
+
# When +thread_id+ is omitted the robot runs in a fire-and-forget mode —
|
|
56
|
+
# no persistence, no broadcasting, result returned directly.
|
|
57
|
+
#
|
|
58
|
+
# @param message [String] the user message forwarded to robot.run
|
|
59
|
+
# @param robot_class [String, Class, nil] override; falls back to the class-level DSL
|
|
60
|
+
# @param thread_id [String, nil] session key for persistence and Turbo broadcasting
|
|
61
|
+
# @param context [Hash] additional keyword args forwarded to robot.run
|
|
62
|
+
# @return [RobotResult]
|
|
63
|
+
def perform(message:, robot_class: nil, thread_id: nil, **context)
|
|
64
|
+
klass = resolve_robot_class(robot_class)
|
|
65
|
+
thread = setup_thread(thread_id, message)
|
|
66
|
+
robot = build_robot(klass, thread_id)
|
|
67
|
+
result = robot.run(message, **context)
|
|
68
|
+
|
|
69
|
+
if thread
|
|
70
|
+
persist_result(thread, result)
|
|
71
|
+
broadcast_completion(thread_id)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
result
|
|
75
|
+
rescue StandardError => e
|
|
76
|
+
broadcast_error(thread_id, e) if thread_id
|
|
77
|
+
raise
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# Resolve the robot class from the runtime arg or the class-level DSL.
|
|
83
|
+
def resolve_robot_class(runtime_class)
|
|
84
|
+
klass = runtime_class || self.class.robot_class
|
|
85
|
+
raise ArgumentError,
|
|
86
|
+
"No robot class specified. Pass robot_class: to perform or set robot_class on the job class." \
|
|
87
|
+
unless klass
|
|
88
|
+
|
|
89
|
+
return klass if klass.is_a?(Class)
|
|
90
|
+
|
|
91
|
+
klass.to_s.constantize
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Find or create the thread record and stamp the incoming message.
|
|
95
|
+
# Returns nil when thread_id is absent (fire-and-forget mode).
|
|
96
|
+
def setup_thread(thread_id, message)
|
|
97
|
+
return nil unless thread_id
|
|
98
|
+
|
|
99
|
+
thread = "RobotLabThread".constantize.find_or_create_by_session_id(thread_id)
|
|
100
|
+
thread.update!(last_user_message: message, last_user_message_at: Time.current)
|
|
101
|
+
thread
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Build the robot, wiring Turbo callbacks when thread_id + turbo-rails are present.
|
|
105
|
+
def build_robot(klass, thread_id)
|
|
106
|
+
if thread_id && turbo_available?
|
|
107
|
+
stream_name = "robot_lab_thread_#{thread_id}"
|
|
108
|
+
on_content = TurboStreamCallbacks.build_content_callback(stream_name: stream_name)
|
|
109
|
+
on_tool_call = TurboStreamCallbacks.build_tool_call_callback(stream_name: stream_name)
|
|
110
|
+
klass.build(on_content: on_content, on_tool_call: on_tool_call)
|
|
111
|
+
else
|
|
112
|
+
klass.build
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Append a RobotLabResult record to the thread.
|
|
117
|
+
def persist_result(thread, result)
|
|
118
|
+
sequence = thread.results.maximum(:sequence_number).to_i + 1
|
|
119
|
+
exported = result.export
|
|
120
|
+
|
|
121
|
+
thread.results.create!(
|
|
122
|
+
robot_name: result.robot_name,
|
|
123
|
+
sequence_number: sequence,
|
|
124
|
+
output_data: exported[:output],
|
|
125
|
+
tool_calls_data: exported[:tool_calls],
|
|
126
|
+
stop_reason: result.stop_reason,
|
|
127
|
+
checksum: result.checksum
|
|
128
|
+
)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Broadcast a "Complete" badge to the Turbo Stream.
|
|
132
|
+
def broadcast_completion(thread_id)
|
|
133
|
+
return unless turbo_available?
|
|
134
|
+
|
|
135
|
+
Turbo::StreamsChannel.broadcast_replace_to(
|
|
136
|
+
"robot_lab_thread_#{thread_id}",
|
|
137
|
+
target: "robot_status",
|
|
138
|
+
html: "<div id=\"robot_status\"><span class=\"complete\">Complete</span></div>"
|
|
139
|
+
)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Broadcast an HTML-escaped error message to the Turbo Stream.
|
|
143
|
+
def broadcast_error(thread_id, error)
|
|
144
|
+
return unless turbo_available?
|
|
145
|
+
|
|
146
|
+
Turbo::StreamsChannel.broadcast_append_to(
|
|
147
|
+
"robot_lab_thread_#{thread_id}",
|
|
148
|
+
target: "robot_errors",
|
|
149
|
+
html: "<div class=\"error\">#{ERB::Util.html_escape(error.message)}</div>"
|
|
150
|
+
)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def turbo_available?
|
|
154
|
+
defined?(Turbo::StreamsChannel)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -33,9 +33,18 @@ module RobotLab
|
|
|
33
33
|
Dir.glob("#{path}/**/*.rake").each { |f| load f }
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
# TODO: Add fiber isolation warning once Solid Queue fiber mode lands in a
|
|
37
|
+
# mainline release. PR rails/solid_queue#728 (branch crmne/solid_queue
|
|
38
|
+
# async-worker-execution-mode) introduces the `fibers:` worker key but has
|
|
39
|
+
# not yet been merged or released. When a released version is detectable,
|
|
40
|
+
# add an initializer here that warns when:
|
|
41
|
+
# defined?(SolidQueue) &&
|
|
42
|
+
# app.config.active_support.isolation_level != :fiber
|
|
43
|
+
|
|
36
44
|
generators do
|
|
37
45
|
require "generators/robot_lab/install_generator"
|
|
38
46
|
require "generators/robot_lab/robot_generator"
|
|
47
|
+
require "generators/robot_lab/job_generator"
|
|
39
48
|
end
|
|
40
49
|
end
|
|
41
50
|
end
|
data/lib/robot_lab/run_config.rb
CHANGED
|
@@ -41,7 +41,7 @@ module RobotLab
|
|
|
41
41
|
CALLBACK_FIELDS = %i[on_tool_call on_tool_result on_content].freeze
|
|
42
42
|
|
|
43
43
|
# Infrastructure fields
|
|
44
|
-
INFRA_FIELDS = %i[bus enable_cache max_tool_rounds token_budget ractor_pool_size].freeze
|
|
44
|
+
INFRA_FIELDS = %i[bus enable_cache max_tool_rounds token_budget ractor_pool_size max_concurrent_robots].freeze
|
|
45
45
|
|
|
46
46
|
# All recognized fields
|
|
47
47
|
FIELDS = (LLM_FIELDS + TOOL_FIELDS + CALLBACK_FIELDS + INFRA_FIELDS).freeze
|
data/lib/robot_lab/version.rb
CHANGED
data/lib/robot_lab.rb
CHANGED
|
@@ -251,4 +251,8 @@ if defined?(Rails::Engine)
|
|
|
251
251
|
require 'robot_lab/rails_integration/engine'
|
|
252
252
|
require 'robot_lab/rails_integration/railtie'
|
|
253
253
|
require 'robot_lab/rails_integration/turbo_stream_callbacks'
|
|
254
|
+
require 'robot_lab/rails_integration/job'
|
|
255
|
+
|
|
256
|
+
# Convenience alias so job subclasses can inherit from RobotLab::Job
|
|
257
|
+
RobotLab::Job = RobotLab::RailsIntegration::Job
|
|
254
258
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: robot_lab
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dewayne VanHoozer
|
|
@@ -155,14 +155,14 @@ dependencies:
|
|
|
155
155
|
requirements:
|
|
156
156
|
- - "~>"
|
|
157
157
|
- !ruby/object:Gem::Version
|
|
158
|
-
version: 0.
|
|
158
|
+
version: 0.4.0
|
|
159
159
|
type: :runtime
|
|
160
160
|
prerelease: false
|
|
161
161
|
version_requirements: !ruby/object:Gem::Requirement
|
|
162
162
|
requirements:
|
|
163
163
|
- - "~>"
|
|
164
164
|
- !ruby/object:Gem::Version
|
|
165
|
-
version: 0.
|
|
165
|
+
version: 0.4.0
|
|
166
166
|
- !ruby/object:Gem::Dependency
|
|
167
167
|
name: ractor_queue
|
|
168
168
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -234,7 +234,6 @@ extra_rdoc_files: []
|
|
|
234
234
|
files:
|
|
235
235
|
- ".envrc"
|
|
236
236
|
- ".github/workflows/deploy-github-pages.yml"
|
|
237
|
-
- ".github/workflows/deploy-yard-docs.yml"
|
|
238
237
|
- ".irbrc"
|
|
239
238
|
- CHANGELOG.md
|
|
240
239
|
- COMMITS.md
|
|
@@ -244,9 +243,11 @@ files:
|
|
|
244
243
|
- docs/api/core/index.md
|
|
245
244
|
- docs/api/core/memory.md
|
|
246
245
|
- docs/api/core/network.md
|
|
246
|
+
- docs/api/core/result.md
|
|
247
247
|
- docs/api/core/robot.md
|
|
248
248
|
- docs/api/core/state.md
|
|
249
249
|
- docs/api/core/tool.md
|
|
250
|
+
- docs/api/errors.md
|
|
250
251
|
- docs/api/index.md
|
|
251
252
|
- docs/api/mcp/client.md
|
|
252
253
|
- docs/api/mcp/index.md
|
|
@@ -394,6 +395,7 @@ files:
|
|
|
394
395
|
- examples/28_mcp_discovery.rb
|
|
395
396
|
- examples/29_ractor_tools.rb
|
|
396
397
|
- examples/30_ractor_network.rb
|
|
398
|
+
- examples/31_launch_assessment.rb
|
|
397
399
|
- examples/README.md
|
|
398
400
|
- examples/prompts/assistant.md
|
|
399
401
|
- examples/prompts/audit_trail.md
|
|
@@ -444,12 +446,14 @@ files:
|
|
|
444
446
|
- examples/prompts/template_with_skills_test.md
|
|
445
447
|
- examples/prompts/triage.md
|
|
446
448
|
- lib/generators/robot_lab/install_generator.rb
|
|
449
|
+
- lib/generators/robot_lab/job_generator.rb
|
|
447
450
|
- lib/generators/robot_lab/robot_generator.rb
|
|
448
451
|
- lib/generators/robot_lab/templates/initializer.rb.tt
|
|
449
452
|
- lib/generators/robot_lab/templates/job.rb.tt
|
|
450
453
|
- lib/generators/robot_lab/templates/migration.rb.tt
|
|
451
454
|
- lib/generators/robot_lab/templates/result_model.rb.tt
|
|
452
455
|
- lib/generators/robot_lab/templates/robot.rb.tt
|
|
456
|
+
- lib/generators/robot_lab/templates/robot_job.rb.tt
|
|
453
457
|
- lib/generators/robot_lab/templates/robot_test.rb.tt
|
|
454
458
|
- lib/generators/robot_lab/templates/routing_robot.rb.tt
|
|
455
459
|
- lib/generators/robot_lab/templates/thread_model.rb.tt
|
|
@@ -482,6 +486,7 @@ files:
|
|
|
482
486
|
- lib/robot_lab/ractor_network_scheduler.rb
|
|
483
487
|
- lib/robot_lab/ractor_worker_pool.rb
|
|
484
488
|
- lib/robot_lab/rails_integration/engine.rb
|
|
489
|
+
- lib/robot_lab/rails_integration/job.rb
|
|
485
490
|
- lib/robot_lab/rails_integration/railtie.rb
|
|
486
491
|
- lib/robot_lab/rails_integration/turbo_stream_callbacks.rb
|
|
487
492
|
- lib/robot_lab/robot.rb
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
name: Deploy YARD Documentation to GitHub Pages
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- main
|
|
6
|
-
- develop
|
|
7
|
-
paths:
|
|
8
|
-
- "lib/**"
|
|
9
|
-
- "docs/assets/**"
|
|
10
|
-
- ".yardopts"
|
|
11
|
-
- "*.gemspec"
|
|
12
|
-
- ".github/workflows/deploy-yard-docs.yml"
|
|
13
|
-
workflow_dispatch:
|
|
14
|
-
|
|
15
|
-
permissions:
|
|
16
|
-
contents: write
|
|
17
|
-
pages: write
|
|
18
|
-
id-token: write
|
|
19
|
-
|
|
20
|
-
jobs:
|
|
21
|
-
deploy:
|
|
22
|
-
runs-on: ubuntu-latest
|
|
23
|
-
steps:
|
|
24
|
-
- name: Checkout code
|
|
25
|
-
uses: actions/checkout@v4
|
|
26
|
-
with:
|
|
27
|
-
fetch-depth: 0
|
|
28
|
-
|
|
29
|
-
- name: Setup Ruby
|
|
30
|
-
uses: ruby/setup-ruby@v1
|
|
31
|
-
with:
|
|
32
|
-
ruby-version: "3.3"
|
|
33
|
-
bundler-cache: true
|
|
34
|
-
|
|
35
|
-
- name: Install YARD
|
|
36
|
-
run: gem install yard
|
|
37
|
-
|
|
38
|
-
- name: Build YARD documentation
|
|
39
|
-
run: yard doc
|
|
40
|
-
|
|
41
|
-
- name: Configure Git
|
|
42
|
-
run: |
|
|
43
|
-
git config --local user.email "action@github.com"
|
|
44
|
-
git config --local user.name "GitHub Action"
|
|
45
|
-
|
|
46
|
-
- name: Deploy to GitHub Pages
|
|
47
|
-
uses: peaceiris/actions-gh-pages@v4
|
|
48
|
-
with:
|
|
49
|
-
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
50
|
-
publish_dir: ./doc
|
|
51
|
-
destination_dir: yard
|
|
52
|
-
keep_files: true
|