Skip to content

Commit 5336bff

Browse files
committed
[CI] Add CI workflow for automated build, test, and linting
- Introduced a GitHub Actions CI workflow to automate the build, test, and lint processes for the project. - Configured the workflow to run on pushes and pull requests to the main and develop branches. - Included steps for checking out code, setting up Node.js, installing dependencies, building packages, running type checks, linting, and executing tests with coverage reporting.
1 parent 3bc84fd commit 5336bff

6 files changed

Lines changed: 106 additions & 55 deletions

File tree

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Test Suite
1+
name: CI
22

33
on:
44
push:
@@ -7,28 +7,30 @@ on:
77
branches: [main, develop]
88

99
jobs:
10-
test:
10+
ci:
11+
name: Build, Test & Lint (Node.js 20.x)
1112
runs-on: ubuntu-latest
1213

13-
strategy:
14-
matrix:
15-
node-version: [18.x, 20.x, 22.x]
16-
1714
steps:
1815
- name: Checkout code
1916
uses: actions/checkout@v4
2017

21-
- name: Setup Node.js ${{ matrix.node-version }}
18+
- name: Enable Corepack
19+
run: corepack enable
20+
21+
- name: Setup Node.js
2222
uses: actions/setup-node@v4
2323
with:
24-
node-version: ${{ matrix.node-version }}
25-
cache: 'yarn'
24+
node-version: 20.x
2625

2726
- name: Install dependencies
2827
run: yarn install --frozen-lockfile
2928

3029
- name: Build packages
31-
run: yarn build
30+
run: |
31+
yarn workspace @subzilla/types run build
32+
yarn workspace @subzilla/core run build
33+
yarn workspace @subzilla/cli run build
3234
3335
- name: Run type checking
3436
run: yarn type-check

.yarn/install-state.gz

10.3 KB
Binary file not shown.

packages/core/__tests__/BatchProcessor.test.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,20 +438,23 @@ Test subtitle content
438438
});
439439

440440
it('should respect maxDepth option', async () => {
441-
await createTestSrtFile(path.join(tempDir, 'file1.srt'));
442-
await createTestSrtFile(path.join(tempDir, 'level1', 'file2.srt'));
443-
await createTestSrtFile(path.join(tempDir, 'level1', 'level2', 'file3.srt'));
444-
await createTestSrtFile(path.join(tempDir, 'level1', 'level2', 'level3', 'file4.srt'));
441+
await createTestSrtFile(path.join(tempDir, 'file1.srt')); // depth 0
442+
await createTestSrtFile(path.join(tempDir, 'level1', 'file2.srt')); // depth 1
443+
await createTestSrtFile(path.join(tempDir, 'level1', 'level2', 'file3.srt')); // depth 2
444+
await createTestSrtFile(path.join(tempDir, 'level1', 'level2', 'level3', 'file4.srt')); // depth 3
445445

446446
const pattern = path.join(tempDir, '**', '*.srt');
447+
448+
// Test with maxDepth: 2 - should only find files at depth 0, 1, 2
447449
const options = createDefaultOptions({
448450
batch: { maxDepth: 2 },
449451
} as Partial<IBatchOptions>);
450452

451453
const stats = await processor.processBatch(pattern, options);
452454

453-
// Should only find files up to depth 2
454-
expect(stats.total).toBeLessThan(4);
455+
// Should find 3 files (file1, file2, file3) but not file4 (depth 3)
456+
expect(stats.total).toBe(3);
457+
expect(stats.successful).toBe(3);
455458
});
456459
});
457460

packages/core/src/BatchProcessor.ts

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,32 +106,78 @@ export default class BatchProcessor {
106106
private async findFiles(pattern: string, options: IBatchOptions): Promise<string[]> {
107107
console.info(`🔍 Finding files: ${pattern}`);
108108

109-
const files = await glob(pattern, {
109+
const globOptions: Parameters<typeof glob>[1] = {
110110
nodir: true,
111111
dot: false,
112112
follow: true,
113-
maxDepth: options.batch.maxDepth,
114-
});
113+
};
115114

116-
return files.filter((file) => {
117-
const dirPath = path.dirname(file);
115+
// Note: We don't use glob's maxDepth option as it may not work correctly with ** patterns
116+
// Instead, we filter manually after getting all files
117+
118+
const files = await glob(pattern, globOptions);
119+
120+
return files
121+
.map((file) => String(file))
122+
.filter((file) => {
123+
// Apply maxDepth filtering manually if needed
124+
// Note: glob's maxDepth may not work correctly with ** patterns, so we filter manually
125+
if (options.batch.maxDepth !== undefined) {
126+
// Calculate depth relative to the pattern's base directory
127+
// Pattern is like "tempDir/**/*.srt", base is "tempDir"
128+
// Extract base directory: everything before the first "**"
129+
const doubleStarIndex = pattern.indexOf('**');
130+
let patternBase: string;
131+
132+
if (doubleStarIndex > 0) {
133+
const basePart = pattern.substring(0, doubleStarIndex);
134+
135+
// Remove trailing slash/separator if present
136+
patternBase = basePart.replace(/[/\\]$/, '') || path.dirname(pattern);
137+
} else {
138+
patternBase = path.dirname(pattern);
139+
}
118140

119-
// Check include directories
120-
if (options.batch.includeDirectories?.length) {
121-
if (!options.batch.includeDirectories.some((dir) => dirPath.includes(dir))) {
122-
return false;
141+
// Normalize paths to handle absolute/relative differences
142+
const normalizedBase = path.resolve(patternBase);
143+
const normalizedFile = path.resolve(file);
144+
const relativePath = path.relative(normalizedBase, normalizedFile);
145+
146+
// Skip if relative path is empty or just ".." (file is outside base)
147+
if (!relativePath || relativePath.startsWith('..')) {
148+
return false;
149+
}
150+
151+
// Depth is the number of directory separators in the relative path
152+
// For "level1/file2.srt", depth is 1; for "file1.srt", depth is 0
153+
const pathParts = relativePath
154+
.split(path.sep)
155+
.filter((segment) => segment !== '' && segment !== '.');
156+
const depth = pathParts.length > 0 ? pathParts.length - 1 : 0; // -1 for filename
157+
158+
if (depth > options.batch.maxDepth) {
159+
return false;
160+
}
123161
}
124-
}
125162

126-
// Check exclude directories
127-
if (options.batch.excludeDirectories?.length) {
128-
if (options.batch.excludeDirectories.some((dir) => dirPath.includes(dir))) {
129-
return false;
163+
const dirPath = path.dirname(file);
164+
165+
// Check include directories
166+
if (options.batch.includeDirectories?.length) {
167+
if (!options.batch.includeDirectories.some((dir) => dirPath.includes(dir))) {
168+
return false;
169+
}
130170
}
131-
}
132171

133-
return true;
134-
});
172+
// Check exclude directories
173+
if (options.batch.excludeDirectories?.length) {
174+
if (options.batch.excludeDirectories.some((dir) => dirPath.includes(dir))) {
175+
return false;
176+
}
177+
}
178+
179+
return true;
180+
});
135181
}
136182

137183
private countDirectories(files: string[]): number {

packages/mac/__tests__/main/preferences.test.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@ describe('ConfigMapper - Preferences Management', () => {
120120
it('should have correct default configuration', () => {
121121
const defaults = configMapper.getDefaultConfigData();
122122

123-
expect(defaults.input.encoding).toBe('auto');
124-
expect(defaults.output.encoding).toBe('utf8');
125-
expect(defaults.output.bom).toBe(true);
123+
expect(defaults.input!.encoding).toBe('auto');
124+
expect(defaults.output!.encoding).toBe('utf8');
125+
expect(defaults.output!.bom).toBe(true);
126126
expect(defaults.strip?.bidiControl).toBe(true);
127127
expect(defaults.batch?.parallel).toBe(true);
128128
expect(defaults.app.notifications).toBe(true);
@@ -299,20 +299,20 @@ describe('ConfigMapper - Preferences Management', () => {
299299
it('should have correct input defaults', () => {
300300
const defaults = configMapper.getDefaultConfigData();
301301

302-
expect(defaults.input.encoding).toBe('auto');
303-
expect(defaults.input.format).toBe('auto');
302+
expect(defaults.input!.encoding).toBe('auto');
303+
expect(defaults.input!.format).toBe('auto');
304304
});
305305

306306
it('should have correct output defaults', () => {
307307
const defaults = configMapper.getDefaultConfigData();
308308

309-
expect(defaults.output.encoding).toBe('utf8');
310-
expect(defaults.output.createBackup).toBe(false);
311-
expect(defaults.output.overwriteBackup).toBe(false);
312-
expect(defaults.output.bom).toBe(true);
313-
expect(defaults.output.lineEndings).toBe('auto');
314-
expect(defaults.output.overwriteInput).toBe(false);
315-
expect(defaults.output.overwriteExisting).toBe(true);
309+
expect(defaults.output!.encoding).toBe('utf8');
310+
expect(defaults.output!.createBackup).toBe(false);
311+
expect(defaults.output!.overwriteBackup).toBe(false);
312+
expect(defaults.output!.bom).toBe(true);
313+
expect(defaults.output!.lineEndings).toBe('auto');
314+
expect(defaults.output!.overwriteInput).toBe(false);
315+
expect(defaults.output!.overwriteExisting).toBe(true);
316316
});
317317

318318
it('should have correct strip defaults', () => {
@@ -333,14 +333,14 @@ describe('ConfigMapper - Preferences Management', () => {
333333
it('should have correct batch defaults', () => {
334334
const defaults = configMapper.getDefaultConfigData();
335335

336-
expect(defaults.batch.recursive).toBe(false);
337-
expect(defaults.batch.parallel).toBe(true);
338-
expect(defaults.batch.skipExisting).toBe(false);
339-
expect(defaults.batch.preserveStructure).toBe(false);
340-
expect(defaults.batch.chunkSize).toBe(5);
341-
expect(defaults.batch.retryCount).toBe(0);
342-
expect(defaults.batch.retryDelay).toBe(1000);
343-
expect(defaults.batch.failFast).toBe(false);
336+
expect(defaults.batch!.recursive).toBe(false);
337+
expect(defaults.batch!.parallel).toBe(true);
338+
expect(defaults.batch!.skipExisting).toBe(false);
339+
expect(defaults.batch!.preserveStructure).toBe(false);
340+
expect(defaults.batch!.chunkSize).toBe(5);
341+
expect(defaults.batch!.retryCount).toBe(0);
342+
expect(defaults.batch!.retryDelay).toBe(1000);
343+
expect(defaults.batch!.failFast).toBe(false);
344344
});
345345

346346
it('should have correct app defaults', () => {

yarn.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7558,11 +7558,11 @@ __metadata:
75587558

75597559
"typescript@patch:typescript@npm%3A^5.3.3#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A^5.9.2#optional!builtin<compat/typescript>":
75607560
version: 5.9.2
7561-
resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin<compat/typescript>::version=5.9.2&hash=cef18b"
7561+
resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin<compat/typescript>::version=5.9.2&hash=5786d5"
75627562
bin:
75637563
tsc: bin/tsc
75647564
tsserver: bin/tsserver
7565-
checksum: 10c0/66fc07779427a7c3fa97da0cf2e62595eaff2cea4594d45497d294bfa7cb514d164f0b6ce7a5121652cf44c0822af74e29ee579c771c405e002d1f23cf06bfde
7565+
checksum: 10c0/34d2a8e23eb8e0d1875072064d5e1d9c102e0bdce56a10a25c0b917b8aa9001a9cf5c225df12497e99da107dc379360bc138163c66b55b95f5b105b50578067e
75667566
languageName: node
75677567
linkType: hard
75687568

0 commit comments

Comments
 (0)