Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EDT-1155] Add package for actions/actionhelpers #354

Merged
merged 20 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
* @brapoprod @abdelhalimkhouas @alexandraFlavia9 @pietervp @pkgacek @srares76
/packages/actions/ @Matthiee

9 changes: 9 additions & 0 deletions .github/workflows/pr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,12 @@ jobs:
with:
inlineScript: |
az storage blob upload-batch -d sdk -s packages/sdk/upload/ --connection-string "${{ secrets.AZURE_CDN_STUDIO_DEV_CONNECTION_STRING }}" --overwrite true
- name: prepare for actions upload
run: |
node cicd.js actions node scripts/prepare-release.mjs
- name: Copy to Azure Blob Storage (Actions)
uses: azure/CLI@v1
with:
inlineScript: |
az storage blob upload-batch -d sdk -s packages/actions/cdn/ --connection-string "${{ secrets.AZURE_CDN_STUDIO_DEV_CONNECTION_STRING }}" --overwrite true

13 changes: 12 additions & 1 deletion .github/workflows/publish-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,19 @@ jobs:
cp -R packages/sdk/_bundles/* ${path%"/merge"}
mkdir -p ${versionpath%"/merge"}
cp -R packages/sdk/_bundles/* ${versionpath%"/merge"}
- name: Copy to Azure Blob Storage
- name: Copy to Azure Blob Storage (SDK)
uses: azure/CLI@v1
with:
inlineScript: |
az storage blob upload-batch -d sdk -s packages/sdk/upload/ --connection-string "${{ secrets.AZURE_CDN_STUDIO_DEV_CONNECTION_STRING }}" --overwrite true
- name: prepare for actions upload
run: |
node cicd.js actions yarn && node scripts/prepare-release.mjs
working-directory: packages/actions
- name: Copy to Azure Blob Storage (Actions)
uses: azure/CLI@v1
with:
inlineScript: |
az storage blob upload-batch -d sdk -s packages/actions/cdn/ --connection-string "${{ secrets.AZURE_CDN_STUDIO_DEV_CONNECTION_STRING }}" --overwrite true


brapoprod marked this conversation as resolved.
Show resolved Hide resolved
10 changes: 10 additions & 0 deletions .github/workflows/publish-release-npm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,13 @@ jobs:
with:
inlineScript: |
az storage blob upload-batch -d sdk -s packages/sdk/upload/ --connection-string "${{ secrets.AZURE_CDN_STUDIO_PRD_CONNECTION_STRING }}" --overwrite true
- name: prepare for actions upload
run: |
node cicd.js actions yarn && node scripts/prepare-release.mjs
working-directory: packages/actions
- name: Copy to Azure Blob Storage (Actions)
uses: azure/CLI@v1
with:
inlineScript: |
az storage blob upload-batch -d sdk -s packages/actions/cdn/ --connection-string "${{ secrets.AZURE_CDN_STUDIO_PRD_CONNECTION_STRING }}" --overwrite true

brapoprod marked this conversation as resolved.
Show resolved Hide resolved
106 changes: 41 additions & 65 deletions cicd.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,55 @@
/**
* cicd.js
*
* This script is used to execute commands in a specific directory using yarn.
*
* Examples:
*
* 1. To clean the project in the sdk directory:
* node cicd.js sdk yarn clean
*
* 2. To build the project in the actions directory:
* node cicd.js actions yarn build
*
* 3. To build the project for development in the connectors directory:
* node cicd.js connectors yarn build:dev
*/
// Import required modules
const fs = require('fs');
const { spawn } = require('child_process');
const process = require('process');
const path = require('path');
const { execSync, spawnSync } = require('child_process');

function executeCommandInDirectory(directory, command, callback) {
// Check if directory starts with './packages/' or 'packages/', if not prepend it
if (!directory.startsWith('./packages/') && !directory.startsWith('packages/')) {
directory = path.join('./packages/', directory);
}

// Check if the directory exists
if (!fs.existsSync(directory)) {
return callback(new Error('Directory does not exist'));
}

// Get the current working directory
const originalDirectory = process.cwd();
// Get arguments from command line
const args = process.argv.slice(2);

try {
// Change to the target directory
process.chdir(directory);
// Check if arguments are provided
if (args.length < 2) {
console.error("Invalid arguments. Please provide two arguments: a comma-separated list of subfolders and a command to execute.");
console.error("Example: node cicd.js sdk,actions yarn build");
process.exit(1);
}

// Split command into base command and arguments
const [baseCommand, ...commandArgs] = command.split(' ');
// Split the first argument into an array of subfolders
const subfolders = args[0].split(',');

// Execute the command
const child = spawn(baseCommand, commandArgs, { stdio: 'inherit' });
// The command to execute
const command = args[1];

child.on('exit', (code) => {
// Change back to the original directory
process.chdir(originalDirectory);
// arguments to pass to the command
const commandArgs = args.slice(2);

if (code !== 0) {
return callback(new Error(`Command exited with code ${code}`));
}
// Iterate over subfolders
for (let subfolder of subfolders) {
// Construct the full path to the subfolder
const folderPath = path.join(__dirname, 'packages', subfolder.trim());

callback(null);
});
} catch (err) {
// If an error occurred while changing directories or executing the command,
// change back to the original directory and pass the error to the callback
process.chdir(originalDirectory);
callback(err);
// Check if the subfolder exists
if (!fs.existsSync(folderPath)) {
console.error(`The folder ${folderPath} does not exist.`);
process.exit(1);
}
}

// Get arguments from command line
const args = process.argv.slice(2); // first two args are "node" and script path
if (args.length < 2) {
console.error('Please provide a directory and a command');
process.exit(1);
}
console.log(`Executing command '${command}' in folder ${folderPath}`);

const [directory, ...commandParts] = args;
const command = commandParts.join(' ');
try {
// Execute the command synchronously
const output = spawnSync(command, commandArgs, {
cwd: folderPath,
stdio: 'inherit' // Show command output in console in real-time
});

// Usage
executeCommandInDirectory(directory, command, (err) => {
if (err) {
console.error(err);
if (output.status != 0){
console.error(`Command execution failed in folder ${folderPath}`);
process.exit(1);
}
} catch (error) {
// If the command fails, stop the entire script execution
console.error(`Command execution failed in folder ${folderPath}`);
console.error(`Error: ${error.message}`);
process.exit(1);
}
});
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"name": "studio-sdk-monorepo",
"description": "The umbrella project of grafx studio sdk",
"scripts": {
"install": "node cicd.js sdk yarn install",
"install": "node cicd.js sdk,actions yarn install",
"clean": "node cicd.js sdk yarn clean",
"build": "node cicd.js sdk yarn build",
"build": "node cicd.js sdk,actions yarn build",
"build:dev": "node cicd.js sdk yarn build:dev",
"lint": "node cicd.js sdk yarn lint",
"testw": "node cicd.js sdk yarn testw",
Expand Down
2 changes: 2 additions & 0 deletions packages/actions/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
out/
cdn/
30 changes: 30 additions & 0 deletions packages/actions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Actions package

Build output of this package will be copied to our CDN using following logic:

* https://.../actions/{apiVersion}/actions.d.ts
* `apiVersion` is a property defined in the `package.json` file of this package
* https://.../actions/{sdkVersion}/actionsHelpers.js
* `sdkVersion` is the official sdk version as defined in the `package.json` file in the root of this repository
* https://.../actions/{engineVersion}/actionsHelpers.d.ts
* `engineVersion` is the compatible engine version at build time. This version is stored in the packages/sdk/studio-engine.json file

## Actions.d.ts

This is the main output file of the `actions` package. It contains all the types and interfaces that are used by the `actions` feature
in GraFx Studio.

The contents of this file are copied to the `out/` directory on build.

## ActionsHelpers.ts

This file contains helper functions that are used by the `actions` feature in GraFx Studio.

The `.ts` file is compiled to both a `.js` and `.d.ts` file. The javascript file is used during action execution.
The type definitions can be used to provide autocomplete and type checking in GraFx Studio's action editor.

## Compressing for GPT format (Experimental)

To optimize the size of the `actions.d.ts` file when consuming it in GraFx Genie, it is compressed using the `scripts/compress.mjs` file. This file simply generates a json representation
of the AST of both the `actions.d.ts` and `actionsHelpers.ts` files.

16 changes: 16 additions & 0 deletions packages/actions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "actions",
"version": "0.153.0",
"apiVersion": "1.0",
"license": "MIT",
"scripts": {
"build": "yarn tsc && yarn tsc -p tsconfig.types.json && cp training.json out/training.json && cp types/Actions.d.ts out/Actions.d.ts && node scripts/actionhelpers-monaco.mjs && node scripts/compress.mjs"
},
"devDependencies": {
"dotenv": "^16.3.1",
"find-root": "^1.1.0",
"fs-extra": "^11.1.1",
"terser": "^5.19.4",
"typescript": "^5.2.2"
}
}
101 changes: 101 additions & 0 deletions packages/actions/scripts/actionhelpers-monaco.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import ts from "typescript";
import fs from "fs";

parseFile("./out/ActionHelpers.d.ts");

function visit(root, node, output) {
if (node == null)
return;


if (ts.isFunctionDeclaration(node)) {

const functionInfo = {
name: node.name.escapedText,
parameters: node.parameters.map(p => ({
name: p.name.escapedText,
type: getType(root, p.type)
})),
returnType: getType(root, node.type),
};

const commentRanges = ts.getLeadingCommentRanges(
root.getFullText(),
node.getFullStart());
if (commentRanges?.length) {
const commentStrings =
commentRanges.map(r => root.getFullText().slice(r.pos, r.end));

functionInfo.description = commentStrings;
}

output.functions.push(functionInfo);
}

ts.forEachChild(node, (child) => visit(root, child, output));
}

function getType(root, type) {
if (type == null)
return null;

if (typeof type == "string")
return type;

return type.getText(root);
}

function parseFile(fileName) {
const program = ts.createProgram([fileName], {
allowJs: true
});
const sourceFile = program.getSourceFile(fileName);

const output = {
functions: []
};

visit(sourceFile, sourceFile, output);

var template = `

declare module 'grafx-studio-actions-helper' {
global {
<<GLOBALS>>
}
}
`;

const exports = output.functions.map(f => {
const comments = f.description.map(str => str.split('\n')).flat().map(d => `
${d.trim()}`).join("");
return `
${comments}
function ${f.name}(${f.parameters.map(p => `${p.name}: ${p.type}`).join(", ")}): ${f.returnType};`;
});

template = template.replace("<<GLOBALS>>", exports.join(""));

// Parse the source file
const fileToFormat = ts.createSourceFile(
'test.ts',
template,
ts.ScriptTarget.Latest,
true,
ts.ScriptKind.TS
);

// Create a printer
const printer = ts.createPrinter({
newLine: ts.NewLineKind.LineFeed,
removeComments: false,

});

// format ts
template = printer.printFile(fileToFormat);
const outFileName = fileName.replace(".d.ts", ".monaco.d.ts");

fs.writeFileSync(outFileName, template);

}
Loading