-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: add missing service container health check #2354
Changes from all commits
f55c6c5
3d8e9e5
adc9c8f
52c3d0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -452,6 +452,10 @@ | |
} | ||
} | ||
|
||
func (e *HostEnvironment) GetHealth(ctx context.Context) ContainerHealth { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Service container are not implemented for HostEnvironment, just a stub that is probably never called |
||
return ContainerHealthHealthy | ||
} | ||
|
||
func (e *HostEnvironment) ReplaceLogWriter(stdout io.Writer, _ io.Writer) (io.Writer, io.Writer) { | ||
org := e.StdOut | ||
e.StdOut = stdout | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
"runtime" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"github.com/docker/go-connections/nat" | ||
"github.com/nektos/act/pkg/common" | ||
|
@@ -420,6 +421,7 @@ | |
Mode: 0o666, | ||
Body: "", | ||
}), | ||
rc.waitForServiceContainers(), | ||
)(ctx) | ||
} | ||
} | ||
|
@@ -518,6 +520,40 @@ | |
} | ||
} | ||
|
||
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 | ||
} | ||
Comment on lines
+536
to
+538
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never poll less than every 10s, not looked up anywhere. |
||
} | ||
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{} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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))" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. currently this workflow fails to run, because maindb is still starting. The actions runner wait for it to be ready |
||
- 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" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uses docker inspect to poll container health like actions/runner