1+ name : CI
2+
3+ on :
4+ push :
5+ branches : [main, develop, release/**]
6+ pull_request :
7+ branches : [main, develop]
8+
9+ permissions :
10+ actions : write
11+ contents : read
12+ id-token : write
13+ packages : write
14+
15+ jobs :
16+ test :
17+ runs-on : ${{ matrix.os }}
18+
19+ strategy :
20+ fail-fast : false
21+ matrix :
22+ os : [ubuntu-latest, macos-latest, windows-latest]
23+ ruby-version : ["2.7", "3.0", "3.1", "3.2", "3.3"]
24+
25+ steps :
26+ - uses : actions/checkout@v4
27+ with :
28+ submodules : recursive
29+
30+ - name : Set up Ruby ${{ matrix.ruby-version }}
31+ uses : ruby/setup-ruby@v1
32+ with :
33+ ruby-version : ${{ matrix.ruby-version }}
34+ bundler-cache : true
35+
36+ - name : Install system dependencies (Ubuntu)
37+ if : matrix.os == 'ubuntu-latest'
38+ run : |
39+ sudo apt-get update
40+ sudo apt-get install -y libssl-dev
41+
42+ - name : Install system dependencies (macOS)
43+ if : matrix.os == 'macos-latest'
44+ run : |
45+ brew install openssl
46+
47+ - name : Install system dependencies (Windows)
48+ if : matrix.os == 'windows-latest'
49+ run : |
50+ # OpenSSL comes pre-installed on GitHub Windows runners
51+ # But we may need to set some paths
52+ echo "OPENSSL_ROOT_DIR=C:\Program Files\OpenSSL-Win64" >> $GITHUB_ENV
53+ shell : bash
54+
55+ - name : Compile extension
56+ run : bundle exec rake compile
57+
58+ - name : Run tests with coverage
59+ run : bundle exec rspec
60+
61+ - name : Upload coverage artifact (Ruby 3.3, Ubuntu only)
62+ if : matrix.ruby-version == '3.3' && matrix.os == 'ubuntu-latest'
63+ uses : actions/upload-artifact@v4
64+ with :
65+ name : coverage-report
66+ path : coverage/
67+ retention-days : 1
68+
69+ - name : Run RuboCop (Ruby 3.3, Ubuntu only)
70+ if : matrix.ruby-version == '3.3' && matrix.os == 'ubuntu-latest'
71+ run : bundle exec rubocop || true
72+ continue-on-error : true
73+
74+ coverage :
75+ runs-on : ubuntu-latest
76+ needs : test
77+
78+ steps :
79+ - uses : actions/checkout@v4
80+
81+ - name : Download coverage artifact
82+ uses : actions/download-artifact@v4
83+ with :
84+ name : coverage-report
85+ path : coverage/
86+
87+ - name : Upload coverage to Qlty
88+ uses : qltysh/qlty-action/coverage@v1
89+ continue-on-error : true
90+ env :
91+ QLTY_COVERAGE_TOKEN : ${{ secrets.QLTY_COVERAGE_TOKEN }}
92+ with :
93+ oidc : true
94+ files : coverage/coverage.json
95+
96+ - name : Run Qlty code quality checks
97+ run : |
98+ curl -sSfL https://qlty.sh | sh
99+ echo "$HOME/.qlty/bin" >> $GITHUB_PATH
100+ ~/.qlty/bin/qlty check || true
101+ continue-on-error : true
102+
103+ security :
104+ runs-on : ubuntu-latest
105+
106+ steps :
107+ - uses : actions/checkout@v4
108+ with :
109+ submodules : recursive
110+
111+ - name : Set up Ruby
112+ uses : ruby/setup-ruby@v1
113+ with :
114+ ruby-version : " 3.3"
115+ bundler-cache : true
116+
117+ - name : Install system dependencies
118+ run : |
119+ sudo apt-get update
120+ sudo apt-get install -y libssl-dev
121+
122+ - name : Run bundle audit
123+ run : |
124+ gem install bundler-audit
125+ bundle audit --update || true
126+ continue-on-error : true
127+
128+ build :
129+ runs-on : ubuntu-latest
130+ needs : [test, coverage, security]
131+ if : false # Disabled to prevent accidental gem building
132+
133+ steps :
134+ - uses : actions/checkout@v4
135+ with :
136+ submodules : recursive
137+
138+ - name : Set up Ruby
139+ uses : ruby/setup-ruby@v1
140+ with :
141+ ruby-version : " 3.3"
142+ bundler-cache : true
143+
144+ - name : Install system dependencies
145+ run : |
146+ sudo apt-get update
147+ sudo apt-get install -y libssl-dev
148+
149+ - name : Modify version for develop branch
150+ if : github.ref == 'refs/heads/develop'
151+ run : |
152+ SHORT_SHA=$(git rev-parse --short HEAD)
153+ sed -i "s/VERSION = '\([^']*\)'/VERSION = '\1.dev.${SHORT_SHA}'/" lib/fastpbkdf2/version.rb
154+ echo "VERSION_SUFFIX=.dev.${SHORT_SHA}" >> $GITHUB_ENV
155+
156+ - name : Modify version for release branch
157+ if : startsWith(github.ref, 'refs/heads/release/')
158+ run : |
159+ SHORT_SHA=$(git rev-parse --short HEAD)
160+ sed -i "s/VERSION = '\([^']*\)'/VERSION = '\1.rc.${SHORT_SHA}'/" lib/fastpbkdf2/version.rb
161+ echo "VERSION_SUFFIX=.rc.${SHORT_SHA}" >> $GITHUB_ENV
162+
163+ - name : Set version suffix for main
164+ if : github.ref == 'refs/heads/main'
165+ run : echo "VERSION_SUFFIX=" >> $GITHUB_ENV
166+
167+ - name : Build gem
168+ run : gem build fastpbkdf2.gemspec
169+
170+ - name : Get gem info
171+ id : gem_info
172+ run : |
173+ GEM_FILE=$(ls *.gem)
174+ GEM_VERSION=$(echo $GEM_FILE | sed 's/fastpbkdf2-\(.*\)\.gem/\1/')
175+ echo "gem_file=$GEM_FILE" >> $GITHUB_OUTPUT
176+ echo "gem_version=$GEM_VERSION" >> $GITHUB_OUTPUT
177+
178+ - name : Store gem artifact
179+ uses : actions/upload-artifact@v4
180+ with :
181+ name : gem-${{ steps.gem_info.outputs.gem_version }}
182+ path : " *.gem"
183+ retention-days : 30
184+
185+ - name : Create build summary
186+ run : |
187+ echo "## Gem Built Successfully 💎" >> $GITHUB_STEP_SUMMARY
188+ echo "- **Version**: ${{ steps.gem_info.outputs.gem_version }}" >> $GITHUB_STEP_SUMMARY
189+ echo "- **File**: ${{ steps.gem_info.outputs.gem_file }}" >> $GITHUB_STEP_SUMMARY
190+ echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
191+ echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
192+ echo "" >> $GITHUB_STEP_SUMMARY
193+ echo "🚀 **Ready to publish!** Use the 'Manual Release' workflow to publish this gem." >> $GITHUB_STEP_SUMMARY
194+
195+ deploy :
196+ runs-on : ubuntu-latest
197+ needs : build
198+ if : false # Disabled to prevent accidental gem publishing
199+ environment :
200+ name : production
201+ url : https://github.com/TwilightCoders/fastpbkdf2-ruby/packages
202+ permissions :
203+ contents : read
204+ packages : write
205+
206+ steps :
207+ - uses : actions/checkout@v4
208+ with :
209+ submodules : recursive
210+
211+ - name : Set up Ruby
212+ uses : ruby/setup-ruby@v1
213+ with :
214+ ruby-version : " 3.3"
215+ bundler-cache : true
216+
217+ - name : Install system dependencies
218+ run : |
219+ sudo apt-get update
220+ sudo apt-get install -y libssl-dev
221+
222+ - name : Download gem artifact
223+ uses : actions/download-artifact@v4
224+ with :
225+ pattern : gem-*
226+ merge-multiple : true
227+
228+ - name : Show deployment details
229+ run : |
230+ echo "## 🚀 Ready to Deploy" >> $GITHUB_STEP_SUMMARY
231+ echo "**Gem**: $(ls *.gem)" >> $GITHUB_STEP_SUMMARY
232+ echo "**Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
233+ echo "**Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
234+ echo "**Size**: $(ls -lh *.gem | awk '{print $5}')" >> $GITHUB_STEP_SUMMARY
235+
236+ - name : Publish to GitHub Packages
237+ id : publish
238+ continue-on-error : true
239+ run : |
240+ mkdir -p ~/.gem
241+ cat << EOF > ~/.gem/credentials
242+ ---
243+ :github: Bearer ${{ secrets.GITHUB_TOKEN }}
244+ EOF
245+ chmod 600 ~/.gem/credentials
246+
247+ # Try to publish, capturing output
248+ if gem push --key github --host https://rubygems.pkg.github.com/TwilightCoders *.gem 2>&1 | tee publish_output.log; then
249+ echo "success=true" >> $GITHUB_OUTPUT
250+ echo "message=Successfully published $(ls *.gem)" >> $GITHUB_OUTPUT
251+ else
252+ # Check if it's a version conflict (common scenario)
253+ if grep -q "already exists" publish_output.log || grep -q "Repushing of gem versions is not allowed" publish_output.log; then
254+ echo "success=false" >> $GITHUB_OUTPUT
255+ echo "message=Version $(ls *.gem) already exists in GitHub Packages - no action needed" >> $GITHUB_OUTPUT
256+ else
257+ echo "success=false" >> $GITHUB_OUTPUT
258+ echo "message=Failed to publish: $(cat publish_output.log)" >> $GITHUB_OUTPUT
259+ fi
260+ fi
261+
262+ - name : Deployment summary
263+ run : |
264+ if [ "${{ steps.publish.outputs.success }}" == "true" ]; then
265+ echo "## ✅ Deployment Complete" >> $GITHUB_STEP_SUMMARY
266+ echo "${{ steps.publish.outputs.message }}" >> $GITHUB_STEP_SUMMARY
267+ else
268+ echo "## ⚠️ Deployment Skipped" >> $GITHUB_STEP_SUMMARY
269+ echo "${{ steps.publish.outputs.message }}" >> $GITHUB_STEP_SUMMARY
270+ echo "" >> $GITHUB_STEP_SUMMARY
271+ echo "This is typically expected when the version already exists." >> $GITHUB_STEP_SUMMARY
272+ fi
0 commit comments