Skip to content

Commit fb3f319

Browse files
committed
run dump
1 parent 53f4f22 commit fb3f319

2 files changed

Lines changed: 576 additions & 89 deletions

File tree

docs/llm/dump.txt

Lines changed: 121 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
===============================================================================
22
PROJECT EXPORT (GIT TRACKED ONLY)
3-
Generated: Sun Apr 5 12:05:45 PM EDT 2026
3+
Generated: Sun Apr 5 12:36:10 PM EDT 2026
44
Project Path: /home/kushal/src/kotlin/Seal
55
===============================================================================
66

@@ -913,7 +913,7 @@ jobs:
913913

914914
================================================================================
915915
FILE: .github/workflows/android_ci.yml
916-
SIZE: .58 KB
916+
SIZE: .63 KB
917917
================================================================================
918918

919919
name: Android CI
@@ -922,16 +922,18 @@ on:
922922
pull_request:
923923
branches: [ "main" ]
924924

925+
env:
926+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
927+
925928
jobs:
926929
build:
927-
928930
runs-on: ubuntu-latest
929931

930932
steps:
931933
- uses: actions/checkout@v4
932934

933-
- name: set up JDK 21
934-
uses: actions/setup-java@v3
935+
- name: Set up JDK 21
936+
uses: actions/setup-java@v4
935937
with:
936938
java-version: '21'
937939
distribution: 'temurin'
@@ -940,9 +942,11 @@ jobs:
940942
- name: Setup Android SDK
941943
uses: android-actions/setup-android@v3
942944

943-
- uses: gradle/actions/setup-gradle@v3
945+
- uses: gradle/actions/setup-gradle@v4
946+
944947
- name: Grant execute permission for gradlew
945948
run: chmod +x gradlew
949+
946950
- name: Build with Gradle
947951
run: ./gradlew buildGenericRelease
948952

@@ -970,14 +974,18 @@ jobs:
970974

971975
================================================================================
972976
FILE: .github/workflows/release.yml
973-
SIZE: 7.42 KB
977+
SIZE: 7.55 KB
974978
================================================================================
975979

976980
# .github/workflows/release.yml
977981
#
978982
# Triggers on every push to `main` and produces a signed, full (non-pre-release)
979983
# GitHub Release from the `generic` product flavor.
980984
#
985+
# Version auto-bumps on every build using a timestamp-based scheme:
986+
# Tag format: v2.0.0-alpha.YYYYMMDD.HHMM
987+
# This ensures every push gets a unique, monotonically increasing version.
988+
#
981989
# Required GitHub Secrets (Settings → Secrets and variables → Actions):
982990
# ANDROID_KEYSTORE_BASE64 – base64-encoded android.keystore file
983991
# ANDROID_SIGNING_PASSWORD – password used for both storePassword and keyPassword
@@ -989,8 +997,12 @@ on:
989997
branches:
990998
- main
991999

1000+
# Opt into Node.js 24 to silence the deprecation warnings.
1001+
env:
1002+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
1003+
9921004
# Only allow one release workflow to run at a time; cancel any in-progress run
993-
# if a new push arrives before it finishes. This prevents duplicate releases.
1005+
# if a new push arrives before it finishes.
9941006
concurrency:
9951007
group: release-${{ github.ref }}
9961008
cancel-in-progress: true
@@ -1000,8 +1012,6 @@ jobs:
10001012
name: Build & Publish Release
10011013
runs-on: ubuntu-latest
10021014

1003-
# Give the job permission to create releases and upload assets.
1004-
# "contents: write" is required by softprops/action-gh-release.
10051015
permissions:
10061016
contents: write
10071017

@@ -1010,8 +1020,6 @@ jobs:
10101020
- name: Checkout source
10111021
uses: actions/checkout@v4
10121022
with:
1013-
# Fetch the full history so the tag we create doesn't conflict with
1014-
# any shallow-clone limitation.
10151023
fetch-depth: 0
10161024

10171025
# ── 2. Java / Gradle toolchain ─────────────────────────────────────────
@@ -1020,7 +1028,6 @@ jobs:
10201028
with:
10211029
java-version: '21'
10221030
distribution: 'temurin'
1023-
# Caches ~/.gradle/caches and ~/.gradle/wrapper between runs.
10241031
cache: 'gradle'
10251032

10261033
# ── 3. Android SDK ─────────────────────────────────────────────────────
@@ -1029,105 +1036,119 @@ jobs:
10291036

10301037
# ── 4. Gradle wrapper ──────────────────────────────────────────────────
10311038
- name: Set up Gradle
1032-
uses: gradle/actions/setup-gradle@v3
1039+
uses: gradle/actions/setup-gradle@v4
10331040

10341041
- name: Make gradlew executable
10351042
run: chmod +x gradlew
10361043

1037-
# ── 5. Reconstruct the keystore from the base64 secret ─────────────────
1044+
# ── 5. Generate auto-bumping version ───────────────────────────────────
1045+
#
1046+
# We read the base version from buildSrc/Version.kt (e.g. "2.0.0-alpha")
1047+
# and append a timestamp suffix so every push gets a unique version.
1048+
#
1049+
# Format: <base>.<YYYYMMDD>.<HHMM>
1050+
# Example: 2.0.0-alpha.20260405.1614
10381051
#
1039-
# We write the keystore to a path that is outside the repo tree so it is
1040-
# never accidentally committed. RUNNER_TEMP is a per-job temp directory
1041-
# that GitHub Actions provides; it is automatically cleaned up afterward.
1052+
# The versionCode is derived from the Unix timestamp to guarantee it
1053+
# always increases (Android requires versionCode to be monotonically
1054+
# increasing for updates).
1055+
- name: Generate version
1056+
id: version
1057+
run: |
1058+
# Get base version from Gradle (e.g. "2.0.0-alpha.5")
1059+
BASE_VERSION=$(./gradlew -q printVersionName --no-configuration-cache 2>/dev/null || echo "")
1060+
1061+
# Strip trailing build number if present (e.g. "2.0.0-alpha.5" -> "2.0.0-alpha")
1062+
# This gives us the stable prefix to append our timestamp to.
1063+
BASE_PREFIX=$(echo "$BASE_VERSION" | sed -E 's/\.(alpha|beta|rc)\.([0-9]+)$/.\1/')
1064+
1065+
# If we couldn't parse it, fall back to commit-based version
1066+
if [ -z "$BASE_PREFIX" ]; then
1067+
BASE_PREFIX="0.0.0-dev"
1068+
fi
1069+
1070+
# Timestamp components (UTC)
1071+
DATE_PART=$(date -u +%Y%m%d)
1072+
TIME_PART=$(date -u +%H%M)
1073+
1074+
# Final version name: e.g. "2.0.0-alpha.20260405.1614"
1075+
VERSION_NAME="${BASE_PREFIX}.${DATE_PART}.${TIME_PART}"
1076+
1077+
# versionCode: Unix timestamp divided by 60 (fits in int32 until 2038+)
1078+
# This guarantees monotonic increase and stays well within Android's
1079+
# versionCode limit of 2,100,000,000.
1080+
EPOCH=$(date -u +%s)
1081+
VERSION_CODE=$((EPOCH / 60))
1082+
1083+
echo "name=$VERSION_NAME" >> "$GITHUB_OUTPUT"
1084+
echo "code=$VERSION_CODE" >> "$GITHUB_OUTPUT"
1085+
echo "Generated version: $VERSION_NAME (code: $VERSION_CODE)"
1086+
1087+
# ── 6. Reconstruct the keystore ────────────────────────────────────────
10421088
- name: Decode keystore
10431089
env:
10441090
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
10451091
run: |
10461092
echo "$ANDROID_KEYSTORE_BASE64" | base64 --decode > "$RUNNER_TEMP/android.keystore"
10471093

1048-
# ── 6. Write keystore.properties ───────────────────────────────────────
1049-
#
1050-
# app/build.gradle.kts already contains logic to read this file:
1051-
#
1052-
# val keystorePropertiesFile = rootProject.file("keystore.properties")
1053-
# if (keystorePropertiesFile.exists()) { ... }
1094+
# ── 7. Write keystore.properties ───────────────────────────────────────
10541095
#
1055-
# By writing it here at build time (and NOT committing it to git), we
1056-
# keep credentials out of version control entirely.
1057-
#
1058-
# Key names must match exactly what build.gradle.kts reads:
1059-
# keystoreProperties["keyAlias"] → alias used in keytool -alias
1060-
# keystoreProperties["keyPassword"] → -keypass value
1061-
# keystoreProperties["storeFile"] → absolute path to .keystore
1062-
# keystoreProperties["storePassword"] → -storepass value
1096+
# CRITICAL: No leading whitespace! Properties.load() will include spaces
1097+
# in key names if the lines are indented, causing silent signing failure.
10631098
- name: Write keystore.properties
10641099
env:
10651100
ANDROID_SIGNING_PASSWORD: ${{ secrets.ANDROID_SIGNING_PASSWORD }}
10661101
run: |
1067-
cat > keystore.properties <<EOF
1102+
cat > keystore.properties <<PROPS
10681103
keyAlias=myalias
10691104
keyPassword=${ANDROID_SIGNING_PASSWORD}
10701105
storeFile=$RUNNER_TEMP/android.keystore
10711106
storePassword=${ANDROID_SIGNING_PASSWORD}
1072-
EOF
1073-
1074-
# ── 7. Read the version name from buildSrc ────────────────────────────
1075-
#
1076-
# buildSrc/src/main/kotlin/Version.kt defines `currentVersion`.
1077-
# Rather than parsing Kotlin, we ask Gradle itself for the value by
1078-
# running a one-off task that prints it. This is the single source of
1079-
# truth for the version and avoids duplication or drift.
1080-
#
1081-
# The `generic` flavor + `release` build type is the combination we care
1082-
# about; its versionName comes straight from `baseVersionName` in
1083-
# build.gradle.kts which equals currentVersion.name.
1084-
- name: Read version name from Gradle
1085-
id: version
1086-
run: |
1087-
VERSION=$(./gradlew -q printVersionName --no-configuration-cache 2>/dev/null || \
1088-
./gradlew -q :app:printVersionName 2>/dev/null || \
1089-
grep -oP "Version\.\w+\([^)]+\)" buildSrc/src/main/kotlin/Version.kt | tail -1)
1090-
# Fallback: derive it from the git SHA if Gradle task is unavailable
1091-
if [ -z "$VERSION" ] || echo "$VERSION" | grep -q "Version\."; then
1092-
VERSION="$(date -u +%Y%m%d)-$(git rev-parse --short HEAD)"
1093-
fi
1094-
echo "name=$VERSION" >> "$GITHUB_OUTPUT"
1095-
echo "Resolved version: $VERSION"
1107+
PROPS
1108+
# Strip any leading whitespace from each line (heredoc indentation safety)
1109+
sed -i 's/^[[:space:]]*//' keystore.properties
1110+
echo "--- keystore.properties (keys only) ---"
1111+
cut -d'=' -f1 keystore.properties
10961112

1097-
# ── 8. Build the signed release APK ───────────────────────────────────
1098-
#
1099-
# `assembleGenericRelease` builds the `generic` product flavor in release
1100-
# mode. Because keystore.properties now exists, build.gradle.kts will
1101-
# automatically apply the `githubPublish` signingConfig, so the APK that
1102-
# comes out of Gradle is already signed and zipaligned — no separate
1103-
# signing step needed.
1113+
# ── 8. Patch version for this build ────────────────────────────────────
11041114
#
1105-
# The output file naming in build.gradle.kts is:
1106-
# Seal-<versionName>-<variantName>.apk
1107-
# With splits enabled (default) you get one APK per ABI plus a universal.
1115+
# We override the version at Gradle level using project properties.
1116+
# This avoids modifying Version.kt (which would dirty the working tree).
11081117
- name: Build signed release APK
1109-
run: ./gradlew assembleGenericRelease
1118+
run: |
1119+
./gradlew assembleGenericRelease \
1120+
-PversionNameOverride="${{ steps.version.outputs.name }}" \
1121+
-PversionCodeOverride="${{ steps.version.outputs.code }}"
11101122

1111-
# ── 9. Collect the APKs ────────────────────────────────────────────────
1123+
# ── 9. Debug: show what was produced ───────────────────────────────────
11121124
- name: List produced APKs
1113-
run: find app/build/outputs/apk -name "*.apk" | sort
1114-
1115-
# ── 10. Create GitHub Release ─────────────────────────────────────────
1125+
run: |
1126+
echo "=== All APK files ==="
1127+
find app/build/outputs/apk -name "*.apk" -exec ls -lh {} \;
1128+
echo ""
1129+
echo "=== Verify signing ==="
1130+
for apk in $(find app/build/outputs/apk -name "*.apk"); do
1131+
echo "--- $apk ---"
1132+
$ANDROID_HOME/build-tools/$(ls $ANDROID_HOME/build-tools/ | tail -1)/apksigner verify --print-certs "$apk" 2>&1 || echo "NOT SIGNED"
1133+
done
1134+
1135+
# ── 10. Create GitHub Release ──────────────────────────────────────────
11161136
#
1117-
# softprops/action-gh-release creates a tag + release on GitHub.
1118-
# `prerelease: false` is explicit — this is a full release.
1119-
# The tag is "v<versionName>" so it matches the convention used upstream.
1137+
# The glob pattern must match the actual Gradle output directory structure:
1138+
# app/build/outputs/apk/<flavor>/<buildType>/*.apk
1139+
# Which is: app/build/outputs/apk/generic/release/*.apk
11201140
#
1121-
# We upload every APK produced; the glob `**/*.apk` covers all ABI
1122-
# splits as well as the universal APK.
1141+
# NOT "genericRelease" — Gradle uses separate directories for flavor and
1142+
# build type.
11231143
- name: Create GitHub Release
11241144
uses: softprops/action-gh-release@v2
11251145
with:
11261146
tag_name: v${{ steps.version.outputs.name }}
11271147
name: Seal ${{ steps.version.outputs.name }}
11281148
prerelease: false
1129-
generate_release_notes: true # auto-generates notes from commit messages
1130-
files: app/build/outputs/apk/genericRelease/*.apk
1149+
generate_release_notes: true
1150+
files: |
1151+
app/build/outputs/apk/generic/release/*.apk
11311152
env:
11321153
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
11331154

@@ -3170,7 +3191,7 @@ SIZE: 0 KB
31703191

31713192
================================================================================
31723193
FILE: app/build.gradle.kts
3173-
SIZE: 6.52 KB
3194+
SIZE: 7.02 KB
31743195
================================================================================
31753196

31763197
@file:Suppress("UnstableApiUsage")
@@ -3197,8 +3218,22 @@ val abiFilterList = (properties["ABI_FILTERS"] as String).split(';')
31973218

31983219
val abiCodes = mapOf("armeabi-v7a" to 1, "arm64-v8a" to 2, "x86" to 3, "x86_64" to 4)
31993220

3200-
val baseVersionName = currentVersion.name
3201-
val currentVersionCode = currentVersion.code.toInt()
3221+
// ── Version resolution ────────────────────────────────────────────────────────
3222+
//
3223+
// CI passes -PversionNameOverride=... and -PversionCodeOverride=... to inject
3224+
// a timestamp-based auto-bumping version. When building locally (or if the
3225+
// properties aren't set), we fall back to the values from buildSrc/Version.kt.
3226+
val baseVersionName: String = if (project.hasProperty("versionNameOverride")) {
3227+
project.property("versionNameOverride") as String
3228+
} else {
3229+
currentVersion.name
3230+
}
3231+
3232+
val currentVersionCode: Int = if (project.hasProperty("versionCodeOverride")) {
3233+
(project.property("versionCodeOverride") as String).toInt()
3234+
} else {
3235+
currentVersion.code.toInt()
3236+
}
32023237

32033238
android {
32043239
compileSdk = 35
@@ -3222,8 +3257,7 @@ android {
32223257
applicationId = "com.junkfood.seal"
32233258
minSdk = 24
32243259
targetSdk = 35
3225-
versionCode = 200_000_150
3226-
check(versionCode == currentVersionCode)
3260+
versionCode = currentVersionCode
32273261

32283262
versionName = baseVersionName
32293263
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@@ -3375,15 +3409,13 @@ dependencies {
33753409
// Usage: ./gradlew printVersionName
33763410
// Output: 2.0.0-alpha.5 (whatever currentVersion.name resolves to)
33773411
//
3378-
// The task is intentionally registered on the :app project (this file) so it
3379-
// has direct access to `baseVersionName` which is already resolved above.
3412+
// NOTE: This always prints the Version.kt value, NOT the CI override.
3413+
// The CI uses this as the "base" and then appends a timestamp.
33803414
tasks.register("printVersionName") {
33813415
group = "versioning"
33823416
description = "Prints the current versionName to stdout for CI consumption."
3383-
// We declare no inputs/outputs so Gradle never considers it up-to-date and
3384-
// skips it — we always want a fresh print.
33853417
doLast {
3386-
println(baseVersionName)
3418+
println(currentVersion.name)
33873419
}
33883420
}
33893421

0 commit comments

Comments
 (0)