@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.
- package/dist/bin/check-logs.d.ts +7 -0
- package/dist/bin/check-logs.d.ts.map +1 -0
- package/dist/bin/check-logs.js +51 -60
- package/dist/bin/check-logs.js.map +1 -0
- package/dist/bin/dev-deploy.d.ts +20 -0
- package/dist/bin/dev-deploy.d.ts.map +1 -0
- package/dist/bin/dev-deploy.js +289 -0
- package/dist/bin/dev-deploy.js.map +1 -0
- package/dist/bin/get-env.d.ts +16 -0
- package/dist/bin/get-env.d.ts.map +1 -0
- package/dist/bin/get-env.js +61 -31
- package/dist/bin/get-env.js.map +1 -0
- package/dist/bin/publish.d.ts +20 -0
- package/dist/bin/publish.d.ts.map +1 -0
- package/dist/bin/publish.js +280 -280
- package/dist/bin/publish.js.map +1 -0
- package/dist/bin/release.d.ts +11 -0
- package/dist/bin/release.d.ts.map +1 -0
- package/dist/bin/release.js +125 -102
- package/dist/bin/release.js.map +1 -0
- package/dist/bin/send-event.d.ts +6 -0
- package/dist/bin/send-event.d.ts.map +1 -0
- package/dist/bin/send-event.js +73 -59
- package/dist/bin/send-event.js.map +1 -0
- package/dist/bin/test-invalid-signature.d.ts +3 -0
- package/dist/bin/test-invalid-signature.d.ts.map +1 -0
- package/dist/bin/test-invalid-signature.js +64 -74
- package/dist/bin/test-invalid-signature.js.map +1 -0
- package/dist/bin/version.d.ts +13 -0
- package/dist/bin/version.d.ts.map +1 -0
- package/dist/bin/version.js +194 -181
- package/dist/bin/version.js.map +1 -0
- package/dist/lib/utils/secrets.d.ts +14 -0
- package/dist/lib/utils/secrets.d.ts.map +1 -1
- package/dist/lib/utils/secrets.js +19 -0
- package/dist/lib/utils/secrets.js.map +1 -1
- package/dist/package.json +7 -7
- package/dist/scripts/config-health-check.d.ts +1 -1
- package/dist/scripts/config-health-check.d.ts.map +1 -1
- package/dist/scripts/config-health-check.js +33 -43
- package/dist/scripts/config-health-check.js.map +1 -1
- package/dist/scripts/sync-secrets.d.ts.map +1 -1
- package/dist/scripts/sync-secrets.js +2 -16
- package/dist/scripts/sync-secrets.js.map +1 -1
- package/package.json +7 -7
- package/dist/bin/cdk-dev.js +0 -308
package/dist/bin/cdk-dev.js
DELETED
|
@@ -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
|
-
});
|