Compare commits
3
Commits
3a4d6142e7
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da3b8a4f05 | ||
|
|
6ad37e4a36 | ||
|
|
1df27bdc13 |
@@ -144,3 +144,13 @@ release must be uploaded manually). Play rejects a repeated `versionCode`, so
|
|||||||
bump the `+N` in `pubspec.yaml` for every tag - re-tagging the same version
|
bump the `+N` in `pubspec.yaml` for every tag - re-tagging the same version
|
||||||
will fail the upload. Release notes come from
|
will fail the upload. Release notes come from
|
||||||
`distribution/whatsnew/whatsnew-en-US` (max 500 chars) - update per release.
|
`distribution/whatsnew/whatsnew-en-US` (max 500 chars) - update per release.
|
||||||
|
|
||||||
|
## Community PR flow
|
||||||
|
|
||||||
|
Gitea is the source of truth; GitHub is a push mirror (never commit to GitHub
|
||||||
|
`main`) and the public issue tracker. `scripts/sync-github-prs.sh` (cron on the
|
||||||
|
home server) imports open GitHub PRs into Gitea via Agit
|
||||||
|
(`refs/for/main`, topic `gh-pr-N`), where `.gitea/workflows/pr.yml` runs
|
||||||
|
analyze + tests. That workflow must never use secrets; signing and Play
|
||||||
|
credentials stay on the tag-triggered `build.yml`/`release.yml`. Issue
|
||||||
|
templates are in `.github/ISSUE_TEMPLATE/`.
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
*.sh text eol=lf
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
name: Check PR
|
||||||
|
|
||||||
|
# Runs analyze + tests on pull requests. Deliberately uses no secrets, so it
|
||||||
|
# is safe against imported contributor code. Keep it that way: signing keys
|
||||||
|
# and the Play credentials are only available to the tag-triggered workflows.
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Flutter
|
||||||
|
uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
channel: stable
|
||||||
|
|
||||||
|
- run: flutter pub get
|
||||||
|
- run: flutter analyze
|
||||||
|
- run: flutter test
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
name: Bug report
|
||||||
|
description: Something isn't working as expected
|
||||||
|
labels: [bug]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: what
|
||||||
|
attributes:
|
||||||
|
label: What happened?
|
||||||
|
description: What you did, what you expected, and what happened instead.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Noo version
|
||||||
|
description: Settings → About
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: device
|
||||||
|
attributes:
|
||||||
|
label: Device and OS version
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: server
|
||||||
|
attributes:
|
||||||
|
label: Nextcloud server version
|
||||||
|
- type: textarea
|
||||||
|
id: extra
|
||||||
|
attributes:
|
||||||
|
label: Screenshots or logs
|
||||||
|
description: Remove any personal data or server addresses you don't want public.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Security problem
|
||||||
|
url: https://github.com/ayushyamitabh/noo/blob/main/SECURITY.md
|
||||||
|
about: Please report security issues privately, not as public issues.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
name: Feature request
|
||||||
|
description: Suggest an improvement
|
||||||
|
labels: [enhancement]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: >
|
||||||
|
Noo aims to be a simple, just-works Nextcloud client with reasonable
|
||||||
|
customization, not a replacement for every Nextcloud feature. Requests
|
||||||
|
that fit that goal are most likely to be accepted.
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: What problem are you trying to solve?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: idea
|
||||||
|
attributes:
|
||||||
|
label: What would you like to see?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
@@ -40,6 +40,18 @@ for testing anything destructive (delete, move, trash).
|
|||||||
standards, update the matching file in `.claude/context/` in the same PR.
|
standards, update the matching file in `.claude/context/` in the same PR.
|
||||||
6. Open a pull request and fill in the template.
|
6. Open a pull request and fill in the template.
|
||||||
|
|
||||||
|
## How PRs and issues are handled
|
||||||
|
|
||||||
|
Issues and pull requests live on GitHub. The maintainer's source of truth is
|
||||||
|
a self-hosted Gitea instance: open PRs are imported there, reviewed, and
|
||||||
|
merged there, and `main` is then mirrored back to GitHub. Two things follow:
|
||||||
|
|
||||||
|
- Keep discussion on the GitHub PR; that is where I'll reply.
|
||||||
|
- A merged change may show up on GitHub as the PR being closed with a link to
|
||||||
|
the commit rather than as "Merged". Your authorship is preserved.
|
||||||
|
- Imported PRs run `flutter analyze` and `flutter test` on my server, so
|
||||||
|
please run both locally first.
|
||||||
|
|
||||||
## Commit messages
|
## Commit messages
|
||||||
|
|
||||||
Use the repository's template so history stays consistent:
|
Use the repository's template so history stays consistent:
|
||||||
|
|||||||
@@ -109,3 +109,23 @@ it as your own app.
|
|||||||
|
|
||||||
Contributions are welcome under the terms in
|
Contributions are welcome under the terms in
|
||||||
[`CONTRIBUTING.md`](CONTRIBUTING.md).
|
[`CONTRIBUTING.md`](CONTRIBUTING.md).
|
||||||
|
|
||||||
|
### Why PolyForm Shield?
|
||||||
|
|
||||||
|
I want the code to be open to read, learn from, build, and improve, while
|
||||||
|
keeping anyone from lifting it and shipping a competing copy of the app.
|
||||||
|
Permissive licenses (MIT, Apache) allow exactly that, and copyleft ones
|
||||||
|
(GPL) still allow a rebranded fork. PolyForm Shield sits in between: it is
|
||||||
|
not an OSI "open source" license, and I'm not claiming it is, but it keeps
|
||||||
|
the code available while protecting the project.
|
||||||
|
|
||||||
|
## Where development happens
|
||||||
|
|
||||||
|
The source of truth is a self-hosted Gitea instance, and this GitHub
|
||||||
|
repository is a read-only mirror plus the public issue tracker. I keep it
|
||||||
|
that way so that I own my hosting, builds, and release credentials rather
|
||||||
|
than depending on a third party for them. You don't have to use Gitea:
|
||||||
|
open issues and pull requests here as usual. Open PRs are imported to my
|
||||||
|
instance, reviewed and merged there, and `main` is mirrored back here, so a
|
||||||
|
merged PR may show as closed with a link to the commit instead of "Merged".
|
||||||
|
See [`CONTRIBUTING.md`](CONTRIBUTING.md) for details.
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Imports open GitHub pull requests into Gitea as Agit PRs (refs/for/main).
|
||||||
|
# Gitea is the source of truth: review and merge there, and the push mirror
|
||||||
|
# updates GitHub. Run from cron, e.g. every 5 minutes:
|
||||||
|
# */5 * * * * /srv/noo-sync/scripts/sync-github-prs.sh >> /var/log/noo-sync.log 2>&1
|
||||||
|
#
|
||||||
|
# One PR: sync-github-prs.sh 42
|
||||||
|
# All: sync-github-prs.sh
|
||||||
|
#
|
||||||
|
# Needs: git, curl, jq, and a clone whose `origin` is Gitea (SSH deploy key
|
||||||
|
# or token with write access) plus env var GITHUB_REPO (e.g. ayushyamitabh/noo).
|
||||||
|
# GITHUB_TOKEN is optional (read-only, public repo) but avoids rate limits.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${GITHUB_REPO:?set GITHUB_REPO, e.g. ayushyamitabh/noo}"
|
||||||
|
STATE_DIR="${STATE_DIR:-$HOME/.noo-sync}"
|
||||||
|
BASE_BRANCH="${BASE_BRANCH:-main}"
|
||||||
|
mkdir -p "$STATE_DIR"
|
||||||
|
|
||||||
|
auth=()
|
||||||
|
[ -n "${GITHUB_TOKEN:-}" ] && auth=(-H "Authorization: Bearer $GITHUB_TOKEN")
|
||||||
|
|
||||||
|
git remote get-url github >/dev/null 2>&1 ||
|
||||||
|
git remote add github "https://github.com/$GITHUB_REPO.git"
|
||||||
|
|
||||||
|
import_pr() {
|
||||||
|
local n="$1" pr head_sha title url
|
||||||
|
pr=$(curl -fsS "${auth[@]}" "https://api.github.com/repos/$GITHUB_REPO/pulls/$n")
|
||||||
|
head_sha=$(jq -r .head.sha <<<"$pr")
|
||||||
|
title=$(jq -r '.title | gsub("[\r\n\t]+"; " ")' <<<"$pr")
|
||||||
|
url=$(jq -r .html_url <<<"$pr")
|
||||||
|
local stamp="$STATE_DIR/pr-$n"
|
||||||
|
if [ -f "$stamp" ] && [ "$(cat "$stamp")" = "$head_sha" ]; then return; fi
|
||||||
|
|
||||||
|
git fetch --quiet origin "$BASE_BRANCH"
|
||||||
|
git fetch --quiet github "+refs/pull/$n/head"
|
||||||
|
# Agit: pushing to refs/for/<base> with a stable topic opens a Gitea PR the
|
||||||
|
# first time and updates the same PR on later pushes.
|
||||||
|
git push origin "FETCH_HEAD:refs/for/$BASE_BRANCH" \
|
||||||
|
-o "topic=gh-pr-$n" \
|
||||||
|
-o "title=[GitHub #$n] $title" \
|
||||||
|
-o "description=Imported from $url. Discuss on GitHub; merge here."
|
||||||
|
echo "$head_sha" >"$stamp"
|
||||||
|
echo "imported PR #$n @ $head_sha"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$#" -gt 0 ]; then
|
||||||
|
for n in "$@"; do import_pr "$n"; done
|
||||||
|
else
|
||||||
|
curl -fsS "${auth[@]}" \
|
||||||
|
"https://api.github.com/repos/$GITHUB_REPO/pulls?state=open&per_page=50" |
|
||||||
|
jq -r '.[].number' | while read -r n; do import_pr "$n"; done
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user