fix(cli): make zero-arg ship nounset-safe #873
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: Coverage (baseline) | |
| # Collects bun test coverage for loki-ts as a baseline. Does NOT enforce a | |
| # threshold yet -- the artifact is uploaded for inspection. A future change | |
| # can flip this on once we agree on a target. | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - feat/bun-migration | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| bun-coverage: | |
| name: bun test --coverage | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: 1.3.13 | |
| - name: Install loki-ts dependencies | |
| working-directory: loki-ts | |
| run: bun install | |
| - name: Run bun test with coverage | |
| working-directory: loki-ts | |
| run: | | |
| mkdir -p coverage | |
| set +e | |
| # Emit BOTH reporters: `text` prints the "All files | <pct> | ..." summary | |
| # to stdout (captured below into coverage.txt and parsed for the line-% | |
| # gate), and `lcov` writes lcov.info for the uploaded artifact. With ONLY | |
| # --coverage-reporter=lcov, bun writes the file but pipes no text table, | |
| # so the `^All files` parse found nothing and the gate failed every run | |
| # ("could not parse line coverage"). Both reporters keep the gate working | |
| # and the artifact intact. | |
| bun test --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=./coverage 2>&1 | tee coverage/coverage.txt | |
| ec=${PIPESTATUS[0]} | |
| set -e | |
| if [ "$ec" -ne 0 ]; then | |
| echo "::error::bun test failed (exit $ec)" | |
| exit "$ec" | |
| fi | |
| # v7.4.10: enforce a minimum line coverage threshold. Pre-v7.4.10 this | |
| # workflow was baseline-only (no gate). 70% chosen from observed | |
| # baseline at v7.4.9; bumps later as suite matures. | |
| - name: Enforce minimum line coverage | |
| working-directory: loki-ts | |
| env: | |
| MIN_LINE_PCT: '70' | |
| run: | | |
| # Bun's real header is: | |
| # File | % Funcs | % Lines | Uncovered Line #s | |
| # so the FIRST numeric column is % Funcs and the SECOND is % Lines. | |
| # This gate is named MIN_LINE_PCT and read $2, i.e. it had never once | |
| # measured line coverage -- verified against bun 1.3.13 on this repo: | |
| # All files | 89.29 | 85.90 | ($2=funcs, $3=lines) | |
| # The false-PASS direction is the dangerous one: many small functions | |
| # each called once scores high on % Funcs while their bodies stay | |
| # largely unexecuted, so the gate would wave through exactly the | |
| # coverage profile it exists to catch. | |
| # | |
| # The header is parsed rather than assumed, so a future column | |
| # reordering by bun fails loudly here instead of silently measuring | |
| # the wrong number again. | |
| COVTXT=$(sed -E 's/\x1b\[[0-9;]*m//g' coverage/coverage.txt 2>/dev/null) | |
| LINES_COL=$(printf '%s\n' "$COVTXT" \ | |
| | grep -E "^File .*\|" \ | |
| | head -1 \ | |
| | awk -F'[|]' '{ for (i=2; i<=NF; i++) { gsub(/^[ \t]+|[ \t]+$/, "", $i); if ($i == "% Lines") { print i; exit } } }') | |
| if [ -z "$LINES_COL" ]; then | |
| echo "::error::could not locate the '% Lines' column in bun's coverage header; the table format has drifted. Failing the gate rather than measuring the wrong column." | |
| printf '%s\n' "$COVTXT" | head -3 | |
| exit 1 | |
| fi | |
| PCT=$(printf '%s\n' "$COVTXT" \ | |
| | grep -E "^All files" \ | |
| | head -1 \ | |
| | awk -F'[|]' -v c="$LINES_COL" '{ gsub(/^[ \t]+|[ \t]+$/, "", $c); print $c }') | |
| if [ -z "$PCT" ]; then | |
| echo "::error::could not parse line coverage from bun test output; coverage format may have drifted. Failing the gate rather than silently disabling it." | |
| exit 1 | |
| fi | |
| echo "line coverage (column $LINES_COL, '% Lines'): ${PCT}%" | |
| # Compare as integers (floor). awk handles float arithmetic. | |
| BELOW=$(awk -v p="$PCT" -v m="$MIN_LINE_PCT" 'BEGIN{ print (p+0 < m+0) ? "1" : "0" }') | |
| echo "Line coverage: ${PCT}% (minimum required: ${MIN_LINE_PCT}%)" | |
| if [ "$BELOW" = "1" ]; then | |
| echo "::error::line coverage ${PCT}% < threshold ${MIN_LINE_PCT}%" | |
| exit 1 | |
| fi | |
| - name: Upload coverage artifact | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-loki-ts | |
| path: loki-ts/coverage/ | |
| if-no-files-found: warn | |
| retention-days: 30 |