ci: upload release artifacts to Cloudflare R2 (#237)

Release binaries are currently only attached to the Gitea release, with no mirror on the download CDN. This adds a Cloudflare R2 upload to the tag release workflow, following the approach used by [gitea/tea](https://gitea.com/gitea/tea).

- Add `scripts/upload-r2.sh`, taken from `gitea/tea`: it uploads a single file to an R2 object key with curl's built-in AWS SigV4 signer (R2 is S3-API compatible), and supports a `--check-config` preflight mode. Credentials are passed through a curl config file on stdin so they never appear in `ps` output.
- Add a `Check R2 configuration` step at the beginning of the `goreleaser` job, so a missing `R2_*` secret fails the run before anything is built or published.
- Add an `Upload binaries to Cloudflare R2` step after GoReleaser, which mirrors every archive and `checksums.txt` from `dist/` to `gitea-mcp/<version>/<file>` in the bucket. `tea` does this with a goreleaser `publishers:` entry, but that is a GoReleaser Pro feature and this repository uses the OSS distribution, so the upload runs as a workflow step instead.

Required repository secrets: `R2_ENDPOINT`, `R2_BUCKET`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`. No AWS S3 upload is added; Cloudflare R2 is the only mirror.

Tested locally by pointing `R2_ENDPOINT` at a local HTTP server and verifying the script builds the expected path-style URL and signed request, plus `shellcheck` on the script.

_Authored by Codet (GPT-5-Codex) on behalf of @lunny._

---------

Co-authored-by: bircni <bircni@icloud.com>
Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/237
Reviewed-by: silverwind <2021+silverwind@noreply.gitea.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
Lunny Xiao
2026-08-17 17:15:32 +00:00
committed by bircni
parent 1f5fe9269b
commit 7fce9bc790
2 changed files with 121 additions and 0 deletions
+25
View File
@@ -13,6 +13,16 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
# The R2 upload only runs after goreleaser has already published
# the Gitea release, so fail early instead if the secrets are
# missing.
- name: Check R2 configuration
run: sh scripts/upload-r2.sh --check-config
env:
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_BUCKET: ${{ secrets.R2_BUCKET }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
- name: Set up Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
@@ -25,6 +35,21 @@ jobs:
env:
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GORELEASER_FORCE_TOKEN: "gitea"
# goreleaser `publishers:` is a Pro-only feature, so the release
# artifacts are mirrored to Cloudflare R2 here instead.
- name: Upload binaries to Cloudflare R2
env:
R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
R2_BUCKET: ${{ secrets.R2_BUCKET }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
VERSION: ${{ github.ref_name }}
run: |
for f in dist/*.tar.gz dist/*.zip dist/checksums.txt; do
[ -f "$f" ] || continue
echo "uploading $f"
sh scripts/upload-r2.sh "$f" "gitea-mcp/${VERSION#v}/$(basename "$f")"
done
release-image:
runs-on: ubuntu-latest