Extensions on GitHub

Brady Johnston

2025-09-19

Slides are Available

bradyajohnston.github.io/talks/bcon2025

Who am I?

I’m Brady!

  • Biochemist & Biophysicist turned 3D Animator

  • 2022 talk about Visualising Viruses

Molecular Nodes

  • Import & Animation of molecular data sets
  • Brings data inside of Blender
  • Builds around Geometry Nodes

Molecular Nodes

Install as a python package?

  • Also built and distributed via pypi.org
# !pip install bpy molecularnodes

import molecularnodes as mn
canvas = mn.Canvas(
    engine=mn.scene.Cycles(samples=16),
    resolution=(1280, 720),
    transparent=True
    )

mol = mn.Molecule.fetch("1BNA")
mol.add_style("vdw")

canvas.frame_view(mol, (3.14, 3.14 / 2, 0))
canvas.snapshot()

Install as a python package?

Figure 1: X-ray crystallography structure of a fragment of DNA.

databpy

  • ‘numpy-like’ interfaces to attributes on objects
# set the x component for the first 10 verts to 1.0
obj["position"][:10, 0] = 1.0 

# add 1 to x, 2 to y, 3 to z component of position
obj["position"] += np.array([1, 2, 3]) 

# infers data types for storage and retrieval
obj["att_name"] = np.zeros(len(obj), dypte=int)
obj["att_name"] 

# get and set attributes on non-point domains
obj.store_named_attribute(
  data=np.zeros((len(bob), 4, 4), dtype=float),
  name="a_matrix",
  domain=db.AttributeDomains.FACE
  )
obj.named_attribute()

Building on GitHub

Molecular Nodes on GitHub

Why build on GitHub?

  • Not paid at all, just benefited a lot from using it
  • Other platforms offer similar (CodeBerg etc.) I just have experience with GitHub
  • Free file hosting (within ‘reason’)
  • Free compute for automated testing and deployment (public projects)
  • Increased visibility (>1,000 ⭐️!)(not guaranteed)

Building & Distributing MN

Building & Distributing MN

  • Run tests against different versions of Blender (including daily builds)
  • Run tests against bpy installed via pip for automated pipelines
  • Download and bundle .whl files with extension
  • Upload extension to GitHub & Extensions platform

Testing your Add-ons

Check out Spencer’s talk on testing add-ons:

Anatomy of a GitHub Action

  • Runs on hardware managed by GitHub
    • Free for public projects
    • Mac / Windows / Linux
    • Mid-power machines, no GPU
  • Can use your own hardware as a GHA runner
    • My PC with an RTX 3090 runs any GPU worklods back in Australia

Running Tests

name: tests

on: 
    push:
      branches: ["main"]
    pull_request:
      branches: ["*"]
    
jobs:
    blender:
        runs-on: ${{ matrix.os }}
        strategy:
            max-parallel: 4
            fail-fast: false
            matrix:
              version: ["4.5", "daily"]
              os: [ubuntu-latest, macos-latest, windows-latest]
        steps:
            - uses: actions/checkout@v4
            - uses: BradyAJohnston/setup-blender@v4
              with:
                version: ${{ matrix.version }}
            - name: Install in Blender
              run: |
                blender -b -P tests/python.py -- -m pip install ".[test]"
            - name: Run Tests
              run: |
                blender -b -P tests/run.py -- -vv tests --cov --cov-report=xml
    
            - name: Expose coverage as a CI download 
              uses: actions/upload-artifact@v4
              if: matrix.os == 'ubuntu-latest' && matrix.version == '4.2.5'
              with:
                name: coverage.xml
                path: coverage.xml

            - name: Upload coverage reports to Codecov
              if: matrix.os == 'ubuntu-latest'
              uses: codecov/codecov-action@v3

Breaking 5.0 Changes

Tests are run daily on MacOS, Windows & Linux against the latest alpha builds from Blender.

  • BLENDER_EEVEE_NEXT renamed to BLENDER_EEVEE #855
  • Compositor no longer has use_nodes #971
  • Set Curve Resolution not updating datablock #141721
  • bpy.data.materials.new() starts with empty node tree (not BSDF + Output) #980

Distributing on GitHub

‘Old School’

  • have your add-on be ‘top-level’ on GitHub - users just download the .zip of the repo and install
  • Never clear when updates are out or what version is ‘released’
  • package up .zip and create a GitHub release - users download from release page and check back for updates
  • Clearer which version is currently released, requires users to manually update

Hip & New and Cool and Fresh with ‘Extensions’

  • Host an index.json somewhere accessible on the network which points to files, allows automatic updates
  • Host an index.json and files all on GitHub
    • Simple index for single add-on on a single repo
    • A repo that indexes and builds multiple add-ons from multiple sources

A live example

github.com/BradyAJohnston/monkeymadness

Figure 2: The hottest new monkey-spawning add-on! (But is there a bug?)

Your Personal Extensions Repo

  • Build and release add-ons on GitHub (through automations!) in their own repos
  • Compile multiple add-ons in a single subscribeable repo
  • Users add ‘your personal repo’ - they get updates just like they would from the official Extensions platform

How is it Built?

name: Download Release Files

on:
  push:
    branches: ["main"]
  schedule:
    - cron: '0 0 * * *'

jobs:
  build-website:
    runs-on: macos-latest
    permissions: write-all
    steps:
      - uses: actions/checkout@v4
      - uses: quarto-dev/quarto-actions/setup@v2
      - uses: bradyajohnston/setup-blender@v4
        with: 
          version: latest
      - name: Install uv
        uses: astral-sh/setup-uv@v4
        with:
            version: "latest"
    
      - name: Get Release Assets
        run: |
          uv run --with requests scripts/download.py
        env:
          GITHUB_TOKEN: ${{ github.token }}
      - name: Generate index.json
        run: |
          blender --command extension server-generate --repo-dir=repo
    
      - name: Quarto Render
        run: |
          uv run --with pyyaml quarto render
    
      - name: Publish to GitHub Pages (and render)
        uses: quarto-dev/quarto-actions/publish@v2
        with:
            target: gh-pages
            path: .
            render: false
        env:
            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Distributing your own Extensions

Details and built: https://bradyajohnston.github.io/extensions/ Subscribe with:

https://bradyajohnston.github.io/extensions/index.json

Blext

Thanks!