Skip to content

Merge pull request #28 from yusuf601/main #45

Merge pull request #28 from yusuf601/main

Merge pull request #28 from yusuf601/main #45

Workflow file for this run

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