Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions .github/scripts/summarize-test-failures.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/bin/bash
# Script to summarize wit-stub-generation-test failures
# Outputs a markdown summary suitable for PR comments
#
# Usage: summarize-test-failures.sh <test_output_file> <summary_file>
# test_output_file: File containing captured test output (required)
# summary_file: File to write markdown summary (default: test_summary.md)

set +e # Don't exit on error

TEST_OUTPUT_FILE="${1}"
SUMMARY_FILE="${2:-test_summary.md}"

if [ -z "$TEST_OUTPUT_FILE" ] || [ ! -f "$TEST_OUTPUT_FILE" ]; then
echo "Error: Test output file required as first argument"
exit 1
fi

echo "## wit-stub-generation-test Results" > "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "This test is expected to have failures due to known issues with tuple wrapper types." >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"

# Check if test passed or failed
TEST_EXIT_CODE=1
if grep -q "100% tests passed" "$TEST_OUTPUT_FILE"; then
TEST_EXIT_CODE=0
fi

if [ $TEST_EXIT_CODE -eq 0 ]; then
echo "✅ **All tests passed!**" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "Great news! The wit-stub-generation-test is now fully passing." >> "$SUMMARY_FILE"
else
# Extract compilation statistics from ninja build output
# Look for lines like "4: [6/13] Building CXX"
BUILD_LINES=$(grep "Building CXX" "$TEST_OUTPUT_FILE" | head -1)

if [ -n "$BUILD_LINES" ]; then
# Extract total from format [X/TOTAL]
TOTAL_TARGETS=$(echo "$BUILD_LINES" | grep -oP '\[\d+/\K\d+' | head -1)
else
TOTAL_TARGETS="0"
fi

FAILED_TARGETS=$(grep -c "^4: FAILED:" "$TEST_OUTPUT_FILE" || echo "0")
PASSED_TARGETS=$((TOTAL_TARGETS - FAILED_TARGETS))

if [ $TOTAL_TARGETS -gt 0 ]; then
PASS_PERCENT=$(awk "BEGIN {printf \"%.1f\", ($PASSED_TARGETS / $TOTAL_TARGETS) * 100}")
FAIL_PERCENT=$(awk "BEGIN {printf \"%.1f\", ($FAILED_TARGETS / $TOTAL_TARGETS) * 100}")
else
PASS_PERCENT="0.0"
FAIL_PERCENT="0.0"
fi

# Extract error counts
TOTAL_ERRORS=$(grep -c "error:" "$TEST_OUTPUT_FILE" || echo "0")

# Show compilation statistics
echo "### Compilation Summary" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "| Metric | Value |" >> "$SUMMARY_FILE"
echo "|--------|-------|" >> "$SUMMARY_FILE"
echo "| Total targets | $TOTAL_TARGETS |" >> "$SUMMARY_FILE"
echo "| ✅ Passed | $PASSED_TARGETS ($PASS_PERCENT%) |" >> "$SUMMARY_FILE"
echo "| ❌ Failed | $FAILED_TARGETS ($FAIL_PERCENT%) |" >> "$SUMMARY_FILE"
echo "| Total errors | $TOTAL_ERRORS |" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"

# Count specific error patterns
NO_MATCHING_FUNCTION=$(grep "error: no matching function for call to 'get<" "$TEST_OUTPUT_FILE" | wc -l || echo "0")
RESULT_OK_ERRORS=$(grep "result_ok_wrapper" "$TEST_OUTPUT_FILE" | wc -l || echo "0")
RESULT_ERR_ERRORS=$(grep "result_err_wrapper" "$TEST_OUTPUT_FILE" | wc -l || echo "0")
MISSING_FILES=$(grep "fatal error:.*No such file or directory" "$TEST_OUTPUT_FILE" | wc -l || echo "0")

echo "### Error Breakdown" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "| Error Type | Count |" >> "$SUMMARY_FILE"
echo "|------------|-------|" >> "$SUMMARY_FILE"
echo "| \`std::get<>\` function call errors | $NO_MATCHING_FUNCTION |" >> "$SUMMARY_FILE"
echo "| \`result_ok_wrapper\` related | $RESULT_OK_ERRORS |" >> "$SUMMARY_FILE"
echo "| \`result_err_wrapper\` related | $RESULT_ERR_ERRORS |" >> "$SUMMARY_FILE"
echo "| Missing file errors | $MISSING_FILES |" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"

# Extract sample errors (first 5 unique error messages, excluding file paths)
echo "### Sample Errors" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo '```' >> "$SUMMARY_FILE"
grep "error:" "$TEST_OUTPUT_FILE" | grep -v "No such file or directory" | sed 's|/home/[^/]*/component-model-cpp/||g' | sed 's/^4: //' | sort -u | head -5 >> "$SUMMARY_FILE"
echo '```' >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"

# Check if errors increased, decreased, or stayed the same
if [ -f "previous_test_summary.txt" ]; then
PREV_ERRORS=$(cat previous_test_summary.txt)

echo "### Trend Analysis" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"

if [ "$TOTAL_ERRORS" -lt "$PREV_ERRORS" ]; then
DIFF=$((PREV_ERRORS - TOTAL_ERRORS))
echo "✅ **Improvement**: $DIFF fewer errors than previous run ($PREV_ERRORS → $TOTAL_ERRORS)" >> "$SUMMARY_FILE"
elif [ "$TOTAL_ERRORS" -gt "$PREV_ERRORS" ]; then
DIFF=$((TOTAL_ERRORS - PREV_ERRORS))
echo "⚠️ **Regression**: $DIFF more errors than previous run ($PREV_ERRORS → $TOTAL_ERRORS)" >> "$SUMMARY_FILE"
else
echo "➡️ **No change**: Same number of errors as previous run ($TOTAL_ERRORS)" >> "$SUMMARY_FILE"
fi
echo "" >> "$SUMMARY_FILE"
fi

# Save current error count for next run
echo "$TOTAL_ERRORS" > previous_test_summary.txt
fi

echo "### Known Issues" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "The main issue is that \`result_ok_wrapper\` and \`result_err_wrapper\` types don't support \`std::get<>\` operations needed for tuple unpacking in generated code." >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "**Goal**: These failures should ideally decrease over time or remain stable. Any increase warrants investigation." >> "$SUMMARY_FILE"

echo "Summary written to $SUMMARY_FILE"
cat "$SUMMARY_FILE"

# Always exit successfully so the workflow continues
exit 0
29 changes: 19 additions & 10 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
name: MacOS

# Disabled: Known to fail
# To re-enable, uncomment the 'on:' section below
on:
push:
branches:
- trunk
- main
pull_request:
branches:
- trunk
- main
workflow_dispatch:
workflow_dispatch: # Manual trigger only
# push:
# branches:
# - trunk
# - main
# pull_request:
# branches:
# - trunk
# - main

env:
CTEST_OUTPUT_ON_FAILURE: 1
Expand Down Expand Up @@ -70,7 +72,14 @@ jobs:
- name: test
working-directory: build
run: |
ctest -VV
ctest -VV -E "wit-stub-generation-test"

- name: test-stubs-full (allowed to fail)
working-directory: build
continue-on-error: true
run: |
echo "Running wit-stub-generation-test (failures expected and will be reported)..."
ctest -VV -R "wit-stub-generation-test"

- name: Upload error logs
if: ${{ failure() || cancelled() }}
Expand Down
44 changes: 26 additions & 18 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,25 @@ jobs:
build/cmcpp-*.exe
extra-deps: ""

- os: macos-14
preset: linux-ninja-Release
build-preset: linux-ninja-Release
cpack-generators: "TGZ;ZIP"
package-patterns: |
build/cmcpp-*.tar.gz
build/cmcpp-*.zip
extra-deps: |
brew install \
pkg-config \
autoconf \
autoconf-archive \
automake \
coreutils \
libtool \
cmake \
ninja
# Disabled: Known to fail
# To re-enable, uncomment the macOS section below
# - os: macos-14
# preset: linux-ninja-Release
# build-preset: linux-ninja-Release
# cpack-generators: "TGZ;ZIP"
# package-patterns: |
# build/cmcpp-*.tar.gz
# build/cmcpp-*.zip
# extra-deps: |
# brew install \
# pkg-config \
# autoconf \
# autoconf-archive \
# automake \
# coreutils \
# libtool \
# cmake \
# ninja

runs-on: ${{ matrix.os }}
permissions:
Expand Down Expand Up @@ -117,7 +119,13 @@ jobs:
- name: Run Tests
working-directory: build
run: |
ctest ${{ matrix.cpack-config || '' }} -VV
ctest ${{ matrix.cpack-config || '' }} -VV -E "wit-stub-generation-test"

- name: Upload test summary
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.os }}-test-summary
path: build/test_summary.md

- name: Create Packages
working-directory: build
Expand Down
66 changes: 65 additions & 1 deletion .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ env:
CTEST_OUTPUT_ON_FAILURE: 1
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

permissions:
contents: read
pull-requests: write
issues: write

jobs:
build:
strategy:
Expand Down Expand Up @@ -77,7 +82,66 @@ jobs:
- name: test
working-directory: build
run: |
ctest -VV
ctest -VV -E "wit-stub-generation-test"

- name: test-stubs-full (allowed to fail)
working-directory: build
continue-on-error: true
run: |
echo "Running wit-stub-generation-test (failures expected and will be reported)..."
ctest -VV -R "wit-stub-generation-test" > test_output.txt 2>&1 || true
cat test_output.txt
../.github/scripts/summarize-test-failures.sh test_output.txt test_summary.md

- name: Comment PR with test summary
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const path = require('path');

// Check if summary file exists
const summaryPath = path.join('build', 'test_summary.md');
if (!fs.existsSync(summaryPath)) {
console.log('Test summary file not found, skipping PR comment');
return;
}

const summary = fs.readFileSync(summaryPath, 'utf8');

// 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 botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('wit-stub-generation-test Results')
);

const commentBody = `### Ubuntu Test Results\n\n${summary}\n\n---\n*Updated: ${new Date().toISOString()}*`;

if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
});
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: commentBody
});
}

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5.4.0
Expand Down
12 changes: 11 additions & 1 deletion .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,17 @@ jobs:
- name: test
working-directory: build
run: |
ctest -C Debug -VV
ctest -C Debug -VV -E "wit-stub-generation-test"

- name: test-stubs-full (allowed to fail)
working-directory: build
continue-on-error: true
shell: bash
run: |
echo "Running wit-stub-generation-test (failures expected and will be reported)..."
ctest -C Debug -VV -R "wit-stub-generation-test" > test_output.txt 2>&1 || true
cat test_output.txt
../.github/scripts/summarize-test-failures.sh test_output.txt test_summary.md

- name: Upload error logs
if: ${{ failure() || cancelled() }}
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ antlr-*.jar
# Python cache files
__pycache__/
*.pyc

# Generated test stubs
/test/generated_stubs/
/test/test_stubs_sample/
5 changes: 4 additions & 1 deletion include/cmcpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
#define CMCPP_HPP

#include <cmcpp/context.hpp>
#include <cmcpp/monostate.hpp>
#include <cmcpp/bool.hpp>
#include <cmcpp/integer.hpp>
#include <cmcpp/float.hpp>
#include <cmcpp/string.hpp>
#include <cmcpp/error_context.hpp>
#include <cmcpp/flags.hpp>
#include <cmcpp/list.hpp>
#include <cmcpp/tuple.hpp>
#include <cmcpp/record.hpp>
#include <cmcpp/list.hpp>
#include <cmcpp/variant.hpp>
#include <cmcpp/func.hpp>
#include <cmcpp/lower.hpp>
Expand Down
38 changes: 38 additions & 0 deletions include/cmcpp/bool.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef CMCPP_BOOL_HPP
#define CMCPP_BOOL_HPP

#include "context.hpp"
#include "integer.hpp"
#include "util.hpp"

namespace cmcpp
{
// Boolean ------------------------------------------------------------------
template <Boolean T>
inline void store(LiftLowerContext &cx, const T &v, uint32_t ptr)
{
uint8_t byte = v ? 1 : 0;
integer::store<uint8_t>(cx, byte, ptr);
}

template <Boolean T>
inline WasmValVector lower_flat(LiftLowerContext &cx, const T &v)
{
using WasmValType = WasmValTypeTrait<ValTrait<T>::flat_types[0]>::type;
return {static_cast<WasmValType>(v)};
}

template <Boolean T>
inline T load(const LiftLowerContext &cx, uint32_t ptr)
{
return convert_int_to_bool(integer::load<uint8_t>(cx, ptr));
}

template <Boolean T>
inline T lift_flat(const LiftLowerContext &cx, const CoreValueIter &vi)
{
return convert_int_to_bool(vi.next<int32_t>());
}
}

#endif // CMCPP_BOOL_HPP
Loading