Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
149 lines
4.5 KiB
JavaScript
149 lines
4.5 KiB
JavaScript
#!/usr/bin/env node
|
|
/* eslint-disable no-console */
|
|
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
function usage() {
|
|
console.error(`
|
|
Scaffold a workflow-harness fixture folder.
|
|
|
|
Usage:
|
|
node tools/workflow-harness/scaffold.cjs --name <fixtureName> --event <EVENT_NAME> --schema <payloadSchemaRef>
|
|
|
|
Example:
|
|
node tools/workflow-harness/scaffold.cjs --name ticket-created-demo --event TICKET_CREATED --schema payload.TicketCreated.v1
|
|
`);
|
|
}
|
|
|
|
function parseArgs(argv) {
|
|
const args = {};
|
|
let i = 0;
|
|
while (i < argv.length) {
|
|
const t = argv[i];
|
|
if (t === '--help' || t === '-h') {
|
|
args.help = true;
|
|
i += 1;
|
|
continue;
|
|
}
|
|
if (t.startsWith('--')) {
|
|
const key = t.slice(2);
|
|
const value = argv[i + 1];
|
|
if (!value || value.startsWith('--')) throw new Error(`Missing value for --${key}`);
|
|
args[key] = value;
|
|
i += 2;
|
|
continue;
|
|
}
|
|
i += 1;
|
|
}
|
|
return args;
|
|
}
|
|
|
|
function ensureDir(dir) {
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
}
|
|
|
|
function writeIfMissing(filePath, contents) {
|
|
if (fs.existsSync(filePath)) {
|
|
throw new Error(`Refusing to overwrite existing file: ${filePath}`);
|
|
}
|
|
fs.writeFileSync(filePath, contents, 'utf8');
|
|
}
|
|
|
|
async function main() {
|
|
const args = parseArgs(process.argv.slice(2));
|
|
if (args.help) {
|
|
usage();
|
|
process.exit(0);
|
|
}
|
|
|
|
const name = args.name;
|
|
const eventName = args.event;
|
|
const schemaRef = args.schema;
|
|
if (!name) throw new Error('Missing --name');
|
|
if (!eventName) throw new Error('Missing --event');
|
|
if (!schemaRef) throw new Error('Missing --schema');
|
|
|
|
const root = path.resolve(process.cwd(), 'ee/test-data/workflow-harness', name);
|
|
ensureDir(root);
|
|
|
|
const workflowKey = `fixture.${name}`;
|
|
const bundlePath = path.join(root, 'bundle.json');
|
|
const testPath = path.join(root, 'test.cjs');
|
|
|
|
const bundle = {
|
|
format: 'alga-psa.workflow-bundle',
|
|
formatVersion: 1,
|
|
exportedAt: new Date().toISOString(),
|
|
workflows: [
|
|
{
|
|
key: workflowKey,
|
|
metadata: {
|
|
name: `Fixture: ${name}`,
|
|
description: `Scaffolded fixture for ${eventName}.`,
|
|
payloadSchemaRef: schemaRef,
|
|
payloadSchemaMode: 'pinned',
|
|
pinnedPayloadSchemaRef: schemaRef,
|
|
trigger: { type: 'event', eventName },
|
|
isSystem: false,
|
|
isVisible: true,
|
|
isPaused: false,
|
|
concurrencyLimit: null,
|
|
autoPauseOnFailure: false,
|
|
failureRateThreshold: null,
|
|
failureRateMinRuns: null,
|
|
retentionPolicyOverride: null
|
|
},
|
|
dependencies: {
|
|
actions: [],
|
|
nodeTypes: ['state.set'],
|
|
schemaRefs: [schemaRef]
|
|
},
|
|
draft: {
|
|
draftVersion: 1,
|
|
definition: {
|
|
id: '00000000-0000-0000-0000-00000000f001',
|
|
version: 1,
|
|
name: `Fixture: ${name}`,
|
|
description: `Scaffolded fixture for ${eventName}.`,
|
|
payloadSchemaRef: schemaRef,
|
|
trigger: { type: 'event', eventName },
|
|
steps: [{ id: 'ready', type: 'state.set', config: { state: 'READY' } }, { id: 'done', type: 'control.return' }]
|
|
}
|
|
},
|
|
publishedVersions: [
|
|
{
|
|
version: 1,
|
|
definition: {
|
|
id: '00000000-0000-0000-0000-00000000f001',
|
|
version: 1,
|
|
name: `Fixture: ${name}`,
|
|
description: `Scaffolded fixture for ${eventName}.`,
|
|
payloadSchemaRef: schemaRef,
|
|
trigger: { type: 'event', eventName },
|
|
steps: [{ id: 'ready', type: 'state.set', config: { state: 'READY' } }, { id: 'done', type: 'control.return' }]
|
|
},
|
|
payloadSchemaJson: null
|
|
}
|
|
]
|
|
}
|
|
]
|
|
};
|
|
|
|
writeIfMissing(bundlePath, `${JSON.stringify(bundle, null, 2)}\n`);
|
|
|
|
writeIfMissing(
|
|
testPath,
|
|
`const { randomUUID } = require('node:crypto');\n\nmodule.exports = async function run(ctx) {\n const correlationKey = randomUUID();\n\n await ctx.http.request('/api/workflow/events', {\n method: 'POST',\n json: {\n eventName: ${JSON.stringify(eventName)},\n correlationKey,\n payloadSchemaRef: ${JSON.stringify(schemaRef)},\n payload: {}\n }\n });\n\n const runRow = await ctx.waitForRun({ startedAfter: ctx.triggerStartedAt });\n ctx.expect.equal(runRow.status, 'SUCCEEDED', 'run status');\n};\n`
|
|
);
|
|
|
|
console.log(`Scaffolded: ${root}`);
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error(err?.stack ?? err?.message ?? String(err));
|
|
usage();
|
|
process.exit(1);
|
|
});
|
|
|