Direct store API calls in a project's scripts: androidpublisher.googleapis.com, the googleapis androidpublisher client, api.appstoreconnect.apple.com, altool / Transporter in CI files and scripts; scan rule direct-store-api, check and release status warnings with file:line and the storebound command; storebound's own checkout skipped; test, pitfall 97

This commit is contained in:
CRTkafa 2026-10-22 02:04:28 +08:00
parent 4f993a906a
commit 4fcee60ba6
7 changed files with 72 additions and 10 deletions

View file

@ -3,7 +3,7 @@ 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 { findFastlaneTraces, traceLine, traceMessage } from '../cli/lib/fastlane-traces';
import { runScan } from '../cli/lib/scan';
function project(files: Record<string, string>): string {
@ -30,6 +30,21 @@ describe('fastlane traces', () => {
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('scripts that call the store APIs or upload tools themselves, with the storebound way', () => {
const dir = project({
'scripts/play-upload.mjs': "const url = 'https://androidpublisher.googleapis.com/upload/androidpublisher/v3/applications/com.example.app/edits';\n",
'tools/asc.py': "BASE = 'https://api.appstoreconnect.apple.com/v1'\n",
'deploy/ios.sh': 'xcrun altool --upload-app -f app.ipa\n',
'package.json': '{"name":"an-app","scripts":{"ship":"node scripts/play-upload.mjs"}}',
});
const t = findFastlaneTraces(dir);
expect(t.map(x => `${x.file} ${x.store} ${x.via}`).sort()).toEqual(['deploy/ios.sh apple api', 'scripts/play-upload.mjs play api', 'tools/asc.py apple api']);
expect(traceMessage(t.find(x => x.store === 'play')!)).toContain('play_release_testing');
expect(traceMessage(t.find(x => x.file === 'deploy/ios.sh')!)).toStartWith('altool / Transporter upload in deploy/ios.sh:1');
});
test("storebound's own checkout is not reported", () => {
expect(findFastlaneTraces(project({ 'package.json': '{"name":"storebound"}', 'scripts/x.ts': "fetch('https://api.appstoreconnect.apple.com/v1/apps')\n" }))).toEqual([]);
});
test('a project without fastlane has no traces', () => {
expect(findFastlaneTraces(project({ 'package.json': '{"scripts":{"build":"vite build"}}' }))).toEqual([]);
});