cibuildgem 0.2.1 โ†’ 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 99cac230a997ce3d919879ca0efd36eab30f2f986180e98a323ff3b071612061
4
- data.tar.gz: 695a15ca392fa0eff89f3a2296e76d7a9f74a4adb16471d39d1d951d4d118076
3
+ metadata.gz: f6f1f69c8bc8ebbbe053eab7e7d12d680c3cf2fce25720165e7bcf5340238eff
4
+ data.tar.gz: 1a9190614d8194c3bd972dda1bc559e42ee4b69ca7f1a61682fbb8b390f79b2c
5
5
  SHA512:
6
- metadata.gz: 942a473c81416014f2c4e37442ca035d4a28af007b93b83199bde026288b14f857e0bf3e770f5f1339d003dbe38bc76a69e3718991e3ebe3ea29ffbbc4267eee
7
- data.tar.gz: 6eae16529e1501441099024045e812519402d47aa8d80532ea55a464f6b6fbddb22cb2604942ad3faecc1835128498cf927100356b2a7dd591698b27c775b015
6
+ metadata.gz: a180af046d430b34fe5bd6173d8047d836d2cd623455fbf44a5001a8d51364df28f3ebee1a65b687091535784bd0efd9331a1ba32d54e65e6270738f88f062a1
7
+ data.tar.gz: c64afb34a1f9927bdb3821fcd281c7c5e6a469176ca14084969290520fde52d180a4cbcd0c918abec847063be42b9999d2daba93f56b586c0c6b571791180c42
data/README.md CHANGED
@@ -22,49 +22,22 @@ As noted by [@flavorjones](https://github.com/flavorjones), this toolchain works
22
22
 
23
23
  ## ๐Ÿ’ป cibuildgem
24
24
 
25
- > [!NOTE]
26
- > cibuildgem is for now not able to compile projects that needs to link on external libraries. Unless the project vendors those libraries or uses [mini_portile](https://github.com/flavorjones/mini_portile).
27
-
28
- ### How to use it
29
-
30
- While cibuildgem is generally **not** meant to be used locally, it provides a command to generate the right GitHub workflow for your project:
31
-
32
- 1. Install cibuildgem: `gem install cibuildgem`
33
- 2. Generate the workflow: `cd` in your gem's folder and run `cibuildgem ci_template`
34
- 3. Commit the `.github/workflows/cibuildgem.yaml` file.
35
-
36
- ### Triggering the workflow
37
-
38
- Once pushed in your repository **default** branch, the workflow that we just generated is actionable manually on the GitHub action page. It will run in sequence:
39
-
40
- 1. Compile the gem on the target platform (defaults to MacOS ARM, MacOS Intel, Windows, Ubuntu 24)
41
- 2. Once the compilation succeeds on all platform, it proceeds to run the test suite on the target platform. This will trigger many CI steps as the testing matrix is big.
42
- 3. Once the test suite passes for all platforms and all Ruby versions the gem is compatible with, the action proceeds to installing the gem we just packaged. This step ensure that the gem is actually installable.
43
- 4. [OPTIONAL] When trigering the workflow manually, you can tick the box to automatically release the gems that were packaged. This works using the RubyGems trusted publisher feature (documentation to write later). If you do no want the tool to make the release, you can download all the GitHub artifacts that were uploaded. It will contain all the gems with precompiled binaries in the `pkg` folder. You are free to download them locally and release them yourself from your machine.
25
+ Head to the [documentation Wiki](https://github.com/Shopify/cibuildgem/wiki) to setup and configure cibuildgem for your gem.
44
26
 
27
+ ## Working examples
45
28
 
46
- ### Changes to make in your gem to support precompiled binaries
29
+ Here are some working examples on gem that have setup cibuildgem
47
30
 
48
- Due to the RubyGems specification, we can't release a gem with precompiled binaries for a specific Ruby version. Because the Ruby ABI is incompatible between minor versions, Rake Compiler (the tool underneath cibuildgem), compiles the binary for every minor Ruby versions your gem supports. All those binaries will be packaged in the gem (called a fat gem) in different folder such as `3.0/date.so`, `3.1/date.so` etc...
49
- At runtime, your gem need to require the right binary based on the running ruby version.
31
+ | Name | Example Run | Published Gem |
32
+ |-----------|-------------|---------------|
33
+ | [Rubydex](https://github.com/shopify/rubydex) | [CI Run](https://github.com/Shopify/rubydex/actions/runs/21880161517) | [Gem](https://rubygems.org/gems/rubydex/versions/0.1.0.beta4-arm64-darwin) |
34
+ | [Heap Profiler](https://github.com/shopify/heap-profiler) | [CI Run](https://github.com/Shopify/heap-profiler/actions/runs/20996043558) | [Gem](https://rubygems.org/gems/heap-profiler/versions/0.8.0.rc1-x86_64-linux) |
35
+ | [djb2](https://github.com/Shopify/djb2) | [CI Run](https://github.com/Shopify/djb2/actions/runs/22188688549) | [Gem](https://rubygems.org/gems/djb2/versions/0.1.1-x86_64-linux) |
36
+ | [Blake3](https://github.com/Shopify/blake3-rb) | [CI Run](https://github.com/Shopify/blake3-rb/actions/runs/21253662535) | [Gem](https://rubygems.org/gems/blake3-rb/versions/1.5.6.rc1-x86_64-linux) |
37
+ | [Raindrops (fork)](https://github.com/Edouard-chin/raindrops) | [CI Run](https://github.com/Edouard-chin/raindrops/actions/runs/22045845221) | [Gem](https://rubygems.org/gems/precompiled-raindrops) |
38
+ | [Stack Frames](https://github.com/Shopify/stack_frames) | [CI Run](https://github.com/Shopify/stack_frames/actions/runs/19969899178) | [Gem](https://rubygems.org/gems/stack_frames/versions/0.1.4-x86_64-linux) |
50
39
 
51
- ```ruby
52
- # Before
53
-
54
- require 'date_core.so'
55
-
56
- # After
57
-
58
- begin
59
- ruby_version = /(\d+\.\d+)/.match(::RUBY_VERSION)
60
- require "#{ruby_version}/date_core"
61
- rescue LoadError
62
- # It's important to leave for users that can not or don't want to use the gem with precompiled binaries.
63
- require "date_core"
64
- end
65
- ```
66
-
67
- ### Supported platforms/Ruby versions
40
+ ## Supported platforms/Ruby versions
68
41
 
69
42
  | | MacOS Intel | MacOS ARM | Windows x64 UCRT | Linux GNU x86_64|Linux AARCH64 |
70
43
  |---------|------------- | --------- | ------------|-----------------|-----------------|
@@ -72,7 +45,4 @@ end
72
45
  | Ruby 3.2| ๐ŸŸข | ๐ŸŸข | ๐ŸŸข | ๐ŸŸข | ๐ŸŸข |
73
46
  | Ruby 3.3| ๐ŸŸข | ๐ŸŸข | ๐ŸŸข | ๐ŸŸข | ๐ŸŸข |
74
47
  | Ruby 3.4| ๐ŸŸข | ๐ŸŸข | ๐ŸŸข | ๐ŸŸข | ๐ŸŸข |
75
-
76
- ## ๐Ÿงช Development
77
-
78
- If you'd like to run a end-to-end test, the `date` gem is vendored in this project. You can trigger a manual run to do the whole compile, test, install dance from the GitHub action menu.
48
+ | Ruby 4.0| ๐ŸŸข | ๐ŸŸข | ๐ŸŸ  (not tested)| ๐ŸŸข | ๐ŸŸข |
@@ -3,6 +3,7 @@
3
3
  require "thor"
4
4
  require "rake/extensiontask"
5
5
  require "prism"
6
+ require "open3"
6
7
 
7
8
  module Cibuildgem
8
9
  class CLI < Thor
@@ -112,14 +113,23 @@ module Cibuildgem
112
113
  pathname = Pathname(file)
113
114
  next if pathname.directory? || pathname.extname != ".gem"
114
115
 
115
- Kernel.system("gem push #{file}", exception: true)
116
+ out, status = Open3.capture2e("gem push #{file}")
117
+ next if status.success?
118
+
119
+ if out =~ /Repushing of gem versions is not allowed/
120
+ puts "Gem #{file} already exists on RubyGems.org, skipping..."
121
+
122
+ next
123
+ end
124
+
125
+ raise out
116
126
  end
117
127
  end
118
128
 
119
129
  desc "print_ruby_cc_version", "Output the cross compile ruby version needed for the gem. For internal usage", hide: true
120
130
  method_option "gemspec", type: "string", required: false, desc: "The gemspec to use. If the option is not passed, a gemspec file from the current working directory will be used."
121
131
  def print_ruby_cc_version
122
- print(compilation_task.ruby_cc_version)
132
+ print(ENV["RUBY_CC_VERSION"] || compilation_task.ruby_cc_version)
123
133
  end
124
134
 
125
135
  desc "normalized_platform", "The platform name for compilation purposes", hide: true
@@ -17,8 +17,6 @@ module Cibuildgem
17
17
  end
18
18
 
19
19
  def setup
20
- Rake::ExtensionTask.enable!
21
-
22
20
  gemspec.extensions.each do |path|
23
21
  binary_name = parse_extconf(path)
24
22
  define_task(path, binary_name)
@@ -54,16 +52,19 @@ module Cibuildgem
54
52
  end
55
53
 
56
54
  def define_task(path, binary_name)
57
- @extension_task = Rake::ExtensionTask.new do |ext|
58
- ext.name = File.basename(binary_name)
59
- ext.config_script = File.basename(path)
60
- ext.ext_dir = File.dirname(path)
61
- ext.lib_dir = binary_lib_dir(binary_name) if binary_lib_dir(binary_name)
62
- ext.gem_spec = gemspec
63
- ext.cross_platform = normalized_platform
64
- ext.cross_compile = true
65
- ext.no_native = true
66
- end
55
+ @extension_task = Rake::ExtensionTask.current || Rake::ExtensionTask.new
56
+
57
+ @extension_task.name = File.basename(binary_name)
58
+ @extension_task.config_script = File.basename(path)
59
+ @extension_task.ext_dir = File.dirname(path)
60
+ @extension_task.lib_dir = binary_lib_dir(binary_name) if binary_lib_dir(binary_name)
61
+ @extension_task.gem_spec = gemspec
62
+ @extension_task.cross_platform = normalized_platform
63
+ @extension_task.cross_compile = true
64
+ @extension_task.no_native = true
65
+
66
+ Rake::ExtensionTask.enable!
67
+ @extension_task.define
67
68
 
68
69
  disable_shared unless Gem.win_platform?
69
70
  end
@@ -92,6 +93,17 @@ module Cibuildgem
92
93
 
93
94
  File.write(task.name, makefile_content)
94
95
  end
96
+
97
+ makefile_content.match(/^ldflags\W+=(.*)/) do |match|
98
+ ldflags = match[1].split(" ")
99
+ next if ldflags.include?("-s")
100
+
101
+ ldflags << "-s"
102
+
103
+ makefile_content.gsub!(/^(ldflags\W+=)(.*)/, "\\1#{ldflags.join(" ")}")
104
+
105
+ File.write(task.name, makefile_content)
106
+ end
95
107
  end
96
108
  end
97
109
  end
@@ -7,7 +7,7 @@ module Cibuildgem
7
7
  class << self
8
8
  def prepended(mod)
9
9
  class << mod
10
- attr_accessor :enabled
10
+ attr_accessor :enabled, :current
11
11
 
12
12
  def enable!
13
13
  @enabled = true
@@ -16,6 +16,12 @@ module Cibuildgem
16
16
  end
17
17
  end
18
18
 
19
+ def initialize(*)
20
+ super
21
+
22
+ self.class.current = self
23
+ end
24
+
19
25
  def define
20
26
  super if self.class.enabled
21
27
  end
@@ -12,11 +12,9 @@ task "cibuildgem:setup" do
12
12
  end
13
13
 
14
14
  task "copy:stage:lib" do
15
- version = RUBY_VERSION.match(/(\d\.\d)/)[1]
16
- dest = File.join(task.extension_task.lib_dir, version)
17
- src = File.join("tmp", task.extension_task.cross_platform, "stage", dest)
15
+ src = File.join("tmp", task.extension_task.cross_platform, "stage")
18
16
 
19
- cp_r(src, dest, remove_destination: true)
17
+ cp_r(Dir.glob("#{src}/*"), ".", remove_destination: true)
20
18
  end
21
19
 
22
20
  unless Rake::Task.task_defined?(:test)
@@ -7,6 +7,8 @@ on:
7
7
  required: false
8
8
  type: boolean
9
9
  default: false
10
+ env:
11
+ CIBUILDGEM: 1
10
12
  jobs:
11
13
  compile:
12
14
  timeout-minutes: 20
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cibuildgem
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cibuildgem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify