Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 201 additions & 53 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,18 @@ jobs:
cache-hit: ${{ steps.cache-plugin.outputs.cache-hit }}
steps:
- uses: actions/checkout@v4
- name: Cache protoc plugin
- name: Cache protoc and plugin
id: cache-plugin
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/protoc-plugin
# The key changes only when plugin source files change
key: ${{ runner.os }}-protoc-plugin-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/.bazelrc', 'protoc-gen-rust-grpc/MODULE.bazel') }}
- name: Install Bazel
# The key changes only when plugin source files or CMake files change
key: ${{ runner.os }}-protoc-plugin-cmake-v4-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/CMakeLists.txt', 'protoc-gen-rust-grpc/cmake/**') }}
- name: Install CMake
if: steps.cache-plugin.outputs.cache-hit != 'true'
uses: bazel-contrib/setup-bazel@0.15.0
uses: lukka/get-cmake@latest
with:
# Avoid downloading Bazel every time.
bazelisk-cache: true
# Store build cache per workflow.
disk-cache: ${{ github.workflow }}
# Share repository cache between workflows.
repository-cache: true
module-root: ./protoc-gen-rust-grpc
cmakeVersion: "~3.28.0"
# Building the protoc plugin from scratch takes 6–14 minutes, depending on
# the OS. This delays the execution of workflows that use the plugin in
# build.rs files. We try to avoid rebuilding the plugin if it hasn't
Expand All @@ -62,17 +56,100 @@ jobs:
shell: bash
run: |
set -e
# On windows, the "//src" gets converted to "/". Disable this path
# conversion.
export MSYS_NO_PATHCONV=1
export MSYS2_ARG_CONV_EXCL="*"
# Create build directory
mkdir -p build
cd build

bazel build //src:protoc-gen-rust-grpc --enable_platform_specific_config
# Configure with CMake
cmake .. -DCMAKE_BUILD_TYPE=Release -DPROTOBUF_VERSION=32.0

# Build with limited parallelism to avoid OOM
cmake --build . --parallel 2

# The target path needs to match the cache config.
TARGET_PATH="${{ runner.temp }}/protoc-plugin"
mkdir -p "${TARGET_PATH}"
cp bazel-bin/src/protoc-gen-rust-grpc "${TARGET_PATH}"

# Copy both protoc and the plugin
# First, find and copy protoc
PROTOC_FOUND=false
for protoc_path in "bin/protoc" "bin/protoc.exe" "bin/Release/protoc.exe" "bin/Debug/protoc.exe" "_deps/protobuf-build/protoc" "_deps/protobuf-build/protoc.exe" "_deps/protobuf-build/Release/protoc.exe" "_deps/protobuf-build/Debug/protoc.exe"; do
if [ -f "$protoc_path" ]; then
echo "Found protoc at: $protoc_path"
# Copy with explicit name to ensure it's called 'protoc' or 'protoc.exe'
if [[ "$protoc_path" == *.exe ]]; then
cp "$protoc_path" "${TARGET_PATH}/protoc.exe"
echo "Copied to: ${TARGET_PATH}/protoc.exe"
else
cp "$protoc_path" "${TARGET_PATH}/protoc"
chmod +x "${TARGET_PATH}/protoc"
echo "Copied to: ${TARGET_PATH}/protoc"
fi
PROTOC_FOUND=true
break
fi
done

if [ "$PROTOC_FOUND" = "false" ]; then
echo "Error: protoc not found in expected locations"
echo "Searching for protoc in build directory:"
find . -name "protoc" -o -name "protoc.exe" | head -20
exit 1
fi

# Copy protoc with its standard installation structure
echo "Setting up protoc installation..."

# protoc expects to find includes relative to its binary location
# Standard structure: bin/protoc and include/google/protobuf/*.proto

# First check if CMake created an install directory
if [ -d "install" ] && [ -f "install/bin/protoc" -o -f "install/bin/protoc.exe" ]; then
echo "Found CMake install directory"
cp -r install/* "${TARGET_PATH}/"
else
# Manual setup if no install directory
echo "Creating manual protoc installation structure..."

# The protoc binary should already be copied to TARGET_PATH
# Now find and copy the include files to the correct relative location
mkdir -p "${TARGET_PATH}/include"

# Find the protobuf include files
INCLUDE_FOUND=false
for include_path in "_deps/protobuf-src/src" "_deps/protobuf-build/include" "include"; do
if [ -d "$include_path/google/protobuf" ] && [ -f "$include_path/google/protobuf/descriptor.proto" ]; then
echo "Found protobuf includes at: $include_path"
cp -r "$include_path/google" "${TARGET_PATH}/include/"
INCLUDE_FOUND=true
break
fi
done

if [ "$INCLUDE_FOUND" = "false" ]; then
echo "Warning: Could not find protobuf include files"
echo "Searching for descriptor.proto:"
find . -name "descriptor.proto" -type f | grep -v "test" | head -10
fi
fi

# Then copy the plugin (handle different output locations)
if [ -f "bin/protoc-gen-rust-grpc" ]; then
cp bin/protoc-gen-rust-grpc "${TARGET_PATH}/"
elif [ -f "bin/protoc-gen-rust-grpc.exe" ]; then
cp bin/protoc-gen-rust-grpc.exe "${TARGET_PATH}/"
elif [ -f "bin/Release/protoc-gen-rust-grpc.exe" ]; then
# Windows Release build
cp bin/Release/protoc-gen-rust-grpc.exe "${TARGET_PATH}/"
elif [ -f "bin/Debug/protoc-gen-rust-grpc.exe" ]; then
# Windows Debug build (shouldn't happen with Release config, but just in case)
cp bin/Debug/protoc-gen-rust-grpc.exe "${TARGET_PATH}/"
else
echo "Error: protoc-gen-rust-grpc not found"
echo "Looking for binary in common locations..."
find . -name "protoc-gen-rust-grpc*" -type f 2>/dev/null | head -10
exit 1
fi

clippy:
runs-on: ubuntu-latest
Expand All @@ -82,19 +159,32 @@ jobs:
- uses: hecrj/setup-rust-action@v2
with:
components: clippy
- uses: taiki-e/install-action@v2
with:
tool: protoc@3.32.0
- name: Restore protoc plugin from cache
- name: Restore protoc and plugin from cache
id: cache-plugin
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/protoc-plugin
key: ${{ runner.os }}-protoc-plugin-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/.bazelrc', 'protoc-gen-rust-grpc/MODULE.bazel') }}
- name: Add protoc plugin to PATH
key: ${{ runner.os }}-protoc-plugin-cmake-v4-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/CMakeLists.txt', 'protoc-gen-rust-grpc/cmake/**') }}
- name: Add protoc and plugin to PATH
shell: bash
run: |
echo "${{ runner.temp }}/protoc-plugin" >> $GITHUB_PATH
# Use forward slashes for all paths in bash, even on Windows
PROTOC_DIR="${{ runner.temp }}/protoc-plugin"
PROTOC_DIR="${PROTOC_DIR//\\/\/}" # Convert backslashes to forward slashes

echo "${PROTOC_DIR}" >> $GITHUB_PATH

# Also set PROTOC for build scripts
if [ "${{ runner.os }}" = "Windows" ]; then
echo "PROTOC=${PROTOC_DIR}/protoc.exe" >> $GITHUB_ENV
else
echo "PROTOC=${PROTOC_DIR}/protoc" >> $GITHUB_ENV
fi

# Set the protoc include path only if it exists
if [ -d "${PROTOC_DIR}/include" ]; then
echo "PROTOC_INCLUDE=${PROTOC_DIR}/include" >> $GITHUB_ENV
fi
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --workspace --all-features --all-targets

Expand All @@ -117,19 +207,32 @@ jobs:
toolchain: nightly-2025-03-27
- uses: taiki-e/install-action@cargo-hack
- uses: taiki-e/install-action@cargo-udeps
- uses: taiki-e/install-action@v2
with:
tool: protoc@3.32.0
- name: Restore protoc plugin from cache
- name: Restore protoc and plugin from cache
id: cache-plugin
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/protoc-plugin
key: ${{ runner.os }}-protoc-plugin-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/.bazelrc', 'protoc-gen-rust-grpc/MODULE.bazel') }}
- name: Add protoc plugin to PATH
key: ${{ runner.os }}-protoc-plugin-cmake-v4-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/CMakeLists.txt', 'protoc-gen-rust-grpc/cmake/**') }}
- name: Add protoc and plugin to PATH
shell: bash
run: |
echo "${{ runner.temp }}/protoc-plugin" >> $GITHUB_PATH
# Use forward slashes for all paths in bash, even on Windows
PROTOC_DIR="${{ runner.temp }}/protoc-plugin"
PROTOC_DIR="${PROTOC_DIR//\\/\/}" # Convert backslashes to forward slashes

echo "${PROTOC_DIR}" >> $GITHUB_PATH

# Also set PROTOC for build scripts
if [ "${{ runner.os }}" = "Windows" ]; then
echo "PROTOC=${PROTOC_DIR}/protoc.exe" >> $GITHUB_ENV
else
echo "PROTOC=${PROTOC_DIR}/protoc" >> $GITHUB_ENV
fi

# Set the protoc include path only if it exists
if [ -d "${PROTOC_DIR}/include" ]; then
echo "PROTOC_INCLUDE=${PROTOC_DIR}/include" >> $GITHUB_ENV
fi
- uses: Swatinem/rust-cache@v2
- run: cargo hack udeps --workspace --exclude-features=_tls-any,tls,tls-aws-lc,tls-ring --each-feature
- run: cargo udeps --package tonic --features tls-ring,transport
Expand All @@ -151,19 +254,32 @@ jobs:
- uses: actions/checkout@v4
- uses: hecrj/setup-rust-action@v2
- uses: taiki-e/install-action@cargo-hack
- uses: taiki-e/install-action@v2
with:
tool: protoc@3.32.0
- name: Restore protoc plugin from cache
- name: Restore protoc and plugin from cache
id: cache-plugin
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/protoc-plugin
key: ${{ runner.os }}-protoc-plugin-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/.bazelrc', 'protoc-gen-rust-grpc/MODULE.bazel') }}
- name: Add protoc plugin to PATH
key: ${{ runner.os }}-protoc-plugin-cmake-v4-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/CMakeLists.txt', 'protoc-gen-rust-grpc/cmake/**') }}
- name: Add protoc and plugin to PATH
shell: bash
run: |
echo "${{ runner.temp }}/protoc-plugin" >> $GITHUB_PATH
# Use forward slashes for all paths in bash, even on Windows
PROTOC_DIR="${{ runner.temp }}/protoc-plugin"
PROTOC_DIR="${PROTOC_DIR//\\/\/}" # Convert backslashes to forward slashes

echo "${PROTOC_DIR}" >> $GITHUB_PATH

# Also set PROTOC for build scripts
if [ "${{ runner.os }}" = "Windows" ]; then
echo "PROTOC=${PROTOC_DIR}/protoc.exe" >> $GITHUB_ENV
else
echo "PROTOC=${PROTOC_DIR}/protoc" >> $GITHUB_ENV
fi

# Set the protoc include path only if it exists
if [ -d "${PROTOC_DIR}/include" ]; then
echo "PROTOC_INCLUDE=${PROTOC_DIR}/include" >> $GITHUB_ENV
fi
- uses: Swatinem/rust-cache@v2
- name: Check features
run: cargo hack check --workspace --no-private --each-feature --no-dev-deps
Expand Down Expand Up @@ -204,19 +320,38 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: hecrj/setup-rust-action@v2
- uses: taiki-e/install-action@v2
with:
tool: protoc@3.32.0
- name: Restore protoc plugin from cache
- name: Restore protoc and plugin from cache
id: cache-plugin
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/protoc-plugin
key: ${{ runner.os }}-protoc-plugin-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/.bazelrc', 'protoc-gen-rust-grpc/MODULE.bazel') }}
- name: Add protoc plugin to PATH
key: ${{ runner.os }}-protoc-plugin-cmake-v4-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/CMakeLists.txt', 'protoc-gen-rust-grpc/cmake/**') }}
- name: Check cache status
if: steps.cache-plugin.outputs.cache-hit != 'true'
run: |
echo "ERROR: Cache miss! The protoc plugin was not found in cache."
echo "This means the build-protoc-plugin job either failed or didn't run."
exit 1
- name: Add protoc and plugin to PATH
shell: bash
run: |
echo "${{ runner.temp }}/protoc-plugin" >> $GITHUB_PATH
# Use forward slashes for all paths in bash, even on Windows
PROTOC_DIR="${{ runner.temp }}/protoc-plugin"
PROTOC_DIR="${PROTOC_DIR//\\/\/}" # Convert backslashes to forward slashes

echo "${PROTOC_DIR}" >> $GITHUB_PATH

# Also set PROTOC for build scripts
if [ "${{ runner.os }}" = "Windows" ]; then
echo "PROTOC=${PROTOC_DIR}/protoc.exe" >> $GITHUB_ENV
else
echo "PROTOC=${PROTOC_DIR}/protoc" >> $GITHUB_ENV
fi

# Set the protoc include path only if it exists
if [ -d "${PROTOC_DIR}/include" ]; then
echo "PROTOC_INCLUDE=${PROTOC_DIR}/include" >> $GITHUB_ENV
fi
- uses: taiki-e/install-action@cargo-hack
- uses: taiki-e/install-action@cargo-nextest
- uses: Swatinem/rust-cache@v2
Expand All @@ -243,19 +378,32 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: hecrj/setup-rust-action@v2
- uses: taiki-e/install-action@v2
with:
tool: protoc@3.32.0
- name: Restore protoc plugin from cache
- name: Restore protoc and plugin from cache
id: cache-plugin
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/protoc-plugin
key: ${{ runner.os }}-protoc-plugin-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/.bazelrc', 'protoc-gen-rust-grpc/MODULE.bazel') }}
- name: Add protoc plugin to PATH
key: ${{ runner.os }}-protoc-plugin-cmake-v4-${{ hashFiles('protoc-gen-rust-grpc/src/**', 'protoc-gen-rust-grpc/CMakeLists.txt', 'protoc-gen-rust-grpc/cmake/**') }}
- name: Add protoc and plugin to PATH
shell: bash
run: |
echo "${{ runner.temp }}/protoc-plugin" >> $GITHUB_PATH
# Use forward slashes for all paths in bash, even on Windows
PROTOC_DIR="${{ runner.temp }}/protoc-plugin"
PROTOC_DIR="${PROTOC_DIR//\\/\/}" # Convert backslashes to forward slashes

echo "${PROTOC_DIR}" >> $GITHUB_PATH

# Also set PROTOC for build scripts
if [ "${{ runner.os }}" = "Windows" ]; then
echo "PROTOC=${PROTOC_DIR}/protoc.exe" >> $GITHUB_ENV
else
echo "PROTOC=${PROTOC_DIR}/protoc" >> $GITHUB_ENV
fi

# Set the protoc include path only if it exists
if [ -d "${PROTOC_DIR}/include" ]; then
echo "PROTOC_INCLUDE=${PROTOC_DIR}/include" >> $GITHUB_ENV
fi
- uses: Swatinem/rust-cache@v2
- name: Run interop tests
run: ./interop/test.sh
Expand Down
5 changes: 1 addition & 4 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@
devShells.default = pkgs.mkShell {
packages = with pkgs; [
cargo-nextest
bazel_7
pre-commit
cmake

(rustToolchain.withComponents [
"cargo"
Expand All @@ -92,14 +92,11 @@
"rustfmt"
"rust-analyzer"
])
# protobuf
];

hardeningDisable = [ "fortify" ];

shellHook = ''
export PATH="$PWD/protoc-gen-rust-grpc/bazel-bin/src:$HOME/code/install/bin:$PATH"

${config.pre-commit.installationScript}
'';
};
Expand Down
4 changes: 4 additions & 0 deletions interop/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
fn main() {
let proto = "proto/grpc/testing/test.proto";

eprintln!("{}", tonic_protobuf_build::protoc());
let path = std::env::var("PATH").unwrap_or_default();
std::env::set_var("PATH", format!("{}:{}", path, tonic_protobuf_build::bin()));

tonic_prost_build::compile_protos(proto).unwrap();
tonic_protobuf_build::CodeGen::new()
.include("proto/grpc/testing")
Expand Down
3 changes: 3 additions & 0 deletions protoc-gen-rust-grpc/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ bazel-out
bazel-protoc-gen-rust-grpc
bazel-testlogs
MODULE.bazel.lock

build/*
CMakeFiles/*
Loading
Loading