昨天手動把專案部屬好了,接下來我想要幫專案加上自動化流程,讓每次的異動都能跑過測試並佈署到fly.io,因為專案放在github上,理所當然的選擇了github action作為CICD工具,預計每次都會執行下面的pipline:
目前最容易找到的action-rs
已經不再維護,不建議使用,但是Github提供的actions runner本身就安裝了rust工具鏈,如果真的有需求的話推薦使用這個。
詳細的pipline可以參考repo中的設定,以下只針對其中幾個步驟進行說明
unit-test:
name: run unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: |
target
key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}
- name: run test
run: cargo test --verbose
rust的編譯時須檢查相關依賴套件是否已經編譯過,如果沒有的話需要重新下載一次,這個步驟在Github上極為緩慢,所以我們可以使用Cache的機制加速。編譯時期的依賴套件會放在target資料夾中,這也就是我們快取的目標。Cargo.lock
是用來鎖定套件版本依賴的文件,每次編譯成功會鎖住當時的依賴。這時就會有一個問題,Cargo.lock檔案是否要被加入gitignore中,這點要依專案性質而定,如果是應用端的專案會不建議加入,如果是單純的函式庫,編譯時會取決於使用函式庫的應用端,就建議加入gitignore中。
prepare-test-db:
name: prepare test database
runs-on: ubuntu-latest
env:
FLY_API_TOKEN: ${{ secrets.FLY_POSTGRES_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL_INTERGRATION_TEST }}
steps:
- uses: actions/checkout@v3
- uses: superfly/flyctl-actions/setup-flyctl@master
- uses: actions/cache@v3
with:
path: |
migration/target
key: ${{ runner.os }}-sea-orm-migration-${{ hashFiles('**migration/Cargo.lock') }}
- name: set fly-postgres proxy
run: nohup flyctl proxy 5432 -a marvinhsu-postgres &
- name: reset test database
run: |
cd migration
cargo run fresh
因為使用seaORM的工具進行資料庫版本管理,所以就可以將遷移專案用來準備整合測試用的資料庫。因為這時候測試是使用github action的runner進行,為了能夠連線到資料庫就需要使用fly.io的代理機制建立連線,最後使用cargo run fresh
,就相當於在本機使用sea-orm-cli migrate fresh
。
因為有撰寫整合測試,自然要通過才能進行部屬:
pytest:
name: run intregation tests
needs: [build,prepare-test-db]
runs-on: ubuntu-latest
env:
FLY_API_TOKEN: ${{ secrets.FLY_POSTGRES_TOKEN }}
DATABASE_URL: ${{ secrets.DATABASE_URL_INTERGRATION_TEST }}
steps:
- uses: actions/checkout@v3
- name: Install Poetry
uses: snok/install-poetry@v1
- uses: actions/cache@v3
with:
path: ~/.cache/pypoetry
key: ${{ runner.os }}-poetry-${{ hashFiles('**/pyproject.toml') }}
- name: Install pytest and requests
run: poetry install
- uses: superfly/flyctl-actions/setup-flyctl@master
- uses: actions/download-artifact@v3
with:
name: zero_to_production.tar
- name: load docker image
run: docker load -i zero_to_production.tar
- name: set fly-postgres proxy
run: nohup flyctl proxy 5432 -a marvinhsu-postgres &
- name: run image
run: |
docker run \
-e APP__ENVIRONMENT=test \
-e APP__DATABASE__PASSWORD=${{ secrets.DATABASE_PASSWORD_INTERGRATION_TEST }} \
--network host \
-d zero_to_production
- name: Run tests
run: poetry run pytest
整合測試的步驟較為複雜,因為使用poetry管理環境,官方的image並不支援就需要自行安裝,另外要對測試專安的相依性進行還原。為了減少建置時間將docker image在第一步的時候就先輸出成.tar
,所以在進行整合測試時要先載入。這邊有個小技巧,因為測試用的資料庫需要透過fly的代理才能夠連線,而專案又被包在docker中,所以在運行容器的時候需要對網路做一些調整才能使用,這邊為了求方便,而且只是測試使用,所以我直接開啟了host network模式來共享主機的5432port。
接下來遷移production環境資料庫與佈署的部份與前面的步驟大同小異,就不贅述了。