@synergenius/flowweaver-pack-github-actions 0.1.1 → 0.1.3
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/README.md +62 -0
- package/dist/target.d.ts +8 -0
- package/dist/target.js +91 -2
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @synergenius/flowweaver-pack-github-actions
|
|
2
|
+
|
|
3
|
+
GitHub Actions CI/CD export target for [Flow Weaver](https://github.com/synergenius-fw/flow-weaver).
|
|
4
|
+
|
|
5
|
+
Generates native `.github/workflows/<name>.yml` files from Flow Weaver CI/CD workflows. No runtime dependency — outputs pure GitHub Actions YAML.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @synergenius/flowweaver-pack-github-actions
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This package is a **marketplace pack** — once installed, Flow Weaver automatically discovers it via `createTargetRegistry()`.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### CLI
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Export a CI/CD workflow as GitHub Actions YAML
|
|
21
|
+
npx flow-weaver export my-pipeline.ts --target github-actions
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Programmatic
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { createTargetRegistry } from '@synergenius/flow-weaver/deployment';
|
|
28
|
+
|
|
29
|
+
const registry = await createTargetRegistry(process.cwd());
|
|
30
|
+
const gha = registry.get('github-actions');
|
|
31
|
+
|
|
32
|
+
const artifacts = await gha.generate({
|
|
33
|
+
sourceFile: 'my-pipeline.ts',
|
|
34
|
+
workflowName: 'myPipeline',
|
|
35
|
+
displayName: 'my-pipeline',
|
|
36
|
+
outputDir: './dist/github-actions',
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## What it generates
|
|
41
|
+
|
|
42
|
+
- `.github/workflows/<name>.yml` — Native GitHub Actions workflow
|
|
43
|
+
- `SECRETS_SETUP.md` — Documentation for required secrets
|
|
44
|
+
|
|
45
|
+
### Mapping
|
|
46
|
+
|
|
47
|
+
| Flow Weaver | GitHub Actions |
|
|
48
|
+
|-------------|---------------|
|
|
49
|
+
| `[job: "name"]` annotation | Job in `jobs:` |
|
|
50
|
+
| `@path` dependencies | `needs:` |
|
|
51
|
+
| `@secret NAME` | `${{ secrets.NAME }}` |
|
|
52
|
+
| `@cache` | `actions/cache@v4` |
|
|
53
|
+
| `@artifact` | `actions/upload-artifact@v4` / `actions/download-artifact@v4` |
|
|
54
|
+
| `@trigger push` | `on: push` |
|
|
55
|
+
|
|
56
|
+
## Requirements
|
|
57
|
+
|
|
58
|
+
- `@synergenius/flow-weaver` >= 0.14.0
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
See [LICENSE](./LICENSE).
|
package/dist/target.d.ts
CHANGED
|
@@ -44,6 +44,14 @@ export declare class GitHubActionsTarget extends BaseCICDTarget {
|
|
|
44
44
|
private renderWorkflowYAML;
|
|
45
45
|
private renderTriggers;
|
|
46
46
|
private renderJob;
|
|
47
|
+
/**
|
|
48
|
+
* Parse a timeout string like "30m", "1h", "1h30m" into minutes.
|
|
49
|
+
*/
|
|
50
|
+
private parseTimeoutMinutes;
|
|
51
|
+
/**
|
|
52
|
+
* Translate GitLab-style CI variable conditions to GitHub Actions expressions.
|
|
53
|
+
*/
|
|
54
|
+
private translateCondition;
|
|
47
55
|
private renderStep;
|
|
48
56
|
private renderCacheStep;
|
|
49
57
|
/**
|
package/dist/target.js
CHANGED
|
@@ -182,12 +182,37 @@ export class GitHubActionsTarget extends BaseCICDTarget {
|
|
|
182
182
|
}
|
|
183
183
|
renderJob(job, ast) {
|
|
184
184
|
const jobObj = {};
|
|
185
|
-
// runs-on
|
|
186
|
-
|
|
185
|
+
// runs-on (tags override: self-hosted + tag labels)
|
|
186
|
+
if (job.tags && job.tags.length > 0) {
|
|
187
|
+
jobObj['runs-on'] = ['self-hosted', ...job.tags];
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
jobObj['runs-on'] = job.runner || 'ubuntu-latest';
|
|
191
|
+
}
|
|
187
192
|
// needs
|
|
188
193
|
if (job.needs.length > 0) {
|
|
189
194
|
jobObj.needs = job.needs;
|
|
190
195
|
}
|
|
196
|
+
// continue-on-error (from @job allow_failure)
|
|
197
|
+
if (job.allowFailure) {
|
|
198
|
+
jobObj['continue-on-error'] = true;
|
|
199
|
+
}
|
|
200
|
+
// timeout-minutes (from @job timeout, parse "30m" → 30, "1h" → 60)
|
|
201
|
+
if (job.timeout) {
|
|
202
|
+
jobObj['timeout-minutes'] = this.parseTimeoutMinutes(job.timeout);
|
|
203
|
+
}
|
|
204
|
+
// if: conditional (from @job rules)
|
|
205
|
+
if (job.rules && job.rules.length > 0) {
|
|
206
|
+
// Use the first rule's `if` condition, translate GitLab-style vars to GitHub context
|
|
207
|
+
const condition = job.rules[0].if;
|
|
208
|
+
if (condition) {
|
|
209
|
+
jobObj.if = this.translateCondition(condition);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// env (from @job variables or @variables)
|
|
213
|
+
if (job.variables && Object.keys(job.variables).length > 0) {
|
|
214
|
+
jobObj.env = { ...job.variables };
|
|
215
|
+
}
|
|
191
216
|
// environment
|
|
192
217
|
if (job.environment) {
|
|
193
218
|
const envConfig = ast.options?.cicd?.environments?.find((e) => e.name === job.environment);
|
|
@@ -246,6 +271,13 @@ export class GitHubActionsTarget extends BaseCICDTarget {
|
|
|
246
271
|
if (job.cache) {
|
|
247
272
|
steps.push(this.renderCacheStep(job.cache));
|
|
248
273
|
}
|
|
274
|
+
// before_script as a setup step
|
|
275
|
+
if (job.beforeScript && job.beforeScript.length > 0) {
|
|
276
|
+
steps.push({
|
|
277
|
+
name: 'Setup',
|
|
278
|
+
run: job.beforeScript.join('\n'),
|
|
279
|
+
});
|
|
280
|
+
}
|
|
249
281
|
// Node steps
|
|
250
282
|
for (const step of job.steps) {
|
|
251
283
|
steps.push(this.renderStep(step));
|
|
@@ -266,9 +298,66 @@ export class GitHubActionsTarget extends BaseCICDTarget {
|
|
|
266
298
|
steps.push(uploadStep);
|
|
267
299
|
}
|
|
268
300
|
}
|
|
301
|
+
// reports: junit → test-reporter, coverage → codecov
|
|
302
|
+
if (job.reports && job.reports.length > 0) {
|
|
303
|
+
for (const report of job.reports) {
|
|
304
|
+
if (report.type === 'junit') {
|
|
305
|
+
steps.push({
|
|
306
|
+
name: 'Test Report',
|
|
307
|
+
uses: 'dorny/test-reporter@v1',
|
|
308
|
+
if: 'always()',
|
|
309
|
+
with: {
|
|
310
|
+
name: 'Test Results',
|
|
311
|
+
path: report.path,
|
|
312
|
+
reporter: 'java-junit',
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
else if (report.type === 'cobertura' || report.type === 'coverage') {
|
|
317
|
+
steps.push({
|
|
318
|
+
name: 'Upload Coverage',
|
|
319
|
+
uses: 'codecov/codecov-action@v4',
|
|
320
|
+
with: { files: report.path },
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
steps.push({
|
|
325
|
+
name: `Upload ${report.type} report`,
|
|
326
|
+
uses: 'actions/upload-artifact@v4',
|
|
327
|
+
with: {
|
|
328
|
+
name: `${report.type}-report`,
|
|
329
|
+
path: report.path,
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
269
335
|
jobObj.steps = steps;
|
|
270
336
|
return jobObj;
|
|
271
337
|
}
|
|
338
|
+
/**
|
|
339
|
+
* Parse a timeout string like "30m", "1h", "1h30m" into minutes.
|
|
340
|
+
*/
|
|
341
|
+
parseTimeoutMinutes(timeout) {
|
|
342
|
+
let minutes = 0;
|
|
343
|
+
const hourMatch = timeout.match(/(\d+)h/);
|
|
344
|
+
const minMatch = timeout.match(/(\d+)m/);
|
|
345
|
+
if (hourMatch)
|
|
346
|
+
minutes += parseInt(hourMatch[1], 10) * 60;
|
|
347
|
+
if (minMatch)
|
|
348
|
+
minutes += parseInt(minMatch[1], 10);
|
|
349
|
+
return minutes || 60; // default 60 if unparseable
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Translate GitLab-style CI variable conditions to GitHub Actions expressions.
|
|
353
|
+
*/
|
|
354
|
+
translateCondition(condition) {
|
|
355
|
+
return condition
|
|
356
|
+
.replace(/\$CI_COMMIT_BRANCH/g, "github.ref_name")
|
|
357
|
+
.replace(/\$CI_COMMIT_TAG/g, "startsWith(github.ref, 'refs/tags/')")
|
|
358
|
+
.replace(/\$CI_PIPELINE_SOURCE/g, "github.event_name")
|
|
359
|
+
.replace(/==/g, '==');
|
|
360
|
+
}
|
|
272
361
|
renderStep(step) {
|
|
273
362
|
const mapping = this.resolveActionMapping(step, 'github-actions');
|
|
274
363
|
if (mapping?.githubAction) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synergenius/flowweaver-pack-github-actions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "GitHub Actions CI/CD export target for Flow Weaver",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"flowweaver-marketplace-pack",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"typescript": "^5.0.0",
|
|
39
|
-
"@synergenius/flow-weaver": "^0.
|
|
39
|
+
"@synergenius/flow-weaver": "^0.17.3",
|
|
40
40
|
"@types/node": "^20.0.0"
|
|
41
41
|
},
|
|
42
42
|
"license": "SEE LICENSE IN LICENSE",
|