diff --git a/.github/actions/check-control/action.yml b/.github/actions/check-control/action.yml index c25e0af6..49524204 100644 --- a/.github/actions/check-control/action.yml +++ b/.github/actions/check-control/action.yml @@ -192,11 +192,40 @@ runs: printf "check_date=%s\n" $(TZ=UTC date -Iseconds | cut -d+ -f1-1) >> "$GITHUB_OUTPUT" - id: output_check_details_url if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} + env: + CI_INPUT_TARGET_URL: '${{ inputs.details-url }}' + SAFEURL: 'https://github.com/' shell: bash run: | - if [[ "${{ inputs.details-url }}" != "DEFAULT" ]] ; then - printf "details_url=%s\n" '${{ inputs.details-url }}' >> "$GITHUB_OUTPUT" - printf "::debug:: %s\n" "Check detail url was provided: ${{ inputs.details-url }}" ; + set -euo pipefail + raw_input="${CI_INPUT_TARGET_URL}" + # Reject NUL or newline immediately + if printf '%s' "$raw_input" | grep -q '[^[:print:]]'; then + printf "::error title='Invalid':: %s\n" "Error: input contains disallowed control characters" >&2 + exit 1 + fi + # Strip one level of surrounding quotes and trim whitespace + normalize() { + local s="$1" + s="${s#"${s%%[![:space:]]*}"}" + s="${s%"${s##*[![:space:]]}"}" + if [[ (${s:0:1} == "'" && ${s: -1} == "'") || (${s:0:1} == '"' && ${s: -1} == '"') ]]; then + s="${s:1:-1}" + fi + if [[ "$s" == *$'\n'* ]] || [[ "$s" == *$'\r'* ]]; then + printf "::error title='Invalid Detail Link'::%s\n" "Input contains newline or CR" >&2 + return 125 + fi + if [[ "$s" == *$'::'* ]] || [[ "$s" == *$'##'* ]]; then + printf "::error title='Invalid Detail Link'::%s\n" "Input contains anomalies" >&2 + return 125 + fi + printf '%s' "$s" + } + input_url="$(normalize "$raw_input")" + if [[ "${input_url:0:7}" != "DEFAULT" ]] && [[ "${input_url:0:19}" == "${SAFEURL}" ]] ; then + printf "details_url=%s\n" "${input_url}" >> "$GITHUB_OUTPUT" + printf "::debug:: %s\n" "Check detail url was provided: ${input_url}" ; else if [[ "${{ inputs.workflow-run-id }}" != "" ]] ; then printf "details_url=%s\n" 'https://github.com/reactive-firewall-org/multicast/actions/runs/${{ github.run_id }}' >> "$GITHUB_OUTPUT" diff --git a/.github/actions/checkout-and-rebuild/action.yml b/.github/actions/checkout-and-rebuild/action.yml index 574d1c72..62015610 100644 --- a/.github/actions/checkout-and-rebuild/action.yml +++ b/.github/actions/checkout-and-rebuild/action.yml @@ -127,7 +127,7 @@ runs: - id: fetch_artifact_files name: "Fetch Build Files" if: ${{ (github.repository == 'reactive-firewall-org/multicast') && success() }} - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: ${{ inputs.path }}/dist pattern: multicast-build-${{ steps.output_sha.outputs.sha }} @@ -135,6 +135,7 @@ runs: repository: reactive-firewall-org/multicast github-token: ${{ inputs.token }} run-id: ${{ inputs.build-run-id }} + digest-mismatch: error - name: "Enumerate Fetched Files" id: output_artifact_files if: ${{ (github.repository == 'reactive-firewall-org/multicast') && success() }} diff --git a/.github/actions/run-minimal-acceptance-tests/action.yml b/.github/actions/run-minimal-acceptance-tests/action.yml index 2adae05c..033d29aa 100644 --- a/.github/actions/run-minimal-acceptance-tests/action.yml +++ b/.github/actions/run-minimal-acceptance-tests/action.yml @@ -353,7 +353,7 @@ runs: - name: "Upload Details" id: upload if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: MATS name: ${{ steps.output_artifact_name.outputs.artifact-name }} diff --git a/.github/actions/setup-py-reqs/action.yml b/.github/actions/setup-py-reqs/action.yml index 80491aeb..c73e2441 100644 --- a/.github/actions/setup-py-reqs/action.yml +++ b/.github/actions/setup-py-reqs/action.yml @@ -282,7 +282,7 @@ runs: - name: "Upload Details" id: upload if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: DEPS name: ${{ steps.output_artifact_name.outputs.artifact-name }} diff --git a/.github/actions/test-reporter-upload/action.yml b/.github/actions/test-reporter-upload/action.yml index 16532a91..100a50ce 100644 --- a/.github/actions/test-reporter-upload/action.yml +++ b/.github/actions/test-reporter-upload/action.yml @@ -304,7 +304,7 @@ runs: - name: Upload ${{ steps.output_os.outputs.os }} Python ${{ steps.output_python.outputs.python-version }} coverage to Codecov id: coverage-codecov-upload if: ${{ success() && (steps.output_can_upload.outputs.can_upload == 'true') && (steps.output_upload_tools.outputs.can_upload_to_codecov == 'true') }} - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: token: ${{ inputs.codecov-token }} job_code: ${{ inputs.job_code || '' }} @@ -321,7 +321,7 @@ runs: - name: Upload ${{ steps.output_os.outputs.os }} Python ${{ steps.output_python.outputs.python-version }} Artifact id: coverage-reports-upload if: ${{ !cancelled() && (steps.output_can_upload.outputs.can_upload == 'true') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: Test-Report-${{ steps.output_os.outputs.os }}-${{ steps.output_python.outputs.python-version }}-${{ steps.output_sha.outputs.sha }} path: ./test-reports/ diff --git a/.github/workflows/CI-BUILD.yml b/.github/workflows/CI-BUILD.yml index 1de30d16..d2ef7988 100644 --- a/.github/workflows/CI-BUILD.yml +++ b/.github/workflows/CI-BUILD.yml @@ -70,7 +70,7 @@ jobs: printf "python-version=%s\n" "${{ steps.build-python.outputs.python-version }}" >> "$GITHUB_OUTPUT" printf "PYTHON_VERSION=%s\n" "${{ steps.build-python.outputs.python-version }}" >> "$GITHUB_ENV" printf "%s\n" "::endgroup::" - - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} @@ -123,7 +123,7 @@ jobs: - name: Upload build artifact id: upload if: ${{ !cancelled() && (steps.buildfiles.outputs.files != '') && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: dist name: multicast-build-${{ github.sha }} @@ -246,6 +246,7 @@ jobs: id-token: write contents: read attestations: write + artifact-metadata: write needs: [BUILD] runs-on: ubuntu-latest environment: ${{ needs.BUILD.outputs.build_environment }} @@ -255,7 +256,7 @@ jobs: build-artifact-attestation-id: ${{ steps.multicast-build-attest.outputs.attestation-id }} steps: - name: Download All Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: ${{ github.workspace }}/dist pattern: multicast-build-${{ github.sha }} @@ -266,14 +267,14 @@ jobs: - name: "Attest Build Checksums" id: multicast-build-chksum-attest if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') && (needs.BUILD.outputs.build_environment == 'Deployment' && startsWith(github.ref, 'refs/tags/v')) }} - uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-checksums: build.checksums.txt github-token: ${{ github.token }} - name: "Attest Build Artifact" id: multicast-build-attest if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0 + uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 with: subject-name: multicast-build-${{ github.sha }} subject-digest: sha256:${{ needs.BUILD.outputs.artifact-digest }} @@ -338,7 +339,7 @@ jobs: printf "%s\n" "build_id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" cat <"$GITHUB_OUTPUT" >> "BUILD-info.txt" - name: Download All Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: ${{ github.workspace }}/dist pattern: multicast-build-${{ github.sha }} @@ -346,7 +347,7 @@ jobs: - name: Upload build summary id: upload-build-info if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: "BUILD-info.txt" name: multicast-info-${{ github.sha }} @@ -393,7 +394,7 @@ jobs: - name: Upload build summary id: upload-build-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: ./Build-Summary-Artifact.txt name: BUILD-COMMENT-BODY-${{ github.sha }} @@ -414,7 +415,7 @@ jobs: - name: "Download Status Summary Artifact" id: download-build-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: BUILD-COMMENT-BODY-${{ github.sha }} github-token: ${{ github.token }} diff --git a/.github/workflows/CI-CHGLOG.yml b/.github/workflows/CI-CHGLOG.yml index e31351ea..5e923ecf 100644 --- a/.github/workflows/CI-CHGLOG.yml +++ b/.github/workflows/CI-CHGLOG.yml @@ -75,7 +75,7 @@ jobs: fi - name: "Fetch Build Info" if: ${{ (steps.check.outputs.should_run == 'true') && success() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: "BUILD-info.txt" pattern: multicast-info-* @@ -83,6 +83,7 @@ jobs: merge-multiple: true github-token: ${{ env.GH_TOKEN }} run-id: ${{ steps.get_trigger_id.outputs.trigger_id }} + digest-mismatch: error - name: "move into place" if: ${{ (steps.check.outputs.should_run == 'true') && success() && (github.repository == 'reactive-firewall-org/multicast') }} id: load_build_info @@ -189,7 +190,7 @@ jobs: - name: Upload CHANGELOG artifact id: upload if: ${{ success() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: CHANGELOG.md name: 'multicast-chglog-${{ needs.check_build.outputs.sha }}' @@ -214,7 +215,7 @@ jobs: steps: - name: Download ChangeLog Artifact id: download - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: '${{ runner.temp }}/' artifact-ids: ${{ needs.CHGLOG.outputs.artifact-id }} @@ -259,7 +260,7 @@ jobs: - name: "Upload chglog summary" id: upload-chglog-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: ./chglog-Summary-Artifact.txt name: chglog-COMMENT-BODY-${{ needs.check_build.outputs.sha }} @@ -339,7 +340,7 @@ jobs: - name: Upload build summary id: upload-build-info if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: "chglog-info.txt" name: multicast-chglog-info-${{ needs.check_build.outputs.sha }} @@ -359,7 +360,7 @@ jobs: - name: "Download Status Summary Artifact" id: download-chglog-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: chglog-COMMENT-BODY-${{ needs.check_build.outputs.sha }} github-token: ${{ github.token }} diff --git a/.github/workflows/CI-DOCS.yml b/.github/workflows/CI-DOCS.yml index b332d5dd..b52eb2f1 100644 --- a/.github/workflows/CI-DOCS.yml +++ b/.github/workflows/CI-DOCS.yml @@ -71,7 +71,7 @@ jobs: fi - name: "Fetch MATs Info" if: ${{ (github.repository == 'reactive-firewall-org/multicast') && success() }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: "multicast-info.txt" pattern: multicast-info-* @@ -79,6 +79,7 @@ jobs: merge-multiple: true github-token: ${{ env.GH_TOKEN }} run-id: ${{ steps.get_trigger_id.outputs.trigger_id }} + digest-mismatch: error - name: "move into place" id: load_build_info if: ${{ (github.repository == 'reactive-firewall-org/multicast') && success() }} @@ -182,7 +183,7 @@ jobs: fi - name: Upload Docs Artifact with Python ${{ matrix.python-version }} on ${{ matrix.os }} id: upload-documentation - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: Multicast-Documentation-${{ needs.check_mats.outputs.build_sha }}-${{ matrix.os }}-${{ matrix.python-version }} path: ./Multicast-Documentation @@ -210,7 +211,7 @@ jobs: if: ${{ !cancelled() && (needs.check_mats.outputs.should_run == 'true') && (needs.DOCS.outputs.docs_outcome != 'cancelled') }} steps: - name: Download All Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: ${{ github.workspace }}/Multicast-Documentation pattern: Multicast-Documentation-${{ needs.check_mats.outputs.build_sha }}-*-* @@ -238,7 +239,7 @@ jobs: - name: "Upload DOCs summary" id: upload-docs-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: ./DOCUMENTATION-Summary-Artifact.txt name: DOCUMENTATION-COMMENT-BODY-${{ needs.check_mats.outputs.build_sha }} @@ -249,7 +250,7 @@ jobs: - name: "Upload DOCs Bundle" id: upload-docs-bundle if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: Multicast-Documentation name: Multicast-Documentation-${{ needs.check_mats.outputs.build_sha }}-ALL @@ -290,7 +291,7 @@ jobs: - name: "Download Status Summary Artifact" id: download-documentation-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: DOCUMENTATION-COMMENT-BODY-${{ needs.check_mats.outputs.build_sha }} github-token: ${{ github.token }} diff --git a/.github/workflows/CI-MATs.yml b/.github/workflows/CI-MATs.yml index 584ce363..d93a7de8 100644 --- a/.github/workflows/CI-MATs.yml +++ b/.github/workflows/CI-MATs.yml @@ -79,7 +79,7 @@ jobs: fi - name: "Fetch Build Info" if: ${{ (github.repository == 'reactive-firewall-org/multicast') && (steps.check.outputs.should_run == 'true') && success() }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: "BUILD-info.txt" pattern: multicast-info-* @@ -87,6 +87,7 @@ jobs: merge-multiple: true github-token: ${{ env.GH_TOKEN }} run-id: ${{ steps.get_trigger_id.outputs.trigger_id }} + digest-mismatch: error - name: "move into place" id: load_build_info if: ${{ (github.repository == 'reactive-firewall-org/multicast') && (steps.check.outputs.should_run == 'true') && success() }} @@ -217,7 +218,7 @@ jobs: build_sha: ${{ needs.check_build.outputs.sha }} steps: - name: Download All Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: ${{ github.workspace }}/MATS pattern: multicast-mats-${{ needs.check_build.outputs.sha }}-part-* @@ -291,7 +292,7 @@ jobs: - name: "Upload MATs summary" id: upload-mats-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: ./MATs-Summary-Artifact.txt name: MATS-COMMENT-BODY-${{ needs.check_build.outputs.sha }} @@ -371,7 +372,7 @@ jobs: - name: Upload build summary id: upload-build-info if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: "multicast-info.txt" name: multicast-info-${{ needs.check_build.outputs.sha }} @@ -391,7 +392,7 @@ jobs: - name: "Download Status Summary Artifact" id: download-mats-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: MATS-COMMENT-BODY-${{ needs.check_build.outputs.sha }} github-token: ${{ github.token }} diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 63972f0b..1eb37b54 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -96,7 +96,7 @@ jobs: fi - name: "Fetch MATs Info" if: ${{ (steps.check.outputs.should_run == 'true') && (github.repository == 'reactive-firewall-org/multicast') && success() }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: "multicast-info.txt" pattern: multicast-info-* @@ -104,6 +104,7 @@ jobs: merge-multiple: true github-token: ${{ env.GH_TOKEN }} run-id: ${{ steps.get_trigger_id.outputs.trigger_id }} + digest-mismatch: error - name: "move into place" id: load_build_info if: ${{ (steps.check.outputs.should_run == 'true') && (github.repository == 'reactive-firewall-org/multicast') && success() }} @@ -223,7 +224,7 @@ jobs: make -f Makefile test || exit 1 - name: Upload Python ${{ matrix.python-version }} test coverage to Codecov id: coverage-unittests-codecov-upload - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} job_code: ${{ needs.check_mats.outputs.build_id }}-${{ github.run_number }} @@ -240,7 +241,7 @@ jobs: fail_ci_if_error: false - name: Upload Python ${{ matrix.python-version }} second flag coverage to Codecov id: coverage-project-codecov-upload - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} job_code: ${{ needs.check_mats.outputs.build_id }}-${{ github.run_number }} @@ -397,7 +398,7 @@ jobs: - name: "Upload Coverage Summary" id: upload if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: COVERAGE name: ${{ steps.output_coverage_step_summary.outputs.coverage-artifact-name }} @@ -481,7 +482,7 @@ jobs: make -f Makefile test-mat-doctests || exit 1 - name: Upload Python ${{ matrix.python-version }} doctest coverage to Codecov id: doctests-codecov-upload - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} job_code: ${{ needs.check_mats.outputs.build_id }}-${{ github.run_number }} @@ -499,7 +500,7 @@ jobs: fail_ci_if_error: false - name: Upload Python ${{ matrix.python-version }} Artifact id: doctests-reports-upload - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: DocTest-Report-${{ matrix.os }}-${{ matrix.python-version }} path: ./test-reports/ @@ -631,7 +632,7 @@ jobs: - name: "Upload Doctests Summary" id: upload if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: COVERAGE name: ${{ steps.output_doctests_step_summary.outputs.doctests-artifact-name }} @@ -652,7 +653,7 @@ jobs: if: ${{ !cancelled() && (needs.check_mats.outputs.should_run == 'true') && (needs.COVERAGE.outputs.coverage_outcome != 'cancelled') }} steps: - name: Download All Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: ${{ github.workspace }}/COVERAGE pattern: multicast-coverage-${{ needs.check_mats.outputs.build_sha }}-part-* @@ -691,7 +692,7 @@ jobs: - name: "Upload COVERAGE summary" id: upload-coverage-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: ./COVERAGE-Summary-Artifact.txt name: COVERAGE-COMMENT-BODY-${{ needs.check_mats.outputs.build_sha }} @@ -717,7 +718,7 @@ jobs: - name: "Download Status Summary Artifact" id: download-coverage-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: COVERAGE-COMMENT-BODY-${{ needs.check_mats.outputs.build_sha }} github-token: ${{ github.token }} @@ -930,7 +931,7 @@ jobs: shell: bash - name: Upload Python ${{ matrix.python-version }} integration coverage to Codecov id: integration-codecov-upload - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} job_code: ${{ needs.check_mats.outputs.build_id }}-${{ github.run_number }} @@ -949,7 +950,7 @@ jobs: fail_ci_if_error: false - name: Upload Extra Python ${{ matrix.python-version }} Artifact id: integration-reports-upload - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: Integration-Test-Report-${{ matrix.os }}-${{ matrix.python-version }} path: ./test-reports/ @@ -966,7 +967,7 @@ jobs: - name: Upload Python ${{ matrix.python-version }} integration test results to Codecov if: ${{ !cancelled() && (env.TESTS_USE_PYTEST == '1') }} id: integration-codecov-results-upload - uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: report_type: 'test_results' token: ${{ secrets.CODECOV_TOKEN }} @@ -1200,7 +1201,7 @@ jobs: - name: "Upload integration Summary" id: upload if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: EXTRAS name: ${{ steps.output_integration_step_summary.outputs.integration-artifact-name }} @@ -1226,7 +1227,7 @@ jobs: if: ${{ !cancelled() && (needs.check_mats.outputs.should_run == 'true') && (needs.INTEGRATION.outputs.integration_outcome != 'cancelled') }} steps: - name: Download All Artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: ${{ github.workspace }}/EXTRAS pattern: multicast-integration-${{ needs.check_mats.outputs.build_sha }}-part-* @@ -1281,7 +1282,7 @@ jobs: - name: "Upload INTEGRATION summary" id: upload-integration-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: path: ./Integration-Summary-Artifact.txt name: INTEGRATION-COMMENT-BODY-${{ needs.check_mats.outputs.build_sha }} @@ -1322,7 +1323,7 @@ jobs: - name: "Download Status Summary Artifact" id: download-integration-summary if: ${{ !cancelled() && (github.repository == 'reactive-firewall-org/multicast') }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: INTEGRATION-COMMENT-BODY-${{ needs.check_mats.outputs.build_sha }} github-token: ${{ github.token }} @@ -1387,7 +1388,7 @@ jobs: id: install-pip-tools run: | printf "%s\n" "::group::install-tools" - pip install -U "pip-licenses>=5.5.1" + pip install -U "pip-licenses>=5.5.5" printf "%s\n" "::endgroup::" shell: bash - name: Pre-Clean diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 22f0c18e..2cd26dca 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -50,7 +50,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3 + uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,7 +61,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3 + uses: github/codeql-action/autobuild@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -75,4 +75,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3 + uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 diff --git a/.github/workflows/makefile-lint.yml b/.github/workflows/makefile-lint.yml index 8eca13ec..ec0a4e7e 100644 --- a/.github/workflows/makefile-lint.yml +++ b/.github/workflows/makefile-lint.yml @@ -51,7 +51,7 @@ jobs: yamllint --version || { print_error "Yamllint installation failed." 40 41 ; exit 126; } pandoc --version || { print_error "Pandoc installation failed." 40 41 ; exit 126; } - name: Force Setup newer go - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: 1.25 check-latest: true diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 8c1071dd..37010a6e 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -50,13 +50,13 @@ jobs: # uploads of run results in SARIF format to the repository Actions tab. # https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts - name: "Upload artifact" - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: SARIF file path: results.sarif retention-days: 5 # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3 + uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 with: sarif_file: results.sarif diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 7699ed63..17b1bc46 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -23,7 +23,7 @@ jobs: with: persist-credentials: false - name: Shellcheck Scan - uses: reactive-firewall/shellcheck-scan@ececa8940e6bfbf5bf1426dd9292b9b25367c14a # v0 + uses: reactive-firewall/shellcheck-scan@9e323955cc8c1eb727a1ee0a50a9aca29f81d8c9 # v2 with: # optional arguments match: 'tests/check_* **/*.sh' publish-artifacts: true diff --git a/multicast/recv.py b/multicast/recv.py index 18b7fdde..575fe061 100644 --- a/multicast/recv.py +++ b/multicast/recv.py @@ -31,6 +31,51 @@ Classes: McastRECV: Main tool class for RECV operations. +Private Module Variables: + The following private variables contain warning messages used internally by the + multicast.recv module. These variables follow the naming pattern `_w_[a-z_]*` and + are strictly for internal use only. Developers MUST NOT access these variables + directly. While they may appear in diagnostic output or stack traces, they should + be treated as implementation details and ignored. + + Warning Messages: + _w_prefix (str): Private prefix for warning about unusual calls to `joinstep` + (e.g., when no multicast groups are specified). Used as the primary message + component in warnings about empty group lists. + + _w_example_code (str): Private variable holding recommended code snippet for + proper socket binding. Used only as a component within `_w_advice` to + demonstrate correct API usage patterns. + + _w_advice (str): Private advice component for developers, combining + recommended practices with `_w_example_code`. Used as the guidance + portion of `_w_empty_join_warning` to help developers improve their code. + + _w_empty_join_warning (str): Warning message issued when + `joinstep` is called without multicast groups and without specifying + a bind group. Combines `_w_prefix` and `_w_advice` to provide complete + developer guidance. Issued as SyntaxWarning to notify about unusual API usage. + + _w_unspec_bind (str): Warning message issued when `joinstep` is + called with a non-default multicast group but without an explicit + bind_group parameter. Warns about lazy calls and informs about + default binding behavior. Issued as ResourceWarning to alert + about the specific anti-pattern. + + _w_non_multicast (str): Warning message issued when the multicast + library is used for non-multicast networking scenarios. Advises developers + to use standard `socket.socket.bind()` directly instead of the multicast + library for non-multicast operations. Issued as SyntaxWarning. + + Note: + These warnings are issued from `joinstep` when called without clear multicast + groups, to notify developers of unusual API usage. Typically, multicast + groups must be joined before the upstream network (routers or system + hardware) will properly deliver multicast packets. + + All warning messages are only emitted when `__debug__` is True (i.e., + when Python is not running with -O or -OO optimization flags). + Caution: See details regarding dynamic imports [documented](../__init__.py) in this module. Minimal Acceptance Testing: @@ -205,7 +250,7 @@ raise baton from _cause -module_logger = logging.getLogger(__name__) +module_logger: logging.Logger = logging.getLogger(__name__) module_logger.debug( "Loading %s", # lazy formatting to avoid PYL-W1203 __name__, @@ -243,7 +288,10 @@ ]) -_w_non_multicast = f"{_w_prefix}\nJust use socket.Socket.bind(...) for non-multicast networking." +_w_non_multicast: str = "\n".join([ + _w_prefix, + "Just use socket.socket.bind(...) for non-multicast networking.", +]) def _validate_join_args(groups=None, port=None, iface=None, bind_group=None, isock=None) -> tuple: diff --git a/tests/check_pip b/tests/check_pip index ecd23779..c1aa6e08 100755 --- a/tests/check_pip +++ b/tests/check_pip @@ -249,7 +249,7 @@ SCRIPT_FILE="tests/check_pip" # Set pip-audit options AUDIT_OPTIONS="--progress-spinner off --desc on --requirement" # List of Allowed Licenses delimited by semicolon ; -ALLOW_LICENSES="Public Domain;CC0 1.0 Universal;Public Domain Dedication; Zero-Clause BSD;Apache Software License;Apache-2.0;MIT License;BSD License;Python Software Foundation License;The Unlicense (Unlicense);Mozilla Public License 2.0 (MPL 2.0);" +ALLOW_LICENSES="Public Domain;CC0 1.0 Universal;Public Domain Dedication; Zero-Clause BSD;BSD-2-Clause;Apache Software License;Apache-2.0;MIT License;BSD License;Python Software Foundation License;The Unlicense (Unlicense);Mozilla Public License 2.0 (MPL 2.0);MIT;" # Set pip-licenses options LICENSE_OPTIONS="--from=mixed" # Set pip options @@ -269,7 +269,7 @@ fi ; # typing_extensions is licensed under Python Software Foundation License, but reports "UNKNOWN" # pytest-enabler is licensed under MIT, but reports "UNKNOWN" # pycodestyle is licensed under MIT, but reports just "MIT" (which does not match "MIT License") -LICENSE_OPTIONS="${LICENSE_OPTIONS} urllib3 pip setuptools wheel build hypothesis certifi roman-numerals-py Sphinx typing_extensions pytest-enabler pycodestyle" +LICENSE_OPTIONS="${LICENSE_OPTIONS} urllib3 pip setuptools wheel build hypothesis certifi roman-numerals-py Sphinx typing_extensions pytest-enabler" # Enable auto-fix if '--fix' argument is provided if [[ "$1" == "--fix" ]]; then AUDIT_OPTIONS="--fix --strict ${AUDIT_OPTIONS}"