Back

使用 GitHub API 推送並更新 (取代) GitHub Repository 中的檔案

GitHub API 囊括多種功能,這裡僅針對更新 (取代) 檔案內容的環節進行探討,以下分成三個部分:


產生 Personal access token

進入連結: GitHub new personal access token

登入 GitHub 帳戶後顯示以下畫面


  Set new personal access token
Set new personal access token

  • Note:token 用途註記
  • Select scopes:選擇 token 權限 (僅涉及 repository 操作,勾選 repo 即可)

確認完畢後點擊 Generate token,顯示以下畫面,獲得 token (圖中 token 為示範用,已刪除無安全性問題)

token 只會顯示一次,請複製下來並妥善保存

  Get personal access token
Get personal access token

透過 GitHub API 更新 (取代) 檔案內容

情境:前端透過 POST 方式將 data.json 送往後端,後端接收到檔案後,透過 GitHub API 將 data.json 推送到目標 GitHub repository

用 Node.js 寫一個簡單的 server,這裡使用了 express@octokit/coredotenv 三種套件

  • express:Node.js framework,提供各種便於開發的語法
  • @octokit/core:用來呼叫 GitHub API
  • dotenv:從 .env 檔獲取環境變數 (例如下圖的 GITHUB_TOKEN 和 PORT)。.env 通常用來放置敏感資訊,便於本地開發但不會隨著專案被推送到遠端 repository,內部的變數會等到部署至正式環境時再額外加入
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  const express = require('express')
  const { Octokit } = require('@octokit/core')
  require('dotenv').config()

  // 建立已授權 (攜帶 auth token) 的 Octokit instance
  // process.env.GITHUB_TOKEN 就是上一個步驟產生的 token
  const octokit = new Octokit({
    auth: process.env.GITHUB_TOKEN
  })

  const app = express()
  const port = process.env.PORT || 3000

  // 解析 request 送來的 JSON payload
  app.use(express.json())

  // 前端用 POST 方法呼叫這支 API,並送來 JSON 檔 (資料位於 req.body)
  app.post('/update', async (req, res) => {
    try {
      // 先向 GitHub 索取目標檔案位置資訊,發送檔案更新 (取代) 請求時會需要其中的 blob SHA (一串 hash value)
      const { data } = await octokit.request(
        'GET https://api.github.com/repos/{owner}/{repo}/contents/{path}'
      )
      // 發送請求更新 (取代) 檔案
      const response = await octokit.request(
        'PUT https://api.github.com/repos/{owner}/{repo}/contents/{path}',
        {
          owner: 'Luke',
          repo: 'weather-api',
          path: 'model/data.json',
          message: 'JSON update',
          content: Buffer.from(JSON.stringify(req.body)).toString('base64'),
          sha: data.sha
        }
      )
      // 回傳 response 給 client 端
      res.send(response)
    } catch (err) {
      console.log(err)
    }
  })

  // 指定 server 監聽端口
  app.listen(port)

相關參數

  • owner:GitHub 帳戶名稱
  • repo:GitHub repository 名稱
  • path:檔案路徑
  • message:commit message
  • content:資料內容 (Base64 格式)
  • sha:記錄檔案位置的 blob SHA,replace 或 delete file 才需要該資訊,create file 則不需要

應用情境

可以自訂檔案上傳介面,並使用 My JSON Server 之類的服務,就能夠快速更新 GitHub repository 中的 db.json,打造供給不同資料的 API endpoint。


參考資料

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus