CI/CD是什么
CI/CD 是持续集成(Continuous Integration)和持续部署(Continuous Deployment)或持续交付(Continuous Delivery)的缩写,它们是现代软件开发中用于自动化软件交付过程的实践。
1、持续集成(CI):指的是开发人员频繁(通常是每天多次)将代码变更合并到共享仓库中的实践。每次代码提交后,自动执行构建和测试,以尽早发现并解决集成错误,提高软件质量。
2、持续交付(CD - Continuous Delivery):在持续集成的基础上,自动将代码变更部署到更接近生产环境的测试环境中,以便进行更深入的测试和验证。持续交付确保软件可以随时被部署到生产环境中,但最终的部署动作可能需要手动触发。
3、持续部署(CD - Continuous Deployment):是持续交付的进一步实践,它指的是每当代码变更通过所有的测试阶段后,自动部署到生产环境中。这意味着软件的新版本可以快速且频繁地部署到生产环境中。
CI/CD 的目标是通过自动化测试和部署流程,减少软件开发和发布过程中的手动错误,提高开发效率和软件质量。这通常需要使用专门的工具和平台,如 Jenkins、Travis CI、CircleCI、GitLab CI/CD 和 GitHub Actions 等。
怎么做
这里以GitHub Actions为例,其他的也都类似 GitHub Actions官网
GitHub Actions 的工作流配置文件使用 YAML(.yml 或 .yaml)格式。这些文件位于 GitHub 仓库的 .github/workflows 目录下。在这些 YAML 文件中,你可以定义事件触发器、作业、步骤以及每个步骤使用的动作。
运行器
附位置 =》 运行器

触发
仅列举常用的 附位置 =》 触发工作流
| 触发方式 | 说明 | 
|---|---|
| pull_request | 创建合并请求时,此合并中的所有修改提交都会触发,不包括合并其他分支到主分支 | 
| push | 每次提交修改到远程分支时触发,包括合并其他分支到主分支 | 
区别
 其实二者的触发方式差不多,只不过范围不同,所以使用push时谨慎触发的条件
 可以通过限制分支branch、标签tags、更改的文件路径path等
name: CI
on:
  push:
     ## 以下两个条件是或的关系 
    branches: 
      - master ## 只push到master分支时触发
    tags:
      - v**  ## 标签为以v打头的push触发
    path:
      - src/main/**  ## push的更改文件路径包含src/main下的文件时触发
格式
创建目录文件 .github/workflows/build.yaml,设置工作流触发时机为pull_request即创建合并请求后执行
name: CI  ## 工作流名称
## 工作流的触发时机
on: pull_request  ## 仅在PR(合并请求)触发    
## 作业(任务)
jobs:
  continuous_build: ## 作业名称
    runs-on: ubuntu-latest   ## 运行器环境
    steps: ## 作业步骤
      - name: test
      	run: echo "this is a test step" 
注意github actions 工作流中不允许使用中文
 
情景示例
此情景只适用于测试环境,所以只打包构建到自己的docker hub中。不可用于生产环境,生产环境的配置更复杂,感兴趣的可以了解CI/CD + k8s + rancher
1、在 合并请求 的生命周期,通过自动化工作流提前做一些测试
目标
 在创建合并请求后,在合并之前,每次更改推送都自动执行打包测试(还可以执行 npm run test)
在这之前,由于Gihub Actions具有隔离性,运行在虚拟环境中,每次运行都是在一个干净的环境中开始。所以我们需要在其工作流中做像拉取新项目时的操作如重新npm i
创建目录文件 .github/workflows/build.yaml,设置工作流触发时机为pull_request
name: CI  
on: [pull_request]  
jobs:
  continuous_build: 
    runs-on: ubuntu-latest   
    steps:
      - name:  test
        run:  echo "this is a test step"
      
      - name: checkout  ## 检出代码
        uses: actions/checkout@v3 ## GitHub 提供用于在工作流中检出仓库
      - name: get-hash ## 计算hash,便于缓存
        uses: seepine/hash-files@v1
        id: get-hash
        with: 
          patterns: |-
            package.json
            package-lock.json
      - name: set cache ## 设置缓存
        id: npm-cache
        uses: actions/cache@v3
        with:
          key: coal-manage-${{ steps.get-hash.outputs.hash }} ## 使用项目名称 + 上一步骤的hash
          path: ${{ github.workspace }}/node_modules    ## 上下文表达式,获取执行的工作目录
      - name: install ## 安装依赖
        if: steps.npm-cache.outputs.cache-hit != 'true' ## 判断缓存
        run: npm i --registry=http://registry.npmmirror.com 
        
      - name: build
        run: npm run build

2、在合并分支到主分支时,通过自动化流程做一些部署
目标
 每次合并到主分支或者每次打tag标签发布版本时,通过工作流帮我们打包项目并构建成docker 镜像推送到个人都docker hub中,我们可以直接在本地通过手敲或shell脚本部署。
ps:我也有尝试过直接通过工作流打包然后启动,但是直接访问运行的容器会有一些限制,因为 GitHub Actions 的运行器(runner)是在 GitHub 的虚拟环境中,而不是在本地网络或公开的服务器上。所以需要借助工具或者通过k8s部署,这里暂时不考虑
- 准备docker/Dockerfile
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html/
COPY nginx/nginx.conf /etc/nginx/nginx.conf
EXPOSE 9999
- 准备docker/nginx.conf配置
worker_processes	1;
events {
	worker_connections	1024;
}
http {
	include		/etc/nginx/mime.types;
	default_type	application/octet-stream;
	sendfile	on;
	keepalive_timeout	65;
	server {
		listen	80;
		server_name	localhost;
		location / {
			root	/usr/share/nginx/html;
			index	index.html index.htm;
		}
		error_page	500 502 503 504 /50x.html;
		location = /50x.html {
			root	html;
		}
	}
}
-  在 Docker Hub 创建访问令牌: 1) 登录到 Docker Hub -  进入 Account Settings(账户设置) 
-  选择 Security(安全)选项卡 
-  创建一个新的 Access Token(访问令牌,需要 读写操作)。
-  记下生成的令牌,因为你将需要它来在 GitHub 中配置凭据。 
  
 2) 在 GitHub 仓库中设置 Secrets - 转到你的 GitHub 仓库页面。
- 选择 Settings(设置)> Secrets(密钥)> Actions(操作)。
- 点击 New repository secret(新建仓库密钥)按钮。
- 创建两个密钥:一个用于 Docker Hub 的用户名(例如,DOCKER_USERNAME),另一个用于上一步中生成的访问令牌(例如,DOCKER_PASSWORD)。
  
 
-  
-  创建目录文件 .github/workflows/deploy.yaml,设置触发时机为push master,即当代码被合并到远程仓库时到推送操作执行。
name: CI  
on: 
  push:
    branches:
      - main
jobs:
  continuous_build: 
    runs-on: ubuntu-latest   
    steps:
      
      - name: checkout
        uses: actions/checkout@v3 
      - name: get-hash
        uses: seepine/hash-files@v1
        id: get-hash
        with: 
          patterns: |-
            package.json
            package-lock.json
      - name: set cache
        id: npm-cache
        uses: actions/cache@v3
        with:
          key: coal-trade-web-manage-${{ steps.get-hash.outputs.hash }}
          path: ${{ github.workspace }}/node_modules   
      - name: install
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm i --registry=http://registry.npmmirror.com 
      
      - name: build
        run: npm run build
      
      - name: login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: build and push docker image
        uses: docker/build-push-action@v4
        with:
          context: . ## 执行上下文
          file: docker/Dockerfile  ## Dockerfile路径
          push: true  ## 是否推送
          tags: ${{ secrets.DOCKER_USERNAME }}/my-dockerfile-nginx:${{ github.ref_name }}   ## 标签 docker hub username/镜像名称:版本号(git tag打的标签,不打就是分支名)
合并到主分支、每次打tag标签推送都会执行,执行成功后会显示✅
 
-  可以登录自己的docker hub查看 
  
-  登录docker hub将镜像拉取到本地,直接运行即可 
docker login
# 根据提示输入用户名、密码
docker pull  <username>/<image name>:<tag>

 启动成功返回容器id
# 本地9090端口(访问端口)映射 容器内的端口
docker run --name <container name> -p 9090:80 -d <username>/<image name>:<tag>

 直接访问本地虚拟机ip+端口
 










