用Typescript写自动化工作流

项目地址:acao

挺早之前写过一个工具帮我构建项目并发布到指定平台,主要流程就是获取项目根目录下的配置文件,然后根据配置文件在本地通过 docker 构建一个镜像然后 push 到镜像仓库,最后通过 ssh 连接指定的服务区执行发布任务

但是随着需求的增长项目就愈发臃肿,可能会存在多个镜像仓库,发布到多个平台,有可能是通过 docker-compose 管理 也有可能是 kubectl

要怎么办?

于是我在考虑有没有可能有个工具来帮助我自动化在本地或者远程执行一些任务,而我并不关心任务的内容

同时为了方便使用,需要支持继承本地或者远程的预设配置,让我可以很方便的从之前的工具过渡到新的方案上

他们都是怎么做的?

对于团队来说,可能会有现成的 jenkins 或者 git 平台的 runner,这种方案可以说并没有什么不能实现的,但是对于个人项目或者希望依赖本地环境做一些构建的情况下可能有点 太 重 了

或许也会考虑类似 GitHub Actions 的方式执行一些工作流,但是感觉对命令执行的结果不太好处理并提供给之后的流程

用 ts 写工作流

用编程的方式可能会提高一点使用门槛,但是对于程序员来说真的很方便,在这里向大家介绍一下最近开发的一个工具 acao 已经用在一些个人项目和部分公司业务代码中,基础功能应该没啥问题(欢迎 issue 讨论哦

接下来让我们看看要怎么用叭!

依赖处理 / 初始化

首先还是先安装一下,虽然也可以直接通过 npx 执行,但是对于 js 项目,使用暴露出来的一些辅助函数和预设都会比较方便

pnpm add acao -D

在项目根目录新建一个 acao.config.ts 文件,并先写一个简单的命令

import { defineConfig } from 'acao'

export default defineConfig({
	jobs: {
		ci: {
			steps: ['echo ci']
		}
	}
})

这个工作流定义了一个 名为 ci 的 job 而且只有一个步骤,执行命令 echo ci 通过 npx acao 执行预期结果将会在控制台输出 ci 字符串,相信如果有 GitHub Actions 使用经验的小伙伴看起来应该还是有点眼熟的,数据结构的部分会有参考

如果对此完全陌生的小伙伴先可以简要介绍一下,这个配置的作用是定义一个工作流,一个工作流中可能会包含多个 job 数据类型是 Record<string, AcaoJob> key 是当前这个 job 的名称,多个 job 如果没有 needs 定义的依赖关系则默认同步执行,在 job 中需要定义 steps 数组作为具体执行步骤 steps 会按顺序执行

举个栗子

纯文字看起来还是有点抽象,接下来我们来实际完成一个工作流来熟悉一下

通常对于容器化前端 csr 项目的发布流程是,先生成静态文件,然后 build 一个 docker 镜像,最后推送到镜像仓库,这些会作为构建流程

而发布流程如果是 docker compose 的话则是登陆到指定服务器,然后替换掉 docker compose 中指定 service 的 image 最后 up 一下服务(简化一下

那么我们先通过 acao 来实现一下构建流程

import { defineConfig, run } from 'acao'

const HARBOR_HOST = 'HARBOR_HOST'
const HARBOR_USERNAME = 'HARBOR_USERNAME'
const HARBOR_PASSWORD = 'HARBOR_PASSWORD'
const IMAGE = `${HARBOR_HOST}/frontend`

export default defineConfig({
  jobs: {
    ci: {
      steps: [
        'npm run build',
        run('git log --format="%ad-%h" --date=format:%Y%m%d -1', { transform: stdout => `${IMAGE}:${JSON.parse(stdout)}` }),
        run((tag) => `docker build -t ${tag} . --platform linux/amd64`)
        `docker login ${HARBOR_HOST} --username ${HARBOR_USERNAME} --password ${HARBOR_PASSWORD}`,
        run((_, ctx) => `docker push ${ctx.outputs.ci[1]}`),
      ],
    }
  },
})

在上面这个例子中,我们新引入了一个 run 函数,他同样可以和字符串一样被使用在 job steps 中来执行某个命令,在 acao 中字符串的方式是 run 函数没有特殊需求的一种简写 ‘echo ci’ 与 run(’echo ci’) 是等价的,而 run 函数提供了一些其他方法来帮助我们更好的处理命令之间的 pipeline

对于 run 的类型申明如下

type RunCmd<T = string> = T | ((prev: any, ctx: AcaoContext) => T | Promise<T>);

interface RunOptions extends ExecaOptions {
    ssh: boolean;
    transform: (stdout: string) => any | Promise<any>;
    beforeExec: (ctx: AcaoContext) => any | Promise<any>;
    afterExec: (ctx: AcaoContext) => any | Promise<any>;
}

declare function run(cmd: RunCmd, options?: Partial<RunOptions>): AcaoJobStep;

这样看起来可能有点抽象,我们结合例子来说明一下

run('git log --format="%ad-%h" --date=format:%Y%m%d -1', { transform: stdout => `${IMAGE}:${JSON.parse(stdout)}` }),

这个命令是通过 git 命令获取最近一条 commit 的 short_hash 和 日期并拼接成指定格式作为 image 的 tag 而 run 的第二个参数提供了一个 transform 参数来处理输出,拼上完整的 image 名称作为当前这个 step 的输出提供给其他 step 使用

接下来我们需要用到这条命令的输出并通过 docker 构建一个镜像

run((tag) => `docker build -t ${tag} . --platform linux/amd64`)

run 的命令支持使用一个一个返回值为字符串的函数,回调的第一个参数是上一条命令的输出,我们已经处理成完成的镜像名所以可以直接使用

接下来登陆并推送本地镜像到镜像仓库,我们主要看推送的命令

run((_, ctx) => `docker push ${ctx.outputs.ci[1]}`),

这一步我们同样需要用到处理好的镜像名称,但是对于当前这一步来说上一步的输出结果已经不是我们所期望的了,当然我们也可以通过 git 命令再获取一次,或者通过回调的第二个参数获取上下文中某个 step 的输出

ctx.outputs 中有当前不同 job 执行过所有命令的输出结果,可以通过 job 名称和 step index 获取到具体某条的结果

用一些预设

对于一些常用的命令 acao 也提供了一些预设来方便 steps 的创建,比如 volta / docker 让我们简化一下之前的 ci 流程

import { defineConfig, run } from 'acao'
import { voltaRun } from 'acao/volta'
import { dockerBuild, dockerLogin, dockerPush } from 'acao/docker'

const HARBOR_HOST = 'HARBOR_HOST'
const HARBOR_USERNAME = 'HARBOR_USERNAME'
const HARBOR_PASSWORD = 'HARBOR_PASSWORD'
const IMAGE = `${HARBOR_HOST}/frontend`

export default defineConfig({
  jobs: {
    ci: {
      steps: [
        voltaRun('npm run build', { node: '10.24.1' }),
        run('git log --format="%ad-%h" --date=format:%Y%m%d -1', { transform: stdout => `${IMAGE}:${JSON.parse(stdout)}` }),
        dockerBuild(tag => ({ tag, platform: 'linux/amd64' })),
        dockerLogin(HARBOR_HOST, { username: HARBOR_USERNAME, password: HARBOR_PASSWORD }),
        dockerPush((_, ctx) => ctx.outputs.ci[1]),
      ],
    },
})

具体预设的使用方式可以看看 文档 这里就不过多展开了,函数的方式由于提供了比较好的类型提示,所以比字符串命令的形式还是友好很多

一些远程命令

那么对于发布流程,我们不可避免的需要通过 ssh 链接一些远程服务执行一些操作,对于这种需求 acao 也提供了一种简单的方式

import { defineConfig, run } from 'acao'

export default defineConfig({
  jobs: {
    ci: {
      steps: [],
    },
    
    cd: {
	    needs: ['ci'],
	    
	    ssh: {
		    host: 'HOST',
		    username: 'USERNAME',
        password: 'PASSWORD',
	    },
	    
	    steps: [
		    run('cd /data/docker_compose && docker-compose up -d'),
	    ]
    },
  },
}

在 job 中定义了 ssh 默认 steps 中执行的都是远程命令,也可以在 run 的第二个参数中指定 ssh: false 来混合执行和远程过命令,而且同样支持所有本地的方法比如 transform 和 ctx

在例子中可以看到 needs 参数,对于没有定义依赖的 job 默认会同步执行,而 needs 参数用来定义 job 的依赖 acao 会以此进行拓扑排序,存在循环依赖的话则所有任务都不会执行

最后

acao 的命令还有一些其他用法,比如指定执行某个 job 或者忽略依赖 通过命令行参数的方式注入等等,详细使用方式可以查看 文档

这个项目最近也在持续更新中,后续也会支持更多的预设,web ui 的操作方式也在计划中

小伙伴想参与预设的开发也欢迎 pr 呀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/583980.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IC设计数据传输 如何能保障安全高效?

IC&#xff08;集成电路&#xff09;设计数据&#xff0c;对于IC设计企业来说&#xff0c;其重要性不言而喻。所以IC设计数据传输过程中&#xff0c;其安全性和效率&#xff0c;也需要有保障。 首先我们来看看IC设计数据为什么重要&#xff0c;其重要性体现在多个方面&#xff…

edge 入门基础了解使用

随着Windows 11的发布&#xff0c;Microsoft Edge也迎来了新的更新和改进。作为一名长期使用Edge的用户&#xff0c;我不仅注意到了这些表面的变化&#xff0c;还深入研究了Edge在Windows 11上的新特性和潜在优势。 快捷方式 查找框 在Microsoft Edge浏览器中&#xff0c;按…

踩坑Mybatis + Mybatis-plus + MyBatis-plus-join

数据库里有两张表 tb_bursary和tb_student tb_bursary里关联了tb_student.id作为外键 由于tb_student表可以单独操作&#xff0c;而tb_bursary需要联合tb_student查询 所以一开始&#xff0c;我是用mybatis-plus mybaits混合的模式 mybatis-plus单独操作tb_student表&…

学习 Rust 第 22 天:mini_grep 第 2 部分

书接上文&#xff0c;在本文中&#xff0c;我们学习了如何通过将 Rust 程序的逻辑移至单独的库箱中并采用测试驱动开发 (TDD) 实践来重构 Rust 程序。通过在实现功能之前编写测试&#xff0c;我们确保了代码的可靠性。我们涵盖了基本的 Rust 概念&#xff0c;例如错误处理、环境…

小程序SSL证书更新指南

随着网络技术的不断发展&#xff0c;小程序已经成为许多企业和个人进行业务推广和服务提供的重要平台。在享受小程序带来的便利和高效的同时&#xff0c;我们也必须重视其安全性问题。SSL证书作为保障小程序数据传输安全的重要手段&#xff0c;其更新工作不容忽视。本文将为大家…

在线教程|零门槛部署 Llama 3,70B 版本只占 1.07G 存储空间,新用户免费体验 8B 版本

4 月 18 日&#xff0c;Meta 宣布开源 Llama 3&#xff0c;这个号称「迄今为止最好的开源大模型」一经发布&#xff0c;立刻引爆科技圈&#xff01; 发布当天恰逢斯坦福大学教授、AI 顶尖专家吴恩达的生日&#xff0c;作为 AI 开源倡导者&#xff0c;他激动地发文表示&#xff…

CogAgent:开创性的VLM在GUI理解和自动化任务中的突破

尽管LLMs如ChatGPT在撰写电子邮件等任务上能够提供帮助&#xff0c;它们在理解和与GUIs交互方面存在挑战&#xff0c;这限制了它们在提高自动化水平方面的潜力。数字世界中的自主代理是许多现代人梦寐以求的理想助手。这些代理能够根据用户输入的任务描述自动完成如在线预订票务…

【doghead】ubuntu构建libuv

按照官方的文档2024年3月的版本。首先构建libuv 最终构建的还得了test 构建过程 zhangbin@DESKTOP-1723CM1:/mnt/d/XTRANS/thunderbolt/ayame/zhb-bifrost$ ls Bifrost-202403 README.md draw player-only worker 大神的带宽估计.png zhangbin@DESKTOP-1723CM1:/mnt/d/XTRANS/…

计算机网络 备查

OSI 七层模型 七层模型协议各层实现的功能 简要 详细 TCP/IP协议 组成 1.传输层协议 TCP 2.网络层协议 IP 协议数据单元&#xff08;PDU&#xff09;和 封装 数据收发过程 数据发送过程 1. 2.终端用户生成数据 3.数据被分段&#xff0c;并加上TCP头 4.网络层添加IP地址信息…

React + 项目(从基础到实战) -- 第十期

目标 学会react 状态管理工具 使用redux管理用户状态 Context 跨层级传递,不像props层层传递类似于Vue的provide/inject用于:切换主题颜色,切换语言 useReducer useState 的替代方案 简化版的redux MobX 1. MobX 介绍 MobX 中文文档 声明式的修改数据 , 像vue state ac…

【算法基础实验】图论-UnionFind连通性检测之quick-union

Union-Find连通性检测之quick-union 理论基础 在图论和计算机科学中&#xff0c;Union-Find 或并查集是一种用于处理一组元素分成的多个不相交集合&#xff08;即连通分量&#xff09;的情况&#xff0c;并能快速回答这组元素中任意两个元素是否在同一集合中的问题。Union-Fi…

55.基于SpringBoot + Vue实现的前后端分离-旅游管理系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统&#xff0c;采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的旅游管理系统设计与实现管理工作系统…

【Node.js工程师养成计划】之express框架

一、Express 官网&#xff1a;http://www.expressjs.com.cn express 是一个基于内置核心 http 模块的&#xff0c;一个第三方的包&#xff0c;专注于 web 服务器的构建。 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用&…

docker学习笔记3:VmWare CentOS7安装与静态ip配置

文章目录 一、安装CentOS71、下载centos镜像2、安装二、设置静态ip三、xshell连接centos本专栏的docker环境是在centos7里安装,因此首先需要会安装centos虚拟机。 本篇博客介绍如何在vm虚拟机里安装centos7。 一、安装CentOS7 1、下载centos镜像 推荐清华源,下载如下版本 …

使用量排名前50的GPTs趋势和特征

Chatgpt的gpt商店已经有几千gpts了。目前哪些gpts比较受欢迎呢&#xff1f;有哪些趋势和投资呢? 根据whatplugin.ai&#xff08;截止日期为2024年3月&#xff09;&#xff0c;使用量最多的50个gpts数据分析结果如下&#xff1a; GPTs类型的分布情况如下&#xff1a; 图像生成…

案例-部门管理-删除

黑马程序员JavaWeb开发教程 文章目录 一、查看页面原型二、查看接口文档三、开发1、Controller2、Service&#xff08;1&#xff09;service接口层&#xff08;3&#xff09;service实现层 3、Mapper4、Postman 一、查看页面原型 二、查看接口文档 三、开发 1、Controller 因…

Keepalived+LVS实现Nginx集群配置

Nginx1和Nginx2组成集群&#xff0c;为了实现负载均衡&#xff0c;在集群的前端配置了LVS服务&#xff0c;但是一台LVS容器产生单点故障&#xff0c;因此需要过Keepalived实现LVS的高可用集群 192.168.136.55node1keepalived192.168.136.56node2keeplived192.168.136.57 node3n…

Excel 中用于在一个范围中查找特定的值,并返回同一行中指定列的值 顺序不一样 可以处理吗

一、需求 Excel 中&#xff0c;在一列&#xff08;某范围内&#xff09;查找另一列特定的值&#xff0c;并返回同一行中另一指定列的值&#xff0c; 查找列和返回列的顺序不一样 二、 实现 1、下面是一个使用 INDEX 和 MATCH 函数的例子&#xff1a; 假设你有以下数据&…

CI/CD:基于kubernetes的Gitlab搭建

1. 项目目标 &#xff08;1&#xff09;熟悉使用k8s环境搭建Gitlab &#xff08;2&#xff09;熟练应用Gitlab基本配置 2. 项目准备 2.1. 规划节点 主机名 主机IP 节点规划 k8s-master 10.0.1.1 kube_master k8s-node1 10.0.1.2 kube_node k8s-node2 10.0.1.3 k…

影响外汇交易盈利的因素有哪些?

外汇交易就是通过汇率的差价来赚取相应的利润。在外汇交易中&#xff0c;投资者是否可以盈利&#xff0c;主要取决于是否正确的判断了市场趋势和行情。投资者在交易过程中受到主观和客观的因素影响&#xff0c;具体包含这些内容。 影响外汇交易盈利的因素有哪些&#xff1f; 1、…
最新文章