From 1df27bdc134bc1224d7cab7d537fca277326b903 Mon Sep 17 00:00:00 2001 From: ayushya Date: Thu, 1 Oct 2026 20:09:17 -0400 Subject: [PATCH] Add GitHub PR import script, PR check workflow, issue templates Co-Authored-By: Claude Code --- .claude/context/standards.md | 10 ++++ .gitea/workflows/pr.yml | 26 +++++++++++ .github/ISSUE_TEMPLATE/bug_report.yml | 33 ++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 ++ .github/ISSUE_TEMPLATE/feature_request.yml | 22 +++++++++ CONTRIBUTING.md | 12 +++++ scripts/sync-github-prs.sh | 53 ++++++++++++++++++++++ 7 files changed, 161 insertions(+) create mode 100644 .gitea/workflows/pr.yml create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 scripts/sync-github-prs.sh diff --git a/.claude/context/standards.md b/.claude/context/standards.md index 6960931..18d3836 100644 --- a/.claude/context/standards.md +++ b/.claude/context/standards.md @@ -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 will fail the upload. Release notes come from `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/`. diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml new file mode 100644 index 0000000..d6876ad --- /dev/null +++ b/.gitea/workflows/pr.yml @@ -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 diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..4dc8748 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -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. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..e31abae --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -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. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..e0b887b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ceb10a5..7e3b698 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,6 +40,18 @@ for testing anything destructive (delete, move, trash). standards, update the matching file in `.claude/context/` in the same PR. 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 Use the repository's template so history stays consistent: diff --git a/scripts/sync-github-prs.sh b/scripts/sync-github-prs.sh new file mode 100644 index 0000000..a3d7f36 --- /dev/null +++ b/scripts/sync-github-prs.sh @@ -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/ 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