# Gitlab Runner & CI/CD
###### tags: `git` `CI/CD`
## 1. Gitlab Runner Register (PowerShell)
- gitlab-runner.exe 可在 https://docs.gitlab.com/runner/install/windows.html 下載

## 2. 啟動Gitlab Runner
1. 回到cmd,針對exe檔執行install
1. 執行start
1. 到Windows Service 檢查gitlab-runner是否啟動
1. 回到gitlab看是否綠燈


## 3. Gitlab Runner Register (Docker)
1. [安裝Docker](https://www.docker.com/products/docker-desktop)
1. 取得gitlab-runner image
`docerk pull gitlab/gitlab-runner`
1. 建立gitlab-runner config
`docker volume create gitlab-runner-config`
1. 啟動服務並連接到建立的config
`docker run -d --name gitlab-runner --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v gitlab-runner-config:/etc/gitlab-runner \
gitlab/gitlab-runner:latest`
1. 註冊Runner
`docker run --rm -it -v gitlab-runner-config:/etc/gitlab-runner gitlab/gitlab-runner:latest register`
1. 依照上方CMD註冊畫面依序填,須注意Runner executor須改填docker
1. 輸入所要使用的default docker image(非必填),也可以在yml上設定要執行的image
## 4. Gitlab CI/CD
### CI
```yaml=
default:
before_script:
- echo start
stages: #用來告訴pipeline有幾個階段,下方設置並會依照設置執行
- build
- deploy
build site:
image: node:lastest #執行的版本
stage: build #當前階段
variables:
GIT_STRATEGY: clone #設置job獲取程式方式,有clone、fetch、none
script: #執行建置
- npm install --progress=false
- npm run build
artifacts: #建置完後的檔案暫存
expire_in: 1 week #暫存保留時間
paths:
- dist #暫存路徑
tags:
- test3 #指定的runner
```
### CD
依據不同環境造成撰寫方式不同,這邊列出三種方式,heroku、ftp以及push到其他git repo
1. heroku
```yaml=
heroku:
stage: deploy
variables:
GIT_STRATEGY: clone
cache:
key: '$NODE_MODULES_VERSION'
policy: pull
paths:
- node_modules/
only:
- master #只有branch為master時會執行
script:
# install dpl:
- apt-get update -qy #用來取得遠端更新伺服器的套件檔案清單
- apt-get install rubygems ruby-dev -y #下載 rubygems ruby-dev
- gem install dpl #透過 rubygems 安裝dpl(deployment tool)
# deploy to heroku:
- dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_API_KEY --skip_cleanup
tags:
- test3
```
<br />
1. ftp
```yaml=
heroku:
stage: deploy
variables:
GIT_STRATEGY: clone
cache:
key: '$NODE_MODULES_VERSION'
policy: pull
paths:
- node_modules/
only:
- master
script:
- lftp -e "open {ftp_location_url}; user {userName} {password}; #登入ftp
mirror --reverse --verbose dist/ {ftp_folder}; #透過鏡像方式將artifacts dist複製到ftp資料夾
rm -r back; #建置備份
mirror --reverse --verbose dist/ back;
bye"
tags:
- test3
```
<br />
1. push to other repo
```yaml=
deploy:
stage: deploy
variables:
GIT_STRATEGY: clone
only:
- stage
script:
- git remote set-url origin "https://$PUSH_NAME:$PERSONAL_TOKEN@{git_url}/{repo_location}" #切換repo路徑
- git remote -v #確認是否切換
- git fetch
- git checkout master #切換到要更新的分支
- git config --global user.email $PUSH_EMAIL
- git config --global user.name $PUSH_NAME
- git pull --force origin master:master #強拉資料,避免衝突
- rm -rf {file} #移除特定資料,避免dist複製過去後會重複導致失敗
- mv -f dist/* ./ #將dist內的資料移至外層,避免傳上repo後會多包一層資料夾
- git add --all . #將所有異動都stage
- git status
- git commit -m ${CI_COMMIT_SHA:0:8} #這邊以當前commitId作推送名稱
- git push origin master #推至遠端repo,不可使用-f,會被擋下來
tags:
- test3
```