使用GitHub Actions實現前端自動化打包、部署

一、前言

作為一名前端菜雞,服務器小白,剛開始在Linux服務器上部署網站時,前端代碼我一般都是打包后手動FTP傳上去,后端代碼直接在vscode中使用SSH連接服務器,直接同步代碼更改。

但小黑作為一個生命不息折騰不止的程序猿,肯定要探索更好玩更高效的方法,所以這次,咱就上手折騰了下自動化部署方案

二、準備工作

1、持續集成服務(CI)方案選擇

實現代碼提交的自動化工作流,要依靠持續集成(CI)(或者加上持續交付(CD))服務。現在主流的公用免費的持續集成服務有:

  • Travis CI
  • Jenkins
  • Circle CI
  • Azure Pipeline
  • GitHub Actions

其中GitHub Actions是GitHub自家的持續集成及自動化工作流服務,簡單易用,也是小黑本次使用的服務。它使用起來非常簡單,只要在你的倉庫根目錄建立.github/workflows文件夾,將你的工作流配置(YAML文件)放到這個目錄下,就能啟用GitHub Actions服務。

小黑的網站是部署到騰訊云服務器上的,所以配置過程中用到了服務器相關配置,如果是想把網站放到GitHub Pages上,那只需要有個Github倉庫就可以開始折騰起來了,下文關于遠程服務器的配置可以忽略掉。

2、添加部署秘鑰

要把文件部署到遠程服務器,首先要解決登錄校驗的問題。
比較常見的就是密碼登錄、SSH密鑰登錄或者VNC登錄。小黑推薦使用SSH密鑰登錄,既方便有安全。

2.1、生成SSH密鑰對

相信需要遠程部署到服務器的小伙伴肯定早就把SSH密鑰對配置好了,所以我們可以直接對應的私鑰文件內容復制一下,等下在GitHub中進行配置就可以啦!這里小黑就不再贅述啦

2.2、GitHub填寫自動化配置項

SSH密鑰對生成后,其實準備工作就已經完成的差不多了,最后一步就是將YAML文件中所需要的配置項,配置到Github上
首先打開對應的倉庫,點擊Setting > Secrets > New sceret,然后將我們復制的密鑰文件內容、服務器host和登錄用戶名都添加到配置如下圖對應的配置中,這樣的話即使像小黑一樣把項目開源,隱私信息也不會泄露啦。

20200927-161538-0487.png

配置完上面這些,我們的準備工作就大功告成了,接下來就可以編寫工作流文件啦

三、配置過程

1、編寫工作流文件

在倉庫根目錄中創建.github/workflows文件夾,再創建一個YAML文件,文件名自定,我這里起名叫deploy.yml,所以文件的完整路徑應該為.github/workflows/deploy.yml,配置的意義寫在注釋中啦,當然小黑也會簡略的介紹下重點配置項

1.1、文件基礎配置

首先就是YAML文件比較基礎的配置

on里的內容比較重要,指定自動觸發工作流文件的事件,也可以將工作流設置為只在某些分支、路徑或標記上運行。比如小黑就是在當master分支上進行push時才會觸發,然后忽略掉README.mdLICENSE文件的變更

jobs里就是接下來所要運行的所有工作流程,小黑就設置了build-production這一個job,根據需要也可以設置多個

還有就是runs-on,小黑第一次還以為是要填寫自己云服務器的操作系統,就填了個centos,一跑就報錯,后來看了文檔才明白,這是配置用來運行job的GitHub托管的新虛擬機,和你所使用的操作系統及服務器系統無關,和小黑一樣配置為ubuntu-latest就行

strategy中的node-version可以不配置,為了和本地node版本統一,小黑配置了一下

steps里就是所需要運行的每一個具體的步驟啦,下面就讓小黑一一道來

name: Blog CI/CD

on:
  push:
    branches:
      - master  # 只在master上push觸發部署
    paths-ignore:   # 下列文件的變更不觸發部署,可以自行添加
      - README.md
      - LICENSE

jobs:
  build-production:

    runs-on: ubuntu-latest   # 使用ubuntu系統鏡像運行自動化腳本(溫馨提示:和你所使用的操作系統及服務器系統無關,我本地用的windows10,云服務器用的centos)
    strategy: (可選)
      matrix:
        node-version: [12.x] # 配置所需node版本
    steps:  # 自動化步驟
    ……

1.2、下載代碼

這一步就是檢出你的倉庫并下載里面的代碼到runner中,actions/checkout@v2是官方自己造的輪子,直接拿來用就行

    - uses: actions/checkout@v2   # 第一步,檢出倉庫副本

1.3、配置node版本(可選)

這一步就是安裝node,輪子也是官方的,版本可以選填,使用npm進行打包(不需要打包的項目可以省略1.3——1.5了)

    - name: Use Node.js ${{ matrix.node-version }} 
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }} #規定node.js版本(可不配置)

1.4、安裝依賴

這一步就不用解釋了吧

    - name: Install dependencies  # 第二步,安裝依賴
      run: npm install

1.5、打包代碼

這里小黑用了--if-present標志來避免腳本未定義時出現非零退出的情況,親測在目前項目中寫不寫都行,不必糾結

    - name: Build              # 第三步,打包代碼
      run: npm run build --if-present

在部署服務器時小黑踩到了很大的坑,就是明明打包完成了,但就是不結束任務,進入下一步

20200927-175017-0477.png

都帶薪如廁回來了竟然還沒有完成Build任務,這樣小黑都沒有煩躁也是多虧了和產品相愛相殺的磨練

換成yarn打包?失敗+1
修改node版本?失敗+2
……???????失敗+N

是可忍叔不可忍,叔可忍他嬸子也不可忍了!
這是要逼小黑使出大殺招了!
面對疾風吧!

…%…¥@*(¥@(*)
看我一頓操作猛如虎~

最后,在祭出三根寶貴的頭發之后,終于讓小黑找到了問題所在

我變禿了,也變強了! ——— 小黑

特么的竟然是打包后Node.js進程沒有終止,平時直接手動Ctrl + C就順便關了,根本沒注意到這個問題!

暴風哭泣~

20200927-171341-0496.png

這時問題又來了,作為國服最菜前端,這webpack咱也只會個皮毛,觀察模式也并沒有開啟呀,百度谷歌一頓搜,文檔咱也看了又看,分析來分析去,也不曉得是哪個在占用Node.js進程,索性快刀斬亂麻,一行process.exit(0);直接亂殺!

20200927-171341-0497.png

push一下試試,果然Build任務成功完成,我特么真是個天才,獎勵自己美味飼料一斤!

1.6、推送部署到服務器

打包成功,接下來就是激動人心的部署到服務器環節了,我們這里依然使用別人造好的輪子

DEPLOY_KEYSERVER_IPUSERNAME就是我們剛開始在Github里配置好SSH私鑰、主機名、登錄名,這里就不再贅述

主要需要留意的就是FOLDER、和SERVER_DESTINATION,也就是我們的推送文件夾及目標文件夾,這里一定要將路徑寫正確。

源碼地址:rsync-deploy

    - name: Deploy to Server  # 第四步,rsync推送文件
      uses: AEnterprise/rsync-deploy@v1.0  # 使用別人包裝好的步驟鏡像
      env:
        DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}   # 引用配置,SSH私鑰
        ARGS: -avz --delete --exclude='*.pyc'   # rsync參數,排除.pyc文件
        SERVER_PORT: '22'  # SSH端口
        FOLDER: ./build/*  # 要推送的文件夾,路徑相對于代碼倉庫的根目錄
        SERVER_IP: ${{ secrets.SSH_HOST }}  # 引用配置,服務器的host名(IP或者域名domain.com)
        USERNAME: ${{ secrets.SSH_USERNAME }}  # 引用配置,服務器登錄名
        SERVER_DESTINATION: /www/wwwroot/lmsworld.cn/   # 部署到目標文件夾

我這里是直接將build文件夾內文件替換到網站根目錄的,會存在非同名文件無法替換的情況,本來打算先刪除網站根目錄文件夾再替換的,但考慮到會有打包失敗或者部署失敗的可能性,刪除后網站會無法訪問,遂暫時不用此方法,后續有時間再繼續改進,寫在此處還是希望大佬們多多指點迷津~

1.7、重啟服務(視情況而定)

如果是僅僅是部署了前端代碼的話,那有可能就不用重啟服務了,如果要后端代碼的話,就要重新啟動服務了
可以在YAML配置文件里另加一個后端部署的job,使用need控制下工作流,然后就在script里依次寫下服務器上運行的命令行即可,小黑是用node寫的后臺,僅供參考

    - name: Restart server   # 第五步,重啟服務
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.SSH_HOST }}  # 下面三個配置與上一步類似
        username: ${{ secrets.SSH_USERNAME }}
        key: ${{ secrets.DEPLOY_KEY }}
        # 重啟的腳本,根據自身情況做相應改動,一般要做的是migrate數據庫以及重啟服務器
        script: |
          cd /www/server/web-server/
          pm2 reload app.js

1.8、完整配置文件

貼一下完整的配置文件,根據自己的項目情況修改下配置就行,不能用的話可以給小黑留言

name: Blog CI/CD

on:
  push:
    branches:
      - master  # 只在master上push觸發部署
    paths-ignore:   # 下列文件的變更不觸發部署,可以自行添加
      - README.md
      - LICENSE

jobs:
  build-production:

    runs-on: ubuntu-latest   # 使用ubuntu系統鏡像運行自動化腳本(溫馨提示:和你所使用的操作系統及服務器系統無關,我本地用的windows10,云服務器用的centos)
    strategy:
      matrix:
        node-version: [12.x] # 配置所需node版本
    steps:  # 自動化步驟
    - uses: actions/checkout@v2   # 第一步,檢出倉庫副本

    - name: Use Node.js ${{ matrix.node-version }} #規定node.js版本(可不配置)
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}

    - name: Install dependencies  # 第二步,安裝依賴
      run: npm install

    - name: Build                 # 第三步,打包代碼
      run: npm run build --if-present

    - name: Deploy to Server      # 第四步,rsync推送文件
      uses: AEnterprise/rsync-deploy@v1.0  # 使用別人包裝好的步驟鏡像
      env:
        DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}   # 引用配置,SSH私鑰
        ARGS: -avz --delete --exclude='*.pyc'   # rsync參數,排除.pyc文件
        SERVER_PORT: '22'  # SSH端口
        FOLDER: ./build/*  # 要推送的文件夾,路徑相對于代碼倉庫的根目錄
        SERVER_IP: ${{ secrets.SSH_HOST }}  # 引用配置,服務器的host名(IP或者域名domain.com)
        USERNAME: ${{ secrets.SSH_USERNAME }}  # 引用配置,服務器登錄名
        SERVER_DESTINATION: /www/wwwroot/lmsworld.cn/   # 部署到目標文件夾

    # - name: Restart server   # 第五步,重啟服務
    #   uses: appleboy/ssh-action@master
    #   with:
    #     host: ${{ secrets.SSH_HOST }}  # 下面三個配置與上一步類似
    #     username: ${{ secrets.SSH_USERNAME }}
    #     key: ${{ secrets.DEPLOY_KEY }}
    #     # 重啟的腳本,根據自身情況做相應改動,一般要做的是migrate數據庫以及重啟服務器
    #     script: |
    #       cd /www/server/web-server/
    #       pm2 reload app.js

2、最終效果

小黑迫不及待的將配置文件修改后push到倉庫,這次工作流跑的行云流水,啥錯都沒報,簡直完美!

在這個面板里你可以看到具體每一步任務的耗時與輸出信息,報錯信息也可在這里查詢哦

20200928-102853-0494.png

最后如果你是部署到騰訊云、阿里云等云服務平臺的話,一般會收到一條安全警告通知,比如小黑用的就是騰訊云

20200928-114201-0477.png

存在來自ip:40.122.43.158的異常登錄,這ip是誰的,讓小黑查一下
20200928-110204-0490.png

Microsoft數據中心?應該就是github服務器的ip了,問題不大,這里就先不管他了,后續咱們再找方法解決它

四、待優化部分

小黑最近工作太忙,只是先簡單實現了自動化部署功能,但是還沒來得及進行優化,先留個坑,后續再更

1、緩存依賴加快工作流

GitHub文檔-緩存的依賴關系

2、COS 優化部署

GitHub Actions + COS 優化部署

五、參考

由于小黑見識淺薄、水平有限,所寫內容肯定有很多不足之處,還請各位大佬不吝賜教,十分感激!

以下文檔、博客給了小黑極大的幫助,在此表示炒雞感謝!

1、GitHub Actions文檔
2、How to deploy a create-react-app with github-actions
3、使用 GitHub Actions 實現博客自動化部署

本篇文章由一文多發平臺ArtiPub自動發布

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370