From e2c78fec4656429e765db4efefed8ae9eead495e Mon Sep 17 00:00:00 2001 From: Matteo Cherubini Date: Fri, 8 May 2026 21:09:42 +0200 Subject: [PATCH] feat: Implement repository provider interfaces for GitHub and Forgejo --- providers/forgejo.sh | 53 +++++++++++++++++++++++++++++++++++++++++++ providers/github.sh | 54 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 providers/forgejo.sh create mode 100644 providers/github.sh diff --git a/providers/forgejo.sh b/providers/forgejo.sh new file mode 100644 index 0000000..3ed45be --- /dev/null +++ b/providers/forgejo.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# ============================================================================= +# providers/forgejo.sh +# Forgejo REST API provider implementation. +# ============================================================================= + +provider_name() { + echo "Forgejo (${FORGEJO_URL})" +} + +# --------------------------------------------------------------------------- +# provider_create_repo +# --------------------------------------------------------------------------- +provider_create_repo() { + local name="$1" + local desc="$2" + local private="$3" + + local http_code + http_code=$(curl -s -o /dev/null -w "%{http_code}" \ + -H "Authorization: token ${FORGEJO_TOKEN}" \ + -H "Content-Type: application/json" \ + -X POST "${FORGEJO_URL}/api/v1/user/repos" \ + -d "{ + \"name\": \"${name}\", + \"description\": \"${desc}\", + \"private\": ${private}, + \"auto_init\": false + }") + + case "$http_code" in + 201) success "Repository '${name}' created successfully." ;; + 409) info "Repository '${name}' already exists - skipping." ;; + 401) error "Unauthorized. Check your FORGEJO_TOKEN."; exit 1 ;; + *) error "Forgejo API returned HTTP ${http_code}. Check connectivity."; exit 1 ;; + esac +} + +provider_clone_url() { + echo "${FORGEJO_URL}/${FORGEJO_USER}/${1}.git" +} + +provider_ssh_url() { + local host + # Extract hostname by removing protocol and trailing slashes + host=$(echo "${FORGEJO_URL}" | sed -e 's|^[^/]*//||' -e 's|/*$||') + # Using port 222 as default for many homelab Forgejo/Gitea setups + echo "ssh://git@${host}:222/${FORGEJO_USER}/${1}.git" +} + +provider_web_url() { + echo "${FORGEJO_URL}/${FORGEJO_USER}/${1}" +} diff --git a/providers/github.sh b/providers/github.sh new file mode 100644 index 0000000..14193ae --- /dev/null +++ b/providers/github.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# ============================================================================= +# providers/github.sh +# GitHub REST API provider implementation. +# ============================================================================= + +provider_name() { + echo "GitHub (https://github.com)" +} + +_github_namespace() { + echo "${GITHUB_ORG:-$GITHUB_USER}" +} + +provider_create_repo() { + local name="$1" + local desc="$2" + local private="$3" + local namespace + namespace=$(_github_namespace) + + local endpoint="https://api.github.com/user/repos" + [[ -n "${GITHUB_ORG:-}" ]] && endpoint="https://api.github.com/orgs/${namespace}/repos" + + local http_code + http_code=$(curl -s -o /dev/null -w "%{http_code}" \ + -H "Authorization: token ${GITHUB_TOKEN}" \ + -H "Accept: application/vnd.github.v3+json" \ + -X POST "$endpoint" \ + -d "{ + \"name\": \"${name}\", + \"description\": \"${desc}\", + \"private\": ${private}, + \"auto_init\": false + }") + + case "$http_code" in + 201) success "Repository '${name}' created on GitHub." ;; + 422) info "Repository '${name}' already exists - skipping." ;; + *) error "GitHub API returned HTTP ${http_code}. check token/permissions."; exit 1 ;; + esac +} + +provider_ssh_url() { + echo "git@github.com:$(_github_namespace)/${1}.git" +} + +provider_clone_url() { + echo "https://github.com/$(_github_namespace)/${1}.git" +} + +provider_web_url() { + echo "https://github.com/$(_github_namespace)/${1}" +}