gemika 0.4.1 → 0.5.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/test.yml +122 -0
- data/.ruby-version +1 -1
- data/Gemfile.3.2.mysql2 +1 -1
- data/Gemfile.3.2.mysql2.lock +9 -3
- data/Gemfile.4.2.mysql2 +1 -1
- data/Gemfile.4.2.mysql2.lock +3 -3
- data/Gemfile.4.2.pg.lock +1 -1
- data/Gemfile.5.2.mysql2 +1 -1
- data/Gemfile.5.2.mysql2.lock +3 -3
- data/Gemfile.5.2.pg.lock +1 -1
- data/Gemfile.5.2.sqlite3.lock +1 -1
- data/Gemfile.6.0.pg.lock +1 -1
- data/README.md +73 -4
- data/lib/gemika/errors.rb +2 -0
- data/lib/gemika/github_actions_generator.rb +150 -0
- data/lib/gemika/matrix.rb +38 -37
- data/lib/gemika/matrix/github_actions_config.rb +61 -0
- data/lib/gemika/matrix/travis_config.rb +42 -0
- data/lib/gemika/tasks.rb +1 -0
- data/lib/gemika/tasks/gemika.rb +14 -0
- data/lib/gemika/tasks/matrix.rb +4 -4
- data/lib/gemika/version.rb +1 -1
- data/spec/fixtures/github_actions_yml/Gemfile_without_gemika +1 -0
- data/spec/fixtures/github_actions_yml/excludes.yml +13 -0
- data/spec/fixtures/github_actions_yml/gemfile_without_gemika.yml +8 -0
- data/spec/fixtures/github_actions_yml/includes.yml +20 -0
- data/spec/fixtures/github_actions_yml/invalid.yml +8 -0
- data/spec/fixtures/github_actions_yml/missing_gemfile.yml +8 -0
- data/spec/fixtures/github_actions_yml/multiple_jobs.yml +16 -0
- data/spec/fixtures/github_actions_yml/two_by_two.yml +10 -0
- data/spec/fixtures/migrate/expected_github_actions.yml +129 -0
- data/{.travis.yml → spec/fixtures/migrate/travis.yml} +0 -0
- data/spec/gemika/matrix_spec.rb +100 -0
- data/spec/support/database.github.yml +13 -0
- metadata +18 -6
- data/Gemfile.2.3.mysql2 +0 -18
- data/Gemfile.2.3.mysql2.lock +0 -42
- data/spec/support/database.travis.yml +0 -9
data/lib/gemika/matrix.rb
CHANGED
@@ -1,47 +1,12 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'gemika/errors'
|
3
3
|
require 'gemika/env'
|
4
|
+
require 'gemika/matrix/travis_config'
|
5
|
+
require 'gemika/matrix/github_actions_config'
|
4
6
|
|
5
7
|
module Gemika
|
6
8
|
class Matrix
|
7
9
|
|
8
|
-
##
|
9
|
-
# Load `.travis.yml` files.
|
10
|
-
#
|
11
|
-
# @!visibility private
|
12
|
-
#
|
13
|
-
class TravisConfig
|
14
|
-
class << self
|
15
|
-
|
16
|
-
def load_rows(options)
|
17
|
-
path = options.fetch(:path, '.travis.yml')
|
18
|
-
travis_yml = YAML.load_file(path)
|
19
|
-
rubies = travis_yml.fetch('rvm', [])
|
20
|
-
gemfiles = travis_yml.fetch('gemfile', [])
|
21
|
-
matrix_options = travis_yml.fetch('matrix', {})
|
22
|
-
includes = matrix_options.fetch('include', [])
|
23
|
-
excludes = matrix_options.fetch('exclude', [])
|
24
|
-
|
25
|
-
rows = []
|
26
|
-
rubies.each do |ruby|
|
27
|
-
gemfiles.each do |gemfile|
|
28
|
-
row = { 'rvm' => ruby, 'gemfile' => gemfile }
|
29
|
-
rows << row unless excludes.include?(row)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
rows = rows + includes
|
34
|
-
rows = rows.map { |row| convert_row(row) }
|
35
|
-
rows
|
36
|
-
end
|
37
|
-
|
38
|
-
def convert_row(travis_row)
|
39
|
-
Row.new(:ruby => travis_row['rvm'], :gemfile => travis_row['gemfile'])
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
10
|
##
|
46
11
|
# A row in the test matrix
|
47
12
|
#
|
@@ -129,6 +94,25 @@ module Gemika
|
|
129
94
|
print_summary
|
130
95
|
end
|
131
96
|
|
97
|
+
|
98
|
+
##
|
99
|
+
# Builds a {Matrix} from a `.travis.yml` file, or falls back to a Github Action .yml file
|
100
|
+
#
|
101
|
+
# @param [Hash] options
|
102
|
+
# @option options [String] Path to the `.travis.yml` file.
|
103
|
+
#
|
104
|
+
def self.from_ci_config
|
105
|
+
travis_location = '.travis.yml'
|
106
|
+
workflow_location = '.github/workflows/test.yml'
|
107
|
+
if File.exists?(travis_location)
|
108
|
+
from_travis_yml(:path => travis_location)
|
109
|
+
elsif File.exists?(workflow_location)
|
110
|
+
from_github_actions_yml(:path => workflow_location)
|
111
|
+
else
|
112
|
+
raise MissingMatrixDefinition, "expected either a #{travis_location} or a #{workflow_location}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
132
116
|
##
|
133
117
|
# Builds a {Matrix} from the given `.travis.yml` file.
|
134
118
|
#
|
@@ -140,8 +124,25 @@ module Gemika
|
|
140
124
|
new(options.merge(:rows => rows))
|
141
125
|
end
|
142
126
|
|
127
|
+
##
|
128
|
+
# Builds a {Matrix} from the given Github Action workflow definition
|
129
|
+
#
|
130
|
+
# @param [Hash] options
|
131
|
+
# @option options [String] Path to the `.yml` file.
|
132
|
+
#
|
133
|
+
def self.from_github_actions_yml(options = {})
|
134
|
+
rows = GithubActionsConfig.load_rows(options)
|
135
|
+
new(options.merge(:rows => rows))
|
136
|
+
end
|
137
|
+
|
143
138
|
attr_reader :rows, :current_ruby
|
144
139
|
|
140
|
+
def self.generate_github_actions_workflow(options= {})
|
141
|
+
require 'gemika/github_actions_generator'
|
142
|
+
rows = TravisConfig.load_rows(options)
|
143
|
+
GithubActionsGenerator.new(bundler_version: Bundler::VERSION).generate(rows)
|
144
|
+
end
|
145
|
+
|
145
146
|
private
|
146
147
|
|
147
148
|
def puts(*args)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Gemika
|
2
|
+
class Matrix
|
3
|
+
|
4
|
+
##
|
5
|
+
# Load Github Action `.yml` files.
|
6
|
+
#
|
7
|
+
# @!visibility private
|
8
|
+
#
|
9
|
+
class GithubActionsConfig
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def load_rows(options)
|
13
|
+
path = options.fetch(:path, '.github/workflows/test.yml')
|
14
|
+
workflow_yml = YAML.load_file(path)
|
15
|
+
|
16
|
+
matrices = workflow_yml.fetch('jobs', {}).values.map do |job|
|
17
|
+
job.fetch('strategy', {})['matrix']
|
18
|
+
end.reject(&:nil?)
|
19
|
+
|
20
|
+
matrices.map do |matrix|
|
21
|
+
matrix_to_rows(matrix)
|
22
|
+
end.flatten(1)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def matrix_to_rows(matrix)
|
28
|
+
if (!matrix['ruby'] || !matrix['gemfile']) && (!matrix['include'])
|
29
|
+
raise InvalidMatrixDefinition, 'matrix must use the keys "ruby" and "gemfile"'
|
30
|
+
end
|
31
|
+
|
32
|
+
rubies = matrix.fetch('ruby', [])
|
33
|
+
gemfiles = matrix.fetch('gemfile', [])
|
34
|
+
|
35
|
+
includes = matrix.fetch('include', [])
|
36
|
+
excludes = matrix.fetch('exclude', [])
|
37
|
+
|
38
|
+
rows = []
|
39
|
+
rubies.each do |ruby|
|
40
|
+
gemfiles.each do |gemfile|
|
41
|
+
row = { 'ruby' => ruby, 'gemfile' => gemfile }
|
42
|
+
rows << row unless excludes.include?(row)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
rows = rows + includes
|
47
|
+
rows.map { |row| convert_row(row) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def convert_row(row_hash)
|
51
|
+
if !row_hash['ruby'] || !row_hash['gemfile']
|
52
|
+
raise InvalidMatrixDefinition, 'matrix must use the keys "ruby" and "gemfile"'
|
53
|
+
end
|
54
|
+
Row.new(:ruby => row_hash['ruby'], :gemfile => row_hash['gemfile'])
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Gemika
|
2
|
+
class Matrix
|
3
|
+
|
4
|
+
##
|
5
|
+
# Load `.travis.yml` files.
|
6
|
+
#
|
7
|
+
# @!visibility private
|
8
|
+
#
|
9
|
+
class TravisConfig
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def load_rows(options)
|
13
|
+
path = options.fetch(:path, '.travis.yml')
|
14
|
+
travis_yml = YAML.load_file(path)
|
15
|
+
rubies = travis_yml.fetch('rvm', [])
|
16
|
+
gemfiles = travis_yml.fetch('gemfile', [])
|
17
|
+
matrix_options = travis_yml.fetch('matrix', {})
|
18
|
+
includes = matrix_options.fetch('include', [])
|
19
|
+
excludes = matrix_options.fetch('exclude', [])
|
20
|
+
|
21
|
+
rows = []
|
22
|
+
rubies.each do |ruby|
|
23
|
+
gemfiles.each do |gemfile|
|
24
|
+
row = { 'rvm' => ruby, 'gemfile' => gemfile }
|
25
|
+
rows << row unless excludes.include?(row)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
rows = rows + includes
|
30
|
+
rows = rows.map { |row| convert_row(row) }
|
31
|
+
rows
|
32
|
+
end
|
33
|
+
|
34
|
+
def convert_row(travis_row)
|
35
|
+
Row.new(:ruby => travis_row['rvm'], :gemfile => travis_row['gemfile'])
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
data/lib/gemika/tasks.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'gemika/env'
|
2
|
+
require 'gemika/matrix'
|
3
|
+
|
4
|
+
##
|
5
|
+
# Rake tasks to run commands for each compatible row in the test matrix.
|
6
|
+
#
|
7
|
+
namespace :gemika do
|
8
|
+
|
9
|
+
desc "Generate a github action workflow from a .travis.yml"
|
10
|
+
task :generate_github_actions_workflow do
|
11
|
+
puts Gemika::Matrix.generate_github_actions_workflow.to_yaml
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
data/lib/gemika/tasks/matrix.rb
CHANGED
@@ -9,7 +9,7 @@ namespace :matrix do
|
|
9
9
|
|
10
10
|
desc "Run specs for all Ruby #{RUBY_VERSION} gemfiles"
|
11
11
|
task :spec, :files do |t, options|
|
12
|
-
Gemika::Matrix.
|
12
|
+
Gemika::Matrix.from_ci_config.each do |row|
|
13
13
|
options = options.to_hash.merge(
|
14
14
|
:gemfile => row.gemfile,
|
15
15
|
:fatal => false,
|
@@ -21,21 +21,21 @@ namespace :matrix do
|
|
21
21
|
|
22
22
|
desc "Install all Ruby #{RUBY_VERSION} gemfiles"
|
23
23
|
task :install do
|
24
|
-
Gemika::Matrix.
|
24
|
+
Gemika::Matrix.from_ci_config.each do |row|
|
25
25
|
system('bundle install')
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
desc "List dependencies for all Ruby #{RUBY_VERSION} gemfiles"
|
30
30
|
task :list do
|
31
|
-
Gemika::Matrix.
|
31
|
+
Gemika::Matrix.from_ci_config.each do |row|
|
32
32
|
system('bundle list')
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
desc "Update all Ruby #{RUBY_VERSION} gemfiles"
|
37
37
|
task :update, :gems do |t, options|
|
38
|
-
Gemika::Matrix.
|
38
|
+
Gemika::Matrix.from_ci_config.each do |row|
|
39
39
|
system("bundle update #{options[:gems]}")
|
40
40
|
end
|
41
41
|
end
|
data/lib/gemika/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
gem 'some-gem'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
matrix:
|
2
|
+
jobs:
|
3
|
+
first_job:
|
4
|
+
strategy:
|
5
|
+
matrix:
|
6
|
+
ruby:
|
7
|
+
- "2.1.8"
|
8
|
+
- "2.3.1"
|
9
|
+
gemfile:
|
10
|
+
- gemfiles/Gemfile1
|
11
|
+
- gemfiles/Gemfile2
|
12
|
+
include:
|
13
|
+
- ruby: 2.6.3
|
14
|
+
gemfile: gemfiles/Gemfile3
|
15
|
+
second_job:
|
16
|
+
strategy:
|
17
|
+
matrix:
|
18
|
+
include:
|
19
|
+
- ruby: 2.7.1
|
20
|
+
gemfile: gemfiles/Gemfile3
|
@@ -0,0 +1,129 @@
|
|
1
|
+
name: Tests
|
2
|
+
'on':
|
3
|
+
push:
|
4
|
+
branches:
|
5
|
+
- master
|
6
|
+
pull_request:
|
7
|
+
branches:
|
8
|
+
- master
|
9
|
+
jobs:
|
10
|
+
test_mysql:
|
11
|
+
runs-on: ubuntu-20.04
|
12
|
+
services:
|
13
|
+
mysql:
|
14
|
+
image: mysql:5.6
|
15
|
+
env:
|
16
|
+
MYSQL_ROOT_PASSWORD: password
|
17
|
+
options: --health-cmd "mysqladmin ping" --health-interval 10s --health-timeout
|
18
|
+
5s --health-retries 5
|
19
|
+
ports:
|
20
|
+
- 3306:3306
|
21
|
+
strategy:
|
22
|
+
fail-fast: false
|
23
|
+
matrix:
|
24
|
+
include:
|
25
|
+
- ruby: 1.8.7
|
26
|
+
gemfile: Gemfile.2.3.mysql2
|
27
|
+
- ruby: 1.8.7
|
28
|
+
gemfile: Gemfile.3.2.mysql2
|
29
|
+
- ruby: 2.1.8
|
30
|
+
gemfile: Gemfile.3.2.mysql2
|
31
|
+
- ruby: 2.2.4
|
32
|
+
gemfile: Gemfile.3.2.mysql2
|
33
|
+
- ruby: 2.1.8
|
34
|
+
gemfile: Gemfile.4.2.mysql2
|
35
|
+
- ruby: 2.2.4
|
36
|
+
gemfile: Gemfile.4.2.mysql2
|
37
|
+
- ruby: 2.3.1
|
38
|
+
gemfile: Gemfile.4.2.mysql2
|
39
|
+
- ruby: 2.2.4
|
40
|
+
gemfile: Gemfile.5.2.mysql2
|
41
|
+
- ruby: 2.3.1
|
42
|
+
gemfile: Gemfile.5.2.mysql2
|
43
|
+
env:
|
44
|
+
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
45
|
+
steps:
|
46
|
+
- uses: actions/checkout@v2
|
47
|
+
- name: Install ruby
|
48
|
+
uses: ruby/setup-ruby@v1
|
49
|
+
with:
|
50
|
+
ruby-version: "${{ matrix.ruby }}"
|
51
|
+
- name: Setup database
|
52
|
+
run: |
|
53
|
+
sudo apt-get install -y mysql-client libmariadbclient-dev
|
54
|
+
mysql -e 'create database IF NOT EXISTS test;' -u root --password=password -P 3306 -h 127.0.0.1
|
55
|
+
- name: Bundle
|
56
|
+
run: |
|
57
|
+
gem install bundler:1.17.3
|
58
|
+
bundle install --no-deployment
|
59
|
+
- name: Run tests
|
60
|
+
run: bundle exec rspec
|
61
|
+
test_pg:
|
62
|
+
runs-on: ubuntu-20.04
|
63
|
+
services:
|
64
|
+
postgres:
|
65
|
+
image: postgres
|
66
|
+
env:
|
67
|
+
POSTGRES_PASSWORD: postgres
|
68
|
+
options: "--health-cmd pg_isready --health-interval 10s --health-timeout 5s
|
69
|
+
--health-retries 5"
|
70
|
+
ports:
|
71
|
+
- 5432:5432
|
72
|
+
strategy:
|
73
|
+
fail-fast: false
|
74
|
+
matrix:
|
75
|
+
include:
|
76
|
+
- ruby: 2.1.8
|
77
|
+
gemfile: Gemfile.4.2.pg
|
78
|
+
- ruby: 2.2.4
|
79
|
+
gemfile: Gemfile.4.2.pg
|
80
|
+
- ruby: 2.3.1
|
81
|
+
gemfile: Gemfile.4.2.pg
|
82
|
+
- ruby: 2.2.4
|
83
|
+
gemfile: Gemfile.5.2.pg
|
84
|
+
- ruby: 2.3.1
|
85
|
+
gemfile: Gemfile.5.2.pg
|
86
|
+
- ruby: 2.6.4
|
87
|
+
gemfile: Gemfile.6.0.pg
|
88
|
+
env:
|
89
|
+
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
90
|
+
steps:
|
91
|
+
- uses: actions/checkout@v2
|
92
|
+
- name: Install ruby
|
93
|
+
uses: ruby/setup-ruby@v1
|
94
|
+
with:
|
95
|
+
ruby-version: "${{ matrix.ruby }}"
|
96
|
+
- name: Setup database
|
97
|
+
run: |
|
98
|
+
sudo apt-get install -y postgresql-client
|
99
|
+
PGPASSWORD=postgres psql -c 'create database test;' -U postgres -p 5432 -h localhost
|
100
|
+
- name: Bundle
|
101
|
+
run: |
|
102
|
+
gem install bundler:1.17.3
|
103
|
+
bundle install --no-deployment
|
104
|
+
- name: Run tests
|
105
|
+
run: bundle exec rspec
|
106
|
+
test_sqlite:
|
107
|
+
runs-on: ubuntu-20.04
|
108
|
+
strategy:
|
109
|
+
fail-fast: false
|
110
|
+
matrix:
|
111
|
+
include:
|
112
|
+
- ruby: 2.2.4
|
113
|
+
gemfile: Gemfile.5.2.sqlite3
|
114
|
+
- ruby: 2.3.1
|
115
|
+
gemfile: Gemfile.5.2.sqlite3
|
116
|
+
env:
|
117
|
+
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
118
|
+
steps:
|
119
|
+
- uses: actions/checkout@v2
|
120
|
+
- name: Install ruby
|
121
|
+
uses: ruby/setup-ruby@v1
|
122
|
+
with:
|
123
|
+
ruby-version: "${{ matrix.ruby }}"
|
124
|
+
- name: Bundle
|
125
|
+
run: |
|
126
|
+
gem install bundler:1.17.3
|
127
|
+
bundle install --no-deployment
|
128
|
+
- name: Run tests
|
129
|
+
run: bundle exec rspec
|