diff --git a/.codecov.yml b/.codecov.yml index e3e81ac574d..fb11a3f13f9 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -10,9 +10,6 @@ comment: coverage: range: "95..100" - status: - project: no - component_management: individual_components: - component_id: project diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index ee07408e980..74abc7afaf9 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -53,6 +53,7 @@ jobs: lint: permissions: contents: read # to fetch code (actions/checkout) + pull-requests: read # to read PR metadata (verify change fragments step) name: Linter runs-on: ubuntu-latest @@ -97,6 +98,30 @@ jobs: # can be scanned by slotscheck. pip install -r requirements/base.in -c requirements/base.txt slotscheck -v -m aiohttp + - name: Verify CHANGES fragment references PR + if: github.event_name == 'pull_request' + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_BODY: ${{ github.event.pull_request.body }} + run: | + set -euo pipefail + added=$( + gh api --paginate \ + "repos/${{ github.repository }}/pulls/${PR_NUMBER}/files" \ + --jq '.[] | select(.status=="added") | .filename' \ + | grep '^CHANGES/' || true + ) + failed=0 + for f in $added; do + num=$(basename "$f" | cut -d. -f1) + [[ "$num" =~ ^[0-9]+$ ]] || continue + if [[ "$num" == "$PR_NUMBER" ]]; then continue; fi + if grep -qE "(^|[^0-9])#${num}([^0-9]|$)" <<<"$PR_BODY"; then continue; fi + echo "::error file=$f::Change fragment ($num) must reference PR #$PR_NUMBER or an issue this PR fixes" + failed=1 + done + exit $failed - name: Install spell checker run: | pip install -r requirements/doc-spelling.in -c requirements/doc-spelling.txt diff --git a/CHANGES/12788.contrib.rst b/CHANGES/12788.contrib.rst new file mode 100644 index 00000000000..8a58642ff2e --- /dev/null +++ b/CHANGES/12788.contrib.rst @@ -0,0 +1 @@ +Added check that change fragment matches PR number -- by :user:`Dreamsorcerer`. diff --git a/tests/test_connector.py b/tests/test_connector.py index 3b73677cbc6..a246bd38b18 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -2223,7 +2223,7 @@ async def test_tcp_connector_ssl_shutdown_timeout_passed_to_create_connection( ) as create_connection: create_connection.return_value = mock.Mock(), mock.Mock() - req = make_client_request("GET", URL("https://example.com"), loop=loop) + req = make_client_request("GET", URL("https://127.0.0.1"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): assert create_connection.call_args.kwargs["ssl_shutdown_timeout"] == 2.5 @@ -2241,7 +2241,7 @@ async def test_tcp_connector_ssl_shutdown_timeout_passed_to_create_connection( ) as create_connection: create_connection.return_value = mock.Mock(), mock.Mock() - req = make_client_request("GET", URL("https://example.com"), loop=loop) + req = make_client_request("GET", URL("https://127.0.0.1"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): # When ssl_shutdown_timeout is None, it should not be in kwargs @@ -2260,7 +2260,7 @@ async def test_tcp_connector_ssl_shutdown_timeout_passed_to_create_connection( ) as create_connection: create_connection.return_value = mock.Mock(), mock.Mock() - req = make_client_request("GET", URL("http://example.com"), loop=loop) + req = make_client_request("GET", URL("http://127.0.0.1"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): # For non-SSL connections, ssl_shutdown_timeout should not be passed @@ -2289,12 +2289,12 @@ async def test_tcp_connector_ssl_shutdown_timeout_not_passed_pre_311( create_connection.return_value = mock.Mock(), mock.Mock() # Test with HTTPS - req = make_client_request("GET", URL("https://example.com"), loop=loop) + req = make_client_request("GET", URL("https://127.0.0.1"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): assert "ssl_shutdown_timeout" not in create_connection.call_args.kwargs # Test with HTTP - req = make_client_request("GET", URL("http://example.com"), loop=loop) + req = make_client_request("GET", URL("http://127.0.0.1"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): assert "ssl_shutdown_timeout" not in create_connection.call_args.kwargs @@ -2447,13 +2447,13 @@ async def test_tcp_connector_ssl_shutdown_timeout_zero_not_passed( create_connection.return_value = mock.Mock(), mock.Mock() # Test with HTTPS - req = make_client_request("GET", URL("https://example.com"), loop=loop) + req = make_client_request("GET", URL("https://127.0.0.1"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): # Verify ssl_shutdown_timeout was NOT passed assert "ssl_shutdown_timeout" not in create_connection.call_args.kwargs # Test with HTTP (should not have ssl_shutdown_timeout anyway) - req = make_client_request("GET", URL("http://example.com"), loop=loop) + req = make_client_request("GET", URL("http://127.0.0.1"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): assert "ssl_shutdown_timeout" not in create_connection.call_args.kwargs @@ -2479,13 +2479,13 @@ async def test_tcp_connector_ssl_shutdown_timeout_nonzero_passed( create_connection.return_value = mock.Mock(), mock.Mock() # Test with HTTPS - req = make_client_request("GET", URL("https://example.com"), loop=loop) + req = make_client_request("GET", URL("https://127.0.0.1"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): # Verify ssl_shutdown_timeout WAS passed assert create_connection.call_args.kwargs["ssl_shutdown_timeout"] == 5.0 # Test with HTTP (should not have ssl_shutdown_timeout) - req = make_client_request("GET", URL("http://example.com"), loop=loop) + req = make_client_request("GET", URL("http://127.0.0.1"), loop=loop) with closing(await conn.connect(req, [], ClientTimeout())): assert "ssl_shutdown_timeout" not in create_connection.call_args.kwargs