Skip to content

Commit 7952cca

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

File tree

6 files changed

+322
-42
lines changed

6 files changed

+322
-42
lines changed

.github/workflows/ci.yml

Lines changed: 124 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,137 @@ 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+
1624
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
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:
3363
runs-on: ubuntu-latest
34-
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
35-
64+
3665
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 }}
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+
85+
steps:
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+
- name: Create build summary
131+
run: |
132+
echo "## Gem Built Successfully 💎" >> $GITHUB_STEP_SUMMARY
133+
echo "- **Version**: ${{ steps.gem_info.outputs.gem_version }}" >> $GITHUB_STEP_SUMMARY
134+
echo "- **File**: ${{ steps.gem_info.outputs.gem_file }}" >> $GITHUB_STEP_SUMMARY
135+
echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
136+
echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
137+
echo "" >> $GITHUB_STEP_SUMMARY
138+
echo "🚀 **Ready to publish!** Use the 'Manual Release' workflow to publish this gem." >> $GITHUB_STEP_SUMMARY

.github/workflows/release.yml

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
name: Manual Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
target:
7+
description: "Release target"
8+
required: true
9+
default: "github"
10+
type: choice
11+
options:
12+
- github
13+
- rubygems
14+
- both
15+
run_id:
16+
description: "CI Run ID to use (optional - leave empty to build from current commit)"
17+
required: false
18+
type: string
19+
version_override:
20+
description: "Version override (optional - leave empty to use VERSION constant)"
21+
required: false
22+
type: string
23+
confirm:
24+
description: 'Type "confirm" to proceed with release'
25+
required: true
26+
type: string
27+
28+
permissions:
29+
actions: write
30+
contents: read
31+
id-token: write
32+
packages: write
33+
34+
jobs:
35+
validate:
36+
runs-on: ubuntu-latest
37+
steps:
38+
- name: Validate confirmation
39+
if: inputs.confirm != 'confirm'
40+
run: |
41+
echo "::error::You must type 'confirm' to proceed with release"
42+
exit 1
43+
44+
release:
45+
runs-on: ubuntu-latest
46+
needs: validate
47+
48+
steps:
49+
- uses: actions/checkout@v4
50+
51+
- name: Set up Ruby
52+
uses: ruby/setup-ruby@v1
53+
with:
54+
ruby-version: "3.3"
55+
bundler-cache: true
56+
57+
- name: Download gem artifact
58+
if: inputs.run_id != ''
59+
uses: actions/download-artifact@v4
60+
with:
61+
run-id: ${{ inputs.run_id }}
62+
pattern: gem-*
63+
merge-multiple: true
64+
65+
- name: Build gem from current commit
66+
if: inputs.run_id == ''
67+
run: |
68+
# Override version if specified
69+
if [ "${{ inputs.version_override }}" != "" ]; then
70+
sed -i "s/VERSION = '\([^']*\)'/VERSION = '${{ inputs.version_override }}'/" lib/gemplate/version.rb
71+
echo "Version overridden to: ${{ inputs.version_override }}"
72+
fi
73+
74+
# Run tests first
75+
bundle exec rspec
76+
77+
# Build gem
78+
gem build gemplate.gemspec
79+
80+
- name: Show gem info and get publish details
81+
id: gem_details
82+
run: |
83+
echo "Available gems:"
84+
ls -la *.gem
85+
echo ""
86+
87+
# Get the gem file (assuming single gem)
88+
GEM_FILE=$(ls *.gem | head -1)
89+
GEM_VERSION=$(echo $GEM_FILE | sed 's/gemplate-\(.*\)\.gem/\1/')
90+
91+
echo "gem_file=$GEM_FILE" >> $GITHUB_OUTPUT
92+
echo "gem_version=$GEM_VERSION" >> $GITHUB_OUTPUT
93+
94+
echo "## 💎 PUBLISHING CONFIRMATION"
95+
echo "**Gem Name:** gemplate"
96+
echo "**Version:** $GEM_VERSION"
97+
echo "**File:** $GEM_FILE"
98+
echo "**Target:** ${{ inputs.target }}"
99+
echo "**Size:** $(ls -lh $GEM_FILE | awk '{print $5}')"
100+
echo ""
101+
echo "Gem contents preview:"
102+
gem contents "$GEM_FILE" | head -10
103+
echo "... (and $(gem contents "$GEM_FILE" | wc -l) total files)"
104+
105+
- name: Confirm publication details
106+
run: |
107+
echo "## 🚀 READY TO PUBLISH" >> $GITHUB_STEP_SUMMARY
108+
echo "- **Gem**: gemplate" >> $GITHUB_STEP_SUMMARY
109+
echo "- **Version**: ${{ steps.gem_details.outputs.gem_version }}" >> $GITHUB_STEP_SUMMARY
110+
echo "- **File**: ${{ steps.gem_details.outputs.gem_file }}" >> $GITHUB_STEP_SUMMARY
111+
echo "- **Target**: ${{ inputs.target }}" >> $GITHUB_STEP_SUMMARY
112+
echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
113+
echo "" >> $GITHUB_STEP_SUMMARY
114+
echo "Publishing in 5 seconds..." >> $GITHUB_STEP_SUMMARY
115+
sleep 5
116+
117+
- name: Publish to GitHub Packages
118+
if: inputs.target == 'github' || inputs.target == 'both'
119+
run: |
120+
mkdir -p ~/.gem
121+
cat << EOF > ~/.gem/credentials
122+
---
123+
:github: Bearer ${{ secrets.GITHUB_TOKEN }}
124+
EOF
125+
chmod 600 ~/.gem/credentials
126+
# Temporarily remove allowed_push_host restriction for GitHub Packages
127+
sed -i "s/spec.metadata\['allowed_push_host'\].*$//" gemplate.gemspec
128+
gem build gemplate.gemspec
129+
gem push --key github --host https://rubygems.pkg.github.com/TwilightCoders *.gem
130+
131+
- name: Publish to RubyGems.org
132+
if: inputs.target == 'rubygems' || inputs.target == 'both'
133+
env:
134+
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
135+
run: |
136+
mkdir -p ~/.gem
137+
cat << EOF > ~/.gem/credentials
138+
---
139+
:rubygems_api_key: ${{ secrets.RUBYGEMS_API_KEY }}
140+
EOF
141+
chmod 600 ~/.gem/credentials
142+
gem push *.gem
143+
144+
- name: Create release summary
145+
run: |
146+
echo "## Release Summary" >> $GITHUB_STEP_SUMMARY
147+
echo "- **Target**: ${{ inputs.target }}" >> $GITHUB_STEP_SUMMARY
148+
echo "- **Version**: $(ls *.gem | sed 's/gemplate-\(.*\)\.gem/\1/')" >> $GITHUB_STEP_SUMMARY
149+
echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
150+
echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY

.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: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
Metrics/LineLength:
11+
Max: 120
12+
13+
Style/Documentation:
14+
Enabled: false
15+
16+
Metrics/MethodLength:
17+
Max: 15
18+
19+
Metrics/BlockLength:
20+
Exclude:
21+
- "spec/**/*"
22+
- "*.gemspec"
23+
24+
Style/StringLiterals:
25+
EnforcedStyle: single_quotes
26+
27+
Layout/TrailingEmptyLines:
28+
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

spec/spec_helper.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
require 'simplecov'
2+
SimpleCov.start do
3+
add_filter '/spec/'
4+
5+
# Add JSON formatter for qlty integration
6+
if ENV['CI']
7+
require 'simplecov_json_formatter'
8+
SimpleCov.formatters = [
9+
SimpleCov::Formatter::HTMLFormatter,
10+
SimpleCov::Formatter::JSONFormatter
11+
]
12+
end
13+
end
14+
115
require 'gemplate'
216
require 'pry'
317

0 commit comments

Comments
 (0)