lex-scheduler 0.1.3 → 0.3.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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +16 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +36 -12
  5. data/CHANGELOG.md +38 -0
  6. data/CLAUDE.md +88 -0
  7. data/Dockerfile +1 -1
  8. data/Gemfile +11 -0
  9. data/README.md +43 -3
  10. data/docker_deploy.rb +1 -0
  11. data/lex-scheduler.gemspec +8 -14
  12. data/lib/legion/extensions/scheduler/actors/run_scheduler.rb +24 -16
  13. data/lib/legion/extensions/scheduler/actors/schedule_task.rb +24 -16
  14. data/lib/legion/extensions/scheduler/client.rb +31 -0
  15. data/lib/legion/extensions/scheduler/data/migrations/001_schedule_table.rb +15 -21
  16. data/lib/legion/extensions/scheduler/data/migrations/002_schedule_log.rb +12 -16
  17. data/lib/legion/extensions/scheduler/data/migrations/003_schedule_indexes.rb +2 -0
  18. data/lib/legion/extensions/scheduler/data/migrations/004_schedule_logs_indexes.rb +2 -0
  19. data/lib/legion/extensions/scheduler/data/migrations/005_add_payload_column.rb +3 -1
  20. data/lib/legion/extensions/scheduler/data/migrations/006_add_transform_to_schedule.rb +2 -0
  21. data/lib/legion/extensions/scheduler/data/models/schedule.rb +15 -5
  22. data/lib/legion/extensions/scheduler/data/models/schedule_log.rb +13 -5
  23. data/lib/legion/extensions/scheduler/runners/schedule.rb +22 -7
  24. data/lib/legion/extensions/scheduler/transport/messages/refresh.rb +28 -27
  25. data/lib/legion/extensions/scheduler/transport/messages/send_task.rb +38 -28
  26. data/lib/legion/extensions/scheduler/transport/queues/schedule.rb +18 -13
  27. data/lib/legion/extensions/scheduler/version.rb +1 -1
  28. data/lib/legion/extensions/scheduler.rb +2 -4
  29. metadata +17 -102
  30. data/CODE_OF_CONDUCT.md +0 -74
  31. data/Gemfile.lock +0 -128
  32. data/bitbucket-pipelines.yml +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04eb06cbdfc67f8e33dba90d2f491d067fd72356ebc84de0968fe0ca5dfb1d8b
4
- data.tar.gz: 8943579fcb0855ae53c8f69a96d5647083a9022be81c06906534ce5d77220d5e
3
+ metadata.gz: 17c661a4da86c3c66a0d66f54c6339e2724766bc2ae0231fadf5f167675e6c28
4
+ data.tar.gz: f73724797cd54b5932d57d0e83aae28f6f6cf2197312665771887cce22861371
5
5
  SHA512:
6
- metadata.gz: b51b8f0051ecde12d1767cb009a26f5b565dedfbb6ae02c7b073729037c428ead4f0266ad90adcfd46674470c43b6c2e6b6334b6804120ab3c1c31f0b39a85a2
7
- data.tar.gz: 0c3dbf65e28030c66f107f97e78e6becab2f348d7a0b044106bc190f1561b508ad9000461f43ac76ac40bf7579d640caf6b34fd497409c35580339b9a32024f6
6
+ metadata.gz: 320d897e6b2cb4f78f4b1cb52b927cd89ae88d6fb900a35612b0334f566ab96d24009d230f5f88f126367cd3d4065cd9161d2fa957d3e80adc0a52c3bd37bb10
7
+ data.tar.gz: c3950163ef797ffc297276efd96516eb39406741be6bc9d8d68e089e91a44b819685ba9c0f333ec0a4cbc5f3b3d0afc54d393aa96e3ea06877255cd78632c642
@@ -0,0 +1,16 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+
7
+ jobs:
8
+ ci:
9
+ uses: LegionIO/.github/.github/workflows/ci.yml@main
10
+
11
+ release:
12
+ needs: ci
13
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
14
+ uses: LegionIO/.github/.github/workflows/release.yml@main
15
+ secrets:
16
+ rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ Gemfile.lock
data/.rubocop.yml CHANGED
@@ -1,26 +1,50 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.4
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+
1
6
  Layout/LineLength:
2
- Max: 120
7
+ Max: 160
8
+
9
+ Layout/SpaceAroundEqualsInParameterDefault:
10
+ EnforcedStyle: space
11
+
12
+ Layout/HashAlignment:
13
+ EnforcedHashRocketStyle: table
14
+ EnforcedColonStyle: table
15
+
3
16
  Metrics/MethodLength:
4
- Max: 30
17
+ Max: 50
18
+
5
19
  Metrics/ClassLength:
6
20
  Max: 1500
21
+
22
+ Metrics/ModuleLength:
23
+ Max: 1500
24
+
7
25
  Metrics/BlockLength:
8
- Max: 50
26
+ Max: 40
27
+ Exclude:
28
+ - 'spec/**/*'
29
+
9
30
  Metrics/AbcSize:
10
- Max: 100
31
+ Max: 60
32
+
11
33
  Metrics/CyclomaticComplexity:
12
34
  Max: 15
35
+
13
36
  Metrics/PerceivedComplexity:
14
- Max: 20
37
+ Max: 17
38
+
15
39
  Style/Documentation:
16
40
  Enabled: false
17
- AllCops:
18
- TargetRubyVersion: 2.5
19
- NewCops: enable
20
- SuggestExtensions: false
41
+
42
+ Style/SymbolArray:
43
+ Enabled: true
44
+
21
45
  Style/FrozenStringLiteralComment:
22
- Enabled: false
46
+ Enabled: true
47
+ EnforcedStyle: always
48
+
23
49
  Naming/FileName:
24
50
  Enabled: false
25
- Style/ClassAndModuleChildren:
26
- Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,38 @@
1
+ # Changelog
2
+
3
+ ## [0.3.0] - 2026-03-18
4
+
5
+ ### Fixed
6
+ - Migrations 001/002 rewritten as Sequel DSL (cross-DB: SQLite, PostgreSQL, MySQL)
7
+ - Migration 005 column type `File` -> `String, text: true`
8
+ - ScheduleLog model class name (was defining duplicate `Schedule`)
9
+ - Queue TTL from 5ms to 5000ms (messages were expiring instantly)
10
+ - Nil guard on `last_run` (was TypeError on new schedules)
11
+ - Nil guard on function lookup (was NoMethodError on missing function)
12
+ - Removed dead cron guard (`Time.now < previous_time` was always false)
13
+ - ScheduleLog records now created after each dispatch
14
+ - Entry point `data_required?` is now class method only (framework requirement)
15
+
16
+ ### Added
17
+ - Standalone `Scheduler::Client` for programmatic schedule management
18
+ - Comprehensive spec coverage (92%+)
19
+
20
+ ### Removed
21
+ - ModeScheduler, ModeTransition, EmergencyPromotion runners (dead code, no actor wiring)
22
+ - Dead `message_example` in Refresh message (copy-paste from lex-node)
23
+
24
+ ## [0.2.0] - 2026-03-17
25
+
26
+ ### Added
27
+ - `Runners::ModeScheduler`: time-based operating mode evaluation (active/idle/dream/maintenance)
28
+ - `Runners::ModeTransition`: orchestrated mode transitions with critical task blocking and force override
29
+ - `Runners::EmergencyPromotion`: immediate active mode promotion on critical events (extinction, consent violation)
30
+ - Configurable schedules, emergency patterns, and transition settings
31
+
32
+ ### Fixed
33
+ - Emergency promotion logging uses safe method dispatch for private `Legion::Logging.warn`
34
+
35
+ ## [0.1.4] - 2026-03-13
36
+
37
+ ### Added
38
+ - Initial release
data/CLAUDE.md ADDED
@@ -0,0 +1,88 @@
1
+ # lex-scheduler: Cron and Interval Task Scheduling for LegionIO
2
+
3
+ **Repository Level 3 Documentation**
4
+ - **Parent**: `/Users/miverso2/rubymine/legion/extensions-core/CLAUDE.md`
5
+ - **Grandparent**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
6
+
7
+ ## Purpose
8
+
9
+ Core Legion Extension that manages scheduled, delayed, and cron-style task execution. Reads schedule definitions from the database (interval seconds or cron expressions via `fugit`), determines which tasks are due, and publishes them to the message bus. Uses a distributed lock via `Legion::Cache` to ensure only one node runs the scheduler at a time. Requires `legion-data` (`data_required? true`).
10
+
11
+ **GitHub**: https://github.com/LegionIO/lex-scheduler
12
+ **License**: MIT
13
+ **Version**: 0.3.0
14
+
15
+ ## Architecture
16
+
17
+ ```
18
+ Legion::Extensions::Scheduler
19
+ ├── Actors/
20
+ │ ├── RunScheduler # Every-type actor: periodically calls schedule_tasks
21
+ │ └── ScheduleTask # Every-type actor: periodically publishes refresh messages
22
+ ├── Runners/
23
+ │ └── Schedule # Core scheduling logic
24
+ │ ├── schedule_tasks # Queries DB for due schedules, publishes task messages
25
+ │ ├── send_task # Routes to Dynamic or SendTask (transformation path)
26
+ │ ├── refresh # Acquires distributed scheduler lock via cache (2s TTL)
27
+ │ └── push_refresh # Broadcasts refresh message to cluster
28
+ ├── Data/
29
+ │ ├── Models/
30
+ │ │ ├── Schedule # Sequel model: function_id, interval, cron, active, last_run,
31
+ │ │ │ # task_ttl, payload (JSON), transformation (ERB)
32
+ │ │ └── ScheduleLog # Execution history
33
+ │ └── Migrations/
34
+ │ ├── 001_schedule_table
35
+ │ ├── 002_schedule_log
36
+ │ ├── 003_schedule_indexes
37
+ │ ├── 004_schedule_logs_indexes
38
+ │ ├── 005_add_payload_column
39
+ │ └── 006_add_transform_to_schedule
40
+ └── Transport/
41
+ ├── Queues/Schedule # Schedule queue
42
+ └── Messages/
43
+ ├── Refresh # Cluster-wide refresh notification
44
+ └── SendTask # Task execution message (transformation path)
45
+ ```
46
+
47
+ ## Key Design Patterns
48
+
49
+ ### Distributed Lock
50
+
51
+ Uses `Legion::Cache.set('scheduler_schedule_lock', node_name, 2)` to ensure only one node in the cluster runs `schedule_tasks` at a time. The lock has a 2-second TTL, refreshed each cycle via `refresh`.
52
+
53
+ ### Dual Schedule Types
54
+
55
+ - **Interval**: Integer seconds since last run (`row.interval > 0`)
56
+ - **Cron**: Cron expression string parsed by `Fugit.parse`. Supports both duration strings (`Fugit::Duration`, responds to `to_sec`) and standard cron expressions (`Fugit::Cron`, responds to `previous_time`)
57
+
58
+ ### Transformation Support
59
+
60
+ Scheduled tasks can include an ERB `transformation` column. If present, `send_task` routes through `task.subtask.transform` (via `lex-transformer`) instead of `Legion::Transport::Messages::Dynamic`.
61
+
62
+ ## Dependencies
63
+
64
+ | Gem | Purpose |
65
+ |-----|---------|
66
+ | `fugit` (>= 1.9) | Cron expression parsing (supports duration and cron syntax) |
67
+ | `legion-data` | Required - schedule persistence |
68
+ | `legion-cache` | Required - distributed scheduler lock |
69
+
70
+ ## Database Schema
71
+
72
+ **schedules**: `id`, `function_id`, `interval`, `cron`, `active`, `last_run`, `task_ttl`, `payload` (JSON), `transformation` (ERB template)
73
+
74
+ **schedule_logs**: Execution history linked to schedules
75
+
76
+ ## Testing
77
+
78
+ ```bash
79
+ bundle install
80
+ bundle exec rspec
81
+ bundle exec rubocop
82
+ ```
83
+
84
+ Spec files include `fugit_spec.rb` for cron expression parsing.
85
+
86
+ ---
87
+
88
+ **Maintained By**: Matthew Iverson (@Esity)
data/Dockerfile CHANGED
@@ -6,4 +6,4 @@ RUN apk update && apk add build-base tzdata postgresql-dev mysql-client mariadb-
6
6
 
7
7
  COPY . ./
8
8
  RUN gem install lex-scheduler legion-data --no-document --no-prerelease
9
- CMD ruby --jit $(which legionio)
9
+ CMD ruby --yjit $(which legionio)
data/Gemfile CHANGED
@@ -1,3 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
6
+
7
+ group :test do
8
+ gem 'rake'
9
+ gem 'rspec', '~> 3.13'
10
+ gem 'rubocop', '~> 1.75'
11
+ gem 'sequel'
12
+ gem 'simplecov'
13
+ gem 'sqlite3'
14
+ end
data/README.md CHANGED
@@ -1,6 +1,46 @@
1
- # Legion::Extensions::Scheduler
2
- Used to schedule tasks cron style inside Legion
1
+ # lex-scheduler
2
+
3
+ Cron and interval task scheduling for [LegionIO](https://github.com/LegionIO/LegionIO). Reads schedule definitions from the database, determines which tasks are due, and publishes them to the message bus. Uses a distributed lock via `legion-cache` to ensure only one node runs the scheduler at a time.
4
+
5
+ This is a core LEX required for scheduled task execution.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ gem install lex-scheduler
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Schedules are stored in the database with either a cron expression or an interval:
16
+
17
+ - **Interval**: Run every N seconds since the last completion (integer)
18
+ - **Cron**: Run at specific times using standard cron syntax (`*/5 * * * *`) or human-readable expressions (`every day at noon`) parsed by `fugit`
19
+
20
+ Schedules can also carry a `transformation` ERB template. If present, the scheduled task is routed through `lex-transformer` before execution.
21
+
22
+ ### Adding Schedules
23
+
24
+ Insert records into the `schedules` table via `legion-data`:
25
+
26
+ ```ruby
27
+ Legion::Extensions::Scheduler::Data::Models::Schedule.insert(
28
+ function_id: 42,
29
+ interval: 300, # run every 5 minutes
30
+ active: 1,
31
+ last_run: Time.now,
32
+ payload: '{}'
33
+ )
34
+ ```
35
+
36
+ ## Requirements
37
+
38
+ - Ruby >= 3.4
39
+ - [LegionIO](https://github.com/LegionIO/LegionIO) framework
40
+ - `legion-data` (schedule persistence)
41
+ - `legion-cache` (distributed scheduler lock)
42
+ - `fugit` >= 1.9 (cron expression parsing)
3
43
 
4
44
  ## License
5
45
 
6
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
46
+ MIT
data/docker_deploy.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  name = 'scheduler'
4
5
  require "./lib/legion/extensions/#{name}/version"
@@ -10,27 +10,21 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = 'LEX::Scheduler'
12
12
  spec.description = 'Schedules and manages delayed, async and cron style tasks'
13
- spec.homepage = 'https://bitbucket.org/legion-io/lex-scheduler'
13
+ spec.homepage = 'https://github.com/LegionIO/lex-scheduler'
14
14
  spec.license = 'MIT'
15
- spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
15
+ spec.required_ruby_version = '>= 3.4'
16
16
 
17
17
  spec.metadata['homepage_uri'] = spec.homepage
18
- spec.metadata['source_code_uri'] = 'https://bitbucket.org/legion-io/lex-scheduler'
19
- spec.metadata['documentation_uri'] = 'https://legionio.atlassian.net/wiki/spaces/LEX/pages/612139049'
20
- spec.metadata['changelog_uri'] = 'https://legionio.atlassian.net/wiki/spaces/LEX/pages/612171789'
21
- spec.metadata['bug_tracker_uri'] = 'https://bitbucket.org/legion-io/lex-scheduler/issues'
18
+ spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-scheduler'
19
+ spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-scheduler'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-scheduler'
21
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-scheduler/issues'
22
+ spec.metadata['rubygems_mfa_required'] = 'true'
22
23
 
23
24
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
25
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
26
  end
26
27
  spec.require_paths = ['lib']
27
28
 
28
- spec.add_dependency 'fugit', '>= 1.3.9'
29
-
30
- spec.add_development_dependency 'bundler', '>= 2'
31
- spec.add_development_dependency 'legionio'
32
- spec.add_development_dependency 'rake'
33
- spec.add_development_dependency 'rspec'
34
- spec.add_development_dependency 'rubocop'
35
- spec.add_development_dependency 'simplecov'
29
+ spec.add_dependency 'fugit', '>= 1.9'
36
30
  end
@@ -1,23 +1,31 @@
1
- module Legion::Extensions::Scheduler::Actor
2
- class RunScheduler < Legion::Extensions::Actors::Every
3
- def runner_function
4
- 'schedule_tasks'
5
- end
1
+ # frozen_string_literal: true
6
2
 
7
- def runner_class
8
- Legion::Extensions::Scheduler::Runners::Schedule
9
- end
3
+ module Legion
4
+ module Extensions
5
+ module Scheduler
6
+ module Actor
7
+ class RunScheduler < Legion::Extensions::Actors::Every
8
+ def runner_function
9
+ 'schedule_tasks'
10
+ end
10
11
 
11
- def use_runner?
12
- false
13
- end
12
+ def runner_class
13
+ Legion::Extensions::Scheduler::Runners::Schedule
14
+ end
14
15
 
15
- def check_subtask?
16
- false
17
- end
16
+ def use_runner?
17
+ false
18
+ end
19
+
20
+ def check_subtask?
21
+ false
22
+ end
18
23
 
19
- def generate_task?
20
- false
24
+ def generate_task?
25
+ false
26
+ end
27
+ end
28
+ end
21
29
  end
22
30
  end
23
31
  end
@@ -1,23 +1,31 @@
1
- module Legion::Extensions::Scheduler::Actor
2
- class ScheduleTask < Legion::Extensions::Actors::Every
3
- def runner_function
4
- 'push_refresh'
5
- end
1
+ # frozen_string_literal: true
6
2
 
7
- def runner_class
8
- Legion::Extensions::Scheduler::Runners::Schedule
9
- end
3
+ module Legion
4
+ module Extensions
5
+ module Scheduler
6
+ module Actor
7
+ class ScheduleTask < Legion::Extensions::Actors::Every
8
+ def runner_function
9
+ 'push_refresh'
10
+ end
10
11
 
11
- def use_runner?
12
- false
13
- end
12
+ def runner_class
13
+ Legion::Extensions::Scheduler::Runners::Schedule
14
+ end
14
15
 
15
- def check_subtask?
16
- false
17
- end
16
+ def use_runner?
17
+ false
18
+ end
19
+
20
+ def check_subtask?
21
+ false
22
+ end
18
23
 
19
- def generate_task?
20
- false
24
+ def generate_task?
25
+ false
26
+ end
27
+ end
28
+ end
21
29
  end
22
30
  end
23
31
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fugit'
4
+ require_relative 'runners/schedule'
5
+
6
+ module Legion
7
+ module Extensions
8
+ module Scheduler
9
+ class Client
10
+ include Runners::Schedule
11
+
12
+ def initialize(data_model: nil, fugit: nil)
13
+ @data_model = data_model
14
+ @fugit = fugit || Fugit
15
+ end
16
+
17
+ def models_class
18
+ @data_model || Data::Model
19
+ end
20
+
21
+ def log
22
+ @log ||= defined?(Legion::Logging) ? Legion::Logging : Logger.new($stdout)
23
+ end
24
+
25
+ def settings
26
+ { options: {} }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,24 +1,18 @@
1
- Sequel.migration do
2
- up do
3
- run '
4
- create table schedules (
5
- id int auto_increment,
6
- function_id int null,
7
- active tinyint default 1 not null,
8
- `interval` int null,
9
- cron varchar(255) null,
10
- name varchar(255) null,
11
- description blob null,
12
- task_ttl int null,
13
- last_run datetime null,
14
- created datetime default CURRENT_TIMESTAMP not null,
15
- updated datetime null,
16
- constraint schedules_pk
17
- primary key (id)
18
- );'
19
- end
1
+ # frozen_string_literal: true
20
2
 
21
- down do
22
- drop_table :schedules
3
+ Sequel.migration do
4
+ change do
5
+ create_table(:schedules) do
6
+ primary_key :id
7
+ foreign_key :function_id, :functions, null: true
8
+ String :name, null: false
9
+ Integer :interval, null: true
10
+ String :cron, null: true, text: true
11
+ Integer :task_ttl, null: true
12
+ TrueClass :active, default: true
13
+ DateTime :last_run, null: true
14
+ DateTime :created, default: Sequel::CURRENT_TIMESTAMP
15
+ DateTime :updated, null: true
16
+ end
23
17
  end
24
18
  end
@@ -1,19 +1,15 @@
1
- Sequel.migration do
2
- up do
3
- run '
4
- create table schedule_logs (
5
- id int auto_increment,
6
- schedule_id int not null,
7
- status varchar(255) null,
8
- time_queued datetime default CURRENT_TIMESTAMP not null,
9
- task_id int null,
10
- created datetime default CURRENT_TIMESTAMP not null,
11
- updated datetime null,
12
- constraint schedule_logs_pk primary key (id)
13
- );'
14
- end
1
+ # frozen_string_literal: true
15
2
 
16
- down do
17
- drop_table :schedule_logs
3
+ Sequel.migration do
4
+ change do
5
+ create_table(:schedule_logs) do
6
+ primary_key :id
7
+ foreign_key :schedule_id, :schedules, null: true
8
+ foreign_key :task_id, :tasks, null: true
9
+ foreign_key :function_id, :functions, null: true
10
+ TrueClass :success, null: true
11
+ String :status, null: true
12
+ DateTime :created, default: Sequel::CURRENT_TIMESTAMP
13
+ end
18
14
  end
19
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Sequel.migration do
2
4
  change do
3
5
  add_index :schedules, :last_run, name: 'schedules_last_run_index'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Sequel.migration do
2
4
  change do
3
5
  add_index :schedule_logs, :schedule_id
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Sequel.migration do
2
4
  change do
3
5
  alter_table(:schedules) do
4
- add_column :payload, File, null: false, default: '{}'
6
+ add_column :payload, String, text: true, null: true, default: '{}'
5
7
  end
6
8
  end
7
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Sequel.migration do
2
4
  change do
3
5
  alter_table(:schedules) do
@@ -1,7 +1,17 @@
1
- module Legion::Extensions::Scheduler::Data::Model
2
- class Schedule < Sequel::Model
3
- one_to_many :schedule_logs
4
- # many_to_one :task, class: Legion::Data::Model::Task
5
- many_to_one :function, class: '::Legion::Data::Model::Function'
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Scheduler
6
+ module Data
7
+ module Model
8
+ class Schedule < Sequel::Model
9
+ one_to_many :schedule_logs
10
+ # many_to_one :task, class: Legion::Data::Model::Task
11
+ many_to_one :function, class: '::Legion::Data::Model::Function'
12
+ end
13
+ end
14
+ end
15
+ end
6
16
  end
7
17
  end
@@ -1,7 +1,15 @@
1
- module Legion::Extensions::Scheduler::Data::Model
2
- class Schedule < Sequel::Model
3
- one_to_many :schedule_logs
4
- many_to_one :task
5
- many_to_one :function
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Scheduler
6
+ module Data
7
+ module Model
8
+ class ScheduleLog < Sequel::Model(:schedule_logs)
9
+ many_to_one :schedule, class: '::Legion::Extensions::Scheduler::Data::Model::Schedule'
10
+ end
11
+ end
12
+ end
13
+ end
6
14
  end
7
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fugit'
2
4
 
3
5
  module Legion
@@ -10,6 +12,7 @@ module Legion
10
12
  include Legion::Extensions::Helpers::Data
11
13
 
12
14
  include Legion::Extensions::Helpers::Lex
15
+
13
16
  def push_refresh(**)
14
17
  Legion::Extensions::Scheduler::Transport::Messages::Refresh.new.publish
15
18
  end
@@ -22,25 +25,37 @@ module Legion
22
25
  return unless Legion::Cache.get('scheduler_schedule_lock') == Legion::Settings[:client][:name]
23
26
 
24
27
  models_class::Schedule.where(active: 1).each do |row|
28
+ last_run = row.values[:last_run] || Time.at(0)
29
+
25
30
  if row.values[:interval].is_a?(Integer) && row.values[:interval].positive?
26
- next if (Time.now - row.values[:last_run]) < row.values[:interval]
31
+ next if (Time.now - last_run) < row.values[:interval]
27
32
  elsif row.values[:cron].is_a? String
28
33
  cron_class = Fugit.parse(row.values[:cron])
29
34
  if cron_class.respond_to? :to_sec
30
- next if (Time.now - row.values[:last_run]) < cron_class.to_sec
35
+ next if (Time.now - last_run) < cron_class.to_sec
31
36
  elsif cron_class.respond_to? :previous_time
32
- next if Time.now < Time.parse(cron_class.previous_time.to_s)
33
- next if row.values[:last_run] > Time.parse(cron_class.previous_time.to_s)
37
+ prev = Time.parse(cron_class.previous_time.to_s)
38
+ next if last_run > prev
34
39
  end
35
40
  end
36
41
 
37
42
  function = Legion::Data::Model::Function[row.values[:function_id]]
43
+ next unless function
38
44
 
39
45
  send_task(transformation: row.values[:transformation],
40
- function_id: row.values[:function_id],
41
- expiration: row.values[:task_ttl],
42
- function: function.values[:name],
46
+ function_id: row.values[:function_id],
47
+ expiration: row.values[:task_ttl],
48
+ function: function.values[:name],
43
49
  **Legion::JSON.load(row.values[:payload]))
50
+
51
+ models_class::ScheduleLog.insert(
52
+ schedule_id: row.values[:id],
53
+ function_id: row.values[:function_id],
54
+ success: true,
55
+ status: 'dispatched',
56
+ created: Sequel::CURRENT_TIMESTAMP
57
+ )
58
+
44
59
  row.update(last_run: Sequel::CURRENT_TIMESTAMP)
45
60
  end
46
61
  end
@@ -1,35 +1,36 @@
1
- module Legion::Extensions::Scheduler::Transport::Messages
2
- class Refresh < Legion::Transport::Message
3
- def routing_key
4
- 'schedule'
5
- end
1
+ # frozen_string_literal: true
6
2
 
7
- def type
8
- 'task'
9
- end
3
+ module Legion
4
+ module Extensions
5
+ module Scheduler
6
+ module Transport
7
+ module Messages
8
+ class Refresh < Legion::Transport::Message
9
+ def routing_key
10
+ 'schedule'
11
+ end
10
12
 
11
- def expiration
12
- 5000
13
- end
13
+ def type
14
+ 'task'
15
+ end
14
16
 
15
- def encrypt?
16
- false
17
- end
17
+ def expiration
18
+ 5000
19
+ end
18
20
 
19
- def message
20
- {
21
- function: 'refresh',
22
- runner_class: 'Legion::Extensions::Scheduler::Runners::Schedule'
23
- }
24
- end
21
+ def encrypt?
22
+ false
23
+ end
25
24
 
26
- def message_example
27
- { function: 'push_cluster_secret',
28
- node_name: Legion::Settings[:client][:name],
29
- queue_name: "node.#{Legion::Settings[:client][:name]}",
30
- runner_class: 'Legion::Extensions::Node::Runners::Crypt',
31
- # public_key: Base64.encode64(Legion::Crypt.public_key) }
32
- public_key: Legion::Crypt.public_key }
25
+ def message
26
+ {
27
+ function: 'refresh',
28
+ runner_class: 'Legion::Extensions::Scheduler::Runners::Schedule'
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
33
34
  end
34
35
  end
35
36
  end
@@ -1,36 +1,46 @@
1
- module Legion::Extensions::Scheduler::Transport::Messages
2
- class SendTask < Legion::Transport::Message
3
- def type
4
- 'task'
5
- end
1
+ # frozen_string_literal: true
6
2
 
7
- def message
8
- return @options if routing_key == 'task.subtask.transform'
3
+ module Legion
4
+ module Extensions
5
+ module Scheduler
6
+ module Transport
7
+ module Messages
8
+ class SendTask < Legion::Transport::Message
9
+ def type
10
+ 'task'
11
+ end
9
12
 
10
- {
11
- args: @options[:args] || @options,
12
- function: function.values[:name]
13
- }
14
- end
13
+ def message
14
+ return @options if routing_key == 'task.subtask.transform'
15
15
 
16
- def routing_key
17
- @routing_key ||= if @options.key?(:routing_key)
18
- @options[:routing_key]
19
- else
20
- "#{function.runner.extension.values[:name]}.#{function.runner.values[:name]}.#{function.values[:name]}" # rubocop:disable Layout/LineLength
21
- end
22
- end
16
+ {
17
+ args: @options[:args] || @options,
18
+ function: function.values[:name]
19
+ }
20
+ end
23
21
 
24
- def exchange
25
- @exchange ||= if @options.key?(:exchange) && @options[:exchange].is_a?(String)
26
- Legion::Transport::Exchange.new(@options[:exchange])
27
- else
28
- Legion::Transport::Exchange.new(function.runner.extension.values[:exchange])
29
- end
30
- end
22
+ def routing_key
23
+ @routing_key ||= if @options.key?(:routing_key)
24
+ @options[:routing_key]
25
+ else
26
+ "#{function.runner.extension.values[:name]}.#{function.runner.values[:name]}.#{function.values[:name]}"
27
+ end
28
+ end
29
+
30
+ def exchange
31
+ @exchange ||= if @options.key?(:exchange) && @options[:exchange].is_a?(String)
32
+ Legion::Transport::Exchange.new(@options[:exchange])
33
+ else
34
+ Legion::Transport::Exchange.new(function.runner.extension.values[:exchange])
35
+ end
36
+ end
31
37
 
32
- def function
33
- @function ||= Legion::Data::Model::Function[@options[:function_id]]
38
+ def function
39
+ @function ||= Legion::Data::Model::Function[@options[:function_id]]
40
+ end
41
+ end
42
+ end
43
+ end
34
44
  end
35
45
  end
36
46
  end
@@ -1,16 +1,21 @@
1
- module Legion::Extensions::Scheduler
2
- module Transport
3
- module Queues
4
- class Schedule < Legion::Transport::Queue
5
- def queue_options
6
- {
7
- arguments: {
8
- 'x-single-active-consumer': true,
9
- 'x-max-priority': 255,
10
- 'x-message-ttl': 5
11
- },
12
- auto_delete: false
13
- }
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Scheduler
6
+ module Transport
7
+ module Queues
8
+ class Schedule < Legion::Transport::Queue
9
+ def queue_options
10
+ {
11
+ arguments: {
12
+ 'x-single-active-consumer': true,
13
+ 'x-message-ttl': 5000
14
+ },
15
+ auto_delete: false
16
+ }
17
+ end
18
+ end
14
19
  end
15
20
  end
16
21
  end
@@ -3,7 +3,7 @@
3
3
  module Legion
4
4
  module Extensions
5
5
  module Scheduler
6
- VERSION = '0.1.3'
6
+ VERSION = '0.3.0'
7
7
  end
8
8
  end
9
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'legion/extensions/scheduler/version'
2
4
 
3
5
  module Legion
@@ -8,10 +10,6 @@ module Legion
8
10
  def self.data_required?
9
11
  true
10
12
  end
11
-
12
- def data_required?
13
- true
14
- end
15
13
  end
16
14
  end
17
15
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2021-03-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: fugit
@@ -16,98 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: 1.3.9
18
+ version: '1.9'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: 1.3.9
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '2'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '2'
41
- - !ruby/object:Gem::Dependency
42
- name: legionio
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: simplecov
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
25
+ version: '1.9'
111
26
  description: Schedules and manages delayed, async and cron style tasks
112
27
  email:
113
28
  - matthewdiverson@gmail.com
@@ -115,22 +30,23 @@ executables: []
115
30
  extensions: []
116
31
  extra_rdoc_files: []
117
32
  files:
33
+ - ".github/workflows/ci.yml"
118
34
  - ".gitignore"
119
35
  - ".rspec"
120
36
  - ".rubocop.yml"
121
- - CODE_OF_CONDUCT.md
37
+ - CHANGELOG.md
38
+ - CLAUDE.md
122
39
  - Dockerfile
123
40
  - Gemfile
124
- - Gemfile.lock
125
41
  - LICENSE.txt
126
42
  - README.md
127
43
  - Rakefile
128
- - bitbucket-pipelines.yml
129
44
  - docker_deploy.rb
130
45
  - lex-scheduler.gemspec
131
46
  - lib/legion/extensions/scheduler.rb
132
47
  - lib/legion/extensions/scheduler/actors/run_scheduler.rb
133
48
  - lib/legion/extensions/scheduler/actors/schedule_task.rb
49
+ - lib/legion/extensions/scheduler/client.rb
134
50
  - lib/legion/extensions/scheduler/data/migrations/001_schedule_table.rb
135
51
  - lib/legion/extensions/scheduler/data/migrations/002_schedule_log.rb
136
52
  - lib/legion/extensions/scheduler/data/migrations/003_schedule_indexes.rb
@@ -144,16 +60,16 @@ files:
144
60
  - lib/legion/extensions/scheduler/transport/messages/send_task.rb
145
61
  - lib/legion/extensions/scheduler/transport/queues/schedule.rb
146
62
  - lib/legion/extensions/scheduler/version.rb
147
- homepage: https://bitbucket.org/legion-io/lex-scheduler
63
+ homepage: https://github.com/LegionIO/lex-scheduler
148
64
  licenses:
149
65
  - MIT
150
66
  metadata:
151
- homepage_uri: https://bitbucket.org/legion-io/lex-scheduler
152
- source_code_uri: https://bitbucket.org/legion-io/lex-scheduler
153
- documentation_uri: https://legionio.atlassian.net/wiki/spaces/LEX/pages/612139049
154
- changelog_uri: https://legionio.atlassian.net/wiki/spaces/LEX/pages/612171789
155
- bug_tracker_uri: https://bitbucket.org/legion-io/lex-scheduler/issues
156
- post_install_message:
67
+ homepage_uri: https://github.com/LegionIO/lex-scheduler
68
+ source_code_uri: https://github.com/LegionIO/lex-scheduler
69
+ documentation_uri: https://github.com/LegionIO/lex-scheduler
70
+ changelog_uri: https://github.com/LegionIO/lex-scheduler
71
+ bug_tracker_uri: https://github.com/LegionIO/lex-scheduler/issues
72
+ rubygems_mfa_required: 'true'
157
73
  rdoc_options: []
158
74
  require_paths:
159
75
  - lib
@@ -161,15 +77,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
161
77
  requirements:
162
78
  - - ">="
163
79
  - !ruby/object:Gem::Version
164
- version: 2.5.0
80
+ version: '3.4'
165
81
  required_rubygems_version: !ruby/object:Gem::Requirement
166
82
  requirements:
167
83
  - - ">="
168
84
  - !ruby/object:Gem::Version
169
85
  version: '0'
170
86
  requirements: []
171
- rubygems_version: 3.1.4
172
- signing_key:
87
+ rubygems_version: 3.6.9
173
88
  specification_version: 4
174
89
  summary: LEX::Scheduler
175
90
  test_files: []
data/CODE_OF_CONDUCT.md DELETED
@@ -1,74 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, gender identity and expression, level of experience,
9
- nationality, personal appearance, race, religion, or sexual identity and
10
- orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at matthewdiverson@gmail.com. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [https://contributor-covenant.org/version/1/4][version]
72
-
73
- [homepage]: https://contributor-covenant.org
74
- [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile.lock DELETED
@@ -1,128 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- lex-scheduler (0.1.2)
5
- fugit (>= 1.3.9)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- amq-protocol (2.3.2)
11
- ast (2.4.2)
12
- aws-eventstream (1.1.0)
13
- aws-sigv4 (1.2.2)
14
- aws-eventstream (~> 1, >= 1.0.2)
15
- bunny (2.17.0)
16
- amq-protocol (~> 2.3, >= 2.3.1)
17
- concurrent-ruby (1.1.8)
18
- concurrent-ruby-ext (1.1.8)
19
- concurrent-ruby (= 1.1.8)
20
- connection_pool (2.2.3)
21
- daemons (1.3.1)
22
- dalli (2.7.11)
23
- diff-lcs (1.4.4)
24
- docile (1.3.5)
25
- et-orbi (1.2.4)
26
- tzinfo
27
- fugit (1.4.2)
28
- et-orbi (~> 1.1, >= 1.1.8)
29
- raabro (~> 1.4)
30
- json_pure (2.5.1)
31
- legion-cache (1.1.1)
32
- connection_pool (>= 2.2.3)
33
- dalli (>= 2.7)
34
- redis (>= 4.2)
35
- legion-crypt (0.3.0)
36
- vault (>= 0.15.0)
37
- legion-exceptions (1.1.5)
38
- legion-json (1.1.4)
39
- json_pure
40
- legion-exceptions (>= 1.1.5)
41
- multi_json
42
- legion-logging (1.1.4)
43
- rainbow (~> 3)
44
- legion-settings (1.1.3)
45
- legion-json
46
- legion-logging
47
- legion-transport (1.1.9)
48
- bunny (>= 2.17.0)
49
- concurrent-ruby (>= 1.1.7)
50
- legion-json
51
- legionio (0.4.3)
52
- concurrent-ruby (>= 1.1.7)
53
- concurrent-ruby-ext (>= 1.1.7)
54
- daemons (>= 1.3.1)
55
- legion-cache
56
- legion-crypt (>= 0.2.0)
57
- legion-exceptions
58
- legion-json
59
- legion-logging
60
- legion-settings
61
- legion-transport (>= 1.1.9)
62
- lex-node
63
- oj (>= 3.10)
64
- thor (>= 1)
65
- lex-node (0.1.7)
66
- multi_json (1.15.0)
67
- oj (3.11.2)
68
- parallel (1.20.1)
69
- parser (3.0.0.0)
70
- ast (~> 2.4.1)
71
- raabro (1.4.0)
72
- rainbow (3.0.0)
73
- rake (13.0.3)
74
- redis (4.2.5)
75
- regexp_parser (2.1.1)
76
- rexml (3.2.4)
77
- rspec (3.10.0)
78
- rspec-core (~> 3.10.0)
79
- rspec-expectations (~> 3.10.0)
80
- rspec-mocks (~> 3.10.0)
81
- rspec-core (3.10.1)
82
- rspec-support (~> 3.10.0)
83
- rspec-expectations (3.10.1)
84
- diff-lcs (>= 1.2.0, < 2.0)
85
- rspec-support (~> 3.10.0)
86
- rspec-mocks (3.10.2)
87
- diff-lcs (>= 1.2.0, < 2.0)
88
- rspec-support (~> 3.10.0)
89
- rspec-support (3.10.2)
90
- rubocop (1.11.0)
91
- parallel (~> 1.10)
92
- parser (>= 3.0.0.0)
93
- rainbow (>= 2.2.2, < 4.0)
94
- regexp_parser (>= 1.8, < 3.0)
95
- rexml
96
- rubocop-ast (>= 1.2.0, < 2.0)
97
- ruby-progressbar (~> 1.7)
98
- unicode-display_width (>= 1.4.0, < 3.0)
99
- rubocop-ast (1.4.1)
100
- parser (>= 2.7.1.5)
101
- ruby-progressbar (1.11.0)
102
- simplecov (0.21.2)
103
- docile (~> 1.1)
104
- simplecov-html (~> 0.11)
105
- simplecov_json_formatter (~> 0.1)
106
- simplecov-html (0.12.3)
107
- simplecov_json_formatter (0.1.2)
108
- thor (1.1.0)
109
- tzinfo (2.0.4)
110
- concurrent-ruby (~> 1.0)
111
- unicode-display_width (2.0.0)
112
- vault (0.15.0)
113
- aws-sigv4
114
-
115
- PLATFORMS
116
- ruby
117
-
118
- DEPENDENCIES
119
- bundler (>= 2)
120
- legionio
121
- lex-scheduler!
122
- rake
123
- rspec
124
- rubocop
125
- simplecov
126
-
127
- BUNDLED WITH
128
- 2.1.4
@@ -1,19 +0,0 @@
1
- image: ruby:2.7
2
-
3
- pipelines:
4
- tags:
5
- "v*":
6
- - step:
7
- name: Push to RubyGems
8
- deployment: RubyGems
9
- script:
10
- - gem install gem-release
11
- - (umask 077 ; echo $gem_creds | base64 --decode > ~/.gem/credentials)
12
- - gem release
13
- artifacts:
14
- - pkg/**
15
- - step:
16
- name: Push to Docker
17
- deployment: Docker
18
- script:
19
- - './docker_deploy.rb'