Skip to content

Commit 690db85

Browse files
committed
define workflows for android, ubuntu 20.04 and ubuntu 24.04
1 parent 769fb60 commit 690db85

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

src/lib/tachyon/workflow.js

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
const os = require('os');
2+
const steps = require('./steps');
3+
/**
4+
* @typedef {Object} Workflow
5+
* @property {string} name
6+
* @property {string} value
7+
* @property {Object} [overrideDefaults] - In case some defaults needs to be overridden
8+
* @property {Object} osInfo - Data required to filter out the OS from manifest
9+
* @property {string} [selectionWarning] - Warning to show after the user selects this workflow.
10+
* @property {{ name: string, value: string }[]} variants - Accepted variants to choose
11+
* @property {ReadonlyArray<Step>} steps
12+
*/
13+
14+
/**
15+
* Minimal logger interface that writes JSON lines.
16+
* @typedef {Object} Logger
17+
* @property {(msg: string, extra?: LogExtra) => void} info Write an info entry.
18+
* @property {(msg: string, extra?: LogExtra) => void} error Write an error entry.
19+
* @property {() => Promise<void>} close Flush and close the file.
20+
*/
21+
22+
/**
23+
* Setup options used by the workflow runner.
24+
* @typedef {Object} SetupOptions
25+
* @property {('NA'|'RoW'|string)} region - Target region. Default: `'NA'`.
26+
* @property {string} version - Tachyon version or channel. Default: `settings.tachyonVersion || 'stable'`.
27+
* @property {string} board - Hardware/board identifier (e.g., `'formfactor_dvt'`). Default: `'formfactor_dvt'`.
28+
* @property {string} distroVersion - Distro version (e.g., `'20.04'`). Default: `'20.04'`.
29+
* @property {string} country - Country/locale code (e.g., `'USA'`). Default: `'USA'`.
30+
* @property {string|null} variant - Optional SKU/variant; `null` if not applicable. Default: `null`.
31+
* @property {boolean} skipFlashingOs - If `true`, do not flash the OS. Default: `false`.
32+
* @property {boolean} skipCli - If `true`, skip CLI install/config steps. Default: `false`.
33+
* @property {string} timezone - IANA timezone (e.g., `'America/Mexico_City'`). Default: from `Intl.DateTimeFormat().resolvedOptions().timeZone`.
34+
* @property {boolean} alwaysCleanCache - If `true`, wipe local caches before running. Default: `false`.
35+
*/
36+
/**
37+
* @typedef Config
38+
* @property {Object} deviceInfo - device info from identify
39+
* @property {Object} selectedOS - information of OS to be installed
40+
* @property {SetupOptions} options
41+
* @property {boolean} silent - indicates if the workflow will run on silent mode
42+
* @property {Object} state - indicates logs from every step
43+
*/
44+
45+
/**
46+
* @typedef {Object} Context
47+
* @property {{ write:(msg:string)=>void }} ui
48+
* @property {Workflow} workflow
49+
* @property {Logger} log
50+
* @property {Config} config
51+
* @property {Object} state
52+
*/
53+
54+
/**
55+
* A single step in the workflow.
56+
* @callback Step
57+
* @param {Context} ctx
58+
* @returns {Promise<void>|void}
59+
*/
60+
61+
/** @type {Workflow} */
62+
const ubuntu20 = Object.freeze({
63+
name: 'Ubuntu 20.04 (stable), recommended',
64+
value: 'ubuntu20',
65+
osInfo: {
66+
distribution: 'ubuntu',
67+
distributionVersion: '20.04',
68+
distributionVariant: 'ubuntu'
69+
},
70+
variants: [
71+
{ name: 'Desktop (GUI)', value: 'desktop' },
72+
{ name: 'Headless (command-line only)', value: 'headless' },
73+
],
74+
steps: Object.freeze([
75+
steps.pickVariant,
76+
steps.getUserConfigurationStep,
77+
steps.configureProductStep,
78+
steps.getCountryStep,
79+
steps.downloadOS,
80+
steps.printOSInfo,
81+
steps.registerDeviceStep,
82+
steps.getESIMProfilesStep,
83+
steps.createConfigBlobStep,
84+
steps.flashOSAndConfigStep,
85+
steps.setupCompletedStep
86+
])
87+
});
88+
89+
/** @type {Workflow} */
90+
const ubuntu24 = Object.freeze({
91+
name: 'Ubuntu 24.04 (alpha)',
92+
value: 'ubuntu24',
93+
selectionWarning: 'Heads-up: Development of Ubuntu 24.04 (alpha) is still in progress. Some features may be ' +
94+
`unstable or missing. ${os.EOL}`,
95+
osInfo: {
96+
distribution: 'ubuntu',
97+
distributionVersion: '24.04',
98+
distributionVariant: 'ubuntu'
99+
},
100+
overrideDefaults:{
101+
version: 'latest',
102+
},
103+
variants: [
104+
{ name: 'Desktop (GUI)', value: 'desktop' },
105+
],
106+
steps: Object.freeze([
107+
steps.pickVariant,
108+
steps.getUserConfigurationStep,
109+
steps.configureProductStep,
110+
steps.getCountryStep,
111+
steps.downloadOS,
112+
steps.printOSInfo,
113+
steps.registerDeviceStep,
114+
steps.getESIMProfilesStep,
115+
steps.createConfigBlobStep,
116+
steps.flashOSAndConfigStep,
117+
steps.setupCompletedStep
118+
])
119+
});
120+
121+
122+
/** @type {Workflow} */
123+
const android14 = Object.freeze({
124+
name: 'Android 14 (beta)',
125+
value: 'android14',
126+
osInfo: {
127+
distribution: 'android',
128+
distributionVersion: '14',
129+
},
130+
overrideDefaults:{
131+
version: 'latest',
132+
variant: 'android'
133+
},
134+
variants: [
135+
{ name: 'Android UI', value: 'android' },
136+
],
137+
selectionWarning: `Heads-up: this setup won’t provision the eSIM or connect to the Particle Cloud.${os.EOL}` +
138+
`If you need to provision the SIM, set up Ubuntu 20.04 first. ${os.EOL}`,
139+
steps: Object.freeze([
140+
steps.pickVariant,
141+
steps.configureProductStep,
142+
steps.downloadOS,
143+
steps.printOSInfo,
144+
steps.flashOSAndConfigStep,
145+
steps.setupCompletedStep
146+
]),
147+
});
148+
149+
/**
150+
*
151+
* @param {Workflow} workflow - workflow to run
152+
* @param {Context} context - information required to every step to run
153+
* @return {Promise<void>}
154+
*/
155+
async function run(workflow, context) {
156+
let currentContext = context;
157+
currentContext.log.info(`[${new Date().toISOString()}] Starting workflow ${workflow.name}`);
158+
for (const [index, step] of workflow.steps.entries()) {
159+
try {
160+
currentContext.log.info(`[${new Date().toISOString()}] Step ${step.name} started`);
161+
const result = await step(currentContext, index + 1);
162+
currentContext = { ...currentContext, ...(result ?? {}) };
163+
} catch (error) {
164+
currentContext.log.error(`[${new Date().toISOString()}] Error occurred during step: ${step?.name}: ${error.message} `);
165+
throw error;
166+
} finally {
167+
currentContext.log.info(`[${new Date().toISOString()}] Step ${step?.name} completed`);
168+
}
169+
}
170+
currentContext.log.info(`[${new Date().toISOString()}] Finished workflow ${workflow.name}`);
171+
return currentContext;
172+
}
173+
174+
module.exports = {
175+
workflows: {
176+
ubuntu20,
177+
ubuntu24,
178+
android14,
179+
},
180+
workflowRun: run
181+
};

0 commit comments

Comments
 (0)