updated #20
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: Bats Tests | |
| on: | |
| push: | |
| branches: | |
| - '**' | |
| pull_request: | |
| branches: | |
| - '**' | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@v3 | |
| # - name: Set up Bats cache | |
| # uses: actions/cache@v4 | |
| # id: bats-cache | |
| # with: | |
| # path: | | |
| # /usr/bin/bats | |
| # /usr/lib/bats | |
| # /usr/libexec/bats-core | |
| # key: ${{ runner.os }}-bats-apt-${{ hashFiles('.github/workflows/ci.yaml') }} | |
| # restore-keys: | | |
| # ${{ runner.os }}-bats-apt- | |
| # - name: Update package list | |
| # run: sudo apt-get update | |
| # - name: Install Bats if not cached | |
| # if: steps.bats-cache.outputs.cache-hit != 'true' | |
| # run: | | |
| # echo "Installing Bats using apt..." | |
| # sudo apt-get install -y bats | |
| # - name: Cache apt packages | |
| # uses: actions/cache@v4 | |
| # id: apt-cache | |
| # with: | |
| # path: | | |
| # /var/cache/apt/archives | |
| # /var/lib/apt/lists | |
| # key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/ci.yaml') }} | |
| # restore-keys: | | |
| # ${{ runner.os }}-apt- | |
| # - name: Cache bats testing libraries | |
| # uses: actions/cache@v4 | |
| # id: bats-libs-cache | |
| # with: | |
| # path: | | |
| # ~/.local/lib/bats-support | |
| # ~/.local/lib/bats-assert | |
| # key: ${{ runner.os }}-bats-libs-${{ hashFiles('.github/workflows/ci.yaml') }} | |
| # restore-keys: | | |
| # ${{ runner.os }}-bats-libs- | |
| - name: Update package list and install Bats | |
| run: | | |
| echo "Updating package list..." | |
| sudo apt-get update | |
| echo "Installing Bats using apt..." | |
| sudo apt-get install -y bats | |
| - name: Verify Bats installation | |
| run: | | |
| bats --version | |
| which bats | |
| echo "✅Bats installed successfully via apt" | |
| # - name: Run Bats tests | |
| # run: | | |
| # bats src/test/bats/commands/*.bats | tee bats_output.log | |
| # if [ ${PIPESTATUS[0]} -ne 0 ]; then | |
| # echo "::error::Bats tests failed. Check bats_output.log for details." | |
| # exit 1 | |
| # fi | |
| - name: Run Bats tests with detailed output | |
| id: run-tests | |
| run: | | |
| echo "::group::Running Bats Tests" | |
| # Set up test output files | |
| TEST_OUTPUT_FILE="bats_test_output.log" | |
| # Run tests with TAP output and detailed logging | |
| set +e # Don't exit on test failures | |
| if [ -d "src/test/bats/commands" ] && [ "$(find src/test/bats/commands -name "*.bats" 2>/dev/null | wc -l)" -gt 0 ]; then | |
| echo "Found test files, running tests..." | |
| bats --tap --recursive src/test/bats/commands/ 2>&1 | tee "${TEST_OUTPUT_FILE}" | |
| TEST_EXIT_CODE=${PIPESTATUS[0]} | |
| else | |
| echo "No .bats test files found in src/test/bats/commands/" | |
| TEST_EXIT_CODE=${PIPESTATUS[1]} | |
| fi | |
| echo "::endgroup::" | |
| # Save the exit code for later steps | |
| echo "TEST_EXIT_CODE=${TEST_EXIT_CODE}" >> $GITHUB_ENV | |
| echo "TEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}" >> $GITHUB_ENV | |
| - name: Process test results | |
| if: always() | |
| run: | | |
| echo "::group::Test Results Summary" | |
| if [ -f "${TEST_OUTPUT_FILE}" ] && [ "${TEST_EXIT_CODE}" != "0" ]; then | |
| # Count passed and failed tests | |
| PASSED_TESTS=$(grep -c "^ok " "${TEST_OUTPUT_FILE}" || echo "0") | |
| FAILED_TESTS=$(grep -c "^not ok " "${TEST_OUTPUT_FILE}" || echo "0") | |
| TOTAL_TESTS=$((PASSED_TESTS + FAILED_TESTS)) | |
| echo "📊 Test Summary:" | |
| echo " Total tests: ${TOTAL_TESTS}" | |
| echo " Passed: ${PASSED_TESTS}" | |
| echo " Failed: ${FAILED_TESTS}" | |
| # Set outputs for use in other steps | |
| echo "PASSED_TESTS=${PASSED_TESTS}" >> $GITHUB_ENV | |
| echo "FAILED_TESTS=${FAILED_TESTS}" >> $GITHUB_ENV | |
| echo "TOTAL_TESTS=${TOTAL_TESTS}" >> $GITHUB_ENV | |
| else | |
| echo "❌ No test output file found" | |
| fi | |
| echo "::endgroup::" | |
| - name: Highlight test failures | |
| if: always() | |
| run: | | |
| if [ -f "${TEST_OUTPUT_FILE}" ] && [ "${TEST_EXIT_CODE}" != "0" ]; then | |
| FAILED_TESTS=$(grep -c "^not ok " "${TEST_OUTPUT_FILE}" || echo "0") | |
| echo "::group::❌ Test Failures Detected" | |
| echo "::error title=Bats Tests Failed::${FAILED_TESTS} test(s) failed out of ${TOTAL_TESTS} total tests" | |
| # Extract and highlight failed tests | |
| echo "Failed tests:" | |
| grep -n "^not ok " "${TEST_OUTPUT_FILE}" | while IFS= read -r line; do | |
| echo "::error::${line}" | |
| done | |
| # Show detailed failure output | |
| echo "" | |
| echo "Detailed failure output:" | |
| grep -A 5 -B 1 "^not ok " "${TEST_OUTPUT_FILE}" || true | |
| # Show any error messages | |
| if grep -q "# " "${TEST_OUTPUT_FILE}"; then | |
| echo "" | |
| echo "Error details:" | |
| grep "# " "${TEST_OUTPUT_FILE}" | while IFS= read -r line; do | |
| echo "::error::${line}" | |
| done | |
| fi | |
| fi | |
| echo "::endgroup::" | |
| - name: Generate test report | |
| if: always() | |
| run: | | |
| echo "::group::📋 Generating Test Report" | |
| # Create a markdown report | |
| cat > test-report.md << EOF | |
| # BeSman Bats Test Report | |
| **Test Run Date:** $(date) | |
| **Branch:** ${GITHUB_REF#refs/heads/} | |
| **Commit:** ${GITHUB_SHA:0:8} | |
| **Workflow:** [Run #${GITHUB_RUN_NUMBER}](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}) | |
| # ## Summary | |
| # - **Total Tests:** ${TOTAL_TESTS:-0} | |
| # - **Passed:** ${PASSED_TESTS:-0} | |
| # - **Failed:** ${FAILED_TESTS:-0} | |
| # - **Success Rate:** $(( TOTAL_TESTS > 0 ? (PASSED_TESTS * 100) / TOTAL_TESTS : 0 ))% | |
| ## 📊 Summary | |
| | Metric | Value | | |
| |--------|-------| | |
| | Total Tests | ${TOTAL_TESTS:-0} | | |
| | Passed | ✅ ${PASSED_TESTS:-0} | | |
| | Failed | ❌ ${FAILED_TESTS:-0} | | |
| | Success Rate | $(( TOTAL_TESTS > 0 ? (PASSED_TESTS * 100) / TOTAL_TESTS : 0 ))% | | |
| ## Test Status | |
| $(if [ "${TEST_EXIT_CODE}" = "0" ]; then echo "✅ All tests passed!"; else echo "❌ Some tests failed"; fi) | |
| EOF | |
| if [ -f "${TEST_OUTPUT_FILE}" ] && [ "${FAILED_TESTS:-0}" -gt 0 ]; then | |
| echo "" >> test-report.md | |
| echo "## Failed Tests" >> test-report.md | |
| echo "\`\`\`" >> test-report.md | |
| grep "^not ok " "${TEST_OUTPUT_FILE}" >> test-report.md || true | |
| echo "\`\`\`" >> test-report.md | |
| fi | |
| echo "Test report generated:" | |
| cat test-report.md | |
| echo "::endgroup::" | |
| # - name: Upload Bats output log | |
| # uses: actions/upload-artifact@v4 | |
| # with: | |
| # name: bats-output-log | |
| # path: bats_output.log | |
| - name: Upload test artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: bats-test-results-${{ github.run_number }} | |
| path: | | |
| bats_test_output.log | |
| test-report.md | |
| retention-days: 90 | |
| - name: Comment PR with test results | |
| if: always() && github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| let reportContent = '# 🧪 BeSman Test Results\n\n'; | |
| try { | |
| if (fs.existsSync('test-report.md')) { | |
| reportContent += fs.readFileSync('test-report.md', 'utf8'); | |
| } else { | |
| reportContent += '❌ Test report not found\n'; | |
| } | |
| } catch (error) { | |
| reportContent += `❌ Error reading test report: ${error.message}\n`; | |
| } | |
| // Add link to full logs | |
| reportContent += `\n\n📋 [View full test logs](${context.payload.pull_request.html_url}/checks)`; | |
| // Find existing comment | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existingComment = comments.find(comment => | |
| comment.user.login === 'github-actions[bot]' && | |
| comment.body.includes('🧪 BeSman Test Results') | |
| ); | |
| if (existingComment) { | |
| // Update existing comment | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existingComment.id, | |
| body: reportContent | |
| }); | |
| } else { | |
| // Create new comment | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: reportContent | |
| }); | |
| } | |
| - name: Set final status | |
| if: always() | |
| run: | | |
| if [ "${TEST_EXIT_CODE}" != "0" ]; then | |
| echo "::error title=Test Suite Failed::${FAILED_TESTS} test(s) failed. Check the test output above for details." | |
| exit 1 | |
| else | |
| echo "::notice title=Test Suite Passed::All ${TOTAL_TESTS} tests passed successfully! 🎉" | |
| fi |