2026-05-02 学习日志
今日主题
- Docker 镜像坐标 vs Maven 坐标
- Docker 镜像引用的启发式解析规则
- .gitignore 规则优先级
- GitHub Actions workflow_dispatch
- GitHub Actions 表达式语法
新增认知
Docker 镜像坐标 vs Maven 坐标
- Maven 坐标是纯逻辑标识(groupId:artifactId:version),与物理存储位置完全解耦;仓库地址在外部配置(settings.xml)中指定。Docker 镜像引用则将托管位置(registry 域名)编码在标识自身中,本质上混合了逻辑坐标和物理位置。
- Docker 镜像引用的结构是 [registry-host/][namespace/]repo:tag,其中 registry-host 是必选概念(只是 Docker Hub 可省略)。这意味着同一份软件托管在不同 registry 上就是不同的镜像引用——这和 Maven 的 '一个坐标可以从不同仓库获取' 完全不同。
- Docker 的 tag 是可变指针,不保证不变性(如 latest 可以重新指向),而 Maven 的 version 是正式坐标组成部分,配合仓库的不可变发布策略形成强一致性。这两种版本语义差异源于设计目标不同:Docker 面向部署分发,Maven 面向构建依赖。
Docker 镜像引用的启发式解析规则
- Docker 通过启发式规则(而非显式声明)判定 registry host:第一部分若含 . 或 : 则视为 registry host,否则默认为 Docker Hub。字符串的形态特征决定语义,而非显式的维度声明——这是看起来像什么的猜测,不是你声明它是什么的断言。
- 这个设计是有意为之的 trade-off:让最常用的路径最短(docker pull nginx 只需 6 个字符),代价是边界情况下的歧义。例如内网 registry 域名没有 . 会解析失败,同一个字符串的 registry 归属完全取决于其中是否有个点号。
- 与 Maven 形成鲜明对比:Maven 用 settings.xml 显式声明仓库地址,坐标纯逻辑且无歧义,但使用更繁琐;Docker 把 registry 嵌入引用并用启发式推断,便捷但脆弱。这反映了两种设计哲学的差异:声明式(精确但冗长)vs 隐式推断(简洁但易错)。
.gitignore 规则优先级
- .gitignore 按最后匹配生效(last match wins),不是第一个匹配的规则。要放行被忽略的文件,! 规则必须出现在匹配规则之后,否则会被后面的规则覆盖。
- gradle-wrapper.jar 未被提交的原因是 .gitignore 中 *.jar 规则写在 !gradle/wrapper/gradle-wrapper.jar 放行规则之后,导致放行被覆盖。
GitHub Actions workflow_dispatch
- workflow_dispatch 支持手动触发 workflow,可定义 inputs 让用户在 GitHub 页面输入参数,通过 ${{ github.event.inputs.* }} 获取值。
- 同一个 workflow 可同时支持 tag 驱动和手动触发,通过 ${{ github.event_name }} 判断事件类型来区分逻辑分支。
GitHub Actions 表达式语法
- ${{ }} 表达式由 GitHub 服务端先做字符串替换,替换后的纯 shell 文本才交给 runner 上的 bash 执行。两种语法分属不同层级,不能混淆。
- if: 后面的条件不需要 ${{ }} 包裹(GitHub 自动解析),但字符串插值中需要。完整值可直接用 ${{ }}。
- github 上下文是最常用的上下文,包含 event_name、ref、sha、repository、event 等字段。github.event 是事件载荷,内容随事件类型变化。
- GitHub Actions 内置函数:contains()、startsWith()、endsWith()、format()、join()、hashFiles()、fromJson() 等,可用于条件判断和值计算。