Github项目CI&CD部署

1. 引言

在软件开发中,CI/CD (持续集成 / 持续部署)是一种自动化流程:每当代码更新,系统会自动构建、测试并部署应用,避免手动操作的繁琐与错误。作为 DevOps 的核心实践,CI/CD 有力支撑了敏捷开发"快速交付、持续反馈"的理念,让团队既能灵活响应变化,又能保障交付质量。

2. 操作

2.1 配置 SSH 密钥

如果代码托管在 GitHub 上,那么可以通过 GitHub Actions 来实现 CI/CD 部署。其实 GitHub Actions 的实现原理很简单,就是通过 SSH 登录到目标主机,然后执行一键安装部署脚本。

由于 GitHub Actions 的原理是 Github 主机登录到目标主机(Ubuntu)来执行命令,因此最好先生成一对专用于 CI/CD 新的 SSH 密钥。笔者的开发环境是 Windows,因此通过 PowerShell 来生成:

bash 复制代码
ssh-keygen -t rsa -b 4096 -f ./github_cicd_key

然后会提示输入密码:

bash 复制代码
Enter passphrase (empty for no passphrase):

CI/CD 场景下一般用无密码密钥,直接按回车。结束运行后就可以看到两个密钥文件:

  • github_cicd_key(私钥)
  • github_cicd_key.pub(公钥)

将公钥内容添加到 Ubuntu 服务器的 ~/.ssh/authorized_keys:

bash 复制代码
# 在 Ubuntu 服务器上执行
echo "粘贴 github_cicd_key.pub 的全部内容" >> ~/.ssh/authorized_keys

回到 GitHub 仓库页面:

  • 进入 Settings -> Security -> Secrets and variables → Actions
  • 点击 New repository secret
  • 添加以下三个 Secret:
Name Value(值)
SERVER_HOST 目标主机 IP(如 123.123.123.123)
SERVER_USER 登录用户名(如 ubuntu、root 等)
SSH_PRIVATE_KEY 打开 github_cicd_key 文件,复制全部内容粘贴进来

2.2 创建 CI/CD 工作流

在本地项目根目录(Windows 上)创建文件:

text 复制代码
.github/workflows/build-and-deploy.yml

内容如下所示:

yaml 复制代码
name: Deploy Blog

# 支持两种触发方式
on:
  # 1. 手动触发(GitHub UI 上点击 "Run workflow")
  workflow_dispatch:

  # 2. 自动触发:仅当推送到 main 分支 且 提交信息含 [deploy]
  push:
    branches: [main]

jobs:
  deploy: 
    if: >
      github.event_name == 'workflow_dispatch' ||
      (github.event_name == 'push' && contains(github.event.head_commit.message, '[deploy]'))

    runs-on: ubuntu-latest
    steps:
      - name: Run remote script via SSH
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /home/ubuntu/
            bash -l -c './build-and-deploy.sh'

这段工作流配置的意思是:

  • 可以手动触发(GitHub UI 上点击 "Run workflow")CI/CD 工作流。
  • 可以自动触发 CI/CD 工作流,不过要求推送到 main 分支且提交信息含 [deploy] 。
  • 使用 SSH 的配置 SERVER_HOSTSERVER_USERSSH_PRIVATE_KEY 登录目标主机 。
  • 执行一键构建和部署脚本 build-and-deploy.sh

build-and-deploy.yml 需要提交并推送到 GitHub:

复制代码
git add .
git commit -m "Add simple CI/CD workflow"
git push origin main

最后,通过打开 GitHub 仓库 → Actions 标签页,就可以看到是否有 workflow 正在运行(绿色 ✔ 表示成功),还可以查看具体的 CI/CD 日志。

2.3 注意事项

CI/CD 的配置文件 build-and-deploy.yml 中执行任意 shell 命令,不过还是推荐封装好一键构建部署脚本,直接调用这个脚本。很多情况下可以使用这个脚本来进行手动部署。

另外 GitHub Actions 使用的是 非交互式、非登录式 shell,不会加载 .bashrc 或 .profile,环境变量(尤其是 PATH)与手动登录时不同。因此,有两种方案:

  1. 在构建部署脚本的开头显式加载环境。比如:
bash 复制代码
# 用于CI/CD环境配置
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

export LD_LIBRARY_PATH=/home/ubuntu/GISBasic/lib/:/home/ubuntu/GISBasic/lib64/:${LD_LIBRARY_PATH:-} #支持变量 LD_LIBRARY_PATH 未定义或为空
  1. 配置文件 build-and-deploy.yml 执行脚本命令增加 bash -l -c,表示以登录用户的身份启动一个新 shell,并在这个环境中运行脚本。例如这里的:
bash 复制代码
bash -l -c './build-and-deploy.sh'

3. 展望

其实 CI/CD 配置远不是那么简单,随着项目复杂度提升,还可以逐步引入更多工程实践:

  • 基于 Git Tag 的正式发布:当功能稳定时,打一个 v1.0.0 这样的语义化版本标签,自动触发构建并将二进制文件上传到 GitHub Release,方便他人下载使用。
  • 自动化测试集成:在部署前运行单元测试、端到端测试,确保新代码不会破坏现有功能。
  • 多环境支持:区分开发、预发、生产环境,避免直接在生产服务器上"试错"。
  • 基础设施即代码(IaC):用 Ansible、Terraform 等工具管理服务器配置,让环境可复现、可版本控制。
  • 监控与回滚机制:部署后自动检查服务健康状态,异常时自动回退到上一版本。
相关推荐
辣椒酱.2 小时前
github入门与实战
github
捧月华如2 小时前
React vs Vue vs Angular:三大前端框架深度对比
python·github
观测云2 小时前
AWS DevOps Agent 接入观测云最佳实践
aws·devops·可观测性·观测云
研究点啥好呢10 小时前
Github热门项目推荐 | 创建你的像素风格!
c++·python·node.js·github·开源软件
无限进步_12 小时前
【C++】电话号码的字母组合:从有限处理到通用解法
开发语言·c++·ide·windows·git·github·visual studio
MicrosoftReactor12 小时前
技术速递|使用 Copilot SDK 构建 AI 驱动的 GitHub Issue 分类系统
人工智能·github·copilot
AI成长日志12 小时前
【GitHub开源项目专栏】AI推理优化框架深度解析(上):vLLM架构设计与核心实现
人工智能·开源·github
CV-deeplearning12 小时前
【开源】字节跳动开源 DeerFlow 2.0:一站式 SuperAgent 开发框架,GitHub 星标 5.9 万!
开源·github·deerflow·deerflow 2.0·superagent
信创DevOps先锋13 小时前
DevOps工具链选型新趋势:本土化适配与安全可控成企业核心诉求
运维·安全·devops
牛奶咖啡1313 小时前
DevOps自动化运维实践_ansible-playbook的应用
自动化·云计算·ansible·devops·playbook·playbook的常见使用示例·playbook变量主机命令