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
22 changes: 22 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: Bug report
about: Something doesn't work as expected
labels: bug
---

**What happened?**

**What did you expect to happen?**

**Steps to reproduce**

1.
2.

**Environment**

- Clipster version:
- Android version and device:
- Server: public (clipster.cc) / own server

<!-- Please don't include passwords or clip contents. Report security issues privately, see SECURITY.md -->
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Report a security vulnerability
url: https://github.com/mc51/Clipster-Android/security/advisories/new
about: Please report vulnerabilities privately, not as a public issue.
9 changes: 9 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name: Feature request
about: Suggest an idea for Clipster
labels: enhancement
---

**What problem would this solve?**

**How would you like it to work?**
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: 2
updates:
- package-ecosystem: gradle
directory: /
schedule:
interval: weekly
groups:
gradle-dependencies:
patterns: ["*"]

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
github-actions:
patterns: ["*"]
6 changes: 6 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
**What does this change and why?**

**How did you test it?**

- [ ] `./gradlew spotlessCheck lint testDebugUnitTest assembleRelease` passes
- [ ] Tested on a device or emulator (Android version: )
13 changes: 11 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ jobs:
steps:
- name: Checkout the code
uses: actions/checkout@v7
with:
# Tags are needed to derive the version for manual (non-tag) runs
fetch-depth: 0

- name: Set up JDK
uses: actions/setup-java@v6
Expand Down Expand Up @@ -46,8 +49,14 @@ jobs:
echo "keyPassword=$KEY_PASSWORD"
} > secret

- name: Build the app
run: ./gradlew assembleRelease
# versionName and versionCode are derived from the tag, see app/build.gradle
- name: Test and build the app
run: |
version_args=()
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
version_args+=("-PappVersion=$GITHUB_REF_NAME")
fi
./gradlew "${version_args[@]}" testDebugUnitTest assembleRelease

- name: Verify signature
run: |
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CI

on:
push:
branches: [master]
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
name: Lint, test and build
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout@v7

- name: Set up JDK
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: 17

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6

# Unsigned release build: runs R8 like a real release, but needs no signing
# secrets, so this also works for pull requests from forks
- name: Formatting, lint, unit tests and release build
run: ./gradlew spotlessCheck lint testDebugUnitTest assembleRelease

- name: Upload reports
if: always()
uses: actions/upload-artifact@v7
with:
name: reports
path: |
app/build/reports/
app/build/test-results/
123 changes: 25 additions & 98 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,111 +1,38 @@
!gradle/wrapper/gradle-wrapper.properties
.idea/
*.iml
# .gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
*tmp/
.DS_Store
/build
/captures
*reports/
.externalNativeBuild
.cxx
*.apk
# Gradle and build output
.gradle/
build/
.kotlin/
.externalNativeBuild/
.cxx/
captures/

# Local configuration (SDK path etc.)
local.properties

# Signing: never commit keystores or the signing config (see README)
secret
*.jks
*secret*
# *.jar
*.keystore

# Built application files
# Built artifacts
*.apk
*.aab
*.aar
*.ap_
*.aab

# Files for the ART/Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/
# Uncomment the following line in case you need and you don't have the release build type files in your app
# release/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# IntelliJ
# IDE
.idea/
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/modules.xml
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml
.vscode/

# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
.cxx/

# Google Services (e.g. APIs or Firebase)
# google-services.json

# Freeline
freeline.py
freeline/
freeline_project_description.json
# OS and logs
.DS_Store
*.log
*.hprof

# fastlane
# Fastlane output (metadata in fastlane/metadata is committed)
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md

# Version control
vcs.xml

# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/

# Android Profiling
*.hprof
fastlane/test_output/
44 changes: 44 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Contributing

Thanks for helping! Bug reports and feature requests go to the [issues](https://github.com/mc51/Clipster-Android/issues), code changes to pull requests against `master`.

## Development setup

- JDK 17 or newer and the Android SDK (Android Studio brings both)
- `./gradlew assembleDebug` builds `app/build/outputs/apk/debug/app-debug.apk`

## Before opening a pull request

Run what CI runs:

```sh
./gradlew spotlessCheck lint testDebugUnitTest assembleRelease
```

- **Formatting:** `./gradlew spotlessApply` formats Java with [palantir-java-format](https://github.com/palantir/palantir-java-format).
- **Lint:** warnings fail the build. Fix them, or suppress a false positive with `@SuppressLint` / `tools:ignore` and a comment explaining why.
- **Tests:** JVM unit tests live in `app/src/test`. `CryptoTest` checks compatibility with the other Clipster clients: if it fails, Android can no longer read clips from them.

Dependencies are managed in `gradle/libs.versions.toml` and updated by Dependabot.

## Releases

The git tag is the only place the version is kept. `versionName` and `versionCode` are derived from it (`v0.7.2` becomes `0.7.2` / `702`):

```sh
git tag v0.7.0
git push origin v0.7.0
```

The [Release workflow](.github/workflows/build.yml) then builds, signs and publishes `clipster.apk`. Signing needs these repository secrets: `SIGNING_KEY` (base64 of the keystore), `ALIAS`, `KEY_STORE_PASSWORD` and `KEY_PASSWORD`.

To sign release builds locally, create a file named `secret` in the project root (it's git-ignored):

```properties
storeFile=/path/to/clipster.jks
storePassword=...
keyAlias=...
keyPassword=...
```

Without it, `assembleRelease` builds an unsigned APK.
21 changes: 21 additions & 0 deletions PRIVACY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Privacy Policy

Clipster contains no ads, analytics or trackers. It only talks to the Clipster server you configured: the public server at [clipster.cc](https://clipster.cc) or your own.

## Data sent to the server

- Your username and a hash of your password (used to log in, your password itself is never sent)
- Your clips, encrypted on your device. The server can't read them.
- For each clip: its format (text or image), the name of your device and the time it was shared

The server keeps only your newest clips (5 on the public server) and deletes older ones.

## Data on your device

Your username, server address and the hashes derived from your password are stored in the app's private storage. They are not included in backups. Uninstalling the app or clearing its data removes them.

## Permissions

- **Internet:** to reach the Clipster server
- **Nearby devices** (Android 17+, only if your server is on your local network): to reach it
- **Storage** (Android 9 and older, only when you save an image): to save it to the gallery
Loading
Loading