[CircleCI 2.0] Laravel8.15.0で使用する

# 前準備
1. テスト用の.envファイル作成
$ cp .env.example .env.testing

2. .env.testingのAPP_KEY作成
$ php artisan key:generate –env=testing

.env.testing

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=circle_test
DB_USERNAME=hogehoge
DB_PASSWORD=fugafuga

DB_DATABASEは、circle_testする。

3. テストコード作成
$ php artisan make:test UserRegisterTest

4. デフォルトのテストコードは削除
$ rm ./tests/Feature/ExampleTest.php
$ rm ./tests/Unit/ExampleTest.php

tests/Feature/UserRegisterTest.php
L RefreshDatabaseを使用すると、各テスト前後にマイグレーションとロールバックを実行

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class UserRegisterTest extends TestCase
{
    use RefreshDatabase;
    public function testExample()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}

5. UnitTestのテスト
$ vendor/bin/phpunit –testdox
PHPUnit 9.4.3 by Sebastian Bergmann and contributors.

User Register (Tests\Feature\UserRegister)
✔ Example

Time: 00:00.646, Memory: 26.00 MB

OK (1 test, 1 assertion)

6. ユーザ登録のテスト
$ php artisan route:list | grep register
| | GET|HEAD | register | register | Laravel\Fortify\Http\Controllers\RegisteredUserController@create | App\Http\Middleware\EncryptCookies |
| | POST | register | | Laravel\Fortify\Http\Controllers\RegisteredUserController@store | App\Http\Middleware\EncryptCookies |

tests/Feature/UserRegisterTest.php

class UserRegisterTest extends TestCase
{
    use RefreshDatabase;

    public function testUserRegister()
    {
        $email = 'hogehoge@gmail.com';
        $this->post(route('register'), [
            'name' => 'user1',
            'email' => $email,
            'password' => 'password',
            'password_confirmation' => 'password'
        ])
            ->assertStatus(302);

        $this->assertDatabaseHas('users', ['email' => $email]);
    }
}

$ vendor/bin/phpunit –testdox
PHPUnit 9.4.3 by Sebastian Bergmann and contributors.

User Register (Tests\Feature\UserRegister)
✔ User register

Time: 00:00.463, Memory: 28.00 MB

OK (1 test, 2 assertions)

※functionはtestで始まる必要があり、userRegisterだと、No tests found in class “Tests\Feature\UserRegisterTest”となる。

これをCircleCIで行う

# CircleCIでのテスト
1. config/database.php
L circle_testingを追記する

        'circle_test' => [
            'driver' => 'mysql',
            'host' => '127.0.0.1',
            'port' => '3306',
            'database' => 'circle_test',
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

2. GithubでPrivateのrepositoryを作成し、projectをgit pushします。
$ git init
$ git add .
$ git commit -m “first commit”
$ git remote add origin https://github.com/hoge/fuga.git

3. CircleCIにログインしてSetupProject

Add Configボタン押下

This package requires php ^7.3|^8.0 but your PHP version (7.1.33) does not satisfy that requirement.

config.ymlのdocker imageがphp:7.1になってるからエラー。ここを7.3以上に修正する必要がある。
– dockerはphp:7.4.7を、MySQLは8系を使う
https://circleci.com/docs/ja/2.0/circleci-images/
mysql8系から認証方法が変わったので、command: [–default-authentication-plugin=mysql_native_password]を追記

version: 2
jobs:
  build:
    docker:
      - image: circleci/php:7.4.7-apache-node-browsers
      - image: circleci/mysql:8.0
        command: [--default-authentication-plugin=mysql_native_password]
 
    environment:
      - APP_DEBUG: true
      - APP_ENV: testing
      - APP_KEY: base64:hogehogefugafuga
      - DB_CONNECTION: circle_test
      - MYSQL_ALLOW_EMPTY_PASSWORD: true
 
    working_directory: ~/repo
 
    steps:
      - checkout
 
      - run: sudo docker-php-ext-install pdo_mysql
 
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "composer.json" }}
          - v1-dependencies-
 
      - run: composer install -n --prefer-dist
 
      - save_cache:
          paths:
            - ./vendor
          key: v1-dependencies-{{ checksum "composer.json" }}
 
      - run: php artisan migrate
      - run: php artisan db:seed
 
      - run: php ./vendor/bin/phpunit

$ git add .
$ git config –global core.autoCRLF false
$ git commit -m “circleci”
$ git remote add origin https://github.com/hoge/hoge.git
$ git push -u origin master

復習にちょっと時間がかかり過ぎてしまったが、まぁOKでしょう。というか、Djangoで開発するときも、ちゃんとCircleCI使えばよかった。
これを実装していきます。

CircleCIからEC2にデプロイする際にThe authenticity of host ” can’t be establishedが出た時

$ ssh-keygen -m pem
$ cd .ssh
$ ls
authorized_keys config id_rsa id_rsa.pub

id_rsa(秘密鍵)を Circle CI -> PROJECT SETTINGS -> Add SSH Keyに登録
その際、Host NameはインスタンスのIPアドレスを登録する

id_rsa.pub(公開鍵)をEC2 .ssh/authorized_keysに追加

$ git push -u origin master
The authenticity of host ‘************* (*************)’ can’t be established.

config.yml

      - run: ssh -o 'StrictHostKeyChecking no' ${USER_NAME}@${PUBLIC_IP} 'cd /var/www && git pull'
#!/bin/bash -eo pipefail
ssh -o 'StrictHostKeyChecking no' ${USER_NAME}@${PUBLIC_IP} 'cd /var/www && git pull'
Warning: Permanently added '*************' (ECDSA) to the list of known hosts.

fatal: not a git repository (or any of the parent directories): .git

Exited with code exit status 128

あ、エラー内容が変わりました。

$ cd /var/www
$ sudo git clone https://github.com/hoge/circleci.git

config.yml

      - run: ssh -o 'StrictHostKeyChecking no' ${USER_NAME}@${PUBLIC_IP} 'cd /var/www/circleci && git pull'

error: cannot open .git/FETCH_HEAD: Permission denied
$ sudo chmod 777 .git/
$ git remote add origin https://{username}:{password}@github.com/{username}/project.git

error: insufficient permission for adding an object to repository database .git/objects
fatal: failed to write object
fatal: unpack-objects failed

$ sudo chmod 777 objects/

error: cannot lock ref ‘refs/remotes/origin/master’: Unable to create ‘/var/www/circleci/.git/refs/remotes/origin/master.lock’: Permission denied

$ git remote prune origin

There is no tracking information for the current branch.
Please specify which branch you want to merge with.

error: unable to unlink old ‘.circleci/config.yml’: Permission denied
error: unable to unlink old ‘resources/views/home.blade.php’: Permission denied

$ sudo chown -R ec2-user ./

やっといけました。1日かかりました。
他の方は ssh -o ‘StrictHostKeyChecking no’やgitのpermission変更などせずに行けているようなのであまり参考にならないかもしれませんが。

Circle CIでEC2にデプロイ

### 環境
– vagrant Amazon Linux2
– Laravel7.2.1, Mysql8.0

### 前提
– .circleci/config.ymlを配置済み
– git pushすると、phpunitが走る
– これにデプロイのjobを追加したい

公式: https://circleci.com/docs/ja/2.0/deployment-integrations/

公式のソースコード:
-> runコマンドを見るとgit pushでデプロイしていますね。

deploy:
    machine:
        enabled: true
    working_directory: ~/circleci-demo-workflows
    environment:
      HEROKU_APP: "sleepy-refuge-55486"
    steps:
      - checkout
      - run:
          name: Master を Heroku にデプロイ
          command: |
            git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP.git master

workflows:
  version: 2
  build-and-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: sequential-branch-filter

ec2にsshログインしているので、これをconfig.ymlに書いてやってみたいと思います。

ssh ec2-user@{publicIP} -i  ~/.ssh/***.pem

### 1. テスト用のEC2インスタンス作成
– Amazon Linux 2 AMI (HVM), SSD Volume Type 64bit
– t2.nano
– public subnet
– Auto-assign Public IP: enable
– gp2 8GiB
– SecurityGroup: SSH 0.0.0.0/0
– keypair: create | select

->SSHログインテスト
ssh ec2-user@{publicIP} -i ~/.ssh/***.pem

### 2. EC2にGitインストール
// インストール手順は省略
$ git –version
git version 2.19.2

$ cd /var
$ sudo mkdir www

### 3. CircleCI Project setting
CircleCIのコンソールにログインし、対象リポジトリのproject settingのページに遷移
– Environment Variables
KEY: PUBLIC_IP, VALUE: **.***.***.**
KEY: USER_NAME, VALUE: ec2-user

– SSH Permissions
Hostname: 任意
Private Key:秘密鍵の中身

-----BEGIN RSA PRIVATE KEY-----
// 省略
-----END RSA PRIVATE KEY-----

### 4.config.ymlにdeploy追加

version: 2
jobs:
  build:
    // buildは省略
  deploy:
    machine:
      image: circleci/classic:edge
    steps:
      - checkout
      - add_ssh_keys:
      - run: ssh ${USER_NAME}@${PUBLIC_IP} 'cd /var/www && git pull

workflows:
  version: 2
  build_and_deploy:
    jobs:
      - build
      - deploy:
        requires:
          - build
        filters:
          branches:
            only: master

### 5.git push
$ git push -u origin master
$ echo -e “Host github.com\n\tStrictHostKeyChecking no\n” > ~/.ssh/config

#!/bin/bash -eo pipefail
ssh ${USER_NAME}@${PUBLIC_IP} ‘cd /var/www && git pull’
The authenticity of host ‘************* (*************)’ can’t be established.

buildはsuccessだがdeployが何度やってもダメだ。。。丸一日潰れた。

ん?

EC2 インスタンス上で秘密鍵 (pem ファイル) を作成して CircleCI に登録する必要があります。

秘密鍵はec2で作成するの???
あああああああああ

Laravel7.x : Expected status code 200 but received 302.

Circle CIでテスト

There was 1 failure:

1) Tests\Feature\ExampleTest::testBasicTest
Expected status code 200 but received 302.
Failed asserting that false is true.

/home/circleci/repo/vendor/laravel/framework/src/Illuminate/Testing/TestResponse.php:185
/home/circleci/repo/tests/Feature/ExampleTest.php:19

FAILURES!
Tests: 2, Assertions: 2, Failures: 1.

リダイレクト処理で302になっている為。
tests/Feature/ExampleTest.php

    public function testBasicTest()
    {
        $response = $this->get('/');

        // $response->assertStatus(200);
        $response->assertStatus(302);
    }

-> SUCCESS

OK^^

Docker + Laravel7.2 + CircleCIで継続的インテグレーション

### Docker環境の構築
CircleCIを使うにあたって、Dockerで環境を構築する
– nginx:1.13.5-alpine、node:12.13.0-alpine + FROM php:7.3-fpm-alpin、mysql:5.7.19で作成
※docker-compose.yml, Dockerfileの記載は省略

$ sudo docker-compose build
$ sudo docker-compose up -d
$ sudo docker ps
$ sudo docker exec -it app-1 sh

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar create-project –prefer-dist laravel/laravel app
$ php artisan –version
Laravel Framework 7.2.0

$ /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
$ /sbin/mkswap /var/swap.1
$ /sbin/swapon /var/swap.1
$ vi composer.json

"require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.3",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0",
        "laravel/ui" : "^2.0"
   },

$ php composer.phar update
$ php artisan ui vue –auth
$ php artisan migrate
$ npm install
$ npm run dev

$ sudo docker exec -it db-1 bash
$ mysql -u root -p
mysql> use mydb
mysql> show tables;
+—————–+
| Tables_in_mydb |
+—————–+
| failed_jobs |
| migrations |
| password_resets |
| users |
+—————–+
4 rows in set (0.07 sec)

// 動作確認、日本語のレコードが問題なく入るか
http://192.168.33.10/login
http://192.168.33.10/register
mysql> select * from users;

### Circle CI
– CircleCIでLaravelのMySQLを使ったテストを実行する
Experimental CircleCI images for MySQL
> The following is the customizations CircleCI applies in a Dockerfile:

FROM mysql:latest
ENV MYSQL_ALLOW_EMPTY_PASSWORD=true \
    MYSQL_DATABASE=circle_test \
    MYSQL_HOST=127.0.0.1 \
    MYSQL_ROOT_HOST=% \
    MYSQL_USER=root

config/database.php

'connections' => [

        'circle_test' => [
            'driver' => 'mysql',
            'host' => '127.0.0.1',
            'port' => '3306',
            'database' => 'circle_test',
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ], 

docker imageを選択する
-> laravelの環境に合わせてcircleci/php:7.3.9-apache-node-browsersにする
https://circleci.com/docs/ja/2.0/docker-image-tags.json

.circleci/config.yml

version: 2
jobs:
  build:
    docker:
      - image: circleci/php:7.3.9-apache-node-browsers
      - image: circleci/mysql:5.7

    environment:
      - APP_DEBUG: true
      - APP_ENV: testing
      - APP_KEY: base64:62bhVUIMcTWoVIzZm**************
      - DB_CONNECTION: circle_test
      - MYSQL_ALLOW_EMPTY_PASSWORD: true

    working_directory: ~/repo

    steps:
      - checkout

      - run: sudo docker-php-ext-install pdo_mysql

      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "composer.json" }}
          - v1-dependencies-

      - run: composer install -n --prefer-dist

      - save_cache:
          paths:
            - ./vendor
          key: v1-dependencies-{{ checksum "composer.json" }}

      - run: php artisan migrate
      - run: php artisan db:seed

      - run: php ./vendor/bin/phpunit

$ git add .
$ git config –global core.autoCRLF false
$ git commit -m “circleci”
$ git remote add origin https://github.com/hoge/circleci.git
$ git push -u origin master

repositoryをprivateにして再度 git push。
-> success
private repoでもできるのね。

というか、CircleCI自体がDockerのimageを使っているだけで、別にプロジェクト自体はDocker環境だけでなく、Vagrantでも行けそうですね。

touch /.circleci/config.yml

create new folder “.circleci” and new file “config.yml” followed instruction of CircleCI add Projects for target Github repository.

Here is config.yml

# PHP CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-php/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: circleci/php:7.1-browsers
      
      # 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/mysql:9.4

    working_directory: ~/repo

    steps:
      - checkout

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

      - run: composer install -n --prefer-dist

      - save_cache:
          paths:
            - ./vendor
          key: v1-dependencies-{{ checksum "composer.json" }}
        
      # run tests!
      - run: phpunit

Update project file

echo "This is circle ci test3!"

build

Somehow it seems like I understand or do not understand.
Now, we will start to touch Travis CI.

Try using CircleCI

facebook, kickstarter, spotify are using CircleCI.

Aouth CircleCI with Github

CircleCI dashboard

Failed? What!!

let’s watch job detail

Build-agent version 0.1.1480-7a5183d3 (2019-01-22T18:14:45+0000)
Starting container bash:4.4.19
  using image bash@sha256:9f0a4aa3c9931bd5fdda51b1b2b74a0398a8eabeaf9519d807e010b9d9d41993

Using build environment variables:
  BASH_ENV=/tmp/.bash_env-5c486cf91773df0008cbcc61-0-build
  CI=true
  CIRCLECI=true
  CIRCLE_BRANCH=master
  CIRCLE_BUILD_NUM=2
  CIRCLE_BUILD_URL=https://circleci.com/gh/githubix/test/2
  CIRCLE_COMPARE_URL=
  CIRCLE_JOB=Build Error
  CIRCLE_NODE_INDEX=0
  CIRCLE_NODE_TOTAL=1
  CIRCLE_PREVIOUS_BUILD_NUM=1
  CIRCLE_PROJECT_REPONAME=test
  CIRCLE_PROJECT_USERNAME=githubix
  CIRCLE_REPOSITORY_URL=git@github.com:githubix/test.git
  CIRCLE_SHA1=faed9c8c981615655d296d6137e3abdb9dddfc0d
  CIRCLE_SHELL_ENV=/tmp/.bash_env-5c486cf91773df0008cbcc61-0-build
  CIRCLE_STAGE=Build Error
  CIRCLE_USERNAME=githubix
  CIRCLE_WORKFLOW_ID=bd789861-e6e6-428d-877a-888ff642a15c
  CIRCLE_WORKFLOW_JOB_ID=23b817b9-9ef5-4bcc-861e-93fddfe7e6c7
  CIRCLE_WORKFLOW_UPSTREAM_JOB_IDS=
  CIRCLE_WORKFLOW_WORKSPACE_ID=bd789861-e6e6-428d-877a-888ff642a15c
  CIRCLE_WORKING_DIRECTORY=~/project
#!/bin/sh -eo pipefail
# No configuration was found in your project. Please refer to https://circleci.com/docs/2.0/ to get started with your configuration.
# 
# -------
# Warning: This configuration was auto-generated to show you the message above.
# Don't rerun this job. Rerunning will have no effect.
false

It is said “No configuration was found in your project”

Oh, understood the issue that do I need to create yml file??

How to use Circle CI?

CicleCI is CI service.
https://circleci.com/

By registering from the above page, we can automatically build, test, and deploy like Jenkins.

Jenkins needs to set up a Jenkins server on its own, but since CircleCI is a service that can be used only by registering.

Features
– It is a CI service
– Can cooperate with GitHub
– Run the build in the container under the concept of container
– Free for one container use (billing is required for multiple use)

Concept of Container
Although it is not limited to CircleCI, the CI tool has the concept of “Container”

Features
– As the name implies “box/container” image
– Run build, test and deploy in the container
– As the number of containers increases, the speed increases as it can be executed in parallel. However, CircleCI will be charged for using more than two containers.

When executing two or more builds, waiting time occurs because only one can be executed even when we run a lot of test, it can take time only because it can only be executed in series.