You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
"Fork and replace the userData array" was a maintenance sentence nobody should
serve. Keep the built-in yum bootstrap as the only supported path, but make the
bootstrap pluggable so any distro/extra-setup need is a template away.
- pre-runner-script (the 80% case): a root snippet injected into the built-in
bootstrap before runner configuration (install docker, mount caches, certs).
Runs under set -euo pipefail with its own phase tag, so a failure surfaces as
failed:pre-runner-script in the diagnostics flow.
- user-data-template (full control): replaces the bootstrap entirely. Repo-
relative file path or inline string. The action substitutes documented
placeholders — {{RUNNER_VERSION}}, {{RUNNER_CHECKSUM_X64/ARM64}},
{{REGISTRATION_TOKEN}}, {{REPO_URL}}, {{LABEL}}, {{TTL_MINUTES}} — and submits
the result. Unknown {{...}} tokens error at render (typo protection).
- The two inputs are mutually exclusive (config error). Rendered payload is
size-guarded against the EC2 16 KB limit. Built-in path with neither input is
byte-identical to today (regression).
- examples/user-data/ubuntu.sh.tpl (community-maintained) + examples/user-data/
README stating the support boundary — converts the perennial Ubuntu ask from
"fork" to "copy one file".
Tests: renderUserDataTemplate (substitution, repeats, unknown-token error, token
rendered), assertUserDataSize (limit + multibyte), pre-runner-script injection +
default-absent, config mutual-exclusion (203 tests total). README support-
boundary section replaces the "fork and replace" paragraph; action.yml inputs.
Closes#46
Signed-off-by: kurok <22548029+kurok@users.noreply.github.com>
Copy file name to clipboardExpand all lines: README.md
+48-1Lines changed: 48 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ And all this automatically as a part of your GitHub Actions workflow.
12
12
>
13
13
> The bootstrap script that this action injects as EC2 `user-data` is hardcoded to use `yum`, `useradd`, `sudo`, `bash`, and a `tmpfs``/tmp`. That means the AMI you pass via `ec2-image-id`**must** be a yum-based distribution — Amazon Linux 2023 (the tested baseline), Amazon Linux 2, or a RHEL-family image (RHEL / CentOS Stream / Rocky / Alma) whose `/tmp` is mounted as tmpfs.
14
14
>
15
-
> **Debian, Ubuntu, Alpine, and any other non-yum distributions are not supported.**If you launch this action against such an AMI, the EC2 instance will boot but the runner bootstrap will fail. The action now surfaces this quickly: it fails fast naming the failing step and prints the instance's console output (see [Troubleshooting a failed start](#troubleshooting-a-failed-start)). Cross-distro support is not on the roadmap — if you need it, fork and replace the `userData`bootstrapin `src/aws.js`.
15
+
> **The built-in bootstrap targets yum-based Linux (Amazon Linux 2023) only.**Launching the built-in bootstrap against a non-yum AMI (Debian, Ubuntu, Alpine, …) fails — the action surfaces this fast, naming the failing step and printing the console output (see [Troubleshooting a failed start](#troubleshooting-a-failed-start)). You **don't need to fork** for other distros or extra setup: use [`pre-runner-script`](#custom-bootstrap-pre-runner-script--user-data-template) to inject steps into the built-in bootstrap, or [`user-data-template`](#custom-bootstrap-pre-runner-script--user-data-template) to replace it entirely (an Ubuntu example ships in [`examples/user-data/`](examples/user-data/)). Custom templates are unsupported by design — the boundary *is* the feature.
|`eip-allocation-id`| Optional. Used only with the `start` mode. | Allocation Id of an Elastic IP to associate with the runner instance once it is running. |
324
324
|`runner-version`| Optional. Used only with the `start` mode. | Version of the `actions/runner` binary to download and register (default `2.335.1`). <br><br> Must have a matching entry in `src/runner-checksums.js`; the action verifies the downloaded tarball's SHA-256 against that table before extraction. |
325
325
|`architecture`| Optional. Used only with the `start` mode. | Runner CPU architecture: `x64` (default) or `arm64` (Graviton). Must match the AMI (validated at start). All types in an `ec2-instance-type` fallback list must share this arch. See [Running on Graviton (arm64)](#running-on-graviton-arm64). |
326
+
|`pre-runner-script`| Optional. Used only with the `start` mode. | Shell snippet run as root by the built-in bootstrap **before** runner config (install docker, mount caches, add certs). Fail-fast, tagged `failed:pre-runner-script`. Mutually exclusive with `user-data-template`. See [Custom bootstrap](#custom-bootstrap-pre-runner-script--user-data-template). |
327
+
|`user-data-template`| Optional. Used only with the `start` mode. | Full bootstrap override — a repo-relative file path or inline string with `{{PLACEHOLDERS}}`. Replaces the built-in bootstrap (unsupported by design). Mutually exclusive with `pre-runner-script`. See [Custom bootstrap](#custom-bootstrap-pre-runner-script--user-data-template). |
326
328
|`http-tokens`| Optional. Used only with the `start` mode. | Instance Metadata Service (IMDS) token mode (default `required`). <br><br> - `required` — IMDSv2 only; mitigates SSRF-style credential theft. <br> - `optional` — also allows IMDSv1; set only if a workload on the runner needs it. |
327
329
|`encrypt-ebs`| Optional. Used only with the `start` mode. | When `true`, the root EBS volume is created with SSE-EBS encryption using the account's default AWS-managed key (default `false`). Volume size / type / IOPS are preserved from the AMI unless overridden by the `volume-*` inputs below. |
328
330
|`volume-size`| Optional. Used only with the `start` mode. | Root EBS volume size in GiB. Omitted = AMI default (Amazon Linux 2023: 8 GiB). Must be ≥ the AMI snapshot size. See [Disk space for Docker workloads](#disk-space-for-docker-workloads). |
@@ -524,6 +526,51 @@ A single `subnet-id` + `ec2-instance-type` means a single point of failure: when
524
526
525
527
The `instance-type-used` and `subnet-id-used` outputs report what actually launched. Single values keep the original single-attempt behavior.
Need an extra package or a different distro? Two escape hatches mean you never have to fork.
532
+
533
+
### `pre-runner-script` — the 80% case
534
+
535
+
Inject shell into the built-in (supported) bootstrap, run as root before the runner registers:
536
+
537
+
```yml
538
+
- uses: namecheap/ec2-github-runner@v3
539
+
with:
540
+
mode: start
541
+
# ... other inputs ...
542
+
pre-runner-script: |
543
+
yum install -y docker
544
+
systemctl start docker
545
+
```
546
+
547
+
It runs under `set -euo pipefail` and a failure is tagged `failed:pre-runner-script`, so it shows up in the [fast-fail diagnostics](#troubleshooting-a-failed-start) like any other phase.
548
+
549
+
### `user-data-template` — full control
550
+
551
+
Replace the bootstrap entirely with your own script (repo-relative path or inline string). The action substitutes documented placeholders and submits the result:
Unknown `{{...}}` tokens fail the run (typo protection); the rendered payload must stay under the EC2 16 KB limit.
571
+
572
+
**Support boundary:** the built-in yum bootstrap is the only *supported* path. With a custom template, the action renders your placeholders and gives you the diagnostics tooling — but the script is yours. See [`examples/user-data/`](examples/user-data/) (an Ubuntu 24.04 template ships there as a community-maintained starting point). The two inputs are mutually exclusive.
573
+
527
574
## Running on Graviton (arm64)
528
575
529
576
Graviton instances (c7g/m7g/r7g/…) deliver ~20–40% better price/performance for the compile/test workloads CI runs, and Go/Rust/Node/Java toolchains are all arm64-native. Set `architecture: arm64` and point at an arm64 AMI:
> **Support boundary.** The built-in **yum-based** bootstrap (Amazon Linux 2023) is the only *supported* path. Templates in this directory are **community-maintained starting points**. When you supply `user-data-template`, the action renders your placeholders and gives you the same diagnostics tooling (bootstrap phone-home tags, console capture, cleanup) — but the script is yours to maintain. Bugs in a custom bootstrap are not action bugs.
**Contract:** the template must register the runner (`config.sh … --ephemeral --unattended` then `run.sh`). Verify the tarball checksum. Everything else is your distro's business. Rendered user-data must stay under the EC2 16 KB limit — fetch large payloads at runtime.
For a one-package tweak (e.g. install docker) you usually don't need a full template — use `pre-runner-script` instead, which keeps the supported bootstrap.
0 commit comments