Merge pull request #28 from yusuf601/main #45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Stack Project Build & Test | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| # Default permissions: semua job hanya bisa baca | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint_format: | |
| name: Lint & Format Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install development tools | |
| run: | | |
| sudo apt-get -qq update | |
| sudo apt-get -qq install -y clang-tidy clang-format cmake wget build-essential | |
| - name: Download format scripts | |
| run: | | |
| wget -q https://raw.githubusercontent.com/bellshade/unitesting-script/main/filename_formatter.sh | |
| wget -q https://raw.githubusercontent.com/bellshade/unitesting-script/main/markdown_formatter.sh | |
| chmod +x filename_formatter.sh markdown_formatter.sh | |
| - name: Run filename & markdown formatters | |
| run: | | |
| echo "Running filename formatter..." | |
| ./filename_formatter.sh .c .h .cpp .hpp | |
| echo "Running markdown formatter..." | |
| ./markdown_formatter.sh | |
| - name: Configure CMake for linting | |
| run: cmake -B build -S . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug | |
| - name: Run clang-tidy on changed files | |
| run: | | |
| set -e | |
| echo "Determining base commit..." | |
| if git rev-parse --verify origin/main >/dev/null 2>&1; then | |
| BASE_SHA="$(git merge-base HEAD origin/main)" | |
| else | |
| BASE_SHA="$(git rev-list --max-parents=0 HEAD | tail -n1)" | |
| fi | |
| echo "Base SHA: $BASE_SHA" | |
| CHANGED="$(git diff --diff-filter=dr --name-only "$BASE_SHA"...HEAD | grep -E '\.(c|h|cpp|hpp)$' || true)" | |
| echo "Changed C/C++ files:" | |
| echo "$CHANGED" | |
| if [ -n "$CHANGED" ]; then | |
| echo "Running clang-tidy on changed files..." | |
| for f in $CHANGED; do | |
| if [ -f "$f" ]; then | |
| echo "Analyzing: $f" | |
| # Include paths untuk project ini | |
| clang-tidy "$f" --quiet -- -I./src -std=c++17 | |
| fi | |
| done | |
| echo "clang-tidy analysis completed" | |
| else | |
| echo "No C/C++ files changed, skipping clang-tidy" | |
| fi | |
| build: | |
| name: Build on ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| needs: [lint_format] | |
| # Khusus job ini boleh tulis label di PR | |
| permissions: | |
| contents: read | |
| issues: write | |
| pull-requests: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| include: | |
| - os: ubuntu-latest | |
| name: "Linux" | |
| - os: windows-latest | |
| name: "Windows" | |
| - os: macos-latest | |
| name: "macOS" | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install dependencies (Ubuntu) | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| sudo apt-get -qq update | |
| sudo apt-get -qq install -y cmake build-essential | |
| - name: Install dependencies (Windows) | |
| if: matrix.os == 'windows-latest' | |
| run: | | |
| choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' | |
| - name: Install dependencies (macOS) | |
| if: matrix.os == 'macos-latest' | |
| run: | | |
| brew install cmake | |
| - name: Configure CMake | |
| run: | | |
| echo "Configuring CMake build..." | |
| cmake -B build -S . -DCMAKE_BUILD_TYPE=Release | |
| - name: Build stack library | |
| run: | | |
| echo "Building stack library on ${{ matrix.name }}..." | |
| cmake --build build --config Release --parallel 4 | |
| - name: Verify build artifacts | |
| run: | | |
| echo "Build completed successfully on ${{ matrix.name }}" | |
| echo "Listing build directory contents:" | |
| if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
| dir build /s | |
| else | |
| find build -type f -name "*.a" -o -name "*.so" -o -name "*.dylib" -o -name "*.lib" 2>/dev/null || echo "Library files:" | |
| ls -la build/ | |
| fi | |
| echo "Checking if stack_lib was built:" | |
| if [ -f build/libstack_lib.a ] || [ -f build/Release/stack_lib.lib ] || [ -f build/libstack_lib.dylib ]; then | |
| echo "✅ Stack library built successfully" | |
| else | |
| echo "⚠️ Stack library files not found in expected locations" | |
| echo "Available files:" | |
| find build -name "*stack*" 2>/dev/null || echo "No stack-related files found" | |
| fi | |
| shell: bash | |
| - name: Create simple test program | |
| run: | | |
| echo "Creating simple test to verify library linkage..." | |
| mkdir -p test_build | |
| cat > test_build/test_link.cpp << 'EOF' | |
| // Simple test to verify stack library can be linked | |
| #include <iostream> | |
| // Jika ada header di src/, include di sini | |
| // Untuk sekarang, hanya test bahwa program bisa di-compile dan link | |
| int main() { | |
| std::cout << "Stack library build test passed on ${{ matrix.name }}" << std::endl; | |
| return 0; | |
| } | |
| EOF | |
| echo "Compiling test program..." | |
| if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
| # Windows with MSVC | |
| cd test_build | |
| cmake -S . -B build_test << 'TESTCMAKE' | |
| cmake_minimum_required(VERSION 3.16) | |
| project(TestLink) | |
| set(CMAKE_CXX_STANDARD 17) | |
| add_executable(test_link test_link.cpp) | |
| TESTCMAKE | |
| cmake --build build_test --config Release | |
| ./build_test/Release/test_link.exe || echo "Test program execution completed" | |
| else | |
| # Linux/macOS with GCC/Clang | |
| cd test_build | |
| g++ -std=c++17 test_link.cpp -o test_link | |
| ./test_link | |
| fi | |
| shell: bash | |
| continue-on-error: true | |
| - name: Check case_study programs | |
| run: | | |
| echo "Checking case_study directory..." | |
| if [ -d "case_study" ]; then | |
| echo "Contents of case_study directory:" | |
| ls -la case_study/ | |
| echo "Attempting to compile case study files individually..." | |
| for cpp_file in case_study/*.cpp; do | |
| if [ -f "$cpp_file" ]; then | |
| echo "Compiling: $cpp_file" | |
| filename=$(basename "$cpp_file" .cpp) | |
| if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
| # Windows - compile as standalone | |
| cl //EHsc //std:c++17 "$cpp_file" //Fe:"${filename}.exe" 2>/dev/null || echo "Note: $cpp_file may need specific linking" | |
| if [ -f "${filename}.exe" ]; then | |
| echo "✅ Successfully compiled ${filename}.exe" | |
| # Coba jalankan (jika tidak butuh input) | |
| timeout 5 ./"${filename}.exe" 2>/dev/null || echo "Execution test completed for ${filename}" | |
| fi | |
| else | |
| # Linux/macOS - compile as standalone | |
| g++ -std=c++17 "$cpp_file" -o "${filename}" 2>/dev/null || echo "Note: $cpp_file may need specific linking" | |
| if [ -f "${filename}" ]; then | |
| echo "✅ Successfully compiled ${filename}" | |
| # Coba jalankan (jika tidak butuh input) | |
| timeout 5 ./"${filename}" 2>/dev/null || echo "Execution test completed for ${filename}" | |
| fi | |
| fi | |
| fi | |
| done | |
| else | |
| echo "No case_study directory found" | |
| fi | |
| shell: bash | |
| continue-on-error: true | |
| - name: Upload build artifacts | |
| if: success() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: stack-lib-${{ matrix.name }} | |
| path: | | |
| build/ | |
| !build/**/*.o | |
| !build/**/*.obj | |
| !build/**/CMakeFiles/ | |
| retention-days: 7 | |
| - name: Label PR when build failed (Ubuntu only) | |
| if: ${{ failure() && matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' }} | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const { owner, repo } = context.repo; | |
| const issue_number = context.issue.number; | |
| console.log(`Adding 'build-failed' label to PR #${issue_number}`); | |
| await github.rest.issues.addLabels({ | |
| owner, | |
| repo, | |
| issue_number, | |
| labels: ['build-failed', 'needs-fix'] | |
| }); | |
| summary: | |
| name: Build Summary | |
| runs-on: ubuntu-latest | |
| needs: [build] | |
| if: always() | |
| steps: | |
| - name: Check build results | |
| run: | | |
| echo "Stack Project Build Summary:" | |
| echo "============================" | |
| if [ "${{ needs.build.result }}" == "success" ]; then | |
| echo "✅ All builds passed successfully!" | |
| echo "Stack library can be built on:" | |
| echo " - ✅ Linux (Ubuntu)" | |
| echo " - ✅ Windows (Latest)" | |
| echo " - ✅ macOS (Latest)" | |
| echo "" | |
| echo "Ready for development across all platforms!" | |
| else | |
| echo "❌ Some builds failed" | |
| echo "Check the individual job logs for details" | |
| echo "" | |
| echo "Common issues to check:" | |
| echo " - Missing headers in src/" | |
| echo " - C++17 compatibility issues" | |
| echo " - Platform-specific compilation errors" | |
| exit 1 | |
| fi |