chore: set up branching, CI, and PR workflow #1
Executable
+64
@@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Shared Gitea helpers. Source this; don't execute it.
|
||||||
|
#
|
||||||
|
# Token resolution, in order:
|
||||||
|
# 1. $GITEA_TOKEN
|
||||||
|
# 2. ~/.config/gitea/token (chmod 600)
|
||||||
|
# 3. macOS Keychain, service "gitea-bike-app"
|
||||||
|
#
|
||||||
|
# Store it in the Keychain (recommended — not readable as a plain file):
|
||||||
|
# security add-generic-password -a "$USER" -s gitea-bike-app -w '<token>' -U
|
||||||
|
#
|
||||||
|
# Or as a file:
|
||||||
|
# mkdir -p ~/.config/gitea && printf '%s' '<token>' > ~/.config/gitea/token
|
||||||
|
# chmod 600 ~/.config/gitea/token
|
||||||
|
|
||||||
|
GITEA_URL="${GITEA_URL:-http://192.168.0.3:3000}"
|
||||||
|
GITEA_OWNER="${GITEA_OWNER:-BBergle}"
|
||||||
|
GITEA_REPO="${GITEA_REPO:-bike-app}"
|
||||||
|
|
||||||
|
gitea_token() {
|
||||||
|
if [ -n "${GITEA_TOKEN:-}" ]; then
|
||||||
|
printf '%s' "$GITEA_TOKEN"; return 0
|
||||||
|
fi
|
||||||
|
if [ -r "$HOME/.config/gitea/token" ]; then
|
||||||
|
tr -d '\r\n' < "$HOME/.config/gitea/token"; return 0
|
||||||
|
fi
|
||||||
|
if command -v security >/dev/null 2>&1; then
|
||||||
|
if t="$(security find-generic-password -s gitea-bike-app -w 2>/dev/null)"; then
|
||||||
|
printf '%s' "$t"; return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
gitea_require_token() {
|
||||||
|
if ! GITEA_TOKEN="$(gitea_token)" || [ -z "$GITEA_TOKEN" ]; then
|
||||||
|
cat >&2 <<'MSG'
|
||||||
|
error: no Gitea token found.
|
||||||
|
|
||||||
|
Store it once, either way:
|
||||||
|
|
||||||
|
security add-generic-password -a "$USER" -s gitea-bike-app -w '<token>' -U
|
||||||
|
|
||||||
|
# or
|
||||||
|
mkdir -p ~/.config/gitea && printf '%s' '<token>' > ~/.config/gitea/token
|
||||||
|
chmod 600 ~/.config/gitea/token
|
||||||
|
|
||||||
|
Create the token at http://192.168.0.3:3000/user/settings/applications
|
||||||
|
with scopes: read:user, write:repository, write:issue
|
||||||
|
MSG
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
export GITEA_TOKEN
|
||||||
|
}
|
||||||
|
|
||||||
|
# gitea_api <method> <path> [curl args...] — path is relative to the repo
|
||||||
|
gitea_api() {
|
||||||
|
local method="$1" path="$2"; shift 2
|
||||||
|
curl -sS -X "$method" \
|
||||||
|
-H "Authorization: token $GITEA_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
"$@" \
|
||||||
|
"$GITEA_URL/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/$path"
|
||||||
|
}
|
||||||
+5
-16
@@ -2,20 +2,16 @@
|
|||||||
# Open a pull request against main from the current branch.
|
# Open a pull request against main from the current branch.
|
||||||
#
|
#
|
||||||
# scripts/pr.sh "feat(ingest): parse Bryton FIT activities" [--draft]
|
# scripts/pr.sh "feat(ingest): parse Bryton FIT activities" [--draft]
|
||||||
#
|
|
||||||
# Requires GITEA_TOKEN (scopes: write:repository, write:issue) and optionally GITEA_URL.
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
GITEA_URL="${GITEA_URL:-http://192.168.0.3:3000}"
|
. scripts/lib/gitea.sh
|
||||||
OWNER="${GITEA_OWNER:-BBergle}"
|
|
||||||
REPO="${GITEA_REPO:-bike-app}"
|
|
||||||
BASE="${PR_BASE:-main}"
|
|
||||||
|
|
||||||
die() { echo "error: $*" >&2; exit 1; }
|
die() { echo "error: $*" >&2; exit 1; }
|
||||||
|
|
||||||
[ -n "${GITEA_TOKEN:-}" ] || die "GITEA_TOKEN is not set. See CONTRIBUTING.md."
|
gitea_require_token || exit 1
|
||||||
command -v jq >/dev/null || die "jq is required (brew install jq)."
|
command -v jq >/dev/null || die "jq is required (brew install jq)."
|
||||||
|
|
||||||
|
BASE="${PR_BASE:-main}"
|
||||||
TITLE="${1:-}"
|
TITLE="${1:-}"
|
||||||
[ -n "$TITLE" ] || die "usage: scripts/pr.sh \"<title>\" [--draft]"
|
[ -n "$TITLE" ] || die "usage: scripts/pr.sh \"<title>\" [--draft]"
|
||||||
DRAFT=false
|
DRAFT=false
|
||||||
@@ -23,7 +19,6 @@ DRAFT=false
|
|||||||
|
|
||||||
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
|
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
|
||||||
[ "$BRANCH" != "$BASE" ] || die "refusing to open a PR from $BASE onto itself."
|
[ "$BRANCH" != "$BASE" ] || die "refusing to open a PR from $BASE onto itself."
|
||||||
|
|
||||||
git diff --quiet && git diff --cached --quiet || die "working tree is dirty; commit or stash first."
|
git diff --quiet && git diff --cached --quiet || die "working tree is dirty; commit or stash first."
|
||||||
|
|
||||||
if ! git rev-parse --verify "origin/$BRANCH" >/dev/null 2>&1; then
|
if ! git rev-parse --verify "origin/$BRANCH" >/dev/null 2>&1; then
|
||||||
@@ -31,7 +26,6 @@ if ! git rev-parse --verify "origin/$BRANCH" >/dev/null 2>&1; then
|
|||||||
git push -u origin "$BRANCH"
|
git push -u origin "$BRANCH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Prefer the PR template; otherwise summarise the commits on this branch.
|
|
||||||
if [ -f .gitea/PULL_REQUEST_TEMPLATE.md ]; then
|
if [ -f .gitea/PULL_REQUEST_TEMPLATE.md ]; then
|
||||||
BODY="$(cat .gitea/PULL_REQUEST_TEMPLATE.md)"
|
BODY="$(cat .gitea/PULL_REQUEST_TEMPLATE.md)"
|
||||||
else
|
else
|
||||||
@@ -41,13 +35,8 @@ fi
|
|||||||
RESPONSE="$(jq -n \
|
RESPONSE="$(jq -n \
|
||||||
--arg title "$TITLE" --arg body "$BODY" \
|
--arg title "$TITLE" --arg body "$BODY" \
|
||||||
--arg head "$BRANCH" --arg base "$BASE" \
|
--arg head "$BRANCH" --arg base "$BASE" \
|
||||||
--argjson draft "$DRAFT" \
|
|
||||||
'{title:$title, body:$body, head:$head, base:$base}' \
|
'{title:$title, body:$body, head:$head, base:$base}' \
|
||||||
| curl -sS -X POST \
|
| gitea_api POST pulls -d @-)"
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d @- \
|
|
||||||
"$GITEA_URL/api/v1/repos/$OWNER/$REPO/pulls")"
|
|
||||||
|
|
||||||
if URL="$(echo "$RESPONSE" | jq -er '.html_url' 2>/dev/null)"; then
|
if URL="$(echo "$RESPONSE" | jq -er '.html_url' 2>/dev/null)"; then
|
||||||
echo "PR opened: $URL"
|
echo "PR opened: $URL"
|
||||||
|
|||||||
+21
-18
@@ -1,28 +1,31 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Fetch a PR's diff and metadata for review.
|
# Inspect a PR for review.
|
||||||
#
|
#
|
||||||
# scripts/review.sh 7 # print the diff
|
# scripts/review.sh 7 diff
|
||||||
# scripts/review.sh 7 --meta # title, author, branch, CI state
|
# scripts/review.sh 7 --meta title, author, size, mergeability, CI state
|
||||||
#
|
# scripts/review.sh --list open PRs
|
||||||
# Requires GITEA_TOKEN.
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
. scripts/lib/gitea.sh
|
||||||
|
gitea_require_token || exit 1
|
||||||
|
|
||||||
GITEA_URL="${GITEA_URL:-http://192.168.0.3:3000}"
|
if [ "${1:-}" = "--list" ]; then
|
||||||
OWNER="${GITEA_OWNER:-BBergle}"
|
gitea_api GET "pulls?state=open&limit=30" \
|
||||||
REPO="${GITEA_REPO:-bike-app}"
|
| jq -r '.[] | "#\(.number) \(.title) [\(.head.ref)] by \(.user.login)"'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
[ -n "${GITEA_TOKEN:-}" ] || { echo "error: GITEA_TOKEN not set" >&2; exit 1; }
|
|
||||||
PR="${1:-}"
|
PR="${1:-}"
|
||||||
[ -n "$PR" ] || { echo "usage: scripts/review.sh <pr-number> [--meta]" >&2; exit 1; }
|
[ -n "$PR" ] || { echo "usage: scripts/review.sh <pr-number> [--meta] | --list" >&2; exit 1; }
|
||||||
|
|
||||||
api() { curl -sS -H "Authorization: token $GITEA_TOKEN" "$GITEA_URL/api/v1/repos/$OWNER/$REPO/$1"; }
|
|
||||||
|
|
||||||
if [ "${2:-}" = "--meta" ]; then
|
if [ "${2:-}" = "--meta" ]; then
|
||||||
api "pulls/$PR" | jq '{number, title, user: .user.login, head: .head.ref, base: .base.ref,
|
gitea_api GET "pulls/$PR" | jq '{number, title, user: .user.login, head: .head.ref,
|
||||||
mergeable, draft, additions, deletions, changed_files}'
|
base: .base.ref, draft, mergeable,
|
||||||
echo "--- commit status ---"
|
additions, deletions, changed_files}'
|
||||||
SHA="$(api "pulls/$PR" | jq -r '.head.sha')"
|
echo "--- CI ---"
|
||||||
api "commits/$SHA/status" | jq '{state, statuses: [.statuses[]? | {context, state}]}'
|
SHA="$(gitea_api GET "pulls/$PR" | jq -r '.head.sha')"
|
||||||
|
gitea_api GET "commits/$SHA/status" \
|
||||||
|
| jq '{state, checks: [.statuses[]? | {context, state}]}'
|
||||||
else
|
else
|
||||||
api "pulls/$PR.diff"
|
gitea_api GET "pulls/$PR.diff"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user