5. CI/CD & Build Pipeline
CI/CD Pipeline Health
Build Automation80 / 100
Automated Testing in CI/CD0 / 100
Code Signing Security50 / 100
Deployment Process40 / 100
5.1 Build Configuration
Status: ⚠️Warning
Findings:
- No explicit Flutter version pinning:
codemagic.yamlusesflutter: fvmbut no.fvmrcfile existed in repository to pin specific version - Flutter version managed through Codemagic environment groups (
github_credentials) rather than repository-level configuration - SDK constraint allows Flutter 3.x but no explicit version specified in codebase
- CocoaPods version set to
default(not pinned to specific version like1.15.2) - Deprecated dependencies may block Flutter framework upgrades
- Fixed commit dependencies complicate upgrade process
- No version lock file to ensure reproducible builds across environments
- Build number calculation uses
PROJECT_BUILD_NUMBER + 14000offset (not automatic store API lookup)
Evidence:
codemagic.yaml(revision f8e2a6965abf2ddb2d41ad724ff7f930013b4965):flutter: fvm(uses FVM but no version specified)cocoapods: default(not pinned to specific version)- Environment groups:
github_credentials(notflutter_stg/flutter_prd) - No
.fvmrcfile in repository at that revision pubspec.yamlSDK constraint:>=3.0.0 <4.0.0(allows any 3.x version)- Deprecated packages (moor, device_info, etc.) may have compatibility issues with newer Flutter versions
- Flutter version depends on Codemagic group configuration (not visible in repository)
- Build scripts use
$(($PROJECT_BUILD_NUMBER + 14000))for version code calculation
Risk Level: Medium Risk
Recommendation:
- Immediate actions:
- Add
.fvmrcfile to pin Flutter version in repository - Pin CocoaPods version explicitly (e.g.,
1.15.2) - Document Flutter version in README or build documentation
- Ensure Codemagic groups use same Flutter version as
.fvmrc - Short-term:
- Plan incremental upgrades (e.g., current → latest 3.x → 4.0 when stable) aligned with dependency migrations
- Test Flutter upgrades in staging environment before production
- Resolve deprecated dependencies before major Flutter upgrades
- Use FVM to manage multiple Flutter versions during transition
- Use automatic build number from store APIs instead of offset calculation
5.2 Code Signing & Certificates
Status: ❌Fail
Findings:
- Critical: Sensitive signing credentials stored directly in repository
- Android keystore file (
tinq4u.keystore.jks) inandroid-src-files/ - Private keys (
private_key.pepk,deployment_cert.der,upload_cert.der) in repository - Google Play service account JSON with embedded private key in repository
- Apple Sign In private keys (
.p8files) in repository - Android signing configuration:
- Uses encrypted environment variables (
FCI_KEYSTORE,FCI_KEYSTORE_PASSWORD,FCI_KEY_PASSWORD,FCI_KEY_ALIAS) - Creates
key.propertiesfile dynamically from environment variables during build - Both staging and production workflows include Android signing setup
- Hardcoded path to service account in
android/fastlane/Appfile - iOS signing configuration:
- Uses App Store Connect credentials from environment variables (not Codemagic integration)
- Credentials:
APP_STORE_CONNECT_ID,APP_STORE_CONNECT_PASSWORD,APP_STORE_CONNECT_PRIVATE_KEY, etc. - Uses
app-store-connect fetch-signing-filesto fetch certificates and profiles - Keychain setup and certificate management in build scripts
- Build number management:
- Uses
PROJECT_BUILD_NUMBER + 14000offset calculation (not automatic store API lookup) - Version name extracted from Git tag (e.g.,
prod_1.2.3→1.2.3) - Potential for build number conflicts if not managed carefully
- Certificate management issues:
- No centralized certificate management
- Certificates and keys stored in multiple locations
- Sensitive files in repository despite encrypted variables in CI/CD
Evidence:
codemagic.yaml(revision f8e2a6965abf2ddb2d41ad724ff7f930013b4965):- Android signing: Encrypted environment variables for keystore credentials
- Script
set_key_properties: Createskey.propertiesfrom encrypted variables - iOS signing: Environment variables for App Store Connect credentials
- Scripts:
setup_keychain,setup_certificates,add_certificates,setup_provisioning_profiles - Build number:
$(($PROJECT_BUILD_NUMBER + 14000)) android-src-files/tinq4u.keystore.jks: Android signing keystore in repositoryandroid-src-files/private_key.pepk: Private key file in repositoryandroid-src-files/deployment_cert.der: Deployment certificate in repositoryandroid-src-files/upload_cert.der: Upload certificate in repositoryandroid-src-files/fastlane-serivce-account.json: Google Play service account with private keyapple-src-files/Signin-with-apple-AuthKey_63ZBT4A89B.p8: Apple Sign In private keyapple-src-files/ApplePushServices.certSigningRequest: Certificate signing requestsrc-assets/AuthKey_9BWX5U9947.p8: Additional Apple private keyandroid/fastlane/Appfileline 1: Hardcoded path:json_key_file("/Users/markedeer/FlutterApps/tinq4u.flutter.app/android-src-files/fastlane-serivce-account.json")android/app/build.gradlelines 32-36: Referenceskey.propertiesfor signing config
Risk Level: Critical Risk
Recommendation:
- Immediate actions:
- Remove all sensitive signing files from repository (after backing up to secure location)
- Move signing credentials to Codemagic secrets management or secure cloud storage
- Add sensitive directories to
.gitignore:android-src-files/,apple-src-files/,src-assets/ - Short-term:
- Consider using Codemagic's App Store Connect integration instead of environment variables
5.3 Automated Testing in CI/CD
Status: ❌Fail
Findings:
- No automated tests in CI/CD pipeline:
codemagic.yamldoes not include test execution steps - Builds can succeed even with broken code
- Missing quality gates in build process
Evidence:
codemagic.yaml(revision f8e2a6965abf2ddb2d41ad724ff7f930013b4965):- Workflow scripts (
tinq4u-prod,tinq4u-staging) do not includeflutter testcommands - No test execution steps in build scripts
- No test failure gates in build pipeline
- Scripts focus on dependency setup, signing, and building only
- No linting or static analysis steps visible
Risk Level: High Risk
Recommendation:
- Immediate actions:
- Add test execution steps to Codemagic workflows
- Run unit tests, widget tests, and golden tests before building
- Fail builds if critical tests fail
- Short-term:
- Run integration tests against staging environment in CI/CD
- Add linting and static analysis steps
5.4 Deployment Process
Status: ⚠️Warning
Findings:
- Separate tag-based deployment: Uses different Git tag patterns for staging and production (
staging_*vsprod_*) - Suboptimal tag management: Separate tags make it difficult to track which version is in staging vs production
- No clear promotion path: No mechanism to promote same artifact from staging to production
- Tag-based versioning: Version name extracted from tag (e.g.,
prod_1.2.3→ version1.2.3) - Build number offset: Uses
PROJECT_BUILD_NUMBER + 14000calculation instead of automatic store API lookup - GitFlow workflow: Makes it hard to track pending changes and current state
- Multiple long-lived branches: Create complexity and merge conflicts
- Difficult to identify deployed code: Hard to determine what code is currently deployed in each environment
- Unused CI/CD pipeline files:
jenkins/pipeline.groovyexists but project uses Codemagic - Dead code in repository: Jenkins pipeline configuration is no longer used
- Workflow naming: Uses
tinq4u-prodandtinq4u-stagingworkflow names
Evidence:
codemagic.yaml(revision f8e2a6965abf2ddb2d41ad724ff7f930013b4965):- Separate workflows:
tinq4u-prodandtinq4u-staging - Tag patterns:
prod_*for production,staging_*for staging - Version extraction from tag:
IN="$FCI_TAG"; arrIN=(${IN//_/ }); VERSION_NAME=${arrIN[1]} - Build number:
$(($PROJECT_BUILD_NUMBER + 14000)) - Separate bundle IDs for staging (
nl.tinq4u.tinq4u-app-staging) and production (nl.tinq4u.tinq4u-app) - Different entry points:
lib/main.dart(staging) vslib/main_prod.dart(production) - GitFlow branching model in use (based on audit finding)
jenkins/pipeline.groovycontains placeholder pipeline code (not actively used)- No references to Jenkins in codebase or documentation
- Project uses Codemagic for CI/CD (evident from
codemagic.yaml)
Risk Level: Medium Risk
Recommendation:
- Immediate actions:
- Migrate from GitFlow to trunk-based development workflow
- Implement single tag approach: tag once, deploy to staging, then promote same tag to production after approval
- Finish and merge all hanging changes from feature branches
- Clean up unused CI/CD files (remove
jenkins/directory) - Short-term:
- Implement deployment promotion pipeline: staging → production using same build artifact
- Simplify branching: main/master as primary branch, short-lived feature branches
- Add deployment notifications