Skip to content

Commit f659f6d

Browse files
committed
Add test coverage and make build release manual
1 parent 6e9b56a commit f659f6d

File tree

12 files changed

+1114
-103
lines changed

12 files changed

+1114
-103
lines changed

.github/workflows/ci.yml

Lines changed: 208 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,221 @@ name: CI
22

33
on:
44
push:
5-
branches: [ main ]
5+
branches: [main, develop, release/**]
66
pull_request:
7-
branches: [ main ]
7+
branches: [main, develop]
8+
9+
permissions:
10+
actions: write
11+
contents: read
12+
id-token: write
13+
packages: write
814

915
jobs:
1016
test:
1117
runs-on: ubuntu-latest
18+
1219
strategy:
20+
fail-fast: false
1321
matrix:
14-
ruby-version: ['2.7', '3.0', '3.1', '3.2', '3.3']
15-
22+
ruby-version: ["2.7", "3.0", "3.1", "3.2", "3.3"]
23+
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- name: Set up Ruby ${{ matrix.ruby-version }}
28+
uses: ruby/setup-ruby@v1
29+
with:
30+
ruby-version: ${{ matrix.ruby-version }}
31+
bundler-cache: true
32+
33+
- name: Run tests with coverage
34+
run: bundle exec rspec
35+
36+
- name: Test CLI
37+
run: bundle exec bin/gemplate --help
38+
39+
- name: Upload coverage to Qlty
40+
if: matrix.ruby-version == '3.3'
41+
uses: qltysh/qlty-action/coverage@v1
42+
continue-on-error: true
43+
env:
44+
QLTY_COVERAGE_TOKEN: ${{ secrets.QLTY_COVERAGE_TOKEN }}
45+
with:
46+
oidc: true
47+
files: coverage/coverage.json
48+
49+
- name: Run Qlty code quality checks
50+
if: matrix.ruby-version == '3.3'
51+
run: |
52+
curl -sSfL https://qlty.sh | sh
53+
echo "$HOME/.qlty/bin" >> $GITHUB_PATH
54+
~/.qlty/bin/qlty check || true
55+
continue-on-error: true
56+
57+
- name: Run RuboCop (Ruby 3.3 only)
58+
if: matrix.ruby-version == '3.3'
59+
run: bundle exec rubocop || true
60+
continue-on-error: true
61+
62+
security:
63+
runs-on: ubuntu-latest
64+
65+
steps:
66+
- uses: actions/checkout@v4
67+
68+
- name: Set up Ruby
69+
uses: ruby/setup-ruby@v1
70+
with:
71+
ruby-version: "3.3"
72+
bundler-cache: true
73+
74+
- name: Run bundle audit
75+
run: |
76+
gem install bundler-audit
77+
bundle audit --update || true
78+
continue-on-error: true
79+
80+
build:
81+
runs-on: ubuntu-latest
82+
needs: [test, security]
83+
if: github.event_name == 'push'
84+
1685
steps:
17-
- uses: actions/checkout@v4
18-
19-
- name: Set up Ruby ${{ matrix.ruby-version }}
20-
uses: ruby/setup-ruby@v1
21-
with:
22-
ruby-version: ${{ matrix.ruby-version }}
23-
bundler-cache: true
24-
25-
- name: Run tests
26-
run: bundle exec rake spec
27-
28-
- name: Test CLI
29-
run: bundle exec bin/gemplate --help
30-
31-
publish:
32-
needs: test
86+
- uses: actions/checkout@v4
87+
88+
- name: Set up Ruby
89+
uses: ruby/setup-ruby@v1
90+
with:
91+
ruby-version: "3.3"
92+
bundler-cache: true
93+
94+
- name: Modify version for develop branch
95+
if: github.ref == 'refs/heads/develop'
96+
run: |
97+
SHORT_SHA=$(git rev-parse --short HEAD)
98+
sed -i "s/VERSION = '\([^']*\)'/VERSION = '\1.dev.${SHORT_SHA}'/" lib/gemplate/version.rb
99+
echo "VERSION_SUFFIX=.dev.${SHORT_SHA}" >> $GITHUB_ENV
100+
101+
- name: Modify version for release branch
102+
if: startsWith(github.ref, 'refs/heads/release/')
103+
run: |
104+
SHORT_SHA=$(git rev-parse --short HEAD)
105+
sed -i "s/VERSION = '\([^']*\)'/VERSION = '\1.rc.${SHORT_SHA}'/" lib/gemplate/version.rb
106+
echo "VERSION_SUFFIX=.rc.${SHORT_SHA}" >> $GITHUB_ENV
107+
108+
- name: Set version suffix for main
109+
if: github.ref == 'refs/heads/main'
110+
run: echo "VERSION_SUFFIX=" >> $GITHUB_ENV
111+
112+
- name: Build gem
113+
run: gem build gemplate.gemspec
114+
115+
- name: Get gem info
116+
id: gem_info
117+
run: |
118+
GEM_FILE=$(ls *.gem)
119+
GEM_VERSION=$(echo $GEM_FILE | sed 's/gemplate-\(.*\)\.gem/\1/')
120+
echo "gem_file=$GEM_FILE" >> $GITHUB_OUTPUT
121+
echo "gem_version=$GEM_VERSION" >> $GITHUB_OUTPUT
122+
123+
- name: Store gem artifact
124+
uses: actions/upload-artifact@v4
125+
with:
126+
name: gem-${{ steps.gem_info.outputs.gem_version }}
127+
path: "*.gem"
128+
retention-days: 30
129+
130+
deploy:
33131
runs-on: ubuntu-latest
34-
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
35-
132+
needs: build
133+
if: github.ref == 'refs/heads/main'
134+
environment:
135+
name: production
136+
url: https://github.com/TwilightCoders/gemplate/packages
137+
permissions:
138+
contents: read
139+
packages: write
140+
36141
steps:
37-
- uses: actions/checkout@v4
38-
39-
- name: Set up Ruby
40-
uses: ruby/setup-ruby@v1
41-
with:
42-
ruby-version: '3.3'
43-
bundler-cache: true
44-
45-
- name: Build gem
46-
run: gem build gemplate.gemspec
47-
48-
- name: Publish to GitHub Packages
49-
run: |
50-
mkdir -p $HOME/.gem
51-
touch $HOME/.gem/credentials
52-
chmod 0600 $HOME/.gem/credentials
53-
printf -- "---\n:github: Bearer ${GITHUB_TOKEN}\n" > $HOME/.gem/credentials
54-
gem push --KEY github --host https://rubygems.pkg.github.com/TwilightCoders *.gem
55-
env:
56-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
142+
- uses: actions/checkout@v4
143+
144+
- name: Set up Ruby
145+
uses: ruby/setup-ruby@v1
146+
with:
147+
ruby-version: "3.3"
148+
bundler-cache: true
149+
150+
- name: Download gem artifact
151+
uses: actions/download-artifact@v4
152+
with:
153+
pattern: gem-*
154+
merge-multiple: true
155+
156+
- name: Show deployment details
157+
run: |
158+
echo "## 🚀 Ready to Deploy" >> $GITHUB_STEP_SUMMARY
159+
echo "**Gem**: $(ls *.gem)" >> $GITHUB_STEP_SUMMARY
160+
echo "**Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
161+
echo "**Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
162+
echo "**Size**: $(ls -lh *.gem | awk '{print $5}')" >> $GITHUB_STEP_SUMMARY
163+
echo "" >> $GITHUB_STEP_SUMMARY
164+
echo "### Manual Approval Required" >> $GITHUB_STEP_SUMMARY
165+
echo "This deployment uses the \`production\` environment and can require manual approval." >> $GITHUB_STEP_SUMMARY
166+
echo "" >> $GITHUB_STEP_SUMMARY
167+
echo "**To enable manual approval:**" >> $GITHUB_STEP_SUMMARY
168+
echo "1. Go to **Settings** → **Environments** → **production**" >> $GITHUB_STEP_SUMMARY
169+
echo "2. Enable **Required reviewers** and add yourself" >> $GITHUB_STEP_SUMMARY
170+
echo "3. Optionally enable **Wait timer** for additional safety" >> $GITHUB_STEP_SUMMARY
171+
echo "" >> $GITHUB_STEP_SUMMARY
172+
echo "📖 **See:** [GitHub Docs - Reviewing Deployments](https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-deployments/reviewing-deployments)" >> $GITHUB_STEP_SUMMARY
173+
echo "" >> $GITHUB_STEP_SUMMARY
174+
echo "Once configured, you'll get a **Review deployments** button to approve/reject releases." >> $GITHUB_STEP_SUMMARY
175+
176+
- name: Publish to GitHub Packages
177+
id: publish
178+
continue-on-error: true
179+
run: |
180+
mkdir -p ~/.gem
181+
cat << EOF > ~/.gem/credentials
182+
---
183+
:github: Bearer ${{ secrets.GITHUB_TOKEN }}
184+
EOF
185+
chmod 600 ~/.gem/credentials
186+
187+
# Try to publish, capturing output
188+
if gem push --key github --host https://rubygems.pkg.github.com/TwilightCoders *.gem 2>&1 | tee publish_output.log; then
189+
echo "success=true" >> $GITHUB_OUTPUT
190+
echo "message=Successfully published $(ls *.gem)" >> $GITHUB_OUTPUT
191+
else
192+
# Check if it's a version conflict (common scenario)
193+
if grep -q "already exists" publish_output.log || grep -q "Repushing of gem versions is not allowed" publish_output.log; then
194+
echo "success=false" >> $GITHUB_OUTPUT
195+
echo "message=Version $(ls *.gem) already exists in GitHub Packages - no action needed" >> $GITHUB_OUTPUT
196+
else
197+
echo "success=false" >> $GITHUB_OUTPUT
198+
echo "message=Failed to publish: $(cat publish_output.log)" >> $GITHUB_OUTPUT
199+
fi
200+
fi
201+
202+
- name: Deployment summary
203+
run: |
204+
if [ "${{ steps.publish.outputs.success }}" == "true" ]; then
205+
echo "## ✅ Deployment Complete" >> $GITHUB_STEP_SUMMARY
206+
echo "${{ steps.publish.outputs.message }}" >> $GITHUB_STEP_SUMMARY
207+
else
208+
echo "## ⚠️ Deployment Skipped" >> $GITHUB_STEP_SUMMARY
209+
echo "${{ steps.publish.outputs.message }}" >> $GITHUB_STEP_SUMMARY
210+
echo "" >> $GITHUB_STEP_SUMMARY
211+
echo "This is typically expected when the version already exists." >> $GITHUB_STEP_SUMMARY
212+
fi
213+
214+
- name: Create build summary
215+
run: |
216+
echo "## Gem Built Successfully 💎" >> $GITHUB_STEP_SUMMARY
217+
echo "- **Version**: ${{ steps.gem_info.outputs.gem_version }}" >> $GITHUB_STEP_SUMMARY
218+
echo "- **File**: ${{ steps.gem_info.outputs.gem_file }}" >> $GITHUB_STEP_SUMMARY
219+
echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
220+
echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
221+
echo "" >> $GITHUB_STEP_SUMMARY
222+
echo "🚀 **Ready to publish!** Use the 'Manual Release' workflow to publish this gem." >> $GITHUB_STEP_SUMMARY

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,4 @@ Thumbs.db
8181
#####################
8282
.claude/
8383
CLAUDE.md
84+
.vscode/

.qlty/qlty.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,6 @@ name = "trufflehog"
8989

9090
[[plugin]]
9191
name = "yamllint"
92+
93+
[coverage]
94+
lcov_path = "coverage/lcov/gemplate.lcov"

.rubocop.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
AllCops:
2+
TargetRubyVersion: 2.7
3+
NewCops: enable
4+
Exclude:
5+
- "vendor/**/*"
6+
- "tmp/**/*"
7+
- "coverage/**/*"
8+
9+
# Disable some common rules for gem development
10+
Layout/LineLength:
11+
Max: 120
12+
13+
Style/Documentation:
14+
Enabled: false
15+
16+
Metrics/MethodLength:
17+
Max: 20
18+
Exclude:
19+
- lib/gemplate/generator.rb # Generator methods legitimately need to be longer
20+
- spec/**/* # Test methods can be longer for readability
21+
22+
Metrics/ClassLength:
23+
Max: 250
24+
Exclude:
25+
- lib/gemplate/generator.rb # Generator class is complex by nature
26+
27+
Metrics/AbcSize:
28+
Max: 25
29+
Exclude:
30+
- lib/gemplate/generator.rb
31+
32+
Metrics/CyclomaticComplexity:
33+
Max: 12
34+
Exclude:
35+
- lib/gemplate/generator.rb
36+
37+
Metrics/PerceivedComplexity:
38+
Max: 12
39+
Exclude:
40+
- lib/gemplate/generator.rb
41+
42+
Metrics/BlockLength:
43+
Exclude:
44+
- spec/**/*
45+
- '*.gemspec'
46+
47+
Style/StringLiterals:
48+
EnforcedStyle: single_quotes
49+
50+
Layout/TrailingEmptyLines:
51+
EnforcedStyle: final_newline

gemplate.gemspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,8 @@ Gem::Specification.new do |spec|
2626
spec.add_development_dependency 'rake', '~> 12.0'
2727
spec.add_development_dependency 'rspec', '~> 3.0'
2828
spec.add_development_dependency 'pry-byebug', '~> 3'
29+
spec.add_development_dependency 'simplecov', '~> 0.22'
30+
spec.add_development_dependency 'simplecov_json_formatter', '~> 0.1'
31+
spec.add_development_dependency 'rubocop', '~> 1.50'
2932

3033
end

0 commit comments

Comments
 (0)