From 273868cfe40748b699a7aa4fdebd16da0ba51220 Mon Sep 17 00:00:00 2001 From: Elanthenral Elangovan Date: Fri, 23 Jan 2026 12:12:40 -0800 Subject: [PATCH] ACNA-3996: Refactor shell to JS --- .github/scripts/README.md | 44 ++++ .github/scripts/smoke-test.js | 161 +++++++++++ .github/scripts/test-harness.js | 249 ++++++++++++++++++ .github/scripts/utils.js | 216 +++++++++++++++ .github/workflows/app-smoke-test-js.yml | 110 ++++++++ .../workflows/asset-compute-smoke-test-js.yml | 61 +++++ .gitignore | 6 + 7 files changed, 847 insertions(+) create mode 100644 .github/scripts/README.md create mode 100755 .github/scripts/smoke-test.js create mode 100755 .github/scripts/test-harness.js create mode 100755 .github/scripts/utils.js create mode 100644 .github/workflows/app-smoke-test-js.yml create mode 100644 .github/workflows/asset-compute-smoke-test-js.yml diff --git a/.github/scripts/README.md b/.github/scripts/README.md new file mode 100644 index 0000000..10bca1c --- /dev/null +++ b/.github/scripts/README.md @@ -0,0 +1,44 @@ +# Workflow Scripts + +JavaScript scripts for GitHub Actions workflows, replacing inline shell code. + +## Main Script + +`smoke-test.js` - Unified CLI for all smoke tests + +```bash +# Usage +node smoke-test.js + +# Commands +create-app # Create and deploy app (no extensions) +create-app-extension # Create and deploy app (with extension) +pack # Package app to zip +install # Install app from zip +asset-compute # Run Asset Compute tests +``` + +## Files + +- `smoke-test.js` - Main CLI entry point +- `utils.js` - Shared utilities (runCommand, verifyOutput, etc.) +- `test-harness.js` - Local testing with mocks (no credentials needed) + +## Local Testing + +```bash +# Test with mocks (no credentials required) +node test-harness.js + +# Test with actual CLI (requires credentials) +export AIO_RUNTIME_AUTH="your-auth" +export AIO_RUNTIME_NAMESPACE="your-namespace" +node smoke-test.js create-app +``` + +## Workflows + +| Original | JavaScript Version | +|----------|-------------------| +| `app-smoke-test.yml` | `app-smoke-test-js.yml` | +| `asset-compute-smoke-test.yml` | `asset-compute-smoke-test-js.yml` | \ No newline at end of file diff --git a/.github/scripts/smoke-test.js b/.github/scripts/smoke-test.js new file mode 100755 index 0000000..1b91c06 --- /dev/null +++ b/.github/scripts/smoke-test.js @@ -0,0 +1,161 @@ +#!/usr/bin/env node + +/** + * Unified smoke test script for AIO workflows + * Replaces multiple individual scripts with a single CLI + */ + +const { createAndDeployApp, runCommand, verifyOutput } = require('./utils'); + +const commands = { + /** + * Create app with no extensions + */ + 'create-app': () => { + createAndDeployApp({ + installDeps: true, + cleanFirst: false, + initCommand: 'app:init . -y --no-login --standalone-app', + deployCommand: 'app:deploy', + verifyStrings: [ + 'Your deployed actions:', + 'api/v1/web/ffapp/generic', + '/api/v1/web/ffapp/publish-events', + '.adobeio-static.net/index.html', + 'Successful deployment' + ], + successMessage: 'App creation and deployment successful!' + }); + }, + + /** + * Create app with extension + */ + 'create-app-extension': () => { + createAndDeployApp({ + installDeps: false, + cleanFirst: true, + initCommand: 'app:init . -y --no-login --extension dx/excshell/1', + deployCommand: 'app:deploy --no-publish', + verifyStrings: [ + 'Your deployed actions:', + 'api/v1/web/dx-excshell-1/generic', + '.adobeio-static.net/index.html', + 'Successful deployment' + ], + successMessage: 'App with extension creation and deployment successful!' + }); + }, + + /** + * Pack app + */ + 'pack': () => { + const appDir = 'ffapp'; + const binPath = '../bin/run'; + + try { + console.log('=== Packing app ==='); + process.chdir(appDir); + runCommand(`${binPath} app:pack 2>&1 > consoleoutput.txt`); + verifyOutput('consoleoutput.txt', ['Packaging done.']); + console.log('\n✅ App packing successful!'); + process.exit(0); + } catch (error) { + console.error('\n❌ Script failed:', error.message); + process.exit(1); + } + }, + + /** + * Install app + */ + 'install': () => { + const appDir = 'ffapp'; + const binPath = '../bin/run'; + + try { + console.log('=== Installing app ==='); + process.chdir(appDir); + runCommand(`${binPath} app:install dist/app.zip --output install-folder 2>&1 > consoleoutput.txt`); + verifyOutput('consoleoutput.txt', ['Install done.']); + console.log('\n✅ App installation successful!'); + process.exit(0); + } catch (error) { + console.error('\n❌ Script failed:', error.message); + process.exit(1); + } + }, + + /** + * Asset Compute smoke test + */ + 'asset-compute': () => { + const outputFile = 'consoleoutput.txt'; + + try { + console.log('=== Step 1: Install dependencies ==='); + runCommand('npm i'); + + console.log('\n=== Step 2: Run Asset Compute tests ==='); + runCommand('./node_modules/mocha/bin/mocha test/index.test.js > consoleoutput.txt'); + + console.log('\n=== Step 3: Verify test results ==='); + verifyOutput(outputFile, [ + 'App initialization finished!', + '/test/asset-compute/worker', + 'All tests were successful.' + ]); + + console.log('\n✅ Asset Compute smoke test passed!'); + process.exit(0); + } catch (error) { + console.error('\n❌ Script failed:', error.message); + process.exit(1); + } + } +}; + +/** + * Show usage information + */ +function showUsage() { + console.log(` +Usage: node smoke-test.js + +Commands: + create-app Create and deploy app with no extensions + create-app-extension Create and deploy app with extension + pack Pack the app into a zip + install Install app from zip + asset-compute Run Asset Compute smoke test + +Examples: + node smoke-test.js create-app + node smoke-test.js pack + node smoke-test.js asset-compute + `); + process.exit(1); +} + +/** + * Main entry point + */ +function main() { + const command = process.argv[2]; + + if (!command || !commands[command]) { + console.error(`Error: Unknown command "${command || ''}"\n`); + showUsage(); + } + + commands[command](); +} + +// Run the script +if (require.main === module) { + main(); +} + +module.exports = { commands, main }; + diff --git a/.github/scripts/test-harness.js b/.github/scripts/test-harness.js new file mode 100755 index 0000000..7a7e9a0 --- /dev/null +++ b/.github/scripts/test-harness.js @@ -0,0 +1,249 @@ +#!/usr/bin/env node + +/** + * Test harness for validating scripts locally + * This allows testing the scripts without needing GitHub Actions or Adobe secrets + */ + +const fs = require('fs'); +const path = require('path'); +const { verifyOutput } = require('./utils'); + +/** + * Create mock console output for testing verification logic + */ +function createMockOutputs() { + const mockDir = path.join(__dirname, 'test-mocks'); + + if (!fs.existsSync(mockDir)) { + fs.mkdirSync(mockDir, { recursive: true }); + } + + // Mock output for app initialization + const initOutput = ` +Creating project from template @adobe/generator-app-excshell +? Select components to include +✔ Actions: Deploy Runtime actions +✔ Web Assets: Deploy hosted static assets +? Which Adobe I/O App features do you want to enable for this project? +✔ Actions +✔ Events +✔ Web Assets + +App initialization finished! + +Next steps: + $ cd myapp + $ aio app run +`; + + // Mock output for deployment (standalone app) + const deployOutputStandalone = ` +Building actions... +✔ Built 2 action(s) for 'ffapp' + +Deploying actions... +✔ Deployed 2 action(s) for 'ffapp' + +Your deployed actions: + -> https://adobeioruntime.net/api/v1/web/ffapp/generic + -> https://adobeioruntime.net/api/v1/web/ffapp/publish-events + +Building web assets... +✔ Built web assets + +Deploying web assets... +✔ Deployed web assets to https://12345-namespace.adobeio-static.net/index.html + +Well done, your app is now online 🏄 +Successful deployment +`; + + // Mock output for deployment (with extension) + const deployOutputExtension = ` +Building actions... +✔ Built 2 action(s) for 'dx-excshell-1' + +Deploying actions... +✔ Deployed 2 action(s) for 'dx-excshell-1' + +Your deployed actions: + -> https://adobeioruntime.net/api/v1/web/dx-excshell-1/generic + +Building web assets... +✔ Built web assets + +Deploying web assets... +✔ Deployed web assets to https://12345-namespace.adobeio-static.net/index.html + +Well done, your app is now online 🏄 +Successful deployment +`; + + // Mock output for pack + const packOutput = ` +Packaging your app... +✔ Packaged app to dist/app.zip (size: 1.2 MB) +Packaging done. +`; + + // Mock output for install + const installOutput = ` +Installing app from dist/app.zip... +✔ Extracted app to install-folder +✔ Installed dependencies +Install done. +`; + + // Mock output for asset compute + const assetComputeOutput = ` +App initialization finished! + + Asset Compute Worker Tests +Running tests in /home/runner/work/asset-compute-integration-tests/test/asset-compute/worker + ✓ should process image correctly (1234ms) + ✓ should handle errors gracefully (567ms) + ✓ should validate input parameters (123ms) + + 3 passing (1926ms) + +All tests were successful. +`; + + // Write mock files + fs.writeFileSync(path.join(mockDir, 'init-output.txt'), initOutput); + fs.writeFileSync(path.join(mockDir, 'deploy-standalone.txt'), initOutput + deployOutputStandalone); + fs.writeFileSync(path.join(mockDir, 'deploy-extension.txt'), initOutput + deployOutputExtension); + fs.writeFileSync(path.join(mockDir, 'pack-output.txt'), packOutput); + fs.writeFileSync(path.join(mockDir, 'install-output.txt'), installOutput); + fs.writeFileSync(path.join(mockDir, 'asset-compute-output.txt'), assetComputeOutput); + + return mockDir; +} + +/** + * Test verification functions + */ +function testVerifications() { + console.log('=== Testing Verification Functions ===\n'); + + const mockDir = createMockOutputs(); + const tests = [ + { + name: 'App initialization', + file: path.join(mockDir, 'init-output.txt'), + expected: ['App initialization finished'] + }, + { + name: 'App deployment (standalone)', + file: path.join(mockDir, 'deploy-standalone.txt'), + expected: [ + 'Your deployed actions:', + 'api/v1/web/ffapp/generic', + '/api/v1/web/ffapp/publish-events', + '.adobeio-static.net/index.html', + 'Successful deployment' + ] + }, + { + name: 'App deployment (with extension)', + file: path.join(mockDir, 'deploy-extension.txt'), + expected: [ + 'Your deployed actions:', + 'api/v1/web/dx-excshell-1/generic', + '.adobeio-static.net/index.html', + 'Successful deployment' + ] + }, + { + name: 'App packing', + file: path.join(mockDir, 'pack-output.txt'), + expected: ['Packaging done.'] + }, + { + name: 'App installation', + file: path.join(mockDir, 'install-output.txt'), + expected: ['Install done.'] + }, + { + name: 'Asset Compute smoke test', + file: path.join(mockDir, 'asset-compute-output.txt'), + expected: [ + 'App initialization finished!', + '/test/asset-compute/worker', + 'All tests were successful.' + ] + } + ]; + + let passed = 0; + let failed = 0; + + for (const test of tests) { + try { + console.log(`Testing: ${test.name}`); + verifyOutput(test.file, test.expected); + console.log('✅ PASSED\n'); + passed++; + } catch (error) { + console.error(`❌ FAILED: ${error.message}\n`); + failed++; + } + } + + console.log('=== Test Summary ==='); + console.log(`Passed: ${passed}/${tests.length}`); + console.log(`Failed: ${failed}/${tests.length}`); + + return failed === 0; +} + +/** + * Test with missing strings (should fail) + */ +function testNegativeCases() { + console.log('\n=== Testing Negative Cases (Expected to Fail) ===\n'); + + const mockDir = path.join(__dirname, 'test-mocks'); + + try { + console.log('Testing: Missing expected string'); + verifyOutput(path.join(mockDir, 'init-output.txt'), ['This string does not exist']); + console.log('❌ UNEXPECTED: Test should have failed\n'); + return false; + } catch (error) { + console.log('✅ EXPECTED: Test failed as expected\n'); + return true; + } +} + +/** + * Main test runner + */ +function main() { + console.log('🧪 Running Test Harness\n'); + console.log('This tests the verification logic without needing actual CLI execution\n'); + + const positiveTestsPassed = testVerifications(); + const negativeTestsPassed = testNegativeCases(); + + if (positiveTestsPassed && negativeTestsPassed) { + console.log('\n✅ All tests passed!'); + console.log('\nNext steps:'); + console.log('1. Review the generated mock files in .github/scripts/test-mocks/'); + console.log('2. Try running scripts with --dry-run flag (when implemented)'); + console.log('3. Test with actual CLI once you have Adobe credentials'); + process.exit(0); + } else { + console.error('\n❌ Some tests failed'); + process.exit(1); + } +} + +// Run the tests +if (require.main === module) { + main(); +} + +module.exports = { createMockOutputs, testVerifications, testNegativeCases }; + diff --git a/.github/scripts/utils.js b/.github/scripts/utils.js new file mode 100755 index 0000000..3b9be74 --- /dev/null +++ b/.github/scripts/utils.js @@ -0,0 +1,216 @@ +#!/usr/bin/env node + +/** + * Utility functions for workflow scripts + */ + +const { execSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +/** + * Run a shell command and return the output + * @param {string} command - The command to run + * @param {object} options - Options for execSync + * @returns {string} - Command output + */ +function runCommand(command, options = {}) { + const defaultOptions = { + encoding: 'utf-8', + stdio: ['inherit', 'pipe', 'pipe'], + ...options + }; + + try { + console.log(`[RUN] ${command}`); + const output = execSync(command, defaultOptions); + return output; + } catch (error) { + console.error(`[ERROR] Command failed: ${command}`); + console.error(`Exit code: ${error.status}`); + console.error(`Output: ${error.stdout}`); + console.error(`Error: ${error.stderr}`); + throw error; + } +} + +/** + * Verify that expected strings exist in a file + * @param {string} filePath - Path to the file to check + * @param {string[]} expectedStrings - Array of strings that must exist in the file + * @throws {Error} If any expected string is not found + */ +function verifyOutput(filePath, expectedStrings) { + if (!fs.existsSync(filePath)) { + throw new Error(`Output file not found: ${filePath}`); + } + + const content = fs.readFileSync(filePath, 'utf-8'); + const missing = []; + + for (const expected of expectedStrings) { + if (!content.includes(expected)) { + missing.push(expected); + } + } + + if (missing.length > 0) { + console.error(`[VERIFICATION FAILED] Missing expected strings in ${filePath}:`); + missing.forEach(str => console.error(` - "${str}"`)); + throw new Error(`Verification failed: ${missing.length} expected string(s) not found`); + } + + console.log(`[VERIFICATION PASSED] All ${expectedStrings.length} expected strings found in ${filePath}`); +} + +/** + * Write environment variables to a .env file + * @param {string} filePath - Path to the .env file + * @param {object} vars - Object with key-value pairs + */ +function writeEnvFile(filePath, vars) { + const lines = Object.entries(vars).map(([key, value]) => `${key}=${value}`); + fs.writeFileSync(filePath, lines.join('\n') + '\n'); + console.log(`[ENV] Created ${filePath} with ${Object.keys(vars).length} variables`); +} + +/** + * Ensure a directory exists + * @param {string} dirPath - Path to the directory + */ +function ensureDir(dirPath) { + if (!fs.existsSync(dirPath)) { + fs.mkdirSync(dirPath, { recursive: true }); + console.log(`[MKDIR] Created directory: ${dirPath}`); + } +} + +/** + * Clean up a directory (remove and recreate) + * @param {string} dirPath - Path to the directory + */ +function cleanDir(dirPath) { + if (fs.existsSync(dirPath)) { + fs.rmSync(dirPath, { recursive: true, force: true }); + console.log(`[CLEAN] Removed directory: ${dirPath}`); + } + ensureDir(dirPath); +} + +/** + * Get runtime credentials from environment variables + * @returns {{auth: string, namespace: string} | null} - Credentials object or null if not found + */ +function getRuntimeCredentials() { + const auth = process.env.AIO_RUNTIME_AUTH || process.env.RUNTIME_AUTH; + const namespace = process.env.AIO_RUNTIME_NAMESPACE || process.env.RUNTIME_NAMESPACE; + + if (!auth || !namespace) { + return null; + } + + return { auth, namespace }; +} + +/** + * Setup runtime environment (.env file) + * @param {string} envPath - Path to .env file (default: '.env') + * @returns {boolean} - True if credentials were found and file was written + */ +function setupRuntimeEnv(envPath = '.env') { + const credentials = getRuntimeCredentials(); + + if (!credentials) { + console.warn('[WARN] Runtime credentials not found in environment'); + console.warn('[WARN] Set AIO_RUNTIME_AUTH and AIO_RUNTIME_NAMESPACE to test deployment'); + console.log('[INFO] Skipping deployment step'); + return false; + } + + writeEnvFile(envPath, { + AIO_RUNTIME_AUTH: credentials.auth, + AIO_RUNTIME_NAMESPACE: credentials.namespace + }); + + return true; +} + +/** + * Create and deploy an AIO app (generic function) + * @param {object} options - Configuration options + * @param {boolean} options.installDeps - Whether to run npm install first + * @param {boolean} options.cleanFirst - Whether to clean directory first (vs ensure) + * @param {string} options.initCommand - The app:init command arguments + * @param {string} options.deployCommand - The app:deploy command arguments + * @param {string[]} options.verifyStrings - Strings to verify in output + * @param {string} options.successMessage - Success message to display + */ +function createAndDeployApp(options) { + const { + installDeps = false, + cleanFirst = false, + initCommand, + deployCommand = 'app:deploy', + verifyStrings, + successMessage = 'App creation and deployment successful!' + } = options; + + const appDir = 'ffapp'; + const binPath = '../bin/run'; + let stepNum = 1; + + try { + // Optional: Install dependencies + if (installDeps) { + console.log(`=== Step ${stepNum++}: Install dependencies ===`); + runCommand('npm i @adobe/aio-cli-plugin-app-templates'); + runCommand('npm i'); + } + + // Setup app directory + console.log(`\n=== Step ${stepNum++}: ${cleanFirst ? 'Clean and create' : 'Create'} app directory ===`); + if (cleanFirst) { + cleanDir(appDir); + } else { + ensureDir(appDir); + } + process.chdir(appDir); + + // Initialize app + console.log(`\n=== Step ${stepNum++}: Initialize app ===`); + runCommand(`${binPath} ${initCommand} > consoleoutput.txt`); + verifyOutput('consoleoutput.txt', ['App initialization finished']); + + // Configure environment + console.log(`\n=== Step ${stepNum++}: Configure environment ===`); + if (!setupRuntimeEnv('.env')) { + process.exit(0); + } + + // Deploy app + console.log(`\n=== Step ${stepNum++}: Deploy app ===`); + runCommand(`${binPath} ${deployCommand} >> consoleoutput.txt`); + + // Verify deployment + verifyOutput('consoleoutput.txt', verifyStrings); + + console.log(`\n✅ ${successMessage}`); + process.exit(0); + + } catch (error) { + console.error('\n❌ Script failed:', error.message); + process.exit(1); + } +} + +module.exports = { + runCommand, + verifyOutput, + writeEnvFile, + ensureDir, + cleanDir, + getRuntimeCredentials, + setupRuntimeEnv, + createAndDeployApp +}; + diff --git a/.github/workflows/app-smoke-test-js.yml b/.github/workflows/app-smoke-test-js.yml new file mode 100644 index 0000000..3c13426 --- /dev/null +++ b/.github/workflows/app-smoke-test-js.yml @@ -0,0 +1,110 @@ +name: App Plugin smoke test (JavaScript version) + +on: + workflow_dispatch: + inputs: + branch-name: + description: 'Branch name to checkout' + required: false + default: 'master' + # Uncomment to run on schedule alongside the original workflow + # schedule: + # # run daily at midnight (15 minutes offset from original) + # - cron: '30 0 * * *' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + max-parallel: 1 + matrix: + node-version: [18.x, 20.x] + os: [ubuntu-latest] + + steps: + - name: Checkout e2e-tests repo (for scripts) + uses: actions/checkout@v3 + with: + path: e2e-tests + + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Setup CLI + uses: actions/checkout@v3 + with: + repository: adobe/aio-cli-plugin-app + ref: ${{ github.event.inputs.branch-name }} + path: aio-cli-plugin-app + + - name: Update package.json oclif.plugins + uses: jossef/action-set-json-field@v2.1 + with: + file: aio-cli-plugin-app/package.json + field: oclif.plugins + value: "[\"@adobe/aio-cli-plugin-app-templates\"]" + parse_json: true + + - name: Auth + uses: adobe/aio-apps-action@3.3.0 + with: + os: ${{ matrix.os }} + command: oauth_sts + CLIENTID: ${{ secrets.IMS_CLIENT_ID }} + CLIENTSECRET: ${{ secrets.IMS_CLIENT_SECRET }} + IMSORGID: ${{ secrets.IMS_ORG_ID }} + SCOPES: ${{ secrets.IMS_SCOPES }} + # we are using dummy values as they are not needed to generate oauth_s2s tokens + # see https://github.com/adobe/aio-lib-ims-oauth/issues/114 + TECHNICALACCOUNTID: dummy_id + TECHNICALACCOUNTEMAIL: dummy_email + + - id: create + name: Create app with no extensions + working-directory: aio-cli-plugin-app + run: node ../e2e-tests/.github/scripts/smoke-test.js create-app + env: + AIO_RUNTIME_AUTH: ${{ secrets.RUNTIME_AUTH }} + AIO_RUNTIME_NAMESPACE: ${{ secrets.RUNTIME_NAMESPACE }} + + - id: app_pack + name: Pack an app (uses previous created app) + working-directory: aio-cli-plugin-app + run: node ../e2e-tests/.github/scripts/smoke-test.js pack + + - id: app_install + name: Install an app (uses previous packed app) + working-directory: aio-cli-plugin-app + run: node ../e2e-tests/.github/scripts/smoke-test.js install + + - id: createext + name: Create app with extension + working-directory: aio-cli-plugin-app + run: node ../e2e-tests/.github/scripts/smoke-test.js create-app-extension + env: + AIO_RUNTIME_AUTH: ${{ secrets.RUNTIME_AUTH }} + AIO_RUNTIME_NAMESPACE: ${{ secrets.RUNTIME_NAMESPACE }} + + - id: output + name: Write the output to console for debugging + if: ${{ failure() }} + working-directory: aio-cli-plugin-app + run: | + if [ -d "ffapp" ]; then + echo "=== Console output from ffapp/consoleoutput.txt ===" + cat ffapp/consoleoutput.txt + else + echo "ffapp directory not found" + fi + + - id: slacknotification + name: Slack Notification + if: ${{ failure() }} + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + SLACK_TITLE: 'Node version (JavaScript workflow)' + SLACK_MESSAGE: ${{ matrix.node-version }} + SLACK_COLOR: ${{ job.status }} + diff --git a/.github/workflows/asset-compute-smoke-test-js.yml b/.github/workflows/asset-compute-smoke-test-js.yml new file mode 100644 index 0000000..e0cbc61 --- /dev/null +++ b/.github/workflows/asset-compute-smoke-test-js.yml @@ -0,0 +1,61 @@ +name: Asset Compute smoke test (JavaScript version) + +on: + workflow_dispatch: + # Uncomment to run on schedule alongside the original workflow + # schedule: + # # run daily at midnight (15 minutes offset from original) + # - cron: '30 0 * * *' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + max-parallel: 1 + matrix: + node-version: [18.x, 20.x] + os: [ubuntu-latest] + + steps: + - name: Checkout e2e-tests repo (for scripts) + uses: actions/checkout@v3 + with: + path: e2e-tests + + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Setup Asset Compute + uses: actions/checkout@master + with: + repository: adobe/asset-compute-integration-tests + path: asset-compute-tests + + - id: create-asset-compute + name: asset compute smoke integration test + working-directory: asset-compute-tests + run: node ../e2e-tests/.github/scripts/smoke-test.js asset-compute + + - id: output + name: Write the output to console for debugging + if: ${{ failure() }} + working-directory: asset-compute-tests + run: | + if [ -f "consoleoutput.txt" ]; then + echo "=== Console output from consoleoutput.txt ===" + cat consoleoutput.txt + else + echo "consoleoutput.txt not found" + fi + + - id: slacknotification + name: Slack Notification + if: ${{ failure() }} + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + SLACK_TITLE: 'Node version (JavaScript workflow)' + SLACK_MESSAGE: ${{ matrix.node-version }} + SLACK_COLOR: ${{ job.status }} + diff --git a/.gitignore b/.gitignore index 7f74fbc..e8deae1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,9 @@ env.key.enc .parcel-cache coverage + +# Test mock files (generated by test-harness.js) +.github/scripts/test-mocks/ + +# Temporary files (notes, summaries, etc.) +tmp/