From 7b04b2f9cd1d81859bdf79494d1a211eda809f24 Mon Sep 17 00:00:00 2001 From: robot Date: Sat, 1 Aug 2026 06:52:09 +0000 Subject: [PATCH] fix(ci): generate stub files before flutter analyze The generated/ directory (app_config.dart, theme_colors.dart) is created by build_whitelabel.py from theme.json. Since theme.json is not in the repo, the lint gate fails on missing generated imports. Added ci_stub_gen.py to produce minimal stubs so flutter analyze passes before the whitelabel build step. Wired into all jobs in ci.yml and release.yml. --- .gitea/workflows/ci.yml | 12 ++++- .gitea/workflows/release.yml | 10 ++++ ci_stub_gen.py | 99 ++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 ci_stub_gen.py diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 6fb3bec..b5ce978 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -36,6 +36,10 @@ jobs: - name: Install dependencies run: flutter pub get + - name: Generate stubs (lint gate support) + if: hashFiles('theme.json') == '' + run: python3 ci_stub_gen.py + - name: Analyze Dart code run: flutter analyze --fatal-warnings @@ -61,6 +65,9 @@ jobs: - name: Install dependencies run: flutter pub get + - name: Generate stubs (lint gate support) + run: python3 ci_stub_gen.py + - name: Run tests run: flutter test --reporter=expanded @@ -116,9 +123,12 @@ jobs: python -m pip install --upgrade pip pip install -r requirements.txt - - name: Install Flutter dependencies + - name: Install dependencies run: flutter pub get + - name: Generate stubs (lint gate support) + run: python3 ci_stub_gen.py + - name: Analyze (gate before build) run: flutter analyze --fatal-warnings diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 7cefe18..b4a772b 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -30,6 +30,10 @@ jobs: - name: Install dependencies run: flutter pub get + - name: Generate stubs (lint gate support) + if: hashFiles('theme.json') == '' + run: python3 ci_stub_gen.py + - name: Analyze Dart code run: flutter analyze --fatal-warnings @@ -55,6 +59,9 @@ jobs: - name: Install dependencies run: flutter pub get + - name: Generate stubs (lint gate support) + run: python3 ci_stub_gen.py + - name: Run tests run: flutter test --reporter=expanded @@ -101,6 +108,9 @@ jobs: - name: Install Flutter dependencies run: flutter pub get + - name: Generate stubs (lint gate support) + run: python3 ci_stub_gen.py + # If release signing secrets are available, write keystore # and update build.gradle.kts to use a release signing config. # Otherwise fall back to debug keys (current state of the repo). diff --git a/ci_stub_gen.py b/ci_stub_gen.py new file mode 100644 index 0000000..b569b15 --- /dev/null +++ b/ci_stub_gen.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +"""Generate stub lib/generated/*.dart files so flutter analyze passes +before the whitelabel build script has been run. + +This is only needed for CI lint gates. The real build generates these +from theme.json via build_whitelabel.py. +""" + +import os +import sys + +PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) +GENERATED_DIR = os.path.join(PROJECT_ROOT, "lib", "generated") + +DEFAULT_APP_CONFIG = '''// GENERATED STUB — DO NOT EDIT. +// This file is replaced by `python3 build_whitelabel.py` during actual builds. +// Exists only so that `flutter analyze` passes before whitelabel generation. + +class AppConfig { + static const String callsign = 'KRYZ'; + static const String appName = 'KRYZ Go'; + static const String tagline = ''; + static const String frequency = ''; + static const String streamUrl = ''; + static const String? metadataUrl = null; + static const String defaultTitle = 'KRYZ Live Stream'; + static const String defaultArtist = 'KRYZ Radio'; +} +''' + +DEFAULT_THEME_COLORS = '''// GENERATED STUB — DO NOT EDIT. +// This file is replaced by `python3 build_whitelabel.py` during actual builds. +// Exists only so that `flutter analyze` passes before whitelabel generation. + +import 'package:flutter/material.dart'; +import 'package:kryz_go_flutter/app_theme_business_object.dart'; + +class GeneratedThemeColors { + static const AppThemeColors lightColors = AppThemeColors( + headingColor: Color(0xFF1E293B), + accentColor: Color(0xFF6366F1), + scaffoldGradientStart: Color(0xFFF8F9FA), + scaffoldGradientEnd: Color(0xFFE9ECEF), + shellSurface: Color(0xFFFDFDFD), + shellBorder: Color(0xFFDEE2E6), + mutedText: Color(0xFF6C757D), + textOnDark: Color(0xFFFFFFFF), + textOnDarkSecondary: Color(0xFFE9ECEF), + controlsGradientStart: Color(0xFF1E293B), + controlsGradientEnd: Color(0xFF334155), + controlsShadow: Color(0x24000000), + bodyText: Color(0xFF333333), + cardSurface: Color(0x14FFFFFF), + cardBorder: Color(0x1FFFFFFF), + successColor: Color(0xFF28A745), + dangerColor: Color(0xFFDC3545), + ); + + static const AppThemeColors darkColors = AppThemeColors( + headingColor: Color(0xFF8B949E), + accentColor: Color(0xFF7C83FF), + scaffoldGradientStart: Color(0xFF0D1117), + scaffoldGradientEnd: Color(0xFF161B22), + shellSurface: Color(0xFF161B22), + shellBorder: Color(0xFF30363D), + mutedText: Color(0xFF6C757D), + textOnDark: Color(0xFFFFFFFF), + textOnDarkSecondary: Color(0xFFE9ECEF), + controlsGradientStart: Color(0xFF161B22), + controlsGradientEnd: Color(0xFF1E293B), + controlsShadow: Color(0x37000000), + bodyText: Color(0xFFC9D1D9), + cardSurface: Color(0x14FFFFFF), + cardBorder: Color(0x1FFFFFFF), + successColor: Color(0xFF28A745), + dangerColor: Color(0xFFDC3545), + ); +} +''' + + +def main(): + os.makedirs(GENERATED_DIR, exist_ok=True) + + paths = [ + (os.path.join(GENERATED_DIR, "app_config.dart"), DEFAULT_APP_CONFIG), + (os.path.join(GENERATED_DIR, "theme_colors.dart"), DEFAULT_THEME_COLORS), + ] + + for path, content in paths: + with open(path, "w") as f: + f.write(content) + print(f"Generated {path}") + + print(f"Generated stubs in {GENERATED_DIR}") + + +if __name__ == "__main__": + main()