The composite action in .gitea/actions/review/action.yml hardcodes Gitea assumptions that break when running on GitHub Enterprise Server:
REPO is hardcoded to rodin/review-bot — should be the repo hosting the action on the current server
Releases API uses Gitea path format (/api/v1/repos/...) — GitHub uses /api/v3/repos/... (or REST /repos/...)
Binary download URL format — Gitea: https://gitea.weiker.me/rodin/review-bot/releases/download/... vs GitHub: https://github.concur.com/strat/review-bot/releases/download/...
Observed
When running on github.concur.com runners:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
The version resolution curl hits https://github.concur.com/api/v1/repos/rodin/review-bot/releases — wrong API format and wrong repo.
Fix
The action should:
Detect the VCS host (Gitea vs GitHub) from github.server_url
Use the appropriate releases API format for each host
Derive the action repo from context rather than hardcoding rodin/review-bot
Or: accept an explicit action-repo input that defaults to the Gitea value for backward compatibility
Context
Discovered while testing GitHub support (feature/github-support) against strat/db-migrator on github.concur.com.
## Problem
The composite action in `.gitea/actions/review/action.yml` hardcodes Gitea assumptions that break when running on GitHub Enterprise Server:
1. **`REPO` is hardcoded to `rodin/review-bot`** — should be the repo hosting the action on the current server
2. **Releases API uses Gitea path format** (`/api/v1/repos/...`) — GitHub uses `/api/v3/repos/...` (or REST `/repos/...`)
3. **Binary download URL format** — Gitea: `https://gitea.weiker.me/rodin/review-bot/releases/download/...` vs GitHub: `https://github.concur.com/strat/review-bot/releases/download/...`
## Observed
When running on `github.concur.com` runners:
```
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
```
The version resolution curl hits `https://github.concur.com/api/v1/repos/rodin/review-bot/releases` — wrong API format and wrong repo.
## Fix
The action should:
- Detect the VCS host (Gitea vs GitHub) from `github.server_url`
- Use the appropriate releases API format for each host
- Derive the action repo from context rather than hardcoding `rodin/review-bot`
- Or: accept an explicit `action-repo` input that defaults to the Gitea value for backward compatibility
## Context
Discovered while testing GitHub support (feature/github-support) against `strat/db-migrator` on `github.concur.com`.
rodin
self-assigned this 2026-05-14 03:59:06 +00:00
Plan: Fix version resolution and binary download for GitHub hosts
Problem
The composite action in both .gitea/actions/review/action.yml and .github/actions/review/action.yml has three Gitea-specific assumptions that break on GitHub/GHES:
REPO defaults to rodin/review-bot — on GHES the action lives in a different repo (e.g. strat/review-bot)
Releases API path is Gitea-specific — uses /api/v1/repos/{owner}/{repo}/releases but GitHub uses /repos/{owner}/{repo}/releases (REST v3)
Download URL format — Gitea: {server}/{repo}/releases/download/{tag}/{asset}, GitHub: {server}/{repo}/releases/download/{tag}/{asset} (same pattern but the API endpoint differs)
Constraints
Must remain backward-compatible — existing Gitea users with no repo input should work unchanged
Both .gitea and .github action files must be updated
The inputs.gitea-url name stays for backward compat (renaming would break callers)
No new binary dependencies; python3 + curl already available
Must work on both Gitea Actions and GitHub Actions runners
Proposed Approach
Host detection: Determine whether we're on Gitea or GitHub by checking the releases API. A simple heuristic: if github.server_url contains github.com or the /api/v3/ endpoint responds, treat it as GitHub. Otherwise assume Gitea.
Actually, a cleaner approach: use the API format that matches the host. The action can try the Gitea endpoint first, and if it fails (non-JSON response), fall back to GitHub REST API. But that's fragile.
Simplest reliable approach:
Add a new input action-repo that specifies where to find review-bot releases. Defaults to rodin/review-bot for backward compat.
Detect host type from github.server_url:
If it contains github.com OR returns a GitHub-style API response → GitHub mode
Download URL is the same format on both: ${SERVER_URL}/${REPO}/releases/download/${VERSION}/${BINARY}
Wait — checking the actual GitHub releases download URL format... On GHES it's: https://github.concur.com/{owner}/{repo}/releases/download/{tag}/{asset} which IS the same pattern as Gitea. So the download URL logic is fine as-is. The only real issue is the releases API path and the repo default.
Revised approach (minimal change):
Add action-repo input that defaults to empty (meaning: use github.repository context)
For the REPO variable: use inputs.action-repo || inputs.repo || github.repository — but wait, inputs.repo is the target repo being reviewed, not the repo hosting the action. We need to separate these.
Actually re-reading the code more carefully:
inputs.repo in "Run review" = the repo being reviewed (target)
REPO in "Determine version" and "Install review-bot" = the repo hosting review-bot releases (action source)
These are different repos and currently both default to rodin/review-bot which conflates them.
Final approach:
Add action-repo input (default: empty) — the repo that hosts review-bot releases
When action-repo is empty, derive it from github.action_repository (GitHub Actions provides this as the repo containing the action being run) — but Gitea Actions may not support this. Fallback: hardcode rodin/review-bot if empty (maintains backward compat for Gitea).
Detect host type using a helper function:
Check if ${SERVER_URL}/api/v3/ path exists (GitHub/GHES)
Otherwise use /api/v1/ (Gitea)
Or simpler: just try both — use /api/v1/ if it returns valid JSON, else try /api/v3/
Apply host-appropriate API path for releases query
Simplest implementation (avoiding API probing):
Use a new input vcs-type with values auto|gitea|github, defaulting to auto
auto detection: if github.server_url matches *github* → github, else → gitea
This handles: github.com, github.concur.com, github.yourcompany.io etc.
Implementation Details
New inputs:
action-repo:description:'Repository hosting review-bot releases (owner/name). Defaults to github.action_repository on GitHub, rodin/review-bot on Gitea'required:falsedefault:''
"Determine version" step changes:
SERVER_URL="${{ inputs.gitea-url || github.server_url }}"# Determine action repo (where review-bot releases live)ACTION_REPO="${{ inputs.action-repo }}"if[ -z "$ACTION_REPO"];then# github.action_repository gives us the repo containing this actionACTION_REPO="${{ github.action_repository || 'rodin/review-bot'}}"fi# Detect API format based on server URLifecho"$SERVER_URL"| grep -qi "github";thenAPI_PATH="${SERVER_URL}/api/v3/repos/${ACTION_REPO}/releases?per_page=1"elseAPI_PATH="${SERVER_URL}/api/v1/repos/${ACTION_REPO}/releases?limit=1"fiif["${{ inputs.version }}"="latest"];thenVERSION=$(curl -sSf "$API_PATH"\
| python3 -c "import sys, json; releases = json.load(sys.stdin); print(releases[0]['tag_name'] if releases else '')")
...
fi
"Install review-bot" step changes:
Same pattern — use ACTION_REPO and the server URL directly for download (download URL format is the same on both platforms).
"Run review" step:
Already uses inputs.repo || github.repository for the target repo. The env var names differ between .gitea (GITEA_URL/GITEA_REPO) and .github (GITHUB_SERVER_URL/GITHUB_REPOSITORY) — that's fine and intentional.
Testing Strategy
Verify action still works on Gitea (backward compat) — existing CI on gitea.weiker.me
Test the action-repo input explicitly with a GHES-style URL
Manual test: set gitea-url to https://github.concur.com and action-repo to strat/review-bot
Edge Cases
github.action_repository might not be available in Gitea Actions → fallback to rodin/review-bot
Server URL with trailing slash → strip it
GHES might use a custom domain without "github" in the name → vcs-type or action-repo input covers this
Open Questions
github.action_repository: Gitea Actions might support this (it emulates GitHub Actions context). Need to verify. If it does, no action-repo input needed at all — just use github.action_repository with rodin/review-bot fallback.
Should we support authentication for the releases API call? Currently it's unauthenticated. On GHES, releases might be in a private repo. For now, assume public releases (can add release-token input later if needed).
Completion Checklist
Both .gitea and .github action files updated with host detection
action-repo input added with sensible defaults
Releases API uses correct path format per host type
Download URL works on both Gitea and GitHub
Backward compatible — existing users with no new inputs still work
No new dependencies added
inputs.repo (target repo for review) kept separate from action repo
## Plan: Fix version resolution and binary download for GitHub hosts
### Problem
The composite action in both `.gitea/actions/review/action.yml` and `.github/actions/review/action.yml` has three Gitea-specific assumptions that break on GitHub/GHES:
1. **`REPO` defaults to `rodin/review-bot`** — on GHES the action lives in a different repo (e.g. `strat/review-bot`)
2. **Releases API path is Gitea-specific** — uses `/api/v1/repos/{owner}/{repo}/releases` but GitHub uses `/repos/{owner}/{repo}/releases` (REST v3)
3. **Download URL format** — Gitea: `{server}/{repo}/releases/download/{tag}/{asset}`, GitHub: `{server}/{repo}/releases/download/{tag}/{asset}` (same pattern but the API endpoint differs)
### Constraints
- Must remain backward-compatible — existing Gitea users with no `repo` input should work unchanged
- Both `.gitea` and `.github` action files must be updated
- The `inputs.gitea-url` name stays for backward compat (renaming would break callers)
- No new binary dependencies; python3 + curl already available
- Must work on both Gitea Actions and GitHub Actions runners
### Proposed Approach
**Host detection:** Determine whether we're on Gitea or GitHub by checking the releases API. A simple heuristic: if `github.server_url` contains `github.com` or the `/api/v3/` endpoint responds, treat it as GitHub. Otherwise assume Gitea.
Actually, a cleaner approach: use the API format that matches the host. The action can try the Gitea endpoint first, and if it fails (non-JSON response), fall back to GitHub REST API. But that's fragile.
**Simplest reliable approach:**
- Add a new input `action-repo` that specifies where to find review-bot releases. Defaults to `rodin/review-bot` for backward compat.
- Detect host type from `github.server_url`:
- If it contains `github.com` OR returns a GitHub-style API response → GitHub mode
- Otherwise → Gitea mode
- Use appropriate API path based on host type:
- Gitea: `${SERVER_URL}/api/v1/repos/${REPO}/releases?limit=1`
- GitHub: `${SERVER_URL}/api/v3/repos/${REPO}/releases?per_page=1` (GHES uses `/api/v3/`)
- Download URL is the same format on both: `${SERVER_URL}/${REPO}/releases/download/${VERSION}/${BINARY}`
Wait — checking the actual GitHub releases download URL format... On GHES it's: `https://github.concur.com/{owner}/{repo}/releases/download/{tag}/{asset}` which IS the same pattern as Gitea. So the download URL logic is fine as-is. The only real issue is the **releases API path** and the **repo default**.
**Revised approach (minimal change):**
1. Add `action-repo` input that defaults to empty (meaning: use `github.repository` context)
2. For the REPO variable: use `inputs.action-repo || inputs.repo || github.repository` — but wait, `inputs.repo` is the *target* repo being reviewed, not the repo hosting the action. We need to separate these.
Actually re-reading the code more carefully:
- `inputs.repo` in "Run review" = the repo being reviewed (target)
- `REPO` in "Determine version" and "Install review-bot" = the repo hosting review-bot releases (action source)
These are **different repos** and currently both default to `rodin/review-bot` which conflates them.
**Final approach:**
1. Add `action-repo` input (default: empty) — the repo that hosts review-bot releases
2. When `action-repo` is empty, derive it from `github.action_repository` (GitHub Actions provides this as the repo containing the action being run) — but Gitea Actions may not support this. Fallback: hardcode `rodin/review-bot` if empty (maintains backward compat for Gitea).
3. Detect host type using a helper function:
- Check if `${SERVER_URL}/api/v3/` path exists (GitHub/GHES)
- Otherwise use `/api/v1/` (Gitea)
- Or simpler: just try both — use `/api/v1/` if it returns valid JSON, else try `/api/v3/`
4. Apply host-appropriate API path for releases query
**Simplest implementation (avoiding API probing):**
- Use a new input `vcs-type` with values `auto|gitea|github`, defaulting to `auto`
- `auto` detection: if `github.server_url` matches `*github*` → github, else → gitea
- This handles: `github.com`, `github.concur.com`, `github.yourcompany.io` etc.
### Implementation Details
#### New inputs:
```yaml
action-repo:
description: 'Repository hosting review-bot releases (owner/name). Defaults to github.action_repository on GitHub, rodin/review-bot on Gitea'
required: false
default: ''
```
#### "Determine version" step changes:
```bash
SERVER_URL="${{ inputs.gitea-url || github.server_url }}"
# Determine action repo (where review-bot releases live)
ACTION_REPO="${{ inputs.action-repo }}"
if [ -z "$ACTION_REPO" ]; then
# github.action_repository gives us the repo containing this action
ACTION_REPO="${{ github.action_repository || 'rodin/review-bot' }}"
fi
# Detect API format based on server URL
if echo "$SERVER_URL" | grep -qi "github"; then
API_PATH="${SERVER_URL}/api/v3/repos/${ACTION_REPO}/releases?per_page=1"
else
API_PATH="${SERVER_URL}/api/v1/repos/${ACTION_REPO}/releases?limit=1"
fi
if [ "${{ inputs.version }}" = "latest" ]; then
VERSION=$(curl -sSf "$API_PATH" \
| python3 -c "import sys, json; releases = json.load(sys.stdin); print(releases[0]['tag_name'] if releases else '')")
...
fi
```
#### "Install review-bot" step changes:
Same pattern — use `ACTION_REPO` and the server URL directly for download (download URL format is the same on both platforms).
#### "Run review" step:
Already uses `inputs.repo || github.repository` for the target repo. The env var names differ between `.gitea` (GITEA_URL/GITEA_REPO) and `.github` (GITHUB_SERVER_URL/GITHUB_REPOSITORY) — that's fine and intentional.
### Testing Strategy
- Verify action still works on Gitea (backward compat) — existing CI on `gitea.weiker.me`
- Test the `action-repo` input explicitly with a GHES-style URL
- Manual test: set `gitea-url` to `https://github.concur.com` and `action-repo` to `strat/review-bot`
### Edge Cases
- `github.action_repository` might not be available in Gitea Actions → fallback to `rodin/review-bot`
- Server URL with trailing slash → strip it
- GHES might use a custom domain without "github" in the name → `vcs-type` or `action-repo` input covers this
### Open Questions
- `github.action_repository`: Gitea Actions might support this (it emulates GitHub Actions context). Need to verify. If it does, no `action-repo` input needed at all — just use `github.action_repository` with `rodin/review-bot` fallback.
- Should we support authentication for the releases API call? Currently it's unauthenticated. On GHES, releases might be in a private repo. For now, assume public releases (can add `release-token` input later if needed).
### Completion Checklist
1. Both `.gitea` and `.github` action files updated with host detection
2. `action-repo` input added with sensible defaults
3. Releases API uses correct path format per host type
4. Download URL works on both Gitea and GitHub
5. Backward compatible — existing users with no new inputs still work
6. No new dependencies added
7. `inputs.repo` (target repo for review) kept separate from action repo
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
The composite action in
.gitea/actions/review/action.ymlhardcodes Gitea assumptions that break when running on GitHub Enterprise Server:REPOis hardcoded torodin/review-bot— should be the repo hosting the action on the current server/api/v1/repos/...) — GitHub uses/api/v3/repos/...(or REST/repos/...)https://gitea.weiker.me/rodin/review-bot/releases/download/...vs GitHub:https://github.concur.com/strat/review-bot/releases/download/...Observed
When running on
github.concur.comrunners:The version resolution curl hits
https://github.concur.com/api/v1/repos/rodin/review-bot/releases— wrong API format and wrong repo.Fix
The action should:
github.server_urlrodin/review-botaction-repoinput that defaults to the Gitea value for backward compatibilityContext
Discovered while testing GitHub support (feature/github-support) against
strat/db-migratorongithub.concur.com.Plan: Fix version resolution and binary download for GitHub hosts
Problem
The composite action in both
.gitea/actions/review/action.ymland.github/actions/review/action.ymlhas three Gitea-specific assumptions that break on GitHub/GHES:REPOdefaults torodin/review-bot— on GHES the action lives in a different repo (e.g.strat/review-bot)/api/v1/repos/{owner}/{repo}/releasesbut GitHub uses/repos/{owner}/{repo}/releases(REST v3){server}/{repo}/releases/download/{tag}/{asset}, GitHub:{server}/{repo}/releases/download/{tag}/{asset}(same pattern but the API endpoint differs)Constraints
repoinput should work unchanged.giteaand.githubaction files must be updatedinputs.gitea-urlname stays for backward compat (renaming would break callers)Proposed Approach
Host detection: Determine whether we're on Gitea or GitHub by checking the releases API. A simple heuristic: if
github.server_urlcontainsgithub.comor the/api/v3/endpoint responds, treat it as GitHub. Otherwise assume Gitea.Actually, a cleaner approach: use the API format that matches the host. The action can try the Gitea endpoint first, and if it fails (non-JSON response), fall back to GitHub REST API. But that's fragile.
Simplest reliable approach:
action-repothat specifies where to find review-bot releases. Defaults torodin/review-botfor backward compat.github.server_url:github.comOR returns a GitHub-style API response → GitHub mode${SERVER_URL}/api/v1/repos/${REPO}/releases?limit=1${SERVER_URL}/api/v3/repos/${REPO}/releases?per_page=1(GHES uses/api/v3/)${SERVER_URL}/${REPO}/releases/download/${VERSION}/${BINARY}Wait — checking the actual GitHub releases download URL format... On GHES it's:
https://github.concur.com/{owner}/{repo}/releases/download/{tag}/{asset}which IS the same pattern as Gitea. So the download URL logic is fine as-is. The only real issue is the releases API path and the repo default.Revised approach (minimal change):
action-repoinput that defaults to empty (meaning: usegithub.repositorycontext)inputs.action-repo || inputs.repo || github.repository— but wait,inputs.repois the target repo being reviewed, not the repo hosting the action. We need to separate these.Actually re-reading the code more carefully:
inputs.repoin "Run review" = the repo being reviewed (target)REPOin "Determine version" and "Install review-bot" = the repo hosting review-bot releases (action source)These are different repos and currently both default to
rodin/review-botwhich conflates them.Final approach:
action-repoinput (default: empty) — the repo that hosts review-bot releasesaction-repois empty, derive it fromgithub.action_repository(GitHub Actions provides this as the repo containing the action being run) — but Gitea Actions may not support this. Fallback: hardcoderodin/review-botif empty (maintains backward compat for Gitea).${SERVER_URL}/api/v3/path exists (GitHub/GHES)/api/v1/(Gitea)/api/v1/if it returns valid JSON, else try/api/v3/Simplest implementation (avoiding API probing):
vcs-typewith valuesauto|gitea|github, defaulting toautoautodetection: ifgithub.server_urlmatches*github*→ github, else → giteagithub.com,github.concur.com,github.yourcompany.ioetc.Implementation Details
New inputs:
"Determine version" step changes:
"Install review-bot" step changes:
Same pattern — use
ACTION_REPOand the server URL directly for download (download URL format is the same on both platforms)."Run review" step:
Already uses
inputs.repo || github.repositoryfor the target repo. The env var names differ between.gitea(GITEA_URL/GITEA_REPO) and.github(GITHUB_SERVER_URL/GITHUB_REPOSITORY) — that's fine and intentional.Testing Strategy
gitea.weiker.meaction-repoinput explicitly with a GHES-style URLgitea-urltohttps://github.concur.comandaction-repotostrat/review-botEdge Cases
github.action_repositorymight not be available in Gitea Actions → fallback torodin/review-botvcs-typeoraction-repoinput covers thisOpen Questions
github.action_repository: Gitea Actions might support this (it emulates GitHub Actions context). Need to verify. If it does, noaction-repoinput needed at all — just usegithub.action_repositorywithrodin/review-botfallback.release-tokeninput later if needed).Completion Checklist
.giteaand.githubaction files updated with host detectionaction-repoinput added with sensible defaultsinputs.repo(target repo for review) kept separate from action repo