diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000000..4e039626d5a56 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +github: [matttbe] +liberapay: matttbe +patreon: matttbe +thanks_dev: u/gh/matttbe diff --git a/.github/ISSUE_TEMPLATE/01-bug.yml b/.github/ISSUE_TEMPLATE/01-bug.yml new file mode 100644 index 0000000000000..a0784f2f872eb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01-bug.yml @@ -0,0 +1,104 @@ +name: Bug Report +description: Create a report to help us improve +labels: ["bug", "triage"] +body: + - type: markdown + attributes: + value: | + Thanks for helping us improve! 🙏 + Please answer these questions and provide as much information as possible about your problem. + + - type: checkboxes + id: pre-req + attributes: + label: Pre-requisites + description: "Before opening this ticket, I checked that:" + options: + - label: "A similar [issue](https://github.com/multipath-tcp/mptcp_net-next/issues/) has not been reported before." + - label: "[mptcp.dev](https://www.mptcp.dev) website does not cover my case." + - label: "An up-to-date kernel is being used." + - label: "This case is not fixed with the latest stable (or LTS) version listed on [kernel.org](https://kernel.org)" + + - type: textarea + id: what-did-you-do + attributes: + label: "What did you do?" + description: "If possible, provide a recipe for reproducing the error." + placeholder: | + Steps to reproduce the behavior: + 1. + 2. + validations: + required: true + + - type: textarea + id: actual-behavior + attributes: + label: "What happened?" + description: Prefer copying text output over using screenshots. + validations: + required: true + + - type: textarea + id: expected-behavior + attributes: + label: "What did you expect to have?" + description: Why is the current behavior incorrect, and any additional context we may need to understand the issue. + validations: + required: true + + - type: textarea + id: system-client + attributes: + label: "System info: Client" + description: | + Output of these commands executed on the **client** side: + ``` + uname -a + cat /etc/os-release + sysctl net.mptcp + ip mptcp endpoint show + ip mptcp limits show + ``` + placeholder: | + $ uname -a + Linux my-client 6.12.24-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.24-1 (2025-02-01) x86_64 GNU/Linux + (...) + render: shell + validations: + required: true + + - type: textarea + id: system-server + attributes: + label: "System info: Server" + description: | + Output of these commands executed on the **server** side: + ``` + uname -a + cat /etc/os-release + sysctl net.mptcp + ip mptcp endpoint show + ip mptcp limits show + ``` + placeholder: | + $ uname -a + Linux my-server 6.12.24-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.24-1 (2025-02-01) x86_64 GNU/Linux + (...) + render: shell + validations: + required: true + + - type: textarea + id: additional-context + attributes: + label: "Additional context" + description: | + Add any other context about the problem here. + Note: It might help to get the output of `ip mptcp monitor` while reproducing the issue, in addition to the output from these commands executed just before **and** after the issue: + ``` + ss -ManiH + nstat + ``` + Packet traces (TCPDump / WireShark), configured IP addresses and routing can be helpful too. Check [here](https://www.mptcp.dev/debugging.html) for more details. + mptcpd's [`/usr/libexec/mptcp-get-debug`](https://raw.githubusercontent.com/multipath-tcp/mptcpd/refs/heads/main/scripts/mptcp-get-debug) script (mptcpd >= 0.13) can help to collect such infos. diff --git a/.github/ISSUE_TEMPLATE/02-feature.yml b/.github/ISSUE_TEMPLATE/02-feature.yml new file mode 100644 index 0000000000000..404a29e874b2b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02-feature.yml @@ -0,0 +1,49 @@ +name: Feature Request +description: Suggest an idea for this project +labels: ["enhancement", "triage"] +body: + - type: markdown + attributes: + value: | + Thanks for helping us improve! 🙏 + Please answer these questions and provide as much information as possible about your idea. + + - type: checkboxes + id: pre-req + attributes: + label: Pre-requisites + description: "Before opening this ticket, I checked that:" + options: + - label: "A similar [idea](https://github.com/multipath-tcp/mptcp_net-next/issues?q=label%3Aenhancement) has not been reported before." + - label: "[mptcp.dev](https://www.mptcp.dev) website does not cover my case." + - label: "The [wiki](https://github.com/multipath-tcp/mptcp_net-next/wiki) doesn't cover my case." + + - type: textarea + id: description + attributes: + label: "Description" + description: "A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]" + validations: + required: true + + - type: textarea + id: solution + attributes: + label: "Solution" + description: "A clear and concise description of what you want to have." + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: "Considered alternatives" + description: "A clear and concise description of any alternative solutions or features you've considered." + validations: + required: true + + - type: textarea + id: additional-context + attributes: + label: "Additional context" + description: "Add any other context or screenshots about the feature request here." diff --git a/.github/ISSUE_TEMPLATE/03-question.yml b/.github/ISSUE_TEMPLATE/03-question.yml new file mode 100644 index 0000000000000..5b7618de72db4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03-question.yml @@ -0,0 +1,28 @@ +name: Question +description: Ask any questions not related to an issue or a feature request here +labels: ["question", "triage"] +body: + - type: markdown + attributes: + value: | + Thanks for helping us improve! 🙏 + Please answer these questions and provide as much information as possible about your idea. + + - type: checkboxes + id: pre-req + attributes: + label: Pre-requisites + description: "Before opening this ticket, I checked that:" + options: + - label: "A similar [question](https://github.com/multipath-tcp/mptcp_net-next/issues?q=label%3question) has not been reported before." + - label: "[mptcp.dev](https://www.mptcp.dev) website does not cover my case." + - label: "The [wiki](https://github.com/multipath-tcp/mptcp_net-next/wiki) doesn't cover my case." + - label: "This is not a question related to the current behavior, an issue or a feature requst: if it is, please use [another template](https://github.com/multipath-tcp/mptcp_net-next/issues/new/choose) **even if it is a question**: we will need details about your system: kernel version, config, etc." + + - type: textarea + id: question + attributes: + label: "My question" + description: "A clear and concise description of your question" + validations: + required: true diff --git a/.github/workflows/build-validation.yml b/.github/workflows/build-validation.yml new file mode 100644 index 0000000000000..143decc1bcdca --- /dev/null +++ b/.github/workflows/build-validation.yml @@ -0,0 +1,334 @@ +name: "MPTCP Upstream Build Validation" +on: + push: + branches-ignore: + - 'archived/**' # previous branches + - 't/**' # TopGit tree + - 'net' # part of the TopGit tree + - 'net-next' # part of the TopGit tree + - 'for-review' # part of the TopGit tree + - 'for-review-net' # part of the TopGit tree + tags: + - 'patchew/**' # patchew is using tags + # ideally, we would take 'export/**' but the cache is per branch... + # In other words, when using tags, we can only use the cache if we re-tag. + # https://github.com/actions/cache/issues/556 + # So we build the "export" branch and we try to find the tag later + +env: + CURL_OPT: "--no-progress-meter --connect-timeout 30 --retry 20 --retry-delay 10" + CURL_ACC: "Accept: application/vnd.github.v3+json" + URI: "https://api.github.com" + PW: "https://patchwork.kernel.org/api/1.2" + +permissions: {} + +jobs: + build: + name: "Build (matrix)" + if: "! startswith(github.ref, 'refs/tags/patchew/') || contains(github.event.head_commit.message, 'Message-Id: ')" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + defconfig: ['x86_64', 'i386'] + ipv6: ['with_ipv6', 'without_ipv6'] + mptcp: ['with_mptcp', 'without_mptcp'] + permissions: + contents: read # to fetch code (actions/checkout) + + steps: + - name: "Checkout (light)" + if: github.ref != 'refs/heads/export' + uses: actions/checkout@v4 + with: + fetch-depth: 100 # we should not have more commits on top of export and -net + + - name: "Checkout (export)" + if: github.ref == 'refs/heads/export' + uses: actions/checkout@v4 + with: + fetch-depth: 0 # we need to fetch all commits between net and net-next, quicker to get everything + + - name: "Find base branch" + id: branch + run: | + if [ "${REF_NAME}" = "export" ]; then # just to avoid the next cmd + echo "name=export" >> ${GITHUB_OUTPUT} + elif [ -n "$(git log -1 --grep "^DO-NOT-MERGE: mptcp: enabled by default (net)$" --format="format:%H" HEAD -- net/mptcp/Kconfig)" ]; then + echo "name=export-net" >> ${GITHUB_OUTPUT} + else + echo "name=export" >> ${GITHUB_OUTPUT} + fi + env: + REF_NAME: ${{ github.ref_name }} + + - name: "Restore cache for CCache" + uses: actions/cache/restore@v4 + id: restore-ccache + with: + path: ${{ github.workspace }}/.ccache + key: ${{ runner.os }}_build_${{ matrix.defconfig }}_${{ matrix.ipv6 }}_${{ matrix.mptcp }}_${{ steps.branch.outputs.name }}-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}_build_${{ matrix.defconfig }}_${{ matrix.ipv6 }}_${{ matrix.mptcp }}_${{ steps.branch.outputs.name }}-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.sha }} + ${{ runner.os }}_build_${{ matrix.defconfig }}_${{ matrix.ipv6 }}_${{ matrix.mptcp }}_${{ steps.branch.outputs.name }}-${{ github.run_id }}-${{ github.run_attempt }}- + ${{ runner.os }}_build_${{ matrix.defconfig }}_${{ matrix.ipv6 }}_${{ matrix.mptcp }}_${{ steps.branch.outputs.name }}-${{ github.run_id }}- + ${{ runner.os }}_build_${{ matrix.defconfig }}_${{ matrix.ipv6 }}_${{ matrix.mptcp }}_${{ steps.branch.outputs.name }}- + + - name: "Build Validation" + uses: multipath-tcp/mptcp-upstream-validate-export-action@main + with: + # we want to validate each commits on top of net-next/export (or -net) except for stable + each_commit: ${{ ! startswith(github.ref, 'refs/heads/stable/') }} + ccache_maxsize: 300M ## 10GB = project limit + defconfig: ${{ matrix.defconfig }} + ipv6: ${{ matrix.ipv6 }} + mptcp: ${{ matrix.mptcp }} + debug: ${{ runner.debug }} + + - name: "Artifacts" + if: always() + uses: actions/upload-artifact@v4 + with: + name: results-${{ matrix.defconfig }}_${{ matrix.ipv6 }}_${{ matrix.mptcp }} + path: ./build-*-results.txt + + - name: "Publish details" + if: always() + run: | + if stat ./build-*-results.txt &>/dev/null; then + echo '- Results for ${{ matrix.defconfig }} ${{ matrix.ipv6 }} ${{ matrix.mptcp }}:' >> ${GITHUB_STEP_SUMMARY} + echo "\`\`\`" >> ${GITHUB_STEP_SUMMARY} + cat ./build-*-results.txt >> ${GITHUB_STEP_SUMMARY} + echo "\`\`\`" >> ${GITHUB_STEP_SUMMARY} + fi + + - name: "Save cache for CCache" + if: github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net' + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}/.ccache + key: ${{ steps.restore-ccache.outputs.cache-primary-key }} + + notif-export: + name: "Notifications export branches" + needs: build + # only for the official repo, export branches + if: always() && github.repository_owner == 'multipath-tcp' && (github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net') + runs-on: ubuntu-latest + steps: + - name: get linked tag + id: tag + run: | + TAG=$(curl ${CURL_OPT} -H "${CURL_ACC}" -H "${CURL_AUTH}" "${URL}" | jq -r ".[] | select(.object.sha == \"${SHA}\").ref" | tail -n1) + echo "Found: ${TAG} (${SHA} - ${BRANCH})" + TAG="${TAG:10}" + echo "tag=${TAG:-${BRANCH}}" >> ${GITHUB_OUTPUT} + env: + CURL_AUTH: "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" + URL: "${{ env.URI }}/repos/${{ github.repository }}/git/matching-refs/tags/" + SHA: "${{ github.sha }}" + BRANCH: "${{ github.ref_name }}" + + - name: irc build + uses: rectalogic/notify-irc@v2 + with: + server: irc.libera.chat + channel: "#mptcp-ci" + nickname: gh-build-bot + verbose: true + message: |- + New build validating ${{ steps.tag.outputs.tag }} (by ${{ github.actor }}) ended with ${{ needs.build.result }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + + - name: irc build error + if: needs.build.result == 'failure' + uses: rectalogic/notify-irc@v2 + with: + server: irc.libera.chat + channel: "#mptcp" + nickname: gh-build-bot + verbose: true + message: |- + New build validating ${{ steps.tag.outputs.tag }} (by ${{ github.actor }}) failed: ${{ needs.build.result }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + + notif-patchew: + name: "Notifications patchew tags" + needs: build + # only for the official repo, patchew tags branches + if: always() && github.repository_owner == 'multipath-tcp' && startswith(github.ref, 'refs/tags/patchew/') && (needs.build.result == 'success' || needs.build.result == 'failure') + runs-on: ubuntu-latest + steps: + - name: "Get Results" + uses: actions/download-artifact@v4 + with: + pattern: results-* + merge-multiple: true + + - name: "Patchwork" + run: | + # $1: mid + get_status() { + case "$(awk "/^${1} /{ print \$2 }" build-*-results.txt | sort -u)" in + 'fail'*) echo "fail"; ;; + *'warning') echo "warning"; ;; + 'success') echo "success"; ;; + *) echo "fail"; ;; + esac + } + + # $1: mid, $2: status + get_desc() { + awk "/^${1} ${2} /{ + out=\$3 + for(i=4; i<=NF; i++) + out=out\" \"\$i + print out + }" build-*-results.txt | sort -u | sed '$!{:a;N;s/\n/ ; /;ta}' + } + + # $1: mid, $2: status, $3: desc + _send() { local check_url + check_url="$(curl "${URL_PW}${1}" | jq -r 'last(.[].checks)')" + if [ -z "${check_url}" ] || [ "${check_url}" = "null" ]; then + echo "URL not found: '${check_url}' '${URL_PW}${1}'" + return 1 + fi + + curl ${CURL_OPT} \ + -X POST \ + -H "Authorization: Token ${{ secrets.PW_TOKEN }}" \ + -F "state=${2}" \ + -F "target_url=${URL_GH}" \ + -F "context=build" \ + -F "description=${3}" \ + "${check_url}" | jq '.' + } + + FIRST=1 + send() { local i + # patches can take a bit of time to appear: retry the first time + if [ "${FIRST}" = "1" ]; then + FIRST=0 + + for i in $(seq 45); do + if _send "${@}"; then + echo "Successful sent after ${i} attempts" + return 0 + fi + sleep 1m + done + + curl "${URL_PW}${1}" + return 1 + else + _send "${@}" + fi + } + + if ! ls ./build-*-results.txt; then + echo "Strange, no results, please check why" + exit 1 + fi + + while read -r mid; do + status=$(get_status "${mid}") + desc=$(get_desc "${mid}" "${status}") + send "${mid}" "${status}" "${desc}" + done < <(awk '{ print $1 }' build-*-results.txt | sort -u) + env: + URL_GH: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + URL_PW: "${{ env.PW }}/patches/?project=mptcp&msgid=" + + - name: get commit info + id: commit + if: needs.build.result == 'failure' + run: | + cat <<'EOF' > commit.json + ${{ toJSON(github.event.head_commit) }} + EOF + + # ignore error, just in case the MID has not been added by the author + read -r TAG MID < <(jq -r '.message' commit.json | grep -i "^Message-Id: " | tail -n1) || true + + # Guess the subject from the last commit + SUBJECT=$(jq -r '.message' commit.json | head -n1) + + if [ -n "${MID:1:-1}" ]; then + # get cover-letter and series' name if any + URL_PW_SERIES_API=$(curl "${URL_PW}${MID:1:-1}" | jq -er 'last(last(.[].series)[].url)' || true) + if [ -n "${URL_PW_SERIES_API}" ] && [ "${URL_PW_SERIES_API}" != "null" ]; then + echo "series=${URL_PW_SERIES}$(basename "${URL_PW_SERIES_API}")" >> ${GITHUB_OUTPUT} + if curl "${URL_PW_SERIES_API}" > pw_series.json && [ -s pw_series.json ]; then + CL="$(jq '.cover_letter' pw_series.json || true)" + if [ -n "${CL}" ] && [ "${CL}" != "null" ] && [ "${CL}" != "{}" ]; then + MID=$(echo "${CL}" | jq -er '.msgid' || echo "${MID}") + SUBJECT=$(jq -er '.name' pw_series.json || echo "${SUBJECT}") + fi + fi + fi + + # get tags from Lore: not fully available from Patchwork + SUBJECT="$(curl "${URL_LORE//MID/${MID:1:-1}}" | grep '^Subject: ' | head -n1 | sed 's/^Subject: \(\[.*\] \).*/\1/')${SUBJECT}" + fi + + echo "Found message ID: '${TAG}' '${MID}'" + echo "mid=${MID:1:-1}" >> ${GITHUB_OUTPUT} + + echo "Found subject: '${SUBJECT}'" + echo "subject=${SUBJECT}" >> ${GITHUB_OUTPUT} + + NAME=$(jq -r '.author.name' commit.json) + EMAIL=$(jq -r '.author.email' commit.json) + echo "Found author: '${NAME}' '${EMAIL}'" + echo "name=${NAME%% *}" >> ${GITHUB_OUTPUT} + echo "author=${NAME} <${EMAIL}>" >> ${GITHUB_OUTPUT} + + SHA=$(jq -r '.id' commit.json) + echo "Found SHA: '${SHA}' ('${SHA:0:12}')" + echo "sha=${SHA:0:12}" >> ${GITHUB_OUTPUT} + + COMMITTER=$(jq -r '.committer.name' commit.json) + echo "Found committer: '${COMMITTER}'" + echo "committer=${COMMITTER}" >> ${GITHUB_OUTPUT} + env: + URL_PW: "${{ env.PW }}/patches/?project=mptcp&msgid=" + URL_PW_SERIES: "https://patchwork.kernel.org/project/mptcp/list/?series=" + URL_LORE: "https://lore.kernel.org/mptcp/MID/raw" + + - name: send email + if: needs.build.result == 'failure' + uses: dawidd6/action-send-mail@v3 + with: + server_address: smtp.gmail.com + server_port: 465 + username: ${{ secrets.MAIL_USERNAME }} + password: ${{ secrets.MAIL_PASSWORD }} + to: ${{ steps.commit.outputs.author }} + cc: mptcp@lists.linux.dev + from: MPTCP CI + reply_to: mptcp@lists.linux.dev + in_reply_to: "<${{ steps.commit.outputs.mid }}>" + subject: "Re: ${{ steps.commit.outputs.subject }}" + body: | + Hi ${{ steps.commit.outputs.name }}, + + Thank you for your modifications, that's great! + + But sadly, our CI spotted some issues with it when trying to build it. + + You can find more details there: + + ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + + Status: ${{ needs.build.result }} + Initiator: ${{ steps.commit.outputs.committer }} + Commits: ${{ github.server_url }}/${{ github.repository }}/commits/${{ steps.commit.outputs.sha }} + Patchwork: ${{ steps.commit.outputs.series }} + + Feel free to reply to this email if you cannot access logs, if you need + some support to fix the error, if this doesn't seem to be caused by your + modifications or if the error is a false positive one. + + Cheers, + MPTCP GH Action bot + Bot operated by Matthieu Baerts (NGI0 Core) diff --git a/.github/workflows/checkpatch.yml b/.github/workflows/checkpatch.yml new file mode 100644 index 0000000000000..d86e76eaed06c --- /dev/null +++ b/.github/workflows/checkpatch.yml @@ -0,0 +1,191 @@ +name: "CheckPatch" +on: + push: + branches-ignore: + - 'archived/**' # previous branches + - 't/**' # TopGit tree + - 'net' # part of the TopGit tree + - 'net-next' # part of the TopGit tree + - 'for-review' # part of the TopGit tree + - 'for-review-net' # part of the TopGit tree + tags: + - 'patchew/**' # patchew is using tags + +env: + CURL_OPT: "--no-progress-meter --connect-timeout 30 --retry 20 --retry-delay 10" + PW: "https://patchwork.kernel.org/api/1.2" + CHECKPATCH_RESULTS: "./checkpatch-results.txt" + CHECKPATCH_DETAILS: "./checkpatch-details.txt" + SHELLCHECK_RESULTS: "./shellcheck-results.txt" + SHELLCHECK_DETAILS: "./shellcheck-details.txt" + +permissions: {} + +jobs: + checkpatch: + name: "Checkpatch" + # for others or for the official repo but only commits from patchew + if: "github.repository_owner != 'multipath-tcp' || (startswith(github.ref, 'refs/tags/patchew/') && contains(github.event.head_commit.message, 'Message-Id: '))" + runs-on: ubuntu-latest + permissions: + contents: read # to fetch code (actions/checkout) + + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 ## to make sure a mentioned commit exists + + - name: "Checkpatch" + uses: multipath-tcp/mptcp-upstream-validate-export-action@main + with: + each_commit: true + checkpatch: true + debug: ${{ secrets.BUILD_ACTION_DEBUG }} + + - name: "Publish details" + if: always() + run: | + if [ -s "${{ env.CHECKPATCH_DETAILS }}" ]; then + echo '## CheckPatch' >> ${GITHUB_STEP_SUMMARY} + cat "${{ env.CHECKPATCH_DETAILS }}" >> ${GITHUB_STEP_SUMMARY} + fi + if [ -s "${{ env.SHELLCHECK_DETAILS }}" ]; then + echo '## ShellCheck' >> ${GITHUB_STEP_SUMMARY} + cat "${{ env.SHELLCHECK_DETAILS }}" >> ${GITHUB_STEP_SUMMARY} + fi + + - name: "Artifacts" + uses: actions/upload-artifact@v4 + with: + name: results + path: | + ${{ env.CHECKPATCH_RESULTS }} + ${{ env.SHELLCHECK_RESULTS }} + + - name: "Artifacts" + uses: actions/upload-artifact@v4 + with: + name: details + path: | + ${{ env.CHECKPATCH_DETAILS }} + ${{ env.SHELLCHECK_DETAILS }} + + notif: + name: "Notifications" + needs: checkpatch + # only for the official repo (patchew) + if: github.repository_owner == 'multipath-tcp' && startswith(github.ref, 'refs/tags/patchew/') && (needs.checkpatch.result == 'success' || needs.checkpatch.result == 'failure') + runs-on: ubuntu-latest + steps: + - name: "Get Results" + uses: actions/download-artifact@v4 + with: + name: results + + - name: "Patchwork" + run: | + # $1: mid, $2: status, $3: desc, $4: context + _send() { local check_url + check_url="$(curl "${URL_PW}${1}" | jq -r 'last(.[].checks)')" + if [ -z "${check_url}" ] || [ "${check_url}" = "null" ]; then + echo "URL not found: '${check_url}' '${URL_PW}${1}'" + return 1 + fi + + curl ${CURL_OPT} \ + -X POST \ + -H "Authorization: Token ${{ secrets.PW_TOKEN }}" \ + -F "state=${2}" \ + -F "target_url=${URL_GH}" \ + -F "context=${4}" \ + -F "description=${3}" \ + "${check_url}" | jq '.' + } + + FIRST=1 + send() { local i + # patches can take a bit of time to appear: retry the first time + if [ "${FIRST}" = "1" ]; then + FIRST=0 + + for i in $(seq 45); do + if _send "${@}"; then + echo "Successful sent after ${i} attempts" + return 0 + fi + sleep 1m + done + + curl "${URL_PW}${1}" + return 1 + else + _send "${@}" + fi + } + + # $1: file, $2: context + parse_results() { + if [ ! -s "${1}" ]; then + echo "Strange, no results, please check why" + return 1 + fi + + while read -r mid status desc; do + echo "Sending: '${mid}' '${status}' '${desc}' '${2}'" + send "${mid}" "${status}" "${desc}" "${2}" + done < "${1}" + } + + rc=0 + parse_results "${CHECKPATCH_RESULTS}" "checkpatch" || rc=1 + parse_results "${SHELLCHECK_RESULTS}" "shellcheck" || rc=1 + exit ${rc} + + env: + URL_GH: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + URL_PW: "${{ env.PW }}/patches/?project=mptcp&msgid=" + + status: + name: "Status" + needs: checkpatch + # for others, to report an error if patches were not OK + if: github.repository_owner != 'multipath-tcp' + runs-on: ubuntu-latest + steps: + - name: "Get Results" + uses: actions/download-artifact@v4 + with: + name: results + + - name: "Set exit status" + run: | + # $1: result file, $2: context + check() { + if [ ! -s "${1}" ]; then + echo "Strange, no results, please check why" + exit 1 + fi + + if awk '{ if ($2 != "success") exit 1 }' "${1}"; then + echo " *** Everything OK with ${2}, good job!" + return 0 + fi + + echo " *** ${2} detected some issues:" + cat "${1}" + echo " *** End of the issues detected by ${2}" + + return 1 + } + + echo + rc=0 + check "${CHECKPATCH_RESULTS}" "CheckPatch" || rc=1 + check "${SHELLCHECK_RESULTS}" "ShellCheck" || rc=1 + [ ${rc} -eq 0 ] && exit 0 + + echo + echo "Please check the summary page for more details about these issues:" + echo " ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + exit ${rc} diff --git a/.github/workflows/notif.yml b/.github/workflows/notif.yml new file mode 100644 index 0000000000000..c4ca514ec0cbd --- /dev/null +++ b/.github/workflows/notif.yml @@ -0,0 +1,56 @@ +name: "Notifications" +on: + push: + tags: + - 'export/**' # exclude patchew/** tags and branches + - 'export-net/**' + issues: + types: [opened, reopened, closed, assigned, unassigned] + +permissions: {} + +jobs: + tag: + name: "Tag" + if: github.repository_owner == 'multipath-tcp' && github.event_name == 'push' + runs-on: ubuntu-latest + steps: + - name: tag shortner + id: tag + run: | + echo "tag=${REF:10}" >> ${GITHUB_OUTPUT} + env: + REF: ${{ github.event.ref }} + - name: irc tag + uses: rectalogic/notify-irc@v2 + with: + server: irc.libera.chat + channel: "#mptcp-ci" + nickname: gh-tag-bot + verbose: true + message: "New tag available: ${{ steps.tag.outputs.tag }} (by ${{ github.actor }})" + + issues: + name: "Issues" + if: github.repository_owner == 'multipath-tcp' && github.event_name == 'issues' + runs-on: ubuntu-latest + steps: + - name: issue info + id: info + if: github.event.action != 'opened' + run: | + echo "opener=, opened by ${OPENER}" >> ${GITHUB_OUTPUT} + echo "assignee=${ASSIGNEE:+ and assigned to ${ASSIGNEE}}" >> ${GITHUB_OUTPUT} + env: + OPENER: ${{ github.event.issue.user.login }} + ASSIGNEE: ${{ github.event.assignee.login }} + - name: irc issues + uses: rectalogic/notify-irc@v2 + with: + server: irc.libera.chat + channel: "#mptcp" + nickname: gh-issues-bot + verbose: true + message: |- + Issue #${{ github.event.issue.number }} ("${{ github.event.issue.title }}"${{ steps.info.outputs.opener }}${{ steps.info.outputs.assignee }}) has been ${{ github.event.action }} by ${{ github.actor }} + ${{ github.event.issue.html_url }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000000000..399377da967c3 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,562 @@ +name: "MPTCP Upstream Tests Validation" +on: + push: + branches-ignore: + - 'archived/**' # previous branches + - 't/**' # TopGit tree + - 'net' # part of the TopGit tree + - 'net-next' # part of the TopGit tree + - 'for-review' # part of the TopGit tree + - 'for-review-net' # part of the TopGit tree + tags: + - 'patchew/**' # patchew is using tags + # ideally, we would take 'export/**' but the cache is per branch... + # In other words, when using tags, we can only use the cache if we re-tag. + # https://github.com/actions/cache/issues/556 + # So we test the "export" branch and we try to find the tag later + +env: + CURL_OPT: "--no-progress-meter --connect-timeout 30 --retry 20 --retry-delay 10" + CURL_ACC: "Accept: application/vnd.github.v3+json" + URI: "https://api.github.com" + PW: "https://patchwork.kernel.org/api/1.2" + +permissions: {} + +jobs: + tests: + name: "Tests" + if: "! startswith(github.ref, 'refs/tags/patchew/') || contains(github.event.head_commit.message, 'Message-Id: ')" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + mode: ['normal', 'debug', 'btf-normal', 'btf-debug'] + permissions: + contents: read # to fetch code (actions/checkout) + + steps: + - name: "Checkout" + uses: actions/checkout@v4 + + #- name: "Collect Workflow Telemetry" + # uses: catchpoint/workflow-telemetry-action@v2 + + - name: "Find base branch" + id: branch + run: | + if [ "$(cat .git_markup)" = "MPTCP-related modifications only needed for our tests suite (mptcp-net)." ]; then + echo "name=export-net" >> ${GITHUB_OUTPUT} + else + echo "name=export" >> ${GITHUB_OUTPUT} + fi + + mode="${{ matrix.mode }}" + echo "mode=${mode//-/_}" >> ${GITHUB_OUTPUT} + + - name: "Restore cache for CCache" + uses: actions/cache/restore@v4 + id: restore-ccache + with: + path: ${{ github.workspace }}/.virtme/ccache + key: ${{ runner.os }}_tests_${{ steps.branch.outputs.name }}-${{ steps.branch.outputs.mode }}-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}_tests_${{ steps.branch.outputs.name }}-${{ steps.branch.outputs.mode }}-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.sha }} + ${{ runner.os }}_tests_${{ steps.branch.outputs.name }}-${{ steps.branch.outputs.mode }}-${{ github.run_id }}-${{ github.run_attempt }}- + ${{ runner.os }}_tests_${{ steps.branch.outputs.name }}-${{ steps.branch.outputs.mode }}-${{ github.run_id }}- + ${{ runner.os }}_tests_${{ steps.branch.outputs.name }}-${{ steps.branch.outputs.mode }}- + ${{ runner.os }}_tests_${{ steps.branch.outputs.name }}- + + - name: "Docker image" + run: | + /usr/bin/docker pull ghcr.io/multipath-tcp/mptcp-upstream-virtme-docker:${{ steps.branch.outputs.name == 'export' && 'latest' || 'net' }} + + - name: "Tests" + timeout-minutes: 120 + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + # remove old cache if any + rm -rvf "${{ github.workspace }}/.virtme/ccache-"* 2>/dev/null + + set -x + /usr/bin/docker run --privileged --rm \ + -e "INPUT_CCACHE_MAXSIZE=500M" \ + -e "INPUT_CCACHE_DIR=ccache" \ + -e "INPUT_PACKETDRILL_STABLE=${{ steps.branch.outputs.name == 'export-net' && '1' || '0' }}" \ + -e "INPUT_EXTRA_ENV=${{ startsWith(matrix.mode, 'btf-') && 'INPUT_RUN_TESTS_ONLY=bpftest_all' || '' }}" \ + -e "INPUT_TRACE=${RUNNER_DEBUG}" \ + -e "INPUT_GCOV=1" \ + -e "GITHUB_SHA" -e "GITHUB_REF_NAME" -e "GITHUB_RUN_ID" \ + -e GITHUB_ACTIONS=true -e CI=true \ + --workdir "${PWD}" \ + -v "${PWD}:${PWD}" \ + ghcr.io/multipath-tcp/mptcp-upstream-virtme-docker:${{ steps.branch.outputs.name == 'export' && 'latest' || 'net' }} \ + auto-${{ matrix.mode }} + + - name: "Publish conclusion" + if: always() + run: | + set +e + if [ -s "conclusion.txt" ]; then + { + echo '## Mode ${{ matrix.mode }}' + echo '### Conclusion (${{ matrix.mode }})' + cat "conclusion.txt" + echo '' + echo '### Summary (${{ matrix.mode }})' + echo '```' + cat "summary.txt" + echo '```' + echo '' + echo '### Coverage (${{ matrix.mode }})' + echo '```' + cat "coverage.txt" || echo "No coverage" + echo '```' + } >> "${GITHUB_STEP_SUMMARY}" + fi + touch kernel.lcov || true + + - name: "Artifacts (always)" + if: always() + uses: actions/upload-artifact@v4 + with: + name: results-${{ matrix.mode }} + path: | + conclusion.txt + summary.txt + coverage.txt + *.tap + config.zstd + *.tap.xml + results.json + + - name: "Artifacts (failure)" + if: failure() + uses: actions/upload-artifact@v4 + with: + name: debug-info-${{ matrix.mode }} + path: | + vmlinux.zstd + kmemleak.txt + + - name: "Artifacts (LCov)" + uses: actions/upload-artifact@v4 + with: + name: lcov-${{ matrix.mode }} + compression-level: 9 + path: | + kernel.lcov + + - name: "Artifacts (code)" + uses: actions/upload-artifact@v4 + if: github.repository_owner == 'multipath-tcp' && matrix.mode == 'normal' && (github.ref_name == 'export' || github.ref_name == 'export-net') + with: + name: code + compression-level: 9 + path: | + net/mptcp/*.[ch] + + - name: Coveralls Parallel + uses: coverallsapp/github-action@v2 + if: always() && (github.repository_owner != 'multipath-tcp' || github.ref_name == 'export' || github.ref_name == 'export-net') + with: + flag-name: ${{ matrix.mode }} + parallel: true + file: kernel.lcov + format: lcov + allow-empty: true + compare-ref: ${{ steps.branch.outputs.name }} + + - name: "Publish Test Results" + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + compare_to_earlier_commit: false + check_run: false + check_name: "Test Results (${{ matrix.mode }})" + files: | + *.tap.xml + + - name: "Save cache for CCache" + if: always() && (github.repository_owner != 'multipath-tcp' || github.ref_name == 'export' || github.ref_name == 'export-net') + uses: actions/cache/save@v4 + with: + path: ${{ github.workspace }}/.virtme/ccache + key: ${{ steps.restore-ccache.outputs.cache-primary-key }} + + publish-test-results: + name: "Publish Tests Results" + needs: tests + if: always() + runs-on: ubuntu-latest + permissions: + checks: write + + steps: + - name: "Get results" + uses: actions/download-artifact@v4 + with: + pattern: results-* + merge-multiple: false + + - name: "Publish Test Results" + uses: EnricoMi/publish-unit-test-result-action@v2 + with: + check_run_annotations_branch: "${{ steps.branch.outputs.name }}" + files: | + results-*/*.tap.xml + + - name: Coveralls Finished + uses: coverallsapp/github-action@v2 + if: github.repository_owner != 'multipath-tcp' || github.ref_name == 'export' || github.ref_name == 'export-net' + with: + parallel-finished: true + carryforward: "normal,debug,btf-normal,btf-debug" + + notif: + name: "Notifications" + needs: tests + # only for the official repo (patchew and export) + if: always() && github.repository_owner == 'multipath-tcp' && (needs.tests.result == 'success' || needs.tests.result == 'failure') + concurrency: + group: ${{ startswith(github.ref, 'refs/heads/export') && 'ci-notif' || github.sha }} + cancel-in-progress: false + runs-on: ubuntu-latest + steps: + - name: get results + uses: actions/download-artifact@v4 + with: + pattern: results-* + merge-multiple: false + + - name: get test info + id: test + run: | + for mode in normal debug btf-normal btf-debug; do + ccl="$(cat "results-${mode}/conclusion.txt")" + echo "ccl_${mode//-/_}=${ccl:-"KVM Validation: ${mode}: Critical: No conclusion ❓"}" >> ${GITHUB_OUTPUT} + echo "ccl_title_${mode//-/_}=$(echo "${ccl}" | cut -d: -f1-2)" >> ${GITHUB_OUTPUT} + echo "ccl_status_${mode//-/_}=$(echo "${ccl}" | cut -d: -f3- | sed 's/^ //')" >> ${GITHUB_OUTPUT} + done + echo "url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> ${GITHUB_OUTPUT} + + - name: get linked tag + if: github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net' + id: tag + run: | + TAG=$(curl ${CURL_OPT} -H "${CURL_ACC}" -H "${CURL_AUTH}" "${URL}" | jq -r ".[] | select(.object.sha == \"${SHA}\").ref" | grep "^refs/tags/export" | tail -n1) + echo "Found: ${TAG} (${SHA} - ${BRANCH})" + TAG="${TAG:10}" + echo "tag=${TAG:-${BRANCH}}" >> ${GITHUB_OUTPUT} + env: + CURL_AUTH: "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" + URL: "${{ env.URI }}/repos/${{ github.repository }}/git/matching-refs/tags/" + SHA: "${{ github.sha }}" + BRANCH: "${{ github.ref_name }}" + + - name: irc tests + if: github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net' + uses: rectalogic/notify-irc@v2 + with: + server: irc.libera.chat + channel: "#mptcp-ci" + nickname: gh-tests-bot + verbose: true + message: |- + New GH Actions Tests job validating ${{ steps.tag.outputs.tag }} (by ${{ github.actor }}) just ended: + - ${{ steps.test.outputs.ccl_normal }} + - ${{ steps.test.outputs.ccl_debug }} + - ${{ steps.test.outputs.ccl_btf_normal }} + - ${{ steps.test.outputs.ccl_btf_debug }} + - Task: ${{ steps.test.outputs.url }} + + - name: Checkout results repo + if: github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net' + uses: actions/checkout@v4 + with: + repository: "multipath-tcp/mptcp-upstream-tests-results" + token: '${{ secrets.PAT_MATTTBE }}' + path: results + + - name: setup results repo + if: github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net' + run: | + cd results + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: save flakes results + if: github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net' + run: | + for mode in normal debug btf-normal btf-debug; do + new="results-${mode}/results.json" + all="results/html/results/${{ github.ref_name }}/${mode}.json" + if [ ! -s "${new}" ]; then + echo '{"error": "all", "run_id": "${{ github.run_id }}"}' > "${new}" + fi + # append tag, merge results, limit + jq -c '.tag += "${{ steps.tag.outputs.tag }}"' "${new}" > "${new}.tag" + jq -c '. += [input]' "${all}" "${new}.tag" > "${new}.all" + jq --indent 1 '.[-100:]' "${new}.all" > "${all}" + done + + cd results + git add html/results/${{ github.ref_name }}/*.json + git commit -m "json: new: ${{ steps.tag.outputs.tag }}" + + - name: get lcov + if: needs.tests.result == 'success' && (github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net') + uses: actions/download-artifact@v4 + with: + pattern: lcov-* + merge-multiple: false + + - name: get code + if: needs.tests.result == 'success' && (github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net') + uses: actions/download-artifact@v4 + with: + name: code + path: net/mptcp + + - name: lcov to html and publish results + if: needs.tests.result == 'success' && (github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net') + run: | + out="results/html/lcov/${{ github.ref_name }}" + rm -rf "${out}" + mkdir -p "${out}" + /usr/bin/docker run --pull always --rm \ + --workdir "${PWD}" \ + -v "${PWD}:${PWD}" \ + mptcp/docker-lcov-alpine:latest \ + genhtml -j "$(nproc)" -t "${{ github.ref_name }}" \ + --dark-mode --legend \ + --include '/net/mptcp/' --flat \ + --function-coverage --branch-coverage --keep-going \ + -o "${out}" lcov-*/kernel.lcov | tee genhtml.log + + { + echo '' + echo '## Coverage (All)' + echo '```' + tail -n4 genhtml.log + echo '```' + } >> "${GITHUB_STEP_SUMMARY}" + + cd results + git add html/lcov/${{ github.ref_name }} + git commit -m "lcov: new: ${{ steps.tag.outputs.tag }}" || true + + - name: push results + if: github.ref == 'refs/heads/export' || github.ref == 'refs/heads/export-net' + run: | + cd results + git push + + - name: get commit info + id: commit + if: startswith(github.ref, 'refs/tags/patchew/') + run: | + cat <<'EOF' > commit.json + ${{ toJSON(github.event.head_commit) }} + EOF + + # ignore error, just in case the MID has not been added by the author + read -r TAG MID < <(jq -r '.message' commit.json | grep -i "^Message-Id: " | tail -n1) || true + echo "Found message ID: '${TAG}' '${MID}'" + echo "mid=${MID:1:-1}" >> ${GITHUB_OUTPUT} + + # Guess the subject from the last commit + SUBJECT=$(jq -r '.message' commit.json | head -n1) + echo "Found subject: '${SUBJECT}'" + echo "subject=${SUBJECT}" >> ${GITHUB_OUTPUT} + + NAME=$(jq -r '.author.name' commit.json) + EMAIL=$(jq -r '.author.email' commit.json) + echo "Found author: '${NAME}' '${EMAIL}'" + echo "name=${NAME%% *}" >> ${GITHUB_OUTPUT} + echo "author=${NAME} <${EMAIL}>" >> ${GITHUB_OUTPUT} + + SHA=$(jq -r '.id' commit.json) + echo "Found SHA: '${SHA}' ('${SHA:0:12}')" + echo "sha=${SHA:0:12}" >> ${GITHUB_OUTPUT} + + COMMITTER=$(jq -r '.committer.name' commit.json) + echo "Found committer: '${COMMITTER}'" + echo "committer=${COMMITTER}" >> ${GITHUB_OUTPUT} + + - name: set patchwork check + if: startswith(github.ref, 'refs/tags/patchew/') + run: | + CHECK_URLS=() + set_url() { local series_url + series_url=$(curl ${CURL_OPT} "${URL}" | jq -r 'last(last(.[].series)[].url)') + if [ -z "${series_url}" ] || [ "${series_url}" = "null" ]; then + echo "Series not found: '${series_url}' '${URL}'" + return 1 + fi + + echo "Found Series: '${series_url}'" + + readarray -t CHECK_URLS < <(curl ${CURL_OPT} "${series_url}" | jq -r '.patches[].url + "checks/"') + } + + # $1: title, $2: status, $3: url + submit() { local check_url + if [[ "${2}" == "Success"* ]]; then + STATE="success" + elif [[ "${2}" == "Unstable"* ]]; then + STATE="warning" + else + STATE="fail" + fi + + for check_url in "${CHECK_URLS[@]}"; do + curl ${CURL_OPT} \ + -X POST \ + -H "Authorization: Token ${{ secrets.PW_TOKEN }}" \ + -F "state=${STATE}" \ + -F "target_url=${3}" \ + -F "context=${1//[ :()]/_}" \ + -F "description=${2}" \ + "${check_url}" | jq '.' + done + } + + for i in $(seq 30); do # patches can take a bit of time to appear + set_url && break + sleep 1m + done + + if [ "${#CHECK_URLS[@]}" -eq 0 ]; then + echo "Error: didn't find any URLs after ${i} attempts" + exit 1 + fi + echo "Found: ${#CHECK_URLS[@]} urls after ${i} attempts: ${CHECK_URLS[@]}" + + submit "${{ steps.test.outputs.ccl_title_normal }}" "${{ steps.test.outputs.ccl_status_normal }}" "${{ steps.test.outputs.url }}" + submit "${{ steps.test.outputs.ccl_title_debug }}" "${{ steps.test.outputs.ccl_status_debug }}" "${{ steps.test.outputs.url }}" + submit "${{ steps.test.outputs.ccl_title_btf_normal }}" "${{ steps.test.outputs.ccl_status_btf_normal }}" "${{ steps.test.outputs.url }}" + submit "${{ steps.test.outputs.ccl_title_btf_debug }}" "${{ steps.test.outputs.ccl_status_btf_debug }}" "${{ steps.test.outputs.url }}" + env: + URL: "${{ env.PW }}/patches/?project=mptcp&msgid=${{ steps.commit.outputs.mid }}" + + # do that after having set patchwork checks, so we already waited for it to be ready + - name: get series info + id: series + if: startswith(github.ref, 'refs/tags/patchew/') + run: | + if [ -n "${MID:1:-1}" ]; then + # get cover-letter and series' name if any + URL_PW_SERIES_API=$(curl "${URL_PW}${MID:1:-1}" | jq -er 'last(last(.[].series)[].url)' || true) + if [ -n "${URL_PW_SERIES_API}" ] && [ "${URL_PW_SERIES_API}" != "null" ]; then + echo "series=${URL_PW_SERIES}$(basename "${URL_PW_SERIES_API}")" >> ${GITHUB_OUTPUT} + if curl "${URL_PW_SERIES_API}" > pw_series.json && [ -s pw_series.json ]; then + CL="$(jq '.cover_letter' pw_series.json || true)" + if [ -n "${CL}" ] && [ "${CL}" != "null" ] && [ "${CL}" != "{}" ]; then + MID=$(echo "${CL}" | jq -er '.msgid' || echo "${MID}") + SUBJECT=$(jq -er '.name' pw_series.json || echo "${SUBJECT}") + fi + fi + fi + # get tags from Lore: not fully available from Patchwork + SUBJECT="$(curl "${URL_LORE//MID/${MID:1:-1}}" | grep '^Subject: ' | head -n1 | sed 's/^Subject: \(\[.*\] \).*/\1/')${SUBJECT}" + fi + + echo "Found message ID: '${MID}'" + echo "mid=${MID:1:-1}" >> ${GITHUB_OUTPUT} + echo "Found subject: '${SUBJECT}'" + echo "subject=${SUBJECT}" >> ${GITHUB_OUTPUT} + env: + URL_PW: "${{ env.PW }}/patches/?project=mptcp&msgid=" + URL_PW_SERIES: "https://patchwork.kernel.org/project/mptcp/list/?series=" + URL_LORE: "https://lore.kernel.org/mptcp/MID/raw" + MID: "<${{ steps.commit.outputs.mid }}>" + SUBJECT: "${{ steps.commit.outputs.subject }}" + + - name: send email + if: startswith(github.ref, 'refs/tags/patchew/') + uses: dawidd6/action-send-mail@v3 + with: + server_address: smtp.gmail.com + server_port: 465 + username: ${{ secrets.MAIL_USERNAME }} + password: ${{ secrets.MAIL_PASSWORD }} + to: ${{ steps.commit.outputs.author }} + cc: mptcp@lists.linux.dev + from: MPTCP CI + reply_to: mptcp@lists.linux.dev + in_reply_to: "<${{ steps.series.outputs.mid }}>" + subject: "Re: ${{ steps.series.outputs.subject }}" + body: | + Hi ${{ steps.commit.outputs.name }}, + + Thank you for your modifications, that's great! + + Our CI did some validations and here is its report: + + - ${{ steps.test.outputs.ccl_title_normal }}: ${{ steps.test.outputs.ccl_status_normal }} + - ${{ steps.test.outputs.ccl_title_debug }}: ${{ steps.test.outputs.ccl_status_debug }} + - ${{ steps.test.outputs.ccl_title_btf_normal }}: ${{ steps.test.outputs.ccl_status_btf_normal }} + - ${{ steps.test.outputs.ccl_title_btf_debug }}: ${{ steps.test.outputs.ccl_status_btf_debug }} + - Task: ${{ steps.test.outputs.url }} + + Initiator: ${{ steps.commit.outputs.committer }} + Commits: ${{ github.server_url }}/${{ github.repository }}/commits/${{ steps.commit.outputs.sha }} + Patchwork: ${{ steps.series.outputs.series }} + + + If there are some issues, you can reproduce them using the same environment as + the one used by the CI thanks to a docker image, e.g.: + + $ cd [kernel source code] + $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \ + --pull always mptcp/mptcp-upstream-virtme-docker:latest \ + auto-normal + + For more details: + + https://github.com/multipath-tcp/mptcp-upstream-virtme-docker + + + Please note that despite all the efforts that have been already done to have a + stable tests suite when executed on a public CI like here, it is possible some + reported issues are not due to your modifications. Still, do not hesitate to + help us improve that ;-) + + Cheers, + MPTCP GH Action bot + Bot operated by Matthieu Baerts (NGI0 Core) + + status: + name: "Status" + needs: tests + # only for the non official repos + if: always() && github.repository_owner != 'multipath-tcp' + runs-on: ubuntu-latest + steps: + - name: Get Results + uses: actions/download-artifact@v4 + with: + pattern: results-* + merge-multiple: false + + - name: Check Status + run: | + issues=() + for mode in normal debug btf-normal btf-debug; do + ccl="results-${mode}/conclusion.txt" + if [ ! -f "${ccl}" ] || ! grep -q "Success" "${ccl}"; then + issues+=("${mode}") + fi + done + if [ ${#issues[@]} -eq 0 ]; then + echo "Great, no issues!" + exit 0 + fi + echo "Issues have been found during the tests in: ${issues[*]}." + echo "Please check the summary page for more details:" + echo " ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + exit 1 diff --git a/.github/workflows/update-tg-tree.yml b/.github/workflows/update-tg-tree.yml new file mode 100644 index 0000000000000..767de620ee2cf --- /dev/null +++ b/.github/workflows/update-tg-tree.yml @@ -0,0 +1,54 @@ +name: "Update TopGit tree" + +on: + workflow_dispatch: + inputs: + keep_base_untouched: + description: 'Set it to 1 to force a sync without updating the base from upstream' + required: true + default: '0' + force_sync: + description: 'Set it to 1 to force a sync even if net-next is not updated' + required: true + default: '0' + force_upd_net: + description: 'Set it to 1 to force updating the -net base with upstream instead of the merge-base with net-next' + required: true + default: '1' + + schedule: + - cron: '33 5 * * 1-5' # in UTC: after US West coast's work day + +permissions: {} + +jobs: + export: + if: github.repository_owner == 'multipath-tcp' + runs-on: ubuntu-latest + permissions: + contents: write # for git push (multipath-tcp/mptcp-upstream-topgit-action) + + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 # we need all commits for TopGit + token: '${{ secrets.PAT_MATTTBE }}' + + - name: "Update TG tree" + uses: multipath-tcp/mptcp-upstream-topgit-action@main + with: + not_base: "${{ github.event.inputs.keep_base_untouched || '0' }}" + force_sync: "${{ github.event.inputs.force_sync || '0' }}" + force_upd_net: "${{ github.event.inputs.force_upd_net || '1' }}" + + - name: irc topgit + if: failure() && github.repository_owner == 'multipath-tcp' + uses: rectalogic/notify-irc@v2 + with: + server: irc.libera.chat + channel: "#mptcp" + nickname: gh-topgit-bot + verbose: true + message: |- + New sync with latest net and net-next failed (initiated by ${{ github.actor }}): ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000000..bcf5c945a0a8d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,17 @@ +# Security Policy + +## Supported Versions + +The ones mentioned on [kernel.org](https://www.kernel.org). + +## Reporting a Vulnerability + +Please report any issues to us, either via +[GitHub](https://github.com/multipath-tcp/mptcp_net-next/security/advisories/new), +or via emails to the MPTCP maintainers: + + - Matthieu Baerts + - Mat Martineau + +(Check the [MAINTAINERS](https://github.com/multipath-tcp/mptcp_net-next/blob/export/MAINTAINERS) +file to get the up-to-date list.)