@andrian.yablonskyy/thub-coordinator 1.1.13 → 1.1.14
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/package.json +2 -2
- package/views/help/_agent-cli.pug +4 -4
- package/views/help/_ci.pug +2 -2
- package/views/help/_client-machines.pug +4 -5
- package/views/help/_client-setup.pug +2 -2
- package/views/help/_docker.pug +38 -10
- package/views/help/_env.pug +11 -14
- package/views/help/_git.pug +10 -6
- package/views/mixins/client-config.pug +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrian.yablonskyy/thub-coordinator",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.14",
|
|
4
4
|
"description": "TestHub Coordinator — job queue, resource registry, scheduler, heartbeat monitor, log/artifact store and web dashboard",
|
|
5
5
|
"main": "src/server.js",
|
|
6
6
|
"engines": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"lint:fix": "eslint . --fix"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@andrian.yablonskyy/thub-common": "^1.1.
|
|
22
|
+
"@andrian.yablonskyy/thub-common": "^1.1.4",
|
|
23
23
|
"better-sqlite3": "^12.4.1",
|
|
24
24
|
"express": "^5.1.0",
|
|
25
25
|
"express-session": "^1.18.2",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
{ title: 'What to run', rows: [
|
|
26
26
|
['--command <string>', 'Required. Run with sh -c in the work directory. Exit code 0 = PASSED. It clones repositories and runs containers itself (see Using git / Using Docker).', "--command './ci/test.sh'"],
|
|
27
27
|
['--arg <value>', 'Argument for the command, as "$@" (repeatable).', '--arg --junit --arg -v'],
|
|
28
|
-
['--suite <name>', 'Passed as
|
|
28
|
+
['--suite <name>', 'Passed as JOB_SUITE (default: default).', '--suite smoke'],
|
|
29
29
|
['--download-file <url>', 'File downloaded before the command (repeatable, http(s), no credentials). THUB_DOWNLOAD_1…', '--download-file https://…/app.bin'],
|
|
30
30
|
['--env <vars>', 'NAME=value[,NAME=value] for the command (repeatable): how data and secrets reach the job (git tokens, registry passwords). --env NAME takes the value from your shell. Masked, dropped at job end.', '--env TARGET=staging --env API_TOKEN']
|
|
31
31
|
] },
|
|
@@ -70,12 +70,12 @@
|
|
|
70
70
|
thub run --type hw --label board:nucleo-f401re \
|
|
71
71
|
--download-file https://artifactory.example.com/fw-local/app/1.4.0-42/app.bin \
|
|
72
72
|
--env GH_TOKEN \
|
|
73
|
-
--command 'git clone --depth 1 --branch v1.4.0 "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git"
|
|
74
|
-
st-flash --
|
|
73
|
+
--command 'git clone --depth 1 --branch v1.4.0 "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git" src && cd src &&
|
|
74
|
+
st-flash --reset write "$THUB_DOWNLOAD_1" 0x08000000 && ./ci/test.sh "$@"' \
|
|
75
75
|
--arg --junit --timeout 45m --wait
|
|
76
76
|
+code('Reproduce a failure on the exact bench (the job carries your username)').
|
|
77
77
|
thub run --type hw --label board:nucleo-f401re --client lab-hw-01 \
|
|
78
|
-
--download-file "$IMAGE_URL" --env GH_TOKEN --command 'git clone --depth 1 "https://x-access-token:$GH_TOKEN@$TESTS_REPO"
|
|
78
|
+
--download-file "$IMAGE_URL" --env GH_TOKEN --command 'git clone --depth 1 "https://x-access-token:$GH_TOKEN@$TESTS_REPO" src && cd src && ./ci/test.sh'
|
|
79
79
|
# Ctrl-C detaches; the job keeps running. Re-attach:
|
|
80
80
|
thub status M-00126
|
|
81
81
|
+code('Verify a download before using it').
|
package/views/help/_ci.pug
CHANGED
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
--type hw --label board:nucleo-f401re \
|
|
35
35
|
--download-file "${{ needs.build.outputs.image_url }}" \
|
|
36
36
|
--env GH_TOKEN="${{ secrets.TESTS_READ_TOKEN }}",SHA="$GITHUB_SHA",REPO="$GITHUB_REPOSITORY" \
|
|
37
|
-
--command 'git init -q
|
|
38
|
-
st-flash --
|
|
37
|
+
--command 'git init -q src && cd src && git fetch -q --depth 1 "https://x-access-token:$GH_TOKEN@github.com/$REPO.git" "$SHA" && git checkout -q FETCH_HEAD &&
|
|
38
|
+
st-flash --reset write "$THUB_DOWNLOAD_1" 0x08000000 && ./ci/hw-tests.sh' \
|
|
39
39
|
--suite smoke --timeout 30m --wait \
|
|
40
40
|
--meta runUrl="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
|
|
41
41
|
ul.small.mb-0
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
thub run --type hw --label board:nucleo-f401re \
|
|
54
54
|
--download-file https://artifactory.example.com/fw-local/app/1.4.0-42/app.bin \
|
|
55
55
|
--env GH_TOKEN \
|
|
56
|
-
--command 'git clone --depth 1 --branch v1.4.0 "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git"
|
|
57
|
-
st-flash --
|
|
56
|
+
--command 'git clone --depth 1 --branch v1.4.0 "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git" src && cd src &&
|
|
57
|
+
st-flash --reset write "$THUB_DOWNLOAD_1" 0x08000000 && ./ci/test.sh' \
|
|
58
58
|
--wait
|
|
59
59
|
|
|
60
60
|
+note('warning').
|
|
@@ -74,10 +74,9 @@
|
|
|
74
74
|
+code('A typical SW job').
|
|
75
75
|
thub run --type sw \
|
|
76
76
|
--env GH_TOKEN --env DOCKER_PASSWORD \
|
|
77
|
-
--command 'git clone --depth 1 "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git"
|
|
78
|
-
export DOCKER_CONFIG="$THUB_WORK_DIR/.docker" &&
|
|
77
|
+
--command 'git clone --depth 1 "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git" src && cd src &&
|
|
79
78
|
echo "$DOCKER_PASSWORD" | docker login registry.lab.local:5000 -u ci --password-stdin &&
|
|
80
|
-
docker run --rm -v "$
|
|
79
|
+
docker run --rm --user "$(id -u):$(id -g)" -v "$THUB_WORK_DIR/src:/work" -w /work registry.lab.local:5000/dut-emulator:2026.08 make test' --wait
|
|
81
80
|
|
|
82
81
|
h3.h6 Checklist for any Client machine
|
|
83
82
|
ul.small.mb-0
|
|
@@ -106,8 +106,8 @@
|
|
|
106
106
|
change it hasn't applied yet. #[strong USB devices → Import to config] fills them from the host's #[code lsusb].
|
|
107
107
|
The card's #[strong Export] and #[strong Import] icons download a Client's config file (never its
|
|
108
108
|
#[code joinKey]) and apply one to it. An older HW Client takes only the file's #[code hw-devices].
|
|
109
|
-
There's no ST-Link serial field: the job's #[code --command] picks the probe
|
|
110
|
-
|
|
109
|
+
There's no ST-Link serial field: the job's #[code --command] picks the probe (#[code st-flash] alone uses the
|
|
110
|
+
only one; with several, #[code st-flash --serial] with a serial from #[code st-info --probe]).
|
|
111
111
|
|
|
112
112
|
h3.h6 Several DUT slots on one machine
|
|
113
113
|
+code('One instance per slot').
|
package/views/help/_docker.pug
CHANGED
|
@@ -13,11 +13,10 @@
|
|
|
13
13
|
thub run --type sw \
|
|
14
14
|
--env DOCKER_REGISTRY=registry.lab.local:5000,DOCKER_USER=ci --env DOCKER_PASSWORD \
|
|
15
15
|
--env TARGET=staging \
|
|
16
|
-
--command '
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-e TARGET -e THUB_SUITE -e THUB_JOB_ID \
|
|
16
|
+
--command 'echo "$DOCKER_PASSWORD" | docker login "$DOCKER_REGISTRY" -u "$DOCKER_USER" --password-stdin &&
|
|
17
|
+
docker run --rm --user "$(id -u):$(id -g)" \
|
|
18
|
+
-v "$THUB_WORK_DIR/src:/work" -w /work \
|
|
19
|
+
-e TARGET -e JOB_SUITE -e THUB_JOB_ID \
|
|
21
20
|
"$DOCKER_REGISTRY/team/test-runner:1.4" ./run-tests.sh --junit results/junit.xml' \
|
|
22
21
|
--wait
|
|
23
22
|
table.table.table-sm.small
|
|
@@ -30,8 +29,8 @@
|
|
|
30
29
|
td: code --rm
|
|
31
30
|
td Removes the container when the tests end.
|
|
32
31
|
tr
|
|
33
|
-
td: code -v "$THUB_WORK_DIR:/work" -w /work
|
|
34
|
-
td
|
|
32
|
+
td: code -v "$THUB_WORK_DIR/src:/work" -w /work
|
|
33
|
+
td Only the clone (#[code src/]), not the job directory, which holds the registry login in #[code .docker/]. The Client reads JUnit XML from #[code src/results/] or #[code src/artifacts/] for the test counts.
|
|
35
34
|
tr
|
|
36
35
|
td: code -e NAME
|
|
37
36
|
td Passes a job variable (#[code --env], #[code THUB_*], #[code JOB_*]) into the container.
|
|
@@ -40,7 +39,37 @@
|
|
|
40
39
|
td Files written to #[code /work] stay owned by the Client user, so the workspace can be cleaned up.
|
|
41
40
|
tr
|
|
42
41
|
td: code --device /dev/thub/dut1-uart
|
|
43
|
-
td HW: gives the container the DUT's UART (#[code
|
|
42
|
+
td HW: gives the container the DUT's UART (#[code /dev/thub/dut1-uart]). Use #[code --privileged] only if you must.
|
|
43
|
+
|
|
44
|
+
h3.h6 Clone and test inside a container, with a deploy key and a registry login from the job
|
|
45
|
+
p.small.
|
|
46
|
+
Everything comes from the Agent as #[code --env]: the registry and its credentials, and the private key the
|
|
47
|
+
container clones with. Nothing is set up on the Client host beforehand.
|
|
48
|
+
+code('Reference example').
|
|
49
|
+
# In CI, from its secret store — never typed on the command line:
|
|
50
|
+
export THUB_KEY=… # a CI token (dashboard → CI tokens)
|
|
51
|
+
export DOCKER_PASSWORD=… # the registry password
|
|
52
|
+
export GIT_KEY="$(cat ~/.ssh/thub_deploy)" # a private deploy key with read access to the repository
|
|
53
|
+
|
|
54
|
+
thub run --type sw \
|
|
55
|
+
--env DOCKER_REGISTRY=registry.lab:5000,DOCKER_USERNAME=ci-reader \
|
|
56
|
+
--env DOCKER_PASSWORD --env GIT_KEY \
|
|
57
|
+
--command 'echo "$DOCKER_PASSWORD" | docker login "$DOCKER_REGISTRY" --username "$DOCKER_USERNAME" --password-stdin &&
|
|
58
|
+
mkdir -p "$THUB_WORK_DIR/src" &&
|
|
59
|
+
docker run --rm -e GIT_KEY -e HOME=/tmp --user "$(id -u):$(id -g)" \
|
|
60
|
+
-v "$THUB_WORK_DIR/src:/work" -w /work --entrypoint sh alpine/git -c "
|
|
61
|
+
eval \$(ssh-agent -s) > /dev/null &&
|
|
62
|
+
printf \"%s\n\" \"\$GIT_KEY\" | ssh-add - &&
|
|
63
|
+
GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=accept-new\" git clone --depth 1 git@bitbucket.org:yourorg/web-ui-tests.git . &&
|
|
64
|
+
./run-tests.sh"' \
|
|
65
|
+
--wait
|
|
66
|
+
ul.small
|
|
67
|
+
li Plain values go as #[code --env NAME=value]. Secrets go as #[code --env NAME] alone: the Agent takes the value from its own environment, so it never appears on the command line, in shell history or in CI logs. A multi-line value, such as the key, arrives intact.
|
|
68
|
+
li The Client sets #[code DOCKER_CONFIG=$THUB_WORK_DIR/.docker]: the registry login lands in the job's directory, deleted with the job. Only #[code src/] is mounted into the container, so the login isn't visible in it.
|
|
69
|
+
li #[code -e GIT_KEY] hands the key to the container. #[code --entrypoint sh] is needed because #[code alpine/git]'s own entrypoint is #[code git]. #[code --user "$(id -u):$(id -g)"] (with #[code HOME=/tmp]) keeps the clone owned by the Client user, so it can be deleted with the job; #[code mkdir -p] first so Docker doesn't create #[code src/] as root.
|
|
70
|
+
li In the inner script, #[code \$] is escaped, so the #[strong container] expands the variables, not the Client's shell. #[code ssh-agent] holds the key in memory: it's never written to a file. #[code accept-new] trusts the git server's host key on first use.
|
|
71
|
+
li #[code alpine/git] comes from Docker Hub. The #[code docker login] is for private images such as #[code $DOCKER_REGISTRY/team/test-runner:1.4].
|
|
72
|
+
li Never #[code echo] a secret: the command's output is the job log, which is stored and visible.
|
|
44
73
|
|
|
45
74
|
h3.h6 An emulator as the DUT
|
|
46
75
|
p.small.
|
|
@@ -49,8 +78,7 @@
|
|
|
49
78
|
thub run --type sw \
|
|
50
79
|
--download-file https://artifactory.example.com/fw-local/app/1.4.0-42/app.elf \
|
|
51
80
|
--env DOCKER_REGISTRY=registry.lab.local:5000,DOCKER_USER=ci --env DOCKER_PASSWORD \
|
|
52
|
-
--command '
|
|
53
|
-
echo "$DOCKER_PASSWORD" | docker login "$DOCKER_REGISTRY" -u "$DOCKER_USER" --password-stdin &&
|
|
81
|
+
--command 'echo "$DOCKER_PASSWORD" | docker login "$DOCKER_REGISTRY" -u "$DOCKER_USER" --password-stdin &&
|
|
54
82
|
dut="thub-$THUB_JOB_ID" && trap "docker rm -f $dut >/dev/null" EXIT &&
|
|
55
83
|
docker run -d --name "$dut" -p 127.0.0.1:5555:5555 -v "$THUB_DOWNLOADS_DIR:/downloads:ro" \
|
|
56
84
|
"$DOCKER_REGISTRY/dut-emulator:2026.08" &&
|
package/views/help/_env.pug
CHANGED
|
@@ -10,14 +10,11 @@
|
|
|
10
10
|
const thubVars = [
|
|
11
11
|
['THUB_JOB_ID', 'The job id, e.g. M-00125'],
|
|
12
12
|
['THUB_ARTIFACTS_FILE', 'Where the command may list the artifacts it published elsewhere: a JSON array of {"name", "size", "link", "timestamp"}, shown on the job page'],
|
|
13
|
-
['THUB_WORK_DIR', 'The directory the command
|
|
14
|
-
['
|
|
13
|
+
['THUB_WORK_DIR', 'The job\'s directory (<client workDir>/<jobId>), where the command starts. Holds downloads/, the artifacts list and .docker/ (the job\'s DOCKER_CONFIG); clone into a folder of your own, e.g. src/. JUnit XML in results/ or artifacts/ gives the test counts; deleted when the job ends'],
|
|
14
|
+
['DOCKER_CONFIG', '$THUB_WORK_DIR/.docker — so a docker login stays with the job and is deleted with it (unless --env sets DOCKER_CONFIG)'],
|
|
15
15
|
['THUB_DOWNLOADS_DIR', 'Where the --download-file files are'],
|
|
16
16
|
['THUB_DOWNLOADS / THUB_DOWNLOAD_<n>', 'Local paths of the downloads: all, one per line / each one'],
|
|
17
17
|
['THUB_META_<KEY>', '--meta values; camelCase keys become SNAKE_CASE (ciJobId → THUB_META_CI_JOB_ID)'],
|
|
18
|
-
['THUB_DUT_STLINK / _<n>', 'HW: ST-Link serials (device path if the serial couldn\'t be read); unsuffixed = the first'],
|
|
19
|
-
['THUB_DUT_UART / _<n>', 'HW: UART device paths (/dev/thub/dut<N>-uart); unsuffixed = the first'],
|
|
20
|
-
['THUB_DUT_USB / _<n>', 'HW: DUT USB device paths']
|
|
21
18
|
]
|
|
22
19
|
.table-responsive
|
|
23
20
|
table.table.table-sm.small
|
|
@@ -80,7 +77,7 @@
|
|
|
80
77
|
+code('ci/test.sh (shell)').
|
|
81
78
|
#!/bin/sh
|
|
82
79
|
set -eu
|
|
83
|
-
echo "Job $THUB_JOB_ID on $(hostname), suite ${
|
|
80
|
+
echo "Job $THUB_JOB_ID on $(hostname), suite ${JOB_SUITE}"
|
|
84
81
|
|
|
85
82
|
# optional parameters with defaults
|
|
86
83
|
TARGET="${TARGET:-staging}"
|
|
@@ -90,21 +87,21 @@
|
|
|
90
87
|
printf '%s\n' "$THUB_DOWNLOADS" | while read -r f; do echo "downloaded: $f"; done
|
|
91
88
|
|
|
92
89
|
# HW: flash through the first ST-Link, talk to the second UART
|
|
93
|
-
st-flash --
|
|
94
|
-
python3 -m pytest tests/ --uart "
|
|
90
|
+
st-flash --reset write "$THUB_DOWNLOAD_1" 0x08000000
|
|
91
|
+
python3 -m pytest tests/ --uart "/dev/thub/dut2-uart" --junitxml=results/junit.xml
|
|
95
92
|
|
|
96
93
|
# CI metadata passed with --meta ciJobId=… / --meta sha=…
|
|
97
94
|
echo "CI run ${THUB_META_CI_JOB_ID:-local}, sha ${THUB_META_SHA:-unknown}"
|
|
98
95
|
+code('conftest.py (Python)').
|
|
99
|
-
import os
|
|
96
|
+
import glob, os
|
|
100
97
|
|
|
101
|
-
UARTS =
|
|
98
|
+
UARTS = sorted(glob.glob("/dev/thub/dut*-uart")) # this Client's UARTs, by udev path
|
|
102
99
|
FIRMWARE = os.environ.get("THUB_DOWNLOAD_1")
|
|
103
|
-
RESULTS =
|
|
100
|
+
RESULTS = "results" # in the clone (src/results), where the tests run
|
|
104
101
|
API_TOKEN = os.environ["API_TOKEN"] # from --env API_TOKEN
|
|
105
102
|
+code('Into a container: -e NAME copies a variable from the job').
|
|
106
|
-
docker run --rm -v "$THUB_WORK_DIR:/work" -w /work \
|
|
107
|
-
-e THUB_JOB_ID -e
|
|
103
|
+
docker run --rm --user "$(id -u):$(id -g)" -v "$THUB_WORK_DIR/src:/work" -w /work \
|
|
104
|
+
-e THUB_JOB_ID -e JOB_SUITE -e TARGET -e API_TOKEN \
|
|
108
105
|
python:3.14 ./run-tests.sh
|
|
109
106
|
+code('Submitting the job that feeds these').
|
|
110
107
|
export API_TOKEN=…
|
|
@@ -113,7 +110,7 @@
|
|
|
113
110
|
--env TARGET=production,BRANCH=main --env API_TOKEN --env GH_TOKEN \
|
|
114
111
|
--meta ciJobId="$GITHUB_RUN_ID" --meta sha="$GITHUB_SHA" \
|
|
115
112
|
--suite smoke \
|
|
116
|
-
--command 'git clone --depth 1 --branch "$BRANCH" "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git"
|
|
113
|
+
--command 'git clone --depth 1 --branch "$BRANCH" "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git" src && cd src &&
|
|
117
114
|
./ci/test.sh' --wait
|
|
118
115
|
p.small.text-body-secondary.mb-0.
|
|
119
116
|
Tip: #[code thub run … --dry-run] lists every variable the command would get on the chosen Client, with #[code --env] values as #[code ***].
|
package/views/help/_git.pug
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export GH_TOKEN=… # GitHub: a fine-grained PAT with read access; GitLab: oauth2 token; Bitbucket: x-token-auth
|
|
12
12
|
thub run --type sw \
|
|
13
13
|
--env GH_TOKEN \
|
|
14
|
-
--command 'git clone --depth 1 --branch main "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git"
|
|
14
|
+
--command 'git clone --depth 1 --branch main "https://x-access-token:$GH_TOKEN@github.com/yourorg/firmware-tests.git" src && cd src &&
|
|
15
15
|
./ci/test.sh' \
|
|
16
16
|
--wait
|
|
17
17
|
p.small.
|
|
@@ -23,19 +23,23 @@
|
|
|
23
23
|
export DEPLOY_KEY_B64="$(base64 < ~/.ssh/thub_deploy | tr -d '\n')"
|
|
24
24
|
thub run --type hw --label board:nucleo-f401re \
|
|
25
25
|
--env DEPLOY_KEY_B64 \
|
|
26
|
-
--command 'umask 077 && echo "$DEPLOY_KEY_B64" | base64 -d > "$THUB_WORK_DIR
|
|
27
|
-
GIT_SSH_COMMAND="ssh -i $THUB_WORK_DIR
|
|
28
|
-
git clone --depth 1 git@github.com:yourorg/firmware-tests.git
|
|
26
|
+
--command 'umask 077 && echo "$DEPLOY_KEY_B64" | base64 -d > "$THUB_WORK_DIR/key" &&
|
|
27
|
+
GIT_SSH_COMMAND="ssh -i $THUB_WORK_DIR/key -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new" \
|
|
28
|
+
git clone --depth 1 git@github.com:yourorg/firmware-tests.git src && cd src &&
|
|
29
29
|
./ci/test.sh' \
|
|
30
30
|
--wait
|
|
31
31
|
p.small.
|
|
32
32
|
The job directory, key included, is deleted when the job ends. Add the public key as a read-only deploy key: GitHub,
|
|
33
33
|
Repository → Settings → Deploy keys; GitLab, Settings → Repository → Deploy keys; Bitbucket, Repository settings → Access keys.
|
|
34
34
|
|
|
35
|
+
p.small.
|
|
36
|
+
To clone #[em inside a container] with a key passed the same way (held by #[code ssh-agent], never written to disk), see
|
|
37
|
+
#[a(href="#docker") Using Docker → Clone and test inside a container].
|
|
38
|
+
|
|
35
39
|
h3.h6 Branch, tag, commit, submodules, LFS
|
|
36
40
|
+code('All in the command').
|
|
37
|
-
git clone --depth 1 --branch v1.4.0 "$REPO"
|
|
38
|
-
git init -q
|
|
41
|
+
git clone --depth 1 --branch v1.4.0 "$REPO" src # a branch or tag
|
|
42
|
+
git init -q src && cd src && git remote add origin "$REPO" && git fetch -q --depth 1 origin a1b2c3d && git checkout -q FETCH_HEAD # a commit
|
|
39
43
|
git submodule update --init --recursive --depth 1 && git lfs pull # submodules / LFS
|
|
40
44
|
p.small.
|
|
41
45
|
Pass the repository and ref as #[code --env REPO=…,REF=…] (or #[code --meta]) so the same command works for every branch.
|
|
@@ -249,7 +249,7 @@ mixin configPanes(r, returnTo, groupsById)
|
|
|
249
249
|
+configPane(p, 'stlinks')
|
|
250
250
|
+capabilitiesStatus(r)
|
|
251
251
|
+deviceTable('stlinks', 'ST-Link probes', current.stlinks || [], ['Device', 'udev devpath'])
|
|
252
|
-
.form-text Device: a udev index 1–8 (→ /dev/thub/dut<N>-stlink) or a /dev path. Which probe a job uses is up to its #[code --command] (
|
|
252
|
+
.form-text Device: a udev index 1–8 (→ /dev/thub/dut<N>-stlink) or a /dev path. Which probe a job uses is up to its #[code --command] (st-flash, by serial with several probes).
|
|
253
253
|
+saveCapabilities(canEdit)
|
|
254
254
|
+configPane(p, 'uarts')
|
|
255
255
|
+capabilitiesStatus(r)
|