You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab CI/CD 技术求助:生成附带可执行文件的Release失败问题排查

解决GitLab CI/CD Release生成与资产上传问题

我来帮你搞定这两个CI/CD流水线的问题,咱们一步步拆解修复:

一、Upload阶段:Content-Type不支持错误

问题原因

你遇到的{"error":"The provided content-type '' is not supported."}错误,本质有两个:一是用curl上传文件时没指定Content-Type,GitLab通用包注册表要求明确声明文件MIME类型;二是你当前的上传URL不符合GitLab通用包的路径规范,导致服务器无法识别上传目标。

修复方案

  1. 构造正确的通用包上传URL:GitLab通用包的标准上传路径是${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/<包名>/<版本标识>/<文件名>,这里用提交SHA作为版本标识,能保证每次上传的唯一性。
  2. 给curl添加Content-Type请求头:指定为application/octet-stream,这是二进制文件的通用MIME类型,适配你的可执行文件。

二、Release阶段:两个错误的修复

错误1:系统尝试打开不存在的文件路径

这是因为release-cli的--description参数默认会把传入值当作文件路径去读取内容,但你实际想传入的是字符串描述。解决办法很简单:改用--description-string参数,直接传递字符串内容即可。

你当前的URL有两个问题:一是变量在单引号中不会被Shell展开(导致${PACKAGE_REGISTRY_URL}还是原样字符串);二是URL格式不符合GitLab资产链接的合法要求。推荐两种可行的URL方案:

  • 方案1:使用通用包的下载URL(和上传路径完全对应)
  • 方案2:直接用CI Artifact的访问URL,格式为${CI_JOB_URL}/artifacts/raw/source/bin/snippet-generator,可以直接引用Build阶段生成的制品,甚至能省略Upload阶段。

另外要注意:资产链接的JSON必须用双引号包裹,确保Shell能正确展开变量。

修改后的完整.gitlab-ci.yml配置

stages:
  - build
  - upload
  - release

variables:
  STACK_ROOT: "${CI_PROJECT_DIR}/.stack-root"
  # 定义通用包的基础上传/下载路径
  GENERIC_PACKAGE_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/snippet-generator/${CI_COMMIT_SHA}"

cache:
  paths:
    - .stack-work/
    - .stack-root/

build:
  only:
    - master
  stage: build
  image: haskell:9
  artifacts:
    expire_in: 30 days
    paths:
      - source/bin/
  script:
    - cd source
    - stack update
    - stack build --copy-bins
    - stack clean

upload:
  stage: upload
  image: curlimages/curl:latest
  cache: {}
  script:
    # 上传到GitLab通用包注册表
    - |
      curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
           --header "Content-Type: application/octet-stream" \
           --upload-file "source/bin/snippet-generator" \
           "${GENERIC_PACKAGE_URL}/snippet-generator"

release:
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli
  cache: {}
  only:
    - master
  when: manual
  except:
    - tags
  script:
    - >
      release-cli create 
      --name "Snippet Generator Release - ${CI_COMMIT_SHORT_SHA}" 
      --description-string "Automated release from CI pipeline - Commit: ${CI_COMMIT_SHA}" 
      --tag-name "release-${CI_COMMIT_SHORT_SHA}" 
      --ref ${CI_COMMIT_SHA} 
      --assets-link "{\"name\":\"Snippet Generator Executable\",\"url\":\"${GENERIC_PACKAGE_URL}/snippet-generator\"}"

额外说明

  • 如果你不想用通用包,完全可以省略Upload阶段,把Release中的资产链接URL改成"${CI_JOB_URL}/artifacts/raw/source/bin/snippet-generator",直接引用Build阶段的制品。
  • 标签名我改成了release-${CI_COMMIT_SHORT_SHA},比之前的job-$CI_JOB_ID更直观,方便关联到具体的代码提交。

内容的提问来源于stack exchange,提问作者Jip W.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 21:57:44