使用GitHub Actions實(shí)現(xiàn)前端自動(dòng)化打包、部署

一秀又、前言

作為一名前端菜雞单寂,服務(wù)器小白,剛開始在Linux服務(wù)器上部署網(wǎng)站時(shí)吐辙,前端代碼我一般都是打包后手動(dòng)FTP傳上去宣决,后端代碼直接在vscode中使用SSH連接服務(wù)器,直接同步代碼更改昏苏。

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

二洼专、準(zhǔn)備工作

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

實(shí)現(xiàn)代碼提交的自動(dòng)化工作流孵构,要依靠持續(xù)集成(CI)(或者加上持續(xù)交付(CD))服務(wù)∑ㄉ蹋現(xiàn)在主流的公用免費(fèi)的持續(xù)集成服務(wù)有:

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

其中GitHub Actions是GitHub自家的持續(xù)集成及自動(dòng)化工作流服務(wù),簡(jiǎn)單易用颈墅,也是小黑本次使用的服務(wù)棒假。它使用起來(lái)非常簡(jiǎn)單,只要在你的倉(cāng)庫(kù)根目錄建立.github/workflows文件夾精盅,將你的工作流配置(YAML文件)放到這個(gè)目錄下帽哑,就能啟用GitHub Actions服務(wù)。

小黑的網(wǎng)站是部署到騰訊云服務(wù)器上的叹俏,所以配置過(guò)程中用到了服務(wù)器相關(guān)配置妻枕,如果是想把網(wǎng)站放到GitHub Pages上,那只需要有個(gè)Github倉(cāng)庫(kù)就可以開始折騰起來(lái)了,下文關(guān)于遠(yuǎn)程服務(wù)器的配置可以忽略掉屡谐。

2述么、添加部署秘鑰

要把文件部署到遠(yuǎn)程服務(wù)器,首先要解決登錄校驗(yàn)的問(wèn)題愕掏。
比較常見的就是密碼登錄度秘、SSH密鑰登錄或者VNC登錄。小黑推薦使用SSH密鑰登錄饵撑,既方便有安全剑梳。

2.1、生成SSH密鑰對(duì)

相信需要遠(yuǎn)程部署到服務(wù)器的小伙伴肯定早就把SSH密鑰對(duì)配置好了滑潘,所以我們可以直接對(duì)應(yīng)的私鑰文件內(nèi)容復(fù)制一下垢乙,等下在GitHub中進(jìn)行配置就可以啦!這里小黑就不再贅述啦

2.2语卤、GitHub填寫自動(dòng)化配置項(xiàng)

SSH密鑰對(duì)生成后追逮,其實(shí)準(zhǔn)備工作就已經(jīng)完成的差不多了,最后一步就是將YAML文件中所需要的配置項(xiàng)粹舵,配置到Github上
首先打開對(duì)應(yīng)的倉(cāng)庫(kù)钮孵,點(diǎn)擊Setting > Secrets > New sceret,然后將我們復(fù)制的密鑰文件內(nèi)容、服務(wù)器host和登錄用戶名都添加到配置如下圖對(duì)應(yīng)的配置中眼滤,這樣的話即使像小黑一樣把項(xiàng)目開源巴席,隱私信息也不會(huì)泄露啦。

20200927-161538-0487.png

配置完上面這些柠偶,我們的準(zhǔn)備工作就大功告成了,接下來(lái)就可以編寫工作流文件啦

三睬关、配置過(guò)程

1诱担、編寫工作流文件

在倉(cāng)庫(kù)根目錄中創(chuàng)建.github/workflows文件夾,再創(chuàng)建一個(gè)YAML文件电爹,文件名自定蔫仙,我這里起名叫deploy.yml,所以文件的完整路徑應(yīng)該為.github/workflows/deploy.yml丐箩,配置的意義寫在注釋中啦摇邦,當(dāng)然小黑也會(huì)簡(jiǎn)略的介紹下重點(diǎn)配置項(xiàng)

1.1、文件基礎(chǔ)配置

首先就是YAML文件比較基礎(chǔ)的配置

on里的內(nèi)容比較重要屎勘,指定自動(dòng)觸發(fā)工作流文件的事件施籍,也可以將工作流設(shè)置為只在某些分支、路徑或標(biāo)記上運(yùn)行概漱。比如小黑就是在當(dāng)master分支上進(jìn)行push時(shí)才會(huì)觸發(fā),然后忽略掉README.mdLICENSE文件的變更

jobs里就是接下來(lái)所要運(yùn)行的所有工作流程丑慎,小黑就設(shè)置了build-production這一個(gè)job,根據(jù)需要也可以設(shè)置多個(gè)

還有就是runs-on,小黑第一次還以為是要填寫自己云服務(wù)器的操作系統(tǒng),就填了個(gè)centos,一跑就報(bào)錯(cuò)竿裂,后來(lái)看了文檔才明白玉吁,這是配置用來(lái)運(yùn)行job的GitHub托管的新虛擬機(jī),和你所使用的操作系統(tǒng)及服務(wù)器系統(tǒng)無(wú)關(guān)腻异,和小黑一樣配置為ubuntu-latest就行

strategy中的node-version可以不配置,為了和本地node版本統(tǒng)一进副,小黑配置了一下

steps里就是所需要運(yùn)行的每一個(gè)具體的步驟啦,下面就讓小黑一一道來(lái)

name: Blog CI/CD

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

jobs:
  build-production:

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

1.2影斑、下載代碼

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

    - uses: actions/checkout@v2   # 第一步这嚣,檢出倉(cāng)庫(kù)副本

1.3鸥昏、配置node版本(可選)

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

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

1.4吏垮、安裝依賴

這一步就不用解釋了吧

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

1.5罐旗、打包代碼

這里小黑用了--if-present標(biāo)志來(lái)避免腳本未定義時(shí)出現(xiàn)非零退出的情況膳汪,親測(cè)在目前項(xiàng)目中寫不寫都行九秀,不必糾結(jié)

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

在部署服務(wù)器時(shí)小黑踩到了很大的坑,就是明明打包完成了鼓蜒,但就是不結(jié)束任務(wù)痹换,進(jìn)入下一步

20200927-175017-0477.png

都帶薪如廁回來(lái)了竟然還沒(méi)有完成Build任務(wù),這樣小黑都沒(méi)有煩躁也是多虧了和產(chǎn)品相愛相殺的磨練

換成yarn打包?失敗+1
修改node版本都弹?失敗+2
……娇豫??畅厢?冯痢??框杜?浦楣?失敗+N

是可忍叔不可忍,叔可忍他嬸子也不可忍了!
這是要逼小黑使出大殺招了!
面對(duì)疾風(fēng)吧咪辱!

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

最后振劳,在祭出三根寶貴的頭發(fā)之后,終于讓小黑找到了問(wèn)題所在

我變禿了油狂,也變強(qiáng)了澎迎! ——— 小黑

特么的竟然是打包后Node.js進(jìn)程沒(méi)有終止庐杨,平時(shí)直接手動(dòng)Ctrl + C就順便關(guān)了,根本沒(méi)注意到這個(gè)問(wèn)題夹供!

暴風(fēng)哭泣~

20200927-171341-0496.png

這時(shí)問(wèn)題又來(lái)了灵份,作為國(guó)服最菜前端,這webpack咱也只會(huì)個(gè)皮毛哮洽,觀察模式也并沒(méi)有開啟呀填渠,百度谷歌一頓搜,文檔咱也看了又看鸟辅,分析來(lái)分析去氛什,也不曉得是哪個(gè)在占用Node.js進(jìn)程,索性快刀斬亂麻匪凉,一行process.exit(0);直接亂殺枪眉!

20200927-171341-0497.png

push一下試試,果然Build任務(wù)成功完成再层,我特么真是個(gè)天才贸铜,獎(jiǎng)勵(lì)自己美味飼料一斤!

1.6聂受、推送部署到服務(wù)器

打包成功蒿秦,接下來(lái)就是激動(dòng)人心的部署到服務(wù)器環(huán)節(jié)了,我們這里依然使用別人造好的輪子

DEPLOY_KEY蛋济、SERVER_IP棍鳖、USERNAME就是我們剛開始在Github里配置好SSH私鑰、主機(jī)名碗旅、登錄名渡处,這里就不再贅述

主要需要留意的就是FOLDER、和SERVER_DESTINATION祟辟,也就是我們的推送文件夾及目標(biāo)文件夾医瘫,這里一定要將路徑寫正確。

源碼地址: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參數(shù)茫孔,排除.pyc文件
        SERVER_PORT: '22'  # SSH端口
        FOLDER: ./build/*  # 要推送的文件夾叮喳,路徑相對(duì)于代碼倉(cāng)庫(kù)的根目錄
        SERVER_IP: ${{ secrets.SSH_HOST }}  # 引用配置,服務(wù)器的host名(IP或者域名domain.com)
        USERNAME: ${{ secrets.SSH_USERNAME }}  # 引用配置缰贝,服務(wù)器登錄名
        SERVER_DESTINATION: /www/wwwroot/lmsworld.cn/   # 部署到目標(biāo)文件夾

我這里是直接將build文件夾內(nèi)文件替換到網(wǎng)站根目錄的馍悟,會(huì)存在非同名文件無(wú)法替換的情況,本來(lái)打算先刪除網(wǎng)站根目錄文件夾再替換的剩晴,但考慮到會(huì)有打包失敗或者部署失敗的可能性锣咒,刪除后網(wǎng)站會(huì)無(wú)法訪問(wèn)侵状,遂暫時(shí)不用此方法,后續(xù)有時(shí)間再繼續(xù)改進(jìn)毅整,寫在此處還是希望大佬們多多指點(diǎn)迷津~

1.7趣兄、重啟服務(wù)(視情況而定)

如果是僅僅是部署了前端代碼的話,那有可能就不用重啟服務(wù)了悼嫉,如果要后端代碼的話艇潭,就要重新啟動(dòng)服務(wù)了
可以在YAML配置文件里另加一個(gè)后端部署的job,使用need控制下工作流戏蔑,然后就在script里依次寫下服務(wù)器上運(yùn)行的命令行即可蹋凝,小黑是用node寫的后臺(tái),僅供參考

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

1.8情龄、完整配置文件

貼一下完整的配置文件迄汛,根據(jù)自己的項(xiàng)目情況修改下配置就行,不能用的話可以給小黑留言

name: Blog CI/CD

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

jobs:
  build-production:

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

    - name: Use Node.js ${{ matrix.node-version }} #規(guī)定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參數(shù)唯卖,排除.pyc文件
        SERVER_PORT: '22'  # SSH端口
        FOLDER: ./build/*  # 要推送的文件夾,路徑相對(duì)于代碼倉(cāng)庫(kù)的根目錄
        SERVER_IP: ${{ secrets.SSH_HOST }}  # 引用配置躬柬,服務(wù)器的host名(IP或者域名domain.com)
        USERNAME: ${{ secrets.SSH_USERNAME }}  # 引用配置拜轨,服務(wù)器登錄名
        SERVER_DESTINATION: /www/wwwroot/lmsworld.cn/   # 部署到目標(biāo)文件夾

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

2、最終效果

小黑迫不及待的將配置文件修改后push到倉(cāng)庫(kù)颠锉,這次工作流跑的行云流水法牲,啥錯(cuò)都沒(méi)報(bào),簡(jiǎn)直完美琼掠!

在這個(gè)面板里你可以看到具體每一步任務(wù)的耗時(shí)與輸出信息拒垃,報(bào)錯(cuò)信息也可在這里查詢哦

20200928-102853-0494.png

最后如果你是部署到騰訊云、阿里云等云服務(wù)平臺(tái)的話瓷蛙,一般會(huì)收到一條安全警告通知悼瓮,比如小黑用的就是騰訊云

20200928-114201-0477.png

存在來(lái)自ip:40.122.43.158的異常登錄戈毒,這ip是誰(shuí)的,讓小黑查一下
20200928-110204-0490.png

Microsoft數(shù)據(jù)中心横堡?應(yīng)該就是github服務(wù)器的ip了埋市,問(wèn)題不大,這里就先不管他了命贴,后續(xù)咱們?cè)僬曳椒ń鉀Q它

四恐疲、待優(yōu)化部分

小黑最近工作太忙,只是先簡(jiǎn)單實(shí)現(xiàn)了自動(dòng)化部署功能套么,但是還沒(méi)來(lái)得及進(jìn)行優(yōu)化培己,先留個(gè)坑,后續(xù)再更

1胚泌、緩存依賴加快工作流

GitHub文檔-緩存的依賴關(guān)系

2省咨、COS 優(yōu)化部署

GitHub Actions + COS 優(yōu)化部署

五、參考

由于小黑見識(shí)淺薄玷室、水平有限零蓉,所寫內(nèi)容肯定有很多不足之處,還請(qǐng)各位大佬不吝賜教穷缤,十分感激敌蜂!

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

1、GitHub Actions文檔
2身坐、How to deploy a create-react-app with github-actions
3秸脱、使用 GitHub Actions 實(shí)現(xiàn)博客自動(dòng)化部署

本篇文章由一文多發(fā)平臺(tái)ArtiPub自動(dòng)發(fā)布

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市部蛇,隨后出現(xiàn)的幾起案子摊唇,更是在濱河造成了極大的恐慌,老刑警劉巖涯鲁,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巷查,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡抹腿,警方通過(guò)查閱死者的電腦和手機(jī)岛请,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)幢踏,“玉大人髓需,你說(shuō)我怎么就攤上這事许师》坎酰” “怎么了僚匆?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)搭幻。 經(jīng)常有香客問(wèn)我咧擂,道長(zhǎng),這世上最難降的妖魔是什么檀蹋? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任松申,我火速辦了婚禮,結(jié)果婚禮上俯逾,老公的妹妹穿的比我還像新娘贸桶。我一直安慰自己,他們只是感情好桌肴,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布皇筛。 她就那樣靜靜地躺著,像睡著了一般坠七。 火紅的嫁衣襯著肌膚如雪水醋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天彪置,我揣著相機(jī)與錄音拄踪,去河邊找鬼。 笑死拳魁,一個(gè)胖子當(dāng)著我的面吹牛惶桐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播潘懊,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼耀盗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了卦尊?” 一聲冷哼從身側(cè)響起叛拷,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岂却,沒(méi)想到半個(gè)月后忿薇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡躏哩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年署浩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扫尺。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡筋栋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出正驻,到底是詐尸還是另有隱情弊攘,我是刑警寧澤抢腐,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站襟交,受9級(jí)特大地震影響迈倍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捣域,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一啼染、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧焕梅,春花似錦迹鹅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蜗字,卻和暖如春打肝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挪捕。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工粗梭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人级零。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓断医,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親奏纪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鉴嗤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361