Skip to content

feat(api): add Envied API config and Dio/Retrofit client scaffold#8

Merged
CowboyGH merged 5 commits intodevelopfrom
feature/api-client-setup
Feb 18, 2026
Merged

feat(api): add Envied API config and Dio/Retrofit client scaffold#8
CowboyGH merged 5 commits intodevelopfrom
feature/api-client-setup

Conversation

@CowboyGH
Copy link
Owner

@CowboyGH CowboyGH commented Feb 17, 2026

🚀 Summary

Introduces the API client foundation for the next auth work: environment-based API configuration (Envied) + baseline Dio/Retrofit wiring in DI, with CI/Docker support to inject API_URL during codegen/build.

✨ Changes

  • ✅ Set up API configuration from environment variables (API_URL) using Envied.
  • ✅ Updated CI and Docker to pass API_URL during code generation (GitHub secret + Docker BuildKit secret), so builds work the same outside local machines.
  • ✅ Added a basic networking foundation with Dio + Retrofit for future API modules.
  • ✅ Connected the API client to DI and added default JSON headers and simple timeouts.

⚠️ Breaking Changes

  • CI/Docker now require API_URL in GitHub Secrets for code generation/build jobs.
  • Local codegen/build now requires a local .env file with API_URL.

🧪 Verification

  • flutter pub get
  • dart run build_runner build --delete-conflicting-outputs
  • flutter analyze
  • flutter test

@CowboyGH CowboyGH self-assigned this Feb 17, 2026
@CowboyGH CowboyGH added area: network API, requests, and data parsing type: feature New feature or request labels Feb 17, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2026

📝 Walkthrough

Walkthrough

Adds CI and Docker steps to write API_URL into a .env during build, introduces Envied-based runtime environment access, a centralized ApiPaths, a Retrofit ApiClient scaffold, and registers Dio + ApiClient in DI; also adds envied packages and updates CHANGELOG.

Changes

Cohort / File(s) Summary
CI / Docker
\.github/workflows/main.yml, Dockerfile
Create a .env from the API_URL secret during CI/analyze and in the Docker build (via secret mount), and pass the secret into the image build.
Environment config
lib/core/env/env.dart, lib/api/service/api_paths.dart
Add Envied-based Env class to expose apiUrl from .env; add ApiPaths with baseUrl = Env.apiUrl.
API client & DI
lib/api/service/api_client.dart, lib/core/di/di.dart
Introduce a Retrofit-style ApiClient factory and register a configured Dio instance plus ApiClient as lazy singletons in DI (base URL from ApiPaths).
Deps & docs
pubspec.yaml, CHANGELOG.md
Add envied and envied_generator deps and update CHANGELOG with entries about env config and API client/CI changes.

Sequence Diagram(s)

sequenceDiagram
  participant CI as CI Workflow
  participant Builder as Docker Build
  participant Image as App Image
  participant App as Dart App (runtime)
  participant API as External API

  CI->>Builder: provide `API_URL` secret (analyze job & build)
  Builder->>Builder: write `/run/secrets/api_url` -> create `.env` in image
  Builder->>Image: produce container image with .env
  Image->>App: start runtime (Env reads generated config)
  App->>App: Env.apiUrl -> ApiPaths.baseUrl
  App->>App: DI provides Dio configured with baseUrl -> ApiClient
  App->>API: ApiClient makes HTTP request to baseUrl (External API)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through CI and Docker's flow,
I tucked the API where env vars go,
Envied whispers the base URL bright,
Dio and Retrofit join the flight,
A cozy DI nest—code feels right! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding Envied for API configuration management and setting up a Dio/Retrofit client scaffold, which are the primary objectives of this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/api-client-setup

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
.github/workflows/main.yml (1)

37-39: Fail fast when API_URL is missing in CI.

If the secret isn’t available (e.g., forked PRs), the .env file is created empty and the build fails later with a vague error. Add an explicit check to make failures clear and immediate.

🔧 Suggested guard
-      - name: Create .env file
-        run: echo "API_URL=${{ secrets.API_URL }}" > .env
+      - name: Create .env file
+        run: |
+          if [ -z "${{ secrets.API_URL }}" ]; then
+            echo "API_URL secret is missing" >&2
+            exit 1
+          fi
+          printf 'API_URL=%s\n' "${{ secrets.API_URL }}" > .env
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/main.yml around lines 37 - 39, The "Create .env file" CI
step writes API_URL directly from the secret without verifying it's present;
change that step to validate that the secret (secrets.API_URL) is non-empty and
fail fast with a clear error if missing, then only write the .env file when
present. Concretely, update the step's run script to check the value of
secrets.API_URL (the API_URL secret), emit a descriptive error and exit non‑zero
when empty, otherwise write "API_URL=..." into .env; keep the step name "Create
.env file" so reviewers can find it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfile`:
- Line 9: The Dockerfile currently declares a build-arg "ARG API_URL" which can
leak sensitive values into image history; remove this ARG and switch to BuildKit
secrets: accept no API_URL build-arg, instead read the secret at build time
(e.g., via RUN --mount=type=secret,id=api_url) and write it into the generated
.env or required config file inside the image (use the secret content to create
the .env in the same stage where API_URL was needed); also update the CI
workflow/action that performs docker buildx to pass the secret via the buildx
"secrets" option (map the secret name "api_url" to the repository secret) so the
secret is never passed as a build-arg or embedded in image history.

In `@lib/api/service/api_client.dart`:
- Around line 6-10: The factory constructor for ApiClient declares an optional
named parameter baseUrl as non-nullable which violates Dart 3.10 null-safety;
change the factory signature in ApiClient so the named parameter is nullable
(e.g., make baseUrl a String?) or give it a default value so it is always
non-null; update the factory declaration (factory ApiClient(Dio dio, {String?
baseUrl} = _ApiClient;) — locate the ApiClient factory in the abstract class and
adjust the baseUrl parameter to be nullable (String?) or provide a sensible
default to fix the null-safety violation and match call sites like
ApiClient(di<Dio>()).

---

Nitpick comments:
In @.github/workflows/main.yml:
- Around line 37-39: The "Create .env file" CI step writes API_URL directly from
the secret without verifying it's present; change that step to validate that the
secret (secrets.API_URL) is non-empty and fail fast with a clear error if
missing, then only write the .env file when present. Concretely, update the
step's run script to check the value of secrets.API_URL (the API_URL secret),
emit a descriptive error and exit non‑zero when empty, otherwise write
"API_URL=..." into .env; keep the step name "Create .env file" so reviewers can
find it.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Dockerfile (1)

159-191: ⚠️ Potential issue | 🟠 Major

Avoid running the runtime image as root.

The runtime stage never drops privileges, which is a security posture gap. Add a non-root user and ensure /artifacts is owned by it.

🔐 Suggested fix
 FROM alpine:latest AS runtime

@@
-# Create directory for APKs
-RUN mkdir -p /artifacts
+# Create non-root user and directory for APKs
+RUN addgroup -S app && adduser -S app -G app && \
+    mkdir -p /artifacts

@@
-# Copy built APKs from builder stage
-COPY --from=builder /app/build/app/outputs/flutter-apk/*.apk /artifacts/
+# Copy built APKs from builder stage
+COPY --from=builder --chown=app:app /app/build/app/outputs/flutter-apk/*.apk /artifacts/

@@
 # Set working directory
 WORKDIR /artifacts
+
+# Drop privileges
+USER app
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 159 - 191, The runtime stage runs as root; create a
non-root user and group (e.g., appuser/appgroup) in the runtime stage, chown
/artifacts to that user after creating the directory or after copying the APKs
from the builder stage, and switch to that user with the USER directive before
the WORKDIR/CMD so the container never runs as root; update references in this
Dockerfile runtime stage (COPY --from=builder, /artifacts, WORKDIR, CMD)
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@Dockerfile`:
- Around line 159-191: The runtime stage runs as root; create a non-root user
and group (e.g., appuser/appgroup) in the runtime stage, chown /artifacts to
that user after creating the directory or after copying the APKs from the
builder stage, and switch to that user with the USER directive before the
WORKDIR/CMD so the container never runs as root; update references in this
Dockerfile runtime stage (COPY --from=builder, /artifacts, WORKDIR, CMD)
accordingly.

@CowboyGH CowboyGH merged commit ea541bf into develop Feb 18, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: network API, requests, and data parsing type: feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant