@andrian.yablonskyy/thub-agent 1.1.4 → 1.1.5

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.
Files changed (3) hide show
  1. package/README.md +28 -23
  2. package/package.json +2 -2
  3. package/src/cli.js +2 -2
package/README.md CHANGED
@@ -52,7 +52,7 @@ Key options for `thub run`. **On the Client** names the environment variable the
52
52
  | `--command <string>` | **Required.** The task's entry point: a shell command the Client runs (`sh -c`) in the job's work directory, after the downloads. It clones repositories and runs containers itself (see Git and Docker below), with credentials from `--env`. Exit code 0 = PASSED. | `JOB_COMMAND` | `JOB_COMMAND` |
53
53
  | `--download-file <url>` | A file the Client downloads before running the command (repeatable, `http(s)`), into the job's `downloads/` directory. | `JOB_DOWNLOAD_FILE`, `JOB_DOWNLOAD_FILE_<n>` (URLs); `THUB_DOWNLOAD_<n>` (local paths) |
54
54
  | `--env <vars>` | Environment variables for every command the Client runs for the job (git and `--command`): `NAME=value[,NAME=value]`, repeatable; `--env NAME` alone takes the value from your shell. Any names — none means anything to the Agent or the Client (only `THUB_*`, `JOB_*`, `GIT_TERMINAL_PROMPT`, `GIT_ALLOW_PROTOCOL` are refused). Every value is a secret: it reaches only the Client running the job; the Coordinator masks it and drops it when the job ends. | each `NAME` itself |
55
- | `--suite <name>` | Passed to the command as `THUB_SUITE`. | `JOB_SUITE` (also `THUB_SUITE`) |
55
+ | `--suite <name>` | Test suite name for the command. | `JOB_SUITE` |
56
56
  | `--arg <value>` | Extra argument for the command, as `"$@"` (repeatable). | `JOB_ARG`, `JOB_ARG_<n>` (and `"$@"`) |
57
57
  | `--timeout <dur>` | e.g. `30m`, default `30m`. | `JOB_TIMEOUT` (seconds) |
58
58
  | `--priority <n>` | 0–100; CI defaults to 50, CLI to 60 so a developer is not starved by a busy pipeline. | `JOB_PRIORITY` |
@@ -85,8 +85,8 @@ Exit codes make the Agent usable as a CI step:
85
85
  export GH_TOKEN=… # read access to the tests repository
86
86
  thub run --type hw --label board:nucleo-f401re \
87
87
  --download-file "$IMAGE_URL" --env GH_TOKEN \
88
- --command 'git clone --depth 1 --branch v1.4.0 "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git" . &&
89
- st-flash --serial "$THUB_DUT_STLINK" --reset write "$THUB_DOWNLOAD_1" 0x08000000 && ./ci/test.sh "$@"' \
88
+ --command 'git clone --depth 1 --branch v1.4.0 "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git" src && cd src &&
89
+ st-flash --reset write "$THUB_DOWNLOAD_1" 0x08000000 && ./ci/test.sh "$@"' \
90
90
  --arg --junit --wait
91
91
  ```
92
92
 
@@ -147,7 +147,7 @@ The Client doesn't clone anything (and doesn't need git itself): the command doe
147
147
  ```bash
148
148
  export GH_TOKEN=…
149
149
  thub run --type sw --env GH_TOKEN,REF=main \
150
- --command 'git clone --depth 1 --branch "$REF" "https://x-access-token:$GH_TOKEN@github.com/yourorg/tests.git" . && ./ci/test.sh' --wait
150
+ --command 'git clone --depth 1 --branch "$REF" "https://x-access-token:$GH_TOKEN@github.com/yourorg/tests.git" src && cd src && ./ci/test.sh' --wait
151
151
  ```
152
152
 
153
153
  For SSH, pass the private key itself as `--env` (base64) and use it via `GIT_SSH_COMMAND` from a file in the job directory, which is deleted with the job (main README, §7.2).
@@ -162,48 +162,53 @@ The Client doesn't pull images or start containers (and doesn't need Docker itse
162
162
  export DOCKER_PASSWORD=…
163
163
  thub run --type hw \
164
164
  --env DOCKER_REGISTRY=registry.lab.local:5000,DOCKER_USER=ci --env DOCKER_PASSWORD \
165
- --command 'export DOCKER_CONFIG="$THUB_WORK_DIR/.docker" &&
166
- echo "$DOCKER_PASSWORD" | docker login "$DOCKER_REGISTRY" --username "$DOCKER_USER" --password-stdin &&
165
+ --command 'echo "$DOCKER_PASSWORD" | docker login "$DOCKER_REGISTRY" --username "$DOCKER_USER" --password-stdin &&
167
166
  docker pull "$DOCKER_REGISTRY/team/test-runner:1.4"' \
168
167
  --wait
169
168
  ```
170
169
 
171
- **Run the command inside a container:** `--command` starts on the Client host in the work directory (`$THUB_WORK_DIR`). Clone into it, then start the container mounting it:
170
+ **Run the command inside a container:** `--command` starts on the Client host in the job's directory (`$THUB_WORK_DIR`). Clone into `src/`, then start the container mounting only `src/` (the directory also holds `.docker/`, the job's registry login):
172
171
 
173
172
  ```bash
174
173
  thub run --type sw \
175
174
  --env DOCKER_REGISTRY=registry.lab.local:5000,DOCKER_USER=ci --env DOCKER_PASSWORD --env GH_TOKEN \
176
- --command 'git clone --depth 1 "https://x-access-token:$GH_TOKEN@github.com/yourorg/web-ui-tests.git" . &&
177
- export DOCKER_CONFIG="$THUB_WORK_DIR/.docker" &&
175
+ --command 'git clone --depth 1 "https://x-access-token:$GH_TOKEN@github.com/yourorg/web-ui-tests.git" src && cd src &&
178
176
  echo "$DOCKER_PASSWORD" | docker login "$DOCKER_REGISTRY" --username "$DOCKER_USER" --password-stdin &&
179
- docker run --rm -v "$THUB_WORK_DIR:/work" -w /work "$DOCKER_REGISTRY/python:3.14" ./run-tests.sh' \
177
+ docker run --rm --user "$(id -u):$(id -g)" -v "$THUB_WORK_DIR/src:/work" -w /work "$DOCKER_REGISTRY/python:3.14" ./run-tests.sh' \
180
178
  --wait
181
179
  ```
182
180
 
183
- **Clone the repository inside the image, with parameters from `--env`:**
181
+ **Clone and test inside a container, with a deploy key and a registry login from `--env`** (the reference example for passing data and secrets to a job):
184
182
 
185
183
  ```bash
184
+ # In CI, from its secret store — never typed on the command line:
185
+ export THUB_KEY=… # a CI token (dashboard → CI tokens)
186
+ export DOCKER_PASSWORD=… # the registry password
187
+ export GIT_KEY="$(cat ~/.ssh/thub_deploy)" # a private deploy key with read access to the repository
188
+
186
189
  thub run --type sw \
187
- --env DOCKER_REGISTRY=registry.lab.local:5000,DOCKER_USER=ci --env DOCKER_PASSWORD \
188
- --env TEST_IMAGE=registry.lab.local:5000/team/test-runner:1.4 \
189
- --env REPO_URL=git@bitbucket.org:yourorg/web-ui-tests.git,REPO_REF=main \
190
- --env 'GIT_SSH_COMMAND=ssh -i /root/.ssh/id_ed25519 -o StrictHostKeyChecking=accept-new' \
191
- --command 'export DOCKER_CONFIG="$THUB_WORK_DIR/.docker" &&
192
- echo "$DOCKER_PASSWORD" | docker login "$DOCKER_REGISTRY" --username "$DOCKER_USER" --password-stdin &&
193
- docker run --rm -e REPO_URL -e REPO_REF -e GIT_SSH_COMMAND \
194
- -v "$HOME/.ssh:/root/.ssh:ro" -v "$THUB_WORK_DIR/results:/results" \
195
- "$TEST_IMAGE" sh -c "git clone --depth 1 --branch \"\$REPO_REF\" \"\$REPO_URL\" /src && cd /src && ./run-tests.sh --junit /results"' \
190
+ --env DOCKER_REGISTRY=registry.lab:5000,DOCKER_USERNAME=ci-reader \
191
+ --env DOCKER_PASSWORD --env GIT_KEY \
192
+ --command 'echo "$DOCKER_PASSWORD" | docker login "$DOCKER_REGISTRY" --username "$DOCKER_USERNAME" --password-stdin &&
193
+ mkdir -p "$THUB_WORK_DIR/src" &&
194
+ docker run --rm -e GIT_KEY -e HOME=/tmp --user "$(id -u):$(id -g)" \
195
+ -v "$THUB_WORK_DIR/src:/work" -w /work --entrypoint sh alpine/git -c "
196
+ eval \$(ssh-agent -s) > /dev/null &&
197
+ printf \"%s\n\" \"\$GIT_KEY\" | ssh-add - &&
198
+ GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=accept-new\" git clone --depth 1 git@bitbucket.org:yourorg/web-ui-tests.git . &&
199
+ ./run-tests.sh"' \
196
200
  --wait
197
201
  ```
198
202
 
203
+ Plain values go as `--env NAME=value`, secrets as `--env NAME` (taken from your environment, so never on the command line; multi-line values arrive intact). The inner script's `\$` is expanded in the container; `ssh-agent` keeps the key in memory only; `--entrypoint sh` because `alpine/git`'s entrypoint is `git`; `--user` keeps the clone deletable by the Client. Only `src/` is mounted, so the registry login (the Client's `DOCKER_CONFIG`, `$THUB_WORK_DIR/.docker`) stays out of the container. More in the main README, §7.2.
204
+
199
205
  The Client host needs Docker and the Client's user in the `docker` group for these (install Docker before the Client). Add `--dry-run` to see every command a job would run on the Client (every `--env` value shown as `***`) without running any. More in the main README, §7.2.
200
206
 
201
207
  ## Client environment variables
202
208
 
203
209
  On the Client, the job's `--command` gets every option above as a `JOB_<NAME>` variable (the **On the Client** column). A variable whose option wasn't given is unset. A repeatable option gives `<NAME>` with all values plus `<NAME>_<n>` for each one. It also gets:
204
210
  - its `--env` variables, under their own names;
205
- - `THUB_JOB_ID`, `THUB_WORK_DIR` (where it runs), `THUB_DOWNLOADS_DIR`, `THUB_DOWNLOADS`, `THUB_DOWNLOAD_<n>` (local paths), `THUB_SUITE` and `THUB_META_<KEY>`;
206
- - the DUT's `THUB_DUT_UART[_<n>]`, `THUB_DUT_USB[_<n>]`, `THUB_DUT_STLINK[_<n>]` (HW).
211
+ - `THUB_JOB_ID`, `THUB_WORK_DIR` (where it runs), `THUB_DOWNLOADS_DIR`, `THUB_DOWNLOADS`, `THUB_DOWNLOAD_<n>` (local paths) and `THUB_META_<KEY>`. HW devices are used by their `/dev/thub/dut<N>-uart|usb|stlink` paths; no device variables are passed.
207
212
 
208
213
  `THUB_*` and `JOB_*` names can't be set with `--env`. The full list is in the main README, §7.4.
209
214
 
@@ -246,7 +251,7 @@ test-sw:
246
251
  npx -y @andrian.yablonskyy/thub-agent run --type sw \
247
252
  --download-file "${{ needs.build.outputs.image_url }}" \
248
253
  --env GH_TOKEN="${{ secrets.TESTS_READ_TOKEN }}",REPO="$GITHUB_REPOSITORY",SHA="$GITHUB_SHA" \
249
- --command 'git init -q . && git fetch -q --depth 1 "https://x-access-token:$GH_TOKEN@github.com/$REPO.git" "$SHA" &&
254
+ --command 'git init -q src && cd src && git fetch -q --depth 1 "https://x-access-token:$GH_TOKEN@github.com/$REPO.git" "$SHA" &&
250
255
  git checkout -q FETCH_HEAD && ./ci/sw-tests.sh' --suite full --wait
251
256
  ```
252
257
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andrian.yablonskyy/thub-agent",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "TestHub Agent CLI — the single entry point CI/CD and developers use to submit and follow test jobs",
5
5
  "bin": {
6
6
  "thub": "./src/cli.js"
@@ -12,7 +12,7 @@
12
12
  "lint:fix": "eslint . --fix"
13
13
  },
14
14
  "dependencies": {
15
- "@andrian.yablonskyy/thub-common": "^1.1.3",
15
+ "@andrian.yablonskyy/thub-common": "^1.1.4",
16
16
  "commander": "^13.1.0"
17
17
  },
18
18
  "devDependencies": {
package/src/cli.js CHANGED
@@ -131,7 +131,7 @@ program
131
131
  '--command <string>',
132
132
  'The task\'s entry point: a shell command the Client runs (sh -c) in the job\'s work directory, after downloading ' +
133
133
  '--download-file files. --arg values arrive as "$@". Anything else the job needs it does itself — e.g. ' +
134
- '`git clone "https://x-access-token:$GH_TOKEN@github.com/org/tests.git" . && ./ci/test.sh` or ' +
134
+ '`git clone "https://x-access-token:$GH_TOKEN@github.com/org/tests.git" src && cd src && ./ci/test.sh` or ' +
135
135
  '`docker run --rm "$IMAGE" ./run.sh` — with credentials passed by --env'
136
136
  )
137
137
  .option(
@@ -150,7 +150,7 @@ program
150
150
  collectRepeatable,
151
151
  []
152
152
  )
153
- .option('--suite <name>', 'Test suite name, passed to --command as THUB_SUITE', 'default')
153
+ .option('--suite <name>', 'Test suite name, passed to --command as JOB_SUITE', 'default')
154
154
  .option('--arg <value>', 'Extra argument for --command, as "$@" (repeatable)', collectRepeatable, [])
155
155
  .option('--timeout <duration>', 'e.g. 30m, 1h', '30m')
156
156
  .option('--priority <n>', 'Priority 0-100', (v) => Number(v))