mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-07-26 09:20:53 +08:00
Compare commits
3 Commits
fix/563-pu
...
v2.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d74ae636a | ||
|
|
b12d02c25f | ||
|
|
f2e0cf9131 |
@@ -379,6 +379,13 @@ func (rc *RunContext) startJobContainer() common.Executor {
|
|||||||
|
|
||||||
// add service containers
|
// add service containers
|
||||||
for serviceID, spec := range rc.Run.Job().Services {
|
for serviceID, spec := range rc.Run.Job().Services {
|
||||||
|
// GitHub compatibility: skip services whose image evaluates to an
|
||||||
|
// empty string, enabling conditional services via expressions
|
||||||
|
serviceImage := rc.ExprEval.Interpolate(ctx, spec.Image)
|
||||||
|
if serviceImage == "" {
|
||||||
|
logger.Infof("The service '%s' will not be started because the container definition has an empty image.", serviceID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
// interpolate env
|
// interpolate env
|
||||||
interpolatedEnvs := make(map[string]string, len(spec.Env))
|
interpolatedEnvs := make(map[string]string, len(spec.Env))
|
||||||
for k, v := range spec.Env {
|
for k, v := range spec.Env {
|
||||||
@@ -417,7 +424,7 @@ func (rc *RunContext) startJobContainer() common.Executor {
|
|||||||
c := container.NewContainer(&container.NewContainerInput{
|
c := container.NewContainer(&container.NewContainerInput{
|
||||||
Name: serviceContainerName,
|
Name: serviceContainerName,
|
||||||
WorkingDir: ext.ToContainerPath(rc.Config.Workdir),
|
WorkingDir: ext.ToContainerPath(rc.Config.Workdir),
|
||||||
Image: rc.ExprEval.Interpolate(ctx, spec.Image),
|
Image: serviceImage,
|
||||||
Username: username,
|
Username: username,
|
||||||
Password: password,
|
Password: password,
|
||||||
Cmd: interpolatedCmd,
|
Cmd: interpolatedCmd,
|
||||||
|
|||||||
@@ -303,6 +303,7 @@ func TestRunEvent(t *testing.T) {
|
|||||||
// services
|
// services
|
||||||
{workdir, "services", "push", "", platforms, secrets},
|
{workdir, "services", "push", "", platforms, secrets},
|
||||||
{workdir, "services-with-container", "push", "", platforms, secrets},
|
{workdir, "services-with-container", "push", "", platforms, secrets},
|
||||||
|
{workdir, "services-empty-image", "push", "", platforms, secrets},
|
||||||
|
|
||||||
// local remote action overrides
|
// local remote action overrides
|
||||||
{workdir, "local-remote-action-overrides", "push", "", platforms, secrets},
|
{workdir, "local-remote-action-overrides", "push", "", platforms, secrets},
|
||||||
|
|||||||
10
act/runner/testdata/services-empty-image/push.yml
vendored
Normal file
10
act/runner/testdata/services-empty-image/push.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
name: services-empty-image
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: ${{ false && 'postgres:16' || '' }}
|
||||||
|
steps:
|
||||||
|
- run: echo "empty-image service was skipped"
|
||||||
4
go.mod
4
go.mod
@@ -29,6 +29,7 @@ require (
|
|||||||
github.com/opencontainers/selinux v1.15.1
|
github.com/opencontainers/selinux v1.15.1
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/prometheus/client_golang v1.23.2
|
github.com/prometheus/client_golang v1.23.2
|
||||||
|
github.com/prometheus/client_model v0.6.2
|
||||||
github.com/rhysd/actionlint v1.7.12
|
github.com/rhysd/actionlint v1.7.12
|
||||||
github.com/sirupsen/logrus v1.9.4
|
github.com/sirupsen/logrus v1.9.4
|
||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
@@ -37,7 +38,7 @@ require (
|
|||||||
github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928
|
github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928
|
||||||
go.etcd.io/bbolt v1.5.0
|
go.etcd.io/bbolt v1.5.0
|
||||||
go.yaml.in/yaml/v4 v4.0.0-rc.3
|
go.yaml.in/yaml/v4 v4.0.0-rc.3
|
||||||
golang.org/x/sys v0.46.0
|
golang.org/x/sys v0.47.0
|
||||||
golang.org/x/term v0.44.0
|
golang.org/x/term v0.44.0
|
||||||
google.golang.org/protobuf v1.36.11
|
google.golang.org/protobuf v1.36.11
|
||||||
gotest.tools/v3 v3.5.2
|
gotest.tools/v3 v3.5.2
|
||||||
@@ -84,7 +85,6 @@ require (
|
|||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/pjbgf/sha1cd v0.6.0 // indirect
|
github.com/pjbgf/sha1cd v0.6.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_model v0.6.2 // indirect
|
|
||||||
github.com/prometheus/common v0.66.1 // indirect
|
github.com/prometheus/common v0.66.1 // indirect
|
||||||
github.com/prometheus/procfs v0.17.0 // indirect
|
github.com/prometheus/procfs v0.17.0 // indirect
|
||||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -262,6 +262,8 @@ golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
|
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||||
|
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
||||||
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
||||||
|
|||||||
@@ -366,7 +366,6 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.
|
|||||||
} else if t := task.Secrets["GITHUB_TOKEN"]; t != "" {
|
} else if t := task.Secrets["GITHUB_TOKEN"]; t != "" {
|
||||||
preset.Token = t
|
preset.Token = t
|
||||||
}
|
}
|
||||||
applyPullRequestTargetCheckoutContext(preset)
|
|
||||||
|
|
||||||
if actionsIDTokenRequestURL := taskContext["actions_id_token_request_url"].GetStringValue(); actionsIDTokenRequestURL != "" {
|
if actionsIDTokenRequestURL := taskContext["actions_id_token_request_url"].GetStringValue(); actionsIDTokenRequestURL != "" {
|
||||||
envs["ACTIONS_ID_TOKEN_REQUEST_URL"] = actionsIDTokenRequestURL
|
envs["ACTIONS_ID_TOKEN_REQUEST_URL"] = actionsIDTokenRequestURL
|
||||||
@@ -575,41 +574,6 @@ func postInternalCache(url, secret string, body map[string]string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyPullRequestTargetCheckoutContext(preset *model.GithubContext) {
|
|
||||||
if preset == nil || preset.EventName != "pull_request_target" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
headSHA := nestedString(preset.Event, "pull_request", "head", "sha")
|
|
||||||
if headSHA == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
preset.Sha = headSHA
|
|
||||||
preset.Ref = headSHA
|
|
||||||
if headRef := nestedString(preset.Event, "pull_request", "head", "ref"); headRef != "" {
|
|
||||||
preset.HeadRef = headRef
|
|
||||||
preset.RefName = headRef
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func nestedString(m map[string]any, keys ...string) string {
|
|
||||||
var current any = m
|
|
||||||
for _, key := range keys {
|
|
||||||
next, ok := current.(map[string]any)
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
current, ok = next[key]
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value := current.(string)
|
|
||||||
if value == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Runner) RunningCount() int64 {
|
func (r *Runner) RunningCount() int64 {
|
||||||
return r.runningCount.Load()
|
return r.runningCount.Load()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"gitea.com/gitea/runner/act/model"
|
|
||||||
clientmocks "gitea.com/gitea/runner/internal/pkg/client/mocks"
|
clientmocks "gitea.com/gitea/runner/internal/pkg/client/mocks"
|
||||||
"gitea.com/gitea/runner/internal/pkg/config"
|
"gitea.com/gitea/runner/internal/pkg/config"
|
||||||
"gitea.com/gitea/runner/internal/pkg/ver"
|
"gitea.com/gitea/runner/internal/pkg/ver"
|
||||||
@@ -93,67 +92,6 @@ func TestNewRunnerInitializesLabelsAndEnvironment(t *testing.T) {
|
|||||||
require.Nil(t, r.cacheHandler)
|
require.Nil(t, r.cacheHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApplyPullRequestTargetCheckoutContextUsesHeadSHA(t *testing.T) {
|
|
||||||
preset := &model.GithubContext{
|
|
||||||
EventName: "pull_request_target",
|
|
||||||
Sha: "base-sha",
|
|
||||||
Ref: "refs/heads/main",
|
|
||||||
RefName: "main",
|
|
||||||
HeadRef: "feature",
|
|
||||||
Event: map[string]any{
|
|
||||||
"pull_request": map[string]any{
|
|
||||||
"head": map[string]any{
|
|
||||||
"sha": "head-sha",
|
|
||||||
"ref": "contributor-branch",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
applyPullRequestTargetCheckoutContext(preset)
|
|
||||||
|
|
||||||
require.Equal(t, "head-sha", preset.Sha)
|
|
||||||
require.Equal(t, "head-sha", preset.Ref)
|
|
||||||
require.Equal(t, "contributor-branch", preset.RefName)
|
|
||||||
require.Equal(t, "contributor-branch", preset.HeadRef)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApplyPullRequestTargetCheckoutContextNoOpsWithoutHeadSHA(t *testing.T) {
|
|
||||||
preset := &model.GithubContext{
|
|
||||||
EventName: "pull_request_target",
|
|
||||||
Sha: "base-sha",
|
|
||||||
Ref: "refs/heads/main",
|
|
||||||
RefName: "main",
|
|
||||||
Event: map[string]any{},
|
|
||||||
}
|
|
||||||
|
|
||||||
applyPullRequestTargetCheckoutContext(preset)
|
|
||||||
|
|
||||||
require.Equal(t, "base-sha", preset.Sha)
|
|
||||||
require.Equal(t, "refs/heads/main", preset.Ref)
|
|
||||||
require.Equal(t, "main", preset.RefName)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApplyPullRequestTargetCheckoutContextNoOpsForOtherEvents(t *testing.T) {
|
|
||||||
preset := &model.GithubContext{
|
|
||||||
EventName: "pull_request",
|
|
||||||
Sha: "merge-sha",
|
|
||||||
Ref: "refs/pull/1/merge",
|
|
||||||
Event: map[string]any{
|
|
||||||
"pull_request": map[string]any{
|
|
||||||
"head": map[string]any{
|
|
||||||
"sha": "head-sha",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
applyPullRequestTargetCheckoutContext(preset)
|
|
||||||
|
|
||||||
require.Equal(t, "merge-sha", preset.Sha)
|
|
||||||
require.Equal(t, "refs/pull/1/merge", preset.Ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
func taskWithDefaultActionsURL(url string) *runnerv1.Task {
|
func taskWithDefaultActionsURL(url string) *runnerv1.Task {
|
||||||
return &runnerv1.Task{
|
return &runnerv1.Task{
|
||||||
Context: &structpb.Struct{
|
Context: &structpb.Struct{
|
||||||
|
|||||||
@@ -110,6 +110,11 @@ cache:
|
|||||||
dir: ""
|
dir: ""
|
||||||
# Outbound IP or hostname that job containers use to reach this runner's cache server.
|
# Outbound IP or hostname that job containers use to reach this runner's cache server.
|
||||||
# Leave empty to detect automatically. 0.0.0.0 is not valid here.
|
# Leave empty to detect automatically. 0.0.0.0 is not valid here.
|
||||||
|
# If the runner itself runs in Docker, automatic detection can choose an
|
||||||
|
# address on the runner container's network that job containers cannot reach
|
||||||
|
# when the runner creates a separate per-job network. In that case, set this
|
||||||
|
# to a hostname/IP reachable from job containers, and set port to a fixed
|
||||||
|
# published port or put the job containers on a shared Docker network.
|
||||||
# Ignored when external_server is set.
|
# Ignored when external_server is set.
|
||||||
host: ""
|
host: ""
|
||||||
# Port for the built-in cache server. 0 picks a random free port.
|
# Port for the built-in cache server. 0 picks a random free port.
|
||||||
@@ -133,6 +138,8 @@ container:
|
|||||||
# Specifies the network to which the container will connect.
|
# Specifies the network to which the container will connect.
|
||||||
# Could be host, bridge or the name of a custom network.
|
# Could be host, bridge or the name of a custom network.
|
||||||
# If it's empty, runner will create a network automatically.
|
# If it's empty, runner will create a network automatically.
|
||||||
|
# For dockerized runners using the built-in cache server, a custom shared
|
||||||
|
# network can be required so job containers can reach cache.host/cache.port.
|
||||||
# Deprecated: `network_mode` is still accepted for old configs; use `network` instead.
|
# Deprecated: `network_mode` is still accepted for old configs; use `network` instead.
|
||||||
network: ""
|
network: ""
|
||||||
# network_create_options only apply when `network` is left empty and the runner
|
# network_create_options only apply when `network` is left empty and the runner
|
||||||
|
|||||||
Reference in New Issue
Block a user