From 18d51fd4b2590dcb38e0816557b3fa0c305fa783 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 10 Aug 2024 08:14:37 +0100 Subject: [PATCH] Chore: Switch from Circle to Github Actions for CI (#4734) Because: - It's _slightly_ faster - The configuration is more approachable - We get unlimited free usage since the repo is public This commit: - Adds a GitHub actions workflow for running our linters and tests - Adds bin stubs for rubocop, erblint and rspec --- .circleci/config.yml | 85 ----------------------------- .github/workflows/ci.yml | 91 +++++++++++++++++++++++++++++++ README.md | 2 +- bin/erblint | 27 +++++++++ bin/rspec | 27 +++++++++ bin/rubocop | 27 +++++++++ spec/support/precompile_assets.rb | 7 ++- 7 files changed, 179 insertions(+), 87 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/workflows/ci.yml create mode 100755 bin/erblint create mode 100755 bin/rspec create mode 100755 bin/rubocop diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index b556950b7e..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,85 +0,0 @@ ---- -version: 2.1 - -orbs: - browser-tools: circleci/browser-tools@1.4.8 - ruby: circleci/ruby@2.1.1 - -executors: - rails-executor: - docker: - - image: cimg/ruby:3.3.4-browsers - environment: - RAILS_ENV: test - POSTGRES_USERNAME: postgres - POSTGRES_PASSWORD: password - - image: cimg/redis:6.2.6 - - image: cimg/postgres:14.2 - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: password - POSTGRES_DB: theodinproject_test - working_directory: ~/theodinproject - -commands: - build-app: - description: Building app - steps: - - run: gem install bundler:2.4.13 - - restore_cache: - name: Restore bundle cache - key: theodinproject-bundle-{{ checksum "Gemfile.lock" }} - - restore_cache: - name: Restore yarn cache - key: theodinproject-yarn-{{ checksum "yarn.lock" }} - - run: bundle install --path vendor/bundle - - run: yarn install - - save_cache: - name: Store bundle cache - key: theodinproject-bundle-{{ checksum "Gemfile.lock" }} - paths: - - vendor/bundle - - save_cache: - name: Store yarn cache - key: theodinproject-yarn-{{ checksum "yarn.lock" }} - paths: - - ~/.yarn-cache - - run: dockerize -wait tcp://localhost:5432 -timeout 1m - - run: bundle exec rake db:schema:load - -jobs: - tests: - executor: rails-executor - steps: - - checkout - - browser-tools/install-chromedriver - - run: - command: - google-chrome --version - chromedriver --version - name: Check install - - build-app - - ruby/rspec-test - linters: - executor: rails-executor - steps: - - checkout - - build-app - - run: bundle exec rubocop - - run: bundle exec erblint --lint-all - - run: yarn run eslint - seeds: - executor: rails-executor - steps: - - checkout - - build-app - - run: - name: Seeds - command: bin/rails db:seed - -workflows: - build: - jobs: - - tests - - linters - - seeds diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..34f5e7cdb5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,91 @@ +name: CI + +on: + pull_request: + branches: ["*"] + push: + branches: [main] + +concurrency: ci-${{ github.ref }} + +jobs: + linters: + name: Linters + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Ruby and install gems + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + + - name: Install packages + run: | + yarn install --pure-lockfile + + - name: Run linters + run: | + bin/rubocop --parallel + bin/erblint --lint-all + yarn run eslint + + tests: + name: Tests + runs-on: ubuntu-latest + services: + postgres: + image: postgres:15.7 + env: + POSTGRES_USER: postgres + POSTGRES_DB: theodinproject_test + POSTGRES_PASSWORD: "password" + ports: ["5432:5432"] + + redis: + image: redis + ports: ["6379:6379"] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Ruby and install gems + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + + - name: Install packages + run: | + yarn install --pure-lockfile + + - name: Build assets + run: | + bin/rails javascript:build + bin/rails css:build + + - name: Setup test database + env: + RAILS_ENV: test + DATABASE_URL: postgres://postgres:password@localhost:5432/theodinproject_test + run: | + bin/rails db:schema:load + + - name: Run tests + env: + RAILS_ENV: test + DATABASE_URL: postgres://postgres:password@localhost:5432/theodinproject_test + run: bin/rspec diff --git a/README.md b/README.md index 5c298734cb..0bf9ba1877 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Our community can be found on the [TOP Discord server](https://discord.gg/fbFCkY ## Contributing -[![Build Status](https://circleci.com/gh/TheOdinProject/theodinproject.svg?style=svg)](https://app.circleci.com/pipelines/github/TheOdinProject/theodinproject) +![Build status](https://github.com/TheOdinProject/theodinproject/actions/workflows/ci.yml/badge.svg) The Odin Project depends on open-source contributions to improve, grow, and thrive. We welcome contributors of all experience levels and backgrounds to help maintain this awesome curriculum and community. If you would like to contribute to our curriculum, be sure to thoroughly read our [contributing guide](https://github.com/TheOdinProject/theodinproject/blob/main/CONTRIBUTING.md). diff --git a/bin/erblint b/bin/erblint new file mode 100755 index 0000000000..63d662cffa --- /dev/null +++ b/bin/erblint @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'erblint' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +bundle_binstub = File.expand_path("bundle", __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") + load(bundle_binstub) + else + abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. +Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") + end +end + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("erb_lint", "erblint") diff --git a/bin/rspec b/bin/rspec new file mode 100755 index 0000000000..cb53ebe5f0 --- /dev/null +++ b/bin/rspec @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'rspec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +bundle_binstub = File.expand_path("bundle", __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") + load(bundle_binstub) + else + abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. +Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") + end +end + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rspec-core", "rspec") diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 0000000000..369a05bedb --- /dev/null +++ b/bin/rubocop @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'rubocop' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +bundle_binstub = File.expand_path("bundle", __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") + load(bundle_binstub) + else + abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. +Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") + end +end + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rubocop", "rubocop") diff --git a/spec/support/precompile_assets.rb b/spec/support/precompile_assets.rb index f5a302fc7f..fddbbb38bb 100644 --- a/spec/support/precompile_assets.rb +++ b/spec/support/precompile_assets.rb @@ -3,6 +3,11 @@ examples = RSpec.world.filtered_examples.values.flatten has_no_system_tests = examples.none? { |example| example.metadata[:type] == :system } + if ENV['CI'] + $stdout.puts "\n🚀️️ CI detected. Skip assets compilation.\n" + next + end + if has_no_system_tests $stdout.puts "\n🚀️️ No system test selected. Skip assets compilation.\n" next @@ -14,7 +19,7 @@ start = Time.current begin $stdout.reopen(File.new('/dev/null', 'w')) - system('bin/rails assets:precompile') + system('bin/rails test:prepare') # invokes css:build and javascript:build ensure $stdout.reopen(original_stdout) $stdout.puts "Finished in #{(Time.current - start).round(2)} seconds"