Skip to content

Commit

Permalink
Technical/Update CI/CD flow (#58)
Browse files Browse the repository at this point in the history
* Added new bunch of project linters
* Added auto deploy to RubyGems
* Added auto creating release notes on GitHub
* Added lefthook config, removed overcommit
* Updated gemspecs
* Updated codeclimate/circleci configs
* Updated gem development dependencies
* Updated gem version, changelog
  • Loading branch information
bestwebua committed Dec 1, 2022
1 parent a9b27f6 commit bdf6806
Show file tree
Hide file tree
Showing 22 changed files with 281 additions and 119 deletions.
87 changes: 74 additions & 13 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
---

version: 2.1

defaults: &defaults
Expand All @@ -13,26 +15,42 @@ references:
restore_cache:
keys:
- ruby-smtp-mock-{{ checksum "smtp_mock.gemspec" }}
paths:
- ~/vendor/bundle

bundle_install: &bundle_install
run:
name: Installing gems
command: |
bundle config set --local path 'vendor/bundle'
bundle config set --local path '~/vendor/bundle'
bundle install
save_bundle_cache: &save_bundle_cache
save_cache:
key: ruby-smtp-mock-{{ checksum "smtp_mock.gemspec" }}
paths:
- vendor/bundle
- ~/vendor/bundle

system_dependencies: &system_dependencies
run:
name: Installing system requirements
command: |
bundle exec smtp_mock -s -i ~
install_yamllint: &install_yamllint
run:
name: Installing Yamllint
command: |
sudo apt-get update -y
sudo apt-get install -y yamllint
install_lefthook: &install_lefthook
run:
name: Installing Lefthook
command: |
curl -1sLf 'https://dl.cloudsmith.io/public/evilmartians/lefthook/setup.deb.sh' | sudo -E bash
sudo apt-get install -y lefthook
install_codeclimate_reporter: &install_codeclimate_reporter
run:
name: Installing CodeClimate test reporter
Expand All @@ -43,14 +61,12 @@ references:
use_latest_gemspec: &use_latest_gemspec
run:
name: Using latest gemspec
command: |
cp .circleci/gemspec_latest smtp_mock.gemspec
command: cp .circleci/gemspecs/latest smtp_mock.gemspec

use_compatible_gemspec: &use_compatible_gemspec
run:
name: Using compatible gemspec
command: |
cp .circleci/gemspec_compatible smtp_mock.gemspec
command: cp .circleci/gemspecs/compatible smtp_mock.gemspec

jobs:
linters-ruby:
Expand All @@ -67,12 +83,23 @@ jobs:
- <<: *restore_bundle_cache
- <<: *bundle_install
- <<: *save_bundle_cache
- <<: *install_yamllint
- <<: *install_lefthook

- run:
name: Running code style linters
command: lefthook run code-style-linters

- run:
name: Running Overcommit
name: Running code performance linters
command: |
bundle exec overcommit -s
SKIP=AuthorEmail,AuthorName bundle exec overcommit -r
cp .circleci/linter_configs/.fasterer.yml .fasterer.yml
lefthook run code-performance-linters
rm .fasterer.yml
- run:
name: Running code vulnerability linters
command: lefthook run code-vulnerability-linters

tests-ruby:
parameters:
Expand Down Expand Up @@ -116,22 +143,45 @@ jobs:
parameters:
ruby-version:
type: string
docker:
- image: cimg/ruby:<< parameters.ruby-version >>

<<: *defaults

steps:
- checkout

- <<: *use_compatible_gemspec

- ruby/install-deps:
bundler-version: "2.3.26"
with-cache: false
path: './vendor/custom_bundle'
path: '~/vendor/custom_bundle'

- <<: *system_dependencies

- run:
name: Running compatibility tests
command: bundle exec rspec

releasing-gem-from-ruby:
parameters:
ruby-version:
type: string

<<: *defaults

steps:
- checkout

- add_ssh_keys:
fingerprints:
- "55:d3:88:af:10:c9:b1:9d:53:f4:d8:fc:79:4c:69:f7"

- run:
name: Publishing new release
command: ./.circleci/scripts/release.sh

workflows:
build_and_test:
build_test_deploy:
jobs:
- linters-ruby:
matrix:
Expand All @@ -145,3 +195,14 @@ workflows:
matrix:
parameters:
ruby-version: ["2.5", "2.6", "2.7", "3.0"]
- releasing-gem-from-ruby:
requires:
- linters-ruby
- tests-ruby
- compatibility-ruby
matrix:
parameters:
ruby-version: ["2.5"]
filters:
branches:
only: master
37 changes: 0 additions & 37 deletions .circleci/gemspec_compatible

This file was deleted.

27 changes: 27 additions & 0 deletions .circleci/gemspecs/compatible
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

require_relative 'lib/smtp_mock/version'

Gem::Specification.new do |spec|
spec.name = 'smtp_mock'
spec.version = SmtpMock::VERSION
spec.authors = ['Vladislav Trotsenko']
spec.email = %w[[email protected]]
spec.summary = %(smtp_mock)
spec.description = %(💎 Ruby SMTP mock. Mimic any SMTP server behaviour for your test environment.)
spec.homepage = 'https://github.com/mocktools/ruby-smtp-mock'
spec.license = 'MIT'

dry_struct_version = ::Gem::Version.new(::RUBY_VERSION) >= ::Gem::Version.new('2.7.0') ? '~> 1.6' : '~> 1.4'

spec.required_ruby_version = '>= 2.5.0'
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.executables = %w[smtp_mock]
spec.require_paths = %w[lib]

spec.add_runtime_dependency 'dry-struct', dry_struct_version

spec.add_development_dependency 'ffaker'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'rspec'
end
20 changes: 4 additions & 16 deletions .circleci/gemspec_latest → .circleci/gemspecs/latest
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,24 @@ Gem::Specification.new do |spec|
spec.name = 'smtp_mock'
spec.version = SmtpMock::VERSION
spec.authors = ['Vladislav Trotsenko']
spec.email = ['[email protected]']

spec.email = %w[[email protected]]
spec.summary = %(smtp_mock)
spec.description = %(💎 Ruby SMTP mock. Mimic any SMTP server behaviour for your test environment.)

spec.homepage = 'https://github.com/mocktools/ruby-smtp-mock'
spec.license = 'MIT'

spec.metadata = {
'homepage_uri' => 'https://github.com/mocktools/ruby-smtp-mock',
'changelog_uri' => 'https://github.com/mocktools/ruby-smtp-mock/blob/master/CHANGELOG.md',
'source_code_uri' => 'https://github.com/mocktools/ruby-smtp-mock',
'documentation_uri' => 'https://github.com/mocktools/ruby-smtp-mock/blob/master/README.md',
'bug_tracker_uri' => 'https://github.com/mocktools/ruby-smtp-mock/issues'
}

spec.required_ruby_version = '>= 2.5.0'

spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.executables = %w[smtp_mock]
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.executables = %w[smtp_mock]
spec.require_paths = %w[lib]
spec.post_install_message = 'smtpmock is required system dependency. For more details run: `bundle exec smtp_mock -h`'

spec.add_runtime_dependency 'dry-struct', '~> 1.6'

spec.add_development_dependency 'bundler-audit', '~> 0.9.1'
spec.add_development_dependency 'fasterer', '~> 0.10.0'
spec.add_development_dependency 'ffaker', '~> 2.21'
spec.add_development_dependency 'mdl', '~> 0.12.0'
spec.add_development_dependency 'net-smtp', '~> 0.3.3'
spec.add_development_dependency 'overcommit', '~> 0.59.1'
spec.add_development_dependency 'pry-byebug', '~> 3.10', '>= 3.10.1'
spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6'
spec.add_development_dependency 'reek', '~> 6.1', '>= 6.1.1'
Expand Down
4 changes: 4 additions & 0 deletions .circleci/linter_configs/.bundler-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---

ignore:
- EXA-MPLE-XXXX
4 changes: 4 additions & 0 deletions .circleci/linter_configs/.fasterer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---

exclude_paths:
- '.circleci/**/*.rb'
7 changes: 7 additions & 0 deletions .circleci/linter_configs/.mdlrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

all
rule 'MD013', line_length: 500
rule 'MD029', style: :ordered
exclude_rule 'MD007'
exclude_rule 'MD024'
23 changes: 13 additions & 10 deletions .rubocop.yml → .circleci/linter_configs/.rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
---

require:
- rubocop-rspec
- rubocop-performance

AllCops:
DisplayCopNames: true
DisplayStyleGuide: true
TargetRubyVersion: 2.5
DisplayCopNames: true
DisplayStyleGuide: true
TargetRubyVersion: 2.5
SuggestExtensions: false
NewCops: enable

# Metrics ---------------------------------------------------------------------
Expand Down Expand Up @@ -66,13 +69,13 @@ Layout/ClassStructure:
- prepend
- extend
ExpectedOrder:
- module_inclusion
- constants
- public_class_methods
- initializer
- public_methods
- protected_methods
- private_methods
- module_inclusion
- constants
- public_class_methods
- initializer
- public_methods
- protected_methods
- private_methods

Layout/EmptyLineAfterGuardClause:
Enabled: false
Expand Down
7 changes: 7 additions & 0 deletions .circleci/linter_configs/.yamllint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---

extends: default

rules:
line-length:
max: 200
63 changes: 63 additions & 0 deletions .circleci/scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# !/bin/sh
set -e

GH_CLI_RELEASES_URL="https://github.com/cli/cli/releases"
FILE_NAME="gh"
BUILD_ARCHITECTURE="linux_amd64.deb"
DELIMETER="_"
PACKAGE_FILE="$FILE_NAME$DELIMETER$BUILD_ARCHITECTURE"

gh_cli_latest_release() {
curl -sL -o /dev/null -w %{url_effective} "$GH_CLI_RELEASES_URL/latest" | rev | cut -f1 -d'/'| rev
}

download_gh_cli() {
test -z "$VERSION" && VERSION="$(gh_cli_latest_release)"
test -z "$VERSION" && {
echo "Unable to get GitHub CLI release." >&2
exit 1
}
curl -s -L -o "$PACKAGE_FILE" "$GH_CLI_RELEASES_URL/download/$VERSION/$FILE_NAME$DELIMETER${VERSION:1}$DELIMETER$BUILD_ARCHITECTURE"
}

install_gh_cli() {
sudo dpkg -i "$PACKAGE_FILE"
rm "$PACKAGE_FILE"
}

get_release_candidate_version() {
echo $(ruby -r rubygems -e "puts Gem::Specification::load('$(ls *.gemspec)').version")
}

release_candidate_tag="v$(get_release_candidate_version)"

is_an_existing_github_release() {
git fetch origin "refs/tags/$release_candidate_tag" >/dev/null 2>&1
}

release_to_rubygems() {
echo "Setting RubyGems publisher credentials..."
./.circleci/scripts/set_publisher_credentials.sh
echo "Preparation for release..."
git config --global user.email ${PUBLISHER_EMAIL}
git config --global user.name ${PUBLISHER_NAME}
git stash
git checkout develop
gem install yard gem-ctags
bundle install
echo "Publishing new gem release to RubyGems..."
rake release
}

release_to_github() {
echo "Downloading and installing latest gh cli..."
download_gh_cli
install_gh_cli
echo "Publishing new release notes to GitHub..."
gh release create "$release_candidate_tag" --generate-notes
}

if is_an_existing_github_release
then echo "Tag $release_candidate_tag already exists on GitHub. Skipping releasing flow..."
else release_to_rubygems; release_to_github
fi
Loading

0 comments on commit bdf6806

Please sign in to comment.