11---
2- name : CD
3-
4- on :
5- workflow_dispatch :
6- push :
7- tags : ["v*"]
8-
9- concurrency :
10- group : ${{ github.workflow }}-${{ github.ref }}
11- cancel-in-progress : true
12-
13- jobs :
14- ci-data :
15- runs-on : ubuntu-latest
16- outputs :
17- result : ${{ steps.fetch.outputs.result }}
18- steps :
19- - id : fetch
20- uses : oxidize-rb/actions/fetch-ci-data@v1
21- with :
22- supported-ruby-platforms : |
23- # Excluding:
24- # `arm-linux`: Cranelift doesn't support 32-bit architectures
25- # `x64-mingw32`: `x64-mingw-ucrt` should be used for Ruby 3.1+ (https://github.com/rake-compiler/rake-compiler-dock?tab=readme-ov-file#windows)
26- # 3.0 is deprecated as stable ruby version according to:
27- # https://github.com/oxidize-rb/actions/blob/main/fetch-ci-data/evaluate.rb#L54
28- exclude: [arm-linux, x64-mingw32]
29- stable-ruby-versions : |
30- exclude: [head]
31-
32- build :
33- name : Build native gems
34- needs : ci-data
35- runs-on : ubuntu-latest
36- strategy :
37- fail-fast : false
38- matrix :
39- ruby-platform : ${{ fromJSON(needs.ci-data.outputs.result).supported-ruby-platforms }}
40- steps :
41- - uses : actions/checkout@v4
42-
43- - uses : ruby/setup-ruby@v1
44- with :
45- ruby-version : " 3.4"
46-
47- - uses : oxidize-rb/actions/cross-gem@v1
48- id : cross-gem
49- with :
50- platform : ${{ matrix.ruby-platform }}
51- ruby-versions : ${{ join(fromJSON(needs.ci-data.outputs.result).stable-ruby-versions, ',') }}
52-
53- - uses : actions/upload-artifact@v4
54- with :
55- name : cross-gem-${{ matrix.ruby-platform }}
56- path : pkg/*-${{ matrix.ruby-platform }}.gem
57- if-no-files-found : error
58-
59- - name : Smoke gem install
60- if : matrix.ruby-platform == 'ignore-for-now-x86_64-linux' # GitHub actions architecture
61- run : |
62- gem install pkg/fast_code_owners-*.gem --verbose
63- script="puts FastCodeOwners::VERSION"
64- ruby -rfast_code_owners -e "$script" | grep 0.1.0
65- echo "✅ Successfully gem installed"
66-
67- release :
68- name : Release
69- needs : build
70- runs-on : ubuntu-latest
71- steps :
72- - uses : actions/checkout@v4
73-
74- - uses : oxidize-rb/actions/setup-ruby-and-rust@v1
75- with :
76- ruby-version : " 3.4"
77- bundler-cache : true
78- cargo-cache : true
79- cache-version : v1
80-
81- - uses : actions/download-artifact@v4
82- with :
83- pattern : cross-gem-*
84- merge-multiple : true
85- path : pkg/
86-
87- - name : Package source gem
88- run : bundle exec rake pkg:ruby
89-
90- - name : Ensure version matches the tag
91- run : |
92- GEM_VERSION=$(grep -Eo "[0-9]+\.[0-9]+\.[0-9]+[-0-9]*" lib/code_ownership/version.rb | head -n 1)
93- if [ "v$GEM_VERSION" != "${{ github.ref_name }}" ]; then
94- echo "Gem version does not match tag"
95- echo " v$GEM_VERSION != ${{ github.ref_name }}"
96- exit 1
97- fi
98-
99- - name : Push Gem
100- working-directory : pkg/
101- env :
102- GEM_HOST_API_KEY : ${{ secrets.RUBYGEMS_API_KEY }}
103- run : |
104- mkdir -p $HOME/.gem
105- touch $HOME/.gem/credentials
106- chmod 0600 $HOME/.gem/credentials
107- printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
108- ls -l
109- for i in *.gem; do
110- if [ -f "$i" ]; then
111- if ! gem push "$i" >push.out; then
112- gemerr=$?
113- sed 's/^/::error:: /' push.out
114- if ! grep -q "Repushing of gem" push.out; then
115- exit $gemerr
116- fi
2+ name : CD
3+
4+ on :
5+ workflow_call :
6+ workflow_dispatch : # Allow manual triggering
7+ inputs :
8+ dry_run :
9+ description : ' Dry run (skip actual gem push)'
10+ required : false
11+ type : boolean
12+ default : false
13+
14+ concurrency :
15+ group : ${{ github.workflow }}-${{ github.ref }}
16+ cancel-in-progress : true
17+
18+ jobs :
19+ ci-data :
20+ runs-on : ubuntu-latest
21+ outputs :
22+ result : ${{ steps.fetch.outputs.result }}
23+ steps :
24+ - id : fetch
25+ uses : oxidize-rb/actions/fetch-ci-data@v1
26+ with :
27+ supported-ruby-platforms : |
28+ # Excluding:
29+ # `arm-linux`: Cranelift doesn't support 32-bit architectures
30+ # `x64-mingw32`: `x64-mingw-ucrt` should be used for Ruby 3.1+ (https://github.com/rake-compiler/rake-compiler-dock?tab=readme-ov-file#windows)
31+ # `x64-mingw-ucrt`: Rust target not available in rake-compiler-dock
32+ # `aarch64-linux-musl`: Rust target not available in rake-compiler-dock
33+ # 3.0 is deprecated as stable ruby version according to:
34+ # https://github.com/oxidize-rb/actions/blob/main/fetch-ci-data/evaluate.rb#L54
35+ exclude: [arm-linux, x64-mingw32, x64-mingw-ucrt, aarch64-linux-musl]
36+ stable-ruby-versions : |
37+ exclude: [head]
38+
39+ build :
40+ name : Build native gems
41+ needs : ci-data
42+ runs-on : ubuntu-latest
43+ strategy :
44+ fail-fast : false
45+ matrix :
46+ ruby-platform : ${{ fromJSON(needs.ci-data.outputs.result).supported-ruby-platforms }}
47+ steps :
48+ - uses : actions/checkout@v4
49+
50+ - uses : ruby/setup-ruby@v1
51+ with :
52+ ruby-version : " 3.4"
53+
54+ - uses : oxidize-rb/actions/cross-gem@v1
55+ id : cross-gem
56+ with :
57+ platform : ${{ matrix.ruby-platform }}
58+ ruby-versions : ${{ join(fromJSON(needs.ci-data.outputs.result).stable-ruby-versions, ',') }}
59+ cache-save-always : false
60+ cargo-cache-clean : false # Add this to disable cargo-cache usage
61+ env :
62+ # Add a unique identifier to prevent cache conflicts
63+ ACTIONS_CACHE_KEY_SUFFIX : " -${{ matrix.ruby-platform }}-${{ github.run_id }}"
64+
65+ - uses : actions/upload-artifact@v4
66+ with :
67+ name : cross-gem-${{ matrix.ruby-platform }}
68+ path : pkg/*-${{ matrix.ruby-platform }}.gem
69+ if-no-files-found : error
70+ retention-days : 30 # Keep artifacts for 30 days
71+
72+ - name : Smoke test gem install
73+ if : matrix.ruby-platform == 'x86_64-linux' # Enable for Linux x64
74+ run : |
75+ # Install the platform-specific gem
76+ gem install pkg/code_ownership-*-${{ matrix.ruby-platform }}.gem --verbose
77+
78+ # Test that it works
79+ ruby -e "require 'code_ownership'; puts 'Version: ' + CodeOwnership::VERSION"
80+
81+ # Run a simple functionality test
82+ ruby -e "require 'code_ownership'; CodeOwnership.file_owner_team_names('lib/code_ownership.rb')" || true
83+
84+ echo "✅ Successfully tested ${{ matrix.ruby-platform }} gem"
85+
86+ release :
87+ name : Release
88+ needs : build
89+ runs-on : ubuntu-latest
90+ permissions :
91+ contents : write # Required for creating releases
92+ steps :
93+ - uses : actions/checkout@v4
94+
95+ - uses : oxidize-rb/actions/setup-ruby-and-rust@v1
96+ with :
97+ ruby-version : " 3.4"
98+ bundler-cache : true
99+ cargo-cache : false
100+
101+ - uses : actions/download-artifact@v4
102+ with :
103+ pattern : cross-gem-*
104+ merge-multiple : true
105+ path : pkg/
106+
107+ - name : Package source gem
108+ run : bundle exec rake pkg:ruby
109+
110+ - name : Push Gem
111+ id : push-gem
112+ working-directory : pkg/
113+ env :
114+ GEM_HOST_API_KEY : ${{ secrets.RUBYGEMS_API_KEY }}
115+ run : |
116+ set -e # Exit on error
117+
118+ # Setup credentials
119+ mkdir -p $HOME/.gem
120+ touch $HOME/.gem/credentials
121+ chmod 0600 $HOME/.gem/credentials
122+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
123+
124+ # List all gems to be pushed
125+ echo "📦 Gems to be pushed:"
126+ ls -la *.gem
127+
128+ # Extract version from the Ruby version file
129+ GEM_VERSION=$(ruby -r ../lib/code_ownership/version.rb -e "puts CodeOwnership::VERSION")
130+ echo "gem_version=${GEM_VERSION}" >> $GITHUB_OUTPUT
131+ echo "🏷️ Detected gem version: ${GEM_VERSION}"
132+
133+ # Track results
134+ NEW_VERSION=false
135+ PUSHED_GEMS=()
136+ SKIPPED_GEMS=()
137+
138+ for i in *.gem; do
139+ if [ -f "$i" ]; then
140+ echo "⏳ Attempting to push $i..."
141+ if ! gem push "$i" >push.out 2>&1; then
142+ gemerr=$?
143+ if grep -q "Repushing of gem" push.out; then
144+ echo "⏭️ Gem $i already exists on RubyGems, skipping..."
145+ SKIPPED_GEMS+=("$i")
146+ else
147+ echo "❌ Failed to push $i:"
148+ cat push.out
149+ exit $gemerr
117150 fi
151+ else
152+ echo "✅ Successfully pushed $i"
153+ PUSHED_GEMS+=("$i")
154+ NEW_VERSION=true
118155 fi
119- done
120-
121- - name : Create GitHub release
122- uses : ncipollo/release-action@v1
123- with :
124- allowUpdates : true
125- generateReleaseNotes : true
126- draft : true
127- omitBodyDuringUpdate : true
128- omitNameDuringUpdate : true
129- omitPrereleaseDuringUpdate : true
130- skipIfReleaseExists : true
156+ fi
157+ done
158+
159+ # Summary
160+ echo "📊 Push Summary:"
161+ echo " - Pushed: ${#PUSHED_GEMS[@]} gems"
162+ echo " - Skipped: ${#SKIPPED_GEMS[@]} gems"
163+
164+ # Set outputs
165+ echo "new_version=${NEW_VERSION}" >> $GITHUB_OUTPUT
166+ echo "pushed_count=${#PUSHED_GEMS[@]}" >> $GITHUB_OUTPUT
167+ echo "skipped_count=${#SKIPPED_GEMS[@]}" >> $GITHUB_OUTPUT
168+
169+ - name : Create GitHub Release
170+ if : ${{ steps.push-gem.outputs.new_version == 'true' }}
171+ env :
172+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
173+ run : |
174+ # Create release with more detailed information
175+ RELEASE_NOTES="## CodeOwnership v${{ steps.push-gem.outputs.gem_version }}
176+
177+ ### 📦 Published Gems
178+ - Source gem: code_ownership-${{ steps.push-gem.outputs.gem_version }}.gem
179+ - Platform gems: Published for all supported platforms
180+
181+ ### 🎯 Supported Platforms
182+ $(ls pkg/*.gem | grep -E '\-(x86|arm|aarch)' | sed 's/.*-\([^-]*\)\.gem/- \1/')
183+
184+ ---
185+ "
186+
187+ gh release create "v${{ steps.push-gem.outputs.gem_version }}" \
188+ --title "v${{ steps.push-gem.outputs.gem_version }}" \
189+ --notes "$RELEASE_NOTES" \
190+ --generate-notes \
191+ pkg/*.gem
0 commit comments