# github 仓库自动化部署

# 准备变量

  • HOST、PORT、USERNAME、PRIVATE_KEY:服务器地址、端号、用户名、SSH 私钥
  • GITHUB_TOKEN: Github API 令牌,用于访问 Github API,可以用于操作仓库构建和下载 release
创建Github API令牌,请按照以下步骤操作:

转到Github网站,登录您的帐户。
单击您的头像,在下拉菜单中选择“Settings”。
单击左侧菜单中的“Developer settings”。
单击“Personal access tokens”。
单击“Generate new token”。
输入令牌名称并选择所需的权限。
单击“Generate token”。
将新生成的令牌复制到您的文本编辑器中。

现在有一个 GITHUB_TOKEN 了,该怎样验证它是否生效?
curl -H "Authorization: token YOUR_GITHUB_TOKEN" https://api.github.com/user
  • 在仓库中设置上述变量,仓库 -> settings -> secrets and variables

# 准备工具

jq 是一个命令行工具,用于处理和分析 JSON 格式的数据。在大多数 Linux 发行版上,您可以通过包管理器来安装 jq 工具,例如:

  • 在 Ubuntu 和 Debian 上,可以使用以下命令安装:

    sudo apt-get update
    sudo apt-get install jq
    
  • 在 CentOS 和 Fedora 上,可以使用以下命令安装:

    sudo yum install jq
    
  • 在 macOS 上,可以使用 Homebrew 来安装:

    brew install jq
    
  • 在 win 上安装,(还要配置下环境变量):

    curl -L -o jq-win64.exe https://github.com/stedolan/jq/releases/download/jq-1.6/jq-win64.exe
    
    

验证安装,jq --version,安装完成后,您就可以使用 jq 工具来处理 JSON 数据了。

# 编写 workflows

在仓库的根目录下,创建 .github\workflows\index.yml

name: Publish And Deploy
on:
  # push:
  #   branches:
  #     - master

  # 发布并部署版本到服务器
  # git add .
  # git commit -m "xxx"
  # git tag v0.1.0
  # git push origin v0.1.0

  # 如果非发布版本时 不能 push 尝试
  # git pull --rebase origin master
  # git push -u origin master

  # 如果 出现 error: src refspec refs/heads/master matches more than one 不能push
  # 尝试 git tag 查看本地标签,或远程仓库上查看tags,git tag -d refs/heads/master 删除多余标签
  push:
    tags:
      - "v*"

jobs:
  build-and-release:
    runs-on: ubuntu-latest
    steps:
      # 下载源码
      - name: Checkout
        uses: actions/checkout@master

      # 打包构建
      - name: Build
        uses: actions/setup-node@master
      - run: npm install
      - run: npm run build
      - run: cd ./dist && tar -zcvf release.tgz *

      # # 发布 Release
      - name: Create Release
        id: create_release
        uses: actions/create-release@master
        env:
          GITHUB_TOKEN: ${{ secrets.HUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: Release ${{ github.ref }}
          draft: false
          prerelease: false

      # # 上传构建结果到 Release
      - name: Upload Release Asset
        id: upload-release-asset
        uses: actions/upload-release-asset@master
        env:
          GITHUB_TOKEN: ${{ secrets.HUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./dist/release.tgz
          asset_name: release.tgz
          asset_content_type: application/x-tgz

  # 如果是共有仓库,参考:
  deploy:
    needs: build-and-release
    runs-on: ubuntu-latest
    steps:
      # # 部署到服务器
      - name: executing remote ssh commands using ssh key
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.PRIVATE_KEY }}
          port: ${{ secrets.PORT }}
          script: |
            cd /usr/local/nginx/data/www/HERE_PROJECT
            wget https://github.com/HERE_OWNER/HERE_REPO/releases/latest/download/release.tgz -O release.tgz
            tar -zxvf release.tgz

  # 如果是私有仓库,参考:
  deploy:
    needs: build-and-release
    runs-on: ubuntu-latest
    steps:
      # # 部署到服务器
      - name: executing remote ssh commands using ssh key
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.PRIVATE_KEY }}
          port: ${{ secrets.PORT }}
          ## 把 '|' 换成 |
          script: '|'
            cd /www/server/nginx/data/service/HERE_PROJECT
            npm run stop
            OAUTH_TOKEN= ${{ secrets.HUB_TOKEN }}
            OWNER="HERE_OWNER"
            REPO="HERE_REPO"
            FILE_NAME="release.tgz"
            API_URL="https://$OAUTH_TOKEN:@api.github.com/repos/$OWNER/$REPO"
            ASSET_ID=$(curl $API_URL/releases/latest | jq -r '.assets[0].id')
            echo "Asset ID: $ASSET_ID"
            rm -f $FILE_NAME
            curl -x http://127.0.0.1:7890 -O -J -L -H "Accept: application/octet-stream" "$API_URL/releases/assets/$ASSET_ID"
            tar -zxvf release.tgz
            npm run start

# 验证和测试

push 仓库触发一下 workflows,再到 github 上查看 actions 执行。

# 知识拓展

# 学习 wget 和 curl

wget 和 curl 都是在终端中使用的命令行工具,用于从互联网下载文件。

当你需要在终端中下载文件时,wget 和 curl 都是非常有用的工具。以下是使用 wget 和 curl 下载文件的一些简单示例:

# 使用 wget 下载文件:
  1. 下载单个文件:
wget URL
  1. 下载整个目录:使用 -r 和 -np 选项下载整个目录,其中 -r 表示递归下载,-np 表示不跳转到父级目录。
wget -r -np URL
  1. -c:断点续传下载文件。
wget -c URL
  1. -t:设置重试次数。
wget -t 5 URL
  1. -q:静默下载,不输出任何信息。
wget -q URL
  1. -b:后台下载文件。
wget -b URL
  1. -P:指定保存下载文件的目录。
wget -P /path/to/directory URL
  1. -e: 指定代理服务器
wget -e "use_proxy=yes" -e "http_proxy=192.168.1.100:8080" -e "https_proxy=192.168.1.100:8080" https://example.com/file.txt
# 使用 curl 下载文件:
  1. 下载单个文件:在终端中输入以下命令,并将 URL 替换为要下载的文件的实际 URL:
curl -O URL
  1. 下载整个目录:使用 -OJ 选项下载整个目录,其中 -O 表示使用远程文件的名称,-J 表示使用远程文件名并解析出下载文件的文件名。
curl -OJ URL
  1. -L:跟随重定向,下载重定向后的文件。
curl -L URL
  1. -k:允许不安全的 SSL 连接。
curl -k URL
  1. -u:指定用户名和密码进行下载。
curl -u username:password URL
  1. -s:静默下载,不输出任何信息。
curl -s URL
  1. -o:指定保存下载文件的文件名。
curl -o filename URL
  1. -x:指定代理服务器。
curl -x 192.168.1.100:8080 https://example.com/file.txt
  1. 保存输出为 json
curl -H "Authorization: token YOUR_GITHUB_TOKEN" https://api.github.com/repos/OWNER/REPO/releases -o releases.json