Skip to content

docs(readme): link to v0.4.0 cross-tool scorecard #29

docs(readme): link to v0.4.0 cross-tool scorecard

docs(readme): link to v0.4.0 cross-tool scorecard #29

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
- name: Install coreutils (gtimeout) on macOS
if: runner.os == 'macOS'
run: brew install coreutils
- name: Install dependencies
run: bun install
- name: Run tests
run: bun test
- name: Typecheck
run: |
if [ -f tsconfig.json ]; then
bunx tsc --noEmit
else
echo "No tsconfig.json found, skipping typecheck"
fi
- name: ShellCheck
shell: bash
run: |
if [ "$RUNNER_OS" = "macOS" ]; then
brew install shellcheck
else
sudo apt-get update && sudo apt-get install -y shellcheck
fi
files=$(find . -type f -name '*.sh' -not -path './node_modules/*' -not -path './.git/*')
if [ -n "$files" ]; then
echo "$files" | xargs shellcheck
else
echo "No .sh files found"
fi
coverage:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
permissions:
pull-requests: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- name: Run coverage
id: cov
run: |
set -o pipefail
bun test --coverage 2>&1 | tee coverage.txt
- name: Comment PR with coverage
if: always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const raw = fs.readFileSync('coverage.txt', 'utf8');
const body = [
'## Coverage report',
'',
'Thresholds: `line >= 70%`, `function >= 60%` (see `bunfig.toml`).',
'',
'```',
raw.trim(),
'```',
].join('\n');
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const marker = '## Coverage report';
const existing = comments.find(c => c.body && c.body.startsWith(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}
coverage-badge:
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Bun
uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: bun install
- name: Run coverage
run: |
set -o pipefail
bun test --coverage 2>&1 | tee coverage.txt
- name: Regenerate badge
run: |
line_pct=$(awk -F'|' '/^All files/ { gsub(/ /,"",$3); print $3 }' coverage.txt)
if [ -z "$line_pct" ]; then
echo "could not extract line %, leaving badge as-is"
exit 0
fi
bun scripts/gen-coverage-badge.ts "$line_pct"
- name: Commit badge if changed
run: |
if git diff --quiet docs/coverage.svg README.md; then
echo "no badge change"
exit 0
fi
git config user.name "batonq-ci"
git config user.email "ci@batonq.local"
git add docs/coverage.svg README.md
git commit -m "ci(coverage): refresh badge [skip ci]"
git push