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
17 changes: 14 additions & 3 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: Android CI/CD Rho.Studio®
name: Android Debug CI/CD Rho.Studio®

on:
workflow_dispatch:
push:
branches: [ " " ]
pull_request:
branches: [ "dev" , "pre-release" , "main" ]
branches: [ "dev" , "pre-release" ]

jobs:
build:
Expand All @@ -25,11 +25,22 @@ jobs:

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Run Unit Tests
run: ./gradlew test

- name: Build with Gradle
run: ./gradlew build
run: ./gradlew assembleDebug

- name: Upload APK
uses: actions/upload-artifact@v7.0.1
with:
name: app-debug
path: app/build/outputs/apk/debug/app-debug.apk

- name: Upload Test Reports
if: failure()
uses: actions/upload-artifact@v7.0.1
with:
name: test-reports
path: "**/build/reports/tests/"
52 changes: 52 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Android Release Rho.Studio®

on:
workflow_dispatch:
push:
branches: [ "Pre-release-v102" ]
pull_request:
branches: [ "main" ]

jobs:
build:
name: Build and Release Rho.Studio®
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v6.1.0

- name: Set up JDK 17
uses: actions/setup-java@v5.5.0
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Run Unit Tests
run: ./gradlew test

- name: Build with Gradle
run: ./gradlew assembleDebug

- name: List APK directory
run: ls -la app/build/outputs/apk/debug/

- name: Rename APK
run: mv app/build/outputs/apk/debug/app-debug.apk app/build/outputs/apk/debug/RhoStudioUI.apk

- name: Upload APK
uses: actions/upload-artifact@v7.0.1
with:
name: Rho-Studio-UI
path: app/build/outputs/apk/debug/RhoStudioUI.apk

- name: Upload Test Reports
if: failure()
uses: actions/upload-artifact@v7.0.1
with:
name: test-reports
path: "**/build/reports/tests/"
70 changes: 70 additions & 0 deletions CONTRIBUTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Architecture & Contribution Guide: Rho Studio UI

## 1. Project Vision & Architecture
Rho Studio UI is a modern Android application built with **Jetpack Compose** and **MVVM** following a **Single-Activity Architecture**.

To achieve enterprise-grade scalability, we strictly implement **Clean Architecture** principles. This ensures a clear separation of concerns, framework independence, and high testability.

---

## 2. Clean Architecture Layer Responsibilities
All contributions must respect the strict boundaries between the following three layers:

### 2.1 The UI Layer (`features/` & `ui/`)
* **Role**: Handles user interaction and data presentation.
* **Components**:
* **Compose Screens/Components**: Purely declarative and stateless. They observe state and emit events.
* **ViewModels**: Act as a bridge. They manage UI state (Loading, Error, Toast) and handle user intent by calling Use Cases.
* **Boundary Rule**: Never contains business logic. Never interacts directly with Repositories.

### 2.2 The Domain Layer (`core/domain/`)
* **Role**: The "Heart" of the application. Contains the essential business rules.
* **Components**:
* **Use Cases (Interactors)**: Classes like `LoginUseCase.kt` that encapsulate a single, atomic business transaction.
* **Domain Models**: Pure data entities (e.g., `User.kt`) that are framework-independent.
* **Boundary Rule**: **Pure Kotlin only**. Must not import `android.*` or depend on any external libraries/frameworks (except pure Kotlin ones). This layer is the "Single Source of Truth" for *logic*.

### 2.3 The Data Layer (`core/data/`)
* **Role**: Manages data acquisition and persistence.
* **Components**:
* **Repositories**: Implementation of data fetching (API, Room, Preferences).
* **Managers**: State holders like `SessionManager.kt` that coordinate global app state.
* **Boundary Rule**: Acts as the "Single Source of Truth" for *data state*. It implements the requirements defined by the Domain layer.

---

## 3. Core Requirements for Contributions

### 3.1 MVVM & UDF (Unidirectional Data Flow)
- **State flows down**: From ViewModel to Composables.
- **Events flow up**: From UI to ViewModel via lambdas.

### 3.2 Single-Activity & Reactive Navigation
- **MainActivity** is the sole navigation orchestrator.
- **ViewModels** and **Use Cases** must **never** hold a `NavController` or trigger navigation directly.
- **Logic**: Use Cases update the session/state in the Data layer. `MainActivity` observes this state and performs the transition (e.g., auto-routing to Login on session expiry).

---

## 4. Implementing New Features (Profile, Feed, Chat)

Every new feature should be built following the **Inside-Out** approach:

1. **Inside (Domain)**: Create the `UseCase` (e.g., `UpdateProfileUseCase`, `GetFeedUseCase`, `SendMessageUseCase`).
- Use the `Result<T>` wrapper for success/failure.
- Write a Unit Test for the logic.
2. **Middle (ViewModel)**: Create the bridge that transforms the Use Case `Result` into observable UI state.
3. **Outside (UI)**: Build the stateless Compose UI.
- **Feed UI**: Use `LazyColumn` for efficiency. Implement a stateless `PostItem.kt`.
- **Chat UI**: Implement specialized "Message Bubble" components. Input fields must update the ViewModel state immediately.

---

## 5. Technical Constraints
- **Atomic Transactions**: Multi-step actions (e.g., validate -> save -> sync) must be managed as a single atomic unit within a `UseCase`.
- **Framework Independence**: Keep the Domain layer free of Android dependencies to support future Gradle modularization.
- **Standardized Results**: Always return `Result.Success`, `Result.Error`, or `Result.Loading` from Use Cases.

---
**[Rho.Studio®](https://rho.studio/) - Engineering Department** - Contact [alexis.tercero@rho.studio](mailto:alexis.tercero@rho.studio)

Loading