
1. 引言在现代 DevOps 实践中GitHub Actions 已成为最流行的 CI/CD 平台之一。它不仅能够自动化构建、测试和部署流程还能承担大量运维任务如自动清理资源、监控仓库状态、定时执行脚本、自动发布版本等。本文将从实战角度出发通过完整的代码示例带你掌握 GitHub Actions 在自动化运维中的核心用法。2. 基础概念与准备工作2.1 什么是 GitHub ActionsGitHub Actions 是 GitHub 提供的持续集成与持续交付CI/CD平台允许你在仓库中定义工作流Workflow自动响应代码推送、Issue 创建、PR 合并等事件或按计划定时执行任务。2.2 核心概念Workflow工作流一个可配置的自动化流程定义在.github/workflows/目录下的 YAML 文件中。Job作业工作流中的一个任务单元多个 Job 可以并行或串行执行。Step步骤Job 中的单个操作可以是运行命令、执行脚本或调用 Action。Action动作可复用的自定义应用可以从 GitHub Marketplace 获取或自己编写。Runner运行器执行工作流的服务器可以是 GitHub 托管的Ubuntu/Windows/macOS或自托管的。2.3 准备工作开始之前请确保拥有一个 GitHub 账号并创建了目标仓库。仓库中已包含需要运维的项目代码。了解基本的 YAML 语法。可选准备好云服务商的 API Token 或 SSH 密钥用于远程操作。3. 第一个自动化运维工作流3.1 创建基础工作流文件在仓库根目录创建.github/workflows/ops-demo.yml文件name: 自动化运维演示 on: push: branches: [ main ] schedule: - cron: 0 2 * * * # 每天 UTC 2:00 执行 workflow_dispatch: # 支持手动触发 jobs: health-check: runs-on: ubuntu-latest steps: - name: 检出代码 uses: actions/checkoutv4 - name: 检查系统状态 run: | echo 磁盘使用情况 df -h echo 内存使用情况 free -h echo 运行中的进程 ps aux --sort-%mem | head -10 name: 检查网络连通性 run: | echo 检查 GitHub 连通性... curl -s -o /dev/null -w %{http_code} https://api.github.com echo echo 检查外部服务... curl -s -o /dev/null -w %{http_code} https://example.com3.2 触发与查看结果将文件推送到main分支后进入仓库的Actions标签页即可看到工作流运行。每次推送会自动触发同时每天凌晨 2 点也会自动执行一次健康检查。4. 定时任务自动清理与备份4.1 自动清理过期 ArtifactsGitHub Actions 生成的 Artifacts 会占用存储空间以下工作流定期清理 7 天前的产物name: 清理过期 Artifacts on: schedule: - cron: 0 6 * * 0 # 每周日 UTC 6:00 workflow_dispatch: jobs: cleanup: runs-on: ubuntu-latest steps: - name: 获取并删除过期 Artifacts env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPO: ${{ github.repository }} run: | # 获取所有 Artifacts artifacts$(gh api /repos/$REPO/actions/artifacts --jq .artifacts[]) # 计算 7 天前的时间戳 cutoff$(date -d 7 days ago %s) echo 开始清理 7 天前的 Artifacts... echo $artifacts | while read -r artifact; do created_at$(echo $artifact | jq -r .created_at) created_ts$(date -d $created_at %s) name$(echo $artifact | jq -r .name) id$(echo $artifact | jq -r .id) if [ $created_ts -lt $cutoff ]; then echo 删除过期 Artifact: $name (ID: $id) gh api -X DELETE /repos/$REPO/actions/artifacts/$id fi done echo 清理完成/code/pre 4.2 自动备份仓库到外部存储 将仓库完整备份到 AWS S3 或阿里云 OSS name: 仓库自动备份 on: schedule: cron: 0 4 * * * # 每天 UTC 4:00 workflow_dispatch: jobs: backup-to-s3: runs-on: ubuntu-latest steps: name: 检出完整仓库含所有分支和标签 uses: actions/checkoutv4 with: fetch-depth: 0 # 拉取完整历史 name: 打包仓库 run: | TIMESTAMP$(date %Y%m%d_%H%M%S) REPO_NAME$(echo ${{ github.repository }} | tr / ) ARCHIVE_NAME${REPO_NAME}${TIMESTAMP}.tar.gz tar -czf $ARCHIVE_NAME --exclude.git . echo ARCHIVE_NAME$ARCHIVE_NAME $GITHUB_ENV echo 备份包大小: $(du -h $ARCHIVE_NAME | cut -f1) name: 上传到 S3 env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: us-east-1 S3_BUCKET: ${{ secrets.S3_BACKUP_BUCKET }} run: | aws s3 cp ${{ env.ARCHIVE_NAME }} s3://$S3_BUCKET/backups/${{ env.ARCHIVE_NAME }} echo 备份已上传到 S3: s3://$S3_BUCKET/backups/${{ env.ARCHIVE_NAME }} name: 清理本地备份文件 run: rm -f ${{ env.ARCHIVE_NAME }} 自动发布版本与生成 Release Notes 5.1 语义化版本自动发布 当推送符合语义化版本规范的标签时自动创建 Release 并生成变更日志 name: 自动发布版本 on: push: tags: v* # 匹配 v1.0.0、v2.1.3 等标签 jobs: release: runs-on: ubuntu-latest permissions: contents: write steps: name: 检出代码 uses: actions/checkoutv4 with: fetch-depth: 0 name: 生成变更日志 id: changelog run: | 获取上一个标签 PREV_TAG$(git tag --sort-creatordate | sed -n 2p) if [ -z $PREV_TAG ]; then echo 这是第一个版本无历史对比 CHANGELOG## 初始版本\n\n- 首次发布 else echo 对比范围: $PREV_TAG - ${{ github.ref_name }} CHANGELOG$(git log $PREV_TAG..${{ github.ref_name }} --prettyformat:- %s (%h) --no-merges) fi 将多行内容写入环境变量 echo CHANGELOGlt;lt;EOF gt;gt; $GITHUB_ENV echo -e $CHANGELOG gt;gt; $GITHUB_ENV echo EOF gt;gt; $GITHUB_ENV name: 创建 Release uses: softprops/action-gh-releasev2 with: name: Release ${{ github.ref_name }} body: | 版本 ${{ github.ref_name }} 变更内容 ${{ env.CHANGELOG }} 安装说明 请参考项目文档获取最新版本。 draft: false prerelease: false generate_release_notes: false 6. 自动 Issue 与 PR 管理 6.1 自动标记和分类 Issue name: Issue 自动分类 on: issues: types: [opened] jobs: triage: runs-on: ubuntu-latest permissions: issues: write steps: name: 根据标题添加标签 uses: actions/github-scriptv7 with: script: | const title context.payload.issue.title.toLowerCase(); const labels []; if (title.includes(bug) || title.includes(错误) || title.includes(故障)) { labels.push(bug); } if (title.includes(feature) || title.includes(功能) || title.includes(需求)) { labels.push(enhancement); } if (title.includes(doc) || title.includes(文档)) { labels.push(documentation); } if (title.includes(urgent) || title.includes(紧急) || title.includes(critical)) { labels.push(urgent); } if (labels.length gt; 0) { await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.issue.number, labels: labels }); } name: 自动回复新 Issue uses: actions/github-scriptv7 with: script: | const body 感谢你提交 Issue 自动回复 你的问题已收到维护团队会尽快处理。 请确认以下信息 是否已搜索过类似 Issue 是否提供了复现步骤 是否附带了相关日志或截图 amp;gt; 这是一个自动回复请勿回复此消息。; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.issue.number, body: body });/code/pre 6.2 自动关闭过期 Issue name: 关闭过期 Issue on: schedule: cron: 0 0 * * # 每天 UTC 0:00 workflow_dispatch: jobs: stale: runs-on: ubuntu-latest permissions: issues: write pull-requests: write steps: uses: actions/stalev9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 此 Issue 已超过 30 天无活动将被标记为过期。如果仍需处理请回复。 stale-pr-message: 此 PR 已超过 30 天无活动将被标记为过期。 close-issue-message: 由于长期无活动此 Issue 已被自动关闭。 close-pr-message: 由于长期无活动此 PR 已被自动关闭。 days-before-stale: 30 days-before-close: 7 stale-issue-label: stale stale-pr-label: stale exempt-issue-labels: pinned,security exempt-pr-labels: pinned,security 安全扫描与合规检查 7.1 依赖安全扫描 name: 安全扫描 on: push: branches: [ main, develop ] pull_request: branches: [ main ] schedule: cron: 0 8 * * 1 # 每周一 UTC 8:00 jobs: security-scan: runs-on: ubuntu-latest steps: uses: actions/checkoutv4 name: 运行 Trivy 漏洞扫描 uses: aquasecurity/trivy-actionmaster with: scan-type: fs scan-ref: . format: sarif output: trivy-results.sarif severity: CRITICAL,HIGH name: 上传扫描结果到 GitHub Security uses: github/codeql-action/upload-sarifv3 with: sarif_file: trivy-results.sarif name: 检查 Secrets 泄露 uses: gitleaks/gitleaks-actionv2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} name: 运行 Dependency Check uses: dependency-check/Dependency-Check_Actionmain with: project: my-project path: . format: HTML out: reports env: JAVA_HOME: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/17.0.9-9/x64 多环境部署自动化 8.1 环境审批与自动部署 name: 多环境部署 on: push: branches: develop staging main jobs: test: runs-on: ubuntu-latest steps: uses: actions/checkoutv4 name: 运行测试 run: | echo 运行单元测试... npm test 或 mvn test 等 echo 所有测试通过 deploy-dev: needs: test if: github.ref refs/heads/develop runs-on: ubuntu-latest environment: name: development url: https://dev.example.com steps: name: 部署到开发环境 run: | echo 部署到开发服务器... scp 或 rsync 或 kubectl 命令 echo 部署完成: https://dev.example.com deploy-staging: needs: test if: github.ref refs/heads/staging runs-on: ubuntu-latest environment: name: staging url: https://staging.example.com steps: name: 部署到预发布环境 run: | echo 部署到预发布服务器... echo 部署完成: https://staging.example.com deploy-production: needs: test if: github.ref refs/heads/main runs-on: ubuntu-latest environment: name: production url: https://example.com steps: name: 等待人工审批 uses: trstringer/manual-approvalv1 with: secret: ${{ secrets.GITHUB_TOKEN }} approvers: admin-team minimum-approvals: 2 issue-title: 生产环境部署审批请求 name: 部署到生产环境 run: | echo 部署到生产服务器... echo 部署完成: https://example.com name: 健康检查 run: | sleep 30 STATUS$(curl -s -o /dev/null -w %{http_code} https://example.com/health) if [ $STATUS ! 200 ]; then echo 健康检查失败 exit 1 fi echo 健康检查通过 监控与告警 9.1 工作流运行状态监控 name: 工作流运行监控 on: workflow_run: workflows: [] types: completed jobs: notify-on-failure: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion failure }} steps: name: 发送失败通知到钉钉 env: DINGTALK_WEBHOOK: ${{ secrets.DINGTALK_WEBHOOK }} run: | WORKFLOW${{ github.event.workflow_run.name }} BRANCH${{ github.event.workflow_run.head_branch }} URL${{ github.event.workflow_run.html_url }} MESSAGE{msgtype:markdown,markdown:{title:工作流运行失败,text:### ⚠️ 工作流运行失败\n\n工作流: $WORKFLOW\n分支: $BRANCH\n仓库: ${{ github.repository }}\n详情: 查看运行日志\n\n请相关同事及时处理}} curl -s -X POST -H Content-Type: application/json -d $MESSAGE $DINGTALK_WEBHOOK name: 发送失败通知到 Slack uses: slackapi/slack-github-actionv1.24.0 with: payload: | { channel: #ops-alerts, username: GitHub Actions Bot, icon_emoji: :robot_face:, text: ⚠️ 工作流 ${{ github.event.workflow_run.name }} 运行失败\n仓库: ${{ github.repository }}\n分支: ${{ github.event.workflow_run.head_branch }}\n查看详情: ${{ github.event.workflow_run.html_url }} } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} 最佳实践与优化建议 10.1 性能优化 缓存依赖使用 actions/cache 缓存 npm、Maven、pip 等依赖包减少重复下载。 矩阵构建使用 strategy.matrix 并行测试多个版本或平台。 条件执行利用 if 条件跳过不必要的步骤。 Job 并行化将无依赖的 Job 设置为并行执行。 10.2 安全最佳实践 最小权限原则为 GITHUB_TOKEN 设置最小必要权限。 Secrets 管理敏感信息使用 GitHub Secrets 存储不要在 YAML 中硬编码。 第三方 Action 审查使用前检查 Action 源码优先使用官方或经过验证的 Action。 环境隔离为不同环境dev/staging/prod配置独立的 Environment 和 Secrets。 10.3 可维护性建议 复用工作流将通用步骤抽取为可复用的 Composite Action 或 Reusable Workflow。 命名规范工作流、Job、Step 使用有意义的名称便于排查问题。 日志输出在关键步骤添加详细的日志输出方便调试。 版本锁定使用 Action 的精确版本号如 v4.1.0而非大版本如 v4避免意外更新导致兼容性问题。 总结 本文从实战角度出发详细介绍了 GitHub Actions 在自动化运维中的多种应用场景包括 基础健康检查与定时任务 自动清理与备份 版本发布与 Release Notes 生成 Issue 与 PR 自动管理 安全扫描与合规检查 多环境部署与审批流程 监控告警集成 通过这些实战代码示例你可以快速搭建起一套完整的自动化运维体系。建议先从简单的健康检查工作流开始逐步增加更复杂的运维任务最终实现全面的自动化运维覆盖。