Skip to content

Github Actions 部署项目

前言

GitHub Actions 是一个持续集成和持续交付(CI/CD)平台,可以执行自动化构建和部署。通过创建工作流,方便的将项目部署到生产中。

本教程将从纯静态文件部署项目打包文件部署sh 脚本项目部署全自动项目部署几个方面实现 Github Actions 自动部署项目。

重要提示

本教程中的示例项目代码拉取下来后,请将项目推送到自己的 GitHub 仓库中,以便后续操作步骤能够成功运行。如果是已有项目,请酌情执行部署步骤!

1.纯静态文件部署

引子

纯静态文件部署常用在纯 html 页面且无需编译打包的项目中,入口 index.html 文件在项目根目录,克隆Github 示例项目

  1. 项目结构
|- test-static-pages
  - index.css
  - index.html
  - index.js
  1. 项目代码

    • index.html

      html
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0"
          />
          <title>测试静态文件部署</title>
          <link rel="stylesheet" href="index.css" />
        </head>
        <body>
          测试静态文件部署
      
          <script src="index.js"></script>
        </body>
      </html>
    • index.js

      js
      console.log("测试静态文件部署");
    • index.css

      css
      * {
        color: red;
      }
  2. 配置 Actions:

    • 克隆并推送项目到自己的 GitHub 仓库中;
    • 打开项目:Settings -> Pages;
    • Source 默认选择 Deploy from a branch
    • Branch 分支选择 master 分支【默认分支名称在此处修改】;
    • Select folder 默认选择 /(root)
    • 点击 Save 后,项目会自动部署到 GitHub Pages 上,访问示例项目
    • 操作步骤如下图:

    配置 actions

注意

  1. 只要在 master 分支上推送代码,都会自动部署项目。因此可以另起一个 develop 分支去写开发内容,有需要部署时,将 develop 分支合并到 master 分支,合并成功后依然会自动部署 master 分支。
  2. 可以在项目的 Actions 页面查看部署日志,观察部署过程。

2.项目打包文件部署

引子

上小节实现了纯静态页面的自动部署,但对于需要编译打包的项目来说,打包好的文件会在 dist 目录下,很明显上小节 Select folder 时没有 /dist 选项【PS:当然把项目打包目录设定为 /docs 去部署也可以】,这就需要用到 Actions 里的 yml 配置。

项目打包文件部署,常用在 dist 文件在本地打包好,提交到 GitHub 上,然后部署的场景中,克隆Github 示例项目,本节所用示例为 vite+vue3 项目,其他框架逻辑一致。

  1. 克隆项目【在已有项目中直接跳到第 3 步】:

    sh
    git clone https://github.com/Ele-Cat/test-dist-pages.git
  2. 安装依赖&打包

    sh
    npm install
    sh
    npm run build
  3. 推送项目到自己的 GitHub 仓库中,注意此时会将 dist 目录也提交上去【.gitignore文件不忽略dist目录】

  4. 配置 Actions:

    • 打开项目:Settings -> Pages;

    • Source 选择 GitHub Actions

    • workflow 选择 Static HTMLConfigure,会跳转到 */.github/workflows/static.yml 编辑页;

    • 修改 static.yml

      yml
      # Simple workflow for deploying static content to GitHub Pages
      
      # 这行代码设置了工作流程的名称为 "Deploy static content to Pages"。
      name: Deploy static content to Pages
      
      # 这部分定义了触发工作流程执行的事件。它指定当代码推送到名为 "master" 的分支时触发工作流程执行,并且还可以通过 GitHub Actions 界面手动触发工作流程。
      on:
        push:
          branches: ["master"]
        workflow_dispatch:
      
      # 这部分设置了 GITHUB_TOKEN 的权限,以允许对 GitHub Pages 进行部署。它指定 GITHUB_TOKEN 具有读取仓库内容、写入页面和写入身份令牌的权限。
      permissions:
        contents: read
        pages: write
        id-token: write
      
      # 这部分定义了并发性设置。它指定一个名为 "pages" 的组,用于限制只能有一个并发的页面部署任务运行,同时取消排队中的运行。但不会取消正在进行中的运行,以确保生产部署完成。
      concurrency:
        group: "pages"
        cancel-in-progress: false
      
      # 这部分定义了一个名为 "deploy" 的任务(job)。该任务在 Ubuntu 最新版本上运行。它包含一系列步骤以执行静态内容的部署过程,具体步骤包括:
      # Checkout 步骤使用 actions/checkout 动作来获取代码库。
      # Setup Pages 步骤使用 actions/configure-pages 动作进行页面配置。
      # Upload artifact 步骤使用 actions/upload-pages-artifact 动作将 "./dist" 目录下的文件上传到 GitHub Pages 所需的存储库。
      # Deploy to GitHub Pages 步骤使用 actions/deploy-pages 动作执行实际的 GitHub Pages 部署操作,并将操作结果保存在 deployment 变量中,可以通过 ${{steps.deployment.outputs.page_url }} 访问部署后的页面 URL。
      jobs:
        deploy:
          environment:
            name: github-pages
            url: ${{ steps.deployment.outputs.page_url }}
          runs-on: ubuntu-latest
          steps:
            - name: Checkout
              uses: actions/checkout@v4
            - name: Setup Pages
              uses: actions/configure-pages@v5
            - name: Upload artifact
              uses: actions/upload-pages-artifact@v3
              with:
                # Upload entire repository
                path: "."
                path: "./dist"
            - name: Deploy to GitHub Pages
              id: deployment
              uses: actions/deploy-pages@v4
    • 点击右上角的 Commit changes 后,再点击弹窗的 Commit changes,项目会自动部署到 GitHub Pages 上,访问示例项目

    • 操作步骤如下图: 配置 actions

注意

  1. 与上小节一样,在推送 master 分支推送任意代码,后续无需任何配置,都会自动触发部署 dist
  2. 本节案例场景多用在项目所需依赖为私有部署,在 GitHub 中无法自动 install&build;如果项目所需依赖可在 GitHub 上完成,更推荐用全自动项目部署的操作。

3.sh 脚本项目部署

引子

上小节中实现的项目部署较为繁琐:

  1. 开发完成后本地 build;
  2. build 后提交文件到 GitHub;
  3. 等待 GitHub Actions 部署。

本节通过 sh 脚本,来实现:

  1. 项目自动打包并推送 dist 到对应分支;
  2. 自动部署。

虽然只缩减了一小步,但也是大进步 🎉!克隆Github 示例项目,本节所用示例为 vite+vue3 项目,其他框架逻辑一致。

  1. 克隆项目【在已有项目中直接跳到第 4 步】:

    sh
    git clone https://github.com/Ele-Cat/test-sh-pages.git
  2. 安装依赖

    sh
    npm install
  3. 推送项目到自己的 GitHub 仓库中

  4. 修改项目根目录 deploy.sh 文件的第 21 行代码:

    sh
    #!/usr/bin/env sh
    
    set -x  # 这里是为了看错误日志
    
    # 打包项目
    npm run build
    
    # 进入打包后的文件夹
    cd dist
    
    # 初始化一个 Git 仓库,如果在 dist 目录中还没有 Git 仓库的话。
    git init
    # 添加所有更改过的文件到暂存区。
    git add -A
    # 提交暂存区的所有更改,并附上一个提交信息。
    git commit -m '🚀自动部署'
    
    # 将当前分支强制推送到 GitHub 上的指定分支。
    # -f 选项表示强制推送,它会覆盖远程分支上的任何更改。
    # 这里的 master:sh-pages 表示将本地的 master 分支推送到远程的 sh-pages 分支。
    git push -f https://github.com/Ele-Cat/test-sh-pages.git master:sh-pages

    请将https://github.com/Ele-Cat/test-sh-pages.git仓库地址修改为自己的仓库地址,master:sh-pages分支信息修改为自己仓库对应的目标分支。

  5. 在项目根目录运行命令:

    sh
    sh deploy.sh

    在 Windows 电脑 的 VSCode 命令行工具中运行 sh deploy.sh,可能会报 sh : 无法将“sh”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 解决办法:在 Git Bash 中运行脚本命令。

  6. 等待脚本运行完成,可以在项目仓库中看到新的 sh-pages 分支。

  7. 配置 Actions:

    • 打开项目:Settings -> Pages;
    • Source 默认选择 Deploy from a branch
    • Branch 分支选择 sh-pages 分支【注意这里的sh-pages分支为第四步推送的分支名称】;
    • Select folder 默认选择 /(root)
    • 点击 Save 后,项目会自动部署到 GitHub Pages 上,访问示例项目
    • 操作步骤图参考第一小节。

注意

  1. 本小节部署方式最为灵活,在非 sh-pages 分支提交代码时,不会触发执行项目部署;在需要项目部署时,运行 sh deploy.sh 脚本,即可实现自动部署。
  2. 但是通过 sh 脚本打包、推送、部署,还是需要开发者手动运行命令触发,并非全自动。下小节将介绍如何实现代码提交即触发全自动部署。

4.全自动项目部署

引子

回归“前言”,GitHub Actions 是一个持续集成和持续交付(CI/CD)平台,可以执行自动化构建和部署。我们完全可以通过 Actions 实现代码提交即触发全自动部署,即安装、打包、部署都在 Actions 中完成。

一些基础概念
  1. CICD(持续构建、持续交付)

    ① CI 持续集成(Continuous Integration)

    持续集成:频繁的将代码合并到主分支中,强调通过集成测试反馈给开发一个结果,不管失败还是成功。

    持续集成分成三个阶段:

    • 持续集成准备阶段:根据软件开发的需要,准备 CI 的一些前置工作
      • 集成 CI 工具的代码仓库(Gitlab、Github、Jenkins 等)
      • 单元测试或者集成测试的脚本
      • 触发 CI 的配置文件,实现各种功能的 Jobs
    • 持续集成进行阶段
      • 推送代码出发 CI 系统
      • 通过 CI 系统监听代码的测试、构建,反馈集成结果
      • 通过版本管理系统实现版本的管理
    • 接续集成完成阶段:反馈集成结果

    ② CD 持续交付(Continuous Delivery)

    持续交付:主要面向测试人员和产品,可以保证一键部署,常常要交付的内容包括

    • 源代码:缺点,代码依赖的环境不容易控制
    • 打包的二进制文件或者系统包:存在兼容性问题和环境差异出现的部署失败
    • 虚拟机镜像交付:系统隔离最好,但占用系统资源严重
    • Docker 交付:容器交付,成本最低,兼容性最好

    持续部署:此时要提供一个稳定的版本,包括所需的环境和依赖,主要面向用户提供服务,发生错误要能快速回滚。

    CICD 是目前大多数互联网公司选择的一种部署方案,因为它能够灵活配置项目部署过程中的各个阶段。

  2. Workflows(工作流)

    工作流是一个可配置的自动化的程序。创建一个工作流,你需要定义一个 YAML 文件,当你的仓库触发某个事件的时候,工作流就会运行,当然也可以手动触发,或者定义一个时间表。一个仓库可以创建多个工作流,每一个工作流都可以执行不同的步骤。

    • Events(事件)

      事件是指仓库触发运行工作流的具体的行为,比如创建一个 pull request、新建一个 issue、或者推送一个 commit。你也可以使用时间表触发一个工作流,或者通过请求一个 REST API,再或者手动触发。

    • Jobs(任务)

      任务是在同一个运行器上执行的一组步骤。一个步骤要么是一个 shell 脚本要么是一个动作。步骤会顺序执行,并彼此独立。因为每一个步骤都在同一个运行器上被执行,所以你可以从一个步骤传递数据到另一个步骤 。

      你可以配置一个任务依赖其他任务,默认情况下,任务没有依赖,并行执行。当一个任务需要另外一个任务的时候,它会等到依赖的任务完成再执行。

    • Actions(动作)

      动作是 GitHub Actions 平台的一个自定义的应用,它会执行一个复杂但是需要频繁重复的作业。使用动作可以减少重复代码。比如一个 action 可以实现从 GitHub 拉取你的 git 仓库,为你的构建环境创建合适的工具链等。你可以写自己的动作 ,或者在 GitHub 市场找已经实现好的动作。

    • Runners(运行器)

      一个运行器是一个可以运行工作流的服务。每一个运行器一次只运行一个单独的任务。GitHub 提供 Ubuntu Linux,Microsoft Windows 和 macOS 运行器,每一个工作流都运行在一个独立新建的虚拟机中。如果你需要一个不同的操作系统,你可以自定义运行器。

  1. 克隆项目【在已有项目中直接跳到第 2 步】:

    sh
    git clone https://github.com/Ele-Cat/test-auto-pages.git
  2. 推送项目到自己的 GitHub 仓库中

    • 如果用的是克隆项目,直接推送即可

    • 如果是自己的全新项目,在项目根目录新增 .github/workflows/auto-deploy.yml文件:

      yml
      # .github/workflows/auto-deploy.yml
      
      name: auto deploy 🚀
      
      on:
        # 监听push操作
        push:
          branches:
            - master # 这里只配置了master分支,所以只有推送master分支才会触发以下任务
        pull_request:
      
        # 这个选项可以使你手动在 Action tab 页面触发工作流
        workflow_dispatch:
      
      permissions:
        # 允许对仓库的内容进行写操作。包括创建、修改和删除文件、目录以及提交更改等
        # 这里只配置了push,所以只有推送master分支才会触发以下任务
        contents: write
        # 允许管理 GitHub Pages 服务并对其进行写操作
        pages: write
      
      jobs:
        # 任务ID
        build-and-deploy:
          # 运行环境
          runs-on: ubuntu-latest
          concurrency:
            group: ${{ github.workflow }}-${{ github.ref }}
      
          # 步骤
          steps:
            # 官方action,将代码拉取到虚拟机
            - name: Checkout
              uses: actions/checkout@v3
      
            # 安装依赖
            - name: Install dependencies
              run: npm install
            # 打包
            - name: Build application 🔧
              run: npm run build
      
            # 部署
            - name: Deploy 🚀
              uses: JamesIves/github-pages-deploy-action@v4
              if: github.ref == 'refs/heads/master'
              with:
                token: ${{ secrets.PAT }}
                branch: gh-pages # default: gh-pages
                folder: dist
                clean: true # Automatically remove deleted files from the deploy branch

      提示

      首次推送代码后,会执行一次自动部署且报错,不用担心,这是因为 GitHub Actions 会监听 .github/workflows 目录的 .yml 文件,我们在配置了令牌后,就可以成功执行 Actions 了。

  3. 创建令牌

    • 打开 GitHub:右上角头像 -> Settings【不是仓库的 Settings 哦!】;
    • 左侧最下边的 Developer settings 进入;
    • 展开 Personal access tokens -> Fine-grained tokens【推荐使用这个,而不是 Tokens(classic),查看原因】;
    • 点击右上角的 Generate new token 按钮,进入配置界面; Fine-grained tokens
    • 填写 Token name 为 generate for test auto pages,这个令牌名称不可以跟其他令牌的名称重复;
    • 选择 Expiration,最多可以选择一年;
    • Repository access 选择 Only select repositories,然后选择需要自动部署的项目仓库;
    • 将 Permissions 中 Repository permissions 的全部选择都选择 Read and write,没有该选项的就选择 Read-only
    • 点击 Generate token 按钮,会显示一个令牌,复制这个令牌保存好,后续需要用到【如果忘记了令牌,可以在令牌详情重新生成一个,不过用到该令牌的全部项目都需要同步更新】。
  4. 将令牌应用在仓库中

    • 回到仓库中:Settings -> Security;
    • 展开 Secrets and variables,打开 Actions;
    • 在 Repository secrets 处绑定令牌,点击 New repository secret 按钮;
    • Name 填写 PAT【这个变量名在第 2 步的 auto-deploy.yml 文件中可自定义】;
    • Secret 填写 上步创建的令牌;
    • 点击 Add secret 按钮保存。
  5. 运行 Actions:

    • 随便推送代码到 master 分支 或 手动运行一次 Actions,为的是让 Actions 再跑一次部署流程;
    • 打开项目:顶部 Actions【可以看到有一条报错的部署信息,这就是上边说的,我们第 2 步时还没有配置令牌,所以报错了】;
    • 点击这条报错 workflow run,进入后点击右上角的 Re-run jobs -> Re-run all jobs
    • 这时候可以点击进入查看部署过程,等待 Complete job 后,我们可以看到仓库新增了一个 gh-pages 分支,且里边的内容就是我们打包后生成的 dist 文件夹内容;
    • 这时候打开项目:Settings -> Pages,就会发现 Build and deployment 已经自动将 gh-pages 分支部署好了,访问示例项目

      提示

      以后每次推送 master 分支代码后,Actions 都会自动执行安装、打包、部署任务,将最新代码部署到 gh-pages 分支;

总结

  1. 使用 GitHub Actions 来部署项目,其实就是将打包好的代码【不管是本地打包还是通过 jobs 打包】,部署到仓库的对应分支,并启用 GitHub Pages;
  2. 教程里的 1、2、4 都是只要提交代码,就会执行部署;3 为运行 sh 脚本才部署;可以根据自己的实际需求选择部署方式;
  3. 大多数情况下,master 分支是受保护的,我们可以推送代码到开发分支,仅在部署时,合并代码到 master 分支,合并时自动部署;

参考资料