@andrian.yablonskyy/thub-agent 1.0.22 → 1.0.23

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +45 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andrian.yablonskyy/thub-agent",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
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"
package/src/cli.js CHANGED
@@ -77,6 +77,34 @@ function firmwareFromImage(opts){
77
77
  return { image: opts.image };
78
78
  }
79
79
 
80
+ // --tests (archive URL) or --tests-git (+ at most one of branch/tag/commit).
81
+ function testsFromOptions(opts){
82
+ const refs = ['branch', 'tag', 'commit'].filter((k) => opts[`tests${k[0].toUpperCase()}${k.slice(1)}`]);
83
+ if (opts.tests && opts.testsGit){
84
+ throw usageError('give either --tests (an archive URL) or --tests-git (a repository), not both');
85
+ }
86
+ if (!opts.tests && !opts.testsGit){
87
+ throw usageError('missing test sources: --tests <archive-url> or --tests-git <repo> [--tests-branch|--tests-tag|--tests-commit]');
88
+ }
89
+ if (opts.tests){
90
+ if (refs.length){
91
+ throw usageError(`--tests-${refs[0]} only applies to --tests-git`);
92
+ }
93
+ return { url: opts.tests };
94
+ }
95
+ if (refs.length > 1){
96
+ throw usageError(`give at most one of --tests-branch, --tests-tag, --tests-commit (got ${refs.map((r) => `--tests-${r}`).join(', ')})`);
97
+ }
98
+ return {
99
+ git: {
100
+ url: opts.testsGit,
101
+ ...(opts.testsBranch ? { branch: opts.testsBranch } : {}),
102
+ ...(opts.testsTag ? { tag: opts.testsTag } : {}),
103
+ ...(opts.testsCommit ? { commit: opts.testsCommit } : {})
104
+ }
105
+ };
106
+ }
107
+
80
108
  function usageError(message){
81
109
  return Object.assign(new Error(message), { status: EXIT_CODES.USAGE });
82
110
  }
@@ -114,9 +142,22 @@ program
114
142
  'pulled from the Client\'s registry or Docker Hub; the Client must allow it (sw.allowJobImages)'
115
143
  )
116
144
  .option('--sha256 <hex>', 'Expected sha256 of a firmware --image URL; the Client verifies it before flashing/running')
117
- .requiredOption('--tests <url>', 'Test package URL in Artifactory')
145
+ .option(
146
+ '--tests <url>',
147
+ 'Test sources as an archive URL (tar, tar.gz/.tgz/.bz2/.xz, or zip) the Client downloads and unpacks. ' +
148
+ 'Give this or --tests-git'
149
+ )
150
+ .option('--tests-git <repo>', 'Test sources as a git repository (https://, ssh://, git:// or user@host:path) the Client fetches')
151
+ .option('--tests-branch <name>', 'With --tests-git: the branch to check out (default: the repository\'s default branch)')
152
+ .option('--tests-tag <name>', 'With --tests-git: the tag to check out')
153
+ .option('--tests-commit <sha>', 'With --tests-git: the commit to check out (7-40 hex digits)')
154
+ .option(
155
+ '--run <command>',
156
+ 'Shell command that starts the tests, run in the test sources on the Client (--arg values arrive as "$@"). ' +
157
+ 'Default: the sources\' own run-tests.sh. The Client must allow it (allowJobCommands)'
158
+ )
118
159
  .option('--suite <name>', 'Test suite name', 'default')
119
- .option('--arg <value>', 'Extra argument passed through to run-tests.sh on the Client (repeatable)', collectRepeatable, [])
160
+ .option('--arg <value>', 'Extra argument passed through to run-tests.sh / --run on the Client (repeatable)', collectRepeatable, [])
120
161
  .option('--timeout <duration>', 'e.g. 30m, 1h', '30m')
121
162
  .option('--priority <n>', 'Priority 0-100', (v) => Number(v))
122
163
  .option('--wait', 'Do not detach on job end; exit with the verdict code (used in CI)', false)
@@ -138,6 +179,7 @@ program
138
179
  .action(async (opts) => {
139
180
  try {
140
181
  const firmware = firmwareFromImage(opts),
182
+ testSources = testsFromOptions(opts),
141
183
  c = client(),
142
184
  labels = [...(opts.board ? [`board:${opts.board}`] : []), ...opts.label],
143
185
  meta = Object.fromEntries(opts.meta.map((kv) => kv.split(/=(.*)/s).slice(0, 2))),
@@ -147,7 +189,7 @@ program
147
189
  spec = {
148
190
  target: { type: opts.type, labels, ...(group ? { group } : {}), ...(opts.client ? { client: opts.client } : {}) },
149
191
  firmware,
150
- tests: { url: opts.tests, suite: opts.suite, args: opts.arg },
192
+ tests: { ...testSources, ...(opts.run ? { command: opts.run } : {}), suite: opts.suite, args: opts.arg },
151
193
  timeoutSec: parseDurationSec(opts.timeout),
152
194
  ...(opts.priority !== undefined ? { priority: opts.priority } : {}),
153
195
  ...(user ? { user } : {}),