Skip to content

Commit 0832b7f

Browse files
authored
Add release framework for EventSource. (#125)
1 parent 302d1b2 commit 0832b7f

32 files changed

+219
-82
lines changed

.github/release.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Release notes template (https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes)
2+
3+
changelog:
4+
categories:
5+
- title: Breaking Changes 🚧
6+
labels:
7+
# Semver-Major
8+
- breaking change
9+
- title: New Features ✨
10+
labels:
11+
# Semver-Minor
12+
- enhancement
13+
- title: Bug Fixes 🐛
14+
labels:
15+
# Semver-Patch
16+
- bugfix
17+
- title: Other Changes 📦
18+
labels:
19+
- "*"
20+
exclude:
21+
labels:
22+
- chore
23+
- version bump

.github/workflows/label-checker.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Label Checker
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- synchronize
8+
- reopened
9+
- labeled
10+
- unlabeled
11+
12+
jobs:
13+
check_labels:
14+
name: Check labels
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: docker://agilepathway/pull-request-label-checker:latest
18+
with:
19+
# At least one of the labels listed below must be present on the PR for the check to pass
20+
any_of: breaking change,enhancement,bugfix,version bump,release,chore,documentation,security
21+
repo_token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/publish-release.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Publish Release
2+
3+
on:
4+
push:
5+
tags:
6+
- v[0-9]+.[0-9]+.[0-9]+
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
publish:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Create release
17+
env:
18+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19+
run: |
20+
gh release create "${{ github.ref_name }}" \
21+
--repo="$GITHUB_REPOSITORY" \
22+
--title="${{ github.ref_name }}" \
23+
--generate-notes

.github/workflows/rspec.yml

+47-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ name: Rspec
22
on: push
33

44
jobs:
5+
rubocop:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- uses: actions/checkout@v2
9+
- uses: ruby/setup-ruby@v1
10+
- name: Cache Gems
11+
uses: actions/cache@v4
12+
with:
13+
path: vendor/bundle
14+
key: ${{ runner.os }}-3.2.1-event_source-gems-${{ hashFiles('**/Gemfile.lock') }}-${{ hashFiles('**/Gemfile' ) }}
15+
- name: bundle install
16+
run: |
17+
bundle config path vendor/bundle
18+
bundle install
19+
bundle exec rubocop-git trunk
20+
521
rspec:
622
strategy:
723
fail-fast: false
@@ -20,19 +36,44 @@ jobs:
2036
with:
2137
ruby-version: ${{ matrix.ruby_version }}
2238
- name: Cache Gems
23-
uses: actions/cache@v1
39+
uses: actions/cache@v4
40+
with:
41+
path: vendor/bundle
42+
key: ${{ runner.os }}-${{matrix.ruby_version}}-event_source-gems-${{ hashFiles('**/Gemfile.lock') }}-${{ hashFiles('**/Gemfile' ) }}
43+
- name: bundle install
44+
run: |
45+
bundle config path vendor/bundle
46+
bundle install
47+
- name: Run rspec
48+
run: |
49+
bundle exec rspec
50+
rspec-hosted:
51+
strategy:
52+
fail-fast: false
53+
matrix:
54+
ruby_version: ['2.7.5', '3.0.5', '3.1.4', '3.2.2']
55+
runs-on: ubuntu-latest
56+
steps:
57+
- uses: actions/checkout@v2
58+
- name: Boot RabbitMQ
59+
run: |
60+
sudo apt-get update
61+
sudo apt-get install rabbitmq-server
62+
sudo rabbitmqctl add_vhost event_source
63+
sudo rabbitmqctl set_permissions -p event_source guest ".*" ".*" ".*"
64+
- uses: ruby/setup-ruby@v1
65+
with:
66+
ruby-version: ${{ matrix.ruby_version }}
67+
- name: Cache Gems
68+
uses: actions/cache@v4
2469
with:
2570
path: vendor/bundle
2671
key: ${{ runner.os }}-${{matrix.ruby_version}}-event_source-gems-${{ hashFiles('**/Gemfile.lock') }}-${{ hashFiles('**/Gemfile' ) }}
27-
restore-keys: |
28-
${{ runner.os }}-${{matrix.ruby_version}}-event_source-gems-${{ hashFiles('**/Gemfile.lock') }}-${{ hashFiles('**/Gemfile' ) }}
2972
- name: bundle install
3073
run: |
3174
bundle config path vendor/bundle
3275
bundle install
33-
# - name: Run rubocop
34-
# run: |
35-
# bundle exec rubocop
3676
- name: Run rspec
3777
run: |
78+
cd spec/rails_app
3879
bundle exec rspec

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ node_modules
1818
*.log
1919
*.log.age
2020
*.swp
21+
spec/rails_app/log/*.log

.rubocop.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This yaml describes our current checks.
22
AllCops:
3-
TargetRubyVersion: 2.5
3+
TargetRubyVersion: 2.7
44
SuggestExtensions: false
55
NewCops: enable
66
Exclude:
@@ -25,6 +25,9 @@ Layout/EmptyLinesAroundModuleBody:
2525
Layout/SpaceInsideBlockBraces:
2626
Enabled: false
2727

28+
Layout/SpaceInsideHashLiteralBraces:
29+
Enabled: false
30+
2831
Layout/TrailingEmptyLines:
2932
Enabled: false
3033

Gemfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ gemspec
88
group :development, :test do
99
gem "rails", '>= 6.1.4'
1010
gem "rspec-rails"
11-
gem "parallel_tests"
1211
gem "pry", platform: :mri, require: false
1312
gem "pry-byebug", platform: :mri, require: false
1413
gem 'rubocop'
1514
gem 'yard'
15+
gem 'rubocop-git'
1616
end

Gemfile.lock

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
event_source (0.5.8)
4+
event_source (0.6.0)
55
addressable (>= 2.8.0)
66
bunny (>= 2.14)
77
deep_merge (~> 1.2.0)
@@ -18,7 +18,7 @@ PATH
1818
faraday_middleware (~> 1.0)
1919
logging (~> 2.3.0)
2020
mime-types
21-
nokogiri (>= 1.13.0)
21+
nokogiri (= 1.15.7)
2222
oj (~> 3.11)
2323
ox (~> 2.14)
2424
typhoeus (~> 1.4.0)
@@ -194,7 +194,7 @@ GEM
194194
mime-types-data (~> 3.2015)
195195
mime-types-data (3.2021.0901)
196196
mini_mime (1.1.2)
197-
mini_portile2 (2.8.1)
197+
mini_portile2 (2.8.8)
198198
minitest (5.14.4)
199199
mongo (2.14.0)
200200
bson (>= 4.8.2, < 5.0.0)
@@ -206,6 +206,9 @@ GEM
206206
mustermann (1.1.1)
207207
ruby2_keywords (~> 0.0.1)
208208
nio4r (2.5.8)
209+
nokogiri (1.15.7)
210+
mini_portile2 (~> 2.8.2)
211+
racc (~> 1.4)
209212
oj (3.13.9)
210213
ox (2.14.5)
211214
parallel (1.20.1)
@@ -218,7 +221,7 @@ GEM
218221
byebug (~> 11.0)
219222
pry (~> 0.10)
220223
public_suffix (4.0.6)
221-
racc (1.6.2)
224+
racc (1.8.1)
222225
rack (2.2.3)
223226
rack-protection (2.1.0)
224227
rack
@@ -283,9 +286,11 @@ GEM
283286
unicode-display_width (>= 1.4.0, < 3.0)
284287
rubocop-ast (1.7.0)
285288
parser (>= 3.0.1.1)
289+
rubocop-git (0.1.3)
290+
rubocop (>= 0.24.1)
286291
ruby-progressbar (1.11.0)
287292
ruby2_keywords (0.0.4)
288-
set (1.0.2)
293+
set (1.0.3)
289294
sinatra (2.1.0)
290295
mustermann (~> 1.0)
291296
rack (~> 2.2)
@@ -331,6 +336,7 @@ DEPENDENCIES
331336
rails (>= 6.1.4)
332337
rspec-rails
333338
rubocop
339+
rubocop-git
334340
sinatra
335341
webmock
336342
yard

RELEASING.md

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Release
2+
3+
This file describes the process for publishing a new version of the gem as a GitHub release.
4+
5+
Releases are managed through the [GitHub Releases](https://github.com/ideacrew/event_source/releases) page.
6+
7+
Release names follow the [Semantic Versioning](https://semver.org/) standard.
8+
9+
Follow the steps below to package and release a new version of the gem.
10+
11+
## Major/Minor release
12+
### Prepare the release
13+
1. Checkout the main branch and pull the latest changes.
14+
2. Create and checkout a branch - avoid naming the branch solely after proposed release number - something like 'rm12313453_v1.0.0._update_gemspec' might be ideal.
15+
3. Update the version number in the `lib/<project>/version.rb` file. Note the [correct format](https://guides.rubygems.org/specification-reference/#version); only digits and dots are allowed. Do not include a `v` prefix.
16+
4. Update the `Gemfile.lock` file:
17+
- `bundle update --patch --conservative event_source` will generally reduce dependency bumps. Typically, other effects in the lockfile beyond the gem itself being bumped should be discarded.
18+
- See bundler documentation for detailed information on how this [command](https://bundler.io/v2.5/man/bundle-update.1.html) behaves.
19+
5. Commit the changes with a message like `bump version to v1.0.0`.
20+
6. Push the branch and raise a pull request against the main branch. The pull request title should follow the format: `bump version to v1.0.0`. Be sure to label the pull request with the `version-bump` label.
21+
22+
### Publishing the Release
23+
1. Once the pull request is approved and merged, checkout the main branch and pull the latest changes.
24+
2. Create a new release branch in the pattern of `1.0.x-release`.
25+
- Note: `x` is literal, to aid reuse of same branch for minor bugfixes.
26+
3. Create a new annotated tag with the version number, e.g., `git tag -as v1.0.0 -m "v1.0.0"`.
27+
- IMPORTANT: make sure the tag abides by the format `vX.Y.Z` where `X`, `Y`, and `Z` are integers. It is important that the tag name has a different format than any branch name to avoid confusion with Bundler.
28+
4. Push the tag to the remote repository, e.g., `git push origin refs/tags/v1.0.0`.
29+
- Avoid `git push --tags`, to not accidentally push random assorted local tags.
30+
5. GitHub Actions will automatically create a new release on the [GitHub Releases](https://github.com/ideacrew/event_source/releases) page with release notes. Confirm that the release was successfully published there and that all intended commits are included in the release.
31+
32+
## Patch/Bugfix release
33+
### Prepare the release
34+
35+
1. Fix bug in the main branch, via normal PR process.
36+
2. Create a temp branch off any live release branch that has the bug - pick a name that won't conflict with another branch or tag, as with Major/Minor step 2.
37+
- Using a branch, which is then PR’d, ensures traceability and inclusion of an item in the generated release notes.
38+
3. Cherry-pick the fix commits to the temp branch.
39+
4. Update the gem `version.rb` file and `Gemfile.lock` as in Major/Minor release steps 3 and 4.
40+
5. `git push` the temp branch.
41+
6. Issue a PR to merge to the release branch.
42+
7. You will need to do this for each branch that has the bug.
43+
44+
### Publishing the Release
45+
1. Once the pull request is approved and merged, checkout the release branch and pull the latest changes.
46+
2. Create a new annotated tag with the version number, at the point of the release branch with the fix, e.g., `git tag -as v1.0.1 -m "v1.0.1"`.
47+
3. Push the tag to the remote repository, e.g., `git push origin refs/tags/v1.0.1`.
48+
- Again, better to avoid `git push --tags`.
49+
4. Github Actions will create the release and pull in the fix PR's to the changelog.
50+
51+
## Using a Tagged Release in Another Project
52+
To use the new release in another project, update the project's `Gemfile` to reference the release's tag, e.g., `gem 'event_source', git: 'https://github.com/ideacrew/event_source.git', tag: 'v1.0.0'`.
53+
54+
## Git Process diagram
55+
![Git Process Diagram - Gem](docs_assets/release_branching_gem.png)

docs_assets/NOTE.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This folder is intended for assets used in project internal documentation (RELEASING.md, README.md, etc.).

docs_assets/release_branching_gem.png

86.6 KB
Loading

event_source.gemspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
2020
Philippe Creux"
2121
spec.homepage = 'https://github.com/ideacrew/event_source'
2222
spec.license = 'MIT'
23-
spec.required_ruby_version = Gem::Requirement.new('>= 2.5')
23+
spec.required_ruby_version = Gem::Requirement.new('>= 2.7')
2424

2525
# Specify which files should be added to the gem when it is released.
2626
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.

lib/event_source/async_api/contracts.rb

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@
1414
require_relative "contracts/info_contract"
1515
require_relative "contracts/message_contract"
1616
require_relative "contracts/security_scheme_contract"
17-
require_relative "contracts/server_contract"
1817

1918
module EventSource
2019
module AsyncApi
2120
module Contracts
2221
end
2322
end
24-
end
23+
end

lib/event_source/boot_registry.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def register_subscriber(subscriber_klass)
7575
def boot_publishers!
7676
@bootex.synchronize do
7777
@unbooted_publishers.each do |pk|
78-
pk.validate
78+
pk.validate
7979
@booted_publishers << pk
8080
end
8181
@unbooted_publishers = Set.new

lib/event_source/configure/config.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def create_connections
4848
def validate_connections
4949
validation_result =
5050
::EventSource::Configure::Operations::ValidateServerConfigurations.new
51-
.call(@server_configurations)
51+
.call(@server_configurations)
5252
return if validation_result.success?
5353
validation_result.failure.each do |result|
5454
formatted_trace =

lib/event_source/operations/mime_decode.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def valid_json_string?(data)
9292
true
9393
rescue JSON::ParserError
9494
false
95-
end
95+
end
9696
end
9797
end
9898
end

lib/event_source/protocols/amqp/bunny_exchange_proxy.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class BunnyExchangeProxy
1515
# @attr_reader [EventSource::Protcols::Amqp::BunnyChannelProxy] channel_proxy the channel_proxy used to create this exchange
1616
attr_reader :subject, :channel_proxy
1717

18-
DefaultMimeType = 'application/json'.freeze
18+
DefaultMimeType = 'application/json'
1919

2020
# @param [EventSource::AsyncApi::Channel] channel_proxy instance on which to open this Exchange
2121
# @param [Hash<EventSource::AsyncApi::Exchange>] exchange_bindings instance with configuration for this Exchange

lib/event_source/protocols/amqp/bunny_queue_proxy.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def on_receive_message(
171171
def decode_payload(payload)
172172
async_api_subscribe_operation = @async_api_channel_item.subscribe
173173
return payload unless async_api_subscribe_operation.message
174-
174+
175175
message_bindings = async_api_subscribe_operation.message['bindings']
176176
encoding = message_bindings.first[1]['contentEncoding'] if message_bindings
177177
return payload unless encoding
@@ -234,7 +234,7 @@ def convert_to_consumer_options(options)
234234
def channel_item_queue_bindings_for(bindings)
235235
result =
236236
EventSource::Protocols::Amqp::Contracts::ChannelBindingContract.new
237-
.call(bindings)
237+
.call(bindings)
238238
if result.success?
239239
result.values[:amqp][:queue]
240240
else

lib/event_source/protocols/http/faraday_request_proxy.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def publish(payload: nil, publish_bindings: {}, headers: {})
101101
def attach_payload_correlation_id(response, text_payload, payload)
102102
payload_correlation_id =
103103
JSON.parse(text_payload)['CorrelationID'] if @request_content_type
104-
.json? && payload
104+
.json? && payload
105105
response.headers.merge!(
106106
'CorrelationID' =>
107107
(payload_correlation_id || generate_correlation_id)
@@ -144,7 +144,7 @@ def sanitize_bindings(bindings)
144144
options = bindings[:http] || {}
145145
operation_bindings = {}
146146
operation_bindings[:headers] = options[:headers] if options
147-
.respond_to?(:headers)
147+
.respond_to?(:headers)
148148
operation_bindings
149149
end
150150
end

0 commit comments

Comments
 (0)