@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/LICENSE +21 -0
- package/README.md +889 -0
- package/bin/cli.js +351 -0
- package/lib/analysis.js +445 -0
- package/lib/apiClient.js +130 -0
- package/lib/archive.js +31 -0
- package/lib/archiveUtils.js +95 -0
- package/lib/config-store.js +47 -0
- package/lib/config.js +217 -0
- package/lib/errors.js +49 -0
- package/lib/init.js +478 -0
- package/lib/logger.js +48 -0
- package/lib/screencap.js +55 -0
- package/lib/templates.js +226 -0
- package/package.json +61 -0
- package/scripts/postinstall.js +7 -0
package/lib/templates.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate GitHub Actions workflow templates
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get package manager setup action
|
|
7
|
+
*/
|
|
8
|
+
function getPackageManagerSetup(packageManager) {
|
|
9
|
+
switch (packageManager) {
|
|
10
|
+
case 'pnpm':
|
|
11
|
+
return ` - name: Setup pnpm
|
|
12
|
+
uses: pnpm/action-setup@v2
|
|
13
|
+
with:
|
|
14
|
+
version: 8
|
|
15
|
+
`;
|
|
16
|
+
case 'yarn':
|
|
17
|
+
return ''; // Yarn is supported by default in setup-node
|
|
18
|
+
case 'bun':
|
|
19
|
+
return ` - name: Setup Bun
|
|
20
|
+
uses: oven-sh/setup-bun@v1
|
|
21
|
+
`;
|
|
22
|
+
default:
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get install command for package manager
|
|
29
|
+
* All commands handle missing lockfiles gracefully
|
|
30
|
+
*/
|
|
31
|
+
function getInstallCommand(packageManager) {
|
|
32
|
+
switch (packageManager) {
|
|
33
|
+
case 'npm':
|
|
34
|
+
// Use npm install which works with or without package-lock.json
|
|
35
|
+
return 'npm install';
|
|
36
|
+
case 'pnpm':
|
|
37
|
+
// Just use pnpm install - it works with or without lockfile
|
|
38
|
+
// We set CI=false to prevent pnpm from auto-enabling frozen-lockfile
|
|
39
|
+
return 'CI=false pnpm install';
|
|
40
|
+
case 'yarn':
|
|
41
|
+
return 'yarn install';
|
|
42
|
+
case 'bun':
|
|
43
|
+
return 'bun install';
|
|
44
|
+
default:
|
|
45
|
+
return 'npm install';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get cache value for package manager
|
|
51
|
+
*/
|
|
52
|
+
function getCacheValue(packageManager) {
|
|
53
|
+
if (packageManager === 'npm') {
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
return ` cache: '${packageManager}'`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Generate main deployment workflow
|
|
61
|
+
*/
|
|
62
|
+
function generateMainWorkflow(projectId, apiUrl, packageManager, buildCmd) {
|
|
63
|
+
const pmSetup = getPackageManagerSetup(packageManager);
|
|
64
|
+
const installCmd = getInstallCommand(packageManager);
|
|
65
|
+
const cache = getCacheValue(packageManager);
|
|
66
|
+
const runCmd = packageManager === 'npm' ? `npm run ${buildCmd}` : `${packageManager} run ${buildCmd}`;
|
|
67
|
+
|
|
68
|
+
return `# Auto-generated by Scry Storybook Deployer
|
|
69
|
+
# Deploy Storybook to production on push to main branch
|
|
70
|
+
|
|
71
|
+
name: Deploy Storybook
|
|
72
|
+
|
|
73
|
+
on:
|
|
74
|
+
push:
|
|
75
|
+
branches: [main, master]
|
|
76
|
+
|
|
77
|
+
jobs:
|
|
78
|
+
deploy:
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
|
|
81
|
+
steps:
|
|
82
|
+
- name: Checkout code
|
|
83
|
+
uses: actions/checkout@v4
|
|
84
|
+
|
|
85
|
+
${pmSetup} - name: Setup Node.js
|
|
86
|
+
uses: actions/setup-node@v4
|
|
87
|
+
with:
|
|
88
|
+
node-version: '20'
|
|
89
|
+
${cache}
|
|
90
|
+
|
|
91
|
+
- name: Install dependencies
|
|
92
|
+
run: ${installCmd}
|
|
93
|
+
|
|
94
|
+
- name: Build Storybook
|
|
95
|
+
run: ${runCmd}
|
|
96
|
+
|
|
97
|
+
- name: Deploy to Scry
|
|
98
|
+
run: npx @scrymore/scry-deployer --dir ./storybook-static
|
|
99
|
+
env:
|
|
100
|
+
STORYBOOK_DEPLOYER_API_URL: \${{ vars.SCRY_API_URL }}
|
|
101
|
+
STORYBOOK_DEPLOYER_PROJECT: \${{ vars.SCRY_PROJECT_ID }}
|
|
102
|
+
STORYBOOK_DEPLOYER_API_KEY: \${{ secrets.SCRY_API_KEY }}
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Generate PR preview workflow
|
|
108
|
+
*/
|
|
109
|
+
function generatePRWorkflow(projectId, apiUrl, packageManager, buildCmd) {
|
|
110
|
+
const pmSetup = getPackageManagerSetup(packageManager);
|
|
111
|
+
const installCmd = getInstallCommand(packageManager);
|
|
112
|
+
const cache = getCacheValue(packageManager);
|
|
113
|
+
const runCmd = packageManager === 'npm' ? `npm run ${buildCmd}` : `${packageManager} run ${buildCmd}`;
|
|
114
|
+
|
|
115
|
+
return `# Auto-generated by Scry Storybook Deployer
|
|
116
|
+
# Deploy Storybook preview for pull requests
|
|
117
|
+
|
|
118
|
+
name: Deploy Storybook PR Preview
|
|
119
|
+
|
|
120
|
+
on:
|
|
121
|
+
pull_request:
|
|
122
|
+
types: [opened, synchronize, reopened]
|
|
123
|
+
|
|
124
|
+
jobs:
|
|
125
|
+
deploy-preview:
|
|
126
|
+
runs-on: ubuntu-latest
|
|
127
|
+
|
|
128
|
+
permissions:
|
|
129
|
+
contents: read
|
|
130
|
+
pull-requests: write
|
|
131
|
+
|
|
132
|
+
steps:
|
|
133
|
+
- name: Checkout code
|
|
134
|
+
uses: actions/checkout@v4
|
|
135
|
+
|
|
136
|
+
${pmSetup} - name: Setup Node.js
|
|
137
|
+
uses: actions/setup-node@v4
|
|
138
|
+
with:
|
|
139
|
+
node-version: '20'
|
|
140
|
+
${cache}
|
|
141
|
+
|
|
142
|
+
- name: Install dependencies
|
|
143
|
+
run: ${installCmd}
|
|
144
|
+
|
|
145
|
+
- name: Build Storybook
|
|
146
|
+
run: ${runCmd}
|
|
147
|
+
|
|
148
|
+
- name: Deploy Preview
|
|
149
|
+
id: deploy
|
|
150
|
+
run: |
|
|
151
|
+
# Deploy with PR-specific version
|
|
152
|
+
npx @scrymore/scry-deployer \\
|
|
153
|
+
--dir ./storybook-static \\
|
|
154
|
+
--version pr-\${{ github.event.pull_request.number }}
|
|
155
|
+
|
|
156
|
+
# Construct deployment URL
|
|
157
|
+
PROJECT_ID="\${{ vars.SCRY_PROJECT_ID }}"
|
|
158
|
+
API_URL="\${{ vars.SCRY_API_URL }}"
|
|
159
|
+
DEPLOY_URL="\${API_URL}/\${PROJECT_ID}/pr-\${{ github.event.pull_request.number }}"
|
|
160
|
+
echo "deployment_url=\$DEPLOY_URL" >> $GITHUB_OUTPUT
|
|
161
|
+
env:
|
|
162
|
+
STORYBOOK_DEPLOYER_API_URL: \${{ vars.SCRY_API_URL }}
|
|
163
|
+
STORYBOOK_DEPLOYER_PROJECT: \${{ vars.SCRY_PROJECT_ID }}
|
|
164
|
+
STORYBOOK_DEPLOYER_API_KEY: \${{ secrets.SCRY_API_KEY }}
|
|
165
|
+
|
|
166
|
+
- name: Comment on PR
|
|
167
|
+
uses: actions/github-script@v7
|
|
168
|
+
with:
|
|
169
|
+
script: |
|
|
170
|
+
const deploymentUrl = '\${{ steps.deploy.outputs.deployment_url }}';
|
|
171
|
+
const prNumber = context.issue.number;
|
|
172
|
+
const commitSha = context.payload.pull_request.head.sha.substring(0, 7);
|
|
173
|
+
const branch = '\${{ github.event.pull_request.head.ref }}';
|
|
174
|
+
const deployedAt = new Date().toUTCString();
|
|
175
|
+
|
|
176
|
+
const commentBody = [
|
|
177
|
+
'## 🚀 Storybook Preview Deployed',
|
|
178
|
+
'',
|
|
179
|
+
'**Preview URL:** ' + deploymentUrl,
|
|
180
|
+
'',
|
|
181
|
+
'📌 **Details:**',
|
|
182
|
+
'- **Commit:** ' + commitSha,
|
|
183
|
+
'- **Branch:** ' + branch,
|
|
184
|
+
'- **Deployed at:** ' + deployedAt,
|
|
185
|
+
'',
|
|
186
|
+
'> This preview updates automatically on each commit to this PR.'
|
|
187
|
+
].join('\\n');
|
|
188
|
+
|
|
189
|
+
// Check if a comment from this bot already exists
|
|
190
|
+
const { data: comments } = await github.rest.issues.listComments({
|
|
191
|
+
owner: context.repo.owner,
|
|
192
|
+
repo: context.repo.repo,
|
|
193
|
+
issue_number: prNumber,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const botComment = comments.find(comment =>
|
|
197
|
+
comment.user.type === 'Bot' &&
|
|
198
|
+
comment.body.includes('🚀 Storybook Preview Deployed')
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
if (botComment) {
|
|
202
|
+
// Update existing comment
|
|
203
|
+
await github.rest.issues.updateComment({
|
|
204
|
+
owner: context.repo.owner,
|
|
205
|
+
repo: context.repo.repo,
|
|
206
|
+
comment_id: botComment.id,
|
|
207
|
+
body: commentBody
|
|
208
|
+
});
|
|
209
|
+
console.log('Updated existing PR comment');
|
|
210
|
+
} else {
|
|
211
|
+
// Create new comment
|
|
212
|
+
await github.rest.issues.createComment({
|
|
213
|
+
owner: context.repo.owner,
|
|
214
|
+
repo: context.repo.repo,
|
|
215
|
+
issue_number: prNumber,
|
|
216
|
+
body: commentBody
|
|
217
|
+
});
|
|
218
|
+
console.log('Created new PR comment');
|
|
219
|
+
}
|
|
220
|
+
`;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
module.exports = {
|
|
224
|
+
generateMainWorkflow,
|
|
225
|
+
generatePRWorkflow
|
|
226
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@scrymore/scry-deployer",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "A CLI to automate the deployment of Storybook static builds.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"scry-deployer": "bin/cli.js",
|
|
8
|
+
"scry": "bin/cli.js",
|
|
9
|
+
"storybook-deploy": "bin/cli.js",
|
|
10
|
+
"storybook-deploy-setup": "scripts/postinstall.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin",
|
|
14
|
+
"lib",
|
|
15
|
+
"scripts"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"storybook",
|
|
19
|
+
"deploy",
|
|
20
|
+
"cli",
|
|
21
|
+
"scry",
|
|
22
|
+
"scrymore"
|
|
23
|
+
],
|
|
24
|
+
"author": "Scrymore",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"type": "commonjs",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/epinnock/scry-node.git"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public",
|
|
33
|
+
"registry": "https://registry.npmjs.org/"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"archiver": "^7.0.1",
|
|
40
|
+
"axios": "^1.12.2",
|
|
41
|
+
"chalk": "^4.1.2",
|
|
42
|
+
"commander": "^11.1.0",
|
|
43
|
+
"form-data": "^4.0.0",
|
|
44
|
+
"inquirer": "^8.2.6",
|
|
45
|
+
"open": "^8.4.2",
|
|
46
|
+
"storycap": "^4.2.0",
|
|
47
|
+
"yargs": "^17.7.2"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@changesets/changelog-github": "^0.5.2",
|
|
51
|
+
"@changesets/cli": "^2.29.8",
|
|
52
|
+
"dotenv": "^17.2.2"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
56
|
+
"postinstall": "node scripts/postinstall.js",
|
|
57
|
+
"changeset": "changeset",
|
|
58
|
+
"version": "changeset version",
|
|
59
|
+
"release": "changeset publish"
|
|
60
|
+
}
|
|
61
|
+
}
|