Posted in

Go语言VS Code环境配置(Mac M2/M3专属版):绕过Rosetta兼容陷阱、arm64-gopls编译失败与Homebrew冲突全解

第一章:Go语言VS Code环境配置(Mac M2/M3专属版):绕过Rosetta兼容陷阱、arm64-gopls编译失败与Homebrew冲突全解

Mac M2/M3芯片采用原生arm64架构,但许多开发者误启Rosetta 2运行x86_64版本Go或VS Code,导致gopls崩溃、调试器失联、模块校验失败等深层兼容问题。关键在于全程保持arm64二进制一致性。

确认并强制使用原生arm64工具链

首先验证当前Shell架构:

uname -m  # 应输出 arm64,非 x86_64
arch     # 同上

若为x86_64,请退出终端并在“终端”App设置中取消勾选“使用Rosetta打开”,重启后重试。

安装arm64原生Go(非Homebrew默认包)

Homebrew默认go公式在M系列Mac上可能拉取x86_64交叉编译包,存在隐式架构降级风险。推荐直接下载官方arm64安装包:

  • 访问 https://go.dev/dl/ → 下载 go1.xx.x.darwin-arm64.pkg
  • 双击安装(路径自动设为 /usr/local/go
  • 验证:/usr/local/go/bin/go version 输出含 darwin/arm64

解决gopls arm64编译失败问题

VS Code的Go扩展默认调用go install golang.org/x/tools/gopls@latest,但若系统PATH混入x86_64 Go路径,将触发编译错误。执行以下清理与重装:

# 彻底清除旧gopls(含缓存)
rm -rf ~/go/bin/gopls
go clean -cache -modcache

# 强制指定arm64 Go路径安装
/usr/local/go/bin/go install golang.org/x/tools/gopls@latest

# 验证架构
file ~/go/bin/gopls  # 输出应含 "arm64"

处理Homebrew多架构冲突

若已通过Homebrew安装过Go,执行:

brew uninstall go
brew cleanup
# 清理残留的x86_64 Homebrew(如存在)
rm -rf /opt/homebrew-x86_64  # 仅当手动安装过Rosetta版Homebrew时需删
项目 正确值 错误信号
which go /usr/local/go/bin/go /opt/homebrew/bin/go(x86_64 Homebrew)
go env GOARCH arm64 amd64
VS Code状态栏Go版本 显示 go1.xx.x darwin/arm64 显示 darwin/amd64 或空白

最后,在VS Code中打开命令面板(Cmd+Shift+P),执行 Go: Install/Update Tools仅勾选 gopls,避免其他工具链引入架构污染。

第二章:M2/M3芯片架构认知与Go原生环境根基重建

2.1 Apple Silicon arm64指令集特性与Go多架构支持原理

Apple Silicon(如M1/M2)基于ARMv8.5-A架构,引入了Pointer Authentication Codes(PAC)Scalable Vector Extension 2(SVE2)预备指令集内存序强化模型(RCpc),显著提升安全性和并行计算效率。

Go语言自1.16起原生支持darwin/arm64,其多架构支持依赖于:

  • 编译时GOOS=darwin GOARCH=arm64触发交叉编译流程
  • runtime/internal/sys中硬编码的ArchFamily = ARM64常量
  • 汇编引导代码(runtime/asm_arm64.s)适配寄存器约定与调用规范

Go构建链对arm64的适配关键点

// src/runtime/proc.go 中的架构相关初始化片段
func archInit() {
    // PAC启用检测(仅Apple Silicon生效)
    if sys.GOOS == "darwin" && sys.GOARCH == "arm64" {
        enablePAC() // 调用内联汇编:PACIA1716 + AUTIA1716
    }
}

该函数在进程启动早期执行,通过PACIA1716指令为LR寄存器注入签名,防止ROP攻击;AUTIA1716用于验证返回地址合法性,参数1716表示使用x17/x16寄存器对生成密钥——这是Apple Silicon专属的安全增强机制。

特性 ARM64通用支持 Apple Silicon扩展
寄存器数量 31×64-bit通用寄存器 新增x29-x30专用PAC上下文寄存器
内存模型 弱序(Weak ordering) RCpc(Release-Consume with partial ordering)
graph TD
    A[go build -o app] --> B{GOARCH=arm64?}
    B -->|Yes| C[调用cmd/compile/internal/arm64]
    C --> D[生成符合AAPCS64 ABI的机器码]
    D --> E[链接runtime/arm64/libgcc.a中的PAC stubs]

2.2 Rosetta 2运行时机制剖析及其对gopls、dlv等工具链的隐式降级危害

Rosetta 2 并非纯解释器,而是动态二进制翻译(DBT)层,在首次执行 x86_64 指令时将其编译为 ARM64 本地指令并缓存。

动态翻译延迟触发点

# 触发 Rosetta 2 翻译缓存生成(如首次运行 dlv)
arch -x86_64 dlv --headless --listen=:2345 --api-version=2 ./main

此命令强制以 x86_64 模式启动调试器;--api-version=2 是 gopls 与 dlv 通信的关键协议标识,但 Rosetta 2 无法透传 CPU 特性信号,导致 runtime.GOARCH 仍报告 arm64,而实际执行流经翻译层——引发调试符号偏移、断点错位等静默故障。

工具链兼容性风险矩阵

工具 原生 ARM64 行为 Rosetta 2 下表现 风险等级
gopls 实时 AST 缓存 + LSP 响应 符号解析延迟 ≥300ms,hover 失效 ⚠️⚠️⚠️
dlv 精确寄存器映射与步进 step-in 跳过内联函数,goroutine list 漏报 ⚠️⚠️⚠️⚠️

调试会话状态同步异常流程

graph TD
  A[gopls 请求 /textDocument/hover] --> B{dlv 发起 eval}
  B --> C[Rosetta 2 翻译 x86_64 debug info]
  C --> D[ARM64 地址空间与 DWARF offset 不匹配]
  D --> E[返回空 hover 内容或 panic]

2.3 验证当前Shell、Terminal、VS Code进程架构的实操诊断流程

快速识别终端与Shell架构

执行以下命令获取进程树及架构信息:

# 查看当前Shell进程及其架构(x86_64 / arm64)
ps -p $PPID -o comm=,args=,pid=,ppid=,vsz= | xargs file /proc/*/exe 2>/dev/null | grep -E "(x86_64|arm64)"

逻辑分析$PPID 指向上层终端进程;file /proc/*/exe 检查可执行文件实际架构,绕过uname -m的内核视图偏差。vsz(虚拟内存大小)辅助判断是否为完整Shell实例。

VS Code终端进程链验证

在VS Code内置终端中运行:

pstree -s -p $$ | grep -E "(code|terminal|zsh|bash|fish)"

参数说明$$ 是当前Shell PID;-s 显示父进程链;输出可清晰定位 code → electron → ptyhost → zsh 的跨架构调用路径。

架构兼容性对照表

进程角色 典型路径 推荐架构 常见不匹配现象
VS Code主进程 /Applications/Visual Studio Code.app/... arm64 Rosetta转译延迟
内置终端PTY /proc/[pid]/exe(ptyhost) arm64 spawn失败或SIGILL
当前Shell /bin/zsh 匹配宿主 file: cannot open 错误

架构诊断决策流

graph TD
    A[执行 ps -p $$] --> B{vsz > 10MB?}
    B -->|是| C[确认为完整Shell]
    B -->|否| D[可能为精简shell或容器环境]
    C --> E[file /proc/$$/exe]
    E --> F{x86_64 or arm64?}

2.4 彻底卸载Rosetta残留Go安装与清理$GOROOT/$GOPATH交叉污染路径

Rosetta 2 运行的 Go 二进制可能在 Apple Silicon 上留下混杂架构(x86_64)的 $GOROOT 和污染的 $GOPATH/bin,导致 go build 静默降级或 exec format error

识别残留安装

# 查看所有 Go 安装路径(含 Rosetta 启动的进程)
ps aux | grep 'go[[:space:]]' | grep -i rosetta
ls -la $(which go) /usr/local/go /opt/homebrew/opt/go
file $(which go)  # 关键:输出含 "x86_64" 即为 Rosetta 残留

file 命令检测 ELF 架构;若显示 x86_64,说明该 go 二进制依赖 Rosetta,不可用于原生开发。

清理策略优先级

  • ✅ 删除 /usr/local/go(Rosetta 常见安装点)
  • ✅ 清空 $HOME/go/bin 中非 arm64 可执行文件(file ./tool | grep x86_64 && rm ./tool
  • ❌ 不直接 unset GOROOT —— 应由新原生安装自动设值

环境变量污染检查表

变量 安全值示例 危险信号
$GOROOT /opt/homebrew/opt/go/libexec /usr/local/go(x86_64 路径)
$PATH /opt/homebrew/bin /usr/local/go/bin(未验证架构)
graph TD
  A[检测 which go 架构] --> B{file output contains x86_64?}
  B -->|Yes| C[rm -rf /usr/local/go $HOME/go/bin/*]
  B -->|No| D[保留并验证 go version]
  C --> E[重装 arm64 Homebrew Go]

2.5 从源码构建arm64原生Go SDK并验证CGO_ENABLED=1下的系统调用兼容性

构建前环境准备

确保宿主机为 Linux arm64(如 AWS Graviton2 或 Apple M1/M2 运行 Linux):

uname -m  # 应输出 aarch64
gcc --version  # 需 ≥10.0,用于 CGO 编译

拉取与编译 Go 源码

git clone https://go.googlesource.com/go && cd go/src
./make.bash  # 自动构建 cmd/dist、runtime、stdlib 等

make.bash 调用 cmd/dist 启动引导编译链,生成 GOOS=linux GOARCH=arm64 原生工具链;不依赖交叉编译,避免 syscall ABI 误匹配。

验证 CGO 系统调用行为

export GOROOT=$(pwd)/../  # 指向新构建的 SDK
export PATH=$GOROOT/bin:$PATH
CGO_ENABLED=1 go run -gcflags="-S" main.go  # 触发 libc 调用并内联汇编检查
测试项 预期结果 说明
syscall.Syscall 成功返回 直接陷入 svc #0
os.Open 调用 openat(AT_FDCWD, ...) 经 glibc 封装,ABI 兼容
graph TD
    A[go build] --> B[链接 libpthread.so.0]
    B --> C[调用 __libc_openat64]
    C --> D[最终执行 arm64 svc #0]

第三章:VS Code核心插件arm64适配攻坚

3.1 go extension(golang.go)在M系列芯片上的架构感知加载机制解析

VS Code 的 golang.go 扩展在 Apple M 系列芯片(ARM64)上启用架构感知加载,避免 x86_64 兼容层带来的性能损耗与二进制不兼容问题。

架构探测逻辑

扩展启动时通过 Node.js process.archprocess.platform 结合 os.cpus() 指令集特征,精准识别 arm64 环境:

// golang.go/src/adapter/arch.ts
export function detectTargetArch(): 'arm64' | 'x64' {
  if (process.arch === 'arm64' && process.platform === 'darwin') {
    return 'arm64'; // ✅ M1/M2/M3 原生路径
  }
  return process.arch as 'x64' | 'arm64';
}

逻辑分析:process.arch 是 Node.js 运行时架构(非宿主 CPU),但 VS Code for macOS ARM64 版本强制运行于原生 arm64 Node.js,因此该判断安全可靠;参数 process.platform === 'darwin' 排除 Linux/arm64 误判。

加载策略差异

架构 Go 工具链路径 LSP 服务器二进制
arm64 ~/.vscode/extensions/golang.go/bin/go-darwin-arm64 gopls-darwin-arm64
x64 ~/.vscode/extensions/golang.go/bin/go-darwin-amd64 gopls-darwin-amd64

初始化流程

graph TD
  A[Extension Activates] --> B{detectTargetArch()}
  B -->|arm64| C[Load go-darwin-arm64]
  B -->|x64| D[Load go-darwin-amd64]
  C --> E[Set GOOS=darwin GOARCH=arm64]
  D --> F[Use Rosetta 2 if needed]

3.2 手动编译并注入arm64-gopls:从go install到静态链接libzstd的完整实践

为何需手动编译?

gopls 官方二进制默认不启用 zstd 压缩支持,且 macOS/Linux ARM64 环境下动态链接 libzstd 易因路径或 ABI 版本不一致导致 plugin.Open: failed to load 错误。

静态链接 libzstd 的关键步骤

# 1. 编译静态 libzstd(ARM64)
git clone https://github.com/facebook/zstd && cd zstd
make -C contrib/makefiles/posix CC=aarch64-apple-darwin23-clang CFLAGS="-O2 -fPIC -static" libzstd.a

# 2. 注入构建标签并静态链接
CGO_ENABLED=1 CC=aarch64-apple-darwin23-clang \
GOOS=darwin GOARCH=arm64 \
CGO_LDFLAGS="-L$(pwd)/zstd/lib -lzstd -static" \
go build -trimpath -ldflags="-s -w -buildmode=exe" \
    -tags="zstd,netgo,osusergo" \
    -o gopls ./gopls

CGO_LDFLAGS 指向本地静态库路径;-tags=zstd 启用 gopls/internal/lsp/cache 中的 zstd 支持;-static 强制静态链接,规避运行时依赖。

构建参数对照表

参数 作用 必要性
CGO_ENABLED=1 启用 cgo(zstd 依赖 C 实现) ✅ 强制开启
-tags=zstd 启用 zstd 压缩逻辑分支 ✅ 核心开关
-ldflags=-static 静态链接所有依赖(含 libc) ⚠️ 可选,但提升可移植性
graph TD
    A[go build] --> B{CGO_ENABLED=1?}
    B -->|Yes| C[调用 clang 链接 libzstd.a]
    C --> D[生成无动态依赖的 arm64-gopls]
    B -->|No| E[跳过 zstd,降级为 gzip]

3.3 替代方案评估:gopls@v0.14+ arm64预发布二进制安全接入与签名验证

安全接入关键约束

需同时满足:

  • ARM64 架构兼容性(GOOS=linux GOARCH=arm64
  • 预发布版本(v0.14.0-20231015182234-9f74a2e3d4b7)可溯源
  • 二进制签名由 golang.org/x/tools/gopls 官方密钥链签发

签名验证流程

# 下载预发布二进制及对应 .sig 文件
curl -L https://github.com/golang/tools/releases/download/gopls%2Fv0.14.0-20231015182234-9f74a2e3d4b7/gopls-linux-arm64 > gopls
curl -L https://github.com/golang/tools/releases/download/gopls%2Fv0.14.0-20231015182234-9f74a2e3d4b7/gopls-linux-arm64.sig > gopls.sig

# 使用 Go 工具链内置 verify 命令校验(需 go1.21+)
go tool sigsum verify --key https://go.dev/signatures.pub gopls gopls.sig

逻辑分析:go tool sigsum verify 调用 Sigsum 协议,通过 Merkle Tree 根哈希比对远程可信签名日志(Sigstore Rekor),确保二进制未被篡改且来自官方构建流水线;--key 指定 Go 官方公钥 URI,避免本地密钥管理负担。

验证结果对照表

项目
构建时间戳 2023-10-15T18:22:34Z
签名日志索引 rekor.dev/index/0e8a3...c2f
架构标识 linux/arm64
graph TD
    A[下载 gopls-linux-arm64] --> B[获取 .sig 文件]
    B --> C[调用 go tool sigsum verify]
    C --> D{Sigstore Rekor 日志查询}
    D -->|匹配成功| E[加载并信任二进制]
    D -->|哈希不一致| F[拒绝执行]

第四章:Homebrew生态冲突治理与多版本Go协同管理

4.1 Homebrew默认x86_64 bottle策略导致go@1.21等公式安装失败的根因定位

Homebrew 自 4.0 起默认为 Intel Mac(x86_64)构建并分发 bottle,但 go@1.21 等旧版公式未同步更新其 bottle :unneededbottle :disabled 声明,导致在 Apple Silicon(ARM64)上强制拉取 x86_64 bottle 并失败。

关键诊断命令

brew info go@1.21 | grep "Built for"
# 输出:Built for: x86_64 (unavailable on arm64)

该命令揭示 bottle 元数据硬编码架构,brew install 拒绝跨架构安装(无 --force-bottle 时)。

架构匹配逻辑流程

graph TD
    A[brew install go@1.21] --> B{Bottle available?}
    B -->|Yes, x86_64 only| C[Check host arch]
    C -->|arm64| D[Reject: arch mismatch]
    C -->|x86_64| E[Install successfully]

解决路径对比

方式 命令 风险
强制安装 brew install --force-bottle go@1.21 运行时 SIGBUS(Rosetta 2 不兼容部分 Go 1.21 二进制)
源码编译 brew install --build-from-source go@1.21 可行,但耗时且需 Xcode CLI

根本原因在于 formula 中缺失 bottle :rebuild => 1disable! date: "2023-01-01", because: "arm64 support added" 声明。

4.2 使用–build-from-source + HOMEBREW_FORCE_BOTTLE=0实现arm64原生formula重编译

在 Apple Silicon Mac 上,Homebrew 默认可能安装 x86_64 瓶装(bottle)二进制,导致 Rosetta 转译运行。为获得真正 arm64 原生性能,需强制源码编译。

触发原生构建的两种等效方式

  • brew install --build-from-source <formula>
  • HOMEBREW_FORCE_BOTTLE=0 brew install <formula>
# 推荐组合:显式禁用 bottle 并启用源码构建
HOMEBREW_FORCE_BOTTLE=0 brew install --build-from-source ffmpeg

此命令绕过所有预编译 bottle 下载逻辑,强制调用 ./configure && make && make installHOMEBREW_FORCE_BOTTLE=0 优先级高于 bottle 元数据,确保 arch -arm64 环境下生成原生 Mach-O 二进制。

关键环境行为对照表

环境变量 / 参数 是否跳过 bottle 是否启用 arm64 编译 备注
--build-from-source ⚠️ 取决于 configure 脚本 需 formula 显式支持 arm64
HOMEBREW_FORCE_BOTTLE=0 ✅(在 arm64 终端中) 更底层、更可靠的控制
graph TD
    A[执行 brew install] --> B{HOMEBREW_FORCE_BOTTLE==0?}
    B -->|是| C[忽略 bottle URL]
    B -->|否| D[尝试下载 bottle]
    C --> E[调用 build_formula<br>→ run_autotools/cmake]
    E --> F[编译目标架构 = host arch]

4.3 asdf-go多版本管理器在M2/M3上的arm64优先策略配置与shell hook深度集成

Apple Silicon(M2/M3)原生运行 arm64 架构二进制,但部分 Go 工具链仍默认拉取 amd64 交叉构建版本。asdf-go 需显式启用 arm64 优先策略。

arm64 架构感知配置

# ~/.asdfrc 中启用架构感知与自动匹配
arch=arm64
legacy_version_file=true
plugin_repository_url=https://github.com/kennyp/asdf-go.git

arch=arm64 强制插件优先解析 go-1.22.5-darwin-arm64.tar.gz 而非 darwin-amd64legacy_version_file=true 兼容 .go-version 中未标注平台的旧写法。

Shell Hook 注入时机优化

# 在 ~/.zshrc 末尾注入(避免被其他插件覆盖)
source "$HOME/.asdf/asdf.sh"
source "$HOME/.asdf/plugins/go/shim-env.sh"  # 提供 goenv_hook

该 hook 在每次 shell 启动时动态重写 GOROOTPATH,确保 go version 输出含 arm64 标识。

环境变量 值示例 作用
GOOS darwin 锁定 macOS 目标平台
GOARCH arm64 强制生成/使用 arm64 二进制
GODEBUG mmap=1 修复 M-series 内存映射兼容性
graph TD
  A[Shell 启动] --> B[执行 shim-env.sh]
  B --> C[读取 .go-version]
  C --> D[匹配 arm64 二进制路径]
  D --> E[导出 GOROOT/GOPATH]

4.4 VS Code workspace settings.json中GOOS/GOARCH/GOPROXY的动态上下文感知配置模板

核心配置结构

VS Code 工作区级 settings.json 支持基于文件路径、环境变量和多工作区上下文的条件化配置。关键在于利用 ${env:NAME}${workspaceFolderBasename} 实现动态注入。

配置示例与逻辑分析

{
  "go.toolsEnvVars": {
    "GOOS": "${env:GOOS:-linux}",
    "GOARCH": "${env:GOARCH:-amd64}",
    "GOPROXY": "${env:GOPROXY:-https://proxy.golang.org,direct}"
  }
}

逻辑分析${env:GOOS:-linux} 表示优先读取系统环境变量 GOOS,缺失时回退为 linux;VS Code 在启动 Go 工具链(如 goplsgo build)前自动展开该变量,实现构建目标平台的即时切换。

多环境适配策略

  • 开发机默认设为 linux/amd64
  • 嵌入式项目目录下通过 .vscode/settings.json 覆盖为 GOOS=linux GOARCH=arm64
  • CI/CD 流水线中由 GitHub Actions 注入 GOPROXY=https://goproxy.cn,direct
场景 GOOS GOARCH GOPROXY
本地开发 linux amd64 https://proxy.golang.org
macOS 构建 darwin arm64 https://goproxy.cn
Windows 交叉编译 windows 386 direct

第五章:终极验证与可持续维护指南

验证清单的自动化执行

在生产环境上线前,必须运行一套可重复、可审计的验证清单。以下为某电商系统灰度发布时的实际检查项(部分):

检查项 工具/命令 预期输出 失败响应
核心API可用性 curl -s -o /dev/null -w "%{http_code}" https://api.example.com/v2/orders?limit=1 200 触发PagerDuty告警并回滚
数据库连接池健康度 kubectl exec -n prod db-proxy-0 -- psql -U monitor -c "SELECT * FROM pg_stat_activity WHERE state = 'active' LIMIT 5;" \| wc -l ≤15 自动扩容连接代理实例
缓存穿透防护生效 redis-cli -h cache-prod -p 6379 GET "order:nonexistent_999999999" "__NULL__"(非空值或报错) 更新Redis ACL策略并重载

该清单已封装为GitHub Actions workflow,每次合并至release/*分支即自动触发,并生成带签名的验证报告PDF存档至S3。

灾难恢复演练的常态化机制

某金融客户将RTO(恢复时间目标)压缩至4分17秒,关键在于每月第三周周五14:00–14:30强制执行“静默故障注入”:

  • 使用Chaos Mesh随机终止一个Kubernetes StatefulSet中的Pod;
  • 同步调用Prometheus Alertmanager API关闭对应告警通道(模拟监控失效);
  • 所有操作日志实时写入Elasticsearch索引chaos-run-2024*,供事后分析。
    过去6次演练中,3次暴露了etcd备份快照未启用增量压缩的问题,已通过Ansible Playbook统一修复。

日志归档策略与合规审计追踪

所有应用日志必须满足GDPR第32条“加密存储+最小保留期”要求。实际落地如下:

# 生产集群Logstash配置节选(logstash.conf)
filter {
  if [kubernetes][namespace] == "prod-finance" {
    mutate { add_field => { "[@metadata][archive_bucket]" => "eu-west-1-finance-logs-encrypted" } }
  }
}
output {
  s3 {
    bucket => "%{[@metadata][archive_bucket]}"
    region => "eu-west-1"
    server_side_encryption => true
    server_side_encryption_algorithm => "AES256"
    time_file => 1h
    prefix => "year=%{+YYYY}/month=%{+MM}/day=%{+dd}/hour=%{+HH}/"
  }
}

监控指标的基线漂移检测

采用Prophet模型对核心延迟指标进行动态基线建模,当P99响应时间连续5分钟超出预测区间±2.5σ时触发深度诊断:

flowchart TD
    A[Prometheus采集latency_p99] --> B{Prophet实时预测}
    B --> C[计算残差Z-score]
    C --> D{Z > 2.5?}
    D -->|Yes| E[自动抓取火焰图 + 查询最近3次部署变更]
    D -->|No| F[维持当前基线]
    E --> G[生成根因线索报告至Jira Service Management]

技术债偿还的量化看板

团队使用自研工具techdebt-tracker扫描代码库,将技术债分类为“安全债”“性能债”“测试债”,每季度生成热力图:

  • X轴:服务模块(payment-gateway, user-profile, notification-engine)
  • Y轴:债务严重等级(L1-L4,L4需48小时内修复)
  • 单元格颜色深浅代表未修复债务累计工时(如notification-engine L4债务=17.5人时)
    上季度支付网关模块L4安全债被标记为阻塞发布,推动完成OpenSSL 3.0迁移及FIPS模式启用。

变更影响范围的拓扑映射

通过eBPF探针采集服务间调用关系,构建实时依赖图谱。当修改inventory-service的库存扣减逻辑时,系统自动高亮下游6个直连服务及12个间接依赖组件,并标注各链路SLA历史达标率(如checkout-service近30天P95超时率1.8%)。

文档即代码的版本协同

所有运维手册均以Markdown形式存放于infra-docs仓库,与Terraform模块同目录结构。CI流水线检测到modules/rds/README.md更新时,自动执行:

  1. terraform-docs markdown table modules/rds > modules/rds/README.md
  2. markdown-link-check -c .github/.mlc-config.json modules/rds/README.md
  3. 若发现链接失效,阻止PR合并并标记docs/broken-link标签。

守护服务器稳定运行,自动化是喵的最爱。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注