diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 490bd8e..2f8ee31 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -175,18 +175,17 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v4 - - name: Install dependencies - run: | - . .env 2>/dev/null || true - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" + - name: Set up environment + env: + REPO_TOKEN: ${{ secrets.REPO_TOKEN }} + run: make setup-ci - name: Run automated PR review env: REPO_TOKEN: ${{ secrets.REPO_TOKEN }} PYTHONPATH: src run: | set -euo pipefail + . .venv/bin/activate python3 -m devx.ci.pr_review \ "${{ github.event.number }}" \ "${{ github.repository }}" @@ -210,12 +209,10 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.REPO_TOKEN }} - - name: Install dependencies - run: | - . .env 2>/dev/null || true - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" + - name: Set up environment + env: + REPO_TOKEN: ${{ secrets.REPO_TOKEN }} + run: make setup-ci - name: Squash merge with task ID env: REPO_TOKEN: ${{ secrets.REPO_TOKEN }} @@ -228,6 +225,7 @@ jobs: REPOSITORY: ${{ github.repository }} PR_NUMBER: ${{ github.event.number }} run: | + . .venv/bin/activate python3 -m devx.ci.auto_merge \ "$HEAD_REF" \ "$PR_TITLE" \ diff --git a/.gitea/workflows/post-merge.yml b/.gitea/workflows/post-merge.yml index 73f7ce0..3f5e4ea 100644 --- a/.gitea/workflows/post-merge.yml +++ b/.gitea/workflows/post-merge.yml @@ -6,21 +6,20 @@ name: Post-merge # # Job dependency graph: # -# detect-type ──┬── release (skip if release commit) +# detect-type ──┬── validate-commit-msg (skip if release commit) +# ├── release (skip if release commit) # ├── badges (ALWAYS runs — even on release commits) # ├── configure-repo (independent — skip if release commit) -# ├── sync-wiki (needs release — skip if release commit/fails) -# └── vikunja (needs release — skip if release commit/fails) +# ├── sync-wiki (skip if release commit — runs for ALL merges) +# └── vikunja (skip if release commit — runs for ALL merges) # -# sync-wiki and vikunja depend on release succeeding so that the wiki -# and task tracker are only updated when the code is actually released. -# If release fails, they are skipped to avoid leaving the wiki or -# Vikunja in an inconsistent state with the codebase on master. +# sync-wiki and vikunja run for ALL non-release commits, not just when +# release succeeds. This ensures the wiki and task tracker are updated +# even for infrastructure-only changes (docs, CI config, etc.). # -# The badges job depends on release so it picks up the latest version -# number. It uses `if: always()` with no is-release condition so it -# runs on every push to master, including release commits. This -# ensures badges (tests, coverage, version, etc.) are always current. +# The badges job uses `if: always()` with no is-release condition so it +# runs on every push to master, including release commits. This ensures +# badges (tests, coverage, version, etc.) are always current. # # When release.py creates a "release: vX.Y.Z" commit, the release # commit's post-merge run still updates badges (version badge picks @@ -40,15 +39,17 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Install dependencies - run: | - . .env 2>/dev/null || true - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" + - name: Set up environment + env: + REPO_TOKEN: ${{ secrets.REPO_TOKEN }} + run: make setup-ci - name: Check if this is a release commit id: check env: PYTHONPATH: src - run: python3 -m devx.ci.detect_release_commit + run: | + . .venv/bin/activate + python3 -m devx.ci.detect_release_commit validate-commit-msg: needs: [detect-type] @@ -59,15 +60,16 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Install dependencies - run: | - . .env 2>/dev/null || true - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" + - name: Set up environment + env: + REPO_TOKEN: ${{ secrets.REPO_TOKEN }} + run: make setup-ci - name: Validate latest commit message env: PYTHONPATH: src DEVX_TASK_PREFIX: GRM run: | + . .venv/bin/activate git log -1 --format=%B > commit-msg.txt python3 -m devx.ci.validate_commit_msg commit-msg.txt --branch master rm -f commit-msg.txt @@ -100,20 +102,6 @@ jobs: . .venv/bin/activate export PATH="$HOME/.local/bin:$PATH" python3 -m devx.ci.release - - name: Publish release - env: - REPO_TOKEN: ${{ secrets.REPO_TOKEN }} - PYTHONPATH: src - run: | - . .venv/bin/activate - export PATH="$HOME/.local/bin:$PATH" - TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") - if [ -z "$TAG" ]; then - echo "No tag found — skipping publish" - exit 0 - fi - echo "Publishing release $TAG (idempotent — skips if already published)..." - python3 -m devx.ci.publish "$TAG" "${{ github.repository }}" - name: Notify on failure if: failure() env: @@ -122,7 +110,6 @@ jobs: run: | . .venv/bin/activate 2>/dev/null || true export PATH="$HOME/.local/bin:$PATH" - python3 -m devx.tools.install_tools --tool tea python3 -m devx.ci.notify_failure --auto-login \ --repo "${{ github.repository }}" \ --run-id "${{ github.run_id }}" \ @@ -130,7 +117,7 @@ jobs: --commit "${{ github.sha }}" sync-wiki: - needs: [detect-type, release] + needs: [detect-type] if: needs.detect-type.outputs.is-release == 'false' runs-on: docker timeout-minutes: 10 @@ -156,7 +143,6 @@ jobs: PYTHONPATH: src run: | export PATH="$HOME/.local/bin:$PATH" - python3 -m devx.tools.install_tools --tool tea python3 -m devx.ci.notify_failure --auto-login \ --repo "${{ github.repository }}" \ --run-id "${{ github.run_id }}" \ @@ -164,7 +150,7 @@ jobs: --commit "${{ github.sha }}" badges: - needs: [detect-type, release] + needs: [detect-type] if: always() runs-on: docker timeout-minutes: 10 @@ -195,7 +181,6 @@ jobs: PYTHONPATH: src run: | export PATH="$HOME/.local/bin:$PATH" - python3 -m devx.tools.install_tools --tool tea python3 -m devx.ci.notify_failure --auto-login \ --repo "${{ github.repository }}" \ --run-id "${{ github.run_id }}" \ @@ -203,7 +188,7 @@ jobs: --commit "${{ github.sha }}" vikunja: - needs: [detect-type, release] + needs: [detect-type] if: needs.detect-type.outputs.is-release == 'false' runs-on: docker timeout-minutes: 10 @@ -211,17 +196,19 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Install dependencies - run: | - . .env 2>/dev/null || true - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" + - name: Set up environment + env: + REPO_TOKEN: ${{ secrets.REPO_TOKEN }} + run: make setup-ci - name: Update Vikunja task env: VIKUNJA_TOKEN: ${{ secrets.VIKUNJA_TOKEN }} PYTHONPATH: src DEVX_TASK_PREFIX: GRM DEVX_VIKUNJA_PROJECT_ID: 6 - run: python3 -m devx.ci.post_merge --git-sha "${{ github.sha }}" + run: | + . .venv/bin/activate + python3 -m devx.ci.post_merge --git-sha "${{ github.sha }}" - name: Notify on failure if: failure() env: @@ -229,7 +216,6 @@ jobs: PYTHONPATH: src run: | export PATH="$HOME/.local/bin:$PATH" - python3 -m devx.tools.install_tools --tool tea python3 -m devx.ci.notify_failure --auto-login \ --repo "${{ github.repository }}" \ --run-id "${{ github.run_id }}" \ @@ -243,10 +229,10 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v4 - - name: Install dependencies - run: | - . .env 2>/dev/null || true - python3 -m pip install --break-system-packages --target=src "devx==0.14.1" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" + - name: Set up environment + env: + REPO_TOKEN: ${{ secrets.REPO_TOKEN }} + run: make setup-ci - name: Ensure branch protection and labels env: REPO_TOKEN: ${{ secrets.REPO_TOKEN }} @@ -254,7 +240,9 @@ jobs: DEVX_REPO_NAME: grm DEVX_REPO_OWNER: oblachno-oss DEVX_STATUS_CHECKS: "CI / quality (pull_request),CI / molecule-tests (1) (pull_request),CI / molecule-tests (2) (pull_request),CI / molecule-tests (3) (pull_request)" - run: python3 -m devx.tools.configure_repo + run: | + . .venv/bin/activate + python3 -m devx.tools.configure_repo - name: Notify on failure if: failure() env: @@ -262,7 +250,6 @@ jobs: PYTHONPATH: src run: | export PATH="$HOME/.local/bin:$PATH" - python3 -m devx.tools.install_tools --tool tea python3 -m devx.ci.notify_failure --auto-login \ --repo "${{ github.repository }}" \ --run-id "${{ github.run_id }}" \ diff --git a/.gitea/workflows/publish.yml b/.gitea/workflows/publish.yml index bd9e382..8eb075c 100644 --- a/.gitea/workflows/publish.yml +++ b/.gitea/workflows/publish.yml @@ -19,27 +19,16 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Install CI tools - env: - PYTHONPATH: src - run: | - . .env 2>/dev/null || true - python3 -m pip install --break-system-packages --target=src "devx==0.12.0" --extra-index-url "https://emil:${{ secrets.REPO_TOKEN }}@git.oblachno.oblachno.fyi/api/packages/oblachno-oss/pypi/simple/" - python3 -m devx.tools.install_tools --tool git-cliff --tool tea - - name: Install build tools - run: python3 -m pip install --break-system-packages build twine - - name: Configure tea login + - name: Set up environment env: REPO_TOKEN: ${{ secrets.REPO_TOKEN }} - run: | - export PATH="$HOME/.local/bin:$PATH" - tea login add --name grm --url "${{ github.server_url }}" --token "$REPO_TOKEN" || true - tea login default grm || true + run: make setup-release - name: Build and publish release env: REPO_TOKEN: ${{ secrets.REPO_TOKEN }} PYTHONPATH: src run: | + . .venv/bin/activate export PATH="$HOME/.local/bin:$PATH" python3 -m devx.ci.publish \ "${{ github.event.inputs.tag || github.ref_name }}" \ @@ -50,6 +39,7 @@ jobs: REPO_TOKEN: ${{ secrets.REPO_TOKEN }} PYTHONPATH: src run: | + . .venv/bin/activate 2>/dev/null || true export PATH="$HOME/.local/bin:$PATH" python3 -m devx.ci.notify_failure --auto-login \ --repo "${{ github.repository }}" \ diff --git a/AGENTS.md b/AGENTS.md index f8d1fc4..ca71a05 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -221,14 +221,18 @@ Vikunja task updates: - `--skip-tests` flag bypasses test verification (emergency use only, not recommended) - Loops are prevented by `has_unreleased_changes` — after a release commit is tagged, the next run finds no unreleased changes and exits -3. **sync-wiki** — Syncs documentation to the Gitea wiki. +3. **sync-wiki** — Syncs documentation to the Gitea wiki. Runs for ALL + non-release commits (not just when release succeeds), so docs-only + changes still update the wiki. 4. **badges** — Generates and pushes quality badge SVGs to the `badges` branch. - Runs **after** the release job (even if release fails or is skipped) so the - version badge always reflects the latest state. The script fetches the - latest master before generating badges to pick up any release commits. + Uses `if: always()` so it runs on every push, including release commits. + The script fetches the latest master before generating badges to pick up + any release commits. -5. **vikunja** — Marks the corresponding Vikunja task as done. +5. **vikunja** — Marks the corresponding Vikunja task as done. Runs for ALL + non-release commits (not just when release succeeds), so infrastructure-only + changes still update the task tracker. The tag push triggers the **publish workflow** (`.gitea/workflows/publish.yml`) which builds and publishes the package to PyPI.