完美創建Slack Bot以通過Hubot調用GitHub操作

如果您使用GitHub Actions作為您的構建和發佈管道,而您的團隊也使用Slack,您是否知道您甚至都不必離開Slack?創建Slack機器人以自動從Slack直接調用GitHub Actions工作流程!

在本教程中,您將學習如何使用名為Hubot的機器人構建工具來設置一個新的Slack聊天機器人,並自動啟動GitHub Actions工作流程來部署代碼到服務器。

讓我們開始吧!

先決條件

本教程將進行一個動手演示。如果您想跟著做,請確保您具備以下條件:

  • A Slack Workspace
  • A GitHub account and a GitHub personal token
  • A Linux server to deploy code to – This tutorial will use Ubuntu 19.
  • A local Linux machine – This tutorial will use Ubuntu so that all local commands will be Linux. If you’re running another operating system, the commands may be slightly different.
  • 用於連接到您將部署代碼的服務器的SSH憑證。
  • A code editor of your choice that understands YAML like Visual Studio Code.

創建項目和GitHub Actions工作流程

在您可以從Slack快速調用GitHub Actions工作流程之前,您必須首先創建工作流程。

要創建工作流程,讓我們創建一個項目文件夾,以保存您將使用的所有文件。

1. 開啟您喜歡的終端應用程序。

2. 現在運行下面的一系列命令來創建名為Hubot的專案文件夾並進入其中。

mkdir ~/Hubot # 創建一個名為 Hubot 的目錄
cd ~/Hubot    # 切換目錄到 Hubot

3. 接下來,運行npm init來創建一個 Node.JSpackage.json文件。運行npm init會創建一個標準的 Node.JS 專案,其中包含package.json文件,該文件包含有關項目和任何依賴NPM packages的各種信息。

npm init      # 初始化 package.json 文件

4. 現在,創建一個workflows目錄和deploy.yml workflow 文件。工作流文件是一系列在 GitHub Actions 將要遵循的步驟的序列。

mkdir .github/workflows && touch deploy.yml

5. 接下來,定義你的工作流程將要讀取的每個GitHub secrets。你即將要創建的工作流程將會參考這些秘密。由於你需要你的伺服器地址、用戶名、密碼和 SSH 的伺服器端口,讓我們創建 GitHub secrets。

請訪問此 URL https://github.com/yourusername/yourrepository/settings/secrets/actions 以添加你的 GitHub secrets。將yourusername替換為你的 GitHub 用戶名,將yourrepository替換為你的 GitHub 存儲庫。

點擊下方顯示的新增存儲庫秘密按鈕,填寫關於你正在添加的秘密的信息。

Adding GitHub Secrets

6. 現在填寫秘密的名稱和值字段,然後點擊添加秘密以保存。頁面將重定向到 GitHub 秘密頁面,你將看到所有的秘密。要添加更多秘密,請像之前一樣點擊新增存儲庫秘密按鈕。

請確保為給定變量保存與你將引用的相同名稱的秘密,這些變量是 HOST、USERNAME、PASSWORD 和 PORT。

Filling up Information for a GitHub Secret
Viewing All GitHub Secrets

7. 最後,打開你的程式編輯器中的~/Hubot/.github/workflows/deploy.yml工作流程文件,並複製/貼上以下代碼。下面的代碼是每當你稍後通過 Slack 觸發工作流程時將運行的工作流程。

當你調用工作流程時,將執行一些操作:

  • GitHub Actions將解析以下工作流檔案,以使用在HOST密碼中定義的hostUSERNAMEPASSWORD作為密碼,SSH登入目標。
  • 然後,工作流將通過運行git pull origin$branchName來下載特定分支($branchName)的GitHub存儲庫的內容。請確保分支名包含您想部署的代碼。
  • 您將使用來自Github MarketplaceWorkflow Package,名為ssh-remote-commands。此套件有一個很好的包裝器,可以解決您只需提供主機、用戶名、密碼、端口和要在生產環境上運行的命令的情況。

請確保您的服務器安裝了git,並擁有從GitHub存儲庫中拉取代碼的必要登錄憑據

# 將在程式中多次引用的名稱
name: deploy 
on:
  # 事件 respository_dispatch 意味著在每個 API 觸發上,
  # 這個整個文件都會被執行
  repository_dispatch: 
    types: [deploy-service]
# 可以有多個工作,但目前,
# 本教程只會處理一個
jobs:
  deploy:
    name: Deploy
    # 所有 YAML 中的代碼都在其中執行的基礎映像的名稱
    runs-on: ubuntu-latest
    steps:
    - name: executing remote ssh commands using password
      # appleboy/ssh-action@master 是一個開源包
      # 它通過 ssh 登錄到服務器並執行腳本
      uses: appleboy/ssh-action@master
      # 這些通常是該包需要的變量
      # 以登錄到服務器並執行腳本
      with:
       # 密鑰是從
       # https://docs.github.com/en/actions/security-guides/encrypted-secrets 中的變量

       # 存儲在 github 密鑰上的伺服器主機
        host: ${{ secrets.HOST }} 
        # 用於登錄的伺服器用戶名
        # 存儲在 github 密鑰上的用戶名
        username: ${{ secrets.USERNAME }} 
        # 用於登錄的伺服器密碼
        # 存儲在 github 密鑰上的密碼
        password: ${{ secrets.PASSWORD }} 
        # 用於登錄的伺服器端口
        # 存儲在 github 密鑰上的端口
        port: ${{ secrets.PORT }}  
        # deploy-app.sh 可以是任何東西,例如您可以從 GitHub 上拉取代碼
        # 並重新啟動您的 web 服務器或隊列等
        # 確保您在伺服器上克隆了存儲庫
        # 您可以運行許多腳本,就像您喜歡的那樣
        script: git pull origin {{ github.event.client_payload.branch 

執行工作流程手動

您現在已經創建了通過Slack調用的GitHub Actions工作流程。但是,此時您的代碼僅存在於本地計算機上。要觸發工作流程,您需要將代碼推送到GitHub。

運行以下一系列命令告訴git代碼應該從哪裡推送和拉取,在此示例中,從您的遠程GitHub存儲庫。在下面的git remote add origin命令中,將yourusernameyourrepository替換為您的GitHub用戶名和存儲庫

# 打開github.com並創建存儲庫
git init # 初始化git
git remote add origin https://github.com/yourusername/yourrepository.git
git add . # 添加新創建的文件以供git跟踪
git commit -m "Created GitHub workflow file"
git push -u origin master

讓我們首先測試您的代碼是否有效。使用流行的curl實用程序手動調用您的代碼。

運行以下命令向您的GitHub存儲庫https://github.com/username/repository/dispatches URL發送POST請求,告訴GitHub觸發您之前創建的Workflow文件deploy.yml。將username替換為您的實際GitHub用戶名,將repository替換為您的GitHub存儲庫。

在下面的代碼中將$github_personal_token替換為您的個人令牌。

# 在 https://github.com/username/repository/dispatches 的 URL 上進行 POST 請求 
curl-X POST  https://github.com/username/repository/dispatches \
# 添加接受內容類型的標頭
-H 'Accept: application/vnd.github.everest-preview+json' \
# 添加授權的標頭
-H "Authorization: token $github_personal_token" \
# 在 POST 請求的主體上添加 JSON 內容,以便您可以發送多個參數
# 從此數據部分,您可以傳遞環境名稱和 ref 名稱作為分支名稱,以便您知道要在哪個服務器上部署哪個分支
--data '{"event_type": "deploy-service", "client_payload": {"environment": "'"$1"'", "ref": "'"$2"'"}}' # 您可以將環境名稱和 ref 名稱作為分支名稱傳遞,以便知道要在哪個服務器上部署

使用 Hubot 創建 Slack 機器人

既然您能夠手動觸發 GitHub Action 工作流程,那就是個好的開始。現在讓我們試著通過 Slack 機器人自動執行相同的手動步驟。您將創建一個 Slack 機器人,它會聽取您的命令並使用參數觸發 GitHub Action。

創建 Slack 機器人有兩種選擇,可以從頭開始,也可以使用預先構建的 Hubot 套件來為 Slack 工作空間創建。在本教程中,您將使用一個名為 Hubot 的預先構建機器人套件。Hubot 是一個開源的自動化工具,可以與 Slack、Discord、Gitter、TeamSpeak 等聊天服務集成。

創建自定義機器人,而不使用類似 Hubot 的應用程式會花費很多時間。為什麼?因為你將處理所有設置流程、監聽 Webhooks 並託管機器人。因此,在本教程中,你將使用 Hubot Slack 應用程式來簡化所有這些流程。

使用 Npm 安裝 Hubot

由於你正在使用 Hubot 創建 Slack 機器人,讓我們首先在本地機器上下載並安裝 Hubot。Hubot將是連接 Slack 和 GitHub actions 的連接器。

1. 在終端中,導航(cd)到你的項目目錄(〜/Hubot)。

cd ~/Hubot

2. 使用以下 npm install 命令在本地機器上全局安裝 yogenerator-hubot 套件(-g)。yo 套件幫助你通過在任何語言中生成項目來安裝新項目(Web、Java、Python、C# 等)。generator-hubot 套件使用 yo 套件來安裝所有依賴項以及初始設置。

安裝完成後,你可以從任何地方運行 yo 命令,因為它是全局安裝的。

npm install -g yo generator-hubot

3. 現在,使用以下命令創建一個基本的 Hubot「boilerplate」。「Boilerplate」是包含在許多地方的代碼段。如果沒有「boilerplate」,您總是需要從頭開始編寫代碼。

下面的命令在您的專案目錄中創建一個基本的 Hubot「boilerplate」。Hubot「boilerplate」連接到 Slack(--adapter=slack),這樣機器人就可以聽取並回答 Slack 頻道中的消息。yo hubot --adapter=slack

yo hubot --adapter=slack

將 Hubot 添加到您的 Slack 工作區

現在,已經在您的本地機器上安裝了 Hubot,您需要配置 Hubot 與 Slack 進行通信。

讓我們在您的 Slack 工作區中安裝 Hubot。

1. 打開網絡瀏覽器,使用以下 URL 導航到 Slack 管理設置頁面:https://workspacename.slack.com/admin/settings.workspacename 替換為您實際的 Slack 工作區名稱。

點擊左側面板上的 配置應用程式 按鈕,如下所示,這樣您就可以在市場上搜索 Hubot。Slack 有一個市場,您可以在其中找到預先構建的應用程式。

Accessing Slack Admin Settings

2. 點擊搜索欄,然後輸入 hubot 以在 市場 中搜索 Hubot,然後選擇 Hubot

現在,點擊下面的 添加到 Slack 按鈕,將 Hubot 添加到您的 Slack 工作區中。

Searching Hubot and Adding it to Slack Workspace

3. 最後,填寫一些有關你的機器人的一般資訊,比如名稱(deployerhubot)和圖標。請注意API Token,你稍後將在 Hubot 部署器中使用它,以啟動你之前創建的 Hubot 項目中的機器人。

Setting up Bot Information and Taking Note of the API Token

測試 GitHub Actions Workflow 與 Slack 整合

你現在已經在 Slack 工作區中安裝了 Hubot,所以讓我們通過監聽並發送消息到頻道來測試機器人。但首先,你必須啟動機器人。

1. 在專案的根目錄中運行下面的命令,以啟動 Slack 的機器人(--adapter slack)從你的 Hubot 存儲庫中(./bin/hubot)。請務必將$token替換為你先前記下的 API token

HUBOT_SLACK_TOKEN=$token ./bin/hubot --adapter slack

2. 運行下面的命令來邀請(/invite)機器人(botusername)到你的 Slack 頻道。將botusername替換為你在“將 Hubot 添加到你的 Slack 工作區”部分中註冊的機器人名稱。

/invite deployerhubot

現在,在 Slack 中提及一個帶有文本的機器人,例如@deployerhubot ping,以測試整合是否正常工作。如果機器人回應 PONG,如下所示,那麼一切就設置好了。

Testing Hubot and Slack Integration

如果機器人沒有回應,請在網頁瀏覽器中導航到你的 GitHub 存儲庫,並點擊Actions標籤。你可以通過它上面的圓形紅色勾選徽章找到失敗的工作流程。點擊失敗的工作流程以查看是什麼導致了失敗並加以修復。

Viewing Failed Workflows

以下,您可以看到失敗在於使用密碼執行遠程SSH命令。修復工作流後,回到第3步,看看機器人是否會回應PONG。

Navigating to GitHub repository to fix failed workflow

從Slack啟動GitHub Actions工作流

現在您已經啟用了Slack Bot,是時候從Slack啟動GitHub Actions工作流了!

您需要靈活性,將給定分支部署到給定的服務器,例如從給定分支拉取代碼。您將教導機器人在有人在Slack頻道上輸入***@*bot deploy API feature-x to production時自動回應。您可以驗證環境名稱,稍後人們只能部署特定的環境和分支。

自動化機器人的回應:

1. 創建一個名為〜/ Hubot/scripts的目錄。 〜/ Hubot/scripts目錄是您將保存觸發GitHub工作流程的腳本的地方。

2. 在您的代碼編輯器中,創建一個名為bot.js的文件,放在〜/ Hubot/scripts目錄中。現在複製下面的代碼並將其粘貼到bot.js文件中。

下面的代碼允許機器人在Slack頻道上聽取聊天消息,然後觸發工作流以向Slack頻道發送響應。

const validServices = ['api','app'];
const validEnvironments = ['production'];
robot.hear (`@${process.env.BOT_ID}`,async (bot) => {
    //機器人只對聽取訊息感興趣
    //像是@deploy api featurex to production
    //設置可重複使用的變數
	  const payload = bot.message.text.split(" ")
    const service = payload[2];
    const branch = payload[3];
    const environment = payload[5];
    const username = bot.message.user.name;
    //告知使用者我們正在處理
    bot.send(`Roger that! Please wait.`);
//驗證使用的指令是否有效
//因為使用者也可能使用無效的指令
if(!validateCommand(bot,username,service,branch,environment)) {
      return;
    }
    //如果指令似乎有效,則觸發工作流程
    await triggerWorkflow(bot,username,service,environment,branch)
    
    //告知使用者工作流程已成功觸發
    bot.send(`Github Action has been triggered successfully`);
  })
  const validateCommand = (bot,username,service,branch,environment) => {
    //限制服務,因為使用者可能使用未列出的服務
    //這將嘗試觸發工作流程並產生錯誤
    if(!validServices.includes(service)) {
       bot.send(`${service} is not availble, Only ${validServices.join(', ')} are available`);
      return false;
      }
      //限制環境,因為使用者可能使用無效的環境清單
      if(!validEnvironments.includes(environment)) {
        bot.send(`${environment} is not availble. Only ${validEnvironments.join(', ')} are available`);
        return false;
      }
      return true;
  }

  const triggerWorkflow = (bot,username,service,environment,branch) => {
    try {
      //這是從curl轉換成實際的JavaScript POST請求的手動觸發工作流程代碼
      //從curl轉換成實際的JavaScript POST請求的手動觸發工作流程代碼
      const data = await axios.post(`https://api.github.com/repos/yourusername/yourreponame/dispatches`,{
        'event_type': 'deploy-service',
        'client_payload': {'environment': environment, 'ref': branch}
      },{headers:{
      Authorization: `token ${token}`,
      }})
    }
      catch(e) {
        bot.send(`Sorry @${username} could not trigger github action. Please check my logs ${e.message}`);
      }
  }

3. 最後,在Slack中發送@botusername deploy api staging to dev的訊息,您將看到類似的回應,如下所示。

工作流程檔案可以在各種 GitHub 事件上觸發,例如將程式碼推送到特定分支、建立標籤、建立拉取請求、請求某些 URL 等等。

send the @botusername deploy api staging to dev message in slack

結論

在本教程中,您已經了解了 GitHub 工作流程,從使用代碼手動觸發 Slack 回應到建立聊天機器人。您還了解到在 Slack 中擁有聊天機器人可以通過調用 GitHub 操作工作流程來自動執行任務。

您是否想將這些新知識提升到一個新水平,也許添加一個提醒機器人或製作互動消息?

Source:
https://adamtheautomator.com/create-slack-bot/