
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 自動管理 安全掃描與合規檢查 多環境部署與審批流程 監控告警集成 通過這些實戰代碼示例你可以快速搭建起一套完整的自動化運維體系。建議先從簡單的健康檢查工作流開始逐步增加更復雜的運維任務最終實現全面的自動化運維覆蓋。