@andrian.yablonskyy/thub-agent 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/package.json +1 -1
- package/src/cli.js +18 -3
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ Key options for `thub run`. **On the Client** names the environment variable the
|
|
|
48
48
|
| Option | Description | On the Client |
|
|
49
49
|
|---|---|---|
|
|
50
50
|
| `--type hw\|sw` | Required resource type. | `JOB_TYPE` |
|
|
51
|
-
| `--
|
|
51
|
+
| `--label <l>` | Required labels (repeatable; a board is `--label board:<name>`): the job runs only on a runner that has all of them. Each 1–64 characters, no whitespace, commas or semicolons. | `JOB_LABEL`, `JOB_LABEL_<n>` |
|
|
52
52
|
| `--client <name\|id>` | Run on this specific Client (resource name or id) only; the job waits in that Client's queue even if other matching resources are idle. | `JOB_CLIENT` |
|
|
53
53
|
| `--user <name>` | Free-text job owner — a label, not an identity. Falls back to `THUB_USER` / `thub config set user <name>`. | `JOB_USER` |
|
|
54
54
|
| `--command <string>` | **Required.** The task's entry point: a shell command the Client runs (`sh -c`) in the task's work directory — the `--git-repo` checkout, else an empty directory — after preparing its inputs. Its exit code is the verdict. On HW it flashes the board itself (the Client doesn't); it gets `THUB_DUT_STLINK`/`_UART`/`_USB`/`_HOST`/`_CONTAINER`, `THUB_DOWNLOAD_<n>`, `THUB_DOWNLOADS_DIR`, `THUB_GIT_COMMIT`, `THUB_SUITE`, `THUB_META_*`. | `JOB_COMMAND` |
|
|
@@ -88,7 +88,7 @@ Exit codes make the Agent usable as a CI step:
|
|
|
88
88
|
**Run a task** — download the firmware, check out the tests at a tag, flash and test (HW):
|
|
89
89
|
|
|
90
90
|
```bash
|
|
91
|
-
thub run --type hw --board
|
|
91
|
+
thub run --type hw --label board:nucleo-f401re \
|
|
92
92
|
--download-file "$IMAGE_URL" \
|
|
93
93
|
--git-repo https://github.com/yourorg/firmware-tests.git v1.4.0 \
|
|
94
94
|
--command 'st-flash --serial "$THUB_DUT_STLINK" --reset write "$THUB_DOWNLOAD_1" 0x08000000 && ./ci/test.sh "$@"' \
|
|
@@ -125,7 +125,7 @@ thub run --type sw --download-file https://does-not-exist.invalid/app.bin \
|
|
|
125
125
|
**Label a job with its owner** — purely informational, shows up on the dashboard, in `thub jobs`, and on the Client's own console:
|
|
126
126
|
|
|
127
127
|
```bash
|
|
128
|
-
thub run --type hw --board
|
|
128
|
+
thub run --type hw --label board:nucleo-f401re \
|
|
129
129
|
--git-repo "$TESTS_REPO" --command ./ci/test.sh --user "Your Name" --wait
|
|
130
130
|
```
|
|
131
131
|
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -134,12 +134,27 @@ function fail(err){
|
|
|
134
134
|
process.exit(err.status && Number.isInteger(err.status) && err.status < 100 ? err.status : EXIT_CODES.USAGE);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
// --label: the labels a runner must all have for the job (§7.1).
|
|
138
|
+
// Checked here against the Coordinator's rule, so a typo fails before the
|
|
139
|
+
// job is sent.
|
|
140
|
+
const LABEL_RE = /^[^\s,;]{1,64}$/;
|
|
141
|
+
function requiredLabels(opts){
|
|
142
|
+
const labels = opts.label,
|
|
143
|
+
bad = labels.filter((l) => !LABEL_RE.test(l));
|
|
144
|
+
if (bad.length){
|
|
145
|
+
const err = new Error(`Invalid label: ${bad.join(', ')} — 1–64 characters, no spaces, commas or semicolons`);
|
|
146
|
+
err.status = EXIT_CODES.USAGE;
|
|
147
|
+
throw err;
|
|
148
|
+
}
|
|
149
|
+
return [...new Set(labels)];
|
|
150
|
+
}
|
|
151
|
+
|
|
137
152
|
program
|
|
138
153
|
.command('run')
|
|
139
154
|
.description('Submit a test job and follow its log')
|
|
140
155
|
.requiredOption('--type <hw|sw>', 'Required resource type')
|
|
141
|
-
.option('--
|
|
142
|
-
|
|
156
|
+
.option('--label <label>', 'A label the runner must have (repeatable; the job runs only on a runner with all of them). ' +
|
|
157
|
+
'1–64 characters, no spaces, commas or semicolons', collectRepeatable, [])
|
|
143
158
|
.option(
|
|
144
159
|
'--client <nameOrId>',
|
|
145
160
|
'Run on this specific Client (resource name or id) only; the job waits in that Client\'s queue ' +
|
|
@@ -211,7 +226,7 @@ program
|
|
|
211
226
|
try {
|
|
212
227
|
const task = taskFromOptions(opts),
|
|
213
228
|
c = client(),
|
|
214
|
-
labels =
|
|
229
|
+
labels = requiredLabels(opts),
|
|
215
230
|
meta = Object.fromEntries(opts.meta.map((kv) => kv.split(/=(.*)/s).slice(0, 2))),
|
|
216
231
|
user = resolveUser({ user: opts.user }),
|
|
217
232
|
|