name: Asset Validation & CI Safeguards on: pull_request: paths: - 'resources/**' - 'config/assets/**' - 'capacitor-assets.config.json' - 'capacitor.config.ts' - 'capacitor.config.json' push: branches: [main, develop] paths: - 'resources/**' - 'config/assets/**' - 'capacitor-assets.config.json' - 'capacitor.config.ts' - 'capacitor.config.json' jobs: asset-validation: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: 'npm' - name: Install dependencies run: npm ci - name: Validate asset configuration run: npm run assets:validate - name: Check for committed platform assets (Android) run: | if git ls-files -z android/app/src/main/res | grep -E '(AppIcon.*\.png|Splash.*\.png|mipmap-.*/ic_launcher.*\.png)' > /dev/null; then echo "โŒ Android platform assets found in VCS - these should be generated at build-time" git ls-files -z android/app/src/main/res | grep -E '(AppIcon.*\.png|Splash.*\.png|mipmap-.*/ic_launcher.*\.png)' exit 1 fi echo "โœ… No Android platform assets committed" - name: Check for committed platform assets (iOS) run: | if git ls-files -z ios/App/App/Assets.xcassets | grep -E '(AppIcon.*\.png|Splash.*\.png)' > /dev/null; then echo "โŒ iOS platform assets found in VCS - these should be generated at build-time" git ls-files -z ios/App/App/Assets.xcassets | grep -E '(AppIcon.*\.png|Splash.*\.png)' exit 1 fi echo "โœ… No iOS platform assets committed" - name: Test asset generation run: | echo "๐Ÿงช Testing asset generation workflow..." npm run build:capacitor npx cap sync npx capacitor-assets generate --dry-run || npx capacitor-assets generate echo "โœ… Asset generation test completed" - name: Verify clean tree after build run: | if [ -n "$(git status --porcelain)" ]; then echo "โŒ Dirty tree after build - asset configs were modified" git status git diff exit 1 fi echo "โœ… Build completed with clean tree" schema-validation: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: 'npm' - name: Install dependencies run: npm ci - name: Validate schema compliance run: | echo "๐Ÿ” Validating schema compliance..." node -e " const fs = require('fs'); const config = JSON.parse(fs.readFileSync('capacitor-assets.config.json', 'utf8')); const schema = JSON.parse(fs.readFileSync('config/assets/schema.json', 'utf8')); // Basic schema validation if (!config.icon || !config.splash) { throw new Error('Missing required sections: icon and splash'); } if (!config.icon.source || !config.splash.source) { throw new Error('Missing required source fields'); } if (!/^resources\/.*\.(png|svg)$/.test(config.icon.source)) { throw new Error('Icon source must be in resources/ directory'); } if (!/^resources\/.*\.(png|svg)$/.test(config.splash.source)) { throw new Error('Splash source must be in resources/ directory'); } console.log('โœ… Schema validation passed'); " - name: Check source file existence run: | echo "๐Ÿ“ Checking source file existence..." node -e " const fs = require('fs'); const config = JSON.parse(fs.readFileSync('capacitor-assets.config.json', 'utf8')); const requiredFiles = [ config.icon.source, config.splash.source ]; if (config.splash.darkSource) { requiredFiles.push(config.splash.darkSource); } const missingFiles = requiredFiles.filter(file => !fs.existsSync(file)); if (missingFiles.length > 0) { console.error('โŒ Missing source files:', missingFiles); process.exit(1); } console.log('โœ… All source files exist'); "