Configure Play Store roadmap and Hugo website with automated deployment
This commit is contained in:
@@ -29,13 +29,10 @@ jobs:
|
|||||||
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||||
run: nix develop --command task build-android-bundle
|
run: nix develop --command task build-android-bundle
|
||||||
|
|
||||||
# Placeholder for Play Store upload.
|
# Play Store upload disabled for now
|
||||||
# Once you have the Service Account JSON and everything is ready,
|
|
||||||
# you can uncomment this or use a specialized action.
|
|
||||||
# - name: Upload to Play Store
|
# - name: Upload to Play Store
|
||||||
# env:
|
# env:
|
||||||
# PLAY_STORE_CONFIG_JSON: ${{ secrets.PLAY_STORE_CONFIG_JSON }}
|
# PLAY_STORE_CONFIG_JSON: ${{ secrets.PLAY_STORE_CONFIG_JSON }}
|
||||||
# run: |
|
# run: |
|
||||||
# echo "$PLAY_STORE_CONFIG_JSON" > play-store-key.json
|
# echo "$PLAY_STORE_CONFIG_JSON" > play-store-key.json
|
||||||
# # Example using a tool like 'fastlane supply' or a dedicated flutter package
|
# # nix develop --command fvm flutter pub run supply ...
|
||||||
# # nix develop --command fvm flutter pub run ...
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
name: Deploy Website
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'website/**'
|
||||||
|
- '.forgejo/workflows/website.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
name: Build & Deploy Website
|
||||||
|
runs-on: self-hosted
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Setup SSH
|
||||||
|
env:
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.WEBSITE_SSH_PRIVATE_KEY }}
|
||||||
|
run: |
|
||||||
|
if [ -n "$SSH_PRIVATE_KEY" ]; then
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
else
|
||||||
|
echo "Error: WEBSITE_SSH_PRIVATE_KEY secret is not set."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
env:
|
||||||
|
SSH_USER: ${{ secrets.WEBSITE_SSH_USER }}
|
||||||
|
SSH_HOST: ${{ secrets.WEBSITE_SSH_HOST }}
|
||||||
|
run: nix develop --command task website-deploy
|
||||||
@@ -94,6 +94,11 @@ sharedinbox-runner/runner-data/
|
|||||||
.gemini/
|
.gemini/
|
||||||
.rustup/
|
.rustup/
|
||||||
|
|
||||||
|
# --- Hugo ---
|
||||||
|
website/public/
|
||||||
|
website/resources/
|
||||||
|
website/.hugo_build.lock
|
||||||
|
|
||||||
.copilot/
|
.copilot/
|
||||||
.dotnet/
|
.dotnet/
|
||||||
.vscode-server/
|
.vscode-server/
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "website/themes/PaperMod"]
|
||||||
|
path = website/themes/PaperMod
|
||||||
|
url = https://github.com/adityatelange/hugo-PaperMod.git
|
||||||
@@ -322,6 +322,27 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- fvm dart run scripts/check_coverage.dart
|
- fvm dart run scripts/check_coverage.dart
|
||||||
|
|
||||||
|
website-dev:
|
||||||
|
desc: Run Hugo development server
|
||||||
|
cmds:
|
||||||
|
- fvm flutter pub global run # Just a placeholder if nix shell hook isn't active
|
||||||
|
- nix develop --command hugo server --source website -D
|
||||||
|
|
||||||
|
website-build:
|
||||||
|
desc: Build the static website
|
||||||
|
cmds:
|
||||||
|
- nix develop --command hugo --source website --minify
|
||||||
|
|
||||||
|
website-deploy:
|
||||||
|
desc: Deploy the website via rsync to public_html
|
||||||
|
deps: [website-build]
|
||||||
|
cmds:
|
||||||
|
- |
|
||||||
|
rsync -avz --delete \
|
||||||
|
-e "ssh -o StrictHostKeyChecking=no" \
|
||||||
|
website/public/ \
|
||||||
|
${SSH_USER}@${SSH_HOST}:public_html/
|
||||||
|
|
||||||
check-fast:
|
check-fast:
|
||||||
desc: Pre-commit checks — analyze + unit tests + widget tests (no build, no integration)
|
desc: Pre-commit checks — analyze + unit tests + widget tests (no build, no integration)
|
||||||
deps: [analyze, test, test-widget, check-hygiene]
|
deps: [analyze, test, test-widget, check-hygiene]
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Technical Audit for Play Store Readiness
|
||||||
|
|
||||||
|
Your generated `.aab` (App Bundle) is technically valid, but to be fully "Play Store ready," you should verify these four areas:
|
||||||
|
|
||||||
|
## 1. Target SDK Version
|
||||||
|
Google requires apps to target at least **Android 14 (API level 34)**.
|
||||||
|
Current status: **PASS** (Flutter defaults to 34+ in recent versions).
|
||||||
|
|
||||||
|
## 2. Versioning
|
||||||
|
* **`versionName`**: Currently `0.1.1`. This is visible to users.
|
||||||
|
* **`versionCode`**: This must be a **unique integer** for every single upload to the Play Console.
|
||||||
|
* If you need to re-upload the same version because of a fix, you must increment the code (e.g., from `1` to `2`).
|
||||||
|
* Set this in `pubspec.yaml`: `version: 0.1.1+1` (the number after the `+` is the `versionCode`).
|
||||||
|
|
||||||
|
## 3. App Icon
|
||||||
|
Check your icons in `android/app/src/main/res/mipmap-*`.
|
||||||
|
* **Status:** Currently using default `ic_launcher.png`.
|
||||||
|
* **Requirement:** Replace these with your own branding before submission. Google may reject apps that use default placeholder logos for being "Low Quality."
|
||||||
|
|
||||||
|
## 4. Privacy & Data Safety (Crucial)
|
||||||
|
Google requires these before you can move to production:
|
||||||
|
* **Privacy Policy:** You **must** provide a public URL to a privacy policy.
|
||||||
|
* **Data Safety Section:** You must complete the questionnaire in the Play Console.
|
||||||
|
* Since this is an **Email app**, you must declare that it handles "Personal Communications" and potentially "User IDs" or "Contact Info."
|
||||||
|
|
||||||
|
## 5. Helpful Commands
|
||||||
|
To inspect your bundle's manifest (to verify permissions or package name):
|
||||||
|
```bash
|
||||||
|
# requires bundletool
|
||||||
|
bundletool dump manifest --bundle build/app/outputs/bundle/release/app-release.aab
|
||||||
|
```
|
||||||
|
|
||||||
|
**Next Step Recommendation:** Complete the Privacy Policy and Data Safety questionnaire in the Play Console as they often take the longest to be approved.
|
||||||
Generated
+3
-3
@@ -20,11 +20,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776221942,
|
"lastModified": 1778430510,
|
||||||
"narHash": "sha256-FbQAeVNi7G4v3QCSThrSAAvzQTmrmyDLiHNPvTF2qFM=",
|
"narHash": "sha256-Ti+ZBvW6yrWWAg2szExVTwCd4qOJ3KlVr1tFHfyfi8Q=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "1766437c5509f444c1b15331e82b8b6a9b967000",
|
"rev": "8fd9daa3db09ced9700431c5b7ad0e8ba199b575",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -59,6 +59,9 @@
|
|||||||
# Coverage merging (flutter test --merge-coverage requires lcov)
|
# Coverage merging (flutter test --merge-coverage requires lcov)
|
||||||
lcov
|
lcov
|
||||||
|
|
||||||
|
# Website
|
||||||
|
hugo
|
||||||
|
|
||||||
# Utilities
|
# Utilities
|
||||||
git
|
git
|
||||||
curl
|
curl
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Helper script to generate a production Android Keystore.
|
||||||
|
# Run this from the project root.
|
||||||
|
|
||||||
|
# Define the path relative to the project root
|
||||||
|
KEYSTORE_PATH="android/app/upload-keystore.jks"
|
||||||
|
|
||||||
|
echo "Generating keystore at: $KEYSTORE_PATH"
|
||||||
|
|
||||||
|
keytool -genkey -v \
|
||||||
|
-keystore "$KEYSTORE_PATH" \
|
||||||
|
-alias upload \
|
||||||
|
-keyalg RSA \
|
||||||
|
-keysize 2048 \
|
||||||
|
-validity 10000
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Done."
|
||||||
|
echo "1. Remember your password!"
|
||||||
|
echo "2. Back up $KEYSTORE_PATH safely."
|
||||||
|
echo "3. Do NOT commit the .jks file or passwords to git."
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# Play Store Publishing Roadmap
|
||||||
|
|
||||||
|
To publish the Flutter app to the Play Store, you need to transition from a "development" state to a "production-ready" state.
|
||||||
|
|
||||||
|
## 1. What has been done
|
||||||
|
* **Application ID:** Changed to `de.sharedinbox.mua` (verified in `build.gradle.kts`, `MainActivity.kt`, and integration tests).
|
||||||
|
* **Build Logic:** `android/app/build.gradle.kts` now supports:
|
||||||
|
* **Local builds:** Using `key.properties` (ignored by git).
|
||||||
|
* **CI builds:** Using environment variables (`ANDROID_KEY_ALIAS`, `ANDROID_KEY_PASSWORD`, `ANDROID_KEYSTORE_PASSWORD`).
|
||||||
|
* **Taskfile:** Added `task build-android-bundle` to generate the `.aab` file.
|
||||||
|
* **CI Workflow:** Created `.forgejo/workflows/release.yml` which triggers on merge to `main`.
|
||||||
|
|
||||||
|
## 2. What you need to do next
|
||||||
|
### A. Create the Keystore
|
||||||
|
Run the helper script I created for you:
|
||||||
|
```bash
|
||||||
|
./t.sh
|
||||||
|
```
|
||||||
|
Follow the prompts and use a strong password (24-32 chars).
|
||||||
|
|
||||||
|
### B. Configure Codeberg Secrets
|
||||||
|
Go to **Settings > Actions > Secrets** in your Codeberg repo and add:
|
||||||
|
1. **`ANDROID_KEYSTORE_BASE64`**: The output of `base64 -w 0 android/app/upload-keystore.jks`.
|
||||||
|
2. **`ANDROID_KEYSTORE_PASSWORD`**: Your keystore password.
|
||||||
|
3. **`PLAY_STORE_CONFIG_JSON`**: The JSON key from your Google Play Service Account.
|
||||||
|
|
||||||
|
### C. First Manual Upload
|
||||||
|
Google Play requires the **very first upload** to be done manually through the web console:
|
||||||
|
1. Generate your keystore using `./t.sh`.
|
||||||
|
2. Run the build locally using temporary environment variables:
|
||||||
|
```bash
|
||||||
|
export ANDROID_KEYSTORE_PASSWORD=your_password
|
||||||
|
nix develop --command task build-android-bundle
|
||||||
|
```
|
||||||
|
3. Upload the resulting `.aab` from `build/app/outputs/bundle/release/app-release.aab` to the Play Console (Internal Testing or Production track).
|
||||||
|
4. This "locks in" your signing key.
|
||||||
|
|
||||||
|
## 3. Firebase Test Lab
|
||||||
|
Once you have the Service Account JSON, you can add a task to `Taskfile.yml` to run automated tests on real devices:
|
||||||
|
```yaml
|
||||||
|
test-lab:
|
||||||
|
desc: Run integration tests in Firebase Test Lab
|
||||||
|
cmds:
|
||||||
|
- gcloud firebase test android run \
|
||||||
|
--type instrumentation \
|
||||||
|
--app build/app/outputs/apk/debug/app-debug.apk \
|
||||||
|
--test build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
|
||||||
|
--device model=virtuall1,version=30
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recommendation:** Complete step **A** (Keystore) and **B** (Secrets) first. Once the first manual upload is done, the CI will take over for all future merges to `main`.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
+++
|
||||||
|
date = '{{ .Date }}'
|
||||||
|
draft = true
|
||||||
|
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||||
|
+++
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: 'Welcome to SharedInbox'
|
||||||
|
date: 2026-05-12T08:00:00Z
|
||||||
|
draft: false
|
||||||
|
---
|
||||||
|
|
||||||
|
Welcome to the official website of SharedInbox!
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
baseURL = 'https://sharedinbox.de/'
|
||||||
|
languageCode = 'en-us'
|
||||||
|
title = 'SharedInbox'
|
||||||
|
theme = 'PaperMod'
|
||||||
|
|
||||||
|
[params]
|
||||||
|
env = 'production'
|
||||||
|
title = 'SharedInbox'
|
||||||
|
description = 'IMAP/SMTP Email Client'
|
||||||
|
author = 'SharedInbox Team'
|
||||||
|
|
||||||
|
[params.homeInfoParams]
|
||||||
|
Title = "SharedInbox"
|
||||||
|
Content = "The modern IMAP/SMTP email client for your desktop and mobile."
|
||||||
|
|
||||||
|
[[params.socialIcons]]
|
||||||
|
name = "github"
|
||||||
|
url = "https://codeberg.org/guettli/sharedinbox"
|
||||||
Submodule
+1
Submodule website/themes/PaperMod added at 154d006e01
Reference in New Issue
Block a user