Tiếp theo bài về execute UnitTest giờ thì ta deploy lên STAG / UAT
Giả sử ta có Workflow như sau
- Chạy Code Standards checks
- Rồi Rector để upgrade code structure với PHP 8
- Sau đó chạy UnitTest
- Cuối cùng sẽ deploy lên STAG
- Sau khi merge PR về
develop
sẽ deploy lên UAT
1 chút nhắc lại câu chuyện Parallel
- Nếu chạy Tests mà có tương tác với database thì chỉ nên chạy 1 runner / server
Đầu tiên là build và deploy trên Stag
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
on:
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows
pull_request:
branches: [ develop ]
types: [ opened, synchronize ]
push:
branches: [ develop ]
Action này sẽ được trigger các branches của develop
với 2 types là opened
& synchronize
Note: By default, only the
https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_requestopened
,synchronize
, andreopened
activity types trigger workflows that run on thepull_request
event. To trigger workflows by different activity types, use thetypes
keyword.
Tiếp theo là build & tests
jobs:
build:
name: Code standards check
strategy:
matrix:
lint: [ phpstan, phpmd, rector ]
php: [ php8.0, php8.1 ]
runs-on:
- self-hosted
- ${{ matrix.php }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
# PHP will be installed on server by itself
- name: Setup application
if: success()
run: |
php -r "file_exists('.env') || copy('.env.example', '.env');"
composer install --no-ansi --no-scripts --no-progress --prefer-dist
- name: Lint
run: composer ${{ matrix.lint }}
tests:
name: Execute UnitTest
strategy:
matrix:
test: [ Core, Flickr, Jav ]
runs-on:
- self-hosted
- database
needs: [ build ]
services:
mysql:
image: mariadb:latest
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: xcrawler
ports:
- 3306:3306
redis:
image: redis
ports:
- 6379:6379
mongo:
image: mongo:bionic
options: >-
--health-cmd mongo
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 27017:27017
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup application
if: success()
run: |
php -r "file_exists('.env') || copy('.env.example', '.env');"
composer install --no-ansi --no-scripts --no-progress --prefer-dist
php artisan key:generate
chmod -R 777 storage bootstrap/cache
php artisan config:clear
php artisan migrate:fresh
- name: Execute tests (Unit and Feature tests) via PHPUnit
if: success()
run: |
./vendor/bin/phpunit --testsuite=${{ matrix.test }} --coverage-clover coverage-${{ matrix.test }}.xml
- name: Coverage
uses: actions/upload-artifact@v2
if: success()
with:
name: coverage-reports
path: coverage-${{ matrix.test }}.xml
test_finished:
name: Test Finished
runs-on:
- self-hosted
needs: [ tests ]
steps:
- name: Download build from artifact
uses: actions/download-artifact@v2
if: success()
with:
name: coverage-reports
path: ./reports
- name: Upload coverage to codecov.io
uses: codecov/codecov-action@v1
if: success()
with:
directory: ./reports
- name: Notifications
uses: act10ns/slack@v1.5.0
if: success()
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
with:
status: ${{ job.status }}
config: .github/config/slack.yml
Và đây là khúc quan trọng nhất. Deploy lên stag – dynamic branch. Giả sử mỗi PR ta đều deploy lên độc lập.
deploy_staging:
name: Deploy to Staging
runs-on:
- self-hosted
- staging
needs: [ test_finished ]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Build staging
if: success() && ${{ github.event.pull_request.type}} == 'opened'
run: |
BRANCH_NAME=$(bin/slugified.sh "${{ github.head_ref }}")
rm -rf ~/public_html/xcrawler.dynamic/$BRANCH_NAME
git clone git@github.com:jooservices/XCrawler.git ~/public_html/xcrawler.dynamic/$BRANCH_NAME
cd ~/public_html/xcrawler.dynamic/$BRANCH_NAME
cp ~/.env.xcrawler.staging .env
composer install
php artisan migrate --force
Ở đây còn 1 số bất cập
- Database là hard code từ
env.xcrawler.staging
. Do đó … hờ mất đi ý nghĩa của dynamic . Nên cái này có thể gọi là chỉ 1 staging thôi.
1 lưu ý khác
- Nếu staging server nằm độc lập và không có runner trên đó thì ta cần execute deploy qua SSH. Do staging ở trên nằm cùng server với runner nên tiện chạy
run
luôn - Gọi qua
bin/slugified.sh
để tạo slug từ branch name . - Có thể improve thêm bằng việc gửi Notification nếu đã deployed success hoặc notification khi
test_finished
bị fail .
Leave a Reply