build: consolidate fastlane

This commit is contained in:
2026-04-12 11:27:49 +03:00
parent c5595c0d1a
commit 7c57b7bcbb
31 changed files with 95 additions and 465 deletions

9
fastlane/Appfile Normal file
View File

@@ -0,0 +1,9 @@
# Android
json_key_file(ENV["GOOGLE_PLAY_KEY_FILE"])
package_name("dev.casraf.pantry")
# iOS
app_identifier("dev.casraf.pantry")
apple_id(ENV["APPLE_ID"])
itc_team_id(ENV["ITC_TEAM_ID"])
team_id(ENV["APPLE_TEAM_ID"])

3
fastlane/Deliverfile Normal file
View File

@@ -0,0 +1,3 @@
# The Deliverfile allows you to store various App Store Connect metadata
# For more information, check out the docs
# https://docs.fastlane.tools/actions/deliver/

188
fastlane/Fastfile Normal file
View File

@@ -0,0 +1,188 @@
require "digest"
require "json"
# -- Shared helpers --
def version_info
pubspec = File.read(File.expand_path("../pubspec.yaml", __dir__))
version = pubspec.match(/^version:\s*(.+)$/)[1].strip
name, build = version.split("+")
{ name: name, build: build }
end
def version_name
v = version_info
"#{v[:build]} (#{v[:name]})"
end
def changelog_notes
version = version_info[:name]
changelog_path = File.expand_path("../CHANGELOG.md", __dir__)
return "Release #{version}" unless File.exist?(changelog_path)
changelog = File.read(changelog_path)
escaped = Regexp.escape(version)
pattern = /^## (?:\[#{escaped}\]|#{escaped}[\s(]).*?\n(.*?)(?=^## |\z)/m
match = changelog.match(pattern)
return "Release #{version}" unless match
match[1].strip
.gsub(/\s*\(\[[\da-f]+\]\([^)]+\)\)/, "")
.gsub(/^\*\s+\*\*[^*]+:\*\*\s*/m, "- ")
.gsub(/^\*\s+/, "- ")
.gsub(/^### /, "")
.gsub(/\n{3,}/, "\n\n")
.strip
.then { |n| n.empty? ? "Release #{version}" : n }
end
# -- Android --
default_platform(:android)
platform :android do
# Google Play enforces a 500-char limit on release notes per language.
PLAY_NOTES_MAX = 500
PLAY_NOTES_TRAILER = "\n\n… see full notes on GitHub."
def play_changelog
notes = changelog_notes
return notes if notes.length <= PLAY_NOTES_MAX
budget = PLAY_NOTES_MAX - PLAY_NOTES_TRAILER.length
truncated = notes[0, budget]
last_newline = truncated.rindex("\n")
truncated = truncated[0, last_newline] if last_newline && last_newline > budget / 2
truncated.rstrip + PLAY_NOTES_TRAILER
end
# -- Image change detection --
IMAGE_HASH_CACHE = File.expand_path(".image_hashes.json", __dir__)
def current_image_hashes
root = File.expand_path("metadata/android", __dir__)
return {} unless Dir.exist?(root)
files = Dir.glob(File.join(root, "**/images/**/*")).select { |f| File.file?(f) }
files.sort.each_with_object({}) do |path, acc|
rel = path.sub("#{root}/", "")
acc[rel] = Digest::SHA256.file(path).hexdigest
end
end
def cached_image_hashes
return {} unless File.exist?(IMAGE_HASH_CACHE)
JSON.parse(File.read(IMAGE_HASH_CACHE))
rescue StandardError
{}
end
def images_changed?
current_image_hashes != cached_image_hashes
end
def save_image_hashes
File.write(IMAGE_HASH_CACHE, JSON.pretty_generate(current_image_hashes))
end
desc "Upload AAB to Google Play"
lane :deploy do |options|
version_code = version_info[:build]
changelog_dir = File.expand_path("metadata/android/en-US/changelogs", __dir__)
FileUtils.mkdir_p(changelog_dir)
File.write(File.join(changelog_dir, "#{version_code}.txt"), play_changelog)
changed = images_changed?
UI.message(changed ? "Images changed — uploading." : "Images unchanged — skipping.")
upload_to_play_store(
aab: File.expand_path("../build/app/outputs/bundle/release/app-release.aab", __dir__),
track: options[:track] || "internal",
release_status: options[:status] || "draft",
version_name: version_name,
metadata_path: File.expand_path("metadata/android", __dir__),
skip_upload_images: !changed,
skip_upload_screenshots: !changed,
)
save_image_hashes if changed
end
desc "Sync metadata and screenshots only (no AAB upload)"
lane :metadata do
changed = images_changed?
UI.message(changed ? "Images changed — uploading." : "Images unchanged — skipping.")
upload_to_play_store(
skip_upload_aab: true,
skip_upload_apk: true,
metadata_path: File.expand_path("metadata/android", __dir__),
skip_upload_images: !changed,
skip_upload_screenshots: !changed,
)
save_image_hashes if changed
end
desc "Promote a release from one track to another"
lane :promote do |options|
from = options[:from] || "internal"
to = options[:to] || "production"
status = options[:status] || "draft"
upload_to_play_store(
track: from,
track_promote_to: to,
release_status: status,
version_name: version_name,
skip_upload_aab: true,
skip_upload_apk: true,
skip_upload_metadata: true,
skip_upload_changelogs: true,
skip_upload_images: true,
skip_upload_screenshots: true,
)
end
end
# -- iOS --
platform :ios do
def api_key
key_id = ENV.fetch("APP_STORE_API_KEY")
app_store_connect_api_key(
key_id: key_id,
issuer_id: ENV.fetch("APP_STORE_ISSUER_ID"),
key_filepath: File.join(ENV.fetch("APP_STORE_KEY_PATH"), "AuthKey_#{key_id}.p8"),
)
end
def find_ipa
ipa_path = Dir[File.expand_path("../build/ios/ipa/*.ipa", __dir__)].first
UI.user_error!("No IPA found in build/ios/ipa/. Run 'make ios-build' first.") unless ipa_path
ipa_path
end
desc "Upload to TestFlight"
lane :beta do
upload_to_testflight(
api_key: api_key,
ipa: find_ipa,
changelog: changelog_notes,
skip_waiting_for_build_processing: true,
)
end
desc "Upload to App Store"
lane :release do
deliver(
api_key: api_key,
ipa: find_ipa,
skip_metadata: true,
skip_screenshots: true,
submit_for_review: false,
release_notes: { "en-US" => changelog_notes },
)
end
end

48
fastlane/README.md Normal file
View File

@@ -0,0 +1,48 @@
fastlane documentation
----
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```sh
xcode-select --install
```
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
# Available Actions
## Android
### android deploy
```sh
[bundle exec] fastlane android deploy
```
Upload AAB to Google Play
### android metadata
```sh
[bundle exec] fastlane android metadata
```
Sync metadata and screenshots only (no AAB upload)
### android promote
```sh
[bundle exec] fastlane android promote
```
Promote a release from one track to another
----
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

View File

@@ -0,0 +1 @@
Release 0.1.0

View File

@@ -0,0 +1,8 @@
Features
- add sorting by category for checklist
- notifications support
Bug Fixes
- add bottom padding to accomodate fab

View File

@@ -0,0 +1,3 @@
Bug Fixes
- sorting prefs persistence & error wrapping

View File

@@ -0,0 +1,25 @@
Pantry is a companion app for the Nextcloud Pantry server app. It lets you and your household members collaborate on shared checklists, a photo board, and a notes wall — all stored on your own Nextcloud server.
* Checklists
Create shopping lists and to-do lists with categories, quantities, recurring items, and images. Drag to reorder, sort by name or date, and check items off as you go.
* Photo Board
Upload and organize photos into folders. Add captions, drag to reorder, and browse everything in a clean grid view.
* Notes Wall
Keep shared notes with your household. Color-code them, write in markdown, and pin the important stuff where everyone can see it.
* Your data, your server
Pantry connects directly to your self-hosted Nextcloud instance. No accounts to create, no cloud services in between. Your data never leaves your server.
* Features
- Shared checklists with categories, quantities, and recurrence
- Photo board with folders, captions, and multi-upload
- Color-coded notes wall
- Drag-and-drop reordering everywhere
- Multi-select for bulk actions
- Offline caching for fast loading
- Material Design 3 with dark mode support
- Nextcloud Login Flow v2 authentication
* Pantry requires a Nextcloud server with the Pantry app installed. Visit the project page for setup instructions.

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View File

@@ -0,0 +1 @@
Manage your household with your Nextcloud — lists, photos & notes.

View File

@@ -0,0 +1 @@
Nextcloud Pantry