英文:
Gitlab CI/CD fail with "bash: line 132: go: command not found"
问题
我们已经在我们的自定义服务器上安装了Gitlab。我们希望使用Gitlab的CI/CD流水线来构建和发布我们的软件,为此我正在进行一个POC。我创建了一个带有以下.gitlab-ci.yml
的项目:
variables:
GOOS: linux
GOARCH: amd64
stages:
- test
- build
- deb-build
run_tests:
stage: test
image: golang:latest
before_script:
- go mod tidy
script:
- go test ./...
build_binary:
stage: build
image: golang:latest
artifacts:
untracked: true
script:
- GOOS=$GOOS GOARCH=$GOARCH go build -o newer .
build deb:
stage: deb-build
image: ubuntu:latest
before_script:
- mkdir -p deb-build/usr/local/bin/
- chmod -R 0755 deb-build/*
- mkdir build
script:
- cp newer deb-build/usr/local/bin/
- dpkg-deb --build deb-build release-1.1.1.deb
- mv release-1.1.1.deb build
artifacts:
paths:
- build/*
TLDR: 我已经更新了gitlab-ci.yml和错误的截图。
我注意到,如果我使用共享的runner(GJ7z2Aym),错误是持久存在的,如果你注册一个runner(即特定的runner)。
gitlab-runner register --non-interactive --url "https://gitlab.sboxdc.com/" --registration-token "<register_token>" --description "" --executor "docker" --docker-image "docker:latest"
我看到构建通过了,没有任何问题。
失败的案例。
https://gist.github.com/meetme2meat/0676c2ee8b78b3683c236d06247a8a4d
通过的案例。
https://gist.github.com/meetme2meat/058e2656595a428a28fcd91ba68874e8
英文:
We have installed Gitlab on our custom server. We are looking to use the gitlab CI/CD pipeline to build and release our software for that I'm working on a POC. I have created a project with the following .gitlab-ci.yml
variables:
GOOS: linux
GOARCH: amd64
stages:
- test
- build
- deb-build
run_tests:
stage: test
image: golang:latest
before_script:
- go mod tidy
script:
- go test ./...
build_binary:
stage: build
image: golang:latest
artifacts:
untracked: true
script:
- GOOS=$GOOS GOARCH=$GOARCH go build -o newer .
build deb:
stage: deb-build
image: ubuntu:latest
before_script:
- mkdir -p deb-build/usr/local/bin/
- chmod -R 0755 deb-build/*
- mkdir build
script:
- cp newer deb-build/usr/local/bin/
- dpkg-deb --build deb-build release-1.1.1.deb
- mv release-1.1.1.deb build
artifacts:
paths:
- build/*
TLDR: I have updated the gitlab-ci.yml and the screenshot of the error.
What I have noticed, the error is persistent if I use the shared runner(GJ7z2Aym) if you register a runner (i.e Specific Runner)
gitlab-runner register --non-interactive --url "https://gitlab.sboxdc.com/" --registration-token "<register_token>" --description "" --executor "docker" --docker-image "docker:latest"
I see the build passing without any problem
Failed case.
https://gist.github.com/meetme2meat/0676c2ee8b78b3683c236d06247a8a4d
One that Passed
https://gist.github.com/meetme2meat/058e2656595a428a28fcd91ba68874e8
答案1
得分: 4
失败的作业正在使用一个具有shell
执行器的运行器,这可能是在配置GitLab实例时设置的。可以通过以下日志行看到这一点:
Preparing the "shell" executor
Using Shell executor...
shell
执行器将忽略作业的image:
配置。它将直接在托管运行器的机器上运行作业脚本,并尝试在该机器上找到go
二进制文件(在您的情况下失败)。这有点像在没有安装go
的Ubuntu上运行go
命令。
成功的作业正在使用一个具有docker
执行器的运行器,在您请求的golang:latest
镜像中运行作业脚本。这就像运行docker run golang:latest sh -c '[your script]'
。可以在作业的日志中看到这一点:
Preparing the "docker" executor
Using Docker executor with image golang:latest ...
Pulling docker image golang:latest ...
Using docker image sha256:05e[...]
golang:latest with digest golang@sha256:04f[...]
你可以做以下事情:
-
确保配置一个具有
docker
执行器的运行器。您的config.toml
应如下所示:[[runners]] # ... executor = "docker" [runners.docker] # ...
您似乎已经通过注册自己的运行器来完成了这一点。
-
使用作业的标签(tags)配置作业以使用此运行器。您可以在Docker运行器上设置标签
docker_executor
(在注册时或通过GitLab UI)并设置如下内容:build_binary: stage: build # Tags a runner must have to run this job tags: - docker_executor image: golang:latest artifacts: untracked: true script: - GOOS=$GOOS GOARCH=$GOARCH go build -o newer .
有关详细信息,请参阅Runner registration和Docker executor。
英文:
The failing job is using a runner with shell
executor, that was probably setup when you configured your GitLab instance. This can be seen on logs by this line:
>
> Preparing the "shell" executor
> Using Shell executor...
>
shell
executor will ignore your job's image:
config. It will run job script directly on the machine on which the runner is hosted, and will try to find go
binary on this machine (failing in your case). It's a bit like running go
commands on some Ubuntu without having go
installed.
Your successful job is using a runner with docker
executor, running your job's script in a golang:latest
image as you requested. It's like running docker run golang:latest sh -c '[your script]'
. This can be seen in job's logs:
>
> Preparing the "docker" executor
> Using Docker executor with image golang:latest ...
> Pulling docker image golang:latest ...
> Using docker image sha256:05e[...]
> golang:latest with digest golang@sha256:04f[...]
>
What you can do:
- Make sure you configure a runner with a
docker
executor. Yourconfig.toml
would then look like:
[[runners]]
# ...
executor = "docker"
[runners.docker]
# ...
It seems you already did by registering your own runner.
- Configure your jobs to use this runner with job
tags
. You can set tagdocker_executor
on your Docker runner (when registering or via Gitlab UI) and setup something like:
build_binary:
stage: build
# Tags a runner must have to run this job
tags:
- docker_executor
image: golang:latest
artifacts:
untracked: true
script:
- GOOS=$GOOS GOARCH=$GOARCH go build -o newer .
See Runner registration and Docker executor for details.
答案2
得分: 1
由于您使用了image: golang:latest
,因此go
应该在$PATH中。
您需要检查失败的阶段是run_tests
还是build_binary
。
在脚本步骤中添加echo $PATH
,以检查所考虑的$PATH是什么。
还要检查错误是否来自于缺少git
,Go用于访问模块远程存储库。参见此答案作为示例。
从您的gists中可以看出,默认的GitLab runner使用了shell executor(对Go一无所知)。
相反,第二个使用了基于Go镜像的Docker executor。
因此,注册(Docker) runner是确保预期执行程序的正确方法。
英文:
Since you have used image: golang:latest
, go
should be in the $PATH
You need to check at which stage it is failing: run_tests
or build_binary
.
Add echo $PATH
in your script steps, to check what $PATH is considered.
Check also if the error comes from the lack of git
, used by Go for accessing modules remote repositories. See this answer as an example.
From your gists, the default GitLab runner uses a shell executor (which knows nothing about Go)
Instead, the second one uses a Docker executor, based on the Go image.
Registering the (Docker) runner is therefore the right way to ensure the expected executor.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论