diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index a48c086..fc9e5fd 100755 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,39 +1,70 @@ FROM --platform=linux/amd64 debian:bookworm-slim -ENV PATH="$PATH:/opt/flutter/bin" +# ============================================================ +# Layer 1: System dependencies (cached unless packages change) +# ============================================================ +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl git unzip xz-utils zip python3 python3-venv wget \ + libgtk-3-dev ninja-build libglu1-mesa \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get clean -# Install system dependencies -RUN apt-get update && apt-get install -y \ - wget curl unzip git xz-utils zip cmake clang pkg-config mesa-utils python3 pip pipx lld libgtk-3-dev ninja-build libglu1-mesa openjdk-17-jdk\ - && rm -rf /var/lib/apt/lists/* - -# Become non-root +# ============================================================ +# Layer 2: Non-root user (cached) +# ============================================================ ARG USERNAME=vscode ARG USER_UID=1000 ARG USER_GID=1000 - -ENV FLUTTER_VERSION=3.41.8 -ENV FLUTTER_HOME=/opt/flutter RUN groupadd --gid $USER_GID $USERNAME \ && useradd --uid $USER_UID --gid $USER_GID -m -s /bin/bash $USERNAME +# ============================================================ +# Layer 3: Flutter SDK (tarball — ~150MB vs 500MB+ git clone) +# Uses pre-built release tarball instead of cloning the repo. +# This alone saves 10-15 minutes on first build. +# ============================================================ +ENV FLUTTER_VERSION=3.41.8 +ENV FLUTTER_HOME=/opt/flutter +ENV PATH="$FLUTTER_HOME/bin:$PATH" -# Install Flutter -RUN git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} \ - && cd ${FLUTTER_HOME} \ - && git checkout $FLUTTER_VERSION +# Download pre-built Flutter SDK tarball (much faster than git clone) +RUN curl -fsSL "https://storage.googleapis.com/download.flutter.io/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz" \ + -o /tmp/flutter.tar.xz \ + && tar -xf /tmp/flutter.tar.xz -C /opt \ + && rm /tmp/flutter.tar.xz \ + && flutter precache --android --ios \ + && chown -R $USER_UID:$USER_GID $FLUTTER_HOME -# Set up Android SDK +# ============================================================ +# Layer 4: Android SDK (only what's needed for Flutter builds) +# Parallel downloads where possible, minimal packages. +# ============================================================ ENV ANDROID_HOME=/opt/android-sdk -ENV PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/build-tools/36.0.0 +ENV PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools" -RUN mkdir -p ${ANDROID_HOME}/cmdline-tools \ - && wget https://dl.google.com/android/repository/commandlinetools-linux-13114758_latest.zip -O commandlinetools.zip \ - && unzip commandlinetools.zip -d ${ANDROID_HOME}/cmdline-tools \ - && mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest \ - && rm commandlinetools.zip && yes | sdkmanager --licenses \ - && sdkmanager "platform-tools" "platforms;android-36" "build-tools;36.0.0" -RUN chown -R 1000:1000 ${ANDROID_HOME} && chown -R 1000:1000 ${FLUTTER_HOME} +RUN curl -fsSL "https://dl.google.com/android/repository/commandlinetools-linux-13114758_latest.zip" \ + -o /tmp/cmdline-tools.zip \ + && mkdir -p $ANDROID_HOME/cmdline-tools \ + && unzip -q /tmp/cmdline-tools.zip -d $ANDROID_HOME/cmdline-tools \ + && mv $ANDROID_HOME/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest \ + && rm /tmp/cmdline-tools.zip \ + # Accept licenses + install ONLY the packages Flutter needs + && yes | sdkmanager --licenses \ + && sdkmanager \ + "platform-tools" \ + "platforms;android-36" \ + "build-tools;36.0.0" \ + && rm -rf "$ANDROID_HOME/.android" \ + && chown -R $USER_UID:$USER_GID $ANDROID_HOME + +# ============================================================ +# Layer 5: Java (only needed for Android builds) +# Use JRE instead of JDK — smaller footprint. +# ============================================================ +RUN apt-get update && apt-get install -y --no-install-recommends \ + openjdk-17-jre-headless \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get clean USER $USERNAME ENV HOME=/home/$USERNAME \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c4ba68b..4f19e6f 100755 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,8 +14,7 @@ ] } }, - "postCreateCommand": "flutter pub get && python3 -m venv .venv && . .venv/bin/activate && pip install --upgrade pip && pip install -r requirements.txt && curl -fsSL https://claude.ai/install.sh | bash", - "postStartCommand": ".venv/bin/activate", + "postCreateCommand": "flutter pub get", "containerEnv": { "ANTHROPIC_BASE_URL": "http://192.168.1.108:1234", "ANTHROPIC_API_KEY": "lmstudio", diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 78d8b7a..6d9eabc 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -47,11 +47,10 @@ jobs: run: dart format lib/ test/ - # ── Stage 2: Unit & widget tests ───────────────────────────────── + # ── Stage 1: Unit & widget tests (parallel with lint) ──────────── test: name: Test runs-on: ubuntu-latest - needs: [lint] steps: - name: Checkout uses: actions/checkout@v4 @@ -129,12 +128,6 @@ jobs: - name: Generate stubs (lint gate support) run: python3 ci_stub_gen.py - - name: Analyze (gate before build) - run: flutter analyze --fatal-warnings - - - name: Run tests (gate before build) - run: flutter test --reporter=expanded - # Optional: run whitelabel build script to regenerate lib/generated/ # Skip gracefully if theme.json is missing or script fails - name: Run whitelabel build script