fastlane traces: check and release status warn, scan reports fastlane-upload when a Fastfile / Appfile or a CI file or script still runs fastlane supply, deliver or pilot (file:line, storebound import fastlane); test, pitfall 96
This commit is contained in:
parent
e03cbbe8aa
commit
4f993a906a
7 changed files with 140 additions and 1 deletions
43
tests/fastlane-traces.test.ts
Normal file
43
tests/fastlane-traces.test.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// fastlane left in a project (Fastfile, CI calls to supply / deliver / pilot) is found and named (pitfall 96).
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { findFastlaneTraces, traceLine } from '../cli/lib/fastlane-traces';
|
||||
import { runScan } from '../cli/lib/scan';
|
||||
|
||||
function project(files: Record<string, string>): string {
|
||||
const dir = mkdtempSync(join(tmpdir(), 'sb-fl-'));
|
||||
for (const [p, text] of Object.entries(files)) { mkdirSync(join(dir, p, '..'), { recursive: true }); writeFileSync(join(dir, p), text); }
|
||||
return dir;
|
||||
}
|
||||
|
||||
describe('fastlane traces', () => {
|
||||
test('Fastfile actions, Appfile, and CI / script calls with file:line', () => {
|
||||
const dir = project({
|
||||
'android/fastlane/Fastfile': 'lane :ship do\n # supply in a comment is not a call\n supply(track: "internal")\nend\n',
|
||||
'fastlane/Appfile': 'app_identifier("com.example.game")\n',
|
||||
'Jenkinsfile': 'stage("upload") {\n sh "bundle exec fastlane supply --aab app.aab"\n}\n',
|
||||
'.github/workflows/ios.yml': 'steps:\n - run: fastlane pilot upload\n',
|
||||
'scripts/release.sh': 'echo fastlane is fine to mention\n',
|
||||
});
|
||||
const t = findFastlaneTraces(dir);
|
||||
expect(t).toContainEqual({ file: 'android/fastlane/Fastfile', line: 3, text: 'supply(track: "internal")', store: 'play' });
|
||||
expect(t).toContainEqual({ file: 'fastlane/Appfile', line: 1, text: 'app_identifier("com.example.game")', store: 'both' });
|
||||
expect(t).toContainEqual({ file: 'Jenkinsfile', line: 2, text: 'sh "bundle exec fastlane supply --aab app.aab"', store: 'play' });
|
||||
expect(t).toContainEqual({ file: '.github/workflows/ios.yml', line: 2, text: '- run: fastlane pilot upload', store: 'apple' });
|
||||
expect(t.some(x => x.file === 'scripts/release.sh')).toBe(false);
|
||||
expect(t.filter(x => x.file === 'android/fastlane/Fastfile')).toHaveLength(1);
|
||||
expect(traceLine(t.find(x => x.file === 'Jenkinsfile')!)).toBe('fastlane in Jenkinsfile:2: sh "bundle exec fastlane supply --aab app.aab"');
|
||||
});
|
||||
test('a project without fastlane has no traces', () => {
|
||||
expect(findFastlaneTraces(project({ 'package.json': '{"scripts":{"build":"vite build"}}' }))).toEqual([]);
|
||||
});
|
||||
test('scan reports fastlane-upload with the evidence lines', async () => {
|
||||
const dir = project({ 'Jenkinsfile': 'sh "fastlane supply"\n' });
|
||||
const { report } = await runScan(dir, {});
|
||||
const f = report.findings.find(x => x.rule === 'fastlane-upload' && x.store === 'play');
|
||||
expect(f?.evidence[0]).toMatchObject({ file: 'Jenkinsfile', line: 1 });
|
||||
expect(f?.fix).toContain('storebound import fastlane');
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue