Skip to content

Biome Ecosystem CI #404

Biome Ecosystem CI

Biome Ecosystem CI #404

Workflow file for this run

name: Biome Ecosystem CI
permissions:
contents: none
on:
schedule:
- cron: "0 5 * * 1,3,5" # monday,wednesday,friday 5AM
workflow_dispatch:
inputs:
biome-ref:
description: biomejs/biome reference to checkout
type: string
default: main
jobs:
build-biome:
name: Build Biome (${{ inputs.biome-ref || 'main' }})
timeout-minutes: 20
runs-on: depot-ubuntu-24.04-arm-64
steps:
- name: Checkout Biome
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: biomejs/biome
ref: ${{ inputs.biome-ref }}
- name: Install toolchain
uses: moonrepo/setup-rust@abb2d32350334249b178c401e5ec5836e0cd88d3 # v1.3
with:
cache-target: release
cache-base: main
- name: Build Biome binary
env:
# We set `BIOME_VERSION` to disable the recommended rules from the nursery group
# The version needs to be different from 0.0.0
BIOME_VERSION: 0.0.1
RUSTFLAGS: -C debug-assertions
run: |
cargo build --bin biome --release
- name: Upload Biome binary
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
if-no-files-found: error
retention-days: 10
name: biome
path: ./target/release/biome
test-ecosystem:
strategy:
fail-fast: false
matrix:
include:
# Add projects to test here
# Supported fields:
# - id: identifier
# - repository: GitHub repository to checkout
# - ref: ref to checkout (default is the default branch)
# - working-directory: where to execute `biome` (default is the root of the repository)
# The path is relative to the root of the repository
# - arguments: extra arguments to pass to the `biome check` command (default is `.`)
- id: n8n
repository: n8n-io/n8n
- id: django
repository: django/django
- id: cline
repository: cline/cline
- id: astro
repository: withastro/astro
- id: cherry-studio
repository: CherryHQ/cherry-studio
- id: novu
repository: novuhq/novu
- id: refine
repository: refinedev/refine
- id: discordjs
repository: discordjs/discord.js
- id: promptfoo
repository: promptfoo/promptfoo
- id: eliza
repository: elizaOS/eliza
- id: react-native-vector-icons
repository: oblador/react-native-vector-icons
- id: vercel
repository: vercel/vercel
- id: midday
repository: midday-ai/midday
- id: coder
repository: coder/coder
- id: ten-framework
repository: TEN-framework/ten-framework
- id: typebot
repository: baptisteArno/typebot.io
- id: coss
repository: cosscom/coss
- id: superset
repository: superset-sh/superset
- id: fast
repository: microsoft/fast
- id: react-native-vision-camera
repository: mrousavy/react-native-vision-camera
- id: nhost
repository: nhost/nhost
- id: openstatus
repository: openstatusHQ/openstatus
- id: kreuzberg
repository: kreuzberg-dev/kreuzberg
- id: podman-desktop
repository: podman-desktop/podman-desktop
- id: anytype-ts
repository: anyproto/anytype-ts
- id: wagmi
repository: wevm/wagmi
- id: stagewise
repository: stagewise-io/stagewise
- id: vike
repository: vikejs/vike
- id: rivet
repository: rivet-dev/rivet
- id: ark
repository: chakra-ui/ark
- id: modern-js
repository: web-infra-dev/modern.js
- id: FluidFramework
repository: microsoft/FluidFramework
- id: freelens
repository: freelensapp/freelens
- id: epicenter
repository: EpicenterHQ/epicenter
- id: pollinations
repository: pollinations/pollinations
- id: fern
repository: fern-api/fern
- id: livestore
repository: livestorejs/livestore
- id: vscode-material-icon-theme
repository: material-extensions/vscode-material-icon-theme
- id: scanpy
repository: scverse/scanpy
- id: indico
repository: indico/indico
- id: parabol
repository: ParabolInc/parabol
- id: carbon
repository: crbnos/carbon
- id: c15t
repository: c15t/c15t
name: Test ${{ matrix.id }}
needs: build-biome
timeout-minutes: 5
runs-on: depot-ubuntu-24.04-arm-16
steps:
- name: Download Biome binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: biome
path: bin/
- run: |
chmod +x bin/biome
echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH
- name: Checkout ${{ matrix.repository }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ${{ matrix.repository }}
sparse-checkout: ${{ matrix.working-directory }}
ref: ${{ matrix.ref }}
path: repository
- name: Migrate
continue-on-error: true
working-directory: repository/${{ matrix.working-directory }}
run: |
biome migrate --write
- name: Run Biome check and generate report
if: ${{ ! cancelled() }}
id: test
working-directory: repository/${{ matrix.working-directory }}
run: |
# Define report file path
REPORT_FILE="$GITHUB_WORKSPACE/biome-report-${{ matrix.id }}.json"
# Run biome check with JSON reporter to file, capture exit code but always succeed
# Using --reporter=json with --reporter-file writes JSON to the file
# The diagnostic limit is automatically lifted when using non-default reporters
set +e
biome check --error-on-warnings --reporter=json --reporter-file="$REPORT_FILE" ${{ matrix.arguments || '.' }}
BIOME_EXIT_CODE=$?
set -e
# Set outcome based on exit code
if [ $BIOME_EXIT_CODE -eq 0 ]; then
echo "outcome=success" >> "$GITHUB_OUTPUT"
else
echo "outcome=failure" >> "$GITHUB_OUTPUT"
fi
# Debug: Check if file was created
echo "Checking report file: $REPORT_FILE"
if [ -f "$REPORT_FILE" ]; then
FILE_SIZE=$(wc -c < "$REPORT_FILE")
echo "Report file exists, size: $FILE_SIZE bytes"
if [ $FILE_SIZE -gt 0 ]; then
echo "First 200 chars:"
head -c 200 "$REPORT_FILE" || true
fi
else
echo "ERROR: Report file was not created by Biome!"
fi
# If the report file doesn't exist or is empty, create error placeholder
if [ ! -f "$REPORT_FILE" ] || [ ! -s "$REPORT_FILE" ]; then
echo "Creating error placeholder because file is missing or empty"
echo '{"error": true}' > "$REPORT_FILE"
fi
- name: Upload Biome report
# Don't save the report if the biome binary was not built on main.
if: ${{ always() && (! inputs.biome-ref || inputs.biome-ref == 'main') }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
if-no-files-found: error
retention-days: 10
name: biome-report-${{ matrix.id }}
path: ${{ github.workspace }}/biome-report-${{ matrix.id }}.json
- name: Save outcome JSON
run: |
echo '{"id": "${{ matrix.id }}", "outcome": "${{ steps.test.outputs.outcome }}"}' > "$GITHUB_WORKSPACE/outcome-${{ matrix.id }}.json"
- name: Upload outcome
if: ${{ always() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
if-no-files-found: error
retention-days: 1
name: outcome-${{ matrix.id }}
path: ${{ github.workspace }}/outcome-${{ matrix.id }}.json
notify-discord:
name: Notify Discord
needs: test-ecosystem
runs-on: depot-ubuntu-24.04-arm-16
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: "24"
- name: Download all outcome artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: outcome-*
path: outcomes/
merge-multiple: true
- name: Download all biome report artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: biome-report-*
path: reports/
merge-multiple: true
- name: Download previous biome report artifacts
uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6.0.0
with:
workflow_conclusion: completed
search_artifacts: true
if_no_artifact_found: warn
name_is_regexp: true
name: biome-report-.*
path: previous-reports/
skip_unpack: false
- name: Aggregate results
id: aggregate
run: |
MESSAGE=$(node --experimental-strip-types scripts/index.ts \
--outcomes-dir outcomes \
--reports-dir reports \
--previous-reports-dir previous-reports \
--biome-ref "${{ inputs.biome-ref || 'main' }}" \
--run-url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}")
# Use heredoc to handle multiline output
{
echo 'message<<EOF'
echo "$MESSAGE"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Send Discord notification
uses: tsickert/discord-webhook@b217a69502f52803de774ded2b1ab7c282e99645 # v7.0.0
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
content: ${{ steps.aggregate.outputs.message }}