Implement Rust version of log-lazy #1
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: JavaScript | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| types: [opened, synchronize, reopened] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref == 'refs/heads/main' }} | |
| jobs: | |
| detect-changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| js-changed: ${{ steps.changes.outputs.js-changed }} | |
| package-changed: ${{ steps.changes.outputs.package-changed }} | |
| docs-changed: ${{ steps.changes.outputs.docs-changed }} | |
| workflow-changed: ${{ steps.changes.outputs.workflow-changed }} | |
| any-code-changed: ${{ steps.changes.outputs.any-code-changed }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect changed files | |
| id: changes | |
| shell: bash | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| BASE_SHA="${{ github.event.pull_request.base.sha }}" | |
| HEAD_SHA="${{ github.event.pull_request.head.sha }}" | |
| git fetch origin "$BASE_SHA" | |
| CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA") | |
| else | |
| CHANGED_FILES=$(git diff --name-only HEAD^ HEAD 2>/dev/null || git ls-tree --name-only -r HEAD) | |
| fi | |
| echo "Changed files:" | |
| echo "$CHANGED_FILES" | |
| if echo "$CHANGED_FILES" | grep -qE '^js/'; then | |
| echo "js-changed=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "js-changed=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| if echo "$CHANGED_FILES" | grep -qE '^js/(package\.json|package-lock\.json|bun\.lock)$'; then | |
| echo "package-changed=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "package-changed=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| if echo "$CHANGED_FILES" | grep -qE '(^docs/|\.md$)'; then | |
| echo "docs-changed=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "docs-changed=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| if echo "$CHANGED_FILES" | grep -qE '^\.github/workflows/js\.yml$'; then | |
| echo "workflow-changed=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "workflow-changed=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| if echo "$CHANGED_FILES" | grep -qE '^(js/|\.github/workflows/js\.yml$)'; then | |
| echo "any-code-changed=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "any-code-changed=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| test-compilation: | |
| name: Test Compilation | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes] | |
| if: | | |
| github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' || | |
| needs.detect-changes.outputs.js-changed == 'true' || | |
| needs.detect-changes.outputs.workflow-changed == 'true' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Check JavaScript syntax | |
| working-directory: js | |
| shell: bash | |
| run: | | |
| find src tests examples benchmarks -name "*.js" -type f -print0 | while IFS= read -r -d '' file; do | |
| echo "Checking $file" | |
| node --check "$file" | |
| done | |
| check-file-line-limits: | |
| name: Check File Line Limits | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes] | |
| if: | | |
| github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' || | |
| needs.detect-changes.outputs.js-changed == 'true' || | |
| needs.detect-changes.outputs.docs-changed == 'true' || | |
| needs.detect-changes.outputs.workflow-changed == 'true' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Simulate fresh merge with base branch | |
| if: github.event_name == 'pull_request' | |
| shell: bash | |
| run: | | |
| git fetch origin "${{ github.base_ref }}" | |
| git merge --no-commit --no-ff "origin/${{ github.base_ref }}" | |
| - name: Enforce file line limits | |
| shell: bash | |
| run: | | |
| failures=0 | |
| while IFS= read -r file; do | |
| limit=1500 | |
| case "$file" in | |
| docs/*.md) limit=2500 ;; | |
| esac | |
| line_count=$(wc -l < "$file") | |
| echo "$file: $line_count lines" | |
| if [ "$line_count" -gt "$limit" ]; then | |
| echo "::error file=$file::File has $line_count lines (limit: $limit)" | |
| failures=$((failures + 1)) | |
| fi | |
| done < <( | |
| find js docs .github/workflows -type f \( \ | |
| -name "*.js" -o \ | |
| -name "*.mjs" -o \ | |
| -name "*.cjs" -o \ | |
| -name "*.md" -o \ | |
| -name "*.yml" -o \ | |
| -name "*.yaml" \ | |
| \) 2>/dev/null | grep -vE '/(node_modules|\.git)/' | |
| ) | |
| test "$failures" -eq 0 | |
| version-check: | |
| name: Check npm Version | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes] | |
| if: | | |
| github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' || | |
| needs.detect-changes.outputs.js-changed == 'true' || | |
| needs.detect-changes.outputs.package-changed == 'true' || | |
| needs.detect-changes.outputs.workflow-changed == 'true' | |
| outputs: | |
| should-publish: ${{ steps.check.outputs.should-publish }} | |
| version: ${{ steps.check.outputs.version }} | |
| package-name: ${{ steps.check.outputs.package-name }} | |
| npm-version: ${{ steps.check.outputs.npm-version }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Check package version | |
| id: check | |
| working-directory: js | |
| shell: bash | |
| run: | | |
| CURRENT_VERSION=$(node -p "require('./package.json').version") | |
| PACKAGE_NAME=$(node -p "require('./package.json').name") | |
| NPM_VERSION=$(npm view "$PACKAGE_NAME" version 2>/dev/null || echo "not-found") | |
| echo "Package: $PACKAGE_NAME" | |
| echo "Current version: $CURRENT_VERSION" | |
| echo "NPM version: $NPM_VERSION" | |
| echo "package-name=$PACKAGE_NAME" >> "$GITHUB_OUTPUT" | |
| echo "version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT" | |
| echo "npm-version=$NPM_VERSION" >> "$GITHUB_OUTPUT" | |
| if [ "${{ github.event_name }}" = "pull_request" ] && [ "$NPM_VERSION" = "$CURRENT_VERSION" ]; then | |
| echo "::error::Version must be bumped for PR. Current version ($CURRENT_VERSION) is already published to npm" | |
| exit 1 | |
| fi | |
| if [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/main" ] && [ "$NPM_VERSION" != "$CURRENT_VERSION" ]; then | |
| echo "should-publish=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "should-publish=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| lint: | |
| name: Lint and Typecheck | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes, check-file-line-limits] | |
| if: | | |
| !cancelled() && | |
| (github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' || | |
| needs.detect-changes.outputs.js-changed == 'true' || | |
| needs.detect-changes.outputs.docs-changed == 'true' || | |
| needs.detect-changes.outputs.package-changed == 'true' || | |
| needs.detect-changes.outputs.workflow-changed == 'true') && | |
| (needs.check-file-line-limits.result == 'success' || needs.check-file-line-limits.result == 'skipped') | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Simulate fresh merge with base branch | |
| if: github.event_name == 'pull_request' | |
| shell: bash | |
| run: | | |
| git fetch origin "${{ github.base_ref }}" | |
| git merge --no-commit --no-ff "origin/${{ github.base_ref }}" | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| working-directory: js | |
| run: bun install --frozen-lockfile | |
| - name: Run ESLint | |
| working-directory: js | |
| run: bun run lint | |
| - name: Test TypeScript definitions | |
| working-directory: js | |
| run: bun run test:types | |
| test: | |
| name: Test (${{ matrix.runtime }} on ${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| needs: [detect-changes, test-compilation, lint, check-file-line-limits] | |
| if: | | |
| !cancelled() && | |
| (github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' || | |
| needs.detect-changes.outputs.js-changed == 'true' || | |
| needs.detect-changes.outputs.package-changed == 'true' || | |
| needs.detect-changes.outputs.workflow-changed == 'true') && | |
| (needs.test-compilation.result == 'success' || needs.test-compilation.result == 'skipped') && | |
| (needs.lint.result == 'success' || needs.lint.result == 'skipped') && | |
| (needs.check-file-line-limits.result == 'success' || needs.check-file-line-limits.result == 'skipped') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runtime: [bun, node, deno] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Simulate fresh merge with base branch | |
| if: github.event_name == 'pull_request' | |
| shell: bash | |
| run: | | |
| git fetch origin "${{ github.base_ref }}" | |
| git merge --no-commit --no-ff "origin/${{ github.base_ref }}" | |
| - name: Setup Bun | |
| if: matrix.runtime == 'bun' | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Setup Node.js | |
| if: matrix.runtime == 'node' | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24.x' | |
| - name: Setup Deno | |
| if: matrix.runtime == 'deno' | |
| uses: denoland/setup-deno@v2 | |
| with: | |
| deno-version: v2.x | |
| - name: Install dependencies with Bun | |
| if: matrix.runtime == 'bun' | |
| working-directory: js | |
| run: bun install --frozen-lockfile | |
| - name: Install dependencies with npm | |
| if: matrix.runtime == 'node' | |
| working-directory: js | |
| run: npm ci | |
| - name: Run Bun tests | |
| if: matrix.runtime == 'bun' | |
| working-directory: js | |
| run: bun test | |
| - name: Run Node.js tests | |
| if: matrix.runtime == 'node' | |
| working-directory: js | |
| shell: bash | |
| run: | | |
| passed=0 | |
| failed=0 | |
| for file in tests/{bunyan,debug,log4js,pino,winston,simple-ci,fix-attempt,reorder-import}.test.js; do | |
| output=$(node "$file" 2>&1 || true) | |
| if echo "$output" | grep -q "0 failed" && echo "$output" | grep -q "passed"; then | |
| echo "$(basename "$file"): passed" | |
| passed=$((passed + 1)) | |
| else | |
| echo "$(basename "$file"): failed" | |
| echo "$output" | tail -20 | |
| failed=$((failed + 1)) | |
| fi | |
| done | |
| echo "Node.js tests: $passed passed, $failed failed" | |
| test "$failed" -eq 0 | |
| - name: Run Deno tests | |
| if: matrix.runtime == 'deno' | |
| working-directory: js | |
| shell: bash | |
| run: | | |
| passed=0 | |
| failed=0 | |
| for file in tests/{debug,log4js,simple-ci,fix-attempt,reorder-import}.test.js; do | |
| output=$(deno test --allow-read "$file" 2>&1 || true) | |
| if echo "$output" | grep -q "0 failed" && echo "$output" | grep -q "passed"; then | |
| echo "$(basename "$file"): passed" | |
| passed=$((passed + 1)) | |
| else | |
| echo "$(basename "$file"): failed" | |
| echo "$output" | tail -20 | |
| failed=$((failed + 1)) | |
| fi | |
| done | |
| echo "Deno tests: $passed passed, $failed failed" | |
| test "$failed" -eq 0 | |
| - name: Run coverage | |
| if: matrix.os == 'ubuntu-latest' && matrix.runtime == 'bun' | |
| working-directory: js | |
| run: bun test --coverage | |
| benchmark: | |
| name: Benchmarks | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes, test] | |
| if: | | |
| !cancelled() && | |
| needs.test.result == 'success' && | |
| (github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' || | |
| needs.detect-changes.outputs.js-changed == 'true' || | |
| needs.detect-changes.outputs.package-changed == 'true') | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| working-directory: js | |
| run: bun install --frozen-lockfile | |
| - name: Run benchmarks | |
| working-directory: js | |
| run: bun run bench | |
| build: | |
| name: Build Package | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes, lint, test] | |
| if: | | |
| !cancelled() && | |
| (github.event_name == 'push' || | |
| github.event_name == 'workflow_dispatch' || | |
| needs.detect-changes.outputs.js-changed == 'true' || | |
| needs.detect-changes.outputs.package-changed == 'true' || | |
| needs.detect-changes.outputs.workflow-changed == 'true') && | |
| needs.lint.result == 'success' && | |
| needs.test.result == 'success' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24.x' | |
| - name: Install dependencies | |
| working-directory: js | |
| run: npm ci | |
| - name: Check package contents | |
| working-directory: js | |
| run: npm pack --dry-run | |
| publish: | |
| name: Publish npm Package | |
| needs: [version-check, lint, test, benchmark, build] | |
| runs-on: ubuntu-latest | |
| if: | | |
| !cancelled() && | |
| github.event_name == 'push' && | |
| github.ref == 'refs/heads/main' && | |
| needs.version-check.outputs.should-publish == 'true' && | |
| needs.lint.result == 'success' && | |
| needs.test.result == 'success' && | |
| (needs.benchmark.result == 'success' || needs.benchmark.result == 'skipped') && | |
| needs.build.result == 'success' | |
| permissions: | |
| contents: write | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24.x' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install dependencies | |
| working-directory: js | |
| run: npm ci | |
| - name: Publish to npm | |
| working-directory: js | |
| run: npm publish --access public | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Create GitHub release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="${{ needs.version-check.outputs.version }}" | |
| git tag -a "js-v$VERSION" -m "JavaScript release v$VERSION" | |
| git push origin "js-v$VERSION" | |
| gh release create "js-v$VERSION" \ | |
| --title "JavaScript v$VERSION" \ | |
| --notes "npm: https://www.npmjs.com/package/${{ needs.version-check.outputs.package-name }}/v/$VERSION" | |
| summary: | |
| name: Summary | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes, test-compilation, check-file-line-limits, version-check, lint, test, benchmark, build, publish] | |
| if: always() | |
| steps: | |
| - name: Workflow summary | |
| run: | | |
| echo "## JavaScript Workflow Summary" | |
| echo "- Event: ${{ github.event_name }}" | |
| echo "- Ref: ${{ github.ref_name }}" | |
| echo "- JS changed: ${{ needs.detect-changes.outputs.js-changed }}" | |
| echo "- Package changed: ${{ needs.detect-changes.outputs.package-changed }}" | |
| echo "- Docs changed: ${{ needs.detect-changes.outputs.docs-changed }}" | |
| echo "- Workflow changed: ${{ needs.detect-changes.outputs.workflow-changed }}" | |
| echo "- Compilation: ${{ needs.test-compilation.result }}" | |
| echo "- File limits: ${{ needs.check-file-line-limits.result }}" | |
| echo "- Version check: ${{ needs.version-check.result }}" | |
| echo "- Lint: ${{ needs.lint.result }}" | |
| echo "- Test: ${{ needs.test.result }}" | |
| echo "- Benchmarks: ${{ needs.benchmark.result }}" | |
| echo "- Build: ${{ needs.build.result }}" | |
| echo "- Publish: ${{ needs.publish.result }}" |