mirror of
https://code.forgejo.org/forgejo/runner.git
synced 2025-09-15 18:57:01 +00:00
fix: enforce job.<job-id>.timeout-minutes (#982)
- enforce timeout-minutes timeout for jobs in a way similar to how it is done for steps - minimal refactor of evaluateStepTimeout evaluateTimeout so it can be used by jobs as well, with additional debug information and error logging if parsing fails - add integration tests for both step and job timeout-minutes, verifying expressions are allowed and evaluated Resolves forgejo/runner#979 --- Manually verified to work as expected https://v13.next.forgejo.org/earl-warren/testtimeout-minutes/actions/runs/3/jobs/0/attempt/1 ```yaml on: [push] jobs: test: runs-on: docker timeout-minutes: 1 steps: - run: | set -x while : ; do sleep 30 done ```  <!--start release-notes-assistant--> <!--URL:https://code.forgejo.org/forgejo/runner--> - bug fixes - [PR](https://code.forgejo.org/forgejo/runner/pulls/982): <!--number 982 --><!--line 0 --><!--description Zml4OiBlbmZvcmNlIGpvYi48am9iLWlkPi50aW1lb3V0LW1pbnV0ZXM=-->fix: enforce job.<job-id>.timeout-minutes<!--description--> <!--end release-notes-assistant--> Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/982 Reviewed-by: Michael Kriese <michael.kriese@gmx.de> Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org> Co-authored-by: Earl Warren <contact@earl-warren.org> Co-committed-by: Earl Warren <contact@earl-warren.org>
This commit is contained in:
parent
933667bdf1
commit
02a51c0a21
6 changed files with 39 additions and 6 deletions
|
@ -943,7 +943,10 @@ func (rc *RunContext) Executor() (common.Executor, error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if res {
|
if res {
|
||||||
return executor(ctx)
|
timeoutctx, cancelTimeOut := evaluateTimeout(ctx, rc.ExprEval, rc.Run.Job().TimeoutMinutes)
|
||||||
|
defer cancelTimeOut()
|
||||||
|
|
||||||
|
return executor(timeoutctx)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -272,6 +272,8 @@ func TestRunner_RunEvent(t *testing.T) {
|
||||||
{workdir, "evalmatrix-merge-array", "push", "", platforms, secrets},
|
{workdir, "evalmatrix-merge-array", "push", "", platforms, secrets},
|
||||||
|
|
||||||
{workdir, "basic", "push", "", platforms, secrets},
|
{workdir, "basic", "push", "", platforms, secrets},
|
||||||
|
{workdir, "timeout-minutes-stop", "push", "Job 'check' failed", platforms, secrets},
|
||||||
|
{workdir, "timeout-minutes-job", "push", "context deadline exceeded", platforms, secrets},
|
||||||
{workdir, "fail", "push", "Job 'build' failed", platforms, secrets},
|
{workdir, "fail", "push", "Job 'build' failed", platforms, secrets},
|
||||||
{workdir, "runs-on", "push", "", platforms, secrets},
|
{workdir, "runs-on", "push", "", platforms, secrets},
|
||||||
{workdir, "checkout", "push", "", platforms, secrets},
|
{workdir, "checkout", "push", "", platforms, secrets},
|
||||||
|
|
|
@ -177,7 +177,7 @@ func runStepExecutor(step step, stage stepStage, executor common.Executor) commo
|
||||||
Mode: 0o666,
|
Mode: 0o666,
|
||||||
})(ctx)
|
})(ctx)
|
||||||
|
|
||||||
timeoutctx, cancelTimeOut := evaluateStepTimeout(ctx, rc.ExprEval, stepModel)
|
timeoutctx, cancelTimeOut := evaluateTimeout(ctx, rc.ExprEval, stepModel.TimeoutMinutes)
|
||||||
defer cancelTimeOut()
|
defer cancelTimeOut()
|
||||||
err = executor(timeoutctx)
|
err = executor(timeoutctx)
|
||||||
|
|
||||||
|
@ -213,12 +213,15 @@ func runStepExecutor(step step, stage stepStage, executor common.Executor) commo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func evaluateStepTimeout(ctx context.Context, exprEval ExpressionEvaluator, stepModel *model.Step) (context.Context, context.CancelFunc) {
|
func evaluateTimeout(ctx context.Context, exprEval ExpressionEvaluator, timeoutMinutes string) (context.Context, context.CancelFunc) {
|
||||||
timeout := exprEval.Interpolate(ctx, stepModel.TimeoutMinutes)
|
timeout := exprEval.Interpolate(ctx, timeoutMinutes)
|
||||||
if timeout != "" {
|
if timeout != "" {
|
||||||
if timeOutMinutes, err := strconv.ParseInt(timeout, 10, 64); err == nil {
|
timeOutMinutes, err := strconv.ParseInt(timeout, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
common.Logger(ctx).Debugf("the step will stop in timeout-minutes %s", timeout)
|
||||||
return context.WithTimeout(ctx, time.Duration(timeOutMinutes)*time.Minute)
|
return context.WithTimeout(ctx, time.Duration(timeOutMinutes)*time.Minute)
|
||||||
}
|
}
|
||||||
|
common.Logger(ctx).Errorf("timeout-minutes %s cannot be parsed and will be ignored: %w", timeout, err)
|
||||||
}
|
}
|
||||||
return ctx, func() {}
|
return ctx, func() {}
|
||||||
}
|
}
|
||||||
|
|
3
act/runner/testdata/basic/push.yml
vendored
3
act/runner/testdata/basic/push.yml
vendored
|
@ -18,7 +18,8 @@ jobs:
|
||||||
- run: ls
|
- run: ls
|
||||||
- run: echo 'hello world'
|
- run: echo 'hello world'
|
||||||
- run: echo ${GITHUB_SHA} >> $(dirname "${GITHUB_WORKSPACE}")/sha.txt
|
- run: echo ${GITHUB_SHA} >> $(dirname "${GITHUB_WORKSPACE}")/sha.txt
|
||||||
- run: cat $(dirname "${GITHUB_WORKSPACE}")/sha.txt | grep ${GITHUB_SHA}
|
- timeout-minutes: 30
|
||||||
|
run: cat $(dirname "${GITHUB_WORKSPACE}")/sha.txt | grep ${GITHUB_SHA}
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [check]
|
needs: [check]
|
||||||
|
|
12
act/runner/testdata/timeout-minutes-job/push.yml
vendored
Normal file
12
act/runner/testdata/timeout-minutes-job/push.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
name: timeout-minutes
|
||||||
|
on: push
|
||||||
|
|
||||||
|
env:
|
||||||
|
TIMEOUT_MINUTES: 0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: ${{ env.TIMEOUT_MINUTES }}
|
||||||
|
steps:
|
||||||
|
- run: sleep 10
|
12
act/runner/testdata/timeout-minutes-step/push.yml
vendored
Normal file
12
act/runner/testdata/timeout-minutes-step/push.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
name: timeout-minutes
|
||||||
|
on: push
|
||||||
|
|
||||||
|
env:
|
||||||
|
TIMEOUT_MINUTES: 0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- timeout-minutes: ${{ env.TIMEOUT_MINUTES }}
|
||||||
|
run: sleep 10
|
Loading…
Add table
Add a link
Reference in a new issue