diff --git a/lib/suspenders.rb b/lib/suspenders.rb index ee8e9b5d2..927df199b 100644 --- a/lib/suspenders.rb +++ b/lib/suspenders.rb @@ -3,7 +3,6 @@ require "suspenders/generators/static_generator" require "suspenders/generators/stylesheet_base_generator" require "suspenders/generators/forms_generator" -require "suspenders/generators/ci_generator" require "suspenders/generators/db_optimizations_generator" require "suspenders/generators/factories_generator" require "suspenders/generators/lint_generator" @@ -17,4 +16,5 @@ require "suspenders/generators/production/timeout_generator" require "suspenders/actions" require "suspenders/adapters/heroku" +require "suspenders/adapters/circleci" require "suspenders/app_builder" diff --git a/lib/suspenders/adapters/circleci.rb b/lib/suspenders/adapters/circleci.rb new file mode 100644 index 000000000..c6c537816 --- /dev/null +++ b/lib/suspenders/adapters/circleci.rb @@ -0,0 +1,46 @@ +module Suspenders + module Adapters + class CircleCI + def initialize(app_builder) + @app_builder = app_builder + end + + def configure_circleci + app_builder.empty_directory(".circleci") + app_builder.template "circleci.yml.erb", ".circleci/config.yml" + end + + def configure_circleci_deployment + deploy_command = <<-YML.strip_heredoc + deploy: + docker: + - image: buildpack-deps:trusty + steps: + - checkout + - run: + name: Deploy to staging + command: bin/deploy staging + + workflows: + version: 2 + build-deploy: + jobs: + - build + - deploy: + requires: + - build + filters: + branches: + only: master + + YML + + app_builder.append_file ".circleci/config.yml", deploy_command + end + + private + + attr_reader :app_builder + end + end +end diff --git a/lib/suspenders/app_builder.rb b/lib/suspenders/app_builder.rb index 6ac34d8ac..1f7fe8145 100644 --- a/lib/suspenders/app_builder.rb +++ b/lib/suspenders/app_builder.rb @@ -19,6 +19,12 @@ class AppBuilder < Rails::AppBuilder :set_heroku_remotes, ) + def_delegators( + :circleci_adapter, + :configure_circleci, + :configure_circleci_deployment, + ) + def readme template 'README.md.erb', 'README.md' end @@ -242,15 +248,7 @@ def create_deploy_script end def configure_automatic_deployment - deploy_command = <<-YML.strip_heredoc - deployment: - staging: - branch: master - commands: - - bin/deploy staging - YML - - append_file "circle.yml", deploy_command + configure_circleci_deployment end def create_github_repo(repo_name) @@ -343,5 +341,9 @@ def raise_on_missing_translations_in(environment) def heroku_adapter @heroku_adapter ||= Adapters::Heroku.new(self) end + + def circleci_adapter + @circleci_adapter ||= Adapters::CircleCI.new(self) + end end end diff --git a/lib/suspenders/generators/app_generator.rb b/lib/suspenders/generators/app_generator.rb index a756cf293..e60d67bc0 100644 --- a/lib/suspenders/generators/app_generator.rb +++ b/lib/suspenders/generators/app_generator.rb @@ -56,6 +56,7 @@ def suspenders_customization invoke :setup_bundler_audit invoke :setup_spring invoke :generate_default + invoke :configure_circleci invoke :setup_default_directories invoke :create_local_heroku_setup invoke :create_heroku_apps @@ -177,12 +178,16 @@ def remove_routes_comment_lines build :remove_routes_comment_lines end + def configure_circleci + say "Configuring CircleCI" + build :configure_circleci + end + def generate_default run("spring stop") generate("suspenders:static") generate("suspenders:stylesheet_base") generate("suspenders:testing") - generate("suspenders:ci") generate("suspenders:js_driver") unless options[:api] generate("suspenders:forms") diff --git a/lib/suspenders/generators/ci_generator.rb b/lib/suspenders/generators/ci_generator.rb deleted file mode 100644 index fbaa0e9ba..000000000 --- a/lib/suspenders/generators/ci_generator.rb +++ /dev/null @@ -1,26 +0,0 @@ -require "rails/generators" - -module Suspenders - class CiGenerator < Rails::Generators::Base - source_root File.expand_path( - File.join("..", "..", "..", "templates"), - File.dirname(__FILE__)) - - def simplecov_test_integration - inject_into_file "spec/spec_helper.rb", before: 'SimpleCov.start "rails"' do - <<-RUBY - - if ENV["CIRCLE_ARTIFACTS"] - dir = File.join(ENV["CIRCLE_ARTIFACTS"], "coverage") - SimpleCov.coverage_dir(dir) - end - - RUBY - end - end - - def configure_ci - template "circle.yml.erb", "circle.yml" - end - end -end diff --git a/spec/features/circleci_spec.rb b/spec/features/circleci_spec.rb new file mode 100644 index 000000000..576f1dfcd --- /dev/null +++ b/spec/features/circleci_spec.rb @@ -0,0 +1,24 @@ +require "spec_helper" + +RSpec.describe "CircleCI" do + before(:all) do + drop_dummy_database + remove_project_directory + run_suspenders + setup_app_dependencies + end + + it "creates CircleCI config file" do + expect(File).to exist("#{project_path}/.circleci/config.yml") + end + + it "uses the app name in the config file" do + circleci_config = IO.read("#{project_path}/.circleci/config.yml") + + expect(circleci_config).to match(/working_directory: ~\/#{app_name}/) + end + + def app_name + SuspendersTestHelpers::APP_NAME + end +end diff --git a/spec/features/heroku_spec.rb b/spec/features/heroku_spec.rb index 7e6381195..15a726b32 100644 --- a/spec/features/heroku_spec.rb +++ b/spec/features/heroku_spec.rb @@ -37,15 +37,30 @@ expect(readme).to include("./bin/deploy staging") expect(readme).to include("./bin/deploy production") - circle_yml_path = "#{project_path}/circle.yml" + circle_yml_path = "#{project_path}/.circleci/config.yml" circle_yml = IO.read(circle_yml_path) expect(circle_yml).to include <<-YML.strip_heredoc - deployment: - staging: - branch: master - commands: - - bin/deploy staging + deploy: + docker: + - image: buildpack-deps:trusty + steps: + - checkout + - run: + name: Deploy to staging + command: bin/deploy staging + + workflows: + version: 2 + build-deploy: + jobs: + - build + - deploy: + requires: + - build + filters: + branches: + only: master YML end end diff --git a/templates/circle.yml.erb b/templates/circle.yml.erb deleted file mode 100644 index 2d25fe186..000000000 --- a/templates/circle.yml.erb +++ /dev/null @@ -1,6 +0,0 @@ -database: - override: - - RAILS_ENV=development bin/setup -test: - override: - - COVERAGE=true bin/rake diff --git a/templates/circleci.yml.erb b/templates/circleci.yml.erb new file mode 100644 index 000000000..3cf8d2137 --- /dev/null +++ b/templates/circleci.yml.erb @@ -0,0 +1,53 @@ +version: 2 +jobs: + build: + working_directory: ~/<%= app_name %> + docker: + - image: circleci/ruby:<%= Suspenders::RUBY_VERSION %>-node + environment: + RAILS_ENV: test + PGHOST: localhost + PGUSER: <%= app_name %> + - image: postgres:10.5 + environment: + POSTGRES_USER: <%= app_name %> + POSTGRES_DB: <%= app_name %>_test + POSTGRES_PASSWORD: "" + steps: + - checkout + + - run: + name: Which Bundler? + command: bundle -v + + - restore_cache: + keys: + - <%= app_name %>-{{ .Branch }}-{{ checksum "Gemfile.lock" }} + - <%= app_name %>- + + - run: + name: Bundle Install + command: | + bundle install --deployment \ + --retry=3 \ + --jobs=3 + + - save_cache: + key: <%= app_name %>-{{ .Branch }}-{{ checksum "Gemfile.lock" }} + paths: + - vendor/bundle + + - run: + name: Wait for database + command: dockerize -wait tcp://localhost:5432 -timeout 1m + + - run: + name: Database setup + command: RAILS_ENV=development bin/setup + + - run: + name: Run tests + command: COVERAGE=true bundle exec rake + + - store_artifacts: + path: coverage