diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index 78ed25ddd..4ac10fe9d 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -28,6 +28,13 @@ jobs: path: defang ref: main + - name: Checkout DefangLabs/samples + uses: actions/checkout@v3 + with: + repository: DefangLabs/samples + path: samples + ref: main + - name: Set up Go uses: actions/setup-go@v2 with: diff --git a/docs/tutorials/generate-new-code-using-ai.mdx b/docs/tutorials/generate-new-code-using-ai.mdx index b840a9256..ecc9fddf6 100644 --- a/docs/tutorials/generate-new-code-using-ai.mdx +++ b/docs/tutorials/generate-new-code-using-ai.mdx @@ -11,7 +11,7 @@ Defang supports generating new project outlines using integration with an AI mod In this tutorial we'll use the following prompt: -A basic service with 2 REST endpoints. The default endpoint will be for health check and should return a JSON object like this: { "status": "OK" }. The /echo endpoint will echo back all request parameters in the response. +A basic service with 2 REST endpoints. The default endpoint will be for health check and should return a JSON object like this: `{ "status": "OK" }`. The /echo endpoint will echo back all request parameters in the response. ## Step 1 - Use the CLI generate command ```text diff --git a/package-lock.json b/package-lock.json index ca0456ff0..032255b6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,8 @@ "prism-react-renderer": "^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-markdown": "^9.0.1" + "react-markdown": "^9.0.1", + "yaml": "^2.4.5" }, "devDependencies": { "@docusaurus/module-type-aliases": "3.0.0", @@ -5615,6 +5616,14 @@ "node": ">=10" } }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/cross-fetch": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", @@ -5911,6 +5920,14 @@ "postcss": "^8.2.15" } }, + "node_modules/cssnano/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/csso": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", @@ -7278,6 +7295,14 @@ "node": ">=6" } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -16395,11 +16420,14 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "bin": { + "yaml": "bin.mjs" + }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/yocto-queue": { diff --git a/package.json b/package.json index 9244d8c4b..4541adeee 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "prism-react-renderer": "^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-markdown": "^9.0.1" + "react-markdown": "^9.0.1", + "yaml": "^2.4.5" }, "devDependencies": { "@docusaurus/module-type-aliases": "3.0.0", diff --git a/scripts/prep-samples.js b/scripts/prep-samples.js index 025324460..291cac144 100644 --- a/scripts/prep-samples.js +++ b/scripts/prep-samples.js @@ -1,5 +1,6 @@ const fs = require('fs'); const path = require('path'); +const YAML = require('yaml'); const samplesDir = path.join(__dirname, '..', 'samples', 'samples'); @@ -29,7 +30,36 @@ directories.forEach((sample) => { const tags = readme.match(/Tags: (.*)/)[1].split(',').map(tag => tag.trim()); const languages = readme.match(/Languages: (.*)/)[1].split(',').map(language => language.trim()); - jsonArray.push({ + let configs = []; + try { + composeFile = fs.readFileSync(path.join(samplesDir, sample, 'compose.yaml'), 'utf8'); + compose = YAML.parse(composeFile); + + for (var name in compose.services) { + service = compose.services[name] + if (Array.isArray(service.environment)) { + service.environment.forEach(env => { + if (!env.includes("=")) { + configs.push(env); + } + }); + } else { + for (var name in service.environment) { + value = service.environment[name]; + if (value === null || value === undefined || value === "") { + configs.push(name); + } + } + } + } + } catch (error) { + // Ignore if the sample doesn't have a compose file + if (error.code != 'ENOENT') { + console.log(`failed to parese compose for configs for sample`, sample, error); + } + } + + const sampleSummary = { name: directoryName, category: languages?.[0], readme, @@ -38,7 +68,12 @@ directories.forEach((sample) => { shortDescription, tags, languages, - }); + }; + if (configs.length > 0) { + sampleSummary.configs = configs; + } + jsonArray.push(sampleSummary); + console.log(`@@ Added ${sample}`); });