Skip to content

feat: add problem (217. Contains Duplicate) with unit testing #15

feat: add problem (217. Contains Duplicate) with unit testing

feat: add problem (217. Contains Duplicate) with unit testing #15

Workflow file for this run

---
name: Presubmit (C++)
on: # yamllint disable-line rule:truthy
pull_request:
branches: ["main"]
jobs:
build-cpp:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history for git diff
- name: Detect changed C++ files
id: detect-changes
run: |
# Get list of changed files
if [ "${{ github.event_name }}" = "pull_request" ]; then
# For PR, compare with base branch
CHANGED_FILES=$(git diff --name-only \
${{ github.event.pull_request.base.sha }}..HEAD)
else
# For push, compare with previous commit
if [ "${{ github.event.before }}" = \
"0000000000000000000000000000000000000000" ]; then
# First commit in repo
CHANGED_FILES=$(git diff --name-only --diff-filter=A HEAD)
else
CHANGED_FILES=$(git diff --name-only \
${{ github.event.before }}..HEAD)
fi
fi
echo "All changed files:"
echo "$CHANGED_FILES"
# Filter for C++ files only
CHANGED_CPP_FILES=$(echo "$CHANGED_FILES" | \
grep -E '\.(cc|cpp|cxx|c\+\+|h|hpp|hxx|h\+\+)$' || true)
# Filter for C++ files specifically in the problems directory
CHANGED_CPP_PROBLEMS_FILES=$(echo "$CHANGED_CPP_FILES" | \
grep -E '^problems/' || true)
# Extract unique problem directories from changed C++ files
CHANGED_PROBLEMS=$(echo "$CHANGED_CPP_PROBLEMS_FILES" | \
grep -E '^problems/[^/]+/' | cut -d'/' -f2 | \
sort -u | tr '\n' ' ' || true)
# Check if Makefile or C++-related config files changed
CPP_CONFIG_CHANGES=$(echo "$CHANGED_FILES" | \
grep -E '(Makefile|CMakeLists\.txt|\.clang-format|\.clang-tidy) \
$' || true)
# Check if common directory changed (affects all problems)
COMMON_CHANGES=$(echo "$CHANGED_FILES" | \
grep -E '^common/' || true)
echo "Changed C++ files:"
echo "$CHANGED_CPP_FILES"
echo "Changed C++ files in problems/:"
echo "$CHANGED_CPP_PROBLEMS_FILES"
echo "Changed problems: $CHANGED_PROBLEMS"
echo "C++ config changes: $CPP_CONFIG_CHANGES"
echo "Common directory changes: $COMMON_CHANGES"
# Set outputs
echo "changed_problems=$CHANGED_PROBLEMS" >> $GITHUB_OUTPUT
echo "has_cpp_changes=$([ -n "$CHANGED_CPP_PROBLEMS_FILES" ] && \
echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
echo "has_cpp_config_changes=$([ -n "$CPP_CONFIG_CHANGES" ] && \
echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
echo "has_common_changes=$([ -n "$COMMON_CHANGES" ] && \
echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
echo "should_run_all_tests=$([ -n "$CPP_CONFIG_CHANGES" ] || \
[ -n "$COMMON_CHANGES" ] && echo 'true' || echo 'false')" >> \
$GITHUB_OUTPUT
- name: Install dependencies
if: >
steps.detect-changes.outputs.has_cpp_changes == 'true' ||
steps.detect-changes.outputs.has_cpp_config_changes == 'true' ||
steps.detect-changes.outputs.has_common_changes == 'true'
run: |
sudo apt-get update
sudo apt-get install -y cmake build-essential clang-format clang-tidy
# Install Google Test from source - most reliable approach
git clone https://github.com/google/googletest.git --depth 1
cd googletest
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_SHARED_LIBS=ON
make -j$(nproc)
sudo make install
sudo ldconfig
- name: Debug Google Test configuration
if: >
steps.detect-changes.outputs.has_cpp_changes == 'true' ||
steps.detect-changes.outputs.has_cpp_config_changes == 'true' ||
steps.detect-changes.outputs.has_common_changes == 'true'
run: make debug-gtest
- name: Lint C++ code
if: steps.detect-changes.outputs.has_cpp_changes == 'true'
run: make lint-cpp
- name: Run C++ tests for changed problems
if: >
steps.detect-changes.outputs.changed_problems != '' &&
steps.detect-changes.outputs.should_run_all_tests == 'false'
run: |
PROBLEMS="${{ steps.detect-changes.outputs.changed_problems }}"
echo "Running tests for changed problems: $PROBLEMS"
for problem in $PROBLEMS; do
echo "Testing problem: $problem"
# Convert snake_case to kebab-case for make target
kebab_case=$(echo "$problem" | sed 's/_/-/g')
make test-cpp:$kebab_case || exit 1
done
- name: Run all C++ tests (dependencies changed)
if: steps.detect-changes.outputs.should_run_all_tests == 'true'
run: |
echo "Running all tests due to C++ configuration or common changes"
make test-cpp:all
- name: Clean
if: always()
run: make clean
- name: Summary
if: always()
run: |
echo "## Test Summary" >> $GITHUB_STEP_SUMMARY
if [ "${{ steps.detect-changes.outputs.has_cpp_changes }}" = \
"false" ] && \
[ "${{ steps.detect-changes.outputs.has_cpp_config_changes }}" = \
"false" ] && \
[ "${{ steps.detect-changes.outputs.has_common_changes }}" = \
"false" ]; then
echo "- No C++ files in problems/ changed - skipped all tasks" >> \
$GITHUB_STEP_SUMMARY
elif [ "${{ steps.detect-changes.outputs.should_run_all_tests }}" = \
"true" ]; then
if [ "${{ steps.detect-changes.outputs.has_cpp_config_changes }}" \
= "true" ]; then
echo "- Ran all tests due to config changes" >> \
$GITHUB_STEP_SUMMARY
fi
if [ "${{ steps.detect-changes.outputs.has_common_changes }}" = \
"true" ]; then
echo "- Ran all tests due to common directory changes" >> \
$GITHUB_STEP_SUMMARY
fi
elif [ "${{ steps.detect-changes.outputs.changed_problems }}" != \
"" ]; then
problems="${{ steps.detect-changes.outputs.changed_problems }}"
echo "- Ran targeted tests for: $problems" >> \
$GITHUB_STEP_SUMMARY
else
echo "- No tests needed (no problem files changed)" >> \
$GITHUB_STEP_SUMMARY
fi