Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions .github/workflows/fastlane.yml

This file was deleted.

47 changes: 32 additions & 15 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
name: Build and Release
permissions:
contents: write
packages: write

on:
workflow_dispatch:
inputs:
beta:
type: boolean
description: Is beta?
draft:
type: boolean
description: Is draft?

jobs:
build:
Expand All @@ -18,17 +18,22 @@ jobs:

- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
channel: stable
- uses: actions/setup-java@v4
with:
distribution: 'temurin' # See 'Supported distributions' for available options
java-version: '21'
java-version: '17'

- name: Flutter Doctor
id: flutter_doctor
run: |
flutter doctor -v

- name: Import GPG key
id: import_pgp_key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.PGP_KEY_BASE64 }}
passphrase: ${{ secrets.PGP_PASSPHRASE }}

- name: Check submodule
id: check_submodule
Expand All @@ -47,18 +52,29 @@ jobs:

- name: Build APKs
run: |
sed -i 's/signingConfig = signingConfigs.getByName("release")//g' android/app/build.gradle.kts
sed -i 's/signingConfig signingConfigs.release//g' android/app/build.gradle
flutter build apk --flavor normal && flutter build apk --split-per-abi --flavor normal
for file in build/app/outputs/flutter-apk/app-*normal*.apk*; do mv "$file" "${file//-normal/}"; done
flutter build apk --flavor fdroid -t lib/main_fdroid.dart && flutter build apk --split-per-abi --flavor fdroid -t lib/main_fdroid.dart
rm ./build/app/outputs/flutter-apk/*.sha1
cp ./sign.sh ./build/app/outputs/flutter-apk/
ls -l ./build/app/outputs/flutter-apk/

- name: Save Unsigned APKs as Action Artifacts
uses: actions/upload-artifact@v4
with:
path: build/app/outputs/flutter-apk/*

- name: Sign APKs
env:
KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
run: |
echo "${KEYSTORE_BASE64}" | base64 -d > apksign.keystore
for apk in ./build/app/outputs/flutter-apk/*-release*.apk; do
unsignedFn=${apk/-release/-unsigned}
mv "$apk" "$unsignedFn"
${ANDROID_HOME}/build-tools/$(ls ${ANDROID_HOME}/build-tools/ | tail -1)/apksigner sign --ks apksign.keystore --ks-pass pass:"${KEYSTORE_PASSWORD}" --out "${apk}" "${unsignedFn}"
sha256sum ${apk} | cut -d " " -f 1 > "$apk".sha256
gpg --batch --pinentry-mode loopback --passphrase "${PGP_PASSPHRASE}" --sign --detach-sig "$apk".sha256
done
rm apksign.keystore
PGP_KEY_FINGERPRINT="${{ steps.import_pgp_key.outputs.fingerprint }}"

- name: Create Tag
uses: mathieudutour/github-tag-action@v6.1
Expand All @@ -67,11 +83,12 @@ jobs:
custom_tag: "${{ steps.extract_version.outputs.tag }}"
tag_prefix: ""

- name: Create Draft Release
- name: Create Release And Upload APKs
uses: ncipollo/release-action@v1
with:
token: ${{ secrets.GH_ACCESS_TOKEN }}
tag: "${{ steps.extract_version.outputs.tag }}"
prerelease: "${{ steps.extract_version.outputs.beta }}"
draft: "true"
draft: "${{ inputs.draft }}"
artifacts: ./build/app/outputs/flutter-apk/*-release*.apk*
generateReleaseNotes: true
41 changes: 41 additions & 0 deletions .github/workflows/translations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Auto-Update Translations

on:
push:
branches: [ main ]
paths:
- 'lib/**.dart'

jobs:
update-translations:
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Install gettext
run: sudo apt-get install -y gettext

- name: Extract Strings and Update PO Files
run: |
mkdir -p assets/translations
# Search for tr('...') or tr("...") in the code
find lib -name "*.dart" | xgettext -f - \
--from-code=UTF-8 \
--language=Python \
--keyword=tr \
--output=assets/translations/app.pot || touch assets/translations/app.pot

# Sync PO files with the new template
[ -f assets/translations/en.po ] && msgmerge -U assets/translations/en.po assets/translations/app.pot || cp assets/translations/app.pot assets/translations/en.po
[ -f assets/translations/he.po ] && msgmerge -U assets/translations/he.po assets/translations/app.pot || cp assets/translations/app.pot assets/translations/he.po

- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
commit-message: "chore: update translation files"
title: "🌍 Translation Update"
body: "Found new strings via tr() function."
branch: translations-update
Comment thread Fixed
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[![Download Nightly](https://img.shields.io/badge/Download-Nightly-blue?style=for-the-badge&logo=android)](https://github.com/omeritzics/Updatium/releases/tag/nightly-build) (Note: Updatium is still not ready to function as an independant app, this is a work in progress)
# ![Updatium Icon](./assets/graphics/icon_small.png) Updatium

Update your Android apps directly from the APK source. Forked from [Obtainium](https://github.com/ImranR98/Obtainium) due to the developer's problematic political views and his terrible behavior towards Jewish people who wanted to contribute to his app.
Update your Android apps directly from the APK source. Forked from [Obtainium](https://github.com/ImranR98/Obtainium) due to the developer's problematic political views and his terrible behaviour towards Jewish people who wanted to contribute to his app.

Updatium allows you to install and update apps directly from their releases pages, and receive notifications when new releases are made available.

Expand Down
27 changes: 22 additions & 5 deletions android/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
pluginManagement {
val flutterSdkPath = run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
val localPropsFile = file("local.properties")

val sdkFromProps = if (localPropsFile.exists()) {
localPropsFile.inputStream().use { properties.load(it) }
properties.getProperty("flutter.sdk")
} else null

// Fallbacks if local.properties is missing or doesn't contain flutter.sdk:
// 1) Environment variable FLUTTER_ROOT
// 2) Environment variable FLUTTER_HOME
// 3) $HOME/flutter
sdkFromProps
?: System.getenv("FLUTTER_ROOT")
?: System.getenv("FLUTTER_HOME")
?: "${System.getProperty("user.home")}/flutter"
}

includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
val flutterSdkDir = file(flutterSdkPath)
if (flutterSdkDir.exists()) {
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
} else {
// Avoid failing the build; warn and continue (CI builds can set the path separately).
println("Warning: Flutter SDK not found at '$flutterSdkPath'. Skipping includeBuild for flutter_tools.")
}

repositories {
google()
Expand Down
31 changes: 31 additions & 0 deletions lib/l10n/translation_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter/services.dart';
import 'package:gettext/gettext.dart';
import 'dart:ui' as ui;

class I18n {
static final Gettext _gt = Gettext();

static Future<void> init() async {
// Determine the device language
String locale = ui.window.locale.languageCode;

try {
// Load the .po file from assets
String poContent = await rootBundle.loadString('lib/l10n/$locale.po');
_gt.addTranslations(locale, poContent);
_gt.locale = locale;
} catch (e) {
// Fallback to English if the language file is missing
try {
String enContent = await rootBundle.loadString('lib/l10n/en.po');
_gt.addTranslations('en', enContent);
_gt.locale = 'en';
} catch (err) {
print("Localization error: $err");
}
}
}

// Translation helper function
static String t(String key) => _gt.gettext(key);
}
Loading
Loading