CD #160
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
name: CD | |
on: | |
workflow_call: | |
workflow_dispatch: | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
ci-data: | |
runs-on: ubuntu-latest | |
outputs: | |
result: ${{ steps.fetch.outputs.result }} | |
steps: | |
- id: fetch | |
uses: oxidize-rb/actions/fetch-ci-data@v1 | |
with: | |
supported-ruby-platforms: | | |
# Excluding: | |
# `arm-linux`: Cranelift doesn't support 32-bit architectures | |
# `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) | |
# `x64-mingw-ucrt`: Rust target not available in rake-compiler-dock | |
# `aarch64-linux-musl`: Rust target not available in rake-compiler-dock | |
# 3.0 is deprecated as stable ruby version according to: | |
# https://github.com/oxidize-rb/actions/blob/main/fetch-ci-data/evaluate.rb#L54 | |
exclude: [arm-linux, x64-mingw32, x64-mingw-ucrt, aarch64-linux-musl] | |
stable-ruby-versions: | | |
exclude: [head] | |
build: | |
name: Build native gems | |
needs: ci-data | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
ruby-platform: ${{ fromJSON(needs.ci-data.outputs.result).supported-ruby-platforms }} | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ruby/setup-ruby@v1 | |
with: | |
ruby-version: "3.4" | |
- uses: oxidize-rb/actions/cross-gem@v1 | |
id: cross-gem | |
with: | |
platform: ${{ matrix.ruby-platform }} | |
ruby-versions: ${{ join(fromJSON(needs.ci-data.outputs.result).stable-ruby-versions, ',') }} | |
cache-save-always: false | |
cargo-cache-clean: false # Add this to disable cargo-cache usage | |
env: | |
# Add a unique identifier to prevent cache conflicts | |
ACTIONS_CACHE_KEY_SUFFIX: "-${{ matrix.ruby-platform }}-${{ github.run_id }}" | |
- uses: actions/upload-artifact@v4 | |
with: | |
name: cross-gem-${{ matrix.ruby-platform }} | |
path: pkg/*-${{ matrix.ruby-platform }}.gem | |
if-no-files-found: error | |
retention-days: 30 # Keep artifacts for 30 days | |
- name: Smoke test gem install | |
if: matrix.ruby-platform == 'x86_64-linux' # Enable for Linux x64 | |
run: | | |
# Install the platform-specific gem | |
gem install pkg/code_ownership-*-${{ matrix.ruby-platform }}.gem --verbose | |
# Test that it works | |
ruby -e "require 'code_ownership'; puts 'Version: ' + CodeOwnership::VERSION" | |
# Run a simple functionality test | |
ruby -e "require 'code_ownership'; CodeOwnership.file_owner_team_names('lib/code_ownership.rb')" || true | |
echo "✅ Successfully tested ${{ matrix.ruby-platform }} gem" | |
release: | |
name: Release | |
needs: build | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write # Required for creating releases | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: oxidize-rb/actions/setup-ruby-and-rust@v1 | |
with: | |
ruby-version: "3.4" | |
bundler-cache: true | |
cargo-cache: false | |
- uses: actions/download-artifact@v4 | |
with: | |
pattern: cross-gem-* | |
merge-multiple: true | |
path: pkg/ | |
- name: Package source gem | |
run: bundle exec rake pkg:ruby | |
- name: Push Gem | |
id: push-gem | |
working-directory: pkg/ | |
env: | |
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }} | |
run: | | |
set -e # Exit on error | |
# Setup credentials | |
mkdir -p $HOME/.gem | |
touch $HOME/.gem/credentials | |
chmod 0600 $HOME/.gem/credentials | |
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials | |
# List all gems to be pushed | |
echo "📦 Gems to be pushed:" | |
ls -la *.gem | |
# Extract version from the Ruby version file | |
GEM_VERSION=$(ruby -r ../lib/code_ownership/version.rb -e "puts CodeOwnership::VERSION") | |
echo "gem_version=${GEM_VERSION}" >> $GITHUB_OUTPUT | |
echo "🏷️ Detected gem version: ${GEM_VERSION}" | |
# Track results | |
NEW_VERSION=false | |
PUSHED_GEMS=() | |
SKIPPED_GEMS=() | |
for i in *.gem; do | |
if [ -f "$i" ]; then | |
echo "⏳ Attempting to push $i..." | |
if ! gem push "$i" >push.out 2>&1; then | |
gemerr=$? | |
if grep -q "Repushing of gem" push.out; then | |
echo "⏭️ Gem $i already exists on RubyGems, skipping..." | |
SKIPPED_GEMS+=("$i") | |
else | |
echo "❌ Failed to push $i:" | |
cat push.out | |
exit $gemerr | |
fi | |
else | |
echo "✅ Successfully pushed $i" | |
PUSHED_GEMS+=("$i") | |
NEW_VERSION=true | |
fi | |
fi | |
done | |
# Summary | |
echo "📊 Push Summary:" | |
echo " - Pushed: ${#PUSHED_GEMS[@]} gems" | |
echo " - Skipped: ${#SKIPPED_GEMS[@]} gems" | |
# Set outputs | |
echo "new_version=${NEW_VERSION}" >> $GITHUB_OUTPUT | |
echo "pushed_count=${#PUSHED_GEMS[@]}" >> $GITHUB_OUTPUT | |
echo "skipped_count=${#SKIPPED_GEMS[@]}" >> $GITHUB_OUTPUT | |
- name: Create GitHub Release | |
if: ${{ steps.push-gem.outputs.new_version == 'true' }} | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
# Create release with more detailed information | |
RELEASE_NOTES="## CodeOwnership v${{ steps.push-gem.outputs.gem_version }} | |
### 📦 Published Gems | |
- Source gem: code_ownership-${{ steps.push-gem.outputs.gem_version }}.gem | |
- Platform gems: Published for all supported platforms | |
### 🎯 Supported Platforms | |
$(ls pkg/*.gem | grep -E '\-(x86|arm|aarch)' | sed 's/.*-\([^-]*\)\.gem/- \1/') | |
--- | |
" | |
gh release create "v${{ steps.push-gem.outputs.gem_version }}" \ | |
--title "v${{ steps.push-gem.outputs.gem_version }}" \ | |
--notes "$RELEASE_NOTES" \ | |
--generate-notes \ | |
pkg/*.gem |