alias edit="code ~/.bash_aliases"
function mergeFrom() {
currentBranch=$(git rev-parse --abbrev-ref HEAD)
git checkout "${1:-Development}"
git pull
git checkout "${2:-$currentBranch}"
git merge "${1:-Development}"
}
function commitAndPush(){
git add . && git commit -a -m "$1" && git push
}
export GITEA_TOKEN=<get token in gitea>
# ====== MINIMAL GITEA HELPERS (env-driven, non-interactive) ======
export DEFAULT_BASE_BRANCH="${DEFAULT_BASE_BRANCH:-Development}"
# Required for real API calls:
# export GITEA_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Required repo coordinates (set these once; no parsing logic):
export GITEA_BASE="http://172.31.108.186:3000" # include subpath if any, no trailing slash
# export GITEA_OWNER="Seedbury_Square"
# export GITEA_REPO="Ksitropy"
# Debug without sending requests:
# export DRYRUN=1
# --- smart environment resolver: uses env if set, otherwise parses remote.origin.url ---
__resolve_env() {
# Ensure base always exists
: "${GITEA_BASE:?ERR: GITEA_BASE must be set (e.g. http://172.31.108.186:3000)}"
# If OWNER/REPO already set, skip parsing
if [ -n "$GITEA_OWNER" ] && [ -n "$GITEA_REPO" ]; then
return 0
fi
# Otherwise, derive from git remote
local remote path
remote="$(git config --get remote.origin.url 2>/dev/null)" || {
echo "ERR: not a git repo or missing origin remote" >&2
return 1
}
[ -n "$remote" ] || { echo "ERR: remote.origin.url empty" >&2; return 1; }
# Extract path (Owner/Repo)
path="$(printf '%s' "$remote" | sed -E 's#^[^:]+://[^/]+/##; s#^[^@]+@[^:]+:##')"
path="${path%.git}"
GITEA_OWNER="${path%%/*}"
GITEA_REPO="${path##*/}"
}
__need_env() {
__resolve_env || return 1
: "${GITEA_OWNER:?ERR: could not resolve OWNER}"
: "${GITEA_REPO:?ERR: could not resolve REPO}"
}
__need_token() { [ "${DRYRUN:-0}" = "1" ] && return 0; : "${GITEA_TOKEN:?ERR: set GITEA_TOKEN}"; }
__json_num() { grep -oE '"(index|number)"space:*:space:*[0-9]+' | head -n1 | grep -oE '[0-9]+'; }
showRepo() {
__need_env || return 1
echo "HOST=${GITEA_BASE%/}"
echo "OWNER=$GITEA_OWNER"
echo "REPO=$GITEA_REPO"
echo -n "API check: "
curl -fsS "${GITEA_BASE%/}/api/v1/version" && echo " (OK)"
}
# makeBranch <branch> [base]
makeBranch() {
local br="${1:?Usage: makeBranch <branch> [base]}"
local base="${2:-$DEFAULT_BASE_BRANCH}"
if git rev-parse --verify --quiet "$br" >/dev/null; then
git checkout "$br"
else
git checkout "$base" || return 1
git pull --ff-only || return 1
git checkout -b "$br" || return 1
git push --set-upstream origin "$br"
fi
}
# makeIssue <title> [body] -> prints issue#
makeIssue() {
local title="${1:?Usage: makeIssue <title> [body]}"
local body="${2:-$title}"
__need_env || return 1
__need_token || return 1
local url="${GITEA_BASE%/}/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/issues"
local data; data=$(printf '{"title":"%s","body":"%s"}' "$title" "$body")
echo "POST $url" >&2
if [ "${DRYRUN:-0}" = "1" ]; then echo "$data" >&2; return 0; fi
local resp num
resp="$(curl -fsS -X POST "$url" -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d "$data")" || return 1
num="$(__json_num <<<"$resp")"
[ -n "$num" ] && { printf '%s\n' "$num"; return 0; }
echo "ERR: could not parse issue number" >&2; echo "$resp" >&2; return 1
}
# Usage: makePRFromCurrent <title> <body> <baseBranch>
makePRFromCurrent() {
local title="${1:?Usage: makePRFromCurrent <title> <body> <baseBranch>}"
local body="${2:-}"
local base="${3:-Development}"
# ✅ prepend "WIP:" if not already present
if ! "$title" =~ ^WIP: ; then
title="WIP: $title"
fi
__need_env || return 1
__need_token || return 1
local branch
branch="$(git rev-parse --abbrev-ref HEAD)"
local url="${GITEA_BASE%/}/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/pulls"
echo "POST $url" >&2
if [ "${DRYRUN:-0}" = "1" ]; then
echo "{\"head\":\"$branch\",\"base\":\"$base\",\"title\":\"$title\",\"body\":\"$body\"}"
echo "<PR_NUM>"
return 0
fi
curl -fsS -X POST "$url" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -nc \
--arg head "$branch" \
--arg base "$base" \
--arg title "$title" \
--arg body "$body" \
'{head:$head, base:$base, title:$title, body:$body}')" |
tee /tmp/tea_pr_create.json |
jq -r '.number'
}
# linkIssueDependsOnPR <issue#> <pr#>
linkIssueDependsOnPR() {
local issue="${1:?Usage: linkIssueDependsOnPR <issue#> <pr#>}"
local pr="${2:?Usage: linkIssueDependsOnPR <issue#> <pr#>}"
__need_env || return 1
__need_token || return 1
local url="${GITEA_BASE%/}/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/issues/$issue/dependencies"
local data; data=$(printf '{"owner":"%s","repo":"%s","index":%s}' "$GITEA_OWNER" "$GITEA_REPO" "$pr")
echo "POST $url" >&2
if [ "${DRYRUN:-0}" = "1" ]; then echo "$data" >&2; return 0; fi
curl -fsS -X POST "$url" -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d "$data" >/dev/null
}
__issue_title() {
local idx="${1:?Usage: __issue_title <issue#>}"
__need_env || return 1
__need_token || return 1
local url="${GITEA_BASE%/}/api/v1/repos/$GITEA_OWNER/$GITEA_REPO/issues/$idx"
echo "GET $url" >&2
if [ "${DRYRUN:-0}" = "1" ]; then
echo "<ISSUE_TITLE>" # placeholder in dryrun
return 0
fi
curl -fsS "$url" -H "Authorization: token $GITEA_TOKEN" \
| sed -n 's/.*"title"space:*:space:*"\([^"]*\)".*/\1/p' | head -n1
}
# startWork <branch> [description]
startWork() {
local branch_base="${1:?Usage: startWork <branchBase> <title> [description] }"
local title="${2:?Usage: startWork <branchBase> <title> [description] }"
local desc="${3:-}" # optional description/comment
local pr_body
if [ -n "$desc" ]; then pr_body="$desc"; else pr_body=""; fi
if [ "${DRYRUN:-0}" = "1" ]; then
echo "==> DRYRUN: will create Issue(title='$title'), then branch 'NNN-$branch_base', then PR(title='$title')"
showRepo || true
echo "==> Creating issue"; makeIssue "$title" "$desc"
echo "==> Creating branch 'NNN-$branch_base' (base: ${DEFAULT_BASE_BRANCH})"
echo "git checkout ${DEFAULT_BASE_BRANCH} && git pull --ff-only && git checkout -b NNN-$branch_base && git push --set-upstream origin NNN-$branch_base"
echo "==> Creating PR"; local prBody="$pr_body"$'\n\n'"Closes #<NNN>"; makePRFromCurrent "$title" "$prBody" "$DEFAULT_BASE_BRANCH"
echo "==> Linking dependency"; linkIssueDependsOnPR "<NNN>" "<PR_NUM>"
return 0
fi
echo "==> Creating issue"
local issue; issue="$(makeIssue "$title" "$desc")" || return 1
echo "Created issue #$issue"
local branch="{$issue}-${branch_base}"
# Fix accidental braces if any shell expansion oddities:
branch="${branch//\{\}/}" ; branch="${branch/\{/$issue-}" ; branch="${branch/\}/}"
branch="${issue}-${branch_base}"
echo "==> Creating branch '$branch' (base: ${DEFAULT_BASE_BRANCH})"
makeBranch "$branch" "$DEFAULT_BASE_BRANCH" || return 1
echo "==> Creating PR"
local prBody="$pr_body"
[ -n "$prBody" ] && prBody="$prBody"$'\n\n'"Closes #$issue" || prBody="Closes #$issue"
local pr; pr="$(makePRFromCurrent "$title" "$prBody" "$DEFAULT_BASE_BRANCH")" || return 1
echo "Created PR #$pr"
echo "==> Linking dependency (issue #$issue depends on PR #$pr)"
linkIssueDependsOnPR "$issue" "$pr" || { echo "WARN: failed to add dependency" >&2; return 1; }
echo "✅ Done. Branch: $branch | Issue #$issue | PR #$pr"
}
# Usage: startFromIssue <branchBase> <issueNumber> [titleOverride] [description]
startFromIssue() {
local branch_base="${1:?Usage: startFromIssue <branchBase> <issueNumber> [titleOverride] [description] }"
local issue="${2:?Usage: startFromIssue <branchBase> <issueNumber> [titleOverride] [description] }"
local title_override="${3:-}"
local desc="${4:-}"
local title
if [ -n "$title_override" ]; then
title="$title_override"
else
title="$(__issue_title "$issue")" || return 1
[ -n "$title" ] || { echo "ERR: could not fetch title for issue #$issue" >&2; return 1; }
fi
local branch="${issue}-${branch_base}"
if [ "${DRYRUN:-0}" = "1" ]; then
echo "==> DRYRUN: will create branch '$branch' from issue #$issue, PR titled '$title'"
showRepo || true
echo "==> Creating branch '$branch' (base: ${DEFAULT_BASE_BRANCH})"
echo "git checkout ${DEFAULT_BASE_BRANCH} && git pull --ff-only && git checkout -b ${branch} && git push --set-upstream origin ${branch}"
echo "==> Creating PR"; local prBody="${desc}"$'\n\n'"Closes #$issue"; makePRFromCurrent "$title" "$prBody" "$DEFAULT_BASE_BRANCH"
echo "==> Linking dependency"; linkIssueDependsOnPR "$issue" "<PR_NUM>"
return 0
fi
echo "==> Creating branch '$branch' (base: ${DEFAULT_BASE_BRANCH})"
makeBranch "$branch" "$DEFAULT_BASE_BRANCH" || return 1
echo "==> Creating PR"
local prBody
[ -n "$desc" ] && prBody="$desc"$'\n\n'"Closes #$issue" || prBody="Closes #$issue"
local pr; pr="$(makePRFromCurrent "$title" "$prBody" "$DEFAULT_BASE_BRANCH")" || return 1
echo "Created PR #$pr"
echo "==> Linking dependency (issue #$issue depends on PR #$pr)"
linkIssueDependsOnPR "$issue" "$pr" || { echo "WARN: failed to add dependency" >&2; return 1; }
echo "✅ Done. Branch: $branch | Issue #$issue | PR #$pr"
}