-
Notifications
You must be signed in to change notification settings - Fork 0
R2.1.0 #62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
R2.1.0 #62
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| # Codecov Configuration for RepForge (Devasy/RepForge) | ||
| codecov: | ||
| require_ci_to_pass: yes | ||
|
|
||
| coverage: | ||
| precision: 2 | ||
| round: down | ||
| range: "70...100" | ||
|
|
||
| status: | ||
| project: | ||
| default: | ||
| target: auto | ||
| threshold: 1% | ||
| patch: | ||
| default: | ||
| target: auto | ||
|
|
||
| ignore: | ||
| - "**/*.g.dart" | ||
| - "**/*.freezed.dart" | ||
| - "workout-logger/test/**/*" |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,6 +6,10 @@ on: | |||||||||||||||||||||||||||||||||
| - main | ||||||||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| concurrency: | ||||||||||||||||||||||||||||||||||
| group: release-${{ github.ref }} | ||||||||||||||||||||||||||||||||||
| cancel-in-progress: false | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||
| release: | ||||||||||||||||||||||||||||||||||
| name: Build and Release APK | ||||||||||||||||||||||||||||||||||
|
|
@@ -18,17 +22,20 @@ jobs: | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||
| - name: Checkout repository | ||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v7 | ||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||
| fetch-depth: 0 # Fetch all history for proper versioning | ||||||||||||||||||||||||||||||||||
| token: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Set up Java | ||||||||||||||||||||||||||||||||||
| uses: actions/setup-java@v4 | ||||||||||||||||||||||||||||||||||
| uses: actions/setup-java@v5 | ||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||
| distribution: 'temurin' | ||||||||||||||||||||||||||||||||||
| java-version: '17' | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Setup Gradle Build Cache | ||||||||||||||||||||||||||||||||||
| uses: gradle/actions/setup-gradle@v6 | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Set up Flutter | ||||||||||||||||||||||||||||||||||
| uses: subosito/flutter-action@v2 | ||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||
|
|
@@ -117,6 +124,10 @@ jobs: | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Decode release keystore | ||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||
| if [ -z "${{ secrets.KEYSTORE_BASE64 }}" ]; then | ||||||||||||||||||||||||||||||||||
| echo "Error: KEYSTORE_BASE64 secret is not configured in repository secrets." | ||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+127
to
+130
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Validate all release-signing secrets before the build. Lines 127-130 validate only Proposed fix - name: Decode release keystore
+ env:
+ KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
+ KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
+ KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
+ KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
run: |
- if [ -z "${{ secrets.KEYSTORE_BASE64 }}" ]; then
- echo "Error: KEYSTORE_BASE64 secret is not configured in repository secrets."
- exit 1
- fi
- echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > /tmp/repforge-release.jks
+ : "${KEYSTORE_BASE64:?KEYSTORE_BASE64 is not configured}"
+ : "${KEY_STORE_PASSWORD:?KEY_STORE_PASSWORD is not configured}"
+ : "${KEY_ALIAS:?KEY_ALIAS is not configured}"
+ : "${KEY_PASSWORD:?KEY_PASSWORD is not configured}"
+ printf '%s' "$KEYSTORE_BASE64" | base64 --decode > /tmp/repforge-release.jks📝 Committable suggestion
Suggested change
🧰 Tools🪛 zizmor (1.29.0)[warning] 127-127: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > /tmp/repforge-release.jks | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Build APK | ||||||||||||||||||||||||||||||||||
|
|
@@ -126,7 +137,7 @@ jobs: | |||||||||||||||||||||||||||||||||
| KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }} | ||||||||||||||||||||||||||||||||||
| KEY_ALIAS: ${{ secrets.KEY_ALIAS }} | ||||||||||||||||||||||||||||||||||
| KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} | ||||||||||||||||||||||||||||||||||
| run: flutter build apk --release --split-per-abi | ||||||||||||||||||||||||||||||||||
| run: flutter build apk --release --split-per-abi --obfuscate --split-debug-info=build/app/outputs/symbols | ||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files | rg '(^|/)release\.yml$|workflow|flutter|build|artifact|symbol|crash' || true
echo
echo "== release workflow around build/artifact/release =="
if [ -f .github/workflows/release.yml ]; then
nl -ba .github/workflows/release.yml | sed -n '1,240p'
fi
echo
echo "== search for build/app/outputs/symbols and symbol upload mentions =="
rg -n "split-debug-info|build/app/outputs/symbols|flutter symbol|firebase crash|sentry|crash" .github . -g '!**/*.png' -g '!**/*.svg' || true
echo
echo "== workflow uses/references related to symbols/artifacts =="
rg -n "upload-artifact|download-artifact|split-debug-info|split-per-abi|obfuscate" . -g '*.yml' -g '*.yaml' || trueRepository: Devasy/RepForge Length of output: 840 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== release workflow lines =="
if [ -f .github/workflows/release.yml ]; then
awk '{printf "%6d\t%s\n", NR, $0}' .github/workflows/release.yml | sed -n '1,240p'
fi
echo
echo "== search for symbol-related references =="
rg -n "split-debug-info|build/app/outputs/symbols|flutter symbol|firebase crash|sentry|crash|upload-artifact|download-artifact|split-per-abi|obfuscate" .github workout-logger scripts . -g '*.yml' -g '*.yaml' -g '*.py' -g '*.gradle*' -g '*.dart' -g '!**/*.png' -g '!**/*.svg' || trueRepository: Devasy/RepForge Length of output: 10250 🌐 Web query:
💡 Result: When running a Flutter build with the --split-debug-info flag, the output location for debug symbols is determined by the directory path you explicitly provide as an argument to the flag [1][2]. The flag syntax is: flutter build --split-debug-info=/ [1][2] Key details regarding the output location: - User-Defined Path: You specify the directory path where Flutter should save the symbol files [1][2]. For example, using --split-debug-info=out/android will create a directory named out/android (relative to your project root) and place the generated symbol files there [3][2]. - Not Automatic: Flutter does not place these symbols in a default build folder unless you explicitly direct it to do so (e.g., --split-debug-info=build/app/outputs/symbols) [3]. - Purpose: This command generates symbol map files (e.g., app.android-arm.symbols), which are essential for de-obfuscating stack traces from crash reports [1][4][5]. - Persistence: It is recommended to store these symbols outside of ephemeral build directories (like the standard build/ folder), as they may be cleared by a flutter clean command [4]. Developers often commit these files to version control or an external symbol storage service to ensure they are available for future debugging sessions [4]. Citations:
Persist the obfuscation symbol files after the APK builds. Line 140 writes split-debug-info files to 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Rename APKs | ||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||
|
|
@@ -150,7 +161,7 @@ jobs: | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Create GitHub Release | ||||||||||||||||||||||||||||||||||
| if: github.event_name == 'push' && steps.commit_version.outputs.committed == 'true' | ||||||||||||||||||||||||||||||||||
| uses: softprops/action-gh-release@v2 | ||||||||||||||||||||||||||||||||||
| uses: softprops/action-gh-release@v3 | ||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||
| tag_name: v${{ steps.version.outputs.value }} | ||||||||||||||||||||||||||||||||||
| name: RepForge v${{ steps.version.outputs.value }} | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,20 +2,31 @@ name: Test | |
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| branches: | ||
| - main | ||
| - 'r[0-9]+.[0-9]+.*' | ||
| pull_request: | ||
| branches: [main] | ||
| branches: | ||
| - main | ||
| - 'r[0-9]+.[0-9]+.*' | ||
| release: | ||
| types: [published] | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | ||
|
|
||
| jobs: | ||
| test: | ||
| name: Analyze & Test | ||
| runs-on: ubuntu-latest | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 | ||
| uses: actions/checkout@v7 | ||
|
|
||
| - name: Set up Flutter | ||
| id: flutter-action | ||
|
|
@@ -28,13 +39,14 @@ jobs: | |
| pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-${{ hashFiles('workout-logger/pubspec.lock') }}" | ||
|
|
||
| - name: Install dependencies | ||
| if: steps.flutter-action.outputs.PUB-CACHE-HIT != 'true' | ||
| if: steps.flutter-action.outputs.CACHE-HIT != 'true' | ||
| working-directory: ./workout-logger | ||
| run: flutter pub get | ||
|
Comment on lines
+42
to
44
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== workflow excerpt =="
sed -n '1,140p' .github/workflows/test.yml 2>/dev/null || true
echo
echo "== related files =="
git ls-files | rg '(^|/)(pubspec\.yaml|\.dart_tool/package_config\.json|workflows/test\.yml)$' || true
echo
echo "== pubspec/package_config references =="
rg -n "pubspec|package_config|flutter pub get|CACHE-HIT|flutter-analyz|flutter test" .github workout-logger pubspec.yaml 2>/dev/null || true
echo
echo "== git status =="
git status --shortRepository: Devasy/RepForge Length of output: 3559 🌐 Web query:
💡 Result: The Citations:
🌐 Web query:
💡 Result: In the context of the subosito/flutter-action GitHub Action, CACHE-HIT and PUB-CACHE-HIT are output variables that provide information about the status of the Flutter SDK and Dart pub dependencies caches, respectively [1][2]. These outputs are defined in the action's configuration (action.yaml) to allow users to conditionally execute steps based on whether a cache was restored successfully [1][2]. Specifically: CACHE-HIT: Indicates whether the Flutter SDK cache was a hit (returns 'true' if there is an exact match for the cache key) [1]. PUB-CACHE-HIT: Indicates whether the Dart pub dependencies cache was a hit (returns 'true' if there is an exact match for the cache key) [1]. These values are sourced directly from the cache-hit output of the underlying actions/cache step used within the action [3][4]. They are commonly used in workflow YAML files to skip redundant installation or setup steps, such as bootstrapping dependencies, when a valid cache already exists [2][5]. Example usage in a workflow: - name: Set up Flutter uses: subosito/flutter-action@v2 id: flutter-action with: cache: true pub-cache: true - name: Conditionally run setup if: steps.flutter-action.outputs.PUB-CACHE-HIT!= 'true' run: dart pub get Citations:
🌐 Web query:
💡 Result: Relevant official Dart/Flutter documentation:
The original query returned no exact Run dependency resolution when the Flutter SDK cache hits.
🤖 Prompt for AI Agents |
||
|
|
||
| - name: Analyze | ||
| working-directory: ./workout-logger | ||
| run: | | ||
| set -o pipefail | ||
| # Only fail on errors, ignore warnings and info messages | ||
| flutter analyze --no-fatal-infos --no-fatal-warnings | tee analyze_output.txt | ||
|
|
||
|
|
@@ -53,3 +65,5 @@ jobs: | |
| with: | ||
| files: workout-logger/coverage/lcov.info | ||
| token: ${{ secrets.CODECOV_TOKEN }} | ||
| slug: Devasy/RepForge | ||
|
|
||
|
Comment on lines
+68
to
+69
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Remove the added empty line. The configured YAML linter rejects the empty line after 🧰 Tools🪛 YAMLlint (1.37.1)[error] 69-69: too many blank lines (1 > 0) (empty-lines) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,28 @@ | ||
| import com.android.build.gradle.internal.api.ApkVariantOutputImpl | ||
| import java.io.FileInputStream | ||
| import java.util.Properties | ||
|
Comment on lines
+2
to
+3
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Locate build.gradle.kts files:"
fd -a 'build\.gradle\.kts$' . | sed 's#^\./##' | head -50
echo
echo "Inspect workout-logger/android/app/build.gradle.kts:"
wc -l workout-logger/android/app/build.gradle.kts
sed -n '1,90p' workout-logger/android/app/build.gradle.kts
echo
echo "Search all keyProperties.load/FileInputStream patterns:"
rg -n "keyProperties\.load|FileInputStream|load\(FileInputStream|inputStream\(\)\.use|use \{" -S workout-logger/android/app/build.gradle.kts .Repository: Devasy/RepForge Length of output: 4815 🌐 Web query:
💡 Result: In Kotlin, the Citations:
Close the properties file stream.
🤖 Prompt for AI Agents |
||
|
|
||
| plugins { | ||
| id("com.android.application") | ||
| id("kotlin-android") | ||
| // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. | ||
| // kotlin-android is injected automatically by Flutter's built-in Kotlin support. | ||
| // (android.builtInKotlin=true in gradle.properties) | ||
| id("dev.flutter.flutter-gradle-plugin") | ||
| } | ||
|
|
||
| android { | ||
| namespace = "com.devasy.repforge" | ||
| compileSdk = 36 | ||
| compileSdkExtension = 19 | ||
| compileSdk = 37 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
rg -n \
'com\.android\.application.*version|compileSdk|targetSdk|distributionUrl' \
workout-logger/android/settings.gradle.kts \
workout-logger/android/app/build.gradle.kts \
workout-logger/android/gradle/wrapper/gradle-wrapper.propertiesRepository: Devasy/RepForge Length of output: 546 🌐 Web query:
💡 Result: Android Gradle Plugin (AGP) 8.11.1 does not support compiling against or targeting API 37 [1][2][3]. According to official Android documentation, AGP 8.11 supports a maximum API level of 36 [1][2]. Specifically, the minimum AGP version required to support API 37 is 9.1.1 [3][4]. If your project requires API 37 (Android 17), you must upgrade to a compatible version of the Android Gradle Plugin, such as AGP 9.1.1 or higher, and ensure you are using the corresponding version of Android Studio [3][5][4]. Citations:
🌐 Web query:
💡 Result: As of August 7, 2026, Android Gradle Plugin (AGP) 9.1.1 is fully compatible with Gradle 9.3.1 and supports Android API level 37.0 [1][2][3]. The following compatibility details apply: - Gradle Compatibility: AGP 9.1.1 explicitly requires a minimum Gradle version of 9.3.1 [1][2]. - API Level Support: AGP 9.1.1 provides support for Android API level 37.0 and below [1][2]. - Java Compatibility: Gradle 9.3.1 requires Java Development Kit (JDK) version 17 or higher to run [4]. It is recommended to use the default version (9.3.1) for both the plugin and Gradle for optimal performance and compatibility [1][2]. Citations:
🌐 Web query:
💡 Result: The Android Gradle Plugin (AGP) version 8.11 requires a minimum Gradle version of 8.13 [1][2][3]. Official Android developer documentation specifies that AGP 8.11 must be used with Gradle 8.13 [1][2]. While release notes for AGP 8.11.0 (and by extension 8.11.1) explicitly list Gradle 8.13 as both the minimum and default version [2][3], the broader compatibility table confirms that AGP 8.11 requires Gradle 8.13 [1]. Note that Gradle compatibility requirements are generally tied to the major and minor version of the Android Gradle Plugin (e.g., AGP 8.11.x) [1][2]. [1][2][3] Citations:
🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
echo "== relevant Gradle files =="
for f in \
workout-logger/android/settings.gradle.kts \
workout-logger/android/app/build.gradle.kts \
workout-logger/android/gradle/wrapper/gradle-wrapper.properties
do
echo "--- $f"
sed -n '1,90p' "$f"
doneRepository: Devasy/RepForge Length of output: 5149 Upgrade AGP before targeting Android API 37.
🤖 Prompt for AI AgentsSource: MCP tools |
||
| ndkVersion = flutter.ndkVersion | ||
|
|
||
| compileOptions { | ||
| sourceCompatibility = JavaVersion.VERSION_11 | ||
| targetCompatibility = JavaVersion.VERSION_11 | ||
| sourceCompatibility = JavaVersion.VERSION_17 | ||
| targetCompatibility = JavaVersion.VERSION_17 | ||
| } | ||
|
|
||
| kotlinOptions { | ||
| jvmTarget = JavaVersion.VERSION_11.toString() | ||
| kotlin { | ||
| compilerOptions { | ||
| jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 | ||
| } | ||
| } | ||
|
|
||
| // Strip AGP's "Dependency metadata" signing block from the APK. It embeds a | ||
|
|
@@ -33,11 +36,16 @@ android { | |
|
|
||
| signingConfigs { | ||
| create("release") { | ||
| val keystorePath = System.getenv("KEYSTORE_PATH") | ||
| val storePass = System.getenv("KEY_STORE_PASSWORD") | ||
| val alias = System.getenv("KEY_ALIAS") | ||
| val keyPass = System.getenv("KEY_PASSWORD") | ||
| if (keystorePath != null && storePass != null && alias != null && keyPass != null) { | ||
| val keyProperties = Properties() | ||
| val keyPropertiesFile = rootProject.file("key.properties") | ||
| if (keyPropertiesFile.exists()) { | ||
| keyProperties.load(FileInputStream(keyPropertiesFile)) | ||
| } | ||
| val keystorePath = System.getenv("KEYSTORE_PATH") ?: keyProperties.getProperty("storeFile") | ||
| val storePass = System.getenv("KEY_STORE_PASSWORD") ?: keyProperties.getProperty("storePassword") | ||
| val alias = System.getenv("KEY_ALIAS") ?: keyProperties.getProperty("keyAlias") | ||
| val keyPass = System.getenv("KEY_PASSWORD") ?: keyProperties.getProperty("keyPassword") | ||
| if (!keystorePath.isNullOrEmpty() && !storePass.isNullOrEmpty() && !alias.isNullOrEmpty() && !keyPass.isNullOrEmpty()) { | ||
|
Comment on lines
+44
to
+48
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
for name in KEYSTORE_PATH KEY_STORE_PASSWORD KEY_ALIAS KEY_PASSWORD; do
if [[ -z "${!name:-}" ]]; then
printf 'Missing release signing input: %s\n' "$name" >&2
exit 1
fi
done
test -f "$KEYSTORE_PATH"Repository: Devasy/RepForge Length of output: 198 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
echo "== build.gradle.kts =="
wc -l workout-logger/android/app/build.gradle.kts
sed -n '1,140p' workout-logger/android/app/build.gradle.kts
echo
echo "== release workflow candidates =="
fd -a 'release.*' .github/workflows | sed 's#^\./##' || true
for f in $(fd 'release.*' .github/workflows 2>/dev/null || true); do
echo "--- $f"
wc -l "$f"
sed -n '1,220p' "$f"
done
echo
echo "== signing config usages =="
rg -n "signingConfigs|release|debug|KEYSTORE|storeFile|keyAlias|KEY_STORE_PASSWORD|KEY_PASSWORD|KEYSTORE_BASE64" workout-logger/android .github/workflows -SRepository: Devasy/RepForge Length of output: 16872 🌐 Web query:
💡 Result: There is no property, method, or DSL element named "signingWith" within the Android Gradle Plugin's SigningConfig API [1][2][3][4]. The confusion likely stems from the standard way to associate a signing configuration with a build type, which uses the property name signingConfig [5]. To configure signing in your Android project, you define a SigningConfig object within the android block of your build.gradle file and then assign it to a build type using the signingConfig property [5]. Example usage: android { signingConfigs { release { storeFile file("my-release-key.jks") storePassword "password" keyAlias "my-alias" keyPassword "password" } } buildTypes { release { // This is the correct property, not "signingWith" signingConfig signingConfigs.release } } } The SigningConfig API itself provides properties such as keyAlias, keyPassword, storeFile, storePassword, and methods to enable specific signature schemes (e.g., enableV1Signing, enableV2Signing) [1][2][3][4]. The initWith method is also available for copying properties from another existing SigningConfig [1][3][4]. Citations:
Fail closed for missing release signing inputs. The env variable fallback uses 🧰 Tools🪛 detekt (1.23.8)[warning] 48-48: This condition is too complex (4). Defined complexity threshold for conditions is set to '4' (detekt.complexity.ComplexCondition) 🤖 Prompt for AI AgentsSources: MCP tools, Linters/SAST tools |
||
| storeFile = file(keystorePath) | ||
| storePassword = storePass | ||
| keyAlias = alias | ||
|
|
@@ -53,7 +61,7 @@ android { | |
| // supported. If downgrading, remove the health_connector dependency and | ||
| // all HealthConnectService usages, then restore minSdk to flutter.minSdkVersion. | ||
| minSdk = 26 | ||
| targetSdk = 36 | ||
| targetSdk = 37 | ||
| versionCode = flutter.versionCode | ||
| versionName = flutter.versionName | ||
| // App display name; overridden per build type below so debug installs | ||
|
|
@@ -71,6 +79,12 @@ android { | |
| manifestPlaceholders["appLabel"] = "RepForge (Debug)" | ||
| } | ||
| release { | ||
| isMinifyEnabled = true | ||
| isShrinkResources = true | ||
| proguardFiles( | ||
| getDefaultProguardFile("proguard-android-optimize.txt"), | ||
| "proguard-rules.pro" | ||
| ) | ||
| // Uses the production EC P-256 keystore when KEYSTORE_PATH env var is set | ||
| // (CI injects it via GitHub Secrets). Falls back to the debug key for a | ||
| // local `flutter run --release` without env vars configured. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Suppress missing class warnings for Play Core deferred components in Flutter engine | ||
| -dontwarn com.google.android.play.core.** | ||
|
|
||
| # Flutter Wrapper Rules | ||
| -keep class io.flutter.app.** { *; } | ||
| -keep class io.flutter.plugin.** { *; } | ||
| -keep class io.flutter.util.** { *; } | ||
| -keep class io.flutter.view.** { *; } | ||
| -keep class io.flutter.embedding.** { *; } | ||
| -keep class io.flutter.provider.** { *; } | ||
| -keep class io.flutter.plugin.editing.** { *; } | ||
|
|
||
| # Keep Native plugins and Health Connect interfaces | ||
| -dontwarn com.google.android.gms.** |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,7 @@ | ||
| org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError | ||
| android.useAndroidX=true | ||
| android.enableJetifier=true | ||
| # This builtInKotlin flag was added automatically by Flutter migrator | ||
| android.builtInKotlin=true | ||
| # This newDsl flag was added automatically by Flutter migrator | ||
| android.newDsl=true | ||
|
Comment on lines
+4
to
+7
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files | rg '(^|/)gradle\.properties$|(^|/)build\.gradle\.kts$|(^|/)settings\.gradle\.kts$|flutter\.dart$|pubspec\.yaml$|packages\.txt$|\.flutter$|android/build\.gradle\.kts$|workout-logger' | sed -n '1,160p'
echo
echo "== workout-logger files =="
git ls-files workout-logger | sed -n '1,200p'
echo
echo "== relevant files =="
for f in workout-logger/android/gradle.properties workout-logger/android/settings.gradle.kts workout-logger/android/app/build.gradle.kts; do
if [ -f "$f" ]; then
echo "--- $f ($(wc -l < "$f") lines) ---"
cat -n "$f" | sed -n '1,120p'
fi
done
echo
echo "== git diff stat =="
git diff --stat || true
echo
echo "== diff relevant files =="
git diff -- workout-logger/android/gradle.properties workout-logger/android/settings.gradle.kts workout-logger/android/app/build.gradle.kts | sed -n '1,240p' || true
echo
echo "== search flutter/AGP pins =="
rg -n 'flutter|version:|android\.gradle\.plugin|com\.android\.application|kotlin-android|builtInKotlin|newDsl' workout-logger pubspec.yaml packages.yaml README.md 2>/dev/null | sed -n '1,240p' || trueRepository: Devasy/RepForge Length of output: 43278 🌐 Web query:
💡 Result: With the release of Android Gradle Plugin (AGP) 9.0, Android introduced built-in Kotlin support and a new Domain-Specific Language (DSL) [1][2]. Flutter 3.47 is the version that officially introduced support for enabling these AGP 9.0 features [3]. Key technical details regarding these configurations include: 1. Built-in Kotlin: AGP 9.0 enables built-in Kotlin by default, which removes the need to explicitly apply the Citations:
Keep the built-in Kotlin migration, Flutter version, and AGP version consistent. These flags enable AGP built-in Kotlin/new DSL support, but the repository still pins Flutter 3.44.8 and AGP 8.11.1. Upgrade the Android toolchain to AGP 9+ with Flutter 3.47+, or keep the migration flags disabled and retain the existing legacy Kotlin Gradle Plugin configuration. 📍 Affects 2 files
🤖 Prompt for AI AgentsSource: MCP tools |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # Local Android Release Keystore Configuration | ||
| # Fill in your local keystore path and passwords below. | ||
| # Note: This file should NEVER be committed to Git. | ||
|
|
||
| storeFile=C:/path/to/your/upload-keystore.jks | ||
| storePassword=your_store_password | ||
| keyAlias=your_key_alias | ||
| keyPassword=your_key_password |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: Devasy/RepForge
Length of output: 1190
🌐 Web query:
GitHub Actions recommended secure workflow pinning commit SHA version tags💡 Result:
To secure GitHub Actions workflows against supply chain attacks, GitHub and security experts strongly recommend pinning actions to a full-length (40-character) commit SHA [1][2][3][4]. Why Pinning to Commit SHAs is Necessary Standard version tags (e.g.,
@v4) are mutable references [3][4][5]. If an action's repository is compromised, an attacker can overwrite these tags to point to malicious code, which your workflows would then automatically execute [6][3][4][7]. Because Git tags can be moved or deleted, they do not guarantee that the code running today is the same code you audited previously [8][5][9]. A full-length commit SHA, by contrast, is a unique, immutable cryptographic digest [6][8][9]. Pinning to a specific SHA ensures your workflow always executes the exact code you intended, preventing silent, malicious updates [6][4][5][9]. Recommended Implementation To maintain both security and ease of maintenance, follow these best practices: 1. Use Full-Length SHAs: Always use the 40-character full commit SHA. Never use shortened SHAs, as they are susceptible to collision attacks [1][2][8]. 2. Keep Human-Readable References: Include the version tag as a trailing comment in your workflow file (e.g., uses: actions/checkout@a1b2c3d4e5f6... # v4.2.0) [3][4][9]. This allows automated dependency management tools like Dependabot and Renovate to detect new versions and open pull requests, ensuring you can update your actions securely while maintaining immutability [3][4][7]. 3. Enforce via Policy: If you are an administrator, you can enforce this security standard across your organization or enterprise by enabling the GitHub Actions policy that requires actions to be pinned to a full-length commit SHA [6][2][5]. When enabled, any workflow using a mutable reference (tags or branches) will fail [6][5]. Security Note: While SHA pinning prevents tag-retargeting attacks, it does not protect against code that was already malicious at the time of the initial pin [7]. Always continue to vet the actions and authors you choose to include in your pipelines [10][11].Citations:
🌐 Web query:
actions/checkout release v5 v4 tag commit SHA💡 Result:
In the actions/checkout repository, both v4 and v5 are major release versions [1][2]. The transition from v4 to v5 primarily involved updating the underlying Node.js runtime from Node.js 20 to Node.js 24 [3][4][5]. This update requires the use of GitHub Actions runners with version v2.327.1 or higher [5]. Regarding the use of "tag" or "commit SHA" with these versions: 1. Usage: You can reference any specific version (v4, v5, v6, v7, etc.) in your workflow file using the syntax actions/checkout@v [4][6][2]. 2. Specifying Ref/SHA: Regardless of the action version used (
@v4,@v5, etc.), you can checkout a specific branch, tag, or commit SHA by using the ref input [2][7]. Example: - uses: actions/checkout@v5 with: ref: By default, the action checks out the ref or SHA that triggered the workflow [5][2]. Specifying a ref in the with block allows you to override this default behavior [2][7].Citations:
Pin the remaining GitHub Actions to full commit hashes.
The listed mutable action tags can move or be replaced, changing pipeline behavior without a repository commit. Pin each action to a full 40-character commit SHA and keep the release name in a trailing comment.
🧰 Tools
🪛 zizmor (1.29.0)
[error] 25-25: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
📍 Affects 2 files
.github/workflows/release.yml#L25-L25(this comment).github/workflows/release.yml#L31-L31.github/workflows/release.yml#L37-L37.github/workflows/release.yml#L164-L164.github/workflows/test.yml#L29-L29🤖 Prompt for AI Agents
Source: Linters/SAST tools