Jenkins+Ansible-playbook自动发布回滚

发布需求

  1. 代码发布时,无感更新

  2. 更新失败或代码问题,回退

  3. 可以回退到历史构建

  4. 多代码分支名称对应远程多目录名称

Jenkins 相关

1、变量配置

2、源码管理

3、构建环境

4、Build Steps


# ---------------------------------------------------------- 自动获取分支,不动 ----------------------------

remote_host=<you-remote-address>
directory=$(echo $GIT_BRANCH | sed 's/origin\///')
backup_number=${BUILD_NUMBER}
source="${WORKSPACE}/dist"
target="/data/front/${directory}/dist"
ansibleFile=/usr/local/src/jenkins-ansible/singe-agent-deploy.yml

echo -e "主机: ${remote_host}\n分支: ${directory}\n构建号: ${backup_number}\n源目录: ${source}\n远程目录: ${target}"

case $deploy_status in
    update)
    	echo "Handler $deploy_status"
        pnpm i
        pnpm run build
        # 检查编译结果
        if [ $? -eq 0 ]; then
            echo "PNPM 编译成功"
        else
            echo "PNPM 编译失败"
            exit 1
        fi
        
        ## 判断是否已打包完成
        if [ ! -d "${WORKSPACE}/dist" ];then
           echo "Can't find ${WORKSPACE}/dist, Are you sure, Do u build?"
           exit 1
        fi

        ## 执行同步
        ansible-playbook ${ansibleFile} --tags $deploy_status --extra-vars "remote_host=${remote_host} directory=${directory} backup_number=${backup_number} source=${source} target=${target}" -v
    ;;
    rollback)
        echo -e "Rollback number ===>>> ${rollback_number}"
        if [[ $rollback_number =~ ^[0-9]+$ ]]; then
            if [[ $rollback_number == 0 ]]; then
                # 回滚上一次,当前构建号 - 1
                getRollbackNumber=$(($backup_number-1))
                ansible-playbook ${ansibleFile} --tags $deploy_status --extra-vars "remote_host=${remote_host} directory=${directory} backup_number=${getRollbackNumber} source=${source} target=${target}" -v
            else
                # 回滚到指定构建号
                ansible-playbook ${ansibleFile} --tags $deploy_status --extra-vars "remote_host=${remote_host} directory=${directory} backup_number=${rollback_number} source=${source} target=${target}" -v
            fi
        else
            echo "请传入历史构建数字,默认0,上一次构建"
            exit 1
        fi       
    ;;
esac
  • yml

[root@exc-jenkins jenkins-ansible]# ls
singe-agent-deploy.yml

[root@exc-jenkins jenkins-ansible]# cat singe-agent-deploy.yml 
---
- name: "{{ directory }} 任务执行"
  hosts: "{{ remote_host }}"
  vars:
    directory_name: "{{ directory }}"  # 传入的目录名称
    backup_number: "{{ backup }}"  # 传入的备份号
    source_directory: "{{ source }}"  # 传入的源目录路径
    target_directory: "{{ target }}"  # 传入的远程目标目录路径
    backup_directory: "/tmp/{{ directory_name }}_dist_backup_{{ backup_number }}"  # 备份目录路径
  tasks:
    - name: 打印触发的标签
      debug:
        msg: "当前执行的标签为: {{ ansible_play_hosts_all | intersect(play_hosts) }}"

    - name: 备份远程主机上的目录
      become: yes
      command: cp -r "{{ target_directory }}" "{{ backup_directory }}"
      args:
        creates: "{{ backup_directory }}"
      tags:
        - update

    - name: 复制目录到远程主机
      synchronize:
        src: "{{ source_directory }}/"
        dest: "{{ target_directory }}/"
        delete: yes   # 删除目标目录中不存在于源目录中的文件
        recursive: yes
        compress: yes
        checksum: yes
      tags: 
        - update

    - name: "检查远程目录 {{ backup_directory }} 是否存在"
      stat:
        path: "{{ backup_directory }}"
      register: directory_status
      tags:
        - rollback

    - name: 如果不存在,打印目录状态
      debug:
        msg: "远程目录不存在: {{ backup_directory }}"
      when: not directory_status.stat.exists
      tags:
        - rollback

    - name: 回滚操作 To "{{ backup_number }}"
      shell: "cd {{ target_directory }} && cd .. && mv dist /tmp/{{ directory_name }}_dist_before_rollback_{{ backup_number }}_{{ ansible_date_time.date }} && mv {{ backup_directory }} dist"
      when: directory_status.stat.exists
      tags:
        - rollback

Last updated