基于electron開發(fā)輕量級自動部署工具-部署狗

部署狗

  • 適用與個人與小團(tuán)隊的輕量級自動部署工具
  • 基于electron+vue+element開發(fā)
  • github

技術(shù)棧

  • electron-vue

開發(fā)

$ npm install
$ npm run dev

先來一波圖

項目管理

avatar

添加項目

avatar

發(fā)布進(jìn)度

avatar

部署流程

avatar

安裝包

windows下載

具體代碼:

  • 部署代碼 deploy.js (electron主進(jìn)程中執(zhí)行)
const path = require('path');
const node_ssh = require('node-ssh');
const zipFile = require('compressing')// 壓縮zip

let SSH = new node_ssh(); // 生成ssh實例
let mainWindow = null; // 窗口實例,用于向向渲染進(jìn)程通信

// 部署流程入口
const deploy = async (config, mainWindows) => {
    mainWindow = mainWindows
    await startZip(config);
    await connectSSH(config);
    await uploadZipBySSH(config)
}

//壓縮代碼
const startZip = async (config) => {
    return new Promise((resolve, reject) => {
        let { distPath } = config;
        let distZipPath = path.resolve(distPath, `../dist.zip`);
        mainWindow.send('deploy', '本地項目開始壓縮')
        zipFile.zip.compressDir(distPath, distZipPath).then(res => {
            mainWindow.send('deploy', `本地項目壓縮完成:${distZipPath}`)
            resolve()
        }).catch(err => {
            mainWindow.send('deploy', `壓縮失敗${err}`)
            reject()
        })
    })
}

//連接服務(wù)器
const connectSSH = async (config) => {
    return new Promise((resolve, reject) => {
        mainWindow.send('deploy', `正在連接服務(wù)器:${config.host}`)
        SSH.connect({
            host: config.host,
            username: config.username,
            password: config.password // 密碼登錄 方式二
        }).then(res => {
            mainWindow.send('deploy', `連接服務(wù)器成功:${config.host}`)
            resolve()
        }).catch(err => {
            mainWindow.send('deploy', `連接服務(wù)器失敗:${err}`)
            reject()
        })
    })
}

//清空線上目標(biāo)目錄里的舊文件
const clearOldFile = async (config) => {
    mainWindow.send('deploy', `準(zhǔn)備清空服務(wù)器部署目錄${config.webDir}內(nèi)的文件`)
    const commands = ['ls', 'rm -rf *'];
    await Promise.all(commands.map(async (item) => {
        return await SSH.execCommand(item, { cwd: config.webDir });
    }));
    mainWindow.send('deploy', `清空服務(wù)器目錄${config.webDir}內(nèi)的文件完成`)
}

//上傳zip文件到服務(wù)器
const uploadZipBySSH = async (config) => {
    let distZipPath = path.resolve(config.distPath, `../dist.zip`);
    //線上目標(biāo)文件清空
    await clearOldFile(config);
    try {
        await SSH.putFiles([{ local: distZipPath, remote: config.webDir + '/dist.zip' }]); //local 本地 ; remote 服務(wù)器 ;
        mainWindow.send('deploy', `上傳文件到服務(wù)器成功:${config.webDir}`)
        await SSH.execCommand('unzip -o dist.zip && rm -f dist.zip', { cwd: config.webDir }); //解壓
        mainWindow.send('deploy', `解壓上傳到服務(wù)器的文件成功`)
        await SSH.execCommand(`rm -rf ${config.webDir}/dist.zip`, { cwd: config.webDir }); //解壓完刪除線上壓縮包
        mainWindow.send('deploy', `刪除上傳到服務(wù)器的文件成功`)

        //將解壓后的文件夾內(nèi)的所有文件移動到目標(biāo)目錄
        var dir = path.basename(path.join(config.distPath))
        mainWindow.send('deploy', `將${config.webDir}/${dir}/內(nèi)解壓的文件移動到目錄${config.webDir}`)
        await SSH.execCommand(`mv - f ${config.webDir}/${dir}/*  ${config.webDir}`);
        await SSH.execCommand(`rm -rf ${config.webDir}/${dir}`); //移出后刪除 dist 文件夾
        mainWindow.send('deploy', `全部完成`)
        SSH.dispose(); //斷開連接
    } catch (error) {
        mainWindow.send('deploy', `文件上傳到服務(wù)器失敗:${error}`)
        // process.exit(); //退出流程
    }
}

export default deploy

  • 主進(jìn)程進(jìn)行監(jiān)聽與渲染進(jìn)行發(fā)送的命令
// 監(jiān)聽前臺傳來的deploy命令
ipcMain.on('deploy', (e, data) => {
  deploy(data, mainWindow)
});
  • 前臺部分代碼
<template>
  <div id="wrapper">
    <el-row :gutter="20" class="pro-list">
      <el-col :span="12" v-for="(item, index) in dataList" :key="index">
        <el-card class="box-card">
          <ul class="prolist">
            <li>
              <span class="label">項目名稱:</span>
              <span class="info">{{ item.projectName }}</span>
            </li>
            <li>
              <span class="label">服務(wù)器地址:</span>
              <span class="info">{{ item.host }}</span>
            </li>
        //    ...other
          </ul>
          <div class="btns">
            <el-button icon="el-icon-s-promotion" @click="deploy(item)" type="primary">發(fā)布</el-button>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { ipcRenderer } from "electron";
export default {
  name: "prolist",
  created() {
    this.getDb();
    // 接收主進(jìn)程部署過程 中的 過程信息
    ipcRenderer.on("deploy", (event, arg) => {
      this.activities.unshift({
        content:arg,
        timestamp: new Date().toLocaleTimeString()
      });
    });
  },
  data() {
    return {
      dataList: [],
      activities: []
    };
  },
  methods: {

    // 部署
    deploy(config) {
    //   發(fā)送打包命令 給 主進(jìn)程
      ipcRenderer.send("deploy", config);
    },
    remove(config) {
    //   刪除項目
    }
  }
};
</script>

僅供大家學(xué)習(xí)參考

所有數(shù)據(jù)存在本地lowdb中,所以不用擔(dān)心安全問題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市旗国,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌备蚓,老刑警劉巖濒憋,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壶熏,死亡現(xiàn)場離奇詭異贬循,居然都是意外死亡咸包,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門杖虾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诉儒,“玉大人,你說我怎么就攤上這事亏掀〕婪矗” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵滤愕,是天一觀的道長温算。 經(jīng)常有香客問我,道長间影,這世上最難降的妖魔是什么注竿? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮魂贬,結(jié)果婚禮上巩割,老公的妹妹穿的比我還像新娘。我一直安慰自己付燥,他們只是感情好宣谈,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著键科,像睡著了一般闻丑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勋颖,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天嗦嗡,我揣著相機(jī)與錄音,去河邊找鬼饭玲。 笑死侥祭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的茄厘。 我是一名探鬼主播矮冬,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蚕断!你這毒婦竟也來了欢伏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤亿乳,失蹤者是張志新(化名)和其女友劉穎硝拧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葛假,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡障陶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了聊训。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抱究。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖带斑,靈堂內(nèi)的尸體忽然破棺而出鼓寺,到底是詐尸還是另有隱情勋拟,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布妈候,位于F島的核電站敢靡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏苦银。R本人自食惡果不足惜啸胧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望幔虏。 院中可真熱鬧纺念,春花似錦、人聲如沸想括。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽主胧。三九已至叭首,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間踪栋,已是汗流浹背焙格。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留夷都,地道東北人眷唉。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像囤官,于是被迫代替她去往敵國和親冬阳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容