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:
CRTkafa 2026-10-22 01:39:14 +08:00
parent e03cbbe8aa
commit 4f993a906a
7 changed files with 140 additions and 1 deletions

View file

@ -10,6 +10,7 @@ import { AI_FIX_RULES, scanFixAction } from '../fix-actions';
import { proposeDeclarations, type Proposal } from './declare';
import { detectProject, ECO_LABEL, type ProjectFacts, type Stack, where } from './project';
import type { OriginalityReport } from '../originality';
import { FASTLANE_FIX, findFastlaneTraces } from '../fastlane-traces';
import { APPLE_GUIDELINES, applyIgnore, type ScanFinding, scanRules, type Severity, sortScan, unusedIgnores } from './rules';
import type { SdkCategory } from './sdks';
@ -73,6 +74,15 @@ export async function runScan(dir: string, o: { config?: string } = {}): Promise
fix: g.fix ?? '', skill: 'game-services', ref: 'https://developer.android.com/games/pgs/android/android-start' });
} catch { /* unreadable Android project */ }
}
// fastlane still uploading next to storebound (pitfall 96)
const traces = findFastlaneTraces(dir);
for (const store of ['apple', 'play'] as const) {
if (config && !config[store]) continue;
const ev = traces.filter(t => t.store === store || t.store === 'both');
if (ev.length && !(config?.scan?.ignore ?? []).some(i => i.rule === 'fastlane-upload'))
findings.push({ rule: 'fastlane-upload', guideline: 'storebound workflow', store, severity: 'medium', title: `fastlane still in the project (${ev.length} place${ev.length > 1 ? 's' : ''}); uploads there bypass storebound`,
evidence: ev.map(t => ({ file: t.file, line: t.line, text: t.text })), fix: FASTLANE_FIX, skill: 'migrate-from-fastlane', ref: 'https://git.crt.fyi/CRT/storebound/src/branch/main/skills/migrate-from-fastlane/SKILL.md' });
}
for (const f of findings) {
const action = f.accepted ? undefined : scanFixAction(f.rule, { configPath, declarationsChanged: declarations.changed });
if (action) f.action = action;