upload-artifact v4 在矩阵任务中报 409 Conflict
矩阵任务共用 artifact 名称会使 upload-artifact v4 上传冲突。按矩阵维度命名,区分串行 overwrite 与并行合并,并检查下载后文件路径冲突。
矩阵任务分别构建成功,上传阶段却有几份失败,并出现 409 Conflict 或同名 artifact 已存在的提示。若每个任务都使用 name: build-output,或省略了 name,先检查这些并行任务是不是在争用同一个产物名。
actions/upload-artifact v4 创建的 artifact 不能由多个任务继续追加。本文按 4.6.2 的行为说明,范围是 github.com 上的 v4 产物接口;其他实例和旧版本应先核对支持情况。一个工作流运行中的同名上传,不会自动合并成一份产物。
把矩阵维度写进产物名
给所有会产出不同内容的矩阵组合分配不同名称。例如任务同时按系统和版本展开时:
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
version: [a, b]
steps:
- uses: actions/checkout@v4.2.2
# 在这里保留项目已有构建步骤,产物目录为 build/output。
- uses: actions/upload-artifact@v4.6.2
with:
name: binary-${{ matrix.os }}-${{ matrix.version }}
path: build/output/
if-no-files-found: error
这是展示命名位置的任务结构,必须合入项目真实构建步骤后使用。a、b 是版本维度占位值,build/output/ 也应替换成各任务实际生成的路径。产物不存在时让上传失败,可以避免把“零文件上传”误认成已交付。
只加入系统名,而遗漏另一个版本维度,仍会使同系统的任务重名。除了矩阵任务,也要检查普通任务是否复用了相同名称,或多次省略名称而落到默认值。
产物名称通常只需在本次运行内保持唯一,不必一律添加时间戳。若重跑流程确实可能再次创建同名产物,可按项目的重跑策略加入 github.run_attempt,并同步调整下载方选择规则。
overwrite 不能替并行任务合并内容
设置 overwrite: true 会先删除已有同名 artifact,再创建新的 artifact。新产物有新 ID,旧产物不再存在。多个并行任务同时删除和创建,仍可能冲突,或只留下其中一份内容。
只有明确串行、并且业务本来就要用新产物替换旧产物时,才应考虑 overwrite。例如签名完成后,用一份签名包替换之前的未签名包;还需确认后续步骤没有保存并继续使用旧 artifact ID。
不要用 continue-on-error 隐藏冲突后继续发布。它只能改变任务如何处理失败,不能保证各平台的文件已经完整上传。
汇总时保留文件身份
给每份产物唯一名称后,下游可以分别下载。若使用 actions/download-artifact 4.3.0 的 pattern 选择多份产物,默认可按各产物名分别存放;开启 merge-multiple: true 才会合到同一目录。
合并目录前检查文件名。不同系统都叫 app.zip 时,产物名不同并不能避免合并后的文件路径冲突。可以让文件本身包含平台标识,或保留按产物分开的子目录,不要靠下载顺序决定哪份留下。
修改前保留原上传与下载配置,先验收矩阵每个组合都有对应产物,内容、数量与下游下载结果一致,再允许发布步骤使用它们。撤回配置只影响后续运行,不会自动找回被 overwrite 删除的产物;需要追溯的构建包应在替换前另行保留。


