Skip to content

updated

updated #20

Workflow file for this run

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