vidar 1.16.0 → 1.17.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34f83978f5cf02b12e3b24ba387c8f2816b05d268b7099695ce585d1abbef7a4
4
- data.tar.gz: 9cdb5fbecf48f7a93d143e1e51f61a0d1cdda6c85cca582f5353262ceec8ec94
3
+ metadata.gz: c9f70e2aea16ca7648801c10d594785cf71cc4059e723075a7e0a5ac2df28e7a
4
+ data.tar.gz: e02d0cfe17b044eb62d11fee018e15956c02835ab7bb947a224b5a3fcfdf48bc
5
5
  SHA512:
6
- metadata.gz: 50255dfe156d09b96665f3b5d8476d0ea7e36ea6c8b0792bc5082c68156cbfdcba58465409e3b6f69adebde78f4a6dbc37fe34dc936cfc5b66dff7d5128ded19
7
- data.tar.gz: 9de76e0a980e1db77200f48731c01f2ef62f0c940808f416b744224a39d9828194e5dedb626e19359878d7648266ffff639862f5e682d1e9c4d895d6c94bbf69
6
+ metadata.gz: 88bb3c398a191d7b02a6d2591653b5ddc8ed88a1d2432dd84e2d0188fdcbb3873ea5f20eb7ca00c3b2f3bc49b03f030f3c12dcb4799d306741fa4d0f668489f4
7
+ data.tar.gz: afe4490c85deca103d2b07f720b36710fae66fc7acc60ffb91fbf4c235ac4fa027ecb01067a56710a3bafb9e0d357eeeafb3aa41d729b0c0a43b607ca4c3f3b1
data/.bundler-version CHANGED
@@ -1 +1 @@
1
- 4.0.4
1
+ 4.0.10
@@ -6,10 +6,49 @@ updates:
6
6
  schedule:
7
7
  interval: "weekly"
8
8
  day: "monday"
9
- time: "08:00"
9
+ time: "11:00"
10
10
  timezone: "UTC"
11
+ cooldown:
12
+ default-days: 2
13
+ include:
14
+ - "*"
11
15
  commit-message:
12
16
  prefix: "[dependabot]"
17
+ groups:
18
+ ruby-minor-and-patch:
19
+ applies-to: version-updates
20
+ update-types:
21
+ - "minor"
22
+ - "patch"
13
23
  labels:
24
+ - "dependencies"
14
25
  - "automerge"
26
+ ignore:
27
+ - dependency-name: "*"
28
+ update-types:
29
+ - "version-update:semver-major"
30
+
31
+ - package-ecosystem: "github-actions"
32
+ directory: "/"
33
+ schedule:
34
+ interval: "weekly"
35
+ day: "monday"
36
+ time: "11:00"
37
+ timezone: "UTC"
38
+ cooldown:
39
+ default-days: 2
40
+ commit-message:
41
+ prefix: "[dependabot]"
42
+ groups:
43
+ actions-minor-and-patch:
44
+ applies-to: version-updates
45
+ update-types:
46
+ - "minor"
47
+ - "patch"
48
+ labels:
15
49
  - "dependencies"
50
+ - "automerge"
51
+ ignore:
52
+ - dependency-name: "*"
53
+ update-types:
54
+ - "version-update:semver-major"
@@ -1,14 +1,16 @@
1
- name: Auto approve dependency upgrades and hot-fix PRs
1
+ name: Auto approve hot-fix PRs
2
2
  on:
3
3
  pull_request_target:
4
- types:
5
- - labeled
6
- - ready_for_review
4
+ types: [opened, labeled, ready_for_review]
5
+
7
6
  jobs:
8
7
  auto-approve:
8
+ if: >
9
+ github.actor == 'renofidev' ||
10
+ contains(github.event.pull_request.labels.*.name, 'HOTFIX-AUTO-APPROVE') ||
11
+ contains(github.event.pull_request.labels.*.name, 'self-approve')
9
12
  runs-on: ubuntu-latest
10
13
  steps:
11
- - uses: hmarr/auto-approve-action@v3
12
- if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]' || github.actor == 'renofidev' || contains(github.event.pull_request.labels.*.name, 'HOTFIX-AUTO-APPROVE') || contains(github.event.pull_request.labels.*.name, 'self-approve') || contains(github.event.pull_request.labels.*.name, 'dependencies')
14
+ - uses: hmarr/auto-approve-action@f0939ea97e9205ef24d872e76833fa908a770363 # v4.0.0
13
15
  with:
14
16
  github-token: "${{ secrets.GITHUB_TOKEN }}"
@@ -2,6 +2,9 @@ name: automerge
2
2
  on:
3
3
  pull_request_target:
4
4
  types:
5
+ - opened
6
+ - synchronize
7
+ - reopened
5
8
  - labeled
6
9
  pull_request_review:
7
10
  types:
@@ -9,23 +12,67 @@ on:
9
12
  check_suite:
10
13
  types:
11
14
  - completed
12
- status: {}
15
+
16
+ permissions:
17
+ contents: write
18
+ pull-requests: write
19
+
13
20
  jobs:
14
- automerge:
21
+ automerge-labeled:
22
+ if: >
23
+ github.event.pull_request.user.login != 'dependabot[bot]' &&
24
+ contains(github.event.pull_request.labels.*.name, 'automerge') &&
25
+ !contains(github.event.pull_request.labels.*.name, 'automerge blocked')
15
26
  runs-on: ubuntu-latest
16
27
  steps:
17
- - name: automerge
18
- uses: pascalgn/automerge-action@v0.16.4
28
+ - name: Enable auto-merge
29
+ run: gh pr merge --auto --squash --delete-branch "$PR_URL"
19
30
  env:
20
- GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
21
- MERGE_METHOD: squash
22
- MERGE_DELETE_BRANCH: true
23
- MERGE_LABELS: "automerge,!automerge blocked"
24
- - name: automerge-dependencies
25
- uses: pascalgn/automerge-action@v0.16.4
31
+ PR_URL: ${{ github.event.pull_request.html_url }}
32
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33
+
34
+ automerge-dependabot:
35
+ if: >
36
+ github.event.pull_request.user.login == 'dependabot[bot]' &&
37
+ !contains(github.event.pull_request.labels.*.name, 'automerge blocked')
38
+ runs-on: ubuntu-latest
39
+ steps:
40
+ - name: Fetch Dependabot metadata
41
+ id: metadata
42
+ uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0
43
+ with:
44
+ github-token: ${{ secrets.GITHUB_TOKEN }}
45
+
46
+ - name: Approve minor and patch
47
+ if: >
48
+ steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
49
+ steps.metadata.outputs.update-type == 'version-update:semver-minor'
50
+ uses: hmarr/auto-approve-action@f0939ea97e9205ef24d872e76833fa908a770363 # v4.0.0
51
+ with:
52
+ github-token: ${{ secrets.GITHUB_TOKEN }}
53
+
54
+ - name: Enable auto-merge for minor and patch
55
+ if: >
56
+ steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
57
+ steps.metadata.outputs.update-type == 'version-update:semver-minor'
58
+ run: gh pr merge --auto --squash --delete-branch "$PR_URL"
59
+ env:
60
+ PR_URL: ${{ github.event.pull_request.html_url }}
61
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62
+
63
+ automerge-update-branch:
64
+ if: github.event_name == 'check_suite'
65
+ runs-on: ubuntu-latest
66
+ steps:
67
+ - name: Update branches behind base
26
68
  env:
27
- GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
28
- MERGE_METHOD: squash
29
- MERGE_DELETE_BRANCH: true
30
- MERGE_LABELS: "dependencies,!automerge blocked"
31
- MERGE_REMOVE_LABELS: ""
69
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
70
+ run: |
71
+ gh pr list --repo "$GITHUB_REPOSITORY" \
72
+ --label automerge \
73
+ --limit 100 \
74
+ --json number,labels \
75
+ --jq '.[] | select(.labels | map(.name) | contains(["automerge blocked"]) | not) | .number' \
76
+ | while read pr_number; do
77
+ gh pr update-branch "$pr_number" --repo "$GITHUB_REPOSITORY" 2>/dev/null || true
78
+ done
@@ -14,9 +14,9 @@ jobs:
14
14
  ruby-version: [3.4, 4.0]
15
15
 
16
16
  steps:
17
- - uses: actions/checkout@v3
17
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
18
18
  - name: Set up Ruby
19
- uses: ruby/setup-ruby@v1
19
+ uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
20
20
  with:
21
21
  ruby-version: ${{ matrix.ruby-version }}
22
22
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
data/.gitignore CHANGED
@@ -11,6 +11,6 @@
11
11
  .rspec_status
12
12
 
13
13
  # Cached rubocop config files
14
- .rubocop-remote*
15
- .rubocop-http*
14
+ .rubocop-*
16
15
  vidar.yml
16
+ .claude
data/.standard.yml ADDED
@@ -0,0 +1,2 @@
1
+ format: progress
2
+ parallel: true
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.17.1 - 2026-05-19
4
+
5
+ - Fix `monitor_deploy_status` failing the deploy promotion when `--max_tries` is passed: Thor's `invoke :notify_sentry` was forwarding the parent task's ARGV as positional args. Pass explicit empty args/options to scope the sub-invocation.
6
+
7
+ ## 1.17.0 - 2026-03-24
8
+
9
+ - Replace backtick shell calls with `Open3.capture3` for safer command execution
10
+ - Add `rescue JSON::ParserError` in `K8s::PodSet` to handle malformed kubectl output gracefully
11
+ - Fix `terminated_error?` returning truthy for exit code 0
12
+ - Add `Unknown` state label for containers with unrecognized state
13
+ - Add `sidecar?` method and `sidecar_container_names` config key for configurable sidecar filtering (replaces hardcoded istio-proxy)
14
+ - Add `rescue Faraday::Error` to all notification classes to prevent network errors from crashing deploys
15
+ - Simplify `DeployStatus` polling loops and remove off-by-one in max_tries
16
+ - Add `vidar.yml` schema validation on load (requires `image`, `namespace`, `github`)
17
+ - Pin faraday dependency to `>= 2.0, < 3`
18
+ - Add YARD documentation to all public classes and methods
19
+ - Expand test coverage from 18 to 148 examples
20
+
3
21
  ## 1.16.0 - 2026-01-27
4
22
 
5
23
  Ruby 4.0 support. Drop ruby 3.3 support.
data/Gemfile CHANGED
@@ -1,16 +1,14 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'awesome_print'
6
- gem 'bundler'
7
- gem 'irb'
8
- gem 'pry'
9
- gem 'rake'
10
- gem 'rspec'
11
- gem 'rubocop'
12
- gem 'rubocop-rake'
13
- gem 'rubocop-rspec'
14
- gem 'webmock'
5
+ gem "awesome_print"
6
+ gem "bundler"
7
+ gem "irb"
8
+ gem "pry"
9
+ gem "rake"
10
+ gem "rspec"
11
+ gem "standard"
12
+ gem "webmock"
15
13
 
16
- gem 'openssl'
14
+ gem "openssl"
data/Gemfile.lock CHANGED
@@ -1,19 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vidar (1.16.0)
4
+ vidar (1.17.1)
5
5
  colorize
6
- faraday
6
+ faraday (>= 2.0, < 3)
7
7
  thor (~> 1.0)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- addressable (2.8.8)
12
+ addressable (2.9.0)
13
13
  public_suffix (>= 2.0.2, < 8.0)
14
14
  ast (2.4.3)
15
15
  awesome_print (1.9.2)
16
- bigdecimal (4.0.1)
16
+ bigdecimal (4.1.1)
17
17
  coderay (1.1.3)
18
18
  colorize (1.1.0)
19
19
  crack (1.0.1)
@@ -21,8 +21,8 @@ GEM
21
21
  rexml
22
22
  date (3.5.1)
23
23
  diff-lcs (1.6.2)
24
- erb (6.0.1)
25
- faraday (2.14.0)
24
+ erb (6.0.4)
25
+ faraday (2.14.2)
26
26
  faraday-net_http (>= 2.0, < 3.5)
27
27
  json
28
28
  logger
@@ -30,26 +30,27 @@ GEM
30
30
  net-http (~> 0.5)
31
31
  hashdiff (1.2.1)
32
32
  io-console (0.8.2)
33
- irb (1.16.0)
33
+ irb (1.18.0)
34
34
  pp (>= 0.6.0)
35
+ prism (>= 1.3.0)
35
36
  rdoc (>= 4.0.0)
36
37
  reline (>= 0.4.2)
37
- json (2.18.0)
38
+ json (2.19.5)
38
39
  language_server-protocol (3.17.0.5)
39
40
  lint_roller (1.1.0)
40
41
  logger (1.7.0)
41
42
  method_source (1.1.0)
42
43
  net-http (0.9.1)
43
44
  uri (>= 0.11.1)
44
- openssl (4.0.0)
45
- parallel (1.27.0)
46
- parser (3.3.10.1)
45
+ openssl (4.0.2)
46
+ parallel (1.28.0)
47
+ parser (3.3.11.1)
47
48
  ast (~> 2.4.1)
48
49
  racc
49
50
  pp (0.6.3)
50
51
  prettyprint
51
52
  prettyprint (0.2.0)
52
- prism (1.8.0)
53
+ prism (1.9.0)
53
54
  pry (0.16.0)
54
55
  coderay (~> 1.1)
55
56
  method_source (~> 1.0)
@@ -57,15 +58,15 @@ GEM
57
58
  psych (5.3.1)
58
59
  date
59
60
  stringio
60
- public_suffix (7.0.2)
61
+ public_suffix (7.0.5)
61
62
  racc (1.8.1)
62
63
  rainbow (3.1.1)
63
- rake (13.3.1)
64
- rdoc (7.1.0)
64
+ rake (13.4.2)
65
+ rdoc (7.2.0)
65
66
  erb
66
67
  psych (>= 4.0.0)
67
68
  tsort
68
- regexp_parser (2.11.3)
69
+ regexp_parser (2.12.0)
69
70
  reline (0.6.3)
70
71
  io-console (~> 0.5)
71
72
  rexml (3.4.4)
@@ -78,11 +79,11 @@ GEM
78
79
  rspec-expectations (3.13.5)
79
80
  diff-lcs (>= 1.2.0, < 2.0)
80
81
  rspec-support (~> 3.13.0)
81
- rspec-mocks (3.13.7)
82
+ rspec-mocks (3.13.8)
82
83
  diff-lcs (>= 1.2.0, < 2.0)
83
84
  rspec-support (~> 3.13.0)
84
- rspec-support (3.13.6)
85
- rubocop (1.82.1)
85
+ rspec-support (3.13.7)
86
+ rubocop (1.84.2)
86
87
  json (~> 2.3)
87
88
  language_server-protocol (~> 3.17.0.2)
88
89
  lint_roller (~> 1.1.0)
@@ -90,19 +91,29 @@ GEM
90
91
  parser (>= 3.3.0.2)
91
92
  rainbow (>= 2.2.2, < 4.0)
92
93
  regexp_parser (>= 2.9.3, < 3.0)
93
- rubocop-ast (>= 1.48.0, < 2.0)
94
+ rubocop-ast (>= 1.49.0, < 2.0)
94
95
  ruby-progressbar (~> 1.7)
95
96
  unicode-display_width (>= 2.4.0, < 4.0)
96
- rubocop-ast (1.49.0)
97
+ rubocop-ast (1.49.1)
97
98
  parser (>= 3.3.7.2)
98
99
  prism (~> 1.7)
99
- rubocop-rake (0.7.1)
100
+ rubocop-performance (1.26.1)
100
101
  lint_roller (~> 1.1)
101
- rubocop (>= 1.72.1)
102
- rubocop-rspec (3.9.0)
103
- lint_roller (~> 1.1)
104
- rubocop (~> 1.81)
102
+ rubocop (>= 1.75.0, < 2.0)
103
+ rubocop-ast (>= 1.47.1, < 2.0)
105
104
  ruby-progressbar (1.13.0)
105
+ standard (1.54.0)
106
+ language_server-protocol (~> 3.17.0.2)
107
+ lint_roller (~> 1.0)
108
+ rubocop (~> 1.84.0)
109
+ standard-custom (~> 1.0.0)
110
+ standard-performance (~> 1.8)
111
+ standard-custom (1.0.2)
112
+ lint_roller (~> 1.0)
113
+ rubocop (~> 1.50)
114
+ standard-performance (1.9.0)
115
+ lint_roller (~> 1.1)
116
+ rubocop-performance (~> 1.26.0)
106
117
  stringio (3.2.0)
107
118
  thor (1.5.0)
108
119
  tsort (0.2.0)
@@ -110,7 +121,7 @@ GEM
110
121
  unicode-emoji (~> 4.1)
111
122
  unicode-emoji (4.2.0)
112
123
  uri (1.1.1)
113
- webmock (3.26.1)
124
+ webmock (3.26.2)
114
125
  addressable (>= 2.8.0)
115
126
  crack (>= 0.3.2)
116
127
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -126,9 +137,7 @@ DEPENDENCIES
126
137
  pry
127
138
  rake
128
139
  rspec
129
- rubocop
130
- rubocop-rake
131
- rubocop-rspec
140
+ standard
132
141
  vidar!
133
142
  webmock
134
143
 
data/Rakefile CHANGED
@@ -1,9 +1,8 @@
1
- require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
3
- require 'rubocop/rake_task'
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "standard/rake"
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec)
6
- RuboCop::RakeTask.new
7
6
 
8
- task ci: %i[spec rubocop]
9
- task default: %i[spec rubocop:autocorrect]
7
+ task ci: %i[spec standard]
8
+ task default: %i[spec standard:fix]
data/exe/vidar CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'vidar'
3
+ require "vidar"
4
4
 
5
5
  Vidar::CLI.start
data/lib/vidar/cli.rb CHANGED
@@ -24,7 +24,8 @@ module Vidar
24
24
  Log.info "Pulling #{Config.get!(:image)} tags"
25
25
  Run.docker "pull #{Config.get!(:image)}:#{Config.get!(:base_stage_name)}-#{Config.get!(:current_branch)} 2> /dev/null || true"
26
26
 
27
- image_names = `docker images --format "{{.Repository}}:{{.Tag}}"`.split("\n")
27
+ image_names_stdout, _stderr, _status = Open3.capture3('docker images --format "{{.Repository}}:{{.Tag}}"')
28
+ image_names = image_names_stdout.split("\n")
28
29
  base_image = "#{Config.get!(:image)}:#{Config.get!(:base_stage_name)}-#{Config.get!(:default_branch)}"
29
30
  Run.docker "pull #{base_image} 2> /dev/null || true" unless image_names.include?(base_image)
30
31
 
@@ -128,8 +129,8 @@ module Vidar
128
129
  destination = options[:destination]
129
130
  container = options[:container]
130
131
  all = options[:all]
131
- Log.info "Set kubectl image for #{'all ' if all}#{destination} container=#{container}..."
132
- Run.kubectl "set image #{destination} #{container}=#{Config.get!(:image)}:#{revision} #{'--all' if all}"
132
+ Log.info "Set kubectl image for #{"all " if all}#{destination} container=#{container}..."
133
+ Run.kubectl "set image #{destination} #{container}=#{Config.get!(:image)}:#{revision} #{"--all" if all}"
133
134
  end
134
135
 
135
136
  desc "set_image", "Set image for k8s deployment"
@@ -146,8 +147,8 @@ module Vidar
146
147
  destination = options[:destination]
147
148
  container = options[:container]
148
149
  all = options[:all]
149
- Log.info "Set kubectl image for #{'all ' if all}#{destination} container=#{container}..."
150
- Run.kubectl "set image #{destination} #{container}=#{Config.get!(:image)}:#{revision} #{'--all' if all}"
150
+ Log.info "Set kubectl image for #{"all " if all}#{destination} container=#{container}..."
151
+ Run.kubectl "set image #{destination} #{container}=#{Config.get!(:image)}:#{revision} #{"--all" if all}"
151
152
  end
152
153
 
153
154
  desc "release", "Build and publish docker images"
@@ -178,7 +179,7 @@ module Vidar
178
179
  Log.info "OK: All containers are ready"
179
180
  slack_notification.success if slack_notification.configured?
180
181
  honeycomb_notification.success
181
- invoke :notify_sentry
182
+ invoke :notify_sentry, [], {}
182
183
  else
183
184
  Log.error "ERROR: Some of containers are errored or not ready"
184
185
  slack_notification.failure if slack_notification.configured?
@@ -198,16 +199,17 @@ module Vidar
198
199
  Log.error "ERROR: could not find deployment config for #{Config.get!(:kubectl_context)} context" unless deploy_config
199
200
 
200
201
  pod_set = K8s::PodSet.new(namespace: Config.get!(:namespace), filter: options[:name])
201
- containers = pod_set.containers.select(&:ready_and_running?).reject(&:istio?)
202
+ sidecar_names = Array(Config.get(:sidecar_container_names))
203
+ containers = pod_set.containers.select(&:ready_and_running?).reject { |c| c.sidecar?(sidecar_names) }
202
204
 
203
205
  if containers.empty?
204
- name = options[:name] || 'any'
206
+ name = options[:name] || "any"
205
207
  Log.error "No running containers found with *#{name}* name"
206
208
  exit(1)
207
209
  else
208
210
  Log.info "Available containers:"
209
211
  containers.each(&:print)
210
- container = containers.detect { |c| c.name == 'console' } || containers.last
212
+ container = containers.detect { |c| c.name == "console" } || containers.last
211
213
 
212
214
  Log.info "Running #{options[:command]} in #{container.pod_name}"
213
215
  Run.kubectl("exec -it #{container.pod_name} -- #{options[:command]}")
@@ -232,7 +234,7 @@ module Vidar
232
234
  desc "notify_sentry", "Notify sentry about current release"
233
235
  def notify_sentry
234
236
  sentry_notification = SentryNotification.new(
235
- revision: Config.get!(:revision),
237
+ revision: Config.get!(:revision),
236
238
  deploy_config: Config.deploy_config
237
239
  )
238
240
 
@@ -248,10 +250,10 @@ module Vidar
248
250
  desc "notify_slack", "Send custom slack notification"
249
251
  def notify_slack
250
252
  slack_notification = SlackNotification.new(
251
- github: Config.get!(:github),
252
- revision: Config.get!(:revision),
253
+ github: Config.get!(:github),
254
+ revision: Config.get!(:revision),
253
255
  revision_name: Config.get!(:revision_name),
254
- build_url: Config.build_url,
256
+ build_url: Config.build_url,
255
257
  deploy_config: Config.deploy_config
256
258
  )
257
259
 
data/lib/vidar/config.rb CHANGED
@@ -1,34 +1,44 @@
1
1
  module Vidar
2
+ # Loads and provides access to the vidar.yml manifest configuration.
3
+ # Values fall back to DEFAULT_OPTIONS when not defined in the manifest.
2
4
  class Config
3
5
  DEFAULT_MANIFEST_FILE = "vidar.yml".freeze
4
6
  DEFAULT_BRANCHES = %w[main master].freeze
7
+ REQUIRED_KEYS = %w[image namespace github].freeze
5
8
 
6
9
  DEFAULT_OPTIONS = {
7
- compose_file: -> { "docker-compose.ci.yml" },
8
- compose_cmd: -> { "docker compose" },
9
- default_branch: -> { (DEFAULT_BRANCHES & branches).first || DEFAULT_BRANCHES.first },
10
- current_branch: -> { (ENV['SEMAPHORE_GIT_WORKING_BRANCH'] || `git rev-parse --abbrev-ref HEAD`.strip).tr("/", "-") },
11
- revision: -> { `git rev-parse HEAD`.strip },
12
- revision_name: -> { `git show --pretty=format:"%s (%h)" -s HEAD`.strip },
13
- kubectl_context: -> { `kubectl config current-context`.strip },
14
- shell_command: -> { "/bin/sh" },
15
- console_command: -> { "bin/console" },
16
- base_stage_name: -> { "base" },
10
+ compose_file: -> { "docker-compose.ci.yml" },
11
+ compose_cmd: -> { "docker compose" },
12
+ default_branch: -> { (DEFAULT_BRANCHES & branches).first || DEFAULT_BRANCHES.first },
13
+ current_branch: -> { (ENV["SEMAPHORE_GIT_WORKING_BRANCH"] || shell_capture("git rev-parse --abbrev-ref HEAD")).tr("/", "-") },
14
+ revision: -> { shell_capture("git rev-parse HEAD") },
15
+ revision_name: -> { shell_capture('git show --pretty=format:"%s (%h)" -s HEAD') },
16
+ kubectl_context: -> { shell_capture("kubectl config current-context") },
17
+ shell_command: -> { "/bin/sh" },
18
+ console_command: -> { "bin/console" },
19
+ base_stage_name: -> { "base" },
17
20
  release_stage_name: -> { "release" },
18
- honeycomb_api_key: -> { ENV['HONEYCOMB_API_KEY'] },
21
+ honeycomb_api_key: -> { ENV["HONEYCOMB_API_KEY"] },
22
+ sidecar_container_names: -> { ["istio-proxy"] }
19
23
  }.freeze
20
24
 
21
25
  class << self
22
26
  attr_reader :data
23
27
  attr_writer :manifest_file
24
28
 
29
+ # Loads the manifest file and validates required keys.
30
+ # @param file_path [String] path to vidar.yml
31
+ # @raise [MissingManifestFileError] if the file does not exist
32
+ # @raise [Error] if required keys are missing or schema is invalid
25
33
  def load(file_path = manifest_file)
26
34
  ensure_file_exist!(file_path)
27
35
 
28
36
  @data = YAML.load_file(file_path)
37
+ validate_schema!
29
38
  @loaded = true
30
39
  end
31
40
 
41
+ # @return [String] path to the manifest file
32
42
  def manifest_file
33
43
  @manifest_file || DEFAULT_MANIFEST_FILE
34
44
  end
@@ -37,10 +47,13 @@ module Vidar
37
47
  fail(MissingManifestFileError, file_path) unless File.exist?(file_path)
38
48
  end
39
49
 
50
+ # @return [Boolean] true if the manifest has been loaded
40
51
  def loaded?
41
52
  @loaded
42
53
  end
43
54
 
55
+ # @param key [Symbol, String] config key
56
+ # @return [Object, nil] value from manifest or default
44
57
  def get(key)
45
58
  load unless loaded?
46
59
 
@@ -51,19 +64,26 @@ module Vidar
51
64
  Vidar::Interpolation.call(value, self)
52
65
  end
53
66
 
67
+ # @param key [Symbol, String] config key
68
+ # @return [Object] value from manifest or default
69
+ # @raise [MissingConfigError] if the key is not found
54
70
  def get!(key)
55
71
  get(key) || fail(MissingConfigError, key)
56
72
  end
57
73
 
74
+ # @return [String, nil] CI build URL resolved from env or manifest
58
75
  def build_url
59
76
  value = ENV[get(:build_env).to_s] || get(:build_url)
60
77
  value&.empty? ? nil : value
61
78
  end
62
79
 
80
+ # @param env [String] environment name (maps to HONEYCOMB_API_KEY_<ENV>)
81
+ # @return [String, nil] Honeycomb API key for the given environment
63
82
  def honeycomb_env_api_key(env)
64
83
  ENV["HONEYCOMB_API_KEY_#{env.upcase}"]
65
84
  end
66
85
 
86
+ # @return [DeployConfig] deployment config for the current kubectl context
67
87
  def deploy_config
68
88
  deploy_configs[get!(:kubectl_context)] ||= build_deploy_config(get!(:kubectl_context))
69
89
  end
@@ -88,13 +108,38 @@ module Vidar
88
108
  @deploy_configs ||= {}
89
109
  end
90
110
 
111
+ # @return [Array<String>] local git branch names
91
112
  def branches
92
- `git for-each-ref --format='%(refname:short)' refs/heads/*`.split("\n")
113
+ stdout, _stderr, _status = Open3.capture3("git for-each-ref --format='%(refname:short)' refs/heads/*")
114
+ stdout.split("\n")
93
115
  end
94
116
 
117
+ # @return [Boolean] true if current branch is the default branch
95
118
  def default_branch?
96
119
  get!(:current_branch) == get!(:default_branch)
97
120
  end
121
+
122
+ private
123
+
124
+ def validate_schema!
125
+ missing = REQUIRED_KEYS.reject { |k| @data.key?(k) }
126
+ fail(Error, "vidar.yml is missing required keys: #{missing.join(", ")}") if missing.any?
127
+
128
+ deployments = @data["deployments"]
129
+ fail(Error, "vidar.yml: 'deployments' must be a Hash, got #{deployments.class}") if deployments && !deployments.is_a?(Hash)
130
+
131
+ return unless deployments
132
+
133
+ deployments.each do |context, config|
134
+ fail(Error, "vidar.yml: deployment '#{context}' must be a Hash") unless config.is_a?(Hash)
135
+ fail(Error, "vidar.yml: deployment '#{context}' is missing required key 'name'") unless config.key?("name")
136
+ end
137
+ end
138
+
139
+ def shell_capture(command)
140
+ stdout, _stderr, _status = Open3.capture3(command)
141
+ stdout.strip
142
+ end
98
143
  end
99
144
  end
100
145
  end
@@ -1,4 +1,5 @@
1
1
  module Vidar
2
+ # Polls Kubernetes pod status until deployment completes or times out.
2
3
  class DeployStatus
3
4
  INITIAL_SLEEP = 2
4
5
  SLEEP = 10
@@ -6,52 +7,52 @@ module Vidar
6
7
 
7
8
  attr_reader :namespace, :filter, :max_tries
8
9
 
10
+ # @param namespace [String] Kubernetes namespace, or "all"
11
+ # @param filter [String, nil] optional substring filter on container names
12
+ # @param max_tries [Integer] maximum poll iterations before giving up
9
13
  def initialize(namespace:, filter: nil, max_tries: MAX_TRIES)
10
14
  @namespace = namespace
11
15
  @filter = filter
12
16
  @max_tries = max_tries
13
17
  end
14
18
 
19
+ # Waits until at least one pod exists in the namespace.
20
+ # @return [void]
15
21
  def wait_until_up
16
- tries = 0
17
-
18
22
  sleep(INITIAL_SLEEP)
19
23
 
20
- until pod_set.any?
21
- tries += 1
24
+ max_tries.times do
25
+ ps = current_pod_set
26
+ break if ps.any?
27
+
22
28
  sleep(SLEEP)
23
- if tries > max_tries
24
- break
25
- end
26
29
  end
27
30
  end
28
31
 
32
+ # Waits until all pods are deployed and none are still initializing.
33
+ # @return [void]
29
34
  def wait_until_completed
30
- tries = 0
31
-
32
35
  sleep(INITIAL_SLEEP)
33
36
 
34
- until pod_set.deployed?
35
- tries += 1
37
+ max_tries.times do
38
+ ps = current_pod_set
39
+ break if ps.deployed?
40
+
36
41
  sleep(SLEEP)
37
- if tries > max_tries && !pod_set.waiting?
38
- break
39
- end
40
42
  end
41
43
  end
42
44
 
45
+ # @return [Boolean] true if the last observed pod set reported success
43
46
  def success?
44
- return false unless last_pod_set
47
+ return false unless @last_pod_set
45
48
 
46
- last_pod_set.success?
49
+ @last_pod_set.success?
47
50
  end
48
51
 
49
- def last_pod_set
50
- @pod_set
51
- end
52
+ private
52
53
 
53
- def pod_set
54
- @pod_set = K8s::PodSet.new(namespace:, filter:)
54
+ def current_pod_set
55
+ @last_pod_set = K8s::PodSet.new(namespace:, filter:)
55
56
  end
56
57
  end
57
58
  end
@@ -2,12 +2,12 @@ module Vidar
2
2
  class HoneycombNotification
3
3
  def self.get
4
4
  new(
5
- github: Config.get!(:github),
6
- revision: Config.get!(:revision),
5
+ github: Config.get!(:github),
6
+ revision: Config.get!(:revision),
7
7
  revision_name: Config.get!(:revision_name),
8
- build_url: Config.build_url,
8
+ build_url: Config.build_url,
9
9
  deploy_config: Config.deploy_config,
10
- api_key: Config.get(:honeycomb_api_key),
10
+ api_key: Config.get(:honeycomb_api_key)
11
11
  )
12
12
  end
13
13
 
@@ -68,8 +68,8 @@ module Vidar
68
68
 
69
69
  response = connection.post do |req|
70
70
  req.url "https://api.honeycomb.io/1/markers/#{dataset}"
71
- req.headers['Content-Type'] = 'application/json'
72
- req.headers['X-Honeycomb-Team'] = api_key.to_s
71
+ req.headers["Content-Type"] = "application/json"
72
+ req.headers["X-Honeycomb-Team"] = api_key.to_s
73
73
  req.body = data.to_json
74
74
  end
75
75
 
@@ -77,6 +77,9 @@ module Vidar
77
77
 
78
78
  warn "Honeycomb marker not created: status: #{response.status} response: #{response.body}"
79
79
  false
80
+ rescue Faraday::Error => e
81
+ warn "Honeycomb legacy marker request failed: #{e.message}"
82
+ false
80
83
  end
81
84
 
82
85
  def create_marker
@@ -84,8 +87,8 @@ module Vidar
84
87
 
85
88
  response = connection.post do |req|
86
89
  req.url "https://api.honeycomb.io/1/markers/__all__"
87
- req.headers['Content-Type'] = 'application/json'
88
- req.headers['X-Honeycomb-Team'] = Config.honeycomb_env_api_key(dataset).to_s
90
+ req.headers["Content-Type"] = "application/json"
91
+ req.headers["X-Honeycomb-Team"] = Config.honeycomb_env_api_key(dataset).to_s
89
92
  req.body = data.to_json
90
93
  end
91
94
 
@@ -93,15 +96,18 @@ module Vidar
93
96
 
94
97
  warn "Honeycomb marker not created: status: #{response.status} response: #{response.body}"
95
98
  false
99
+ rescue Faraday::Error => e
100
+ warn "Honeycomb env marker request failed: #{e.message}"
101
+ false
96
102
  end
97
103
 
98
104
  def data
99
105
  {
100
- message: "#{success? ? 'Successful' : 'Failed'} deploy of #{github} revision #{revision} - #{revision_name}",
106
+ message: "#{success? ? "Successful" : "Failed"} deploy of #{github} revision #{revision} - #{revision_name}",
101
107
  type: success? ? "deploy" : "failed_deploy",
102
108
  start_time: start_time.to_i,
103
109
  end_time: end_time.to_i,
104
- url: build_url,
110
+ url: build_url
105
111
  }
106
112
  end
107
113
  end
@@ -8,7 +8,7 @@ module Vidar
8
8
  fail ArgumentError, "getter must respond_to get." unless getter.respond_to?(:get)
9
9
 
10
10
  string.gsub(INTERPOLATION_PATTERN) do |match|
11
- getter.get($1) || ENV[$1] || match # rubocop:disable Style/PerlBackrefs
11
+ getter.get($1) || ENV[$1] || match
12
12
  end
13
13
  end
14
14
  end
@@ -1,5 +1,6 @@
1
1
  module Vidar
2
2
  module K8s
3
+ # Represents a single Kubernetes container and its current state.
3
4
  class Container
4
5
  JOB_KIND = "Job".freeze
5
6
 
@@ -17,22 +18,26 @@ module Vidar
17
18
  @message = data["message"]
18
19
  end
19
20
 
21
+ # @return [String] container name, falling back to pod name
20
22
  def name
21
23
  data["name"] || pod_name
22
24
  end
23
25
 
26
+ # @return [Boolean] true if the container is considered successfully deployed
24
27
  def deployed?
25
28
  return terminated? if job?
26
29
 
27
30
  ready? && running?
28
31
  end
29
32
 
33
+ # @return [Boolean] true if the container completed successfully
30
34
  def success?
31
35
  return terminated_completed? if job?
32
36
 
33
37
  ready_and_running?
34
38
  end
35
39
 
40
+ # @return [Boolean] true if the container is ready and running
36
41
  def ready_and_running?
37
42
  ready? && running?
38
43
  end
@@ -46,9 +51,10 @@ module Vidar
46
51
  parts << namespace.to_s.ljust(20, " ")
47
52
  parts << name.to_s.ljust(35, " ")
48
53
  parts += text_statuses.map { |s| s.ljust(45, " ") }
49
- "| #{parts.join(' | ')} |"
54
+ "| #{parts.join(" | ")} |"
50
55
  end
51
56
 
57
+ # @return [Array<String>] two-element array with status label and detail
52
58
  def text_statuses
53
59
  if unschedulable?
54
60
  [ColorizedString["Unschedulable"].light_red, ColorizedString[message].light_red]
@@ -67,18 +73,21 @@ module Vidar
67
73
  elsif waiting?
68
74
  [ColorizedString["Waiting"].light_yellow, ""]
69
75
  else
70
- [ColorizedString[state.inspect].light_red, ""]
76
+ [ColorizedString["Unknown"].light_yellow, state.empty? ? "" : state.inspect]
71
77
  end
72
78
  end
73
79
 
80
+ # @return [Boolean] true if container state is "waiting"
74
81
  def waiting?
75
82
  state["waiting"]
76
83
  end
77
84
 
85
+ # @return [Boolean] true if container is ready
78
86
  def ready?
79
87
  data["ready"]
80
88
  end
81
89
 
90
+ # @return [Boolean] true if container is running
82
91
  def running?
83
92
  !running_started_at.nil?
84
93
  end
@@ -87,10 +96,12 @@ module Vidar
87
96
  state.dig("running", "startedAt")
88
97
  end
89
98
 
99
+ # @return [Boolean] true if container has terminated (any reason)
90
100
  def terminated?
91
101
  !state["terminated"].nil?
92
102
  end
93
103
 
104
+ # @return [Boolean] true if container terminated successfully
94
105
  def terminated_completed?
95
106
  state.dig("terminated", "reason") == "Completed" || state.dig("terminated", "exitCode") == 0
96
107
  end
@@ -99,18 +110,34 @@ module Vidar
99
110
  state.dig("terminated", "finishedAt")
100
111
  end
101
112
 
113
+ # @return [Boolean] true if container terminated with an error exit code
102
114
  def terminated_error?
103
- state.dig("terminated", "reason") == "Error" || state.dig("terminated", "exitCode")
115
+ exit_code = state.dig("terminated", "exitCode")
116
+ state.dig("terminated", "reason") == "Error" || (!exit_code.nil? && exit_code != 0)
104
117
  end
105
118
 
119
+ # @return [Boolean] true if container state is unknown
120
+ def unknown?
121
+ !unschedulable? && !running? && !terminated? && !waiting?
122
+ end
123
+
124
+ # @return [Boolean] true if container reason is Unschedulable
106
125
  def unschedulable?
107
126
  reason == "Unschedulable"
108
127
  end
109
128
 
129
+ # @return [Boolean] true if this container belongs to a Job
110
130
  def job?
111
131
  kind == JOB_KIND
112
132
  end
113
133
 
134
+ # @param sidecar_names [Array<String>] list of sidecar container names to match
135
+ # @return [Boolean] true if this container is a known sidecar
136
+ def sidecar?(sidecar_names = ["istio-proxy"])
137
+ sidecar_names.include?(name.to_s)
138
+ end
139
+
140
+ # @return [Boolean] true if this is an istio-proxy sidecar container
114
141
  def istio?
115
142
  name == "istio-proxy"
116
143
  end
@@ -1,19 +1,27 @@
1
1
  module Vidar
2
2
  module K8s
3
+ # Represents a collection of Kubernetes pods and their containers
4
+ # fetched via `kubectl get pods` for a given namespace.
3
5
  class PodSet
6
+ # @param namespace [String] Kubernetes namespace, or "all" for all namespaces
7
+ # @param filter [String, nil] optional substring filter on container names
4
8
  def initialize(namespace:, filter: nil)
5
9
  @namespace = namespace
6
10
  @filter = filter
7
11
  end
8
12
 
13
+ # @return [Boolean] true if any containers exist in the pod set
9
14
  def any?
10
15
  containers.any?
11
16
  end
12
17
 
18
+ # @return [Boolean] true if any containers are in waiting state
13
19
  def waiting?
14
20
  containers.any?(&:waiting?)
15
21
  end
16
22
 
23
+ # Logs current container states and returns whether all are deployed.
24
+ # @return [Boolean]
17
25
  def deployed?
18
26
  if items.empty?
19
27
  Log.error "Could not fetch pod list"
@@ -29,12 +37,14 @@ module Vidar
29
37
  containers.all?(&:deployed?)
30
38
  end
31
39
 
40
+ # @return [Boolean] true if all containers report success
32
41
  def success?
33
42
  return false if containers.empty?
34
43
 
35
44
  containers.all?(&:success?)
36
45
  end
37
46
 
47
+ # @return [Array<Container>] filtered container list
38
48
  def containers
39
49
  if filter
40
50
  all_containers.select { |cs| cs.name.to_s.include?(filter) }
@@ -49,21 +59,30 @@ module Vidar
49
59
 
50
60
  def items
51
61
  @items ||= begin
52
- json = JSON.parse(kubectl_get.strip)
53
- json["items"] || []
62
+ output = kubectl_get.strip
63
+ return [] if output.empty?
64
+
65
+ JSON.parse(output)["items"] || []
66
+ rescue JSON::ParserError => e
67
+ Log.error "Failed to parse kubectl JSON output: #{e.message}"
68
+ []
54
69
  end
55
70
  end
56
71
 
57
72
  def kubectl_get
58
- if namespace == "all"
59
- `#{Run.kubectl_envs_string}kubectl get pods --all-namespaces -o json`
73
+ envs = Run.kubectl_envs_hash
74
+ stdout, stderr, status = if namespace == "all"
75
+ Open3.capture3(envs, "kubectl", "get", "pods", "--all-namespaces", "-o", "json")
60
76
  else
61
- `#{Run.kubectl_envs_string}kubectl get pods -n #{namespace} -o json`
77
+ Open3.capture3(envs, "kubectl", "get", "pods", "-n", namespace, "-o", "json")
78
+ end
79
+
80
+ unless status.success?
81
+ Log.error "kubectl get pods failed: #{stderr.strip}"
82
+ return ""
62
83
  end
63
- end
64
84
 
65
- def ready_and_running_containers
66
- containers.select(&:ready_and_running?)
85
+ stdout
67
86
  end
68
87
 
69
88
  def all_containers
data/lib/vidar/log.rb CHANGED
@@ -2,7 +2,7 @@ module Vidar
2
2
  class Log
3
3
  class << self
4
4
  def line
5
- puts "|#{'-' * 142}|"
5
+ puts "|#{"-" * 142}|"
6
6
  end
7
7
 
8
8
  def info(text, fill_with = "#")
data/lib/vidar/run.rb CHANGED
@@ -7,7 +7,7 @@ module Vidar
7
7
 
8
8
  def docker_compose(command)
9
9
  args = %w[revision current_branch].map { |arg| "#{arg.upcase}=#{Config.get!(arg.to_sym)}" }
10
- system("#{args.join(' ')} #{Config.get!(:compose_cmd)} -f #{Config.get!(:compose_file)} #{command}") || exit(1)
10
+ system("#{args.join(" ")} #{Config.get!(:compose_cmd)} -f #{Config.get!(:compose_file)} #{command}") || exit(1)
11
11
  end
12
12
 
13
13
  def kubectl(command, namespace: Config.get!(:namespace))
@@ -24,7 +24,7 @@ module Vidar
24
24
  end
25
25
 
26
26
  def kubectl_envs_hash
27
- { "HTTPS_PROXY" => Config.deploy_config.https_proxy }.compact
27
+ {"HTTPS_PROXY" => Config.deploy_config.https_proxy}.compact
28
28
  end
29
29
  end
30
30
  end
@@ -13,9 +13,12 @@ module Vidar
13
13
  def call
14
14
  connection.post do |req|
15
15
  req.url webhook_url
16
- req.headers['Content-Type'] = 'application/json'
16
+ req.headers["Content-Type"] = "application/json"
17
17
  req.body = data.to_json
18
18
  end
19
+ rescue Faraday::Error => e
20
+ warn "Sentry notification request failed: #{e.message}"
21
+ nil
19
22
  end
20
23
 
21
24
  private
@@ -2,10 +2,10 @@ module Vidar
2
2
  class SlackNotification
3
3
  def self.get
4
4
  new(
5
- github: Config.get!(:github),
6
- revision: Config.get!(:revision),
5
+ github: Config.get!(:github),
6
+ revision: Config.get!(:revision),
7
7
  revision_name: Config.get!(:revision_name),
8
- build_url: Config.build_url,
8
+ build_url: Config.build_url,
9
9
  deploy_config: Config.deploy_config
10
10
  )
11
11
  end
@@ -31,7 +31,7 @@ module Vidar
31
31
  def failure
32
32
  message = [
33
33
  "<!channel> Failed deploy of #{github_link} to #{deploy_link}.",
34
- build_link,
34
+ build_link
35
35
  ]
36
36
  perform_with data(message:, color: failure_color)
37
37
  end
@@ -39,7 +39,7 @@ module Vidar
39
39
  def success
40
40
  message = [
41
41
  "Successful deploy of #{github_link} to #{deploy_link}.",
42
- build_link,
42
+ build_link
43
43
  ]
44
44
  perform_with data(message:, color: success_color)
45
45
  end
@@ -51,9 +51,12 @@ module Vidar
51
51
  def perform_with(data)
52
52
  connection.post do |req|
53
53
  req.url webhook_url
54
- req.headers['Content-Type'] = 'application/json'
54
+ req.headers["Content-Type"] = "application/json"
55
55
  req.body = data.to_json
56
56
  end
57
+ rescue Faraday::Error => e
58
+ warn "Slack notification request failed: #{e.message}"
59
+ nil
57
60
  end
58
61
 
59
62
  private
@@ -72,7 +75,7 @@ module Vidar
72
75
  title_link: github_url,
73
76
  color:,
74
77
  text:,
75
- fallback: text,
78
+ fallback: text
76
79
  }
77
80
  ]
78
81
  }
data/lib/vidar/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vidar
2
- VERSION = '1.16.0'.freeze
2
+ VERSION = "1.17.1".freeze
3
3
  end
data/lib/vidar.rb CHANGED
@@ -1,25 +1,25 @@
1
- require 'json'
2
- require 'open3'
3
- require 'uri'
4
- require 'yaml'
1
+ require "json"
2
+ require "open3"
3
+ require "uri"
4
+ require "yaml"
5
5
 
6
- require 'colorized_string'
7
- require 'faraday'
8
- require 'thor'
6
+ require "colorized_string"
7
+ require "faraday"
8
+ require "thor"
9
9
 
10
- require 'vidar/version'
11
- require 'vidar/config'
12
- require 'vidar/honeycomb_notification'
13
- require 'vidar/interpolation'
14
- require 'vidar/log'
15
- require 'vidar/run'
16
- require 'vidar/sentry_notification'
17
- require 'vidar/slack_notification'
18
- require 'vidar/k8s/container'
19
- require 'vidar/k8s/pod_set'
20
- require 'vidar/deploy_config'
21
- require 'vidar/deploy_status'
22
- require 'vidar/cli'
10
+ require "vidar/version"
11
+ require "vidar/config"
12
+ require "vidar/honeycomb_notification"
13
+ require "vidar/interpolation"
14
+ require "vidar/log"
15
+ require "vidar/run"
16
+ require "vidar/sentry_notification"
17
+ require "vidar/slack_notification"
18
+ require "vidar/k8s/container"
19
+ require "vidar/k8s/pod_set"
20
+ require "vidar/deploy_config"
21
+ require "vidar/deploy_status"
22
+ require "vidar/cli"
23
23
 
24
24
  module Vidar
25
25
  Error = Class.new(StandardError)
data/vidar.gemspec CHANGED
@@ -1,32 +1,32 @@
1
- lib = File.expand_path('lib', __dir__)
1
+ lib = File.expand_path("lib", __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'vidar/version'
3
+ require "vidar/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = 'vidar'
6
+ spec.name = "vidar"
7
7
  spec.version = Vidar::VERSION
8
- spec.authors = ['Krzysztof Knapik', 'RenoFi Engineering Team']
9
- spec.email = ['knapo@knapo.net', 'engineering@renofi.com']
8
+ spec.authors = ["Krzysztof Knapik", "RenoFi Engineering Team"]
9
+ spec.email = ["knapo@knapo.net", "engineering@renofi.com"]
10
10
 
11
- spec.summary = 'K8s deployment tools based on thor'
12
- spec.homepage = 'https://github.com/RenoFi/vidar'
13
- spec.license = 'MIT'
11
+ spec.summary = "K8s deployment tools based on thor"
12
+ spec.homepage = "https://github.com/RenoFi/vidar"
13
+ spec.license = "MIT"
14
14
 
15
- spec.metadata['homepage_uri'] = 'https://github.com/RenoFi/vidar'
16
- spec.metadata['source_code_uri'] = 'https://github.com/RenoFi/vidar'
17
- spec.metadata['changelog_uri'] = 'https://github.com/RenoFi/vidar/blob/master/CHANGELOG.md'
18
- spec.metadata['rubygems_mfa_required'] = 'true'
15
+ spec.metadata["homepage_uri"] = "https://github.com/RenoFi/vidar"
16
+ spec.metadata["source_code_uri"] = "https://github.com/RenoFi/vidar"
17
+ spec.metadata["changelog_uri"] = "https://github.com/RenoFi/vidar/blob/master/CHANGELOG.md"
18
+ spec.metadata["rubygems_mfa_required"] = "true"
19
19
 
20
- spec.required_ruby_version = Gem::Requirement.new('>= 3.4.0')
20
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.4.0")
21
21
 
22
22
  spec.files = Dir.chdir(__dir__) do
23
23
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(bin/|spec/|\.rub)}) }
24
24
  end
25
- spec.bindir = 'exe'
25
+ spec.bindir = "exe"
26
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
- spec.require_paths = ['lib']
27
+ spec.require_paths = ["lib"]
28
28
 
29
- spec.add_dependency 'colorize'
30
- spec.add_dependency 'faraday'
31
- spec.add_dependency 'thor', '~> 1.0'
29
+ spec.add_dependency "colorize"
30
+ spec.add_dependency "faraday", ">= 2.0", "< 3"
31
+ spec.add_dependency "thor", "~> 1.0"
32
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vidar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.0
4
+ version: 1.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Krzysztof Knapik
@@ -30,14 +30,20 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '2.0'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '3'
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - ">="
39
42
  - !ruby/object:Gem::Version
40
- version: '0'
43
+ version: '2.0'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '3'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: thor
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +78,7 @@ files:
72
78
  - ".github/workflows/ci.yml"
73
79
  - ".gitignore"
74
80
  - ".rspec"
81
+ - ".standard.yml"
75
82
  - CHANGELOG.md
76
83
  - Gemfile
77
84
  - Gemfile.lock
@@ -116,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
123
  - !ruby/object:Gem::Version
117
124
  version: '0'
118
125
  requirements: []
119
- rubygems_version: 4.0.4
126
+ rubygems_version: 4.0.10
120
127
  specification_version: 4
121
128
  summary: K8s deployment tools based on thor
122
129
  test_files: []