【CI/CD·Actions篇】GitHub Actions 入门:Workflow 语法与自托管 Runner
前言GitHub Actions 是增长最快的 CI/CD 平台。如果你在 GitHub 上托管代码它几乎零成本就能跑起 CI。本篇从 Workflow 基础语法到自托管 Runner 配置带你快速上手。一、核心概念GitHub Actions 体系: Workflow工作流 → 一个 .yml 文件定义完整 CI/CD 流程 ├── Event事件 → 触发 Workflow 的条件push、PR、定时等 ├── Job任务 → 一个 Workflow 包含多个 Job │ ├── Step步骤→ 一个 Job 包含多个 Step命令或 Action │ └── Runner → 执行 Job 的环境GitHub 托管或自托管 └── Action → 可复用的 Step 组件类似函数调用二、Workflow 语法详解基本结构# .github/workflows/ci.yml name: CI Pipeline # 触发条件 on: push: branches: [main, develop] paths: - src/** - pom.xml pull_request: branches: [main] schedule: - cron: 0 2 * * * # 每天凌晨2点 workflow_dispatch: # 手动触发 inputs: environment: description: 部署环境 required: true default: dev type: choice options: [dev, staging, prod] # 全局环境变量 env: APP_NAME: myapp JAVA_VERSION: 17 jobs: build: runs-on: ubuntu-latest env: MAVEN_OPTS: -Dmaven.repo.local.m2 steps: - uses: actions/checkoutv4 - uses: actions/setup-javav4 with: java-version: ${{ env.JAVA_VERSION }} distribution: temurin cache: maven - run: mvn clean package -DskipTests - uses: actions/upload-artifactv4 with: name: app-jar path: target/*.jar retention-days: 7触发条件on# 多种触发方式组合 on: # Push 到特定分支 push: branches: [main, release/*] tags: [v*] paths-ignore: [docs/**, *.md] # PR 到 main pull_request: branches: [main] # 定时 schedule: - cron: 0 2 * * 1-5 # 工作日凌晨2点 # 手动触发 workflow_dispatch: inputs: debug: description: Enable debug mode type: boolean default: false # 其他 Workflow 完成后触发 workflow_run: workflows: [Build] types: [completed] branches: [main] # 仓库事件 issues: types: [opened, labeled] # 外部 Webhook repository_dispatch: types: [deploy]Job 和 Stepjobs: # 并行执行的 Job lint: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - run: npm ci - run: npm run lint test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - run: npm ci - run: npm test # Job 的条件执行 if: github.event_name pull_request # 依赖前面 Job 的 Job deploy: needs: [lint, test] # 等 lint 和 test 都完成 runs-on: ubuntu-latest if: github.ref refs/heads/main steps: - run: ./deploy.sh条件表达式steps: # if 条件 - name: Deploy to prod if: github.ref refs/heads/main github.event_name push run: ./deploy.sh prod # 基于上一步的输出 - name: Test result if: ${{ steps.build.outcome success }} run: echo Build succeeded - name: Handle failure if: ${{ steps.build.outcome failure }} run: echo Build failed # 基于 GitHub 上下文 - name: PR comment if: github.event_name pull_request run: echo This is a PR build # Job 条件 jobs: deploy-prod: if: | github.ref refs/heads/main github.event_name push runs-on: ubuntu-latest矩阵构建Matrixjobs: test: runs-on: ubuntu-latest strategy: matrix: # 多版本并行测试 java: [17, 21] os: [ubuntu-latest, windows-latest] exclude: - os: windows-latest java: 21 # 排除特定组合 steps: - uses: actions/checkoutv4 - uses: actions/setup-javav4 with: java-version: ${{ matrix.java }} - run: mvn test三、Actions 复用使用 Marketplace 中的 Actionsteps: # 检出代码几乎所有 Workflow 第一步 - uses: actions/checkoutv4 with: fetch-depth: 0 # 获取完整历史用于 changelog 生成 # 缓存依赖 - uses: actions/cachev4 with: path: | ~/.m2/repository ~/.gradle key: ${{ runner.os }}-deps-${{ hashFiles(**/pom.xml) }} restore-keys: | ${{ runner.os }}-deps- # 上传产物 - uses: actions/upload-artifactv4 with: name: app path: target/*.jar # 下载产物跨 Job - uses: actions/download-artifactv4 with: name: appSecrets 和变量# 在 GitHub → Settings → Secrets and variables → Actions 中配置 steps: # 使用 Secret - name: Docker login run: docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASS }} # 使用环境变量非敏感 - name: Build env: APP_ENV: ${{ vars.APP_ENV }} run: npm run build # 从 Secret 读取 Docker Hub 密码 - name: Push image run: | echo ${{ secrets.DOCKER_PASS }} | docker login -u ${{ secrets.DOCKER_USER }} --password-stdin docker push myapp:${{ github.sha }}**踩坑提示**GitHub Secrets 只在 Actions 运行时注入到环境变量中日志中会显示为 ***。但如果你的脚本不小心把 Secret 输出到文件或日志Mask 不会生效。一定不要用 echo $SECRET 或 cat $SECRET_FILE。四、自托管 Runner为什么要自托管| 场景 | GitHub 托管 | 自托管 ||------|-----------|--------|| 开源项目 | 免费 | 不需要 || 私有仓库 | 有免费额度 | 可能需要 || 内网部署 | 不行 | 必须 || 特殊硬件GPU | 不行 | 必须 || 自定义环境 | 不行 | 必须 |添加自托管 Runner在 GitHub 仓库 → Settings → Actions → Runners → New self-hosted runner# Linux 服务器上操作 # 创建 Runner 目录 mkdir actions-runner cd actions-runner # 下载 RunnerURL 从 GitHub 页面获取 curl -o actions-runner-linux-x64-2.317.0.tar.gz -L \ https://github.com/actions/runner/releases/download/v2.317.0/actions-runner-linux-x64-2.317.0.tar.gz # 解压 tar xzf actions-runner-linux-x64-2.317.0.tar.gz # 配置Token 从 GitHub 获取有时效性 ./config.sh --url https://github.com/your-org/your-repo --token YOUR_TOKEN --labels linux,java,docker # 安装为系统服务 sudo ./svc.sh install sudo ./svc.sh start # 验证状态 sudo ./svc.sh status在 Workflow 中使用自托管 Runnerjobs: build: # 使用 GitHub 托管 runs-on: ubuntu-latest deploy: # 使用自托管 Runner runs-on: [self-hosted, linux, java] # labels 中必须全部匹配 docker-build: # 需要 Docker 的自托管 Runner runs-on: [self-hosted, docker]Runner 组管理在组织级别添加 Runner可用于组织下所有仓库# 组织级 Runner ./config.sh --url https://github.com/your-org --token YOUR_TOKEN --labels org-runner # 在 Workflow 中使用 runs-on: [self-hosted, org-runner]**培训要点**自托管 Runner 的安全风险是——Runner 可以访问你的私有仓库代码。不要让不受信任的人有权限触发 Runner 上的 Workflow尤其 PR 触发时。用 environment 保护生产部署的 Job。五、实战完整 Spring Boot 项目 Workflow# .github/workflows/ci-cd.yml name: CI/CD on: push: branches: [main] tags: [v*] pull_request: branches: [main] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: # 构建 build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-javav4 with: java-version: 17 distribution: temurin cache: maven - run: mvn clean package -DskipTests - uses: actions/upload-artifactv4 with: name: app-jar path: target/*.jar # 测试并行 unit-test: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-javav4 with: java-version: 17 distribution: temurin cache: maven - run: mvn test - uses: dorny/test-reporterv1 if: always() with: name: Test Results path: target/surefire-reports/TEST-*.xml reporter: java-junit sonar: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-javav4 with: java-version: 17 distribution: temurin - run: mvn verify sonar:sonar -Dsonar.token${{ secrets.SONAR_TOKEN }} # Docker 构建 docker: needs: [unit-test] runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkoutv4 - uses: actions/download-artifactv4 with: name: app-jar path: target/ - uses: docker/login-actionv3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/metadata-actionv5 id: meta with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | typesha typeref,eventtag typeraw,valuelatest,enable${{ github.ref refs/heads/main }} - uses: docker/build-push-actionv5 with: context: . push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} # 部署 deploy: needs: [docker] runs-on: [self-hosted, k8s] if: startsWith(github.ref, refs/tags/v) environment: production steps: - run: | kubectl set image deployment/myapp \ app${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ github.sha }} \ -n prod kubectl rollout status deployment/myapp -n prod --timeout300s六、本篇要点回顾1. Workflow 用on定义触发jobs定义任务每个 Job 有多个steps2.needs控制 Job 依赖if控制条件执行matrix实现并行多版本测试3. Marketplace Actions 用uses调用Secrets 用secrets.XXX引用4. 自托管 Runner 用runs-on: [self-hosted, label]匹配5.environment: production保护生产部署 Job需要人工审批下一篇预告《进阶实战复合 Action 开发与 Marketplace 利用》——从使用别人的 Action 到开发自己的 Action实现 CI/CD 代码复用。

相关新闻

示波器时基与基础测量入门

示波器时基与基础测量入门

面向新入行硬件测试工程师、硬件工程师、嵌入式工程师的技术科普 1. 调整示波器的时基,就是调整什么? 调整示波器的时基,本质上是在调整屏幕横轴的时间刻度,也就是: 每一格代表多少时间英文常见叫法: Time Base Horizontal Scale Time/Div s/div sec/div比如示波器…

2026/10/21 4:48:16 阅读更多 →
原神7.0前瞻内容介绍 mac可以玩原神吗

原神7.0前瞻内容介绍 mac可以玩原神吗

原神7.0前瞻放出的信息量极大,不仅敲定了上线日期,还曝光了地图、角色、战斗机制与限时福利,直接拉高了玩家对新版本的期待。不少Mac玩家发愁设备没法原生运行游戏,想要第一时间探索雪原秘境,吃透原神7.0前瞻里的玩法内…

2026/10/24 16:36:26 阅读更多 →
双机热备旁挂组网实验

双机热备旁挂组网实验

需求:sw3的流量 正常:sw1--->FW1--->sw1--->R5 故障:sw2--->FW2--->sw2--->R6 sw4的流量 正常:sw2--->FW2--->sw2--->R6 故障:sw1--->FW1--->sw1--->R5 sw1和sw2是核心层设备&…

2026/10/24 0:30:15 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/27 17:33:32 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/27 7:21:53 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/27 18:20:50 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 13:55:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/27 7:21:50 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →