Skip to content

docs: Update projects #41

docs: Update projects

docs: Update projects #41

# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# This workflow is based on the `build-linux-wheel` job of
# https://github.com/mitmproxy/mitmproxy_rs/blob/v0.12.11/.github/workflows/ci.yml
name: Build mitmproxy-linux wheels (riscv64)
on:
workflow_dispatch:
inputs:
version:
description: 'Version glob to (re)build; empty builds every version of docs/packages/mitmproxy-linux.yaml not released yet'
required: false
default: ''
pull_request:
branches: [main]
paths:
- '.github/workflows/build-mitmproxy-linux.yml'
- 'docs/packages/mitmproxy-linux.yaml'
push:
branches: [main]
paths:
- '.github/workflows/build-mitmproxy-linux.yml'
- 'docs/packages/mitmproxy-linux.yaml'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
setup:
uses: $/.github/workflows/_setup.yml
with:
package: mitmproxy-linux
version: ${{ inputs.version }}
build_ebpf:
needs: [setup]
if: needs.setup.outputs.versions != '[]'
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
# bpf-linker calls LLVM through the shared library the Rust toolchain ships,
# which riscv64 toolchains do not carry, and the newest LLVM packaged for
# riscv64 is older than this release's MSRV emits bitcode for. The object is
# architecture-independent BPF bytecode apart from the bpf_target_arch cfg,
# so it is cross-compiled here and embedded by patch 0001.
name: Cross-compile mitmproxy-linux ${{ matrix.version }} eBPF object
runs-on: ubuntu-latest
timeout-minutes: 60
env:
MITMPROXY_LINUX_VERSION: ${{ matrix.version }}
steps:
- name: Checkout mitmproxy_rs v${{ env.MITMPROXY_LINUX_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: mitmproxy/mitmproxy_rs
ref: v${{ env.MITMPROXY_LINUX_VERSION }}
persist-credentials: false
- name: Install the nightly toolchain and bpf-linker
run: |
rustup toolchain install nightly --profile minimal --component rust-src
cargo install --locked bpf-linker@0.9.15
- name: Build the eBPF object
# The flags aya_build::build_ebpf passes, with bpf_target_arch set for
# the wheel's architecture rather than this runner's.
run: |
env -u RUSTC -u RUSTC_WORKSPACE_WRAPPER \
CARGO_ENCODED_RUSTFLAGS=$'--cfg=bpf_target_arch="riscv64"\x1f-Cdebuginfo=2\x1f-Clink-arg=--btf' \
rustup run nightly cargo build --package mitmproxy-linux-ebpf --bins \
--release --target bpfel-unknown-none -Z build-std=core
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: mitmproxy-linux-${{ env.MITMPROXY_LINUX_VERSION }}-ebpf-object
path: target/bpfel-unknown-none/release/mitmproxy-linux
if-no-files-found: error
build_wheel:
needs: [setup, build_ebpf]
if: needs.setup.outputs.versions != '[]'
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
name: Build mitmproxy-linux ${{ matrix.version }} manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 1440
env:
MITMPROXY_LINUX_VERSION: ${{ matrix.version }}
steps:
- name: Checkout mitmproxy_rs v${{ env.MITMPROXY_LINUX_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: mitmproxy/mitmproxy_rs
ref: v${{ env.MITMPROXY_LINUX_VERSION }}
persist-credentials: false
- name: Checkout python-wheels
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: python-wheels
persist-credentials: false
- name: Patch mitmproxy_rs source
run: git apply python-wheels/patches/mitmproxy-linux/${{ env.MITMPROXY_LINUX_VERSION }}/00*.patch
- name: Download the eBPF object
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: mitmproxy-linux-${{ env.MITMPROXY_LINUX_VERSION }}-ebpf-object
path: ebpf-prebuilt
- name: Stage the licence beside mitmproxy-linux's pyproject.toml
# maturin globs LICEN[CS]E* relative to the pyproject directory, which
# in this monorepo is mitmproxy-linux/ -- so upstream's own aarch64
# wheel ships no licence text at all.
run: cp LICENSE mitmproxy-linux/
# `[tool.maturin] bindings = "bin"`: the wheel is one compiled executable
# with no ABI tag, so a single native build covers every interpreter.
- name: Build wheel
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
with:
command: build
target: riscv64gc-unknown-linux-gnu
args: --release --locked --out dist --manifest-path mitmproxy-linux/Cargo.toml
manylinux: '2_39'
before-script-linux: |
git config --global --add safe.directory "*"
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: mitmproxy-linux-${{ env.MITMPROXY_LINUX_VERSION }}-manylinux_riscv64
path: dist/*.whl
if-no-files-found: error
test_wheel:
name: Test mitmproxy-linux ${{ matrix.version }} on Python ${{ matrix.python-version }}
needs: [setup, build_wheel]
if: needs.setup.outputs.versions != '[]'
runs-on: ubuntu-24.04-riscv
timeout-minutes: 30
env:
MITMPROXY_LINUX_VERSION: ${{ matrix.version }}
# Without this uv would reuse the runner image's system CPython for 3.12
# and download a standalone build for the others.
UV_PYTHON_PREFERENCE: only-managed
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
# The wheel is interpreter-agnostic (bindings = "bin"), so every
# interpreter exercises the same binary.
python-version: ['3.12', '3.13', '3.14', '3.14t']
steps:
- name: Download wheel
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: mitmproxy-linux-${{ env.MITMPROXY_LINUX_VERSION }}-manylinux_riscv64
- name: Install Python
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
python-version: ${{ matrix.python-version }}
activate-environment: true
enable-cache: false
- name: Install wheel
run: uv pip install --reinstall --no-index --find-links . mitmproxy_linux
# The redirector needs root, a tun device and cgroup eBPF attach, so it
# cannot be driven end to end here (upstream gates that behind its own
# `root-tests` feature). Assert instead that the eBPF object its build.rs
# cross-compiles to bpfel-unknown-none really is embedded in the riscv64
# executable -- loading it is all the binary does.
- name: Test wheel
run: |
set -euo pipefail
cat > verify.py <<'EOF'
import struct
import subprocess
import sys
from mitmproxy_linux import executable_path
exe = executable_path()
assert exe.is_file(), exe
buf = exe.read_bytes()
assert buf[:6] == b"\x7fELF\x02\x01", buf[:6]
(machine,) = struct.unpack_from("<H", buf, 18)
assert machine == 243, f"redirector is not riscv64: e_machine={machine}"
pos = 0
while True:
pos = buf.find(b"\x7fELF\x02\x01\x01", pos + 1)
assert pos > 0, "no embedded eBPF object in the redirector"
if struct.unpack_from("<H", buf, pos + 18)[0] == 247:
break
(shoff,) = struct.unpack_from("<Q", buf, pos + 0x28)
shentsize, shnum, shstrndx = struct.unpack_from("<HHH", buf, pos + 0x3A)
base = pos + shoff
(strtab,) = struct.unpack_from("<Q", buf, base + shstrndx * shentsize + 0x18)
names = []
for i in range(shnum):
(name,) = struct.unpack_from("<I", buf, base + i * shentsize)
start = pos + strtab + name
names.append(buf[start:buf.index(b"\0", start)].decode())
print("eBPF sections:", [n for n in names if n])
assert "cgroup/sock_create" in names, names
assert b"INTERCEPT_CONF" in buf[pos:], "INTERCEPT_CONF map missing"
run = subprocess.run([exe], capture_output=True, text=True, timeout=60)
print(run.stderr, file=sys.stderr)
assert run.returncode != 0, run
assert "usage:" in run.stderr, run.stderr
EOF
python verify.py
publish:
name: Publish mitmproxy-linux ${{ matrix.version }}
needs: [setup, build_wheel, test_wheel]
if: needs.setup.outputs.versions != '[]'
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
permissions:
contents: write
pull-requests: write
uses: $/.github/workflows/_publish-wheel.yml
secrets:
app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }}
with:
artifact-pattern: mitmproxy-linux-${{ matrix.version }}-manylinux_riscv64