@sembix/cli 1.1.0 → 1.2.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/.env.example +7 -0
- package/README.md +161 -8
- package/dist/__tests__/config-schema.test.js +1 -1
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +75 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/integration/configure.test.d.ts +2 -0
- package/dist/__tests__/integration/configure.test.d.ts.map +1 -0
- package/dist/__tests__/integration/configure.test.js +247 -0
- package/dist/__tests__/integration/configure.test.js.map +1 -0
- package/dist/commands/__tests__/configure.test.d.ts +2 -0
- package/dist/commands/__tests__/configure.test.d.ts.map +1 -0
- package/dist/commands/__tests__/configure.test.js +229 -0
- package/dist/commands/__tests__/configure.test.js.map +1 -0
- package/dist/commands/configure.d.ts +6 -0
- package/dist/commands/configure.d.ts.map +1 -0
- package/dist/commands/configure.js +90 -0
- package/dist/commands/configure.js.map +1 -0
- package/dist/config-schema.d.ts +31 -335
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -3
- package/dist/config.js.map +1 -1
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -1
- package/dist/prompts/__tests__/environment-setup.test.d.ts +2 -0
- package/dist/prompts/__tests__/environment-setup.test.d.ts.map +1 -0
- package/dist/prompts/__tests__/environment-setup.test.js +206 -0
- package/dist/prompts/__tests__/environment-setup.test.js.map +1 -0
- package/dist/prompts/__tests__/hub-integration.test.d.ts +2 -0
- package/dist/prompts/__tests__/hub-integration.test.d.ts.map +1 -0
- package/dist/prompts/__tests__/hub-integration.test.js +126 -0
- package/dist/prompts/__tests__/hub-integration.test.js.map +1 -0
- package/dist/prompts/hub-integration-step.js +3 -3
- package/dist/prompts/hub-integration.js +3 -3
- package/dist/sembix-cli-1.2.1.tgz +0 -0
- package/dist/utils/__tests__/config-file.test.d.ts +2 -0
- package/dist/utils/__tests__/config-file.test.d.ts.map +1 -0
- package/dist/utils/__tests__/config-file.test.js +218 -0
- package/dist/utils/__tests__/config-file.test.js.map +1 -0
- package/dist/utils/config-file.d.ts +23 -0
- package/dist/utils/config-file.d.ts.map +1 -0
- package/dist/utils/config-file.js +100 -0
- package/dist/utils/config-file.js.map +1 -0
- package/dist/utils/config-loader.js +7 -7
- package/package.json +24 -24
- package/dist/sembix-cli-1.1.0.tgz +0 -0
package/.env.example
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# Sembix CLI Environment Variables
|
|
2
|
+
#
|
|
3
|
+
# RECOMMENDED: Use 'sembix configure' instead of this .env file
|
|
4
|
+
# This will securely store your credentials in ~/.sembix/config
|
|
5
|
+
#
|
|
6
|
+
# Run: sembix configure
|
|
7
|
+
|
|
1
8
|
# GitHub Personal Access Token
|
|
2
9
|
# Required scopes: repo, workflow
|
|
3
10
|
GITHUB_TOKEN=ghp_your_token_here
|
package/README.md
CHANGED
|
@@ -2,6 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
A terminal-based CLI tool for managing Sembix products. An intuitive command-line interface designed for technical users.
|
|
4
4
|
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Features](#features)
|
|
8
|
+
- [Prerequisites](#prerequisites)
|
|
9
|
+
- [Deployment Process](#deployment-process)
|
|
10
|
+
- [Installation](#installation)
|
|
11
|
+
- [Configuration](#configuration)
|
|
12
|
+
- [Option 1: Interactive Configuration (Recommended)](#option-1-interactive-configuration-recommended)
|
|
13
|
+
- [Option 2: Environment Variables (.env file)](#option-2-environment-variables-env-file)
|
|
14
|
+
- [Option 3: Config File (Recommended for Automation)](#option-3-config-file-recommended-for-automation)
|
|
15
|
+
- [Creating a GitHub Token](#creating-a-github-token)
|
|
16
|
+
- [Credential Priority](#credential-priority)
|
|
17
|
+
- [Usage](#usage)
|
|
18
|
+
- [Quick Start](#quick-start)
|
|
19
|
+
- [Example: Complete First-Time Setup](#example-complete-first-time-setup)
|
|
20
|
+
- [Commands](#commands)
|
|
21
|
+
- [`sembix configure`](#sembix-configure)
|
|
22
|
+
- [`sembix studio create`](#sembix-studio-create)
|
|
23
|
+
- [`sembix studio update`](#sembix-studio-update)
|
|
24
|
+
- [`sembix studio add-hub`](#sembix-studio-add-hub)
|
|
25
|
+
- [`sembix studio list`](#sembix-studio-list)
|
|
26
|
+
- [Workflow](#workflow)
|
|
27
|
+
- [Configuration Priority](#configuration-priority)
|
|
28
|
+
- [Config File Reference](#config-file-reference)
|
|
29
|
+
- [Use Cases](#use-cases)
|
|
30
|
+
- [Development](#development)
|
|
31
|
+
- [Troubleshooting](#troubleshooting)
|
|
32
|
+
- [Advanced Topics](#advanced-topics)
|
|
33
|
+
- [License](#license)
|
|
34
|
+
- [Support](#support)
|
|
35
|
+
- [See Also](#see-also)
|
|
36
|
+
|
|
5
37
|
## Features
|
|
6
38
|
|
|
7
39
|
- 🚀 **Interactive Setup** - Guided prompts for environment configuration with detailed explanations
|
|
@@ -85,9 +117,23 @@ npm run dev -- studio create
|
|
|
85
117
|
|
|
86
118
|
## Configuration
|
|
87
119
|
|
|
88
|
-
### Option 1:
|
|
120
|
+
### Option 1: Interactive Configuration (Recommended)
|
|
121
|
+
|
|
122
|
+
The easiest way to get started is using the interactive configuration command:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
sembix configure
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This will prompt you for:
|
|
129
|
+
- **GitHub Personal Access Token** (required)
|
|
130
|
+
- **Default GitHub Organization** (optional)
|
|
89
131
|
|
|
90
|
-
|
|
132
|
+
Your credentials will be securely stored in `~/.sembix/config` with restricted file permissions (0600).
|
|
133
|
+
|
|
134
|
+
### Option 2: Environment Variables (.env file)
|
|
135
|
+
|
|
136
|
+
Alternatively, create a `.env` file in the project root directory:
|
|
91
137
|
|
|
92
138
|
```bash
|
|
93
139
|
cp .env.example .env
|
|
@@ -103,7 +149,7 @@ GITHUB_TOKEN=ghp_your_token_here
|
|
|
103
149
|
DEFAULT_GITHUB_ORG=your-org
|
|
104
150
|
```
|
|
105
151
|
|
|
106
|
-
### Option
|
|
152
|
+
### Option 3: Config File (Recommended for Automation)
|
|
107
153
|
|
|
108
154
|
Create a YAML config file for your environment:
|
|
109
155
|
|
|
@@ -136,13 +182,35 @@ See [`config.example.yaml`](./config.example.yaml) for a complete configuration
|
|
|
136
182
|
- ✅ `repo` (all sub-scopes)
|
|
137
183
|
- ✅ `workflow`
|
|
138
184
|
4. Generate and copy the token
|
|
139
|
-
5.
|
|
185
|
+
5. Run `sembix configure` to store it securely, or add to `.env` file, or use `--token` flag
|
|
186
|
+
|
|
187
|
+
### Credential Priority
|
|
188
|
+
|
|
189
|
+
The CLI checks for credentials in this order (highest to lowest priority):
|
|
190
|
+
1. `--token` flag
|
|
191
|
+
2. `GITHUB_TOKEN` environment variable
|
|
192
|
+
3. `~/.sembix/config` (created by `sembix configure`)
|
|
193
|
+
4. Project `.env` file
|
|
140
194
|
|
|
141
195
|
## Usage
|
|
142
196
|
|
|
143
197
|
### Quick Start
|
|
144
198
|
|
|
145
|
-
|
|
199
|
+
**Step 1: Configure credentials (first time only)**
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
sembix configure
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
This interactive command will prompt you for:
|
|
206
|
+
- GitHub Personal Access Token
|
|
207
|
+
- Default GitHub organization (optional)
|
|
208
|
+
|
|
209
|
+
Your credentials are saved securely to `~/.sembix/config`.
|
|
210
|
+
|
|
211
|
+
**Step 2: Create your environment**
|
|
212
|
+
|
|
213
|
+
For a complete deployment, follow the **two-phased process**:
|
|
146
214
|
|
|
147
215
|
```bash
|
|
148
216
|
# PHASE 1: Bootstrap deployment
|
|
@@ -157,6 +225,8 @@ sembix studio add-hub <environment>
|
|
|
157
225
|
# → Studio environment fully operational
|
|
158
226
|
```
|
|
159
227
|
|
|
228
|
+
See the [Deployment Process](#deployment-process) section above for detailed explanation.
|
|
229
|
+
|
|
160
230
|
**Alternative workflows:**
|
|
161
231
|
|
|
162
232
|
```bash
|
|
@@ -176,8 +246,85 @@ sembix studio create production \
|
|
|
176
246
|
# ... (all other flags)
|
|
177
247
|
```
|
|
178
248
|
|
|
249
|
+
### Example: Complete First-Time Setup
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# 1. Configure credentials
|
|
253
|
+
$ sembix configure
|
|
254
|
+
GitHub Personal Access Token: ****
|
|
255
|
+
Default GitHub Organization (optional): acme-corp
|
|
256
|
+
✓ Configuration saved successfully!
|
|
257
|
+
|
|
258
|
+
# 2. Create environment interactively
|
|
259
|
+
$ sembix studio create
|
|
260
|
+
? Select deployment repository: acme-corp/sembix-deployment
|
|
261
|
+
? Environment name: production
|
|
262
|
+
? AWS Account ID: 123456789012
|
|
263
|
+
... [continues with prompts]
|
|
264
|
+
✓ Environment created successfully!
|
|
265
|
+
|
|
266
|
+
# 3. Deploy via GitHub Actions (in browser)
|
|
267
|
+
# → Go to GitHub Actions
|
|
268
|
+
# → Run workflow for "production" environment
|
|
269
|
+
# → Wait for deployment
|
|
270
|
+
# → Copy Hub role ARNs from output
|
|
271
|
+
|
|
272
|
+
# 4. Add Hub integration
|
|
273
|
+
$ sembix studio add-hub production
|
|
274
|
+
? Hub Engine Execution Role ARN: arn:aws:iam::999999999999:role/hub-engine
|
|
275
|
+
... [continues with prompts]
|
|
276
|
+
✓ Hub integration configured!
|
|
277
|
+
|
|
278
|
+
# 5. Deploy again via GitHub Actions
|
|
279
|
+
# → Run workflow again
|
|
280
|
+
# → Studio is now fully operational!
|
|
281
|
+
```
|
|
282
|
+
|
|
179
283
|
## Commands
|
|
180
284
|
|
|
285
|
+
### `sembix configure`
|
|
286
|
+
|
|
287
|
+
Configure Sembix CLI credentials and settings interactively.
|
|
288
|
+
|
|
289
|
+
**Syntax:**
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
sembix configure
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**What it does:**
|
|
296
|
+
1. Prompts for your GitHub Personal Access Token (with validation)
|
|
297
|
+
2. Prompts for your default GitHub organization (optional)
|
|
298
|
+
3. Saves configuration securely to `~/.sembix/config` with file permissions 0600
|
|
299
|
+
|
|
300
|
+
**When to use:**
|
|
301
|
+
- First time setup (recommended for all users)
|
|
302
|
+
- Updating your GitHub token when it expires
|
|
303
|
+
- Changing your default organization
|
|
304
|
+
|
|
305
|
+
**Example:**
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
$ sembix configure
|
|
309
|
+
|
|
310
|
+
Configure Sembix CLI
|
|
311
|
+
|
|
312
|
+
This will store your configuration in:
|
|
313
|
+
~/.sembix/config
|
|
314
|
+
|
|
315
|
+
? GitHub Personal Access Token: ****
|
|
316
|
+
? Default GitHub Organization (optional): acme-corp
|
|
317
|
+
|
|
318
|
+
✓ Configuration saved successfully!
|
|
319
|
+
|
|
320
|
+
Your credentials are stored securely in:
|
|
321
|
+
~/.sembix/config
|
|
322
|
+
|
|
323
|
+
You can now run Sembix commands without the --token flag.
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
181
328
|
### `sembix studio create`
|
|
182
329
|
|
|
183
330
|
Create a new Sembix Studio environment with complete configuration.
|
|
@@ -701,15 +848,21 @@ studio
|
|
|
701
848
|
|
|
702
849
|
## Troubleshooting
|
|
703
850
|
|
|
704
|
-
### "
|
|
851
|
+
### "GitHub token is required"
|
|
852
|
+
|
|
853
|
+
If you see this error, you need to configure your GitHub token. The easiest method is:
|
|
854
|
+
|
|
855
|
+
```bash
|
|
856
|
+
sembix configure
|
|
857
|
+
```
|
|
705
858
|
|
|
706
|
-
|
|
859
|
+
Alternatively, create a `.env` file:
|
|
707
860
|
|
|
708
861
|
```env
|
|
709
862
|
GITHUB_TOKEN=ghp_your_token_here
|
|
710
863
|
```
|
|
711
864
|
|
|
712
|
-
Or pass the token via CLI:
|
|
865
|
+
Or pass the token directly via CLI:
|
|
713
866
|
|
|
714
867
|
```bash
|
|
715
868
|
sembix studio create --token ghp_your_token_here
|
|
@@ -248,7 +248,7 @@ describe('config-schema', () => {
|
|
|
248
248
|
};
|
|
249
249
|
const result = configFileSchema.safeParse(config);
|
|
250
250
|
if (!result.success) {
|
|
251
|
-
console.log('Validation errors:', result.error.
|
|
251
|
+
console.log('Validation errors:', result.error.issues);
|
|
252
252
|
}
|
|
253
253
|
expect(result.success).toBe(true);
|
|
254
254
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
// Must mock BEFORE importing config module
|
|
3
|
+
vi.mock('../utils/config-file.js', () => ({
|
|
4
|
+
readConfig: vi.fn().mockResolvedValue({}),
|
|
5
|
+
getConfigPath: vi.fn().mockReturnValue('/home/testuser/.sembix/config'),
|
|
6
|
+
}));
|
|
7
|
+
// Mock dotenv
|
|
8
|
+
vi.mock('dotenv', () => ({
|
|
9
|
+
default: {
|
|
10
|
+
config: vi.fn(),
|
|
11
|
+
},
|
|
12
|
+
}));
|
|
13
|
+
describe('config', () => {
|
|
14
|
+
describe('validateConfig', () => {
|
|
15
|
+
let originalGithubToken;
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
// Save and clear GITHUB_TOKEN
|
|
18
|
+
originalGithubToken = process.env.GITHUB_TOKEN;
|
|
19
|
+
delete process.env.GITHUB_TOKEN;
|
|
20
|
+
});
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
// Restore GITHUB_TOKEN
|
|
23
|
+
if (originalGithubToken !== undefined) {
|
|
24
|
+
process.env.GITHUB_TOKEN = originalGithubToken;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
it('should throw error when no token is configured', async () => {
|
|
28
|
+
// Re-import to get fresh module with mocked env
|
|
29
|
+
const { validateConfig } = await import('../config.js');
|
|
30
|
+
try {
|
|
31
|
+
validateConfig();
|
|
32
|
+
expect.fail('Should have thrown an error');
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
expect(error.message).toContain('GitHub token is required');
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
it('should include all configuration methods in error message', async () => {
|
|
40
|
+
const { validateConfig } = await import('../config.js');
|
|
41
|
+
try {
|
|
42
|
+
validateConfig();
|
|
43
|
+
expect.fail('Should have thrown an error');
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
expect(error.message).toContain('Run: sembix configure');
|
|
48
|
+
expect(error.message).toContain('Set GITHUB_TOKEN environment variable');
|
|
49
|
+
expect(error.message).toContain('Pass --token flag');
|
|
50
|
+
expect(error.message).toContain('Create a .env file with GITHUB_TOKEN');
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
it('should include config file location in error message', async () => {
|
|
54
|
+
const { validateConfig } = await import('../config.js');
|
|
55
|
+
try {
|
|
56
|
+
validateConfig();
|
|
57
|
+
expect.fail('Should have thrown an error');
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
expect(error.message).toContain('.sembix/config');
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
it('should not throw when token is present', async () => {
|
|
65
|
+
// Set token before importing
|
|
66
|
+
process.env.GITHUB_TOKEN = 'ghp_test_token';
|
|
67
|
+
// Reset modules to force fresh import
|
|
68
|
+
vi.resetModules();
|
|
69
|
+
// Re-import with token set
|
|
70
|
+
const { validateConfig } = await import('../config.js');
|
|
71
|
+
expect(() => validateConfig()).not.toThrow();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEzE,2CAA2C;AAC3C,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAAC,CAAC;IACxC,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;IACzC,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,+BAA+B,CAAC;CACxE,CAAC,CAAC,CAAC;AAEJ,cAAc;AACd,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IACvB,OAAO,EAAE;QACP,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE;KAChB;CACF,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,IAAI,mBAAuC,CAAC;QAE5C,UAAU,CAAC,GAAG,EAAE;YACd,8BAA8B;YAC9B,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;YAC/C,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,GAAG,EAAE;YACb,uBAAuB;YACvB,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;gBACtC,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,mBAAmB,CAAC;YACjD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,gDAAgD;YAChD,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAExD,IAAI,CAAC;gBACH,cAAc,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;gBAC7C,8DAA8D;YAC9D,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YACzE,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAExD,IAAI,CAAC;gBACH,cAAc,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;gBAC7C,8DAA8D;YAC9D,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;gBACzD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAC;gBACzE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;gBACrD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAExD,IAAI,CAAC;gBACH,cAAc,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;gBAC7C,8DAA8D;YAC9D,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YACpD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACtD,6BAA6B;YAC7B,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,gBAAgB,CAAC;YAE5C,sCAAsC;YACtC,EAAE,CAAC,YAAY,EAAE,CAAC;YAElB,2BAA2B;YAC3B,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAExD,MAAM,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/integration/configure.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { configureCommand } from '../../commands/configure.js';
|
|
5
|
+
import * as prompts from '@inquirer/prompts';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
// Mock prompts
|
|
8
|
+
vi.mock('@inquirer/prompts');
|
|
9
|
+
// Mock chalk to avoid ANSI codes in tests
|
|
10
|
+
const createChalkMock = () => {
|
|
11
|
+
const mockFn = (str) => str;
|
|
12
|
+
return new Proxy(mockFn, {
|
|
13
|
+
get: () => createChalkMock(),
|
|
14
|
+
apply: (target, thisArg, args) => args[0],
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
vi.mock('chalk', () => ({
|
|
18
|
+
default: createChalkMock(),
|
|
19
|
+
}));
|
|
20
|
+
// Mock ui utilities
|
|
21
|
+
vi.mock('../../utils/ui.js', () => ({
|
|
22
|
+
banner: vi.fn(),
|
|
23
|
+
highlight: vi.fn((text) => text),
|
|
24
|
+
dim: vi.fn((text) => text),
|
|
25
|
+
success: vi.fn(),
|
|
26
|
+
spinner: vi.fn(() => ({ stop: vi.fn() })),
|
|
27
|
+
}));
|
|
28
|
+
// Mock os.homedir to use temp directory for tests
|
|
29
|
+
// Use process.cwd() with manual path construction to avoid hoisting issues
|
|
30
|
+
vi.mock('os', () => {
|
|
31
|
+
return {
|
|
32
|
+
homedir: vi.fn(() => `${process.cwd()}/.tmp-test/sembix-test-integration`),
|
|
33
|
+
tmpdir: () => '/tmp',
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
const mockPassword = vi.mocked(prompts.password);
|
|
37
|
+
const mockInput = vi.mocked(prompts.input);
|
|
38
|
+
const mockConfirm = vi.mocked(prompts.confirm);
|
|
39
|
+
describe('configure command - Integration Tests', () => {
|
|
40
|
+
const testConfigDir = `${process.cwd()}/.tmp-test/sembix-test-integration`;
|
|
41
|
+
const configPath = join(testConfigDir, '.sembix', 'config');
|
|
42
|
+
beforeEach(async () => {
|
|
43
|
+
vi.clearAllMocks();
|
|
44
|
+
// Clean up test directory
|
|
45
|
+
try {
|
|
46
|
+
await fs.rm(join(testConfigDir, '.sembix'), { recursive: true, force: true });
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Ignore if doesn't exist
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
afterEach(async () => {
|
|
53
|
+
// Clean up after tests
|
|
54
|
+
try {
|
|
55
|
+
await fs.rm(join(testConfigDir, '.sembix'), { recursive: true, force: true });
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Ignore cleanup errors
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
describe('first-time configuration', () => {
|
|
62
|
+
it('should create config directory and file', async () => {
|
|
63
|
+
mockPassword.mockResolvedValue('ghp_testtoken123');
|
|
64
|
+
mockInput.mockResolvedValue('test-org');
|
|
65
|
+
await configureCommand();
|
|
66
|
+
// Verify directory was created
|
|
67
|
+
expect(existsSync(join(testConfigDir, '.sembix'))).toBe(true);
|
|
68
|
+
// Verify file was created
|
|
69
|
+
expect(existsSync(configPath)).toBe(true);
|
|
70
|
+
// Verify content
|
|
71
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
72
|
+
expect(content).toContain('github_token=ghp_testtoken123');
|
|
73
|
+
expect(content).toContain('default_github_org=test-org');
|
|
74
|
+
});
|
|
75
|
+
it('should create config with token only', async () => {
|
|
76
|
+
mockPassword.mockResolvedValue('ghp_testtoken456');
|
|
77
|
+
mockInput.mockResolvedValue('');
|
|
78
|
+
await configureCommand();
|
|
79
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
80
|
+
expect(content).toContain('github_token=ghp_testtoken456');
|
|
81
|
+
expect(content).not.toContain('default_github_org=');
|
|
82
|
+
});
|
|
83
|
+
it('should set correct file permissions (0600)', async () => {
|
|
84
|
+
mockPassword.mockResolvedValue('ghp_testtoken789');
|
|
85
|
+
mockInput.mockResolvedValue('');
|
|
86
|
+
await configureCommand();
|
|
87
|
+
const stats = await fs.stat(configPath);
|
|
88
|
+
// Check that file is readable and writable by owner only
|
|
89
|
+
// 0o100600 is the full mode including file type bits
|
|
90
|
+
expect(stats.mode & 0o777).toBe(0o600);
|
|
91
|
+
});
|
|
92
|
+
it('should include header comments in config file', async () => {
|
|
93
|
+
mockPassword.mockResolvedValue('ghp_testtoken');
|
|
94
|
+
mockInput.mockResolvedValue('');
|
|
95
|
+
await configureCommand();
|
|
96
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
97
|
+
expect(content).toContain('# Sembix CLI Configuration');
|
|
98
|
+
expect(content).toContain('# Generated by: sembix configure');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('updating existing configuration', () => {
|
|
102
|
+
it('should preserve existing token when user chooses to keep it', async () => {
|
|
103
|
+
// Create initial config
|
|
104
|
+
mockPassword.mockResolvedValue('ghp_initialtoken');
|
|
105
|
+
mockInput.mockResolvedValue('initial-org');
|
|
106
|
+
await configureCommand();
|
|
107
|
+
// Update config, keeping token
|
|
108
|
+
vi.clearAllMocks();
|
|
109
|
+
mockConfirm.mockResolvedValue(true); // Keep existing token
|
|
110
|
+
mockInput.mockResolvedValue('updated-org');
|
|
111
|
+
await configureCommand();
|
|
112
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
113
|
+
expect(content).toContain('github_token=ghp_initialtoken');
|
|
114
|
+
expect(content).toContain('default_github_org=updated-org');
|
|
115
|
+
});
|
|
116
|
+
it('should update token when user chooses to replace it', async () => {
|
|
117
|
+
// Create initial config
|
|
118
|
+
mockPassword.mockResolvedValue('ghp_initialtoken');
|
|
119
|
+
mockInput.mockResolvedValue('initial-org');
|
|
120
|
+
await configureCommand();
|
|
121
|
+
// Update config, replacing token
|
|
122
|
+
vi.clearAllMocks();
|
|
123
|
+
mockConfirm.mockResolvedValue(false); // Replace token
|
|
124
|
+
mockPassword.mockResolvedValue('ghp_newtoken');
|
|
125
|
+
mockInput.mockResolvedValue('initial-org');
|
|
126
|
+
await configureCommand();
|
|
127
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
128
|
+
expect(content).toContain('github_token=ghp_newtoken');
|
|
129
|
+
expect(content).not.toContain('ghp_initialtoken');
|
|
130
|
+
});
|
|
131
|
+
it('should handle removing org by setting empty value', async () => {
|
|
132
|
+
// Create initial config with org
|
|
133
|
+
mockPassword.mockResolvedValue('ghp_token');
|
|
134
|
+
mockInput.mockResolvedValue('some-org');
|
|
135
|
+
await configureCommand();
|
|
136
|
+
// Update config, removing org
|
|
137
|
+
vi.clearAllMocks();
|
|
138
|
+
mockConfirm.mockResolvedValue(true);
|
|
139
|
+
mockInput.mockResolvedValue('');
|
|
140
|
+
await configureCommand();
|
|
141
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
142
|
+
expect(content).toContain('github_token=ghp_token');
|
|
143
|
+
expect(content).not.toContain('default_github_org=');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
describe('config file parsing', () => {
|
|
147
|
+
it('should correctly read back written configuration', async () => {
|
|
148
|
+
const testToken = 'ghp_roundtriptest';
|
|
149
|
+
const testOrg = 'roundtrip-org';
|
|
150
|
+
mockPassword.mockResolvedValue(testToken);
|
|
151
|
+
mockInput.mockResolvedValue(testOrg);
|
|
152
|
+
await configureCommand();
|
|
153
|
+
// Read the config file directly
|
|
154
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
155
|
+
const lines = content.split('\n');
|
|
156
|
+
const tokenLine = lines.find((line) => line.startsWith('github_token='));
|
|
157
|
+
const orgLine = lines.find((line) => line.startsWith('default_github_org='));
|
|
158
|
+
expect(tokenLine).toBe(`github_token=${testToken}`);
|
|
159
|
+
expect(orgLine).toBe(`default_github_org=${testOrg}`);
|
|
160
|
+
});
|
|
161
|
+
it('should handle special characters in values', async () => {
|
|
162
|
+
const tokenWithSpecialChars = 'ghp_test-token.with_special/chars123';
|
|
163
|
+
const orgWithSpecialChars = 'org-name_with.special-chars';
|
|
164
|
+
mockPassword.mockResolvedValue(tokenWithSpecialChars);
|
|
165
|
+
mockInput.mockResolvedValue(orgWithSpecialChars);
|
|
166
|
+
await configureCommand();
|
|
167
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
168
|
+
expect(content).toContain(`github_token=${tokenWithSpecialChars}`);
|
|
169
|
+
expect(content).toContain(`default_github_org=${orgWithSpecialChars}`);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
describe('error scenarios', () => {
|
|
173
|
+
it('should handle write permission errors', async () => {
|
|
174
|
+
// Create config directory with no write permissions
|
|
175
|
+
await fs.mkdir(join(testConfigDir, '.sembix'), { recursive: true, mode: 0o555 });
|
|
176
|
+
mockPassword.mockResolvedValue('ghp_testtoken');
|
|
177
|
+
mockInput.mockResolvedValue('test-org');
|
|
178
|
+
await expect(configureCommand()).rejects.toThrow(/Failed to save configuration/);
|
|
179
|
+
// Cleanup: restore permissions
|
|
180
|
+
await fs.chmod(join(testConfigDir, '.sembix'), 0o755);
|
|
181
|
+
});
|
|
182
|
+
it('should validate token format', async () => {
|
|
183
|
+
mockPassword.mockResolvedValue('ghp_validtoken');
|
|
184
|
+
mockInput.mockResolvedValue('');
|
|
185
|
+
await configureCommand();
|
|
186
|
+
// Get the validation function that was passed to password()
|
|
187
|
+
const passwordOptions = mockPassword.mock.calls[0][0];
|
|
188
|
+
const validate = passwordOptions.validate;
|
|
189
|
+
expect(validate).toBeDefined();
|
|
190
|
+
if (validate) {
|
|
191
|
+
// Test valid tokens
|
|
192
|
+
expect(validate('ghp_validtoken123')).toBe(true);
|
|
193
|
+
expect(validate('github_pat_validtoken456')).toBe(true);
|
|
194
|
+
// Test invalid tokens
|
|
195
|
+
expect(validate('')).toBe('GitHub token is required');
|
|
196
|
+
expect(validate(' ')).toBe('GitHub token is required');
|
|
197
|
+
expect(validate('invalid_prefix_token')).toBe('Token should start with ghp_ or github_pat_');
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
describe('sequential updates', () => {
|
|
202
|
+
it('should handle multiple updates correctly', async () => {
|
|
203
|
+
// First update
|
|
204
|
+
mockPassword.mockResolvedValue('ghp_token1');
|
|
205
|
+
mockInput.mockResolvedValue('org1');
|
|
206
|
+
await configureCommand();
|
|
207
|
+
let content = await fs.readFile(configPath, 'utf-8');
|
|
208
|
+
expect(content).toContain('github_token=ghp_token1');
|
|
209
|
+
expect(content).toContain('default_github_org=org1');
|
|
210
|
+
// Second update - change org, keep token
|
|
211
|
+
vi.clearAllMocks();
|
|
212
|
+
mockConfirm.mockResolvedValue(true); // Keep token
|
|
213
|
+
mockInput.mockResolvedValue('org2');
|
|
214
|
+
await configureCommand();
|
|
215
|
+
content = await fs.readFile(configPath, 'utf-8');
|
|
216
|
+
expect(content).toContain('github_token=ghp_token1');
|
|
217
|
+
expect(content).toContain('default_github_org=org2');
|
|
218
|
+
// Third update - change token
|
|
219
|
+
vi.clearAllMocks();
|
|
220
|
+
mockConfirm.mockResolvedValue(false); // Replace token
|
|
221
|
+
mockPassword.mockResolvedValue('ghp_token3');
|
|
222
|
+
mockInput.mockResolvedValue('org3');
|
|
223
|
+
await configureCommand();
|
|
224
|
+
content = await fs.readFile(configPath, 'utf-8');
|
|
225
|
+
expect(content).toContain('github_token=ghp_token3');
|
|
226
|
+
expect(content).toContain('default_github_org=org3');
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
describe('config file format validation', () => {
|
|
230
|
+
it('should maintain INI format with proper structure', async () => {
|
|
231
|
+
mockPassword.mockResolvedValue('ghp_formattest');
|
|
232
|
+
mockInput.mockResolvedValue('format-org');
|
|
233
|
+
await configureCommand();
|
|
234
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
235
|
+
const lines = content.split('\n').filter((line) => line.trim() !== '');
|
|
236
|
+
// Check header comments exist
|
|
237
|
+
expect(lines[0]).toMatch(/^#/);
|
|
238
|
+
expect(lines[1]).toMatch(/^#/);
|
|
239
|
+
// Check key=value format
|
|
240
|
+
const configLines = lines.filter((line) => !line.startsWith('#') && !line.startsWith(';'));
|
|
241
|
+
for (const line of configLines) {
|
|
242
|
+
expect(line).toMatch(/^[a-z_]+=.+$/);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
//# sourceMappingURL=configure.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/configure.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/configure.test.ts"],"names":[],"mappings":""}
|