Initial commit
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# Gitea Tools
|
||||
|
||||
A collection of Python and Bash scripts to automate interactions with Gitea instances.
|
||||
|
||||
## Setup
|
||||
|
||||
A Python virtual environment is included. Activate it using:
|
||||
```bash
|
||||
source venv/bin/activate
|
||||
```
|
||||
|
||||
## 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`.
|
||||
|
||||
## 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
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
HOST="gitea.dadeschools.net"
|
||||
API="https://$HOST/api/v1"
|
||||
ORG="Contractor"
|
||||
REPO="Timesheet"
|
||||
ISSUE_NUM=$1
|
||||
|
||||
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 "${AUTH[@]}" -H "Content-Type: application/json" -d "$PAYLOAD" "$API/repos/$ORG/$REPO/issues/$ISSUE_NUM"
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Define the issues to create based on ROADMAP.md missing/partially done items.
|
||||
ISSUES = [
|
||||
("PDF: Preview PDF before final save", "Show a preview or summary dialog before the PDF is fully committed to disk."),
|
||||
("PDF: Compare generated PDFs against known-good samples", "Add visual or byte-comparison tests to ensure PDF rendering doesn't drift."),
|
||||
("PDF: Validate week/date placement", "Add validation that the week date ranges are accurately placed inside the generated PDF fields."),
|
||||
("PDF: Validate total hours calculation", "Add backend validation to verify that total hours printed in the PDF are mathematically correct."),
|
||||
("PDF: Warn if total hours are not 40", "Add total-hours validation and user-facing warnings when generating timesheets that do not sum to exactly 40 hours."),
|
||||
("PDF: Support PTO, sick, holiday, and blank days", "Timesheet grid assumes default hours and lacks distinct categories. Add support for PTO, sick, holiday, and blank days."),
|
||||
("PDF: Open generated PDF after creation", "Provide an option or automatic behavior to open the PDF in the default viewer immediately after generating."),
|
||||
("Email: Preview email before draft creation", "Display the email body and recipients before launching Outlook."),
|
||||
("Email: Saved manager recipient", "Allow saving the manager's email address in settings so it populates automatically."),
|
||||
("Email: Saved email templates", "Add Outlook email template body customization in Settings."),
|
||||
("GUI: One-click generate this week's timesheet", "Add a quick-action button to generate the current week's timesheet with a single click."),
|
||||
("GUI: Duplicate previous week", "Add functionality to clone the hours and projects from the previous week's timesheet."),
|
||||
("GUI: Better success screen", "Improve the UI feedback shown after a successful generation."),
|
||||
("GUI: Dark-mode friendly UI", "Ensure the UI colors and styling are properly adapted for macOS dark mode."),
|
||||
("Data: Add ~/.timesheet/history.json configuration", "History tracking is currently using `.state/history.json`. Move this to a user-local `~/.timesheet/history.json` path."),
|
||||
("Data: Track generated PDF metadata", "Track generated PDF path, week range, total hours, created_at, and email mode in the history JSON."),
|
||||
("DevOps: Local / Gitea Validation Pipeline", "Lacks git pre-commit hooks and Gitea/Woodpecker pipeline configurations for running tests and pyright."),
|
||||
("Dev: Split large GUI files into smaller controllers", "Further decomposition of large GUI panels and controllers into smaller, more maintainable modules."),
|
||||
("Dev: Add tests for manage.sh", "Add test coverage for the command-line menu tool `manage.sh`."),
|
||||
("Dev: Add app versioning", "Implement dynamic/git tagging and formal app versioning (currently only basic versioning exists)."),
|
||||
("Dev: Add About dialog", "Add an About dialog in the GUI with version and author info."),
|
||||
("Dev: Add release notes", "Create a process for generating and displaying release notes on updates."),
|
||||
("Dev: Improve project structure", "Clean up helper scripts and organize the project root structure better.")
|
||||
]
|
||||
|
||||
SCRIPT_PATH = "./scripts/create-issue.sh"
|
||||
|
||||
def main():
|
||||
if not os.path.exists(SCRIPT_PATH):
|
||||
print(f"Error: Could not find {SCRIPT_PATH}. Run this from the repository root.")
|
||||
sys.exit(1)
|
||||
|
||||
success_count = 0
|
||||
for title, body in ISSUES:
|
||||
print(f"Creating issue: {title}")
|
||||
result = subprocess.run([SCRIPT_PATH, title, body], capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
print(result.stdout.strip())
|
||||
success_count += 1
|
||||
else:
|
||||
print(f"FAILED to create issue: {title}")
|
||||
print(result.stderr.strip())
|
||||
|
||||
print(f"\nFinished! Created {success_count} out of {len(ISSUES)} issues.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
import sys
|
||||
import json
|
||||
import urllib.request
|
||||
import subprocess
|
||||
import base64
|
||||
|
||||
host = "gitea.dadeschools.net"
|
||||
org = "Contractor"
|
||||
repo = "Timesheet"
|
||||
|
||||
p = subprocess.Popen(["git", "credential", "fill"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
|
||||
out, _ = p.communicate(f"protocol=https\nhost=gitea.dadeschools.net\n\n")
|
||||
|
||||
user = ""
|
||||
password = ""
|
||||
for line in out.splitlines():
|
||||
if line.startswith("username="):
|
||||
user = line.split("=")[1]
|
||||
if line.startswith("password="):
|
||||
password = line.split("=")[1]
|
||||
|
||||
if not user or not password:
|
||||
print("Could not get credentials")
|
||||
sys.exit(1)
|
||||
|
||||
url = f"https://{host}/api/v1/repos/{org}/{repo}/pulls"
|
||||
data = {
|
||||
"title": "feat: Support PTO, Sick, Holiday, and Unpaid days",
|
||||
"body": "Closes #6",
|
||||
"head": "feat/6-absence-categories",
|
||||
"base": "main"
|
||||
}
|
||||
req = urllib.request.Request(url, data=json.dumps(data).encode("utf-8"), headers={
|
||||
"Content-Type": "application/json",
|
||||
})
|
||||
|
||||
auth_b64 = base64.b64encode(f"{user}:{password}".encode("utf-8")).decode("utf-8")
|
||||
req.add_header("Authorization", f"Basic {auth_b64}")
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
print(response.read().decode())
|
||||
except urllib.error.HTTPError as e:
|
||||
print("Error:", e.read().decode())
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/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"
|
||||
Reference in New Issue
Block a user