From 4f41f0d98b612cd25b625db92520d4f5df839cce Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Mon, 2 Mar 2026 10:06:29 -0800 Subject: [PATCH] feat: add Gitea actions to sync releases to GitHub Add two new workflows: - sync-release.yml: automatically mirrors releases (with assets) to GitHub when published on Gitea - backfill-releases.yml: manual workflow to bulk-sync all existing Gitea releases to GitHub Co-Authored-By: Claude Opus 4.6 --- .gitea/workflows/backfill-releases.yml | 83 ++++++++++++++++++++++++++ .gitea/workflows/sync-release.yml | 60 +++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 .gitea/workflows/backfill-releases.yml create mode 100644 .gitea/workflows/sync-release.yml diff --git a/.gitea/workflows/backfill-releases.yml b/.gitea/workflows/backfill-releases.yml new file mode 100644 index 0000000..ff01fe3 --- /dev/null +++ b/.gitea/workflows/backfill-releases.yml @@ -0,0 +1,83 @@ +name: Backfill Releases to GitHub + +on: + workflow_dispatch: + +jobs: + backfill: + runs-on: ubuntu-latest + steps: + - name: Backfill all Gitea releases to GitHub + env: + GH_PAT: ${{ secrets.GH_PAT }} + GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + GITEA_API: https://repo.anhonesthost.net/api/v1 + GITEA_REPO: cybercovellc/triple-c + GITHUB_REPO: shadowdao/triple-c + run: | + set -e + + echo "==> Fetching releases from Gitea..." + RELEASES=$(curl -sf \ + -H "Authorization: token $GITEA_TOKEN" \ + "$GITEA_API/repos/$GITEA_REPO/releases?limit=50") + + echo "$RELEASES" | jq -c '.[]' | while read release; do + TAG=$(echo "$release" | jq -r '.tag_name') + NAME=$(echo "$release" | jq -r '.name') + BODY=$(echo "$release" | jq -r '.body') + IS_PRERELEASE=$(echo "$release" | jq -r '.prerelease') + IS_DRAFT=$(echo "$release" | jq -r '.draft') + + EXISTS=$(curl -sf \ + -H "Authorization: Bearer $GH_PAT" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/$GITHUB_REPO/releases/tags/$TAG" \ + -o /dev/null -w "%{http_code}" || true) + + if [ "$EXISTS" = "200" ]; then + echo "==> Skipping $TAG (already exists on GitHub)" + continue + fi + + echo "==> Creating release $TAG..." + RESPONSE=$(curl -sf -X POST \ + -H "Authorization: Bearer $GH_PAT" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/json" \ + https://api.github.com/repos/$GITHUB_REPO/releases \ + -d "{ + \"tag_name\": \"$TAG\", + \"name\": \"$NAME\", + \"body\": $(echo "$BODY" | jq -Rs .), + \"draft\": $IS_DRAFT, + \"prerelease\": $IS_PRERELEASE + }") + + UPLOAD_URL=$(echo "$RESPONSE" | jq -r '.upload_url' | sed 's/{?name,label}//') + + echo "$release" | jq -c '.assets[]?' | while read asset; do + ASSET_NAME=$(echo "$asset" | jq -r '.name') + ASSET_ID=$(echo "$asset" | jq -r '.id') + + echo " ==> Downloading $ASSET_NAME..." + curl -sfL -o "/tmp/$ASSET_NAME" \ + -H "Authorization: token $GITEA_TOKEN" \ + "$GITEA_API/repos/$GITEA_REPO/releases/assets/$ASSET_ID" + + echo " ==> Uploading $ASSET_NAME to GitHub..." + ENCODED_NAME=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" "$ASSET_NAME") + curl -sf -X POST \ + -H "Authorization: Bearer $GH_PAT" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/octet-stream" \ + --data-binary "@/tmp/$ASSET_NAME" \ + "$UPLOAD_URL?name=$ENCODED_NAME" + + echo " Uploaded: $ASSET_NAME" + done + + echo "==> Done: $TAG" + done + + echo "==> Backfill complete." \ No newline at end of file diff --git a/.gitea/workflows/sync-release.yml b/.gitea/workflows/sync-release.yml new file mode 100644 index 0000000..cfe2f97 --- /dev/null +++ b/.gitea/workflows/sync-release.yml @@ -0,0 +1,60 @@ +name: Sync Release to GitHub + +on: + release: + types: [published] + +jobs: + sync-release: + runs-on: ubuntu-latest + steps: + - name: Mirror release to GitHub + env: + GH_PAT: ${{ secrets.GH_PAT }} + GITHUB_REPO: shadowdao/triple-c + RELEASE_TAG: ${{ gitea.event.release.tag_name }} + RELEASE_NAME: ${{ gitea.event.release.name }} + RELEASE_BODY: ${{ gitea.event.release.body }} + IS_PRERELEASE: ${{ gitea.event.release.prerelease }} + IS_DRAFT: ${{ gitea.event.release.draft }} + run: | + set -e + + echo "==> Creating release $RELEASE_TAG on GitHub..." + + RESPONSE=$(curl -sf -X POST \ + -H "Authorization: Bearer $GH_PAT" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/json" \ + https://api.github.com/repos/$GITHUB_REPO/releases \ + -d "{ + \"tag_name\": \"$RELEASE_TAG\", + \"name\": \"$RELEASE_NAME\", + \"body\": $(echo "$RELEASE_BODY" | jq -Rs .), + \"draft\": $IS_DRAFT, + \"prerelease\": $IS_PRERELEASE + }") + + UPLOAD_URL=$(echo "$RESPONSE" | jq -r '.upload_url' | sed 's/{?name,label}//') + echo "Release created. Upload URL: $UPLOAD_URL" + + echo '${{ toJSON(gitea.event.release.assets) }}' | jq -c '.[]' | while read asset; do + ASSET_NAME=$(echo "$asset" | jq -r '.name') + ASSET_URL=$(echo "$asset" | jq -r '.browser_download_url') + + echo "==> Downloading asset: $ASSET_NAME" + curl -sfL -o "/tmp/$ASSET_NAME" "$ASSET_URL" + + echo "==> Uploading $ASSET_NAME to GitHub..." + ENCODED_NAME=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" "$ASSET_NAME") + curl -sf -X POST \ + -H "Authorization: Bearer $GH_PAT" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/octet-stream" \ + --data-binary "@/tmp/$ASSET_NAME" \ + "$UPLOAD_URL?name=$ENCODED_NAME" + + echo " Uploaded: $ASSET_NAME" + done + + echo "==> Release sync complete." \ No newline at end of file