diff --git a/.github/scripts/report-scheduled-failure.sh b/.github/scripts/report-scheduled-failure.sh new file mode 100755 index 0000000..8be1fc4 --- /dev/null +++ b/.github/scripts/report-scheduled-failure.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +LABEL="scheduled-failure" +TITLE="Scheduled dependency check failed" + +# Ensure the label exists. --force makes this idempotent: creates if absent, +# updates color/description without error if present. +gh label create "$LABEL" \ + --color "FBCA04" \ + --description "Weekly dependency check failures" \ + --force + +# Find an open issue with our label, if any. --jq '.[0].number // empty' +# yields the first number or an empty string when there are no matches. +existing=$(gh issue list --label "$LABEL" --state open --json number --jq '.[0].number // empty') + +if [ -z "$existing" ]; then + body=$(printf '%s\n\n%s\n\n%s\n\n%s' \ + "The weekly scheduled dependency check failed." \ + "First failing run: ${RUN_URL}" \ + "Likely cause: a transitive dev or lint dependency (ruff, mypy, pyrefly, pytest, faststream, typing-extensions) released a breaking change. Reproduce locally with \`just install\` then \`just lint\` and \`just test\`." \ + "Close this issue once fixed. The next scheduled failure will open a fresh issue.") + gh issue create --title "$TITLE" --label "$LABEL" --body "$body" +else + gh issue comment "$existing" --body "Failed again: ${RUN_URL}" +fi diff --git a/.github/workflows/_checks.yml b/.github/workflows/_checks.yml new file mode 100644 index 0000000..985e3f8 --- /dev/null +++ b/.github/workflows/_checks.yml @@ -0,0 +1,46 @@ +name: checks +on: + workflow_call: {} + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: extractions/setup-just@v4 + - uses: astral-sh/setup-uv@v7 + with: + cache-dependency-glob: "**/pyproject.toml" + - run: uv python install 3.10 + - run: just install lint-ci + + pytest: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: + - "3.10" + - "3.11" + - "3.12" + - "3.13" + - "3.14" + faststream-version: + - "<0.6.0" + - ">=0.6.0" + steps: + - uses: actions/checkout@v6 + - uses: extractions/setup-just@v4 + - uses: astral-sh/setup-uv@v7 + with: + cache-dependency-glob: "**/pyproject.toml" + - run: uv python install ${{ matrix.python-version }} + - run: just install + - run: uv run --with "faststream${{ matrix.faststream-version }}" pytest . --cov=. --cov-report xml + - uses: codecov/codecov-action@v5.4.3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + files: ./coverage.xml + flags: unittests + name: codecov-${{ matrix.python-version }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9cd2868..f3f9df1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,44 +11,6 @@ concurrency: cancel-in-progress: true jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: extractions/setup-just@v4 - - uses: astral-sh/setup-uv@v7 - with: - cache-dependency-glob: "**/pyproject.toml" - - run: uv python install 3.10 - - run: just install lint-ci - - pytest: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: - - "3.10" - - "3.11" - - "3.12" - - "3.13" - - "3.14" - faststream-version: - - "<0.6.0" - - ">=0.6.0" - steps: - - uses: actions/checkout@v6 - - uses: extractions/setup-just@v4 - - uses: astral-sh/setup-uv@v7 - with: - cache-dependency-glob: "**/pyproject.toml" - - run: uv python install ${{ matrix.python-version }} - - run: just install - - run: uv run --with "faststream${{ matrix.faststream-version }}" pytest . --cov=. --cov-report xml - - uses: codecov/codecov-action@v5.4.3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: - files: ./coverage.xml - flags: unittests - name: codecov-${{ matrix.python-version }} + checks: + uses: ./.github/workflows/_checks.yml + secrets: inherit diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml new file mode 100644 index 0000000..068d5d0 --- /dev/null +++ b/.github/workflows/scheduled.yml @@ -0,0 +1,29 @@ +name: scheduled-dep-check +on: + schedule: + - cron: "0 6 * * 1" # Mondays 06:00 UTC + workflow_dispatch: {} + +concurrency: + group: scheduled-dep-check + cancel-in-progress: false + +jobs: + checks: + uses: ./.github/workflows/_checks.yml + secrets: inherit + + report-failure: + needs: checks + if: failure() && github.event_name == 'schedule' + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + steps: + - uses: actions/checkout@v6 + - name: Open or update tracking issue + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: bash .github/scripts/report-scheduled-failure.sh