@quiltdata/benchling-webhook 0.6.1-20251104T051705Z → 0.6.1

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.
Files changed (46) hide show
  1. package/dist/bin/check-logs.d.ts +7 -0
  2. package/dist/bin/check-logs.d.ts.map +1 -0
  3. package/dist/bin/check-logs.js +51 -60
  4. package/dist/bin/check-logs.js.map +1 -0
  5. package/dist/bin/dev-deploy.d.ts +20 -0
  6. package/dist/bin/dev-deploy.d.ts.map +1 -0
  7. package/dist/bin/dev-deploy.js +289 -0
  8. package/dist/bin/dev-deploy.js.map +1 -0
  9. package/dist/bin/get-env.d.ts +16 -0
  10. package/dist/bin/get-env.d.ts.map +1 -0
  11. package/dist/bin/get-env.js +61 -31
  12. package/dist/bin/get-env.js.map +1 -0
  13. package/dist/bin/publish.d.ts +20 -0
  14. package/dist/bin/publish.d.ts.map +1 -0
  15. package/dist/bin/publish.js +280 -280
  16. package/dist/bin/publish.js.map +1 -0
  17. package/dist/bin/release.d.ts +11 -0
  18. package/dist/bin/release.d.ts.map +1 -0
  19. package/dist/bin/release.js +125 -102
  20. package/dist/bin/release.js.map +1 -0
  21. package/dist/bin/send-event.d.ts +6 -0
  22. package/dist/bin/send-event.d.ts.map +1 -0
  23. package/dist/bin/send-event.js +73 -59
  24. package/dist/bin/send-event.js.map +1 -0
  25. package/dist/bin/test-invalid-signature.d.ts +3 -0
  26. package/dist/bin/test-invalid-signature.d.ts.map +1 -0
  27. package/dist/bin/test-invalid-signature.js +64 -74
  28. package/dist/bin/test-invalid-signature.js.map +1 -0
  29. package/dist/bin/version.d.ts +13 -0
  30. package/dist/bin/version.d.ts.map +1 -0
  31. package/dist/bin/version.js +194 -181
  32. package/dist/bin/version.js.map +1 -0
  33. package/dist/lib/utils/secrets.d.ts +14 -0
  34. package/dist/lib/utils/secrets.d.ts.map +1 -1
  35. package/dist/lib/utils/secrets.js +19 -0
  36. package/dist/lib/utils/secrets.js.map +1 -1
  37. package/dist/package.json +7 -7
  38. package/dist/scripts/config-health-check.d.ts +1 -1
  39. package/dist/scripts/config-health-check.d.ts.map +1 -1
  40. package/dist/scripts/config-health-check.js +33 -43
  41. package/dist/scripts/config-health-check.js.map +1 -1
  42. package/dist/scripts/sync-secrets.d.ts.map +1 -1
  43. package/dist/scripts/sync-secrets.js +2 -16
  44. package/dist/scripts/sync-secrets.js.map +1 -1
  45. package/package.json +7 -7
  46. package/dist/bin/cdk-dev.js +0 -308
@@ -1,308 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Development deployment workflow script
5
- *
6
- * This script:
7
- * 1. Creates a dev git tag with timestamp (v{version}-{timestamp})
8
- * 2. Pushes the tag to GitHub (triggers CI to build Docker image)
9
- * 3. Waits for CI/CD pipeline to complete (monitors GitHub Actions)
10
- * 4. Deploys CDK stack using the CI-built image tag
11
- *
12
- * Usage:
13
- * npm run cdk:dev # Full workflow
14
- * npm run cdk:dev -- --continue # Skip tag creation, wait for CI and deploy
15
- * npm run cdk:dev -- --tag <tag> # Use specific existing tag
16
- *
17
- * IMPORTANT: This uses CI-built images (x86_64), NOT local builds.
18
- * Local ARM builds would fail in AWS which runs on x86_64.
19
- */
20
-
21
- const { execSync } = require('child_process');
22
- const fs = require('fs');
23
- const path = require('path');
24
-
25
- // Read package.json for version
26
- const packagePath = path.join(__dirname, '..', 'package.json');
27
- const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
28
-
29
- function run(command, options = {}) {
30
- const silent = options.silent || false;
31
- if (!silent) {
32
- console.log(`\n$ ${command}\n`);
33
- }
34
- try {
35
- return execSync(command, {
36
- stdio: silent ? 'pipe' : 'inherit',
37
- encoding: 'utf-8',
38
- ...options
39
- });
40
- } catch (error) {
41
- if (!silent) {
42
- console.error(`\n❌ Command failed: ${command}`);
43
- }
44
- if (options.allowFailure) {
45
- return null;
46
- }
47
- process.exit(1);
48
- }
49
- }
50
-
51
- async function waitForWorkflow(commitSha, timeoutMinutes = 15) {
52
- console.log('');
53
- console.log(`Waiting for CI workflow to complete (timeout: ${timeoutMinutes} minutes)...`);
54
- console.log('');
55
-
56
- // Check if gh CLI is available
57
- try {
58
- execSync('gh --version', { stdio: 'ignore' });
59
- } catch (e) {
60
- console.error('❌ GitHub CLI (gh) is not installed or not in PATH');
61
- console.error(' Install from: https://cli.github.com/');
62
- console.error('\n Alternatively, monitor the workflow manually and deploy when complete:');
63
- console.error(' 1. Watch: https://github.com/quiltdata/benchling-webhook/actions');
64
- console.error(' 2. Deploy: npm run cli -- --image-tag <version> --yes');
65
- process.exit(1);
66
- }
67
-
68
- const startTime = Date.now();
69
- const timeoutMs = timeoutMinutes * 60 * 1000;
70
- let attempt = 0;
71
- let workflowUrl = null;
72
-
73
- while (Date.now() - startTime < timeoutMs) {
74
- attempt++;
75
-
76
- try {
77
- // Use gh to list recent workflow runs for this commit
78
- const result = run(`gh run list --commit ${commitSha} --json status,conclusion,url,databaseId --limit 5`, {
79
- silent: true,
80
- allowFailure: true
81
- });
82
-
83
- if (!result) {
84
- process.stdout.write(`\r Attempt ${attempt}: Waiting for workflow to start (commit ${commitSha.substring(0, 7)})...`);
85
- await new Promise(resolve => setTimeout(resolve, 10000));
86
- continue;
87
- }
88
-
89
- const runs = JSON.parse(result);
90
-
91
- if (runs && runs.length > 0) {
92
- const workflowRun = runs[0]; // Most recent run for this commit
93
- const status = workflowRun.status;
94
- const conclusion = workflowRun.conclusion;
95
- workflowUrl = workflowRun.url;
96
-
97
- process.stdout.write(`\r Attempt ${attempt}: Status=${status}, Conclusion=${conclusion || 'pending'}... ${workflowUrl}`);
98
-
99
- if (status === 'completed') {
100
- console.log('\n');
101
- if (conclusion === 'success') {
102
- console.log(`✅ CI workflow completed successfully!`);
103
- console.log(` Run: ${workflowUrl}`);
104
- return true;
105
- } else {
106
- console.error(`\n❌ CI workflow failed with conclusion: ${conclusion}`);
107
- console.error(` Run: ${workflowUrl}`);
108
- console.error(' Please check the workflow logs and fix any issues.');
109
- process.exit(1);
110
- }
111
- }
112
- } else {
113
- process.stdout.write(`\r Attempt ${attempt}: Waiting for workflow to start (commit ${commitSha.substring(0, 7)})...`);
114
- }
115
- } catch (error) {
116
- // Errors are non-fatal, just retry
117
- if (attempt % 10 === 0) {
118
- console.log(`\n Warning: ${error.message}`);
119
- }
120
- }
121
-
122
- // Wait 10 seconds between checks
123
- await new Promise(resolve => setTimeout(resolve, 10000));
124
- }
125
-
126
- console.error('\n\n❌ Timeout waiting for CI workflow to complete');
127
- console.error(` Waited ${timeoutMinutes} minutes`);
128
- if (workflowUrl) {
129
- console.error(` Check status at: ${workflowUrl}`);
130
- } else {
131
- console.error(` Check status at: https://github.com/quiltdata/benchling-webhook/actions`);
132
- }
133
- console.error('\n Once the workflow completes, you can deploy manually with:');
134
- console.error(` npm run cli -- --image-tag <version> --yes`);
135
- process.exit(1);
136
- }
137
-
138
- async function main() {
139
- console.log('🚀 Starting development deployment workflow...');
140
- console.log('');
141
- console.log('This workflow uses CI-built Docker images (x86_64 for AWS).');
142
- console.log('Local ARM builds are NOT used as they would fail in AWS.');
143
- console.log('');
144
-
145
- // Parse command line arguments
146
- const args = process.argv.slice(2);
147
- const continueMode = args.includes('--continue');
148
- const tagIndex = args.indexOf('--tag');
149
- const specificTag = tagIndex !== -1 ? args[tagIndex + 1] : null;
150
-
151
- let devTag;
152
- let version;
153
-
154
- if (specificTag) {
155
- // Use specific tag provided by user
156
- devTag = specificTag;
157
- version = specificTag.replace(/^v/, '').split('-')[0]; // Extract version from tag
158
- console.log(`Using specified tag: ${devTag}`);
159
- console.log(`Extracted version: ${version}`);
160
- } else if (continueMode) {
161
- // Continue mode - find most recent dev tag
162
- console.log('Continue mode: Finding most recent dev tag...');
163
- try {
164
- const tags = run('git tag --sort=-creatordate', { silent: true }).trim().split('\n');
165
- const recentDevTag = tags.find(t => t.match(/^v[\d.]+-.+Z$/));
166
-
167
- if (!recentDevTag) {
168
- console.error('❌ No dev tags found');
169
- console.error(' Run without --continue to create a new dev tag first');
170
- process.exit(1);
171
- }
172
-
173
- devTag = recentDevTag;
174
- version = devTag.replace(/^v/, '').split('-')[0];
175
- console.log(`✅ Found recent dev tag: ${devTag}`);
176
- console.log(` Version: ${version}`);
177
- } catch (e) {
178
- console.error('❌ Failed to find recent dev tag');
179
- process.exit(1);
180
- }
181
- } else {
182
- // Normal mode - create new tag
183
- // 1. Check for uncommitted changes
184
- console.log('Step 1: Checking for uncommitted changes...');
185
- try {
186
- execSync('git diff-index --quiet HEAD --', { stdio: 'ignore' });
187
- } catch (e) {
188
- console.error('❌ You have uncommitted changes');
189
- console.error(' Commit or stash your changes before creating a dev deployment');
190
- process.exit(1);
191
- }
192
- console.log('✅ Working directory is clean');
193
-
194
- // 2. Generate dev tag name
195
- version = pkg.version;
196
- const timestamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+Z$/, 'Z');
197
- devTag = `v${version}-${timestamp}`;
198
-
199
- console.log('');
200
- console.log(`Step 2: Creating dev tag: ${devTag}`);
201
-
202
- // Check if tag already exists
203
- try {
204
- execSync(`git rev-parse ${devTag}`, { stdio: 'ignore' });
205
- console.error(`❌ Tag ${devTag} already exists`);
206
- process.exit(1);
207
- } catch (e) {
208
- // Tag doesn't exist, continue
209
- }
210
-
211
- // Create tag
212
- const message = `Development release ${devTag}\n\nThis is a pre-release for testing purposes.`;
213
- run(`git tag -a ${devTag} -m "${message}"`);
214
- console.log(`✅ Created git tag ${devTag}`);
215
-
216
- // 3. Push tag to origin (triggers CI)
217
- console.log('');
218
- console.log(`Step 3: Pushing tag to origin (this triggers CI/CD)...`);
219
- run(`git push origin ${devTag}`);
220
- console.log(`✅ Pushed tag ${devTag} to origin`);
221
- console.log(' CI will now build Docker image for x86_64 (AWS-compatible)');
222
- }
223
-
224
- // 4. Wait for CI to complete
225
- console.log('');
226
- console.log(`Step 4: Waiting for CI to build Docker image...`);
227
-
228
- // Get the commit SHA for the tag (use ^{commit} to dereference annotated tags)
229
- const commitSha = run(`git rev-parse ${devTag}^{commit}`, { silent: true }).trim();
230
-
231
- await waitForWorkflow(commitSha);
232
-
233
- // 5. Deploy CDK stack with CI-built image tag using secrets-only mode
234
- console.log('');
235
- console.log(`Step 5: Deploying CDK stack with CI-built image (secrets-only mode)...`);
236
- process.chdir(path.join(__dirname, '..'));
237
- // Use the full version with timestamp (without 'v' prefix)
238
- const imageTag = devTag.replace(/^v/, '');
239
-
240
- // Secrets-only mode parameters
241
- const quiltStackArn = 'arn:aws:cloudformation:us-east-1:712023778557:stack/quilt-staging/e51b0c10-10c9-11ee-9b41-12fda87498a3';
242
- const benchlingSecret = 'benchling-webhook-dev';
243
-
244
- run(`npm run deploy:prod -- --quilt-stack-arn ${quiltStackArn} --benchling-secret ${benchlingSecret} --image-tag ${imageTag} --yes`);
245
-
246
- // 6. Get and store the deployment endpoint
247
- console.log('');
248
- console.log('Step 6: Retrieving deployment endpoint...');
249
-
250
- try {
251
- const { CloudFormationClient, DescribeStacksCommand } = require('@aws-sdk/client-cloudformation');
252
- const os = require('os');
253
-
254
- const cloudformation = new CloudFormationClient({ region: 'us-east-1' });
255
- const command = new DescribeStacksCommand({ StackName: 'BenchlingWebhookStack' });
256
- const response = await cloudformation.send(command);
257
-
258
- if (response.Stacks && response.Stacks.length > 0) {
259
- const stack = response.Stacks[0];
260
- const endpointOutput = stack.Outputs?.find(o => o.OutputKey === 'WebhookEndpoint');
261
- const webhookUrl = endpointOutput?.OutputValue || '';
262
-
263
- if (webhookUrl) {
264
- // Store endpoint in XDG config
265
- const configDir = path.join(os.homedir(), '.config', 'benchling-webhook');
266
- const deployJsonPath = path.join(configDir, 'deploy.json');
267
-
268
- // Read existing deploy.json or create new one
269
- let deployConfig = {};
270
- if (fs.existsSync(deployJsonPath)) {
271
- deployConfig = JSON.parse(fs.readFileSync(deployJsonPath, 'utf8'));
272
- }
273
-
274
- // Update dev section
275
- deployConfig.dev = {
276
- endpoint: webhookUrl,
277
- imageTag: imageTag,
278
- deployedAt: new Date().toISOString(),
279
- stackName: 'BenchlingWebhookStack'
280
- };
281
-
282
- // Ensure config directory exists
283
- if (!fs.existsSync(configDir)) {
284
- fs.mkdirSync(configDir, { recursive: true });
285
- }
286
-
287
- // Write deploy.json
288
- fs.writeFileSync(deployJsonPath, JSON.stringify(deployConfig, null, 2));
289
- console.log(`✅ Stored deployment endpoint in ${deployJsonPath}`);
290
- console.log(` Endpoint: ${webhookUrl}`);
291
- }
292
- }
293
- } catch (error) {
294
- console.warn(`⚠️ Could not retrieve/store deployment endpoint: ${error.message}`);
295
- }
296
-
297
- console.log('');
298
- console.log('✅ Development deployment complete!');
299
- console.log('');
300
- console.log(`Dev tag: ${devTag}`);
301
- console.log(`Image tag: ${imageTag} (built by CI for x86_64)`);
302
- console.log('');
303
- }
304
-
305
- main().catch(error => {
306
- console.error('\n❌ Error:', error.message);
307
- process.exit(1);
308
- });