chore: improve tooling quality and docs
- close_issue.sh: add set -euo pipefail, argument validation, confirmation output - mark_issue.sh: track previously untracked claim/release script - create_pr.sh: remove hardcoded one-off (use create_pr.py instead) - README.md: reflect current toolset with usage examples - .gitignore: ignore venv/ and __pycache__/
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
venv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
@@ -2,23 +2,47 @@
|
||||
|
||||
A collection of Python and Bash scripts to automate interactions with Gitea instances.
|
||||
|
||||
## Setup
|
||||
## Supported Instances
|
||||
|
||||
A Python virtual environment is included. Activate it using:
|
||||
```bash
|
||||
source venv/bin/activate
|
||||
```
|
||||
| Remote | Host | Org / Repo |
|
||||
|----------------|----------------------------|-------------------------------------|
|
||||
| `dadeschools` | `gitea.dadeschools.net` | `Contractor / Timesheet` |
|
||||
| `prgs` | `gitea.prgs.cc` | `Scaled-Tech-Consulting / Timesheet`|
|
||||
|
||||
## Authentication
|
||||
|
||||
These scripts securely extract tokens from the macOS keychain to avoid hardcoding secrets.
|
||||
|
||||
- **Dade Schools (gitea.dadeschools.net)**: Retrieved via `git credential fill`. Ensure you have logged in via Git over HTTPS at least once so the keychain caches your credentials.
|
||||
- **NetBridge / Personal (gitea.prgs.cc)**: Retrieved using `security find-generic-password` for the service `netbridge-gitea-token`.
|
||||
Credentials are retrieved via `git credential fill` for the target host. Ensure you have
|
||||
logged in via Git over HTTPS at least once so the keychain caches your credentials.
|
||||
|
||||
## Available Scripts
|
||||
|
||||
- `./create_issue.py` - Create an issue in the Gitea tracker
|
||||
- `./create_pr.py` - Open a Pull Request from a branch via the API
|
||||
- `./create_pr.sh` - Bash equivalent for creating a PR via the API
|
||||
- `./close_issue.sh` - Close a specific issue via the API
|
||||
| Script | Description |
|
||||
|---------------------|-----------------------------------------------------|
|
||||
| `create_issue.py` | Create an issue (`--remote`, `--title`, `--body`) |
|
||||
| `create_pr.py` | Open a Pull Request (`--remote`, `--title`, `--head`, `--base`) |
|
||||
| `close_issue.sh` | Close a specific issue (dadeschools only) |
|
||||
| `mark_issue.sh` | Claim/release an issue via `status:in-progress` label |
|
||||
| `manage_labels.py` | Create label set and apply label mappings (`--dry` to preview) |
|
||||
|
||||
### Quick Examples
|
||||
|
||||
```bash
|
||||
# Create an issue
|
||||
./create_issue.py --title "Fix PDF output" --body "Blank on Safari"
|
||||
|
||||
# Create a PR
|
||||
./create_pr.py --title "feat: add validation" --head feat/validation --body "Closes #12"
|
||||
|
||||
# Close issue #5
|
||||
./close_issue.sh 5
|
||||
|
||||
# Claim an issue before working on it
|
||||
./mark_issue.sh 10 start
|
||||
|
||||
# Release when done
|
||||
./mark_issue.sh 10 done
|
||||
```
|
||||
|
||||
Use `--help` on any Python script for full usage details.
|
||||
|
||||
+16
-4
@@ -1,15 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Close a Gitea issue by setting its state to "closed".
|
||||
#
|
||||
# Usage: ./close_issue.sh <issue_number>
|
||||
#
|
||||
# Auth: macOS keychain via `git credential fill` (same as the other scripts).
|
||||
set -euo pipefail
|
||||
|
||||
HOST="gitea.dadeschools.net"
|
||||
API="https://$HOST/api/v1"
|
||||
ORG="Contractor"
|
||||
REPO="Timesheet"
|
||||
ISSUE_NUM=$1
|
||||
|
||||
ISSUE_NUM="${1:?usage: close_issue.sh <issue_number>}"
|
||||
|
||||
CREDS=$(printf "host=%s\nprotocol=https\n\n" "$HOST" | git credential fill)
|
||||
USER=$(printf '%s\n' "$CREDS" | sed -n 's/^username=//p')
|
||||
PASS=$(printf '%s\n' "$CREDS" | sed -n 's/^password=//p')
|
||||
|
||||
AUTH=(-u "$USER:$PASS")
|
||||
PAYLOAD='{"state": "closed"}'
|
||||
curl -sSL -X PATCH \
|
||||
-u "$USER:$PASS" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"state": "closed"}' \
|
||||
"$API/repos/$ORG/$REPO/issues/$ISSUE_NUM"
|
||||
|
||||
curl -sSL -X PATCH "${AUTH[@]}" -H "Content-Type: application/json" -d "$PAYLOAD" "$API/repos/$ORG/$REPO/issues/$ISSUE_NUM"
|
||||
echo ""
|
||||
echo "#$ISSUE_NUM closed"
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
HOST="gitea.dadeschools.net"
|
||||
API="https://$HOST/api/v1"
|
||||
ORG="Contractor"
|
||||
REPO="Timesheet"
|
||||
|
||||
CREDS=$(printf "host=%s\nprotocol=https\n\n" "$HOST" | git credential fill)
|
||||
USER=$(printf '%s\n' "$CREDS" | sed -n 's/^username=//p')
|
||||
PASS=$(printf '%s\n' "$CREDS" | sed -n 's/^password=//p')
|
||||
|
||||
AUTH=(-u "$USER:$PASS")
|
||||
PAYLOAD='{"title": "feat: Support PTO, Sick, Holiday, and Unpaid days", "body": "Closes #6", "head": "feat/6-absence-categories", "base": "main"}'
|
||||
|
||||
curl -sSL -X POST "${AUTH[@]}" -H "Content-Type: application/json" -d "$PAYLOAD" "$API/repos/$ORG/$REPO/pulls"
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
# Claim or release a Gitea issue by toggling the `status:in-progress` label, so
|
||||
# parallel agents/LLMs don't pick up the same issue.
|
||||
#
|
||||
# Usage:
|
||||
# ./mark_issue.sh <issue_number> # claim (adds status:in-progress)
|
||||
# ./mark_issue.sh <issue_number> start # claim
|
||||
# ./mark_issue.sh <issue_number> done # release (removes the label)
|
||||
#
|
||||
# Auth: macOS keychain via `git credential fill` (same as the other scripts).
|
||||
set -euo pipefail
|
||||
|
||||
HOST="gitea.dadeschools.net"
|
||||
API="https://$HOST/api/v1"
|
||||
ORG="Contractor"
|
||||
REPO="Timesheet"
|
||||
LABEL="status:in-progress"
|
||||
|
||||
NUM="${1:?usage: mark_issue.sh <issue_number> [start|done]}"
|
||||
ACTION="${2:-start}"
|
||||
|
||||
CREDS=$(printf "host=%s\nprotocol=https\n\n" "$HOST" | git credential fill)
|
||||
USER=$(printf '%s\n' "$CREDS" | sed -n 's/^username=//p')
|
||||
PASS=$(printf '%s\n' "$CREDS" | sed -n 's/^password=//p')
|
||||
AUTH=(-u "$USER:$PASS")
|
||||
|
||||
# Resolve the label name -> id (Gitea's issue label endpoints take ids).
|
||||
LID=$(curl -sSL "${AUTH[@]}" "$API/repos/$ORG/$REPO/labels?limit=100" \
|
||||
| python3 -c "import sys,json;print(next((l['id'] for l in json.load(sys.stdin) if l['name']=='$LABEL'),''))")
|
||||
if [ -z "$LID" ]; then
|
||||
echo "Label '$LABEL' not found in $ORG/$REPO -- run manage_labels.py first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$ACTION" in
|
||||
start)
|
||||
curl -sSL -X POST "${AUTH[@]}" -H "Content-Type: application/json" \
|
||||
-d "{\"labels\":[$LID]}" "$API/repos/$ORG/$REPO/issues/$NUM/labels" >/dev/null
|
||||
echo "#$NUM claimed -> $LABEL"
|
||||
;;
|
||||
done)
|
||||
curl -sSL -X DELETE "${AUTH[@]}" \
|
||||
"$API/repos/$ORG/$REPO/issues/$NUM/labels/$LID" >/dev/null
|
||||
echo "#$NUM released -> $LABEL removed"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown action '$ACTION' (expected: start | done)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user