@scrymore/scry-deployer 0.0.2

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/README.md ADDED
@@ -0,0 +1,889 @@
1
+ # Scry Storybook Deployer
2
+
3
+ Deploy your Storybook to the cloud with one command. ⚡
4
+
5
+ ## 🎯 Quick Start (5 seconds)
6
+
7
+ ### 1. Get your credentials
8
+ Visit the [Scry Dashboard](https://dashboard.scry.com) and:
9
+ - 🔐 Login with your account (Firebase)
10
+ - 📦 Create a new project
11
+ - 📋 Copy your **Project ID** and **API Key**
12
+
13
+ ### 2. Run the setup command
14
+
15
+ ```bash
16
+ npx @scry/storybook-deployer init --projectId YOUR_PROJECT_ID --apiKey YOUR_API_KEY
17
+ ```
18
+
19
+ **That's it!** 🎉
20
+
21
+ The `init` command automatically:
22
+ - ✅ Creates configuration file (`.storybook-deployer.json`)
23
+ - ✅ Generates GitHub Actions workflows
24
+ - ✅ Sets up repository variables and secrets
25
+ - ✅ Commits and pushes everything to GitHub
26
+ - ✅ Triggers automatic deployment
27
+
28
+ ### What happens next?
29
+
30
+ Your Storybook now deploys automatically:
31
+ - 🚀 **Push to main** → Deploys to production (`/latest`)
32
+ - 🔍 **Open a PR** → Deploys preview (`/pr-123`)
33
+ - 🔄 **Update PR** → Updates preview automatically
34
+
35
+ No additional configuration needed!
36
+
37
+ ---
38
+
39
+ ## 📚 About
40
+
41
+ A client-side Command-Line Interface (CLI) tool to automate the deployment of Storybook static builds.
42
+
43
+ This tool is designed for execution within a CI/CD pipeline (such as GitHub Actions). The core workflow involves:
44
+ 1. Archiving a specified Storybook build directory.
45
+ 2. Authenticating with a secure backend service.
46
+ 3. Uploading the archive directly to cloud storage.
47
+
48
+ **Features:**
49
+ - 🚀 Simple Storybook static build deployment
50
+ - 🔍 Auto-detection of `.stories.*` files
51
+ - 📊 Story metadata extraction and analysis
52
+ - 📸 Automated screenshot capture with storycap
53
+ - 📦 Organized master ZIP packaging (staticsite, images, metadata)
54
+ - ⚙️ Flexible configuration (CLI, env vars, config file)
55
+ - 🔒 Secure presigned URL uploads
56
+
57
+ ---
58
+
59
+ ## 🚀 Manual Deployment (Testing)
60
+
61
+ Want to test a deployment before setting up automation? Run:
62
+
63
+ ```bash
64
+ npx @scry/storybook-deployer --dir ./storybook-static --project YOUR_PROJECT_ID --api-key YOUR_API_KEY
65
+ ```
66
+
67
+ This deploys your Storybook immediately without setting up GitHub Actions.
68
+
69
+ ---
70
+
71
+ ## 📦 Installation (Optional)
72
+
73
+ **You don't need to install anything!** Just use `npx` to run the init command:
74
+
75
+ ```bash
76
+ # From npm (recommended)
77
+ npx @scry/storybook-deployer init --projectId xxx --apiKey yyy
78
+
79
+ # From GitHub (latest from main branch)
80
+ npx github:epinnock/scry-node init --projectId xxx --apiKey yyy
81
+ ```
82
+
83
+ ### Installing as a Dependency
84
+
85
+ If you prefer to install it as a development dependency:
86
+
87
+ ```bash
88
+ # From npm (when published)
89
+ npm install @scry/storybook-deployer --save-dev
90
+
91
+ # From GitHub
92
+ npm install github:epinnock/scry-node --save-dev
93
+ # or
94
+ pnpm add github:epinnock/scry-node -D
95
+ # or
96
+ yarn add github:epinnock/scry-node --dev
97
+ ```
98
+
99
+ After installation, you can run commands using:
100
+
101
+ ```bash
102
+ # Using the storybook-deployer binary
103
+ npx storybook-deployer init --projectId xxx --apiKey yyy
104
+
105
+ # Using the scry alias
106
+ npx scry init --projectId xxx --apiKey yyy
107
+
108
+ # Using the storybook-deploy alias (for deploy commands)
109
+ npx storybook-deploy --dir ./storybook-static
110
+ ```
111
+
112
+ **Note:** The `init` command handles all configuration automatically, so manual installation is only needed if you want the package in your `node_modules` for local development.
113
+
114
+ ## Configuration for Your API
115
+
116
+ To use this package with the Storybook deployment API at `https://storybook-deployment-service.epinnock.workers.dev`, configure your `.storybook-deployer.json` file:
117
+
118
+ ```json
119
+ {
120
+ "apiUrl": "https://storybook-deployment-service.epinnock.workers.dev",
121
+ "dir": "./storybook-static",
122
+ "project": "my-project",
123
+ "version": "v1.0.0",
124
+ "verbose": false
125
+ }
126
+ ```
127
+
128
+ **API Endpoints Used:**
129
+ 1. **Direct Upload**: `POST /upload/{project}/{version}` with binary zip data
130
+
131
+ **Example Usage:**
132
+
133
+ ```bash
134
+ # Deploy to project "my-storybook" with version "v1.0.0"
135
+ npx storybook-deploy \
136
+ --dir ./storybook-static \
137
+ --project my-storybook \
138
+ --version v1.0.0
139
+
140
+ # Using environment variables
141
+ export STORYBOOK_DEPLOYER_API_URL=https://storybook-deployment-service.epinnock.workers.dev
142
+ export STORYBOOK_DEPLOYER_PROJECT=my-project
143
+ export STORYBOOK_DEPLOYER_VERSION=v1.0.0
144
+
145
+ npx storybook-deploy --dir ./storybook-static
146
+ ```
147
+
148
+ **Note:** If `--project` or `--version` are not provided, they default to `main` and `latest` respectively.
149
+
150
+ ## Usage
151
+
152
+ The CLI provides a single command to handle the deployment. It can be run using `npx` from within your project's directory.
153
+
154
+ ```bash
155
+ npx storybook-deploy [options]
156
+ ```
157
+ The CLI provides two commands: `deploy` (default) and `analyze`.
158
+
159
+ ### Deploy Command (Default)
160
+
161
+ Deploy your Storybook static build, optionally with analysis.
162
+
163
+ ```bash
164
+ npx storybook-deploy [options]
165
+ ```
166
+
167
+ ### Analyze Command
168
+
169
+ Analyze Storybook stories, capture screenshots, and generate metadata without deploying the static site.
170
+
171
+ ```bash
172
+ npx storybook-deploy analyze [options]
173
+ ```
174
+
175
+ ### Options
176
+
177
+ The CLI is configured through a combination of command-line options and environment variables. Command-line options always take precedence.
178
+
179
+ | Option | Environment Variable | Description | Required | Default |
180
+ |----------------|---------------------------------------|--------------------------------------------------------------|----------|--------------------------------------|
181
+ | `--dir` | `STORYBOOK_DEPLOYER_DIR` | Path to the built Storybook directory (e.g., `storybook-static`). | Yes | - |
182
+ | `--api-key` | `STORYBOOK_DEPLOYER_API_KEY` | The API key for the deployment service. | No | - |
183
+ | `--api-url` | `STORYBOOK_DEPLOYER_API_URL` | Base URL for the deployment service API. | No | `https://api.default-service.com/v1` |
184
+ | `--project` | `STORYBOOK_DEPLOYER_PROJECT` | The project name/identifier. | No | `main` |
185
+ | `--version` | `STORYBOOK_DEPLOYER_VERSION` | The version identifier for the deployment. | No | `latest` |
186
+ | `--with-analysis` | `STORYBOOK_DEPLOYER_WITH_ANALYSIS` | Enable Storybook analysis (story crawling + screenshots). | No | `false` |
187
+ | `--stories-dir` | `STORYBOOK_DEPLOYER_STORIES_DIR` | Path to stories directory (optional, auto-detects .stories.* files). | No | Auto-detect |
188
+ | `--screenshots-dir` | `STORYBOOK_DEPLOYER_SCREENSHOTS_DIR` | Directory for captured screenshots. | No | `./screenshots` |
189
+ | `--storybook-url` | `STORYBOOK_DEPLOYER_STORYBOOK_URL` | URL of running Storybook server for screenshot capture. | No | `http://localhost:6006` |
190
+ | `--verbose` | `STORYBOOK_DEPLOYER_VERBOSE` | Enable verbose logging for debugging purposes. | No | `false` |
191
+ | `--help`, `-h` | - | Show the help message. | - | - |
192
+ | `--version`, `-v`| - | Show the version number. | - | - |
193
+
194
+ ### Story File Auto-Detection
195
+
196
+ The analysis feature now automatically detects `.stories.*` files anywhere in your project! You no longer need to specify a stories directory - the system intelligently searches for story files with these features:
197
+
198
+ **Supported File Patterns:**
199
+ - `.stories.ts`, `.stories.tsx`
200
+ - `.stories.js`, `.stories.jsx`
201
+ - `.stories.mjs`, `.stories.cjs`
202
+
203
+ **Auto-Detection Benefits:**
204
+ - **Automatic Discovery**: Finds story files anywhere in your project
205
+ - **Intelligent Exclusions**: Skips common directories (`node_modules`, `dist`, `build`, `.git`, etc.)
206
+ - **Flexible Structure**: Works with any project organization
207
+ - **Performance Optimized**: Searches up to 5 levels deep by default
208
+
209
+ You can still specify a custom directory with `--stories-dir` if needed.
210
+
211
+ ### Configuration Hierarchy
212
+
213
+ The configuration is resolved in the following order of precedence:
214
+ 1. **Command-Line Arguments**: Highest precedence (e.g., `--api-key=some_key`).
215
+ 2. **Environment Variables**: Sourced from the execution environment (e.g., `STORYBOOK_DEPLOYER_API_KEY=some_key`).
216
+ 3. **Configuration File**: Values from `.storybook-deployer.json` in your project directory (automatically created during installation).
217
+ 4. **Programmatic Defaults**: Lowest precedence (e.g., for `--api-url`).
218
+
219
+ ### Configuration File
220
+
221
+ The configuration file (`.storybook-deployer.json`) is automatically created in your project directory when you install the package. You can edit this file to set default values for common options:
222
+
223
+ ```json
224
+ {
225
+ "apiUrl": "https://api.your-service.com/v1",
226
+ "dir": "./storybook-static",
227
+ "project": "my-project",
228
+ "version": "v1.0.0",
229
+ "verbose": false
230
+ }
231
+ ```
232
+
233
+ **Property Reference:**
234
+ - `apiKey` → `--api-key` CLI option
235
+ - `apiUrl` → `--api-url` CLI option
236
+ - `dir` → `--dir` CLI option
237
+ - `project` → `--project` CLI option
238
+ - `version` → `--version` CLI option
239
+ - `verbose` → `--verbose` CLI option
240
+
241
+ **See [`.storybook-deployer.example.json`](.storybook-deployer.example.json) for a complete configuration file with all available options and their default values.**
242
+
243
+ ### Usage Examples
244
+
245
+ **Basic deployment with config file:**
246
+ ```bash
247
+ # Set project and version in .storybook-deployer.json, then run:
248
+ npx storybook-deploy --dir ./storybook-static
249
+ ```
250
+
251
+ **Deploy with Storybook analysis:**
252
+ ```bash
253
+ # Deploy with story metadata and screenshots (auto-detects story files)
254
+ npx storybook-deploy \
255
+ --dir ./storybook-static \
256
+ --with-analysis \
257
+ --storybook-url http://localhost:6006
258
+
259
+ # Or specify a custom stories directory
260
+ npx storybook-deploy \
261
+ --dir ./storybook-static \
262
+ --with-analysis \
263
+ --stories-dir ./src/components \
264
+ --storybook-url http://localhost:6006
265
+ ```
266
+
267
+ **Standalone analysis (no deployment):**
268
+ ```bash
269
+ # Analyze stories and capture screenshots (auto-detects story files)
270
+ npx storybook-deploy analyze \
271
+ --project my-project \
272
+ --version v1.0.0 \
273
+ --storybook-url http://localhost:6006
274
+
275
+ # Or with custom stories directory
276
+ npx storybook-deploy analyze \
277
+ --project my-project \
278
+ --version v1.0.0 \
279
+ --stories-dir ./src \
280
+ --storybook-url http://localhost:6006
281
+ ```
282
+
283
+ **Override specific options:**
284
+ ```bash
285
+ # Use config file defaults but override API URL:
286
+ npx storybook-deploy --api-url https://staging-api.service.com/v1
287
+ ```
288
+
289
+ **Full command-line configuration:**
290
+ ```bash
291
+ npx storybook-deploy \
292
+ --dir ./storybook-static \
293
+ --api-url https://storybook-deployment-service.epinnock.workers.dev \
294
+ --project my-storybook \
295
+ --version v1.0.0 \
296
+ --verbose
297
+ ```
298
+
299
+ ### Master ZIP Structure
300
+
301
+ When analysis is enabled (`--with-analysis`), the tool creates a master ZIP file named `{project}-{version}.zip` with the following CDN-compliant structure:
302
+
303
+ ```
304
+ my-project-v1.0.0.zip
305
+ ├── index.html # Storybook static build at root (CDN-compliant)
306
+ ├── iframe.html
307
+ ├── static/
308
+ │ └── ...
309
+ ├── images/ # Captured screenshots
310
+ │ ├── story1.png
311
+ │ ├── story2.png
312
+ │ └── ...
313
+ └── metadata.json # Story metadata and mappings
314
+ ```
315
+
316
+ **metadata.json** contains:
317
+ - Story metadata (file paths, component names, story names)
318
+ - Screenshot mappings (which image corresponds to which story)
319
+ - Analysis timestamp and configuration
320
+
321
+ **Important:** The static site files (`index.html`, etc.) are placed at the **root of the ZIP** to ensure CDN compatibility. This allows the CDN to find `index.html` at the root level as expected.
322
+
323
+ Without analysis, only the static site is zipped and uploaded as `{project}-{version}.zip` with files at root.
324
+
325
+ ## Example CI/CD Integration (GitHub Actions)
326
+
327
+ This tool is ideal for use in a GitHub Actions workflow. The API key should be stored as a [GitHub Secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions).
328
+
329
+ **Basic deployment workflow:**
330
+ ```yaml
331
+ - name: Deploy Storybook
332
+ env:
333
+ STORYBOOK_DEPLOYER_API_URL: https://storybook-deployment-service.epinnock.workers.dev
334
+ STORYBOOK_DEPLOYER_PROJECT: ${{ github.event.repository.name }}
335
+ STORYBOOK_DEPLOYER_VERSION: ${{ github.sha }}
336
+ run: npx storybook-deploy --dir ./storybook-static
337
+ ```
338
+
339
+ **Deployment with analysis:**
340
+ ```yaml
341
+ - name: Start Storybook server
342
+ run: npm run storybook &
343
+
344
+ - name: Wait for Storybook
345
+ run: npx wait-on http://localhost:6006
346
+
347
+ - name: Deploy Storybook with Analysis
348
+ env:
349
+ STORYBOOK_DEPLOYER_API_URL: https://storybook-deployment-service.epinnock.workers.dev
350
+ STORYBOOK_DEPLOYER_PROJECT: ${{ github.event.repository.name }}
351
+ STORYBOOK_DEPLOYER_VERSION: ${{ github.sha }}
352
+ run: |
353
+ npx storybook-deploy \
354
+ --dir ./storybook-static \
355
+ --with-analysis \
356
+ --storybook-url http://localhost:6006
357
+ # Note: --stories-dir is optional; story files are auto-detected
358
+ ```
359
+
360
+ See the example workflow file: `.github/workflows/deploy-example.yml`
361
+
362
+ ### PR Preview Deployments
363
+
364
+ Automatically deploy Storybook previews for every pull request to get instant visual feedback on UI changes. The PR preview workflow is included in this repository at [`.github/workflows/deploy-pr-preview.yml`](.github/workflows/deploy-pr-preview.yml).
365
+
366
+ **Features:**
367
+ - 🚀 Automatic deployment on PR creation and updates
368
+ - 💬 PR comment with deployment URL and metadata
369
+ - 🔄 Auto-updates the same comment on new commits
370
+ - ⚡ Fast builds (static site only, no analysis)
371
+ - 🏷️ Unique URLs per PR: `https://your-cdn.com/{project}/pr-{number}/`
372
+
373
+ #### Prerequisites
374
+
375
+ Before setting up PR preview deployments, ensure you have:
376
+
377
+ 1. **A Storybook project** with a build command (e.g., `npm run build-storybook`)
378
+ 2. **Access to repository settings** to configure GitHub Actions variables and secrets
379
+ 3. **Backend deployment service** running and accessible (e.g., `https://storybook-deployment-service.epinnock.workers.dev`)
380
+ 4. **Project identifier** for your Storybook deployment
381
+
382
+ #### Step-by-Step Setup
383
+
384
+ **Step 1: Copy the workflow file to your project**
385
+
386
+ If you're using this as a template, copy the workflow file to your repository:
387
+
388
+ ```bash
389
+ mkdir -p .github/workflows
390
+ cp .github/workflows/deploy-pr-preview.yml YOUR_PROJECT/.github/workflows/
391
+ ```
392
+
393
+ If you're installing from GitHub, the workflow file is already included.
394
+
395
+ **Step 2: Configure GitHub Actions Variables**
396
+
397
+ 1. Navigate to your GitHub repository
398
+ 2. Go to **Settings** → **Secrets and variables** → **Actions**
399
+ 3. Click on the **Variables** tab
400
+ 4. Click **New repository variable**
401
+ 5. Add the following variables:
402
+
403
+ | Variable Name | Value | Example |
404
+ |--------------|-------|---------|
405
+ | `SCRY_PROJECT_ID` | Your project identifier | `my-storybook` or `company-design-system` |
406
+ | `SCRY_API_URL` | Backend API endpoint for uploads | `https://api.scrymore.com` |
407
+ | `SCRY_VIEW_URL` | Base URL where users view deployed Storybooks | `https://view.scrymore.com` |
408
+
409
+ **Note:** The `SCRY_VIEW_URL` is where users will access your deployed Storybook (e.g., `https://view.scrymore.com/{project}/pr-{number}`). This is separate from `SCRY_API_URL`, which is the backend API endpoint used for uploads.
410
+
411
+ **Step 3: Configure GitHub Actions Secrets (Optional)**
412
+
413
+ If your backend requires authentication:
414
+
415
+ 1. In the same **Settings** → **Secrets and variables** → **Actions** page
416
+ 2. Click on the **Secrets** tab
417
+ 3. Click **New repository secret**
418
+ 4. Add the following secret:
419
+
420
+ | Secret Name | Value | Description |
421
+ |------------|-------|-------------|
422
+ | `SCRY_API_KEY` | Your API authentication key | Only needed if backend requires authentication |
423
+
424
+ **Step 4: Verify Your Storybook Build Command**
425
+
426
+ The workflow assumes your package.json has a `build-storybook` script. Verify this command exists:
427
+
428
+ ```json
429
+ {
430
+ "scripts": {
431
+ "build-storybook": "storybook build"
432
+ }
433
+ }
434
+ ```
435
+
436
+ If your build command is different, update line 29 in `.github/workflows/deploy-pr-preview.yml`:
437
+
438
+ ```yaml
439
+ - name: Build Storybook
440
+ run: npm run build-storybook # Change this if your command differs
441
+ ```
442
+
443
+ **Step 5: Configure View URL (Where Users Access Storybooks)**
444
+
445
+ The workflow constructs deployment URLs using the `SCRY_VIEW_URL` variable:
446
+ ```
447
+ {SCRY_VIEW_URL}/{PROJECT_ID}/pr-{PR_NUMBER}
448
+ ```
449
+
450
+ **Default:** If `SCRY_VIEW_URL` is not set, it defaults to `https://view.scrymore.com`
451
+
452
+ **Example URLs:**
453
+ - With default: `https://view.scrymore.com/my-project/pr-123`
454
+ - With custom domain: `https://storybooks.mycompany.com/my-project/pr-123`
455
+
456
+ To use a custom domain, add `SCRY_VIEW_URL` as a repository variable (see Step 2).
457
+
458
+ **Step 6: Test with a Pull Request**
459
+
460
+ 1. Create a new branch in your repository:
461
+ ```bash
462
+ git checkout -b test-pr-preview
463
+ ```
464
+
465
+ 2. Make a small change (e.g., update README or add a comment)
466
+
467
+ 3. Push the branch and create a pull request:
468
+ ```bash
469
+ git add .
470
+ git commit -m "Test PR preview deployment"
471
+ git push origin test-pr-preview
472
+ ```
473
+
474
+ 4. Open a PR on GitHub and watch the Actions tab for the workflow execution
475
+
476
+ 5. Once complete, check for a comment on the PR with your deployment URL
477
+
478
+ #### Environment Variables Reference
479
+
480
+ The PR preview workflow uses these environment variables (configured via GitHub Variables and Secrets):
481
+
482
+ | Environment Variable | Source | Required | Description |
483
+ |---------------------|--------|----------|-------------|
484
+ | `SCRY_PROJECT_ID` | GitHub Variable | **Yes** | Project identifier for deployments |
485
+ | `SCRY_API_URL` | GitHub Variable | **Yes** | Backend API endpoint for uploads |
486
+ | `SCRY_VIEW_URL` | GitHub Variable | No | Base URL where users view Storybooks (default: `https://view.scrymore.com`) |
487
+ | `SCRY_API_KEY` | GitHub Secret | No | API authentication key (if required) |
488
+
489
+ **Important:** `SCRY_API_URL` (where files are uploaded) and `SCRY_VIEW_URL` (where users view the deployed Storybook) are two different URLs:
490
+ - **API URL**: Backend service endpoint (e.g., `https://api.scrymore.com`)
491
+ - **View URL**: Public-facing CDN or viewer URL (e.g., `https://view.scrymore.com`)
492
+
493
+ The CLI also supports these environment variables for backward compatibility:
494
+ - `STORYBOOK_DEPLOYER_*` (legacy prefix)
495
+ - `SCRY_*` prefix takes precedence
496
+
497
+ **How it works:**
498
+
499
+ 1. When a PR is opened or updated, the workflow:
500
+ - Builds the Storybook static site
501
+ - Deploys to `{project}/pr-{number}` version
502
+ - Posts a comment with the preview URL
503
+
504
+ 2. The comment includes:
505
+ - Direct link to the deployed preview
506
+ - Commit SHA and branch name
507
+ - Deployment timestamp
508
+
509
+ 3. On subsequent commits to the PR:
510
+ - The workflow redeploys to the same PR version
511
+ - Updates the existing comment with new deployment details
512
+
513
+ **Example PR Comment:**
514
+
515
+ ```markdown
516
+ ## 🚀 Storybook Preview Deployed
517
+
518
+ **Preview URL:** https://view.scrymore.com/my-project/pr-123
519
+
520
+ 📌 **Details:**
521
+ - **Commit:** `abc1234`
522
+ - **Branch:** `feature/new-component`
523
+ - **Deployed at:** Wed, 13 Nov 2024 05:00:00 GMT
524
+
525
+ > This preview will be updated automatically on each commit to this PR.
526
+ ```
527
+
528
+ #### Troubleshooting
529
+
530
+ **Problem: Workflow fails with "SCRY_PROJECT_ID not found"**
531
+ - Solution: Ensure you've added `SCRY_PROJECT_ID` as a repository variable (not secret)
532
+ - Variables and Secrets are different - make sure you're in the Variables tab
533
+
534
+ **Problem: Deployment succeeds but no comment is posted**
535
+ - Solution: Check that the workflow has `pull-requests: write` permission
536
+ - This is already configured in the workflow file but may be restricted by organization settings
537
+
538
+ **Problem: Comment is posted multiple times instead of updating**
539
+ - Solution: This is expected if the bot user changes. The workflow looks for existing comments from the same bot
540
+
541
+ **Problem: Build fails with "command not found: build-storybook"**
542
+ - Solution: Update your package.json to include the build-storybook script, or modify the workflow to use your build command
543
+
544
+ **Problem: Deployment URL returns 404**
545
+ - Solution: Verify your backend deployment service is running and the URL pattern matches your backend's routing
546
+
547
+ #### Workflow File Reference
548
+
549
+ See the complete workflow configuration: [`.github/workflows/deploy-pr-preview.yml`](.github/workflows/deploy-pr-preview.yml)
550
+
551
+ Key workflow features:
552
+ - **Triggers**: `pull_request` with types `[opened, synchronize, reopened]`
553
+ - **Permissions**: `contents: read`, `pull-requests: write`
554
+ - **Node version**: 18 (configurable in workflow)
555
+ - **Comment management**: Smart update/create logic to avoid duplicate comments
556
+
557
+ #### Cleanup
558
+
559
+ PR preview deployments remain available after the PR is closed. To implement automatic cleanup when PRs are closed, consider adding a cleanup workflow that posts a comment notifying users that the preview is no longer maintained.
560
+
561
+ A cleanup workflow template will be added in a future update.
562
+
563
+ ---
564
+
565
+ ## 📢 Notifications (Slack & Microsoft Teams)
566
+
567
+ Want to get notified when Storybook previews are deployed? You can add Slack and/or Microsoft Teams notifications to your workflows.
568
+
569
+ ### Overview
570
+
571
+ Notifications are added as extra steps in your GitHub Actions workflow. This approach gives you full control over the message format and when notifications are sent.
572
+
573
+ ```
574
+ ┌────────────────────────────────────────────────────────────────┐
575
+ │ GitHub Actions Workflow │
576
+ │ ───────────────────────────────────────────────────────────── │
577
+ │ 1. Build Storybook │
578
+ │ 2. Deploy to Scry ─────► deployment_url │
579
+ │ 3. Comment on PR (existing) │
580
+ │ 4. Notify Slack (optional) ◄───── uses deployment_url │
581
+ │ 5. Notify Teams (optional) ◄───── uses deployment_url │
582
+ └────────────────────────────────────────────────────────────────┘
583
+ ```
584
+
585
+ ### Step 1: Create Webhooks
586
+
587
+ #### Slack Webhook Setup
588
+
589
+ 1. Go to [api.slack.com/apps](https://api.slack.com/apps) → **Create New App** → **From scratch**
590
+ 2. Name your app (e.g., "Scry Storybook") and select your workspace
591
+ 3. Go to **Incoming Webhooks** (left sidebar) → Toggle **Activate Incoming Webhooks** to ON
592
+ 4. Click **Add New Webhook to Workspace** → Select the channel for notifications
593
+ 5. Copy the webhook URL (starts with `https://hooks.slack.com/services/...`)
594
+
595
+ #### Microsoft Teams Webhook Setup
596
+
597
+ 1. In Microsoft Teams, go to your channel
598
+ 2. Click the **⋯** (more options) → **Connectors** (or **Workflows** in new Teams)
599
+ 3. Search for **Incoming Webhook** → **Configure**
600
+ 4. Name it (e.g., "Scry Storybook"), optionally upload an icon
601
+ 5. Copy the webhook URL (starts with `https://outlook.office.com/webhook/...`)
602
+
603
+ ### Step 2: Add Secrets to GitHub
604
+
605
+ Add your webhook URLs as GitHub Secrets:
606
+
607
+ ```bash
608
+ # Using GitHub CLI
609
+ gh secret set SLACK_WEBHOOK_URL --body "https://hooks.slack.com/services/..."
610
+ gh secret set TEAMS_WEBHOOK_URL --body "https://outlook.office.com/webhook/..."
611
+ ```
612
+
613
+ **Or via GitHub UI:**
614
+ 1. Go to your repository → **Settings** → **Secrets and variables** → **Actions**
615
+ 2. Click **New repository secret**
616
+ 3. Add `SLACK_WEBHOOK_URL` and/or `TEAMS_WEBHOOK_URL`
617
+
618
+ ### Step 3: Add Notification Steps to Workflow
619
+
620
+ Add these steps to your `.github/workflows/deploy-pr-preview.yml` file, **after** the "Deploy Preview" step:
621
+
622
+ #### Slack Notification
623
+
624
+ ```yaml
625
+ # Add this after the "Deploy Preview" step
626
+ - name: Notify Slack
627
+ if: success()
628
+ uses: slackapi/slack-github-action@v1.26.0
629
+ with:
630
+ payload: |
631
+ {
632
+ "text": "🚀 Storybook Preview Ready",
633
+ "blocks": [
634
+ {
635
+ "type": "header",
636
+ "text": {
637
+ "type": "plain_text",
638
+ "text": "🚀 Storybook Preview Deployed"
639
+ }
640
+ },
641
+ {
642
+ "type": "section",
643
+ "fields": [
644
+ {
645
+ "type": "mrkdwn",
646
+ "text": "*PR:*\n<${{ github.event.pull_request.html_url }}|#${{ github.event.pull_request.number }}>"
647
+ },
648
+ {
649
+ "type": "mrkdwn",
650
+ "text": "*Author:*\n${{ github.event.pull_request.user.login }}"
651
+ },
652
+ {
653
+ "type": "mrkdwn",
654
+ "text": "*Branch:*\n`${{ github.head_ref }}`"
655
+ },
656
+ {
657
+ "type": "mrkdwn",
658
+ "text": "*Commit:*\n`${{ github.sha }}`"
659
+ }
660
+ ]
661
+ },
662
+ {
663
+ "type": "section",
664
+ "text": {
665
+ "type": "mrkdwn",
666
+ "text": "*Title:* ${{ github.event.pull_request.title }}"
667
+ }
668
+ },
669
+ {
670
+ "type": "actions",
671
+ "elements": [
672
+ {
673
+ "type": "button",
674
+ "text": {
675
+ "type": "plain_text",
676
+ "text": "📖 View Storybook"
677
+ },
678
+ "url": "${{ steps.deploy.outputs.deployment_url }}",
679
+ "style": "primary"
680
+ },
681
+ {
682
+ "type": "button",
683
+ "text": {
684
+ "type": "plain_text",
685
+ "text": "View PR"
686
+ },
687
+ "url": "${{ github.event.pull_request.html_url }}"
688
+ }
689
+ ]
690
+ }
691
+ ]
692
+ }
693
+ env:
694
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
695
+ ```
696
+
697
+ #### Microsoft Teams Notification
698
+
699
+ ```yaml
700
+ # Add this after the "Deploy Preview" step
701
+ - name: Notify Teams
702
+ if: success()
703
+ run: |
704
+ curl -H "Content-Type: application/json" -d '{
705
+ "@type": "MessageCard",
706
+ "@context": "http://schema.org/extensions",
707
+ "themeColor": "0076D7",
708
+ "summary": "Storybook Preview Deployed",
709
+ "sections": [{
710
+ "activityTitle": "🚀 Storybook Preview Deployed",
711
+ "activitySubtitle": "PR #${{ github.event.pull_request.number }} by ${{ github.event.pull_request.user.login }}",
712
+ "facts": [{
713
+ "name": "Branch",
714
+ "value": "${{ github.head_ref }}"
715
+ }, {
716
+ "name": "Commit",
717
+ "value": "${{ github.sha }}"
718
+ }, {
719
+ "name": "Title",
720
+ "value": "${{ github.event.pull_request.title }}"
721
+ }],
722
+ "markdown": true
723
+ }],
724
+ "potentialAction": [{
725
+ "@type": "OpenUri",
726
+ "name": "View Storybook",
727
+ "targets": [{
728
+ "os": "default",
729
+ "uri": "${{ steps.deploy.outputs.deployment_url }}"
730
+ }]
731
+ }, {
732
+ "@type": "OpenUri",
733
+ "name": "View PR",
734
+ "targets": [{
735
+ "os": "default",
736
+ "uri": "${{ github.event.pull_request.html_url }}"
737
+ }]
738
+ }]
739
+ }' "${{ secrets.TEAMS_WEBHOOK_URL }}"
740
+ ```
741
+
742
+ ### Optional: Toggle Notifications with Variables
743
+
744
+ Use GitHub Variables to enable/disable notifications without editing the workflow:
745
+
746
+ ```bash
747
+ # Enable notifications
748
+ gh variable set ENABLE_SLACK_NOTIFICATIONS --body "true"
749
+ gh variable set ENABLE_TEAMS_NOTIFICATIONS --body "true"
750
+ ```
751
+
752
+ Then update the `if` condition in the notification steps:
753
+
754
+ ```yaml
755
+ - name: Notify Slack
756
+ if: success() && vars.ENABLE_SLACK_NOTIFICATIONS == 'true'
757
+ # ... rest of step
758
+ ```
759
+
760
+ ### Notification Variables Reference
761
+
762
+ | Name | Type | Description |
763
+ |------|------|-------------|
764
+ | `SLACK_WEBHOOK_URL` | Secret | Your Slack incoming webhook URL |
765
+ | `TEAMS_WEBHOOK_URL` | Secret | Your Microsoft Teams incoming webhook URL |
766
+ | `ENABLE_SLACK_NOTIFICATIONS` | Variable (optional) | Set to `true` to enable Slack notifications |
767
+ | `ENABLE_TEAMS_NOTIFICATIONS` | Variable (optional) | Set to `true` to enable Teams notifications |
768
+
769
+ ### What the Notifications Look Like
770
+
771
+ **Slack:**
772
+ ```
773
+ ┌───────────────────────────────────────────────┐
774
+ │ 🚀 Storybook Preview Deployed │
775
+ ├───────────────────────────────────────────────┤
776
+ │ PR: #42 Author: @developer │
777
+ │ Branch: feature/new Commit: abc1234 │
778
+ ├───────────────────────────────────────────────┤
779
+ │ Title: Add new button component │
780
+ │ │
781
+ │ [📖 View Storybook] [View PR] │
782
+ └───────────────────────────────────────────────┘
783
+ ```
784
+
785
+ **Teams:**
786
+ ```
787
+ ┌───────────────────────────────────────────────┐
788
+ │ 🚀 Storybook Preview Deployed │
789
+ │ PR #42 by developer │
790
+ ├───────────────────────────────────────────────┤
791
+ │ Branch: feature/new-button │
792
+ │ Commit: abc1234 │
793
+ │ Title: Add new button component │
794
+ ├───────────────────────────────────────────────┤
795
+ │ [View Storybook] [View PR] │
796
+ └───────────────────────────────────────────────┘
797
+ ```
798
+
799
+ ### Troubleshooting Notifications
800
+
801
+ **Problem: Slack notification fails with "channel_not_found"**
802
+ - Solution: Regenerate the webhook URL and ensure the Slack app is still installed in your workspace
803
+
804
+ **Problem: Teams notification shows as plain text**
805
+ - Solution: Ensure the webhook is an "Incoming Webhook" connector, not a Power Automate flow
806
+
807
+ **Problem: Notification doesn't include buttons**
808
+ - Solution: Some webhook configurations may not support interactive elements. The links will still appear as text.
809
+
810
+ ---
811
+
812
+ ## 🔧 Troubleshooting the Init Command
813
+
814
+ ### Command fails with "Not a git repository"
815
+
816
+ **Solution:** Initialize git first:
817
+ ```bash
818
+ git init
819
+ git remote add origin https://github.com/your-username/your-repo.git
820
+ ```
821
+
822
+ ### GitHub CLI setup fails
823
+
824
+ **Solution:** Install GitHub CLI and authenticate:
825
+ ```bash
826
+ # macOS
827
+ brew install gh
828
+
829
+ # Linux
830
+ sudo apt install gh # Ubuntu/Debian
831
+ sudo dnf install gh # Fedora
832
+
833
+ # Windows
834
+ winget install --id GitHub.cli
835
+
836
+ # Then authenticate
837
+ gh auth login
838
+ ```
839
+
840
+ Or skip GitHub CLI setup and set variables manually:
841
+ ```bash
842
+ npx @scry/storybook-deployer init --projectId xxx --apiKey yyy --skip-gh-setup
843
+ ```
844
+
845
+ Then manually add variables in GitHub Settings → Secrets and variables → Actions.
846
+
847
+ ### Git push fails with "Authentication failed"
848
+
849
+ **Solution:** Configure Git credentials:
850
+ ```bash
851
+ # For HTTPS
852
+ gh auth setup-git
853
+
854
+ # Or use SSH
855
+ git remote set-url origin git@github.com:your-username/your-repo.git
856
+ ```
857
+
858
+ ### "No build command found" warning
859
+
860
+ **Solution:** Add a build script to your `package.json`:
861
+ ```json
862
+ {
863
+ "scripts": {
864
+ "build-storybook": "storybook build"
865
+ }
866
+ }
867
+ ```
868
+
869
+ ### Want to customize the generated workflows?
870
+
871
+ After running `init`, you can edit:
872
+ - `.github/workflows/deploy-storybook.yml` - Main deployment
873
+ - `.github/workflows/deploy-pr-preview.yml` - PR previews
874
+
875
+ Then commit and push your changes:
876
+ ```bash
877
+ git add .github/
878
+ git commit -m "Customize Storybook workflows"
879
+ git push
880
+ ```
881
+
882
+ ---
883
+
884
+ ## 🆘 Support
885
+
886
+ Need help?
887
+ - 📖 [Documentation](https://github.com/epinnock/scry-node)
888
+ - 🐛 [Report an issue](https://github.com/epinnock/scry-node/issues)
889
+ - 💬 [Discussions](https://github.com/epinnock/scry-node/discussions)