Files
docs/.gitea/workflows/update_swagger.yaml
T
Lunny Xiao bc795ac24a Fix the swagger update cron job (#481)
The scheduled `update swagger files` job has failed on **every** run since it was added (I checked the run list on gitea.com, ~250 consecutive failures). Two reasons:

1. Upstream moved the file: `go-gitea/gitea` main no longer has `templates/swagger/v1_json.tmpl`, it is now `templates/swagger/v1-swagger.generated.json`, and the placeholders changed from `{{.SwaggerAppVer}}` / `{{.SwaggerAppSubUrl}}` to `0.0.0+GITEA-API-APP-VERSION` / `/GITEA-API-APP-SUBURL/api/v1`. Because the script used `curl --silent` without `--fail`, the 404 body was written into `static/swagger-latest.json`.
2. `main` is protected (`required_approvals=1`), so the job's `git push` to main could never succeed.

Changes:

- `update_api_docs.sh`: `set -euo pipefail`, download with `--fail` (a broken download now aborts instead of committing garbage), try the new generated json first and fall back to the old template for released tags, handle the 1.28+/1.24+/<1.24 placeholder variants, and add a `--latest-only` flag.
- `Makefile`: new `update-api-docs-latest` target for the cron job; `clean` no longer deletes the committed `static/swagger-*.json` files (deleting them breaks `make build`).
- `.gitea/workflows/update_swagger.yaml`: every 12h (plus `workflow_dispatch`) it regenerates only `static/swagger-latest.json`, verifies no placeholder is left and the file is valid JSON, force pushes to `bot/update-swagger-latest` and opens a pull request via the API (HTTP 409 = a PR is already open, it just now points at the new commit). It skips entirely when the bot branch already carries the same file, so no PR churn.
- `README.md`: document the two make targets and the automation.

`secrets.DEPLOY_TOKEN` must belong to a real user with `write:repository` so the PR checks are triggered; the job fails with a clear message if it is empty.

Tested locally in a scratch clone: `make update-api-docs-latest` produces a valid `dev` spec with no placeholders left, `make update-api-docs` still regenerates all released versions, and the workflow shell logic was simulated against a local bare repo for all three paths (open PR / bot branch already up to date / main already up to date), including a shallow clone to confirm `fetch-depth: 1` force pushes work.

Fixes #454

Reviewed-on: https://gitea.com/gitea/docs/pulls/481
Reviewed-by: techknowlogick <[email protected]>
2026-08-02 23:25:17 +00:00

100 lines
3.9 KiB
YAML

name: update swagger files
on:
schedule:
- cron: '0 */12 * * *' # every 12 hours on the hour
workflow_dispatch:
env:
# main is protected, so the update is proposed as a pull request from this branch
BOT_BRANCH: bot/update-swagger-latest
BASE_BRANCH: main
jobs:
update-swagger:
if: github.repository == 'gitea/docs'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: main
# pushing uses DEPLOY_TOKEN, keep the ephemeral job token out of .git/config
persist-credentials: false
- name: regenerate swagger-latest.json
run: make update-api-docs-latest
- name: verify the generated file
run: |
set -euo pipefail
# placeholders must have been replaced, otherwise upstream changed them again
if grep -q -e 'GITEA-API-APP' -e '{{' static/swagger-latest.json; then
echo "static/swagger-latest.json still contains template placeholders"
exit 1
fi
if command -v python3 >/dev/null 2>&1; then
python3 -c "import json; json.load(open('static/swagger-latest.json'))"
fi
- name: push bot branch
id: bot_branch
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
run: |
set -euo pipefail
if git diff --quiet -- static/swagger-latest.json; then
echo "swagger-latest.json is already up to date"
echo "changed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if [ -z "$DEPLOY_TOKEN" ]; then
echo "secrets.DEPLOY_TOKEN is missing, cannot push the update"
exit 1
fi
remote="https://x-access-token:$DEPLOY_TOKEN@${GITHUB_SERVER_URL#*://}/$GITHUB_REPOSITORY.git"
# skip if an open bot branch already carries exactly this file
if git fetch --quiet --depth=1 "$remote" "refs/heads/$BOT_BRANCH" 2>/dev/null; then
old_blob="$(git rev-parse --quiet --verify "FETCH_HEAD:static/swagger-latest.json" || true)"
if [ "$old_blob" = "$(git hash-object static/swagger-latest.json)" ]; then
echo "$BOT_BRANCH already proposes this swagger-latest.json"
echo "changed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
fi
git config user.name "Gitea Bot"
git config user.email "[email protected]"
git switch --create "$BOT_BRANCH"
git add static/swagger-latest.json
git commit -m "Update swagger-latest.json"
# force push: the branch is always rebuilt on top of the current main
git push --force "$remote" "HEAD:refs/heads/$BOT_BRANCH"
echo "changed=true" >> "$GITHUB_OUTPUT"
- name: create pull request
if: steps.bot_branch.outputs.changed == 'true'
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
run: |
set -euo pipefail
cat > pull.json <<EOF
{
"base": "$BASE_BRANCH",
"head": "$BOT_BRANCH",
"title": "Update swagger-latest.json",
"body": "Automated update of static/swagger-latest.json from the gitea main branch, opened by the \"update swagger files\" scheduled workflow."
}
EOF
code="$(curl --silent --show-error --output pull-response.json --write-out '%{http_code}' \
-X POST "${GITHUB_API_URL:-$GITHUB_SERVER_URL/api/v1}/repos/$GITHUB_REPOSITORY/pulls" \
-H "Authorization: token $DEPLOY_TOKEN" \
-H 'Content-Type: application/json' \
--data @pull.json)"
case "$code" in
201) echo "pull request created" ;;
409) echo "an open pull request for $BOT_BRANCH already exists, it now points at the new commit" ;;
*) echo "unexpected response $code:"; cat pull-response.json; exit 1 ;;
esac