nexus_semantic_logger 1.14.1 → 1.15.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/.github/workflows/ci.yml +52 -0
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/Appraisals +13 -0
- data/Gemfile +1 -0
- data/README.md +14 -0
- data/gemfiles/rails_7_1.gemfile +11 -0
- data/gemfiles/rails_7_2.gemfile +11 -0
- data/gemfiles/rails_8_0.gemfile +11 -0
- data/lib/nexus_semantic_logger/datadog_formatter.rb +0 -1
- data/lib/nexus_semantic_logger/datadog_tracer.rb +0 -2
- data/lib/nexus_semantic_logger/extensions/action_dispatch/debug_exceptions.rb +13 -2
- data/lib/nexus_semantic_logger/traced_shell.rb +163 -0
- data/lib/nexus_semantic_logger/version.rb +2 -2
- data/lib/nexus_semantic_logger.rb +6 -0
- metadata +15 -4
- data/.gitlab-ci.yml +0 -36
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0dcbcb0a7a4c7de68e7496b8ffb7f6d5d5e08742a981af559e48162bd149fc40
|
|
4
|
+
data.tar.gz: 4cd8249c19ce91fc5a3f2ef7c1919f91685235cf385291f8e0272ecfaf71234f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 17a71300ae2d6f1bd8c5d0175b167071b818c54ea489d5973a6a2d92cc2fa99dd8f8369015b57520ae8eaf2dfef84f17b30e28c12736637c1620d48ec435d28c
|
|
7
|
+
data.tar.gz: f93a642bc2e30c4913f65cab35cbda108a99d9b15f78fab5f715aa91d53511560d9a2189bd10d02782a90c9b810add8efec1509278bb6108fd4a1ee0b9258416
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
tags: ["*"]
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
rspec:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
gemfile: [rails_7_1, rails_7_2, rails_8_0]
|
|
16
|
+
env:
|
|
17
|
+
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
- uses: ruby/setup-ruby@v1
|
|
21
|
+
with:
|
|
22
|
+
ruby-version: "3.2.2"
|
|
23
|
+
- run: bundle install --jobs 4
|
|
24
|
+
- run: bundle exec rspec
|
|
25
|
+
|
|
26
|
+
rubocop:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
- uses: ruby/setup-ruby@v1
|
|
31
|
+
with:
|
|
32
|
+
ruby-version: "3.2.2"
|
|
33
|
+
- run: bundle install --jobs 4
|
|
34
|
+
- run: bundle exec rubocop
|
|
35
|
+
|
|
36
|
+
release:
|
|
37
|
+
needs: [rspec, rubocop]
|
|
38
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
- uses: ruby/setup-ruby@v1
|
|
43
|
+
with:
|
|
44
|
+
ruby-version: "3.2.2"
|
|
45
|
+
- run: bundle install --jobs 4
|
|
46
|
+
- name: Build and push gem to RubyGems
|
|
47
|
+
env:
|
|
48
|
+
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
|
49
|
+
run: |
|
|
50
|
+
sed -i "s/0.0.0/${GITHUB_REF_NAME}/g" lib/nexus_semantic_logger/version.rb
|
|
51
|
+
gem build nexus_semantic_logger.gemspec
|
|
52
|
+
gem push nexus_semantic_logger-*.gem
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/Appraisals
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -60,6 +60,20 @@ For example, to increment a count:
|
|
|
60
60
|
NexusSemanticLogger.metrics.increment('nexus.users.registration.complete')
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
### Running shell commands
|
|
64
|
+
|
|
65
|
+
Use `NexusSemanticLogger.shell.capture3` as a drop-in replacement for `Open3.capture3`:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
stdout, stderr, status = NexusSemanticLogger.shell.capture3('7z', 'x', archive_path)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Each call is wrapped in a Datadog APM span (`shell.exec`) and emits `nexus.shell.duration_ms`,
|
|
72
|
+
`nexus.shell.peak_rss_mb` (the child's peak RSS, sampled from procfs) and `nexus.shell.executions`
|
|
73
|
+
metrics tagged with `command:<binary>` and `outcome:<success|failure|signaled|exception>`, plus an
|
|
74
|
+
info log line. A child killed by the kernel OOM killer shows up as `outcome:signaled` with
|
|
75
|
+
`termsig: 9` and its last-observed peak RSS.
|
|
76
|
+
|
|
63
77
|
# Local gem development
|
|
64
78
|
|
|
65
79
|
Steps to run this gem from local sources in one the nexus 'staged build' rails components:
|
|
@@ -18,7 +18,6 @@ module NexusSemanticLogger
|
|
|
18
18
|
# Note that 'env' is NOT sent- that is set as the default on the agent e.g. staging, canary, production.
|
|
19
19
|
# It does not necessarily align with the Rails env, and we do not want to double tag the env.
|
|
20
20
|
global_tags = [
|
|
21
|
-
"railsenv:#{Rails.env}",
|
|
22
21
|
"service:#{service}",
|
|
23
22
|
"container_name:#{container_name}",
|
|
24
23
|
"pod_name:#{pod_name}",
|
|
@@ -42,7 +41,6 @@ module NexusSemanticLogger
|
|
|
42
41
|
# Trace tags API is Hash<String,String>, see https://www.rubydoc.info/gems/ddtrace/Datadog/Tracing
|
|
43
42
|
# Should match the global tags, but as a Hash.
|
|
44
43
|
c.tags = {
|
|
45
|
-
railsenv: Rails.env,
|
|
46
44
|
service: service,
|
|
47
45
|
container_name: container_name,
|
|
48
46
|
pod_name: pod_name,
|
|
@@ -14,8 +14,19 @@ module ActionDispatch
|
|
|
14
14
|
# log_rescued_responses? is a rails7 feature, but this gem is also used on rails6. Check for its existence.
|
|
15
15
|
return if respond_to?('log_rescued_responses?') && !log_rescued_responses?(request) && wrapper.rescue_response?
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
# Silence deprecations emitted while logging the exception. The API changed in Rails 7.1: the
|
|
18
|
+
# ActiveSupport::Deprecation singleton was deprecated and its class-level `silence` was removed in 7.2,
|
|
19
|
+
# replaced by Rails.application.deprecators. Calling the removed singleton on >= 7.2 raises NoMethodError
|
|
20
|
+
# inside render_exception (before the exception is logged), which swallowed all exception logging and
|
|
21
|
+
# produced empty 500s. Use whichever API the Rails version provides, mirroring rails_semantic_logger.
|
|
22
|
+
if (Rails::VERSION::MAJOR == 7 && Rails::VERSION::MINOR >= 1) || Rails::VERSION::MAJOR > 7
|
|
23
|
+
Rails.application.deprecators.silence do
|
|
24
|
+
ActionController::Base.logger.fatal(wrapper.exception)
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
ActiveSupport::Deprecation.silence do
|
|
28
|
+
ActionController::Base.logger.fatal(wrapper.exception)
|
|
29
|
+
end
|
|
19
30
|
end
|
|
20
31
|
end
|
|
21
32
|
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'open3'
|
|
3
|
+
require 'semantic_logger'
|
|
4
|
+
|
|
5
|
+
module NexusSemanticLogger
|
|
6
|
+
# Instrumented replacement for Open3.capture3, so child processes (7z, unrar, yara, ...) are
|
|
7
|
+
# observable. Each call produces:
|
|
8
|
+
# - a Datadog APM span ('shell.exec', resource = binary basename) tagged with the command line,
|
|
9
|
+
# exit status, terminating signal and peak RSS
|
|
10
|
+
# - statsd metrics: nexus.shell.duration_ms (timing), nexus.shell.peak_rss_mb (distribution)
|
|
11
|
+
# and nexus.shell.executions (count), tagged with command:<binary> and
|
|
12
|
+
# outcome:<success|failure|signaled|exception>
|
|
13
|
+
# - an info log line with the same payload
|
|
14
|
+
#
|
|
15
|
+
# Peak RSS is the child's kernel-maintained high-water mark (VmHWM in /proc/<pid>/status),
|
|
16
|
+
# sampled while the child runs. Linux only; nil elsewhere. Direct child only - grandchildren
|
|
17
|
+
# are not measured. A process killed by the kernel OOM killer reports outcome:signaled with
|
|
18
|
+
# termsig 9 and the last-sampled peak RSS, which is exactly the evidence an OOM postmortem needs.
|
|
19
|
+
class TracedShell
|
|
20
|
+
include SemanticLogger::Loggable
|
|
21
|
+
|
|
22
|
+
SPAN_NAME = 'shell.exec'
|
|
23
|
+
METRIC_PREFIX = 'nexus.shell'
|
|
24
|
+
RSS_POLL_INTERVAL_SECONDS = 0.05
|
|
25
|
+
COMMAND_LOG_MAX_CHARS = 500
|
|
26
|
+
|
|
27
|
+
# Drop-in replacement for Open3.capture3.
|
|
28
|
+
# A leading env Hash and trailing spawn options are supported as with Open3; the env Hash is
|
|
29
|
+
# excluded from spans/logs since it may hold secrets.
|
|
30
|
+
# @return [Array(String, String, Process::Status)] stdout, stderr, status.
|
|
31
|
+
def capture3(*cmd, stdin_data: '', binmode: false, **opts)
|
|
32
|
+
binary = command_basename(cmd)
|
|
33
|
+
started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
34
|
+
outcome = 'exception'
|
|
35
|
+
status = nil
|
|
36
|
+
peak_rss_kb = nil
|
|
37
|
+
trace(binary, cmd) do |span|
|
|
38
|
+
stdout, stderr, status, peak_rss_kb = run_capture3(cmd, stdin_data, binmode, opts)
|
|
39
|
+
outcome = outcome_for(status)
|
|
40
|
+
annotate_span(span, status, peak_rss_kb)
|
|
41
|
+
[stdout, stderr, status]
|
|
42
|
+
end
|
|
43
|
+
ensure
|
|
44
|
+
duration_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - started_at) * 1000).round
|
|
45
|
+
record(cmd, outcome, duration_ms, status, peak_rss_kb)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def trace(binary, cmd, &block)
|
|
51
|
+
return yield(nil) unless defined?(Datadog::Tracing)
|
|
52
|
+
|
|
53
|
+
Datadog::Tracing.trace(SPAN_NAME, resource: binary, type: 'system') do |span|
|
|
54
|
+
span.set_tag('shell.command', command_string(cmd))
|
|
55
|
+
block.call(span)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Open3.capture3 semantics, reimplemented over popen3 so the child pid is available to the
|
|
60
|
+
# RSS poller while it runs.
|
|
61
|
+
def run_capture3(cmd, stdin_data, binmode, opts)
|
|
62
|
+
Open3.popen3(*cmd, **opts) do |stdin, stdout, stderr, wait_thr|
|
|
63
|
+
if binmode
|
|
64
|
+
stdin.binmode
|
|
65
|
+
stdout.binmode
|
|
66
|
+
stderr.binmode
|
|
67
|
+
end
|
|
68
|
+
poller = start_rss_poller(wait_thr)
|
|
69
|
+
out_reader = Thread.new { stdout.read }
|
|
70
|
+
err_reader = Thread.new { stderr.read }
|
|
71
|
+
begin
|
|
72
|
+
stdin.write(stdin_data) if stdin_data && !stdin_data.empty?
|
|
73
|
+
rescue Errno::EPIPE
|
|
74
|
+
# Child exited without consuming stdin; Open3.capture3 ignores this too.
|
|
75
|
+
end
|
|
76
|
+
stdin.close
|
|
77
|
+
status = wait_thr.value
|
|
78
|
+
[out_reader.value, err_reader.value, status, poller&.value]
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def start_rss_poller(wait_thr)
|
|
83
|
+
return nil unless procfs?
|
|
84
|
+
|
|
85
|
+
pid = wait_thr.pid
|
|
86
|
+
Thread.new do
|
|
87
|
+
peak_kb = nil
|
|
88
|
+
while wait_thr.alive?
|
|
89
|
+
sample = read_vm_hwm_kb(pid)
|
|
90
|
+
peak_kb = sample if sample && (peak_kb.nil? || sample > peak_kb)
|
|
91
|
+
sleep(RSS_POLL_INTERVAL_SECONDS)
|
|
92
|
+
end
|
|
93
|
+
peak_kb
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# VmHWM is the process's peak RSS as maintained by the kernel, so each sample is itself a
|
|
98
|
+
# high-water mark; the true peak can only be missed by the process exiting within one poll.
|
|
99
|
+
def read_vm_hwm_kb(pid)
|
|
100
|
+
File.read("/proc/#{pid}/status")[/^VmHWM:\s*(\d+)\s*kB/, 1]&.to_i
|
|
101
|
+
rescue SystemCallError, IOError
|
|
102
|
+
nil
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def procfs?
|
|
106
|
+
return @procfs if defined?(@procfs)
|
|
107
|
+
|
|
108
|
+
@procfs = File.exist?('/proc/self/status')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def outcome_for(status)
|
|
112
|
+
return 'success' if status.success?
|
|
113
|
+
return 'signaled' if status.signaled?
|
|
114
|
+
|
|
115
|
+
'failure'
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def annotate_span(span, status, peak_rss_kb)
|
|
119
|
+
return unless span
|
|
120
|
+
|
|
121
|
+
span.set_tag('shell.exit_status', status.exitstatus) if status.exitstatus
|
|
122
|
+
span.set_tag('shell.termsig', status.termsig) if status.signaled?
|
|
123
|
+
span.set_tag('shell.peak_rss_mb', to_mb(peak_rss_kb)) if peak_rss_kb
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def record(cmd, outcome, duration_ms, status, peak_rss_kb)
|
|
127
|
+
tags = ["command:#{command_basename(cmd)}", "outcome:#{outcome}"]
|
|
128
|
+
metrics = NexusSemanticLogger.metrics
|
|
129
|
+
metrics.timing("#{METRIC_PREFIX}.duration_ms", duration_ms, tags: tags)
|
|
130
|
+
metrics.increment("#{METRIC_PREFIX}.executions", tags: tags)
|
|
131
|
+
peak_rss_mb = peak_rss_kb && to_mb(peak_rss_kb)
|
|
132
|
+
metrics.distribution("#{METRIC_PREFIX}.peak_rss_mb", peak_rss_mb, tags: tags) if peak_rss_mb
|
|
133
|
+
|
|
134
|
+
payload = {
|
|
135
|
+
command: command_string(cmd),
|
|
136
|
+
outcome: outcome,
|
|
137
|
+
duration_ms: duration_ms,
|
|
138
|
+
exit_status: status&.exitstatus,
|
|
139
|
+
termsig: status&.signaled? ? status.termsig : nil,
|
|
140
|
+
peak_rss_mb: peak_rss_mb,
|
|
141
|
+
}.compact
|
|
142
|
+
logger.info('Shell command finished.', payload)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Binary basename for span resource and metric tags; deliberately low cardinality.
|
|
146
|
+
def command_basename(cmd)
|
|
147
|
+
first = cmd.first.is_a?(Hash) ? cmd[1] : cmd.first
|
|
148
|
+
first = first.first if first.is_a?(Array) # [binary, argv0] form
|
|
149
|
+
return 'unknown' unless first.is_a?(String)
|
|
150
|
+
|
|
151
|
+
File.basename(first.split(' ').first.to_s)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def command_string(cmd)
|
|
155
|
+
parts = cmd.reject { |part| part.is_a?(Hash) }
|
|
156
|
+
parts.flatten.join(' ').slice(0, COMMAND_LOG_MAX_CHARS)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def to_mb(kb)
|
|
160
|
+
kb.fdiv(1024).round(1)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
module NexusSemanticLogger
|
|
3
|
-
# Leave this as 1.
|
|
4
|
-
VERSION = '1.
|
|
3
|
+
# Leave this as 1.15.0 in order for CI process to replace with the tagged version.
|
|
4
|
+
VERSION = '1.15.0'
|
|
5
5
|
end
|
|
@@ -5,12 +5,18 @@ require 'nexus_semantic_logger/datadog_formatter'
|
|
|
5
5
|
require 'nexus_semantic_logger/datadog_singleton'
|
|
6
6
|
require 'nexus_semantic_logger/datadog_tracer'
|
|
7
7
|
require 'nexus_semantic_logger/logger_metrics_subscriber'
|
|
8
|
+
require 'nexus_semantic_logger/traced_shell'
|
|
8
9
|
|
|
9
10
|
module NexusSemanticLogger
|
|
10
11
|
# Get application wide object for sending metrics.
|
|
11
12
|
def self.metrics
|
|
12
13
|
DatadogSingleton.instance
|
|
13
14
|
end
|
|
15
|
+
|
|
16
|
+
# Get application wide object for running instrumented shell commands.
|
|
17
|
+
def self.shell
|
|
18
|
+
@shell ||= TracedShell.new
|
|
19
|
+
end
|
|
14
20
|
end
|
|
15
21
|
|
|
16
22
|
# Patch access to LEVELS array.
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nexus_semantic_logger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.15.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Johnathon Harris
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-07-07 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: amazing_print
|
|
@@ -107,16 +108,22 @@ dependencies:
|
|
|
107
108
|
- - "~>"
|
|
108
109
|
- !ruby/object:Gem::Version
|
|
109
110
|
version: 4.16.1
|
|
111
|
+
description:
|
|
110
112
|
email: john.harris@nexusmods.com
|
|
111
113
|
executables: []
|
|
112
114
|
extensions: []
|
|
113
115
|
extra_rdoc_files: []
|
|
114
116
|
files:
|
|
117
|
+
- ".github/workflows/ci.yml"
|
|
115
118
|
- ".gitignore"
|
|
116
|
-
- ".
|
|
119
|
+
- ".rspec"
|
|
117
120
|
- ".rubocop.yml"
|
|
121
|
+
- Appraisals
|
|
118
122
|
- Gemfile
|
|
119
123
|
- README.md
|
|
124
|
+
- gemfiles/rails_7_1.gemfile
|
|
125
|
+
- gemfiles/rails_7_2.gemfile
|
|
126
|
+
- gemfiles/rails_8_0.gemfile
|
|
120
127
|
- lib/nexus_semantic_logger.rb
|
|
121
128
|
- lib/nexus_semantic_logger/appender_filter.rb
|
|
122
129
|
- lib/nexus_semantic_logger/application.rb
|
|
@@ -126,12 +133,15 @@ files:
|
|
|
126
133
|
- lib/nexus_semantic_logger/extensions/action_dispatch/debug_exceptions.rb
|
|
127
134
|
- lib/nexus_semantic_logger/logger_metrics_subscriber.rb
|
|
128
135
|
- lib/nexus_semantic_logger/sneakers_metrics.rb
|
|
136
|
+
- lib/nexus_semantic_logger/traced_shell.rb
|
|
129
137
|
- lib/nexus_semantic_logger/version.rb
|
|
130
138
|
- lib/puma/plugin/README.md
|
|
131
139
|
- lib/puma/plugin/nexus_puma_statsd.rb
|
|
132
140
|
- nexus_semantic_logger.gemspec
|
|
141
|
+
homepage:
|
|
133
142
|
licenses: []
|
|
134
143
|
metadata: {}
|
|
144
|
+
post_install_message:
|
|
135
145
|
rdoc_options: []
|
|
136
146
|
require_paths:
|
|
137
147
|
- lib
|
|
@@ -146,7 +156,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
146
156
|
- !ruby/object:Gem::Version
|
|
147
157
|
version: '0'
|
|
148
158
|
requirements: []
|
|
149
|
-
rubygems_version: 4.
|
|
159
|
+
rubygems_version: 3.4.10
|
|
160
|
+
signing_key:
|
|
150
161
|
specification_version: 4
|
|
151
162
|
summary: semantic_logger usage for nexus
|
|
152
163
|
test_files: []
|
data/.gitlab-ci.yml
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
image: "ruby:3.2.2"
|
|
2
|
-
|
|
3
|
-
stages:
|
|
4
|
-
- release
|
|
5
|
-
- test
|
|
6
|
-
|
|
7
|
-
before_script:
|
|
8
|
-
- gem install bundler --no-document
|
|
9
|
-
- bundle install --jobs $(nproc) "${FLAGS[@]}"
|
|
10
|
-
|
|
11
|
-
rspec:
|
|
12
|
-
script:
|
|
13
|
-
- bundle exec rspec
|
|
14
|
-
|
|
15
|
-
rubocop:
|
|
16
|
-
script:
|
|
17
|
-
- bundle exec rubocop
|
|
18
|
-
|
|
19
|
-
release:
|
|
20
|
-
stage: release
|
|
21
|
-
rules:
|
|
22
|
-
- if: '$CI_COMMIT_TAG'
|
|
23
|
-
script:
|
|
24
|
-
- mkdir -p ~/.gem
|
|
25
|
-
- cp $RUBYGEMS_CREDENTIALS ~/.gem/credentials
|
|
26
|
-
- chmod 0600 ~/.gem/credentials
|
|
27
|
-
- gem update --system
|
|
28
|
-
- ruby --version
|
|
29
|
-
- gem env version
|
|
30
|
-
- sed -i "s/0.0.0/$CI_COMMIT_TAG/g" lib/nexus_semantic_logger/version.rb
|
|
31
|
-
- gem build nexus_semantic_logger.gemspec
|
|
32
|
-
- gem push nexus_semantic_logger*.gem
|
|
33
|
-
artifacts:
|
|
34
|
-
paths:
|
|
35
|
-
- nexus_semantic_logger*.gem
|
|
36
|
-
expire_in: 30 days
|