fix: add missing service container health check (#2354)

* fix: Implement missing health ceck for Services

* Add test case

* linter doesn't support min builtin and fix check

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
ChristopherHX
2024-07-10 17:33:54 +02:00
committed by GitHub
parent 1ac4b60a06
commit 2ad5ff74f8
6 changed files with 93 additions and 0 deletions

View File

@@ -17,6 +17,7 @@ import (
"runtime"
"strconv"
"strings"
"time"
"github.com/docker/go-connections/nat"
"github.com/nektos/act/pkg/common"
@@ -420,6 +421,7 @@ func (rc *RunContext) startJobContainer() common.Executor {
Mode: 0o666,
Body: "",
}),
rc.waitForServiceContainers(),
)(ctx)
}
}
@@ -518,6 +520,40 @@ func (rc *RunContext) startServiceContainers(_ string) common.Executor {
}
}
func (rc *RunContext) waitForServiceContainer(c container.ExecutionsEnvironment) common.Executor {
return func(ctx context.Context) error {
sctx, cancel := context.WithTimeout(ctx, time.Minute*5)
defer cancel()
health := container.ContainerHealthStarting
delay := time.Second
for i := 0; ; i++ {
health = c.GetHealth(sctx)
if health != container.ContainerHealthStarting || i > 30 {
break
}
time.Sleep(delay)
delay *= 2
if delay > 10*time.Second {
delay = 10 * time.Second
}
}
if health == container.ContainerHealthHealthy {
return nil
}
return fmt.Errorf("service container failed to start")
}
}
func (rc *RunContext) waitForServiceContainers() common.Executor {
return func(ctx context.Context) error {
execs := []common.Executor{}
for _, c := range rc.ServiceContainers {
execs = append(execs, rc.waitForServiceContainer(c))
}
return common.NewParallelExecutor(len(execs), execs...)(ctx)
}
}
func (rc *RunContext) stopServiceContainers() common.Executor {
return func(ctx context.Context) error {
execs := []common.Executor{}

View File

@@ -317,6 +317,7 @@ func TestRunEvent(t *testing.T) {
{workdir, "services-empty-image", "push", "", platforms, secrets},
{workdir, "services-host-network", "push", "", platforms, secrets},
{workdir, "services-with-container", "push", "", platforms, secrets},
{workdir, "mysql-service-container-with-health-check", "push", "", platforms, secrets},
// local remote action overrides
{workdir, "local-remote-action-overrides", "push", "", platforms, secrets},

View File

@@ -0,0 +1,19 @@
name: service-container
on: push
jobs:
service-container-test:
runs-on: ubuntu-latest
container: mysql:8
services:
maindb:
image: mysql:8
env:
MYSQL_DATABASE: dbname
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbpass
MYSQL_RANDOM_ROOT_PASSWORD: yes
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- run: mysql -u dbuser -D dbname -pdbpass -h maindb -e "create table T(id INT NOT NULL AUTO_INCREMENT, val VARCHAR(255), PRIMARY KEY (id))"
- run: mysql -u dbuser -D dbname -pdbpass -h maindb -e "insert into T(val) values ('test'),('h')"
- run: mysql -u dbuser -D dbname -pdbpass -h maindb -e "select * from T"