Compare commits

..
Author SHA1 Message Date
emilandDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> 0b47975955 fix: increase download retry attempts and backoff for transient GitHub outages
The CI image build (run 3597) failed because install_tools._download
exhausted its 3 retry attempts on RemoteDisconnected errors from
GitHub releases. The max backoff of 10s was too short for sustained
transient outages.

- Increase MAX_DOWNLOAD_RETRIES from 3 to 5
- Increase max backoff from 10s to 30s

DEVX-158

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-12 23:35:10 +02:00
gitea-actions-bot 544de0bf27 chore: update badge URLs to commit 1f29b164 [skip ci] 2026-08-12 19:33:58 +00:00
emil User f5d3b72a38 DEVX-157: docs: add ADR-0003 and update docs for composite actions 2026-08-12 19:32:28 +00:00
9 changed files with 49 additions and 38 deletions
+16 -3
View File
@@ -51,9 +51,13 @@ jobs:
with:
fetch-depth: 1
- name: Set up environment
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
run: make setup-release
- name: Check if this is a release commit
id: check
env:
PYTHONPATH: src
run: |
. .venv/bin/activate
python3 -m devx.ci.detect_release_commit
@@ -61,6 +65,9 @@ jobs:
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' && steps.check.outputs.is-release == 'false')
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
CI_GITEA_USERNAME: ${{ vars.CI_GITEA_USERNAME }}
run: |
. .venv/bin/activate
_TOKEN="$CI_GITEA_API_TOKEN"
@@ -72,6 +79,10 @@ jobs:
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' && steps.check.outputs.is-release == 'false')
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
CI_GITEA_USERNAME: ${{ vars.CI_GITEA_USERNAME }}
PYTHONPATH: src
run: |
. .venv/bin/activate
export PATH="$HOME/.local/bin:$PATH"
@@ -115,8 +126,13 @@ jobs:
with:
fetch-depth: 1
- name: Set up environment
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
run: make setup-ci
- name: Clean up old image versions
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
PYTHONPATH: src
run: |
. .venv/bin/activate
python3 -m devx.tools.clean_images \
@@ -125,6 +141,3 @@ jobs:
--name oblachno-oss/runner-images/ci-quality \
--name oblachno-oss/runner-images/ci-full \
--keep 2
- uses: ./.gitea/actions/notify-failure
with:
workflow: "build-images/cleanup"
+2 -3
View File
@@ -121,6 +121,7 @@ jobs:
- name: Post approval review
env:
REVIEWER_GITEA_API_TOKEN: ${{ secrets.REVIEWER_GITEA_API_TOKEN }}
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
REPOSITORY: ${{ github.repository }}
run: |
@@ -134,6 +135,7 @@ jobs:
--body "Auto-approved: all CI checks passed (validate job)."
- name: Squash merge with task ID
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
VIKUNJA_TOKEN: ${{ secrets.VIKUNJA_TOKEN }}
DEVX_VIKUNJA_PROJECT_ID: "8"
HEAD_REF: ${{ github.head_ref }}
@@ -147,6 +149,3 @@ jobs:
"$PR_TITLE" \
"$REPOSITORY" \
"$PR_NUMBER"
- uses: ./.gitea/actions/notify-failure
with:
workflow: "ci/auto-merge"
+9
View File
@@ -111,6 +111,8 @@ jobs:
with:
extras: "release"
- name: Configure git
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
run: |
git config user.name "devx-ci-bot"
git config user.email "devx-ci-bot@oblachno.fyi"
@@ -119,12 +121,16 @@ jobs:
- name: Run release
id: release-tag
if: needs.detect-and-configure.outputs.is-release == 'false' && needs.detect-and-configure.outputs.user-facing-changed == 'true'
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
run: |
. .venv/bin/activate 2>/dev/null || true
export PATH="$HOME/.local/bin:$PATH"
python3 -m devx.ci.release
- name: Build and publish release
if: steps.release-tag.outputs.tag != ''
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
run: |
. .venv/bin/activate 2>/dev/null || true
export PATH="$HOME/.local/bin:$PATH"
@@ -134,6 +140,8 @@ jobs:
# --- sync-wiki + vikunja (skip on automated/release commits) ---
- name: Sync documentation to wiki
if: needs.detect-and-configure.outputs.is-automated == 'false'
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
run: |
. .venv/bin/activate 2>/dev/null || true
python3 -m devx.ci.sync_wiki --repo "${{ github.repository }}" --verify
@@ -148,6 +156,7 @@ jobs:
# --- badges (always run — even on release commits) ---
- name: Generate and push badges
env:
CI_GITEA_API_TOKEN: ${{ secrets.CI_GITEA_API_TOKEN }}
PRE_COMMIT_ALLOW_NO_CONFIG: "1"
run: |
. .venv/bin/activate 2>/dev/null || true
-6
View File
@@ -8,12 +8,6 @@ All notable changes to this project will be documented in this file.
- Add composite actions (setup-env, notify-failure, quality-checks) in `.gitea/actions/`
- Convert ci.yml, post-merge.yml, build-images.yml to use composite actions
- Add notify-failure to ci/auto-merge and build-images/cleanup jobs (previously missing)
- Fix `make workflow-dryrun` failure: use `env` context instead of
`vars`/`secrets` in `container.credentials` (act_runner dry-run
does not populate vars/secrets)
- Remove redundant step-level `CI_GITEA_API_TOKEN`/`CI_GITEA_USERNAME`
env vars (now in workflow-level `env:` block)
## [0.50.4] - 2026-08-12
+6 -6
View File
@@ -16,12 +16,12 @@ quality badges.
[![CI](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions/workflows/ci.yml/badge.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-blue)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/src/branch/master/LICENSE)
[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki)
[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases)
[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/python.svg)](https://www.python.org/downloads/)
[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki)
[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases)
[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/python.svg)](https://www.python.org/downloads/)
## Why devx?
+6 -6
View File
@@ -77,17 +77,17 @@ fresh `make setup-image` runs.
- **`ci.yml` validate job**: `setup-env` + `quality-checks` +
`notify-failure`.
- **`ci.yml` auto-merge job**: `setup-env` + `notify-failure` (no
quality checks — auto-merge only runs after validate passes).
- **`ci.yml` auto-merge job**: `setup-env` only (no quality checks,
no notify-failure — auto-merge failure is surfaced by the validate
job's notify-failure).
- **`post-merge.yml` detect-and-configure**: `setup-env` +
`notify-failure`.
- **`post-merge.yml` release-and-maintain**: `setup-env` (with
`extras: "release"`) + `notify-failure`.
- **`build-images.yml` build-and-push**: `notify-failure` only. The
setup steps use `make setup-release` (not `make setup-image`), so
`setup-env` does not apply.
- **`build-images.yml` cleanup**: `notify-failure` only. The setup
step uses `make setup-ci` (not `make setup-image`).
setup steps use `make setup-release` and `make setup-ci` (not
`make setup-image`), so `setup-env` does not apply. The cleanup job
has no notify-failure step (it only runs on build-and-push success).
### Same-Repo Copies (No Cross-Repo References)
+6 -6
View File
@@ -12,12 +12,12 @@ project to be reusable across all oblachno-oss repositories.
[![CI](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions/workflows/ci.yml/badge.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-blue)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/src/branch/master/LICENSE)
[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki)
[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases)
[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/43d0589aeee6d706356f79deef37662c9291b981/python.svg)](https://www.python.org/downloads/)
[![Coverage](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/coverage.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Tests](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/tests.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Docs](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/docs.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/wiki)
[![Code Quality](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/quality.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/actions)
[![Version](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/version.svg)](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/releases)
[![Python](https://git.oblachno.oblachno.fyi/oblachno-oss/devx/raw/commit/1f29b164dcb18ac44ca22922a1cc2f1f8ce49d3f/python.svg)](https://www.python.org/downloads/)
## Overview
-5
View File
@@ -591,8 +591,3 @@ which runs `if: failure()`. This creates a Gitea issue with the workflow
name, run ID, and commit SHA, ensuring failures that would otherwise go
unnoticed in the Actions tab are surfaced as issues. The issue is created
via the tea CLI with a `bug` label if available.
Jobs with `notify-failure`:
- `ci/validate`, `ci/auto-merge`
- `post-merge/detect-and-configure`, `post-merge/release-and-maintain`
- `build-images/build-and-push`, `build-images/cleanup`
+4 -3
View File
@@ -50,8 +50,9 @@ logger = logging.getLogger(__name__)
# GitHub releases occasionally drops connections ("Remote end closed
# connection without response"). Retrying with backoff before falling
# through to the next fallback URL makes the build resilient to
# momentary network blips.
MAX_DOWNLOAD_RETRIES = 3
# momentary network blips. 5 attempts with up to 30s between retries
# handles sustained transient outages (observed in CI image builds).
MAX_DOWNLOAD_RETRIES = 5
ACTIONLINT_VERSION = "1.7.12"
@@ -96,7 +97,7 @@ def _download(url: str, dest: Path, *, _sleep=None) -> None:
"""
retrying = Retrying(
stop=stop_after_attempt(MAX_DOWNLOAD_RETRIES),
wait=wait_exponential(multiplier=2, min=2, max=10),
wait=wait_exponential(multiplier=2, min=2, max=30),
retry=retry_if_exception_type((urllib.error.URLError, OSError, ConnectionError)),
before_sleep=before_sleep_log(logger, logging.WARNING),
sleep=_sleep if _sleep is not None else time.sleep,