[RUBY] CircleCI configuration file that has been replaced by the operation of my own library

I would like to summarize the situation at that time as to why and how the CircleCI settings introduced during the development of the Ruby gem called QiitaTrend changed.

qiita_trend

QiitaTrend is a gem that can get Qiita trend information (Daily, Weekly, Monthly) in 10 seconds.

Rough chronology of config.yml

I've updated CircleCI's config.yml a lot so far. Strictly speaking, the config.yml that has been used has more detailed modifications, but if it is roughly divided, the modification history will be as follows.

Year month Changes
2019/08 Introducing CircleCI
2019/08 Changed YARD to automatically generate documents
2019/08 Introducing workflow
2019/12 CircleCI2.Upgrade to 1
2020/02 Introduction of workspace function
2020/04 Added slack notification / deployment approval function
2020/08 Added workflow to run tests daily
2020/10 Change the image of CircleCI to the next generation
2020/11 Introduction of Ruby orb

August 2019: First CircleCI

It starts with trying to create a Ruby gem for your own study.

** I wanted to automate testing and deployment **, so I decided to introduce ** CircleCI, which I used in my business. In the first place, at this point, ** I have never built CI/CD ** and I started from a state where I had almost no knowledge.

Introduction method

How did you introduce it without any knowledge in the first place? As I recall, I have left an article ** on Qiita regarding the first introduction.

-Experience CI/CD (Continuous Integration/Continuous Delivery) with CircleCI while publishing Ruby gem

Basically ** I read the official document and copied and pasted it as it was, deleted unnecessary ones, added necessary functions and created **. Read the Qiita article for more information.

config.yml

The first config.yml I introduced is: Looking at it now, it's very simple (laughs) It's not version2.1, and you don't have a workflow.

00_add_first_circleci

config.yml
# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: circleci/ruby:2.6.0-node-browsers
        environment:
          BUNDLER_VERSION: 2.0.1

      # Specify service dependencies here if necessary
      # CircleCI maintains a library of pre-built images
      # documented at https://circleci.com/docs/2.0/circleci-images/
      # - image: circleci/postgres:9.4

    working_directory: ~/repo

    steps:
      - checkout
      # Download and cache dependencies
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-
      # install Bundler!
      # ref:https://discuss.circleci.com/t/using-bundler-2-0-during-ci-fails/27411
      - run:
          name: install bundler
          command: |
            sudo gem update --system
            sudo gem uninstall bundler
            sudo rm /usr/local/bin/bundle
            sudo rm /usr/local/bin/bundler
            sudo gem install bundler
      # install gem!
      - run:
          name: install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}
      # run rubocop!
      - run:
          name: run rubocop
          command: |
            bundle exec rubocop
      # run tests!
      - run:
          name: run tests
          command: |
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out test_results/rspec.xml \
              --format progress \
              $TEST_FILES
      # collect reports
      - store_test_results:
          path: test_results
      - store_artifacts:
          #Test result test-Spit to the results directory
          path: test_results
          destination: test-results
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results
      # deploy RubyGems
      - deploy:
          command: |
            if [ "${CIRCLE_BRANCH}" == "master" ]; then
              mkdir ~/.gem
              curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
              git config user.name dodonki1223
              git config user.email $RUBYGEMS_EMAIL
              bundle exec rake build
              bundle exec rake release
            fi

Added content

This section describes processing other than cache. Basically, most of them are just brought from what was in the CircleCI documentation.

Install Bundler

--Processing during installation of Bundler --This is implemented by copying what was written in the CircleCI document. ――By the way, Bundler is a gem that manages the version of gem and the dependency of gem.

- run:
    name: install bundler
    command: |
      sudo gem update --system
      sudo gem uninstall bundler
      sudo rm /usr/local/bin/bundle
      sudo rm /usr/local/bin/bundler
      sudo gem install bundler

Dependency installation

--Process to install dependencies used by gem ――This is also implemented by copying what was written in the CircleCI document

- run:
    name: install gem
    command: |
      # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
      bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3

Run RuboCop

--Processing that is executing the static analysis tool RuboCop

- run:
    name: run rubocop
    command: |
      bundle exec rubocop

Run RSpec

--Processing that is executing RSpec (execution of test) ――This is also implemented by copying what was written in the CircleCI document

- run:
    name: run tests
    command: |
      TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
      bundle exec rspec \
        --format progress \
        --format RspecJunitFormatter \
        --out test_results/rspec.xml \
        --format progress \
        $TEST_FILES

Uploading artifacts

--Processing that uploads test results and coverage results to CircleCI so that you can see the results --This is also implemented with reference to the CircleCI documentation.

# collect reports
- store_test_results:
    path: test_results
- store_artifacts:
    #Test result test-Spit to the results directory
    path: test_results
    destination: test-results
- store_artifacts:
    #Coverage the result of coverage-Spit to the results directory
    path: coverage
    destination: coverage-results

Deploy to RubyGems

--Process to deploy to RubyGems at master branch -I tried to automate the deployment to Rubygems with CircleCI | WEB EGG as a reference

- deploy:
    command: |
      if [ "${CIRCLE_BRANCH}" == "master" ]; then
        mkdir ~/.gem
        curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
        git config user.name dodonki1223
        git config user.email $RUBYGEMS_EMAIL
        bundle exec rake build
        bundle exec rake release
      fi

How was it when you introduced it for the first time?

――I thought CI/CD was a difficult thing to understand, but when I actually introduced it step by step, I found that it was ** not so difficult **. --I was able to understand CircleCI's ** cache to some extent **

August 2019: Automatic document creation

** Introduced YARD to publish gem documentation to RubyDoc.info and added processing to automatically generate documentation. ** The document actually published is here.

config.yml

This is config.yml with added processing to automatically generate documents.

01_add_create_document

config.yml
# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: circleci/ruby:2.6.0-node-browsers
        environment:
          BUNDLER_VERSION: 2.0.1

      # Specify service dependencies here if necessary
      # CircleCI maintains a library of pre-built images
      # documented at https://circleci.com/docs/2.0/circleci-images/
      # - image: circleci/postgres:9.4

    working_directory: ~/repo

    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      # install Bundler!
      # ref:https://discuss.circleci.com/t/using-bundler-2-0-during-ci-fails/27411
      - run:
          name: install bundler
          command: |
            sudo gem update --system
            sudo gem uninstall bundler
            sudo rm /usr/local/bin/bundle
            sudo rm /usr/local/bin/bundler
            sudo gem install bundler
      # install gem!
      - run:
          name: install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}
      # run rubocop!
      - run:
          name: run rubocop
          command: |
            bundle exec rubocop
      # run tests!
      - run:
          name: run tests
          command: |
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out test_results/rspec.xml \
              --format progress \
              $TEST_FILES
      # create document
      - run:
          name: create document
          command: |
            bundle exec yard
      # collect reports
      - store_test_results:
          path: test_results
      - store_artifacts:
          #Test result test-Spit to the results directory
          path: test_results
          destination: test-results
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results
      - store_artifacts:
          #Yard document results-Spit to the results directory
          path: ./doc
          destination: yard-results
      # deploy RubyGems
      - deploy:
          command: |
            if [ "${CIRCLE_BRANCH}" == "master" ]; then
              mkdir ~/.gem
              curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
              git config user.name dodonki1223
              git config user.email $RUBYGEMS_EMAIL
              bundle exec rake build
              bundle exec rake release
            fi

Update contents

Added the YARD creation process and the upload function of the created YARD.

Creating a YARD

--Implemented by referring to the YARD document

# create document
- run:
    name: create document
    command: |
      bundle exec yard

Upload the created YARD

――Since I did the same thing before, I could implement it without thinking about anything.

- store_artifacts:
    #Yard document results-Spit to the results directory
    path: ./doc
    destination: yard-results

August 2019: Introducing workflow

I noticed that there is a function called workflow, and ** introduced workflow **.

config.yml

This is config.yml with the workflow settings added.

02_add_workflows

config.yml
# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.0
        environment:
          BUNDLE_PATH: vendor/bundle

    working_directory: ~/repo

    steps:
      - checkout

      # Install Bundler
      # ref:https://discuss.circleci.com/t/using-bundler-2-0-during-ci-fails/27411
      - run:
          name: Install Bundler
          command: |
            echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV
            source $BASH_ENV
            gem install bundler

      # Which version of bundler?
      - run:
          name: Which bundler?
          command: bundle -v

      # Restore bundle cache
      # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      # Install gem
      - run:
          name: Install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3

      # Store bundle cache for Ruby dependencies
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

      # Run RuboCop
      - run:
          name: Run RuboCop
          command: |
            bundle exec rubocop

      # Run tests
      - run:
          name: Run tests
          command: |
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out test_results/rspec.xml \
              --format progress \
              $TEST_FILES

      # Create document
      - run:
          name: Create document
          command: |
            bundle exec yard

      # Collect Reports
      - store_test_results:
          path: test_results
      - store_artifacts:
          #Test result test-Spit to the results directory
          path: test_results
          destination: test-results
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results
      - store_artifacts:
          #Yard document results-Spit to the results directory
          path: ./doc
          destination: yard-results

  deploy:
    docker:
      - image: circleci/ruby:2.6.0

    steps:
      - checkout

      # Install Bundler
      # ref:https://discuss.circleci.com/t/using-bundler-2-0-during-ci-fails/27411
      - run:
          name: install Bundler
          command: |
            echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV
            source $BASH_ENV
            gem install bundler

      # Which version of bundler?
      - run:
          name: Which bundler?
          command: bundle -v

      # Restore bundle cache
      # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            - v1-dependencies-

      # Install gem
      - run:
          name: Install gem
          command: bundle check --path vendor/bundle || bundle install

      # Store bundle cache for Ruby dependencies
      - save_cache:
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle

      # Deploy RubyGems
      - run:
          name: Deploy RubyGems
          command: |
            curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
            git config user.name dodonki1223
            git config user.email $RUBYGEMS_EMAIL
            bundle exec rake build
            bundle exec rake release

workflows:
  version: 2
  build-and-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: master #Execute DeployJob only in the master branch

Update contents

Part of build was separated, a job called deploy was created, and each was modified so that the order was secured by workflows.

Added workflow settings

--Set to be processed in the order of build → deploy --deploy is set to run only on the master branch.

workflows:
  version: 2
  build-and-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: master #Execute DeployJob only in the master branch

December 2019: Introducing CircleCI 2.1

** Changed CircleCI version from 2.0 to 2.1 to eliminate redundant writing **. When I was doing this refurbishment, I was a ** AWS Certified Solutions Architect-Associate ** and I was sick and tired (laughs). When this was completed, I felt a little better ... Thanks to CircleCI.

** AWS Certified Solutions Architect-Associate ** was successfully accepted one month later.

config.yml

This is config.yml with the version changed from 2.0 to 2.1.

03_update_version2_1

config.yml
version: 2.1
executors:
  base:
    docker:
      - image: circleci/ruby:2.6.0
        environment:
          BUNDLE_PATH: vendor/bundle
    working_directory: ~/repo

commands:
  # ref:https://discuss.circleci.com/t/using-bundler-2-0-during-ci-fails/27411
  install-bundler:
    steps:

      - run:
          name: Install Bundler
          command: |
            echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV
            source $BASH_ENV
            gem install bundler
            # Which version of bundler?
            bundle -v

  # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
  restore-gem-cache:
    steps:

      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

  install-gem:
    steps:
      - run:
          name: Install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3

  save-gem-cache:
    steps:
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

  run-rubocop:
    steps:
      - run:
          name: Run RuboCop
          command: |
            bundle exec rubocop

  run-tests:
    steps:
      - run:
          name: Run tests
          command: |
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out test_results/rspec.xml \
              --format progress \
              $TEST_FILES

  create-document:
    steps:
      - run:
          name: Create document
          command: |
            bundle exec yard

  collect-reports:
    steps:
      # ref:https://circleci.com/docs/ja/2.0/configuration-reference/#store_test_results
      - store_test_results:
          path: test_results
      - store_artifacts:
          #Test result test-Spit to the results directory
          path: test_results
          destination: test-results
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results
      - store_artifacts:
          #Yard document results-Spit to the results directory
          path: ./doc
          destination: yard-results

  # Deploy RubyGems
  deploy-rubygems:

    steps:
      - run:
          name: Deploy RubyGems
          command: |
            curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
            git config user.name dodonki1223
            git config user.email $RUBYGEMS_EMAIL
            bundle exec rake build
            bundle exec rake release

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - install-gem
      - save-gem-cache

  lint:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - run-rubocop

  test:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - run-tests
      - create-document
      - collect-reports

  deploy:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - deploy-rubygems

workflows:
  version: 2.1
  main:
    jobs:
      - setup
      - lint:
          requires:
            - setup
      - test:
          requires:
            - setup
      - deploy:
          requires:
            - lint
            - test
          filters:
            branches:
              only: master #Execute DeployJob only in the master branch

Update contents

The repair at this time was the time when there were the most changes and the contents changed drastically. By using the executor and command functions, there are no redundant parts and the repair is quite refreshing.

If you are still using 2.0, ** we recommend upgrading to 2.1 soon **.

executors

--You can now reuse images in each job using executors

executors:
  base:
    docker:
      - image: circleci/ruby:2.6.0
        environment:
          BUNDLE_PATH: vendor/bundle
    working_directory: ~/repo

commands

--Implement each of the necessary processes for commands so that they can be reused.

commands:
  # ref:https://discuss.circleci.com/t/using-bundler-2-0-during-ci-fails/27411
  install-bundler:
    steps:

      - run:
          name: Install Bundler
          command: |
            echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV
            source $BASH_ENV
            gem install bundler
            # Which version of bundler?
            bundle -v

  # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
  restore-gem-cache:
    steps:

      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

  install-gem:
    steps:
      - run:
          name: Install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3

  save-gem-cache:
    steps:
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

  run-rubocop:
    steps:
      - run:
          name: Run RuboCop
          command: |
            bundle exec rubocop

  run-tests:
    steps:
      - run:
          name: Run tests
          command: |
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out test_results/rspec.xml \
              --format progress \
              $TEST_FILES

  create-document:
    steps:
      - run:
          name: Create document
          command: |
            bundle exec yard

  collect-reports:
    steps:
      # ref:https://circleci.com/docs/ja/2.0/configuration-reference/#store_test_results
      - store_test_results:
          path: test_results
      - store_artifacts:
          #Test result test-Spit to the results directory
          path: test_results
          destination: test-results
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results
      - store_artifacts:
          #Yard document results-Spit to the results directory
          path: ./doc
          destination: yard-results

  # Deploy RubyGems
  deploy-rubygems:
    steps:
      - run:
          name: Deploy RubyGems
          command: |
            curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
            git config user.name dodonki1223
            git config user.email $RUBYGEMS_EMAIL
            bundle exec rake build
            bundle exec rake release

jobs

--Clearly describe jobs using executor and command --Define a job in small units

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - install-gem
      - save-gem-cache

  lint:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - run-rubocop

  test:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - run-tests
      - create-document
      - collect-reports

  deploy:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - deploy-rubygems

workflows

--Reflect the detailed job

workflows:
  version: 2.1
  main:
    jobs:
      - setup
      - lint:
          requires:
            - setup
      - test:
          requires:
            - setup
      - deploy:
          requires:
            - lint
            - test
          filters:
            branches:
              only: master #Execute DeployJob only in the master branch

February 2020: Introduction of workspace function

Know and implement ** cache functionality available between jobs called workspace **

config.yml

A config.yml that adds a workspace to allow caching between jobs.

04_add_workspace

config.yml
version: 2.1
executors:
  base:
    docker:
      - image: circleci/ruby:2.6.0
        environment:
          #Bundler path settings rewritten`vendor/bundle`Not`/usr/local/bundle`I have referred to`bundle exec`Will result in an error
          #Bundler config file(The one with the path set)Persistent in workspace`vendor/bundle`Settings to refer to
          BUNDLE_APP_CONFIG: .bundle
    working_directory: ~/dodonki1223/qiita_trend

commands:
  install-bundler:
    steps:
      - run:
          name: Install bundler(2.1.0)
          command: gem install bundler:2.1.0

  # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
  restore-gem-cache:
    steps:
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

  install-gem:
    steps:
      - run:
          name: Install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3

  save-gem-cache:
    steps:
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

  save-workspace:
    steps:
      - persist_to_workspace:
          # working_Specify a relative or absolute path from directory
          root: .
          paths: .

  using-workspace:
    steps:
      - attach_workspace:
          # working_Specify a relative or absolute path from directory
          at: .

  run-rubocop:
    steps:
      - run:
          name: Run RuboCop
          command: |
            bundle exec rubocop

  run-tests:
    steps:
      - run:
          name: Run tests
          command: |
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out test_results/rspec.xml \
              --format progress \
              $TEST_FILES

  create-document:
    steps:
      - run:
          name: Create document
          command: |
            bundle exec yard

  collect-reports:
    steps:
      # ref:https://circleci.com/docs/ja/2.0/configuration-reference/#store_test_results
      - store_test_results:
          path: test_results
      - store_artifacts:
          #Test result test-Spit to the results directory
          path: test_results
          destination: test-results
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results
      - store_artifacts:
          #Yard document results-Spit to the results directory
          path: ./doc
          destination: yard-results

  deploy-rubygems:
    steps:
      # ref:https://support.circleci.com/hc/ja/articles/115015628247-%E6%8E%A5%E7%B6%9A%E3%82%92%E7%B6%9A%E8%A1%8C%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B-%E3%81%AF%E3%81%84-%E3%81%84%E3%81%84%E3%81%88-
      # read/Both write permissions are required
      - add_ssh_keys:
          fingerprints:
            - "38:d2:72:5e:9f:67:93:9a:ec:95:94:a2:0e:bf:41:9e"

      # ref:https://circleci.com/docs/2.0/gh-bb-integration/#establishing-the-authenticity-of-an-ssh-host
      - run:
          name: Avoid hosts unknown for github
          command: |
            mkdir -p ~/.ssh
            echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
                  bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
                  ' >> ~/.ssh/known_hosts

      - run:
          name: Deploy RubyGems
          command: |
            curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
            chmod 0600 ~/.gem/credentials
            git config user.name dodonki1223
            git config user.email $RUBYGEMS_EMAIL
            bundle exec rake build
            bundle exec rake release

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - install-gem
      - save-gem-cache
      - save-workspace

  lint:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-rubocop

  test:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-tests
      - create-document
      - collect-reports

  deploy:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - deploy-rubygems

workflows:
  version: 2.1
  main:
    jobs:
      - setup
      - lint:
          requires:
            - setup
      - test:
          requires:
            - setup
      - deploy:
          requires:
            - lint
            - test
          filters:
            branches:
              only: master #Execute DeployJob only in the master branch

Update contents

Added command to save and apply workspace and updated it for use in job.

Added command to save and apply workspace

Add the save and apply commands for workspace to command respectively.

save-workspace:
  steps:
    - persist_to_workspace:
        # working_Specify a relative or absolute path from directory
        root: .
        paths: .

using-workspace:
  steps:
    - attach_workspace:
        # working_Specify a relative or absolute path from directory
        at: .

Use workspace in job

--Save to workspace with job in setup --Use the materials created in setup for each job

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - install-gem
      - save-gem-cache
      - save-workspace

  lint:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-rubocop

  test:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-tests
      - create-document
      - collect-reports

  deploy:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - deploy-rubygems

What I learned from the introduction of workspace

caching-dependencies-overview

See image from CircleCI documentation

--Understanding the caches available on CircleCI -I found out that there are ** job cache ** and ** workflow cache (workspace) **.

April 2020: Addition of Slack notification / deployment approval function

Introduced ** orb ** for the first time and added slack notification and deployment approval features.

config.yml

config.yml with added slack notification and deployment approval features.

05_slack_notify

config.yml
version: 2.1
orbs:
  slack: circleci/[email protected]
executors:
  base:
    docker:
      - image: circleci/ruby:2.6.0
        environment:
          #Bundler path settings rewritten`vendor/bundle`Not`/usr/local/bundle`I have referred to`bundle exec`Will result in an error
          #Bundler config file(The one with the path set)Persistent in workspace`vendor/bundle`Settings to refer to
          BUNDLE_APP_CONFIG: .bundle
    working_directory: ~/dodonki1223/qiita_trend

commands:
  install-bundler:
    steps:
      - run:
          name: Install bundler(2.1.0)
          command: gem install bundler:2.1.0

  # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
  restore-gem-cache:
    steps:
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

  install-gem:
    steps:
      - run:
          name: Install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3

  save-gem-cache:
    steps:
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

  save-workspace:
    steps:
      - persist_to_workspace:
          # working_Specify a relative or absolute path from directory
          root: .
          paths: .

  using-workspace:
    steps:
      - attach_workspace:
          # working_Specify a relative or absolute path from directory
          at: .

  run-rubocop:
    steps:
      - run:
          name: Run RuboCop
          command: |
            bundle exec rubocop

  run-tests:
    steps:
      - run:
          name: Run tests
          command: |
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out test_results/rspec.xml \
              --format progress \
              $TEST_FILES

  collect-reports:
    steps:
      # ref:https://circleci.com/docs/ja/2.0/configuration-reference/#store_test_results
      - store_test_results:
          path: test_results
      - store_artifacts:
          #Test result test-Spit to the results directory
          path: test_results
          destination: test-results
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results

  create-document:
    steps:
      - run:
          name: Create document
          command: |
            bundle exec yard
      - store_artifacts:
          #Yard document results-Spit to the results directory
          path: ./doc
          destination: yard-results

  deploy-rubygems:
    steps:
      # ref:https://support.circleci.com/hc/ja/articles/115015628247-%E6%8E%A5%E7%B6%9A%E3%82%92%E7%B6%9A%E8%A1%8C%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B-%E3%81%AF%E3%81%84-%E3%81%84%E3%81%84%E3%81%88-
      # read/Both write permissions are required
      - add_ssh_keys:
          fingerprints:
            - "38:d2:72:5e:9f:67:93:9a:ec:95:94:a2:0e:bf:41:9e"

      # ref:https://circleci.com/docs/2.0/gh-bb-integration/#establishing-the-authenticity-of-an-ssh-host
      - run:
          name: Avoid hosts unknown for github
          command: |
            mkdir -p ~/.ssh
            echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
                  bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
                  ' >> ~/.ssh/known_hosts

      - run:
          name: Deploy RubyGems
          command: |
            curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
            chmod 0600 ~/.gem/credentials
            git config user.name dodonki1223
            git config user.email $RUBYGEMS_EMAIL
            bundle exec rake build
            bundle exec rake release

  deploy-notification:
    steps:
      - slack/status:
          success_message: ':circleci-pass:Deployment completed to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'
          failure_message: ':circleci-fail:Deployment failed on RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - install-gem
      - save-gem-cache
      - save-workspace

  lint:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-rubocop

  test:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-tests
      - collect-reports

  document:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - create-document

  deploy:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - deploy-rubygems
      - deploy-notification

workflows:
  version: 2.1
  main:
    jobs:
      - setup
      - lint:
          requires:
            - setup
      - test:
          requires:
            - setup
      - document:
          requires:
            - setup
      - slack/approval-notification:
          message: ':circleci-pass:Ready to deploy to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME\n When performing a deploy*Approve*Please press'
          requires:
            - lint
            - test
          filters:
            branches:
              only: master
      - approval-job:
          type: approval
          requires:
            - slack/approval-notification
      - deploy:
          requires:
            - approval-job
          filters:
            branches:
              only: master

Update contents

Added the ability to add slack to orbs to notify slack of the approval process and to notify slack after the deployment is complete.

05_01_slack_notify_sample

Add slack to orbs

version: 2.1
orbs:
  slack: circleci/[email protected]

Added deployment completion notification

--Let command notify slack that the deployment is complete

deploy-notification:
  steps:
    - slack/status:
        success_message: ':circleci-pass:Deployment completed to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'
        failure_message: ':circleci-fail:Deployment failed on RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'

--Add slack notification to end of deploy job

deploy:
  executor: base
  steps:
    - using-workspace
    - install-bundler
    - deploy-rubygems
    - deploy-notification

Added approval process

--Added approval process to workflow --Make it run only on the master branch

workflows:
  version: 2.1
  main:
    jobs:
・
・
・
      - slack/approval-notification:
          message: ':circleci-pass:Ready to deploy to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME\n When performing a deploy*Approve*Please press'
          requires:
            - lint
            - test
          filters:
            branches:
              only: master
・
・
・

August 2020: Added workflow to run daily tests

The gem QiitaTrend is scraping the Qiita site, so if the DOM configuration changes, it will fail with an error. Before I knew it, the test failed several times and the gem could not be used. ** Fixed to run daily tests ** because it needed to be quick to detect changes in the DOM configuration **.

config.yml

A config.yml with additional settings to run the test on a regular basis.

06_triggered_execute

config.yml
version: 2.1
orbs:
  slack: circleci/[email protected]
executors:
  base:
    docker:
      - image: circleci/ruby:2.6.0
        auth:
          username: dodonki1223
          password: $DOCKERHUB_PASSWORD
        environment:
          #Bundler path settings rewritten`vendor/bundle`Not`/usr/local/bundle`I have referred to`bundle exec`Will result in an error
          #Bundler config file(The one with the path set)Persistent in workspace`vendor/bundle`Settings to refer to
          BUNDLE_APP_CONFIG: .bundle
          # ref: https://circleci.com/docs/2.0/faq/#how-can-i-set-the-timezone-in-docker-images
          TZ: "Asia/Tokyo"
    working_directory: ~/dodonki1223/qiita_trend

commands:
  install-bundler:
    steps:
      - run:
          name: Install bundler(2.1.0)
          command: gem install bundler:2.1.0

  # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
  restore-gem-cache:
    steps:
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

  install-gem:
    steps:
      - run:
          name: Install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3

  save-gem-cache:
    steps:
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

  save-workspace:
    steps:
      - persist_to_workspace:
          # working_Specify a relative or absolute path from directory
          root: .
          paths: .

  using-workspace:
    steps:
      - attach_workspace:
          # working_Specify a relative or absolute path from directory
          at: .

  run-rubocop:
    steps:
      - run:
          name: Run RuboCop
          command: |
            bundle exec rubocop

  run-tests:
    steps:
      - run:
          name: Run tests
          command: |
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out test_results/rspec/rspec.xml \
              --format progress \
              $TEST_FILES

  collect-reports:
    steps:
      # ref:https://circleci.com/docs/ja/2.0/configuration-reference/#store_test_results
      - store_test_results:
          path: test_results
      - store_artifacts:
          #Test result test-Spit to the results directory
          path: test_results
          destination: test-results
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results

  create-document:
    steps:
      - run:
          name: Create document
          command: |
            bundle exec yard
      - store_artifacts:
          #Yard document results-Spit to the results directory
          path: ./doc
          destination: yard-results

  deploy-rubygems:
    steps:
      # ref:https://support.circleci.com/hc/ja/articles/115015628247-%E6%8E%A5%E7%B6%9A%E3%82%92%E7%B6%9A%E8%A1%8C%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B-%E3%81%AF%E3%81%84-%E3%81%84%E3%81%84%E3%81%88-
      # read/Both write permissions are required
      - add_ssh_keys:
          fingerprints:
            - "38:d2:72:5e:9f:67:93:9a:ec:95:94:a2:0e:bf:41:9e"

      # ref:https://circleci.com/docs/2.0/gh-bb-integration/#establishing-the-authenticity-of-an-ssh-host
      - run:
          name: Avoid hosts unknown for github
          command: |
            mkdir -p ~/.ssh
            echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
                  bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
                  ' >> ~/.ssh/known_hosts

      - run:
          name: Deploy RubyGems
          command: |
            curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
            chmod 0600 ~/.gem/credentials
            git config user.name dodonki1223
            git config user.email $RUBYGEMS_EMAIL
            bundle exec rake build
            bundle exec rake release

  deploy-notification:
    steps:
      - slack/status:
          success_message: ':circleci-pass:Deployment completed to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'
          failure_message: ':circleci-fail:Deployment failed on RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - install-gem
      - save-gem-cache
      - save-workspace

  lint:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-rubocop

  test:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-tests
      - collect-reports

  document:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - create-document

  deploy:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - deploy-rubygems
      - deploy-notification

workflows:
  version: 2.1
  main:
    jobs:
      - setup
      - lint:
          requires:
            - setup
      - test:
          requires:
            - setup
      - document:
          requires:
            - setup
      - slack/approval-notification:
          message: ':circleci-pass:Ready to deploy to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME\n When performing a deploy*Approve*Please press'
          requires:
            - lint
            - test
          filters:
            branches:
              only: master
      - approval-job:
          type: approval
          requires:
            - slack/approval-notification
      - deploy:
          requires:
            - approval-job
          filters:
            branches:
              only: master
  #Run tests on a regular basis
  # ref:https://circleci.com/docs/ja/2.0/triggers/
  nightly:
    triggers:
      - schedule:
          cron: "0 22 * * *" #Described in UTC
          filters:
            branches:
              only:
                - master
    jobs:
      - setup
      - test:
          requires:
            - setup

Update contents

Run RSpec daily to ensure that you can get Qiita trend information as long as the test doesn't fail.

Run the test daily

-Use triggers to have the test run daily at 7am

workflows:
  version: 2.1
  #Run tests on a regular basis
  # ref:https://circleci.com/docs/ja/2.0/triggers/
  nightly:
    triggers:
      - schedule:
          cron: "0 22 * * *" #Described in UTC
          filters:
            branches:
              only:
                - master
    jobs:
      - setup
      - test:
          requires:
            - setup

What happened to running every day?

--Tests have failed several times, and it is now possible to quickly detect changes in the DOM configuration. --When the test fails, CircleCI and slack are linked so that notifications can be detected immediately.

06_01_error_sample

An error is notified to slack like this

October 2020: Change the image of CircleCI to the next generation

Introduction to CircleCI Practice ──Both development speed and quality brought about by CI/CD has been released, so when I read it, I found out that there is a next-generation image called cimg, so I decided to introduce it. did.

config.yml

Config.yml changed to cimg

07_change_cimg

config.yml
version: 2.1
orbs:
  slack: circleci/[email protected]
executors:
  base:
    docker:
      - image: cimg/ruby:2.6.6
        auth:
          username: dodonki1223
          password: $DOCKERHUB_PASSWORD
        environment:
          #Bundler path settings rewritten`vendor/bundle`Not`/usr/local/bundle`I have referred to`bundle exec`Will result in an error
          #Bundler config file(The one with the path set)Persistent in workspace`vendor/bundle`Settings to refer to
          BUNDLE_APP_CONFIG: .bundle
          # ref: https://circleci.com/docs/2.0/faq/#how-can-i-set-the-timezone-in-docker-images
          TZ: "Asia/Tokyo"
    working_directory: ~/dodonki1223/qiita_trend

commands:
  install-bundler:
    steps:
      - run:
          name: Install bundler(2.1.0)
          command: gem install bundler:2.1.0

  # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
  restore-gem-cache:
    steps:
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

  install-gem:
    steps:
      - run:
          name: Install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3

  save-gem-cache:
    steps:
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

  save-workspace:
    steps:
      - persist_to_workspace:
          # working_Specify a relative or absolute path from directory
          root: .
          paths: .

  using-workspace:
    steps:
      - attach_workspace:
          # working_Specify a relative or absolute path from directory
          at: .

  run-rubocop:
    steps:
      - run:
          name: Run RuboCop
          command: |
            bundle exec rubocop

  run-tests:
    steps:
      - run:
          name: Run tests
          command: |
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out test_results/rspec/rspec.xml \
              --format progress \
              $TEST_FILES

  collect-reports:
    steps:
      # ref:https://circleci.com/docs/ja/2.0/configuration-reference/#store_test_results
      - store_test_results:
          path: test_results
      - store_artifacts:
          #Test result test-Spit to the results directory
          path: test_results
          destination: test-results
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results

  create-document:
    steps:
      - run:
          name: Create document
          command: |
            bundle exec yard
      - store_artifacts:
          #Yard document results-Spit to the results directory
          path: ./doc
          destination: yard-results

  deploy-rubygems:
    steps:
      # ref:https://support.circleci.com/hc/ja/articles/115015628247-%E6%8E%A5%E7%B6%9A%E3%82%92%E7%B6%9A%E8%A1%8C%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B-%E3%81%AF%E3%81%84-%E3%81%84%E3%81%84%E3%81%88-
      # read/Both write permissions are required
      - add_ssh_keys:
          fingerprints:
            - "38:d2:72:5e:9f:67:93:9a:ec:95:94:a2:0e:bf:41:9e"

      # ref:https://circleci.com/docs/2.0/gh-bb-integration/#establishing-the-authenticity-of-an-ssh-host
      - run:
          name: Avoid hosts unknown for github
          command: |
            mkdir -p ~/.ssh
            echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
                  bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
                  ' >> ~/.ssh/known_hosts

      - run:
          name: Deploy RubyGems
          command: |
            curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
            chmod 0600 ~/.gem/credentials
            git config user.name dodonki1223
            git config user.email $RUBYGEMS_EMAIL
            bundle exec rake build
            bundle exec rake release

  deploy-notification:
    steps:
      - slack/status:
          success_message: ':circleci-pass:Deployment completed to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'
          failure_message: ':circleci-fail:Deployment failed on RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - install-gem
      - save-gem-cache
      - save-workspace

  lint:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-rubocop

  test:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-tests
      - collect-reports

  document:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - create-document

  deploy:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - deploy-rubygems
      - deploy-notification

workflows:
  version: 2.1
  main:
    jobs:
      - setup
      - test:
          requires:
            - setup
      - document:
          requires:
            - setup
      - slack/approval-notification:
          message: ':circleci-pass:Ready to deploy to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME\n When performing a deploy*Approve*Please press'
          requires:
            - lint
            - test
          filters:
            branches:
              only: master
      - approval-job:
          type: approval
          requires:
            - slack/approval-notification
      - deploy:
          requires:
            - approval-job
          filters:
            branches:
              only: master
  #Run tests on a regular basis
  # ref:https://circleci.com/docs/ja/2.0/triggers/
  nightly:
    triggers:
      - schedule:
          cron: "0 22 * * *" #Described in UTC
          filters:
            branches:
              only:
                - master
    jobs:
      - setup
      - test:
          requires:
            - setup

Update contents

Fixed to create executors using next generation image.

Change to cimg

--fixed to use cimg/ruby: 2.6.6

version: 2.1
orbs:
  slack: circleci/[email protected]
executors:
  base:
    docker:
      - image: cimg/ruby:2.6.6
        auth:
          username: dodonki1223
          password: $DOCKERHUB_PASSWORD
        environment:
          #Bundler path settings rewritten`vendor/bundle`Not`/usr/local/bundle`I have referred to`bundle exec`Will result in an error
          #Bundler config file(The one with the path set)Persistent in workspace`vendor/bundle`Settings to refer to
          BUNDLE_APP_CONFIG: .bundle
          # ref: https://circleci.com/docs/2.0/faq/#how-can-i-set-the-timezone-in-docker-images
          TZ: "Asia/Tokyo"
    working_directory: ~/dodonki1223/qiita_trend

November 2020: Introducing Ruby orb

By using Ruby's orb, it is possible to use the command provided by orb for the processing that was implemented by itself, and the description can be simplified.

config.yml

This is config.yml that I sent to orb in Ruby.

08_change_ruby_orb

config.yml
version: 2.1
orbs:
  ruby: circleci/[email protected]
  slack: circleci/[email protected]
executors:
  base:
    docker:
      - image: cimg/ruby:2.6.6
        auth:
          username: dodonki1223
          password: $DOCKERHUB_PASSWORD
        environment:
          #Bundler path settings rewritten`vendor/bundle`Not`/usr/local/bundle`I have referred to`bundle exec`Will result in an error
          #Bundler config file(The one with the path set)Persistent in workspace`vendor/bundle`Settings to refer to
          BUNDLE_APP_CONFIG: .bundle
          # ref: https://circleci.com/docs/2.0/faq/#how-can-i-set-the-timezone-in-docker-images
          TZ: "Asia/Tokyo"
    working_directory: ~/dodonki1223/qiita_trend

commands:
  save-workspace:
    steps:
      - persist_to_workspace:
          # working_Specify a relative or absolute path from directory
          root: .
          paths: .

  using-workspace:
    steps:
      - attach_workspace:
          # working_Specify a relative or absolute path from directory
          at: .

  collect-reports:
    steps:
      - store_artifacts:
          #Coverage the result of coverage-Spit to the results directory
          path: coverage
          destination: coverage-results

  create-document:
    steps:
      - run:
          name: Create document
          command: |
            bundle exec yard
      - store_artifacts:
          #Yard document results-Spit to the results directory
          path: ./doc
          destination: yard-results

  deploy-rubygems:
    steps:
      # https://discuss.circleci.com/t/the-authenticity-of-github-host-cant-be-stablished/Since job does not proceed due to the same phenomenon as 33133, implement it referring to the following article
      # ref:https://circleci.com/docs/ja/2.0/gh-bb-integration/#ssh-%E3%83%9B%E3%82%B9%E3%83%88%E3%81%AE%E4%BF%A1%E9%A0%BC%E6%80%A7%E3%81%AE%E7%A2%BA%E7%AB%8B

      - run:
          name: Avoid hosts unknown for github
          command: |
            mkdir -p ~/.ssh
            echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
                  ' >> ~/.ssh/known_hosts

      - run:
          name: Deploy RubyGems
          command: |
            curl -u dodonki1223:$RUBYGEMS_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
            chmod 0600 ~/.gem/credentials
            git config user.name dodonki1223
            git config user.email $RUBYGEMS_EMAIL
            bundle exec rake build
            bundle exec rake release

  deploy-notification:
    steps:
      - slack/status:
          success_message: ':circleci-pass:Deployment completed to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'
          failure_message: ':circleci-fail:Deployment failed on RubyGems\n:github_octocat: User: $CIRCLE_USERNAME'

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - ruby/install-deps
      - save-workspace

  lint:
    executor: base
    steps:
      - using-workspace
      - ruby/install-deps
      - ruby/rubocop-check

  test:
    executor: base
    steps:
      - using-workspace
      - ruby/install-deps
      - ruby/rspec-test:
          out-path: 'test_results/rspec/'
      - collect-reports

  document:
    executor: base
    steps:
      - using-workspace
      - ruby/install-deps
      - create-document

  deploy:
    executor: base
    steps:
      - using-workspace
      - ruby/install-deps
      - deploy-rubygems
      - deploy-notification

workflows:
  version: 2.1
  main:
    jobs:
      - setup
      - lint:
          requires:
            - setup
      - test:
          requires:
            - setup
      - document:
          requires:
            - setup
      - slack/approval-notification:
          message: ':circleci-pass:Ready to deploy to RubyGems\n:github_octocat: User: $CIRCLE_USERNAME\n When performing a deploy*Approve*Please press'
          requires:
            - lint
            - test
          filters:
            branches:
              only: master
      - approval-job:
          type: approval
          requires:
            - slack/approval-notification
      - deploy:
          requires:
            - approval-job
          filters:
            branches:
              only: master
  #Run tests on a regular basis
  # ref:https://circleci.com/docs/ja/2.0/triggers/
  nightly:
    triggers:
      - schedule:
          cron: "0 22 * * *" #Described in UTC
          filters:
            branches:
              only:
                - master
    jobs:
      - setup
      - test:
          requires:
            - setup

Update contents

Introduction of Ruby orb

--Changed to use circleci/[email protected]

version: 2.1
orbs:
  ruby: circleci/[email protected]

Removed the process equivalent to command defined in orbs

--Removed Bundler installation and gem installation process --Since the following processing is defined in Ruby orb, delete all and change to alternative processing

  install-bundler:
    steps:
      - run:
          name: Install bundler(2.1.0)
          command: gem install bundler:2.1.0

  # Read about caching dependencies: https://circleci.com/docs/2.0/caching/
  restore-gem-cache:
    steps:
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

  install-gem:
    steps:
      - run:
          name: Install gem
          command: |
            # jobs=4 is a setting for parallel processing and speeding up (meaning to execute with 4 jobs)
            bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3

  save-gem-cache:
    steps:
      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

Change the deleted process to Ruby's orb command

--Description before and after changing to orb

Before correction

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - install-bundler
      - restore-gem-cache
      - install-gem
      - save-gem-cache
      - save-workspace

  lint:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-rubocop

  test:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - run-tests
      - collect-reports

  document:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - create-document

  deploy:
    executor: base
    steps:
      - using-workspace
      - install-bundler
      - deploy-rubygems
      - deploy-notification

Revised

jobs:
  setup:
    executor: base
    steps:
      - checkout
      - ruby/install-deps
      - save-workspace

  lint:
    executor: base
    steps:
      - using-workspace
      - ruby/install-deps
      - run-rubocop

  test:
    executor: base
    steps:
      - using-workspace
      - ruby/install-deps
      - run-tests
      - collect-reports

  document:
    executor: base
    steps:
      - using-workspace
      - ruby/install-deps
      - create-document

  deploy:
    executor: base
    steps:
      - using-workspace
      - ruby/install-deps
      - deploy-rubygems
      - deploy-notification

Finally

I have set up and operated CI/CD with CircleCI, but I learned a lot from myself, and I think it was very good to implement it. I personally highly recommend running CircleCI as it is a great learning experience. I would like to continue to operate this configuration file and implement it as soon as the functions I am interested in increase!

Recommended Posts

CircleCI configuration file that has been replaced by the operation of my own library
The function that can be divided and assigned by right assignment of the development version of Ruby 3.0 has been added.
The date time of java8 has been updated
[CircleCI] I will explain the stupid configuration file (config.yml) that I wrote for the first time.