Skip to content

BJD converters use local microservice only. #1181

BJD converters use local microservice only.

BJD converters use local microservice only. #1181

Workflow file for this run

# This workflow will build a Java project with Ant and run VStar's unit tests
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-ant
name: VStar Unit Tests
on:
push:
branches:
- "**"
pull_request:
branches: [ master ]
permissions:
contents: write
pull-requests: write
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
java: [ '17', '21', '23' ]
name: Java ${{ matrix.java }} VStar UTs
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
- name: Create plugin dir
run:
mkdir -p ~/vstar_plugins
- name: Create plugin libs dir
run:
mkdir -p ~/vstar_plugin_libs
# Issue #579: GUI tests use AssertJ Swing, which needs an X display.
# xvfb is pre-installed on ubuntu-latest; this wraps the whole UT run
# so any test that touches Swing/AWT works headlessly.
- name: Run tests with coverage
id: tests
uses: nick-fields/retry@v3
with:
timeout_minutes: 20
max_attempts: 2
command: xvfb-run -a ant -noinput -buildfile build.xml coverage-report
- name: Extract test and coverage metrics
if: always()
id: metrics
run: |
SUMMARY="test_report/summary.txt"
COV_XML="test_report/coverage/coverage.xml"
TESTS=0; FAILURES=0; ERRORS=0
if [ -f "$SUMMARY" ]; then
while IFS= read -r line; do
t=$(echo "$line" | grep -oP 'Tests run: \K[0-9]+' || true)
f=$(echo "$line" | grep -oP 'Failures: \K[0-9]+' || true)
e=$(echo "$line" | grep -oP 'Errors: \K[0-9]+' || true)
[ -n "$t" ] && TESTS=$((TESTS + t))
[ -n "$f" ] && FAILURES=$((FAILURES + f))
[ -n "$e" ] && ERRORS=$((ERRORS + e))
done < "$SUMMARY"
fi
PASSED=$((TESTS - FAILURES - ERRORS))
echo "tests=$TESTS" >> "$GITHUB_OUTPUT"
echo "passed=$PASSED" >> "$GITHUB_OUTPUT"
echo "failures=$FAILURES" >> "$GITHUB_OUTPUT"
echo "errors=$ERRORS" >> "$GITHUB_OUTPUT"
# Issue #579: split coverage into GUI vs non-GUI so the headline
# number reflects code we actually unit-test, while keeping the
# GUI deficit visible alongside it.
if [ -f "$COV_XML" ]; then
python3 script/coverage_metrics.py \
--src src \
--coverage-xml "$COV_XML" \
--github-output "$GITHUB_OUTPUT"
else
echo "line_cov=N/A" >> "$GITHUB_OUTPUT"
echo "branch_cov=N/A" >> "$GITHUB_OUTPUT"
echo "method_cov=N/A" >> "$GITHUB_OUTPUT"
echo "gui_line_cov=N/A" >> "$GITHUB_OUTPUT"
echo "gui_branch_cov=N/A" >> "$GITHUB_OUTPUT"
echo "gui_method_cov=N/A" >> "$GITHUB_OUTPUT"
echo "all_line_cov=N/A" >> "$GITHUB_OUTPUT"
echo "all_branch_cov=N/A" >> "$GITHUB_OUTPUT"
echo "all_method_cov=N/A" >> "$GITHUB_OUTPUT"
fi
- name: Post step summary
if: always() && steps.metrics.outputs.tests != '0'
run: |
STATUS="${{ steps.tests.outcome == 'success' && 'All tests passed' || 'Tests failed' }}"
cat >> "$GITHUB_STEP_SUMMARY" <<EOF
## VStar Unit Tests (Java ${{ matrix.java }})
**${STATUS}**
| Metric | Value |
|--------|-------|
| Tests | ${{ steps.metrics.outputs.tests }} |
| Passed | ${{ steps.metrics.outputs.passed }} |
| Failures | ${{ steps.metrics.outputs.failures }} |
| Errors | ${{ steps.metrics.outputs.errors }} |
### Coverage by area (issue #579)
A class is "GUI" when its source file imports \`javax.swing\` or \`java.awt\`.
| Area | Line | Branch |
|------|------|--------|
| Non-GUI (headline) | ${{ steps.metrics.outputs.line_cov }} | ${{ steps.metrics.outputs.branch_cov }} |
| GUI | ${{ steps.metrics.outputs.gui_line_cov }} | ${{ steps.metrics.outputs.gui_branch_cov }} |
| Combined | ${{ steps.metrics.outputs.all_line_cov }} | ${{ steps.metrics.outputs.all_branch_cov }} |
EOF
- name: Comment on PR
if: >-
always() &&
github.event_name == 'pull_request' &&
matrix.java == '17' &&
steps.metrics.outputs.tests != '0'
uses: actions/github-script@v7
with:
script: |
const outcome = '${{ steps.tests.outcome }}';
const status = outcome === 'success' ? 'All tests passed' : 'Tests failed';
const tests = '${{ steps.metrics.outputs.tests }}';
const passed = '${{ steps.metrics.outputs.passed }}';
const failures = '${{ steps.metrics.outputs.failures }}';
const errors = '${{ steps.metrics.outputs.errors }}';
const body = [
'## VStar Unit Tests',
'',
`**${status}** (Java 17)`,
'',
'| Metric | Value |',
'|--------|-------|',
`| Tests | ${tests} |`,
`| Passed | ${passed} |`,
`| Failures | ${failures} |`,
`| Errors | ${errors} |`,
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.startsWith('## VStar Unit Tests')
);
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body: body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body,
});
}
- name: Upload coverage report
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-report-java${{ matrix.java }}
path: test_report/coverage/
- name: Checkout gh-pages
if: >-
github.event_name == 'push' &&
github.ref == 'refs/heads/master' &&
matrix.java == '17' &&
steps.metrics.outputs.tests != '0'
uses: actions/checkout@v4
with:
ref: gh-pages
path: _site
- name: Publish to dashboard
if: >-
github.event_name == 'push' &&
github.ref == 'refs/heads/master' &&
matrix.java == '17' &&
steps.metrics.outputs.tests != '0'
run: |
DATE=$(date -u +%Y-%m-%d)
mkdir -p _site/health/data _site/health/coverage/vstar
# Issue #579: line_coverage / branch_coverage are now the non-GUI
# headline figures (a class is GUI when its source imports
# javax.swing or java.awt). gui_* and combined_* are published
# alongside so the dashboard can show the GUI deficit explicitly.
cat > _site/health/data/coverage.json <<DATAJSON
{
"updated": "${DATE}",
"java_version": "17",
"tests": ${{ steps.metrics.outputs.tests }},
"passed": ${{ steps.metrics.outputs.passed }},
"failures": ${{ steps.metrics.outputs.failures }},
"errors": ${{ steps.metrics.outputs.errors }},
"line_coverage": "${{ steps.metrics.outputs.line_cov }}",
"branch_coverage": "${{ steps.metrics.outputs.branch_cov }}",
"gui_line_coverage": "${{ steps.metrics.outputs.gui_line_cov }}",
"gui_branch_coverage": "${{ steps.metrics.outputs.gui_branch_cov }}",
"combined_line_coverage": "${{ steps.metrics.outputs.all_line_cov }}",
"combined_branch_coverage": "${{ steps.metrics.outputs.all_branch_cov }}"
}
DATAJSON
rm -rf _site/health/coverage/vstar/*
if [ -d "test_report/coverage" ]; then
cp -r test_report/coverage/* _site/health/coverage/vstar/
fi
cd _site
git config user.email "github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
git add -A
git diff --cached --quiet && exit 0
git commit -m "Update VStar coverage data [${DATE}]"
for i in 1 2 3; do
git pull --rebase origin gh-pages && git push origin gh-pages && break
echo "Push attempt $i failed, retrying in $((i * 5))s..."
sleep $((i * 5))
done