Skip to content

Instantly share code, notes, and snippets.

@amkisko
Last active September 12, 2023 07:31
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amkisko/0fa124bb8a63aa2f89b4e41d9680c319 to your computer and use it in GitHub Desktop.
Save amkisko/0fa124bb8a63aa2f89b4e41d9680c319 to your computer and use it in GitHub Desktop.
Rails, GitHub Actions, GitLab CI, PostgreSQL, Redis, rspec, codecov, Apollo GraphQL
Configuration files for Rails-driven project basic continuous integration using GitHub Actions and GitLab CI.
2020, amkisko (Andrei Makarov).
# FILEPATH: .github/workflows/pronto.yml
# AUTHOR: github.com/amkisko
name: Pronto
on: [pull_request]
jobs:
pronto:
runs-on: ubuntu-latest
steps:
- name: "Checkout repository"
uses: actions/checkout@v1
- name: "Install Ruby version specified in `.ruby-version`"
uses: eregon/use-ruby-action@master
- run: gem install pronto pronto-rubocop
- run: PRONTO_PULL_REQUEST_ID="$(jq --raw-output .number "$GITHUB_EVENT_PATH")" PRONTO_GITHUB_ACCESS_TOKEN="${{ secrets.GITHUB_TOKEN }}" pronto run -f github_status github_pr -c origin/master
# FILEPATH: .github/workflows/rails.yml
# AUTHOR: github.com/amkisko
name: rails
on:
push:
branches:
- master
jobs:
rspec:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:alpine
ports: ["6379:6379"]
options: --entrypoint redis-server
steps:
- run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
- name: "Checkout repository"
uses: actions/checkout@v1
- name: "Install Ruby version specified in `.ruby-version`"
uses: eregon/use-ruby-action@master
- name: "Install required system packages"
run: sudo apt-get update -y && sudo apt-get install openssh-client rsync libpq-dev cmake -y
- name: "Setup caching for Ruby gems cache"
uses: actions/cache@v1
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gem-
- name: "Read Node.js version"
run: echo "##[set-output name=NVMRC;]$(cat .nvmrc)"
id: nvm
- name: "Install Node.js"
uses: actions/setup-node@v1
with:
node-version: "${{ steps.nvm.outputs.NVMRC }}"
- name: "Read Yarn cache directory path"
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: "Setup caching for Yarn cache"
uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: "Setup caching for assets"
id: assets-cache
uses: actions/cache@v1
with:
path: public/packs-test
key: ${{ runner.os }}-assets-${{ steps.extract_branch.outputs.branch }}
restore-keys: |
${{ runner.os }}-assets-
- name: "Bundle install"
run: |
gem install bundler && bundle update --bundler && bundle -v
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: "Bundle outdated"
continue-on-error: true
run: bundle outdated
- name: "Yarn install"
run: yarn install
- name: "Yarn outdated"
continue-on-error: true
run: yarn outdated
- name: "Compile Assets"
shell: bash
run: |
if [[ ! -d public/packs-test ]]; then
bundle exec rails webpacker:compile
else
echo "No need to compile assets."
fi
- name: "Rails test"
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/test
REDIS_URL: redis://localhost:6379/0
RAILS_ENV: test
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
run: |
bundle exec rails db:setup --trace
bundle exec rails test
bundle exec rspec
bundle exec rails zeitwerk:check
- name: "Generate and upload schemas"
if: ${{ contains('master,testing', steps.vars.outputs.short_ref) || steps.finder.outputs.pr }}
env:
APOLLO_KEY: ${{ secrets.APOLLO_USER_SCHEMA_KEY }}
continue-on-error: true
run: |
bundle exec rake graphql:dump_schema
npx rover graph publish "Project-Name@${{ steps.vars.outputs.short_ref }}" --schema docs/user_schema.graphql
- name: "Inspect user schema"
uses: kamilkisiela/graphql-inspector@master
continue-on-error: true
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
schema: "master:docs/user_schema.graphql"
fail-on-breaking: false
- uses: marocchino/sticky-pull-request-comment@v2
if: ${{ steps.finder.outputs.pr }}
with:
number: ${{ steps.finder.outputs.pr }}
header: graphql-schema
message: |
GraphQL schema available here: https://studio.apollographql.com/graph/Project-Name/home?variant=${{ steps.vars.outputs.short_ref }}
# FILEPATH: .gitlab-ci.yml
# AUTHOR: github.com/amkisko
default:
# https://hub.docker.com/r/library/ruby/tags/
image: ruby:latest
services:
- redis:alpine
- postgres:alpine
cache:
paths:
- vendor/bundle
before_script:
- apt-get update -y && apt-get install openssh-client rsync libpq-dev nodejs cmake -y
- gem install bundler && bundle update --bundler && bundle -v
- mkdir -p ~/.ssh && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- ruby -v
- ssh -V
- bundle config path vendor/bundle
- bundle install --jobs $(nproc) "${FLAGS[@]}"
- bundle exec rails db:setup
variables:
POSTGRES_PASSWORD: postgres
DATABASE_URL: "postgres://postgres:postgres@postgres/test"
REDIS_URL: "redis://redis:6379/0"
RAILS_ENV: test
NODE_ENV: test
BUNDLE_PATH: vendor/bundle
GIT_DEPTH: 20
GIT_SUBMODULE_STRATEGY: none
GET_SOURCES_ATTEMPTS: 3
BUILD_ASSETS_IMAGE: "false"
CODECOV_TOKEN: "1234567a-1234-1a1a-1234a-1234567"
stages:
- test
audit:
stage: test
only:
- master
script:
- bundle exec bundle-audit check --update
- bundle exec brakeman
lint:
stage: test
only:
- master
script:
- bundle exec rubocop -P
test:
stage: test
only:
- master
script:
- bundle exec rails test
- bundle exec rspec
# FILEPATH: codecov.yml
# AUTHOR: github.com/amkisko
ignore:
- "vendor/.*"
- "db/.*"
- "test/test_helper.rb"
- "config/environments"
parsers:
v1:
include_full_missed_files: false
# FILEPATH: config/initializers/secure_headers.rb
# AUTHOR: github.com/amkisko
SecureHeaders::Configuration.default do |config|
config.cookies = {
secure: true,
httponly: true,
samesite: {
strict: true
}
}
config.hsts = "max-age=#{1.week.to_i}"
config.x_frame_options = "DENY"
config.x_content_type_options = "nosniff"
config.x_xss_protection = "1; mode=block"
config.x_download_options = "noopen"
config.x_permitted_cross_domain_policies = "none"
config.referrer_policy = %w(origin-when-cross-origin strict-origin-when-cross-origin)
end
SecureHeaders::Configuration.override(:api) do |config|
config.csp = { default_src: 'none' }
config.hsts = SecureHeaders::OPT_OUT
config.x_frame_options = SecureHeaders::OPT_OUT
config.x_content_type_options = SecureHeaders::OPT_OUT
config.x_xss_protection = SecureHeaders::OPT_OUT
config.x_permitted_cross_domain_policies = SecureHeaders::OPT_OUT
end
# FILEPATH: Gemfile
# AUTHOR: github.com/amkisko
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.7.0'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails'
# gem 'irb'
gem 'pry-rails'
gem 'jbuilder'
gem 'graphql'
gem 'graphiql-rails', group: :development
gem 'batch-loader'
gem 'graphql-errors'
# gem 'pundit'
gem 'puma'
# gem 'webpacker'
gem 'pg', '~> 1.0'
# gem 'scenic'
# gem 'fx'
gem 'strong_migrations'
# gem 'sass-rails'
# gem 'turbolinks'
# gem 'redis'
# Use Active Storage variant
# gem 'image_processing', '~> 1.2'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false
gem 'kaminari'
gem 'rack-attack'
gem 'rack-cors'
gem 'faraday'
gem 'browser'
# gem 'csv'
# gem 'whenever'
# gem 'zhong'
gem 'sidekiq'
gem 'andpush'
# gem 'discordrb-webhooks'
gem 'slack-notifier'
# gem 'telegram-bot'
gem 'rails-i18n'
# gem 'faker'
gem 'ffaker'
gem 'factory_bot_rails'
gem 'forgery'
gem 'request_store_rails'
gem 'attr_encrypted'
gem 'audited'
gem 'lockbox'
gem 'secure_headers'
# gem 'jemalloc'
# gem 'phonelib'
gem 'phony_rails'
gem 'validates_timeliness'
group :development, :test do
gem 'brakeman'
gem 'bundle-audit'
gem 'database_cleaner'
gem 'rspec-rails'
gem 'rubocop'
gem 'rubocop-gitlab-security'
gem 'rubocop-performance'
gem 'rubocop-rails'
gem 'rubocop-rspec'
gem 'derailed_benchmarks'
gem 'memory_profiler'
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of web drivers to run system tests with browsers
gem 'webdrivers'
gem 'rails-controller-testing'
end
gem 'codecov', :require => false, :group => :test
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
{
"name": "my-app",
"private": true,
"engines": {
"node": "14.4.0",
"yarn": "~> 1.22.4"
},
"dependencies": {},
"devDependencies": {
"@apollo/rover": "^0.3.0"
}
}
# FILEPATH: spec/spec_helper.rb
# AUTHOR: github.com/amkisko
require "simplecov"
SimpleCov.start("rails")
require "codecov"
SimpleCov.formatter = SimpleCov::Formatter::Codecov
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
config.filter_run_when_matching :focus
config.disable_monkey_patching!
config.default_formatter = 'doc' if config.files_to_run.one?
config.profile_examples = 10
config.order = :random
Kernel.srand config.seed
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment