.gitlab-ci.yaml 编写说明,示例带注释说明

#  Task 默认在docker里面运行, 运行完成后就删掉, 里面的东西不会保存.

# Task 默认运行使用的docker镜像, 如果Task里面没有指定的话默认使用这个.
image: git.com:9999/docker-image/golang 

# 环境变量 (会自动注入到 Task 运行的 shell 环境中)
variables: 
  CI_REPOSITORY_NAME: git.com/${CI_PROJECT_PATH}
  
  CI_DOCKER_ROOTDIR: "build"
  
# CI 执行的步骤, 此处分为3步: 1. build 2. update 3. deploy, 执行顺序为 1,2,3, 只有前面一个成功后才会执行下面的, 如果前面的执行失败了就直接终止执行.
stages: 
    - build
    - update
    - deploy

# 定义一个变量(或者说C++里的宏?) {.env_init}
.env_init: &env_init | 
  DOCKER_IMAGE="${CI_REGISTRY_IMAGE}"
  DOCKER_IMAGE_TAG="alpha-${CI_PIPELINE_IID}"

  # Fix master
  if [[ "${CI_COMMIT_REF_NAME}" == "master" ]]; then
    DOCKER_IMAGE="test/${CI_PROJECT_NAME}"
    DOCKER_IMAGE_TAG="bata-${CI_PIPELINE_IID}"
  fi

  # Fix tag
  if [[ -n "${CI_COMMIT_TAG}" ]]; then
    DOCKER_IMAGE="test/${CI_PROJECT_NAME}"
    DOCKER_IMAGE_TAG="${CI_COMMIT_TAG}"
  fi

# 定义一个 Task, 名字叫 project_check, 属于步骤: build(如果一个步骤里面有多个Task,这些Task会并发(同时)运行,不同的步骤是按顺序运行)
project_check:
  # 说明这个 Task 属于 build 步骤
  stage: build
  # 有这个说明不用默认的镜像, 比如这里可能不支持默认镜像的版本, 换成 1.9 版本的镜像执行命令.
  image: git.com:9999/docker-image/golang:1.9
  # 环境变量, 这里面定义的是指在这个 Task 里面生效, 最上面那个是全局生效的.
  variables:
    # 这是个特殊环境变量, 指定为 none 说明运行 Task 的时候不要拉仓库的代码, 比如执行的命令用不到仓库里的文件, 要加快速度的话可以指定这个; 
    # 指定为 clone 或者 fetch 代表拉取仓库, 区别和 git 对应的命令一样.
    GIT_STRATEGY: none
  # Task 具体运行的脚本, 按顺序一行一行执行. (Task 实际上就类似于帮你在 shell 里面执行命令, 原来是需要你手动执行,现在是列在这里到时间它自动帮你执行)
  script:
    - setup_golang
    - go fmt $(go list ./... | grep -v /vendor/)
    - go vet $(go list ./... | grep -v /vendor/)
    - go test -race $(go list ./... | grep -v /vendor/)
  # 这里指定什么时候运行, tags 说明打 tag 时候触发运行, branches 说明所有分支都会触发运行, 如果只想 master 分支运行, 这里就写分支名 master.(有多个说明符合任意一个就运行)
  only:
    - tags
    - branches
  # 这个是 gitlab CI 里面 CD 相关的东西, 我目前也没搞明白. 目前感觉用处不大.
  environment:
    # 这里面用来指定 CD 里面的环境的名字
    name: $CI_COMMIT_REF_NAME
    # 当用户点击停止按钮时,运行哪个 Task 来让部署里面的运行停止掉.
    on_stop: stop_k8s

project_compile:
  stage: build
  # 这个是用来指定用哪个环境运行 Task, 需要管理员手动在管理界面添加, 比如某些 Task 不能用 docker 要用 ssh 连到具体的服务器上,就可以用这个来选择使用对应的环境. 
  # 这里面的 root@dev 就代表 ssh 用 root 登录的开发服(172.13.0.53)
  # root@dev 这个是管理员在管理界面添加的, 不是随便填的.
  tags:
    - root@dev
  script:
    - setup_golang
    # ${????} 这种格式是使用 Shell 里面环境变量, ${CI_DOCKER_ROOTDIR} 就代表把这个替换为我们前面定义的环境变量 CI_DOCKER_ROOTDIR
    - mkdir -p ${CI_DOCKER_ROOTDIR}
    - cp -rf conf ${CI_DOCKER_ROOTDIR}
    - CGO_ENABLED=0 go build -ldflags '-extldflags "-static"' -ldflags '-X main.Build=${DOCKER_IMAGE_TAG}' -o ${CI_DOCKER_ROOTDIR}/${CI_PROJECT_NAME}
  # 这里用来指定从 Task 运行环境中把那些文件打包保存下来, 可以通过 gitlab CI 页面右方的下载按钮下载下来.(默认 Task 在docker里面运行,运行完成后就删掉了,里面的东西不会保存)
  artifacts:
    paths:
      - ${CI_DOCKER_ROOTDIR}/
  only:
    - tags
    - test
    - master

update_image:
  tags:
    - docker
  stage: update
  image: git.com:9999/docker-image/docker-stable
  variables:
    GIT_STRATEGY: none
    DOCKER_HOST: tcp://172.13.0.52:2375
    DOCKER_DRIVER: overlay2
  script:
    # 生成服务定义
    - SRV_IMAGE='alpine'
    - SRV_WORKDIR="/${CI_PROJECT_NAME}"

    # 安装 timezone 数据包
    - BUILD_IMAGE_SCRIPT='apk add --no-cache tzdata ca-certificates'
      
    # 生成镜像
    - docker_build ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG} "./${CI_PROJECT_NAME}"
  dependencies:
    - project_compile
  only:
    - tags
    - test
    - master

deploy_k8s:
  tags:
    - kubectl
  stage: deploy
  variables:
    GIT_STRATEGY: fetch
  script:
    # 获取命名空间
    - KUBE_NAMESPACE=`kubectl -n istio-system get configmap ci-deploy -o template --template={{.data.namespace}}` && echo "Use namespace ${KUBE_NAMESPACE}"
    
    # 更新镜像
    - helm template .helm/hallgo --name=hall-go --set image.repository="${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG}" | kubectl -n ${KUBE_NAMESPACE} apply -f -
    - helm template .helm/publisher --name=publisher --set image.repository="${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG}" | kubectl -n ${KUBE_NAMESPACE} apply -f -

    # 更新时区
    - kubectl -n ${KUBE_NAMESPACE} set env deployment/hall-go TZ="Asia/Bangkok" 
    - kubectl -n ${KUBE_NAMESPACE} set env deployment/publisher TZ="Asia/Bangkok" 
  only:
    - test
    - master
  environment:
    name: $CI_COMMIT_REF_NAME
    on_stop: stop_k8s

stop_k8s:
  tags:
    - kubectl
  when: manual
  stage: deploy
  variables:
    GIT_STRATEGY: fetch
  script:
    # 获取命名空间
    - KUBE_NAMESPACE=`kubectl -n istio-system get configmap ci-deploy -o template --template={{.data.namespace}}` && echo "Use namespace ${KUBE_NAMESPACE}"

    # 删除部署
    - helm template .helm/hallgo --name=hall-go --set image.repository="${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG}" | kubectl -n ${KUBE_NAMESPACE} delete -f -
    - helm template .helm/publisher --name=publisher --set image.repository="${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG}" | kubectl -n ${KUBE_NAMESPACE} delete -f -
  only:
    - test
    - master
  environment:
    name: $CI_COMMIT_REF_NAME
    action: stop

# --------------------------------------------------------------------------

# 定义一个变量(或者说C++里的宏?) {.golang_init}
.golang_init: &golang_init | 
  function setup_golang() {
    mkdir -p $GOPATH/src/$(dirname $CI_REPOSITORY_NAME)
    ln -svf $CI_PROJECT_DIR $GOPATH/src/$CI_REPOSITORY_NAME
    cd $GOPATH/src/$CI_REPOSITORY_NAME
  }

# 定义一个变量
.docker_init: &docker_init | 
  function docker_setup() {
    if ! docker info &>/dev/null; then
      if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
        export DOCKER_HOST='tcp://localhost:2375'
      fi
    fi

    if [[ -n "$CI_REGISTRY_USER" ]]; then
      echo "Logging to GitLab Container Registry with CI credentials..."
      docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
      echo ""
    fi
  }

  function docker_build() {
    docker_setup

    _l_ROOTFS=${CI_DOCKER_ROOTDIR}

    _l_DEPLOY_IMAGE=${SRV_IMAGE:-alpine}
    _l_DEPLOY_WORKDIR=${SRV_WORKDIR}
    _l_DEPLOY_ENVIRONMENT=${SRV_ENVIRONMENT}
    
    _l_DEPLOY_SCRIPT=${BUILD_IMAGE_SCRIPT}
    _l_DEPLOY_ENTRYPOINT=${BUILD_IMAGE_ENTRYPOINT}

    _param_TAG=${1}
    _param_CMD=${2}

    if [[ -z "${_param_TAG}" ]]; then
      echo "Building respository address is not null" >&2
      exit -1
    fi

    # if [[ -d "${_param_MERGEDIR}" ]]; then
    #   cp -rf "${_param_MERGEDIR}"/* "${_l_ROOTFS}/"
      
    #   if [[ $? -ne 0 ]]; then
    #     echo "Copy Dockerfile-based dir ${_param_MERGEDIR} to ${_l_ROOTFS} failed" >&2
    #     exit -1
    #   fi
    # fi

    DOCKER_ARGS=""
    DOCKER_FILE="${_l_ROOTFS}/.dockerfile"

    echo "FROM ${_l_DEPLOY_IMAGE}"        >> ${DOCKER_FILE}

    if [[ -n "${_l_DEPLOY_ENVIRONMENT}" ]]; then
      echo "ENV ${_l_DEPLOY_ENVIRONMENT}"   >> ${DOCKER_FILE}
    fi

    echo "WORKDIR ${_l_DEPLOY_WORKDIR}"       >> ${DOCKER_FILE}
    echo "COPY . ."                           >> ${DOCKER_FILE}
    echo "RUN ${_l_DEPLOY_SCRIPT}"            >> ${DOCKER_FILE}
    echo "ENTRYPOINT ${_l_DEPLOY_ENTRYPOINT}" >> ${DOCKER_FILE}
    echo "CMD ${_param_CMD}"                  >> ${DOCKER_FILE}
    echo "Building Dockerfile-based application..."
    cat "${DOCKER_FILE}"
    docker build ${DOCKER_ARGS} -t "${_param_TAG}" -f "${DOCKER_FILE}" "${_l_ROOTFS}"

    echo "Pushing [${_param_TAG}] to GitLab Container Registry..."
    docker push "${_param_TAG}"

    echo ""
  }

# 在运行脚本之前首先先执行啥, 可以放初始化的东西. 每个 Task 运行前都会先运行这个,才会运行 Task 里面的 script
before_script:
  - *env_init
  - *golang_init
  - *docker_init

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值