vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Let a job budget its whole run
e7aa0785cb69ace8c1338cc0b924113ea52a7abb · Keenan Nemetz · 6d ago · parent 2bc0ae74
Let a job budget its whole run A step was capped at an hour and a job was not capped at all, so a job of several slow steps held a runner for as long as they took, with no number saying what the job was allowed to spend. And one long step — a session, a soak test, a slow suite — could not be expressed, because the only clock was per step and its ceiling was an hour. A job may now declare `timeout: 2h`: a wall clock its steps share, starting with the first step. A step that declares its own timeout is cut short when the budget ends first, and a step that declares none runs with whatever is left, so one long step needs only the job's number. A budget spent before a step starts stops the job there instead of running the step on its own cap. The budget is optional, pinned with the run, and spent by a local run the same way, so nothing changes for a workflow that does not declare one. The step ceiling rises from one hour to four to make a single long step possible; the default stays ten minutes. The image build is not charged to the budget — it has its own cap, so a slow pull cannot eat the time the steps were given. A step timeout longer than its job's budget is refused at push time: the budget would end first, so the step could never use what it asked for. Closes #161. # Conflicts: # ci/agent/agent.go # cmd/vole/workflowrun.go # docs/reference/workflow-reference.md
docs/reference/workflow-reference.md +49−5
| @@ -33,8 +33,9 @@ Unknown keys are rejected. A workflow is validated when it is pushed and again b | |||
| 33 | 33 | | Maximum schedules | 5 | | |
| 34 | 34 | | Maximum manual inputs | 10 | | |
| 35 | 35 | | Maximum event payload | 64 KiB | | |
| 36 | | Default step timeout | 10 minutes | | ||
| 37 | | Maximum step timeout | 1 hour | | ||
| 36 | | Default step timeout | 10 minutes, when the job has no budget | | ||
| 37 | | Maximum step timeout | 4 hours | | ||
| 38 | | Maximum job timeout | 4 hours | | ||
| 38 | 39 | ||
| 39 | 40 | ## Top-level fields | |
| 40 | 41 | ||
| @@ -413,6 +414,7 @@ letter. At least one job is required. | |||
| 413 | 414 | | `network` | `none` or `bridge` | no | the runner's setting | Whether the job's container has a network. | | |
| 414 | 415 | | `secrets` | string or list of strings | no | none | Repository secrets the job reads, by name. Each name is also the variable a step finds it in. | | |
| 415 | 416 | | `env` | mapping | no | none | Environment every step of the job runs with. | | |
| 417 | | `timeout` | duration string | no | none | Wall clock the job's steps share. | | ||
| 416 | 418 | | `steps` | list | yes | — | Commands the job runs. At least one is required. | | |
| 417 | 419 | | `artifacts` | list | no | none | Files the job publishes. | | |
| 418 | 420 | | `pages` | mapping | no | none | Directory published as the repository's website. | | |
| @@ -643,6 +645,44 @@ best effort, and worth knowing exactly: | |||
| 643 | 645 | - an artifact, a site file or a release attachment is stored as the step wrote it, | |
| 644 | 646 | so a secret a step writes to a file it publishes is published. | |
| 645 | 647 | ||
| 648 | ### `timeout` | ||
| 649 | |||
| 650 | A wall-clock budget for the job's steps, instead of a cap on each step separately: | ||
| 651 | |||
| 652 | ```yaml | ||
| 653 | jobs: | ||
| 654 | test: | ||
| 655 | image: golang:1.27-bookworm | ||
| 656 | timeout: 2h | ||
| 657 | steps: | ||
| 658 | - run: go test ./... | ||
| 659 | - run: go vet ./... | ||
| 660 | ``` | ||
| 661 | |||
| 662 | The budget starts with the first step and is spent in order. A step that declares its | ||
| 663 | own `timeout:` is still cut short when the budget ends first, and a step that declares | ||
| 664 | none runs with whatever is left, so one long step is enough to say: | ||
| 665 | |||
| 666 | ```yaml | ||
| 667 | jobs: | ||
| 668 | agent: | ||
| 669 | image-file: agent | ||
| 670 | timeout: 4h | ||
| 671 | steps: | ||
| 672 | - run: run-the-session | ||
| 673 | ``` | ||
| 674 | |||
| 675 | When the budget is spent before a step starts, that step does not run and the job | ||
| 676 | fails, with one line in the log saying so. The field is optional: without it each step | ||
| 677 | is bounded by its own timeout, which is how a workflow worked before the field | ||
| 678 | existed. | ||
| 679 | |||
| 680 | The image build is not part of the budget. It has its own cap, so a slow pull cannot | ||
| 681 | eat the time the steps were given. | ||
| 682 | |||
| 683 | `timeout` is at most 4 hours, and a step whose own timeout is longer than the job's is | ||
| 684 | refused at push time: the budget would end first, so the step could never use it. | ||
| 685 | |||
| 646 | 686 | ### `steps` | |
| 647 | 687 | ||
| 648 | 688 | A non-empty list of shell steps, at most 100. Steps run in order. A step that exits | |
| @@ -657,7 +697,7 @@ container and filesystem with the other steps in the same job. | |||
| 657 | 697 | |---|---|---|---|---| | |
| 658 | 698 | | `name` | string | no | first line of `run` | Display name in the log. | | |
| 659 | 699 | | `run` | string | yes | — | Shell command executed with `/bin/sh -c`. | | |
| 660 | | `timeout` | duration string | no | `10m` | Maximum time for this step. | | ||
| 700 | | `timeout` | duration string | no | the job's remaining budget, or `10m` | Maximum time for this step. | | ||
| 661 | 701 | ||
| 662 | 702 | ```yaml | |
| 663 | 703 | steps: | |
| @@ -671,7 +711,11 @@ trimmed; when omitted it is derived from the first line of `run`, shortened to 6 | |||
| 671 | 711 | characters. | |
| 672 | 712 | ||
| 673 | 713 | `timeout` uses Go duration syntax (`90s`, `10m`, `1h`). It must be positive and no | |
| 674 | more than `1h`. When a step times out, the job fails and its container is stopped. | ||
| 714 | more than 4 hours, and it may not be longer than the job's own `timeout` when that is | ||
| 715 | declared. When a step times out, the job fails and its container is stopped. | ||
| 716 | |||
| 717 | A step that declares no timeout of its own runs with the rest of the job's budget, | ||
| 718 | or 10 minutes when the job has no budget. See the job's [`timeout`](#timeout), which is the budget the step runs inside. | ||
| 675 | 719 | ||
| 676 | 720 | ### `artifacts` | |
| 677 | 721 | ||
| @@ -784,7 +828,7 @@ It does not support: | |||
| 784 | 828 | - expressions or `${{ }}` contexts; the shell is the expression language and the | |
| 785 | 829 | event file is the context. See [Context and expressions](#context-and-expressions). | |
| 786 | 830 | - service containers, cache keys, or artifact downloads between jobs | |
| 787 | - job-level timeouts, concurrency groups, or cancel-in-progress | ||
| 831 | - concurrency groups, or cancel-in-progress | ||
| 788 | 832 | - workflow-level `env`, working directories, or shells; `env` is per job and every | |
| 789 | 833 | step runs through `/bin/sh -c` in the checkout | |
| 790 | 834 | - reusable workflows or composite actions (`uses:`); shell in an image is the | |