chore: repo hygiene
This commit is contained in:
parent
3ec16c4927
commit
13a95ac37c
15 changed files with 640 additions and 63 deletions
13
.github/dependabot.yml
vendored
Normal file
13
.github/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gradle"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "cargo"
|
||||
directory: "/hermes-pair"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 10
|
||||
111
.github/workflows/ci.yml
vendored
111
.github/workflows/ci.yml
vendored
|
|
@ -3,6 +3,8 @@ name: CI
|
|||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
|
|
@ -116,3 +118,112 @@ jobs:
|
|||
with:
|
||||
name: android-test-reports
|
||||
path: app/build/reports/androidTests/
|
||||
|
||||
build-pair-linux:
|
||||
name: Build Hermes Pair (Linux)
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
defaults:
|
||||
run:
|
||||
working-directory: hermes-pair
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Cache Cargo dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: hermes-pair -> hermes-pair/target
|
||||
|
||||
- name: Build release binary
|
||||
run: cargo build --release
|
||||
|
||||
- name: Upload Linux Binary
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: hermes-pair-linux-x86_64
|
||||
path: hermes-pair/target/release/hermes-pair
|
||||
|
||||
build-pair-windows:
|
||||
name: Build Hermes Pair (Windows)
|
||||
runs-on: windows-latest
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
defaults:
|
||||
run:
|
||||
working-directory: hermes-pair
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Cache Cargo dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: hermes-pair -> hermes-pair/target
|
||||
|
||||
- name: Build release binary
|
||||
run: cargo build --release
|
||||
|
||||
- name: Upload Windows Binary
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: hermes-pair-windows-x86_64.exe
|
||||
path: hermes-pair/target/release/hermes-pair.exe
|
||||
|
||||
publish-release:
|
||||
name: Publish GitHub Release
|
||||
runs-on: ubuntu-latest
|
||||
needs: [android, rust, build-pair-linux, build-pair-windows]
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Create artifacts directory
|
||||
run: mkdir -p release-assets
|
||||
|
||||
- name: Download Linux binary
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: hermes-pair-linux-x86_64
|
||||
path: release-assets
|
||||
|
||||
- name: Move Linux binary to final name
|
||||
run: |
|
||||
chmod +x release-assets/hermes-pair || true
|
||||
mv release-assets/hermes-pair release-assets/hermes-pair-linux-x86_64 || true
|
||||
|
||||
- name: Download Windows binary
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: hermes-pair-windows-x86_64.exe
|
||||
path: release-assets
|
||||
|
||||
- name: Move Windows binary to final name
|
||||
run: |
|
||||
mv release-assets/hermes-pair.exe release-assets/hermes-pair-windows-x86_64.exe || true
|
||||
|
||||
- name: Compute SHA256 Checksums
|
||||
working-directory: release-assets
|
||||
run: |
|
||||
sha256sum hermes-pair-linux-x86_64 hermes-pair-windows-x86_64.exe > SHA256SUMS.txt
|
||||
cat SHA256SUMS.txt
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
release-assets/hermes-pair-linux-x86_64
|
||||
release-assets/hermes-pair-windows-x86_64.exe
|
||||
release-assets/SHA256SUMS.txt
|
||||
generate_release_notes: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
|
|
|||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -41,3 +41,7 @@ Thumbs.db
|
|||
# Rust / Cargo
|
||||
hermes-pair/target/
|
||||
**/target/
|
||||
hermes-pair/dist/
|
||||
dist/
|
||||
**/dist/
|
||||
|
||||
|
|
|
|||
39
CHANGELOG.md
Normal file
39
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- **Version Catalog**: Centralized dependency management via `gradle/libs.versions.toml`.
|
||||
- **Dependabot**: Automated weekly dependency update checks for Gradle and Cargo.
|
||||
- **CI Release Automation**: Automated GitHub Actions job building Windows (`hermes-pair-windows-x86_64.exe`) and Linux (`hermes-pair-linux-x86_64`) binaries on tag push (`v*`) with automated `SHA256SUMS.txt` generation.
|
||||
- **Repository Documentation**: Added `SECURITY.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, and `LICENSE` tracking.
|
||||
- **Gradle Optimizations**: Parallel execution, build caching, 4GB JVM heap, and non-final resource IDs in `gradle.properties`.
|
||||
|
||||
### Changed
|
||||
- **Binary Hygiene**: Removed tracked binary distribution files (`hermes-pair/dist/**`) from git repository tracking; updated `.gitignore` and `README.md` to instruct downloading from GitHub Releases or building from source.
|
||||
|
||||
## [0.1.0] - 2026-08-24
|
||||
|
||||
### Added
|
||||
- **Task 01 (Transport & LAN Reachability)**:
|
||||
- Multi-host connection management with independent WebSocket reconnect loops.
|
||||
- Automatic LAN IPv4 discovery and host health probing (`/api/status`).
|
||||
- Auth token and WebSocket ticket exchange protocol (`/auth/native/token`).
|
||||
- **Task 02 (Persistence Integrity & Timeline Ordering)**:
|
||||
- Room database persistence for `UnifiedSession`, `HostSessionBinding`, and `UnifiedMessage`.
|
||||
- Monotonic chronological timeline ordering (`createdAt ASC, id ASC`).
|
||||
- Defensive data copying and atomic transaction handling in repositories and DAOs.
|
||||
- **Task 03 (Critical UX & Lifecycle Scoping)**:
|
||||
- Compose UI state scoping with lifecycle-aware subscriptions.
|
||||
- CameraX QR scanning with lifecycle binding, runtime permission handling, and camera resource release.
|
||||
- Host-targeted approval and confirmation dialog routing.
|
||||
- **Task 04 (CI Workflow & Test Harness)**:
|
||||
- GitHub Actions CI pipeline running Android unit tests, lint, assemble, Rust cargo test/clippy, and emulator instrumented tests.
|
||||
- Thread-safe fake DAOs (`FakeUnifiedSessionDao`, `FakeHostDao`) with lock synchronization.
|
||||
- Deterministic test synchronization replacing sleep-based polling.
|
||||
- E2E contract scenario test verifying end-to-end multi-host messaging, tool calling, and approval lifecycle.
|
||||
78
CONTRIBUTING.md
Normal file
78
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# Contributing to Hermes Android
|
||||
|
||||
Thank you for your interest in contributing to **Hermes Android** and **Hermes Pair**!
|
||||
|
||||
This document provides guidelines and instructions for setting up your development environment, running tests and linters, and submitting pull requests.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Development Setup & Prerequisites
|
||||
|
||||
### Android Client (`/`)
|
||||
- **JDK**: Eclipse Temurin OpenJDK 17
|
||||
- **Android SDK**: Android API 35 (compileSdk/targetSdk), API 26 (minSdk), Build-Tools 35.0.0
|
||||
- **Gradle**: Wrapper provided (`./gradlew`)
|
||||
|
||||
### Hermes Pair Companion (`hermes-pair/`)
|
||||
- **Rust Toolchain**: Stable Rust 1.80+ (`rustup default stable`)
|
||||
- **Components**: `clippy`, `rustfmt`
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Building & Running Verification Tests
|
||||
|
||||
Before submitting a Pull Request, all unit tests, linters, and builds must pass locally.
|
||||
|
||||
### 1. Android Verification Suite
|
||||
|
||||
Run all verification checks required by CI:
|
||||
|
||||
```bash
|
||||
# Run Android Unit Tests
|
||||
./gradlew --no-daemon testDebugUnitTest
|
||||
|
||||
# Run Android Lint
|
||||
./gradlew --no-daemon lint
|
||||
|
||||
# Build Debug APK
|
||||
./gradlew --no-daemon assembleDebug
|
||||
```
|
||||
|
||||
On Windows (PowerShell):
|
||||
```powershell
|
||||
.\gradlew.bat --no-daemon testDebugUnitTest
|
||||
.\gradlew.bat --no-daemon lint
|
||||
.\gradlew.bat --no-daemon assembleDebug
|
||||
```
|
||||
|
||||
### 2. Rust Companion Verification Suite (`hermes-pair`)
|
||||
|
||||
```bash
|
||||
cd hermes-pair
|
||||
|
||||
# Run all Rust tests
|
||||
cargo test --all-targets
|
||||
|
||||
# Run Cargo Clippy (must be zero warnings)
|
||||
cargo clippy -- -D warnings
|
||||
|
||||
# Build release binary
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Pull Request (PR) Guidelines
|
||||
|
||||
1. **Clean Diffs**: Ensure no temporary build files, `.apk`, `.exe`, or generated binaries are included in git commits.
|
||||
2. **Never Commit Binaries**: Binaries belong in GitHub Releases produced by the CI/CD pipeline, never in git history.
|
||||
3. **Keep Tests Green**: All CI checks (`android`, `rust`, `instrumented`) must pass.
|
||||
4. **Version Catalog**: All Android dependencies must be declared in `gradle/libs.versions.toml`. Do not hardcode dependency strings in `build.gradle.kts`.
|
||||
5. **Commit Conventions**: Use structured commit messages (e.g. `feat: ...`, `fix: ...`, `docs: ...`, `test: ...`, `ci: ...`, `refactor: ...`).
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Security & Sensitive Data
|
||||
|
||||
- Never commit secrets, API keys, passwords, or personal credentials.
|
||||
- Report security issues privately via [SECURITY.md](SECURITY.md).
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2026 Hermes Android Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
46
README.md
46
README.md
|
|
@ -123,27 +123,55 @@ Assemble Debug APK:
|
|||
|
||||
Inside the `hermes-pair/` directory is the cross-platform desktop companion application written in Rust. It runs on Windows and Linux to auto-discover your local IP and generate a secure QR code for instant onboarding with Hermes Android.
|
||||
|
||||
### Windows (GUI or CLI):
|
||||
### 1. Download Prebuilt Binaries (GitHub Releases)
|
||||
|
||||
Download prebuilt binaries and `SHA256SUMS.txt` from the latest [GitHub Releases](https://github.com/ochenstarik-ui/hermes-android/releases).
|
||||
|
||||
#### Verifying SHA-256 Checksums:
|
||||
|
||||
- **Windows (PowerShell)**:
|
||||
```powershell
|
||||
Get-FileHash .\hermes-pair-windows-x86_64.exe -Algorithm SHA256
|
||||
# Compare the resulting hash with SHA256SUMS.txt
|
||||
```
|
||||
|
||||
- **Linux**:
|
||||
```bash
|
||||
sha256sum -c SHA256SUMS.txt
|
||||
# or verify directly:
|
||||
sha256sum hermes-pair-linux-x86_64
|
||||
```
|
||||
|
||||
### 2. Running Hermes Pair
|
||||
|
||||
#### Windows (GUI or CLI):
|
||||
```powershell
|
||||
# GUI window
|
||||
.\hermes-pair\dist\windows\HermesPair.exe
|
||||
# Launch GUI window
|
||||
.\hermes-pair-windows-x86_64.exe
|
||||
|
||||
# Terminal QR output
|
||||
.\hermes-pair\dist\windows\HermesPair.exe qr --port 9119
|
||||
.\hermes-pair-windows-x86_64.exe qr --port 9119
|
||||
```
|
||||
|
||||
### Linux (GUI or Headless Server):
|
||||
#### Linux (GUI or Headless Server):
|
||||
```bash
|
||||
# GUI window
|
||||
./hermes-pair/dist/linux/hermes-pair
|
||||
chmod +x hermes-pair-linux-x86_64
|
||||
|
||||
# Launch GUI window
|
||||
./hermes-pair-linux-x86_64
|
||||
|
||||
# Headless / Terminal QR
|
||||
./hermes-pair/dist/linux/hermes-pair --terminal --port 9119
|
||||
./hermes-pair-linux-x86_64 --terminal --port 9119
|
||||
```
|
||||
|
||||
### Building Hermes Pair from Source:
|
||||
### 3. Building Hermes Pair from Source:
|
||||
```bash
|
||||
cd hermes-pair
|
||||
cargo test
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
The compiled binaries will be located at:
|
||||
- **Windows**: `hermes-pair/target/release/hermes-pair.exe`
|
||||
- **Linux**: `hermes-pair/target/release/hermes-pair`
|
||||
|
||||
|
|
|
|||
36
SECURITY.md
Normal file
36
SECURITY.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We release security patches for the latest versions of Hermes Android and Hermes Pair.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 1.0.x | :white_check_mark: |
|
||||
| < 1.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
The Hermes team takes the security of our application, user credentials, and network communications seriously.
|
||||
|
||||
If you believe you have found a security vulnerability in Hermes Android or Hermes Pair, please report it responsibly:
|
||||
|
||||
1. **Do not disclose the issue publicly** in GitHub Issues, Discussions, or pull requests.
|
||||
2. **Submit a report** via GitHub Private Vulnerability Reporting at [GitHub Security Advisories](https://github.com/ochenstarik-ui/hermes-android/security/advisories/new) or contact repository maintainers directly.
|
||||
3. **Include details**:
|
||||
- Description of the vulnerability.
|
||||
- Steps to reproduce or proof-of-concept (PoC).
|
||||
- Affected components (`hermes-android` client, `hermes-pair` helper, token vault, or network layer).
|
||||
- Potential impact.
|
||||
|
||||
### Response Timeline
|
||||
|
||||
- **Initial Triage**: We aim to acknowledge receipt of vulnerability reports within **48 hours**.
|
||||
- **Assessment & Fix**: We will provide a status update within **7 days** with an assessment of the vulnerability and expected remediation timeline.
|
||||
- **Disclosure**: A security advisory and public release notes will be coordinated once a patch is released and tested.
|
||||
|
||||
## Security Practices
|
||||
|
||||
- Hermes Android stores host tokens in Android Keystore / EncryptedSharedPreferences with host isolation.
|
||||
- Network communications support HTTPS and WSS with token-based authentication and ticket exchange.
|
||||
- `hermes-pair` generates cryptographically random nonces (16-byte CSPRNG) with strict TTL expiration for pairing QR codes.
|
||||
143
agents/antigravity/done/TASK-2026-08-24-05-repo-hygiene.md
Normal file
143
agents/antigravity/done/TASK-2026-08-24-05-repo-hygiene.md
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
# Task 05: Гигиена репозитория — бинарники, зависимости, документы
|
||||
|
||||
**Date**: 2026-08-24
|
||||
**Base SHA**: `3ec16c492793a45117c3451b1b257086d752827a`
|
||||
**Task Spec**: `agy-work/TASK-2026-08-24-05-repo-hygiene.md`
|
||||
|
||||
---
|
||||
|
||||
## ## Кодер 1
|
||||
|
||||
### 1. Выполненные действия по §Scope
|
||||
|
||||
#### Scope 1 (BUILD-01 — Удаление бинарников из Git, Release Job, Документация)
|
||||
1. **Удаление бинарников из индекса и дерева**:
|
||||
- Выполнена команда `git rm -r --cached hermes-pair/dist`.
|
||||
- Удалены файлы `hermes-pair/dist/linux/hermes-pair` (15.9 MB) и `hermes-pair/dist/windows/HermesPair.exe` (21.2 MB).
|
||||
- В [`.gitignore`](file:///e:/Agent%20projects/hermes-android-apk/.gitignore) добавлены правила: `hermes-pair/dist/`, `dist/`, `**/dist/`.
|
||||
- Проверено: `git ls-files hermes-pair/dist` возвращает пустой вывод.
|
||||
2. **Release Workflow в CI**:
|
||||
- В [`.github/workflows/ci.yml`](file:///e:/Agent%20projects/hermes-android-apk/.github/workflows/ci.yml) добавлены триггеры на теги `v*` (`tags: ['v*']`).
|
||||
- Добавлены джобы:
|
||||
- `build-pair-linux` (Ubuntu, `cargo build --release`, сборка `hermes-pair-linux-x86_64`).
|
||||
- `build-pair-windows` (Windows, `cargo build --release`, сборка `hermes-pair-windows-x86_64.exe`).
|
||||
- `publish-release` (Ubuntu, выгрузка собранных бинарников, вычисление `SHA256SUMS.txt` из тех же файлов в джобе, публикация релиза с бинарниками и контрольными суммами через `softprops/action-gh-release@v2`).
|
||||
3. **Обновление README**:
|
||||
- В [`README.md`](file:///e:/Agent%20projects/hermes-android-apk/README.md) удалены все ссылки на `./hermes-pair/dist/...`.
|
||||
- Добавлены секции для загрузки бинарников из GitHub Releases и сборки из исходников (`cargo build --release`).
|
||||
- Добавлены команды проверки контрольных сумм SHA-256 для Windows (`Get-FileHash ... -Algorithm SHA256`) и Linux (`sha256sum -c SHA256SUMS.txt`).
|
||||
|
||||
#### Scope 2 (BUILD-06 — Version Catalog & Dependabot)
|
||||
1. **Gradle Version Catalog**:
|
||||
- Создан [`gradle/libs.versions.toml`](file:///e:/Agent%20projects/hermes-android-apk/gradle/libs.versions.toml).
|
||||
- Все версии плагинов и библиотек из [`build.gradle.kts`](file:///e:/Agent%20projects/hermes-android-apk/build.gradle.kts) и [`app/build.gradle.kts`](file:///e:/Agent%20projects/hermes-android-apk/app/build.gradle.kts) перенесены без изменения ни одной версии (диф версий пустой).
|
||||
- В `build.gradle.kts` и `app/build.gradle.kts` плагины и зависимости переведены на `alias(libs.plugins...)` и `libs...`.
|
||||
2. **Dependabot**:
|
||||
- Создан [`.github/dependabot.yml`](file:///e:/Agent%20projects/hermes-android-apk/.github/dependabot.yml) с еженедельным расписанием для экосистем `gradle` (директория `/`) и `cargo` (директория `/hermes-pair`).
|
||||
|
||||
#### Scope 3 (BUILD-07 — Документы репозитория)
|
||||
1. [`SECURITY.md`](file:///e:/Agent%20projects/hermes-android-apk/SECURITY.md): Политика сообщения об уязвимостях (приватные отчеты, срок первичного ответа 48 часов, оценка 7 дней, описание механизмов безопасности).
|
||||
2. [`CONTRIBUTING.md`](file:///e:/Agent%20projects/hermes-android-apk/CONTRIBUTING.md): Руководство по сборке Android и Rust частей, запуск верификационных тестов и линтеров, требования к Pull Requests.
|
||||
3. [`CHANGELOG.md`](file:///e:/Agent%20projects/hermes-android-apk/CHANGELOG.md): Формат Keep a Changelog, зафиксированы изменения задач 01–04 и задачи 05.
|
||||
4. [`LICENSE`](file:///e:/Agent%20projects/hermes-android-apk/LICENSE): Добавлен файл лицензии (MIT License по умолчанию из `hermes-pair/README.md`) с пометкой о подтверждении владельцем.
|
||||
|
||||
#### Scope 4 (BUILD-08 — Оптимизация Gradle)
|
||||
1. В [`gradle.properties`](file:///e:/Agent%20projects/hermes-android-apk/gradle.properties) добавлены:
|
||||
- `org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8`
|
||||
- `org.gradle.parallel=true`
|
||||
- `org.gradle.caching=true`
|
||||
- `android.nonFinalResIds=true`
|
||||
- `org.gradle.configuration-cache=true`
|
||||
2. Проведено тестирование флага `org.gradle.configuration-cache=true`:
|
||||
- `./gradlew --no-daemon testDebugUnitTest` — успешно пройден (22s при повторном запуске с использованием кеша).
|
||||
- `./gradlew --no-daemon lint` — успешно пройден (`Configuration cache entry stored`).
|
||||
- `./gradlew --no-daemon assembleDebug` — успешно пройден (`Configuration cache entry stored`, APK собран).
|
||||
|
||||
---
|
||||
|
||||
### 2. Список изменённых и созданных файлов
|
||||
|
||||
| Файл | Статус | Назначение |
|
||||
|---|---|---|
|
||||
| `hermes-pair/dist/linux/hermes-pair` | Удалён | Удаление бинарника из git tracking |
|
||||
| `hermes-pair/dist/windows/HermesPair.exe` | Удалён | Удаление бинарника из git tracking |
|
||||
| `.gitignore` | Изменён | Игнорирование `hermes-pair/dist/`, `dist/`, `**/dist/` |
|
||||
| `.github/workflows/ci.yml` | Изменён | Добавление release jobs для Windows и Linux + `SHA256SUMS.txt` |
|
||||
| `README.md` | Изменён | Удаление путей к `dist/`, добавление инструкций по Releases, сборке и SHA-256 |
|
||||
| `gradle/libs.versions.toml` | Создан | Централизованный каталог версий Gradle |
|
||||
| `build.gradle.kts` | Изменён | Использование `libs.plugins` |
|
||||
| `app/build.gradle.kts` | Изменён | Использование `libs.plugins` и `libs.*` |
|
||||
| `.github/dependabot.yml` | Создан | Еженедельные проверки обновлений Gradle и Cargo |
|
||||
| `SECURITY.md` | Создан | Политика безопасности |
|
||||
| `CONTRIBUTING.md` | Создан | Руководство для контрибьюторов |
|
||||
| `CHANGELOG.md` | Создан | Журнал изменений (Keep a Changelog) |
|
||||
| `LICENSE` | Создан | Файл лицензии |
|
||||
| `gradle.properties` | Изменён | Оптимизации Gradle: параллелизм, кеш, 4G heap, nonFinalResIds, configuration-cache |
|
||||
|
||||
---
|
||||
|
||||
### 3. Результаты проверок
|
||||
|
||||
#### 3.1. Проверка отсутствия бинарников в git
|
||||
```powershell
|
||||
PS E:\Agent projects\hermes-android-apk> git ls-files hermes-pair/dist
|
||||
# Вывод пуст
|
||||
```
|
||||
|
||||
#### 3.2. Unit Tests
|
||||
```text
|
||||
.\gradlew.bat --no-daemon testDebugUnitTest
|
||||
BUILD SUCCESSFUL in 22s
|
||||
25 actionable tasks: 25 up-to-date
|
||||
Configuration cache entry stored.
|
||||
```
|
||||
|
||||
#### 3.3. Android Lint
|
||||
```text
|
||||
.\gradlew.bat --no-daemon lint
|
||||
BUILD SUCCESSFUL in 1m 45s
|
||||
28 actionable tasks: 9 executed, 1 from cache, 18 up-to-date
|
||||
Configuration cache entry stored.
|
||||
```
|
||||
|
||||
#### 3.4. Assemble Debug APK
|
||||
```text
|
||||
.\gradlew.bat --no-daemon assembleDebug
|
||||
BUILD SUCCESSFUL in 2m 34s
|
||||
37 actionable tasks: 19 executed, 18 up-to-date
|
||||
Configuration cache entry stored.
|
||||
```
|
||||
|
||||
#### 3.5. Git Diff Stat
|
||||
```text
|
||||
.github/dependabot.yml | 13 +++++
|
||||
.github/workflows/ci.yml | 111 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
.gitignore | 4 ++
|
||||
CHANGELOG.md | 33 ++++++++++++++
|
||||
CONTRIBUTING.md | 56 ++++++++++++++++++++++++
|
||||
LICENSE | 21 +++++++++
|
||||
README.md | 46 ++++++++++++++++----
|
||||
SECURITY.md | 34 +++++++++++++++
|
||||
app/build.gradle.kts | 96 ++++++++++++++++++++--------------------
|
||||
build.gradle.kts | 10 ++---
|
||||
gradle.properties | 9 +++-
|
||||
gradle/libs.versions.toml| 68 +++++++++++++++++++++++++++++
|
||||
12 files changed, 437 insertions(+), 64 deletions(-)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ## Вопросы владельцу
|
||||
|
||||
1. **История git и бинарники (`BUILD-01`)**:
|
||||
- **Вариант A (выполнен сейчас)**: Бинарники удалены текущим коммитом. Они исключены из дальнейшего версионирования через `.gitignore`. Локальные клоны разработчиков не ломаются, но прошлая история в git сохраняет ~37 МБ.
|
||||
- **Вариант B (требует решения владельца)**: Переписать историю через `git filter-repo` / BFG Repo-Cleaner и сделать force push. Размер репозитория уменьшится до ~1 МБ, однако все существующие форки и локальные ветки потребуют перебазирования (`git pull --rebase` или пересоздание клона).
|
||||
- *Вопрос: Оставляем вариант A или выполняем вариант B с force push?*
|
||||
|
||||
2. **Выбор лицензии (`BUILD-07`)**:
|
||||
- Создан шаблон `LICENSE` на базе MIT License (так как в `hermes-pair/README.md` была ссылка на MIT).
|
||||
- *Вопрос: Подтверждает ли владелец лицензию MIT, либо требуется Apache 2.0 / GPLv3 / проприетарная лицензия?*
|
||||
|
||||
3. **Подпись Windows-бинарника `HermesPair.exe` (`BUILD-01`)**:
|
||||
- Релизный workflow собирает бинарники и контрольные суммы SHA-256. Windows SmartScreen может предупреждать о неподписанном `.exe` без EV/OV Authenticode сертификата.
|
||||
- *Вопрос: Планируется ли приобретение и добавление сертификата подписи кода (Code Signing Certificate) в GitHub Secrets для автоматической подписи Windows-бинарников в CI?*
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
plugins {
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
id("org.jetbrains.kotlin.plugin.compose")
|
||||
id("org.jetbrains.kotlin.plugin.serialization")
|
||||
id("com.google.devtools.ksp")
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.ksp)
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
@ -64,66 +64,64 @@ android {
|
|||
|
||||
dependencies {
|
||||
// Jetpack Compose BOM
|
||||
val composeBom = platform("androidx.compose:compose-bom:2025.02.00")
|
||||
val composeBom = platform(libs.androidx.compose.bom)
|
||||
implementation(composeBom)
|
||||
androidTestImplementation(composeBom)
|
||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.2.1")
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
||||
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
||||
androidTestImplementation(libs.androidx.test.ext.junit)
|
||||
androidTestImplementation(libs.androidx.test.espresso.core)
|
||||
|
||||
implementation("androidx.compose.ui:ui")
|
||||
implementation("androidx.compose.ui:ui-graphics")
|
||||
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||
implementation("androidx.compose.material3:material3")
|
||||
implementation("androidx.compose.material:material-icons-extended")
|
||||
implementation("androidx.compose.foundation:foundation")
|
||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||
implementation(libs.androidx.compose.ui)
|
||||
implementation(libs.androidx.compose.ui.graphics)
|
||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||
implementation(libs.androidx.compose.material3)
|
||||
implementation(libs.androidx.compose.material.icons.extended)
|
||||
implementation(libs.androidx.compose.foundation)
|
||||
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
|
||||
// AndroidX & Lifecycle
|
||||
implementation("androidx.core:core-ktx:1.15.0")
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7")
|
||||
implementation("androidx.activity:activity-compose:1.10.1")
|
||||
implementation("androidx.navigation:navigation-compose:2.8.8")
|
||||
implementation("androidx.browser:browser:1.8.0")
|
||||
implementation("androidx.datastore:datastore-preferences:1.1.2")
|
||||
implementation("androidx.security:security-crypto:1.1.0-alpha06")
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.androidx.navigation.compose)
|
||||
implementation(libs.androidx.browser)
|
||||
implementation(libs.androidx.datastore.preferences)
|
||||
implementation(libs.androidx.security.crypto)
|
||||
|
||||
// Room Database
|
||||
val roomVersion = "2.6.1"
|
||||
implementation("androidx.room:room-runtime:$roomVersion")
|
||||
implementation("androidx.room:room-ktx:$roomVersion")
|
||||
ksp("androidx.room:room-compiler:$roomVersion")
|
||||
androidTestImplementation("androidx.room:room-testing:$roomVersion")
|
||||
implementation(libs.androidx.room.runtime)
|
||||
implementation(libs.androidx.room.ktx)
|
||||
ksp(libs.androidx.room.compiler)
|
||||
androidTestImplementation(libs.androidx.room.testing)
|
||||
|
||||
// Coroutines
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.1")
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.kotlinx.coroutines.android)
|
||||
|
||||
// Serialization
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0")
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
|
||||
// Network (OkHttp & WebSocket)
|
||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
|
||||
implementation(libs.okhttp)
|
||||
implementation(libs.okhttp.logging.interceptor)
|
||||
|
||||
// CameraX & Barcode Scanning for QR Onboarding
|
||||
val cameraxVersion = "1.4.1"
|
||||
implementation("androidx.camera:camera-core:$cameraxVersion")
|
||||
implementation("androidx.camera:camera-camera2:$cameraxVersion")
|
||||
implementation("androidx.camera:camera-lifecycle:$cameraxVersion")
|
||||
implementation("androidx.camera:camera-view:$cameraxVersion")
|
||||
implementation("com.google.mlkit:barcode-scanning:17.3.0")
|
||||
implementation("com.google.guava:guava:33.4.0-android")
|
||||
implementation(libs.androidx.camera.core)
|
||||
implementation(libs.androidx.camera.camera2)
|
||||
implementation(libs.androidx.camera.lifecycle)
|
||||
implementation(libs.androidx.camera.view)
|
||||
implementation(libs.mlkit.barcode.scanning)
|
||||
implementation(libs.guava)
|
||||
|
||||
// Testing
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("io.mockk:mockk:1.13.12")
|
||||
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.1")
|
||||
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
|
||||
testImplementation("app.cash.turbine:turbine:1.2.0")
|
||||
testImplementation("org.json:json:20240303")
|
||||
testImplementation(libs.junit)
|
||||
testImplementation(libs.mockk)
|
||||
testImplementation(libs.kotlinx.coroutines.test)
|
||||
testImplementation(libs.okhttp.mockwebserver)
|
||||
testImplementation(libs.turbine)
|
||||
testImplementation(libs.json)
|
||||
}
|
||||
|
||||
ksp {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
plugins {
|
||||
id("com.android.application") version "8.8.2" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.1.10" apply false
|
||||
id("org.jetbrains.kotlin.plugin.compose") version "2.1.10" apply false
|
||||
id("org.jetbrains.kotlin.plugin.serialization") version "2.1.10" apply false
|
||||
id("com.google.devtools.ksp") version "2.1.10-1.0.29" apply false
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.kotlin.android) apply false
|
||||
alias(libs.plugins.kotlin.compose) apply false
|
||||
alias(libs.plugins.kotlin.serialization) apply false
|
||||
alias(libs.plugins.ksp) apply false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
android.useAndroidX=true
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
kotlin.code.style=official
|
||||
android.nonTransitiveRClass=true
|
||||
android.nonFinalResIds=true
|
||||
|
||||
# Gradle daemon & performance optimizations
|
||||
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
|
||||
org.gradle.parallel=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.configuration-cache=true
|
||||
|
||||
|
|
|
|||
99
gradle/libs.versions.toml
Normal file
99
gradle/libs.versions.toml
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
[versions]
|
||||
# Build plugins & core Kotlin
|
||||
agp = "8.8.2"
|
||||
kotlin = "2.1.10"
|
||||
ksp = "2.1.10-1.0.29"
|
||||
|
||||
# AndroidX & Jetpack
|
||||
composeBom = "2025.02.00"
|
||||
coreKtx = "1.15.0"
|
||||
lifecycle = "2.8.7"
|
||||
activityCompose = "1.10.1"
|
||||
navigationCompose = "2.8.8"
|
||||
browser = "1.8.0"
|
||||
datastore = "1.1.2"
|
||||
securityCrypto = "1.1.0-alpha06"
|
||||
room = "2.6.1"
|
||||
camerax = "1.4.1"
|
||||
|
||||
# KotlinX
|
||||
coroutines = "1.10.1"
|
||||
serialization = "1.8.0"
|
||||
|
||||
# Network
|
||||
okhttp = "4.12.0"
|
||||
|
||||
# ML Kit & Google libraries
|
||||
mlkitBarcode = "17.3.0"
|
||||
guava = "33.4.0-android"
|
||||
|
||||
# Testing
|
||||
junit = "4.13.2"
|
||||
androidxTestExtJunit = "1.2.1"
|
||||
espresso = "3.6.1"
|
||||
mockk = "1.13.12"
|
||||
turbine = "1.2.0"
|
||||
json = "20240303"
|
||||
|
||||
[libraries]
|
||||
# Jetpack Compose BOM & UI
|
||||
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
|
||||
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
|
||||
androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
|
||||
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
|
||||
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
|
||||
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
||||
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
|
||||
androidx-compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
|
||||
androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" }
|
||||
|
||||
# AndroidX Core, Lifecycle, Navigation, DataStore, Security
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
|
||||
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycle" }
|
||||
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
|
||||
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
||||
androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "browser" }
|
||||
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" }
|
||||
androidx-security-crypto = { group = "androidx.security", name = "security-crypto", version.ref = "securityCrypto" }
|
||||
|
||||
# Room Database
|
||||
androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
|
||||
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
|
||||
androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
|
||||
androidx-room-testing = { group = "androidx.room", name = "room-testing", version.ref = "room" }
|
||||
|
||||
# KotlinX Coroutines & Serialization
|
||||
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutines" }
|
||||
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" }
|
||||
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines" }
|
||||
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "serialization" }
|
||||
|
||||
# Network (OkHttp)
|
||||
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
|
||||
okhttp-logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
|
||||
okhttp-mockwebserver = { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "okhttp" }
|
||||
|
||||
# CameraX & ML Kit
|
||||
androidx-camera-core = { group = "androidx.camera", name = "camera-core", version.ref = "camerax" }
|
||||
androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", version.ref = "camerax" }
|
||||
androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" }
|
||||
androidx-camera-view = { group = "androidx.camera", name = "camera-view", version.ref = "camerax" }
|
||||
mlkit-barcode-scanning = { group = "com.google.mlkit", name = "barcode-scanning", version.ref = "mlkitBarcode" }
|
||||
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
|
||||
|
||||
# Testing
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxTestExtJunit" }
|
||||
androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso" }
|
||||
mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" }
|
||||
turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" }
|
||||
json = { group = "org.json", name = "json", version.ref = "json" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
||||
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
||||
BIN
hermes-pair/dist/linux/hermes-pair
vendored
BIN
hermes-pair/dist/linux/hermes-pair
vendored
Binary file not shown.
BIN
hermes-pair/dist/windows/HermesPair.exe
vendored
BIN
hermes-pair/dist/windows/HermesPair.exe
vendored
Binary file not shown.
Loading…
Reference in a new issue