From e67c2fcfde02a9adb053666e326be54c24ee6277 Mon Sep 17 00:00:00 2001 From: Cat Tom Date: Mon, 9 Nov 2026 20:04:08 +0800 Subject: [PATCH] feat: action retry mechanism --- .gitea/workflows/deploy.yaml | 3 +- .gitea/workflows/retry-deploy.yaml | 60 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/retry-deploy.yaml diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 35b9e28..7d570ab 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -1,4 +1,5 @@ name: Deploy +# retry-deploy.yaml reruns all jobs after failure, up to 3 times. on: [push] jobs: @@ -13,4 +14,4 @@ jobs: key: ${{ secrets.SSH_PRIVATE_KEY }} passphrase: ${{ secrets.SSH_PRIVATE_KEY_PASSPHRASE }} command_timeout: 3h - script: bash /root/maria/script/action/blog.sh \ No newline at end of file + script: bash /root/maria/script/action/blog.sh diff --git a/.gitea/workflows/retry-deploy.yaml b/.gitea/workflows/retry-deploy.yaml new file mode 100644 index 0000000..0ef0f82 --- /dev/null +++ b/.gitea/workflows/retry-deploy.yaml @@ -0,0 +1,60 @@ +name: Retry Deploy + +on: + workflow_run: + workflows: [Deploy] + types: [completed] + +permissions: + actions: write + +jobs: + retry: + if: >- + ${{ + (gitea.event.workflow_run.conclusion == 'failure' || + gitea.event.workflow_run.conclusion == 'timed_out') + && gitea.event.workflow_run.run_attempt >= 1 + && gitea.event.workflow_run.run_attempt <= 3 + }} + runs-on: ubuntu-latest + steps: + - name: Retry the entire Deploy workflow + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + GITEA_SERVER_URL: ${{ gitea.server_url }} + GITEA_REPOSITORY: ${{ gitea.repository }} + RUN_ID: ${{ gitea.event.workflow_run.id }} + RUN_ATTEMPT: ${{ gitea.event.workflow_run.run_attempt }} + run: | + python3 - <<'PY' + import json + import os + from urllib.request import Request, urlopen + + max_retries = 3 + event_attempt = int(os.environ['RUN_ATTEMPT']) + server = os.environ['GITEA_SERVER_URL'].rstrip('/') + repository = os.environ['GITEA_REPOSITORY'] + run_id = os.environ['RUN_ID'] + run_url = f'{server}/api/v1/repos/{repository}/actions/runs/{run_id}' + headers = { + 'Authorization': f'token {os.environ["GITEA_TOKEN"]}', + 'Accept': 'application/json', + } + + with urlopen(Request(run_url, headers=headers), timeout=30) as response: + current_run = json.load(response) + + # Ignore stale completion events if a newer attempt has already started. + if (current_run['run_attempt'] != event_attempt + or current_run['status'] not in ('completed', 'failure', 'timed_out') + or current_run['conclusion'] not in ('failure', 'timed_out') + or not 1 <= event_attempt <= max_retries): + print('No retry needed for this completion event.') + else: + request = Request(f'{run_url}/rerun', headers=headers, method='POST') + with urlopen(request, timeout=30) as response: + response.read() + print(f'Retrying all jobs: retry {event_attempt}/{max_retries}.') + PY