Skip to content

Commit 2a5218b

Browse files
pras0131Paras
andauthored
chore: script to create local build (#1301)
* chore: script to create local build * fix: refactor custom webpack config to allow .node files to be created inside build directory add local-build script usage to package.json add README for local-build --------- Co-authored-by: Paras <[email protected]>
1 parent e030bdd commit 2a5218b

File tree

4 files changed

+188
-2
lines changed

4 files changed

+188
-2
lines changed

app/aws-lsp-codewhisperer-runtimes/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ or
2525
node ./out/iam-standalone.js --stdio
2626
```
2727

28+
### Creating packaged build for agent-standalone server and chat-client
29+
There is a single shortcut command to generate packaged build for the mentioned server and client without having to run multiple commands inside separate directories.
30+
This aims to ease the integration with the clients for testing purposes. The command has to run inside `app/aws-lsp-codewhisperer-runtimes` directory. Following is the command:
31+
```bash
32+
npm run local-build
33+
```
34+
2835
### Creating (new) bundle configurations
2936

3037
**It is important to note** that any configuration should atleast contain a variation of the [AmazonQServiceServer](https://github.com/aws/language-servers/blob/main/server/aws-lsp-codewhisperer/src/shared/amazonQServer.ts) (either IAM or Token). For standalone configurations, the
@@ -72,4 +79,4 @@ The server is managed via scripts/dev-server.js, which ensures:
7279
#### Tests configuration
7380
- Test settings are defined in `wdio.conf.ts`
7481
- The actual test implementation is in the `test/e2e` folder
75-
- Max timeout is 5 minutes (300000ms) to allow for the devhost to load the webpage with the bundled webworker which requires some time.
82+
- Max timeout is 5 minutes (300000ms) to allow for the devhost to load the webpage with the bundled webworker which requires some time.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
var path = require('path')
2+
3+
const baseConfig = {
4+
mode: 'production',
5+
resolve: {
6+
extensions: ['.ts', '.tsx', '.js', '.node'],
7+
},
8+
module: {
9+
rules: [
10+
{
11+
test: /\.tsx?$/,
12+
use: 'ts-loader',
13+
exclude: /node_modules/,
14+
},
15+
{
16+
test: /\.node$/,
17+
loader: 'node-loader',
18+
options: {
19+
name: '[name].[ext]', // Preserves original path and filename
20+
},
21+
},
22+
],
23+
},
24+
output: {
25+
path: path.resolve(__dirname, 'build'),
26+
globalObject: 'this',
27+
library: {
28+
type: 'umd',
29+
},
30+
},
31+
target: 'node',
32+
experiments: {
33+
asyncWebAssembly: true,
34+
},
35+
}
36+
37+
const nodeJsBearerTokenBundleConfig = {
38+
...baseConfig,
39+
experiments: {
40+
asyncWebAssembly: true,
41+
},
42+
entry: {
43+
'aws-lsp-codewhisperer': path.join(__dirname, 'src/agent-standalone.ts'),
44+
},
45+
output: {
46+
...baseConfig.output,
47+
filename: `[name].js`,
48+
chunkFormat: false,
49+
},
50+
resolve: {
51+
...baseConfig.resolve,
52+
},
53+
target: 'node',
54+
}
55+
56+
module.exports = [nodeJsBearerTokenBundleConfig]

app/aws-lsp-codewhisperer-runtimes/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"start": "cross-env NODE_OPTIONS=--max_old_space_size=8172 node scripts/dev-server.js start",
1212
"stop-dev-server": "node scripts/dev-server.js stop",
1313
"test": "node scripts/test-runner.js",
14-
"test-bundles": "node scripts/test-bundles.js"
14+
"test-bundles": "node scripts/test-bundles.js",
15+
"local-build": "node scripts/local-build.js"
1516
},
1617
"dependencies": {
1718
"@aws/language-server-runtimes": "^0.2.80",
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
const { execSync } = require('child_process')
2+
const path = require('path')
3+
const fs = require('fs')
4+
5+
const SCRIPT_DIR = __dirname
6+
const ROOT_DIR = path.resolve(SCRIPT_DIR, '../../../')
7+
const CHAT_CLIENT_PATH = path.resolve(ROOT_DIR, 'chat-client')
8+
const CODE_WHISPERER_RUNTIMES_PATH = path.resolve(ROOT_DIR, 'app/aws-lsp-codewhisperer-runtimes')
9+
const CUSTOM_WEBPACK_PATH = path.join(SCRIPT_DIR, '../custom-webpack-config.js')
10+
11+
function executeCommand(command, cwd) {
12+
try {
13+
console.log(`Executing: ${command}`)
14+
execSync(`${command}`, {
15+
cwd,
16+
stdio: 'pipe',
17+
})
18+
} catch (error) {
19+
console.error(`Error executing command "${command}": ${error.message}`)
20+
if (error.signal === 'SIGINT' || error.signal === 'SIGTERM') {
21+
cleanupInterruptedState()
22+
}
23+
if (error.message.includes('Command failed: npm run clean')) {
24+
// ignore this error as it is expected to fail in case clean is run without install
25+
return
26+
}
27+
process.exit(1)
28+
}
29+
}
30+
31+
function handleWebpackConfig(action) {
32+
const webpackPath = path.join(SCRIPT_DIR, '../webpack.config.js')
33+
const backupPath = path.join(SCRIPT_DIR, '../webpack.config.js.backup')
34+
35+
if (action === 'backup' && fs.existsSync(webpackPath)) {
36+
fs.renameSync(webpackPath, backupPath)
37+
fs.copyFileSync(CUSTOM_WEBPACK_PATH, webpackPath)
38+
} else if (action === 'restore' && fs.existsSync(backupPath)) {
39+
if (fs.existsSync(webpackPath)) {
40+
fs.unlinkSync(webpackPath)
41+
}
42+
fs.renameSync(backupPath, webpackPath)
43+
}
44+
}
45+
46+
function cleanupInterruptedState() {
47+
const webpackPath = path.join(SCRIPT_DIR, '../webpack.config.js')
48+
const backupPath = path.join(SCRIPT_DIR, '../webpack.config.js.backup')
49+
50+
if (fs.existsSync(backupPath)) {
51+
console.log('Found backup webpack config from previous interrupted run. Restoring...')
52+
if (fs.existsSync(webpackPath)) {
53+
fs.unlinkSync(webpackPath)
54+
}
55+
fs.renameSync(backupPath, webpackPath)
56+
console.log('Restored original webpack config.')
57+
}
58+
}
59+
60+
function createServerArtifact() {
61+
try {
62+
// Clean up any interrupted state from previous runs
63+
cleanupInterruptedState()
64+
65+
if (!fs.existsSync(ROOT_DIR)) {
66+
throw new Error(`Directory not found: ${ROOT_DIR}`)
67+
}
68+
69+
if (!fs.existsSync(CUSTOM_WEBPACK_PATH)) {
70+
throw new Error(`Custom webpack config not found: ${CUSTOM_WEBPACK_PATH}`)
71+
}
72+
73+
console.log('\nStep 1: Running clean in root directory...')
74+
executeCommand('npm run clean', ROOT_DIR)
75+
76+
console.log('\nStep 2: Installing dependencies in root directory...')
77+
executeCommand('npm i', ROOT_DIR)
78+
79+
console.log('\nStep 3: Running compile in root directory...')
80+
executeCommand('npm run compile', ROOT_DIR)
81+
82+
console.log('\nStep 4: Running package in target directory...')
83+
84+
handleWebpackConfig('backup')
85+
86+
try {
87+
executeCommand('npm run package', CODE_WHISPERER_RUNTIMES_PATH)
88+
} finally {
89+
handleWebpackConfig('restore')
90+
}
91+
92+
console.log('\nServer artifact created successfully! 🎉')
93+
} catch (error) {
94+
console.error('\nServer artifact creation failed:', error.message)
95+
process.exit(1)
96+
}
97+
}
98+
99+
function createClientArtifact() {
100+
try {
101+
if (!fs.existsSync(CHAT_CLIENT_PATH)) {
102+
throw new Error(`Chat client path not found: ${CHAT_CLIENT_PATH}`)
103+
}
104+
executeCommand('npm run compile', CHAT_CLIENT_PATH)
105+
console.log('\nClient artifact created successfully! 🎉')
106+
} catch (error) {
107+
console.error('\nClient artifact creation failed:', error.message)
108+
process.exit(1)
109+
}
110+
}
111+
112+
try {
113+
createServerArtifact()
114+
createClientArtifact()
115+
console.log(
116+
'\nServer artifact created at: language-servers/app/aws-lsp-codewhisperer-runtimes/build/aws-lsp-codewhisperer.js'
117+
)
118+
console.log('\nClient artifact created at: language-servers/chat-client/build/amazonq-ui.js')
119+
} catch (er) {
120+
console.error('\nArtifacts creation failed:', er.message)
121+
process.exit(1)
122+
}

0 commit comments

Comments
 (0)