Skip to content

CI Badge

Add an axm-init check-score badge to your project.

You probably already have it

If you created your package with axm-init scaffold, you're done — scaffolding already emits a correct .github/workflows/axm-quality.yml that runs the axm-init checks, generates the badge JSON (with the AXM logo inlined the right way), and pushes it to the gh-pages/badges/ branch. Most users need nothing further; just add the README snippet below.

The rest of this page is for retrofitting an existing repo that wasn't scaffolded.

Retrofit an existing repo

1. Create the workflow

Add .github/workflows/axm-quality.yml:

YAML
name: axm-init quality

on:
  push:
    branches: [main]

permissions:
  contents: write

jobs:
  init:
    name: AXM Init & Badge
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: astral-sh/setup-uv@v7
      - run: uv python install 3.12

# Verify action versions are current before using:
# - actions/checkout: https://github.com/actions/checkout/releases
# - astral-sh/setup-uv: https://github.com/astral-sh/setup-uv/releases
# - peaceiris/actions-gh-pages: https://github.com/peaceiris/actions-gh-pages/releases

      - name: Run AXM Init check
        id: init
        run: |
          RESULT=$(uvx axm-init check . --json) || true
          SCORE=$(echo "$RESULT" | jq '.score')
          GRADE=$(echo "$RESULT" | jq -r '.grade')
          echo "score=$SCORE" >> "$GITHUB_OUTPUT"
          echo "grade=$GRADE" >> "$GITHUB_OUTPUT"
          echo "📋 AXM Init: Score $SCORE/100 — Grade $GRADE"

      - name: Choose badge color
        id: color
        run: |
          SCORE=$(echo "${{ steps.init.outputs.score }}" | cut -d. -f1)
          if [ "$SCORE" -ge 95 ]; then COLOR="brightgreen"
          elif [ "$SCORE" -ge 80 ]; then COLOR="green"
          elif [ "$SCORE" -ge 60 ]; then COLOR="yellow"
          else COLOR="red"; fi
          echo "color=$COLOR" >> "$GITHUB_OUTPUT"

      - name: Generate badge JSON
        run: |
          mkdir -p badges
          LOGO_FILE=$(mktemp)
          curl -fsSL https://raw.githubusercontent.com/axm-protocols/axm-forge/main/assets/logo.svg \
            -o "$LOGO_FILE" || true

          if [ -s "$LOGO_FILE" ]; then
            jq -n \
              --arg score "${{ steps.init.outputs.score }}" \
              --arg color "${{ steps.color.outputs.color }}" \
              --rawfile logo "$LOGO_FILE" \
              '{
                schemaVersion: 1,
                label: "axm-init",
                message: "\($score)%",
                color: $color,
                style: "flat",
                logoSvg: $logo
              }' > badges/axm-init.json
          else
            jq -n \
              --arg score "${{ steps.init.outputs.score }}" \
              --arg color "${{ steps.color.outputs.color }}" \
              '{
                schemaVersion: 1,
                label: "axm-init",
                message: "\($score)%",
                color: $color,
                style: "flat"
              }' > badges/axm-init.json
          fi

      - name: Push badge to gh-pages
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_branch: gh-pages
          publish_dir: ./badges
          destination_dir: badges
          keep_files: true
          commit_message: "badge: update axm-init score"

uvx vs uv run

Use uvx axm-init for external projects (installs from PyPI).

Logo handling

shields.io renders the AXM logo from an inlined SVG in the logoSvg JSON field. The SVG is fetched from the canonical forge URL:

Text Only
https://raw.githubusercontent.com/axm-protocols/axm-forge/main/assets/logo.svg

The logo is inlined only when it is fetched successfully and non-empty — an empty logoSvg makes shields.io reject the badge. When the fetch fails, the badge JSON is emitted without the logoSvg key (graceful degradation to a logo-less badge).

2. Add the badge to your README

By AXM convention the badge links to the canonical docs page, not to the Actions tab:

Markdown
[![axm-init](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/YOUR_ORG/YOUR_REPO/gh-pages/badges/axm-init.json)](https://forge.axm-protocols.io/init/)

The badge JSON lives at gh-pages/badges/axm-init.json for a standalone package. In a uv-workspace monorepo, per-member badges live under badges/<member-name>/axm-init.json (extra subdir), plus a workspace aggregate at badges/axm-init.json — point each member's README at its own subdir path.

3. Push to main

The badge will appear after the first workflow run pushes to gh-pages.

Stale badge?

After the first publish (or a fix), the badge may keep showing "package not found" or a stale score: shields.io caches the JSON and GitHub's camo image proxy re-caches on top. The badge refreshes on its own within ~1h. To force a refresh or check the real current state, hit the raw JSON or the shields endpoint with a cache-buster query param (e.g. append ?v=2) rather than trusting the rendered image.

Color Thresholds

Score Color
≥ 95 🟢 brightgreen
≥ 80 🟢 green
≥ 60 🟡 yellow
< 60 🔴 red