invoke-ai/InvokeAI

14 workflows · maturity 67% · 6 patterns · GitHub ↗

Security 3.57/100

Practices

✓ Matrix✓ Permissions○ Security scan○ AI review✓ Cache✓ Concurrency✓ Reusable workflows

Detected patterns

Security dimensions

permissions
3.6
security scan
0
supply chain
0
secret handling
0
harden runner
0

Workflows (14)

build-container matrix perms .github/workflows/build-container.yml
Triggers
push, workflow_dispatch
Runs on
ubuntu-latest
Jobs
docker
Matrix
gpu-driver→ cpu, cuda, rocm
Actions
docker/metadata-action, docker/setup-buildx-action, docker/login-action, docker/build-push-action
Commands
  • echo "----- Free space before cleanup" df -h sudo rm -rf /usr/share/dotnet sudo rm -rf "$AGENT_TOOLSDIRECTORY" if [ -f /mnt/swapfile ]; then sudo swapoff /mnt/swapfile sudo rm -rf /mnt/swapfile fi if [ -d /mnt ]; then sudo chmod -R 777 /mnt echo '{"data-root": "/mnt/docker-root"}' | sudo tee /etc/docker/daemon.json sudo systemctl restart docker fi echo "----- Free space after cleanup" df -h
View raw YAML
name: build container image
on:
  push:
    branches:
      - 'main'
    paths:
      - 'pyproject.toml'
      - '.dockerignore'
      - 'invokeai/**'
      - 'docker/Dockerfile'
      - 'docker/docker-entrypoint.sh'
      - 'workflows/build-container.yml'
    tags:
      - 'v*.*.*'
  workflow_dispatch:
    inputs:
      push-to-registry:
        description: Push the built image to the container registry
        required: false
        type: boolean
        default: false

permissions:
  contents: write
  packages: write

jobs:
  docker:
    if: github.event.pull_request.draft == false
    strategy:
      fail-fast: false
      matrix:
        gpu-driver:
        - cuda
        - cpu
        - rocm
    runs-on: ubuntu-latest
    name: ${{ matrix.gpu-driver }}
    env:
      # torch/arm64 does not support GPU currently, so arm64 builds
      # would not be GPU-accelerated.
      # re-enable arm64 if there is sufficient demand.
      # PLATFORMS: 'linux/amd64,linux/arm64'
      PLATFORMS: 'linux/amd64'
    steps:
      - name: Free up more disk space on the runner
        # https://github.com/actions/runner-images/issues/2840#issuecomment-1284059930
        # the /mnt dir has 70GBs of free space
        # /dev/sda1        74G   28K   70G   1% /mnt
        # According to some online posts the /mnt is not always there, so checking before setting docker to use it
        run: |
          echo "----- Free space before cleanup"
          df -h
          sudo rm -rf /usr/share/dotnet
          sudo rm -rf "$AGENT_TOOLSDIRECTORY"
          if [ -f /mnt/swapfile ]; then
            sudo swapoff /mnt/swapfile
            sudo rm -rf /mnt/swapfile
          fi
          if [ -d /mnt ]; then
            sudo chmod -R 777 /mnt
            echo '{"data-root": "/mnt/docker-root"}' | sudo tee /etc/docker/daemon.json
            sudo systemctl restart docker
          fi
          echo "----- Free space after cleanup"
          df -h

      - name: Checkout
        uses: actions/checkout@v4

      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v5
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          images: |
            ghcr.io/${{ github.repository }}
          tags: |
            type=ref,event=branch
            type=ref,event=tag
            type=pep440,pattern={{version}}
            type=pep440,pattern={{major}}.{{minor}}
            type=pep440,pattern={{major}}
            type=sha,enable=true,prefix=sha-,format=short
          flavor: |
            latest=${{ matrix.gpu-driver == 'cuda' && github.ref == 'refs/heads/main' }}
            suffix=-${{ matrix.gpu-driver }},onlatest=false

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          platforms: ${{ env.PLATFORMS }}

      - name: Login to GitHub Container Registry
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build container
        timeout-minutes: 40
        id: docker_build
        uses: docker/build-push-action@v6
        with:
          context: .
          file: docker/Dockerfile
          platforms: ${{ env.PLATFORMS }}
          build-args: |
            GPU_DRIVER=${{ matrix.gpu-driver }}
          push: ${{ github.ref == 'refs/heads/main' || github.ref_type == 'tag' || github.event.inputs.push-to-registry }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          # cache-from: |
          #   type=gha,scope=${{ github.ref_name }}-${{ matrix.gpu-driver }}
          #   type=gha,scope=main-${{ matrix.gpu-driver }}
          # cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-${{ matrix.gpu-driver }}
build-wheel .github/workflows/build-wheel.yml
Triggers
workflow_dispatch, workflow_call
Runs on
ubuntu-latest
Jobs
build-installer
Commands
  • pip install --upgrade build
  • ./scripts/build_wheel.sh
View raw YAML
# Builds and uploads python build artifacts.

name: build wheel

on:
  workflow_dispatch:
  workflow_call:

jobs:
  build-installer:
    runs-on: ubuntu-latest
    timeout-minutes: 5 # expected run time: <2 min
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: setup python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: pip
          cache-dependency-path: pyproject.toml

      - name: install pypa/build
        run: pip install --upgrade build

      - name: setup frontend
        uses: ./.github/actions/install-frontend-deps

      - name: build wheel
        id: build_wheel
        run: ./scripts/build_wheel.sh

      - name: upload python distribution artifact
        uses: actions/upload-artifact@v4
        with:
          name: dist
          path: ${{ steps.build_wheel.outputs.DIST_PATH }}
clean-caches .github/workflows/clean-caches.yml
Triggers
pull_request, workflow_dispatch
Runs on
ubuntu-latest
Jobs
cleanup
Commands
  • gh extension install actions/gh-actions-cache REPO=${{ github.repository }} BRANCH=${{ github.ref }} echo "Fetching list of cache key" cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH | cut -f 1 ) ## Setting this to not fail the workflow while deleting cache keys. set +e echo "Deleting caches..." for cacheKey in $cacheKeysForPR do gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm done echo "Done"
View raw YAML
name: cleanup caches by a branch
on:
  pull_request:
    types:
      - closed
  workflow_dispatch:

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Cleanup
        run: |
          gh extension install actions/gh-actions-cache

          REPO=${{ github.repository }}
          BRANCH=${{ github.ref }}

          echo "Fetching list of cache key"
          cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH | cut -f 1 )

          ## Setting this to not fail the workflow while deleting cache keys.
          set +e
          echo "Deleting caches..."
          for cacheKey in $cacheKeysForPR
          do
              gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
          done
          echo "Done"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
close-inactive-issues .github/workflows/close-inactive-issues.yml
Triggers
schedule
Runs on
ubuntu-latest
Jobs
close-issues
Actions
actions/stale
View raw YAML
name: Close inactive issues
on:
  schedule:
    - cron: "00 4 * * *"

env:
  DAYS_BEFORE_ISSUE_STALE: 30
  DAYS_BEFORE_ISSUE_CLOSE: 14

jobs:
  close-issues:
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: write
    steps:
      - uses: actions/stale@v8
        with:
          days-before-issue-stale: ${{ env.DAYS_BEFORE_ISSUE_STALE }}
          days-before-issue-close: ${{ env.DAYS_BEFORE_ISSUE_CLOSE }}
          stale-issue-label: "Inactive Issue"
          stale-issue-message: "There has been no activity in this issue for ${{ env.DAYS_BEFORE_ISSUE_STALE }} days. If this issue is still being experienced, please reply with an updated confirmation that the issue is still being experienced with the latest release."
          close-issue-message: "Due to inactivity, this issue was automatically closed. If you are still experiencing the issue, please recreate the issue."
          days-before-pr-stale: -1
          days-before-pr-close: -1
          only-labels: "bug"
          exempt-issue-labels: "Active Issue"
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          operations-per-run: 500
frontend-checks .github/workflows/frontend-checks.yml
Triggers
push, pull_request, merge_group, workflow_dispatch, workflow_call
Runs on
ubuntu-latest
Jobs
frontend-checks
Actions
tj-actions/changed-files
Commands
  • pnpm lint:tsc
  • pnpm lint:dpdm
  • pnpm lint:eslint
  • pnpm lint:prettier
  • pnpm lint:knip
View raw YAML
# Runs frontend code quality checks.
#
# Checks for changes to frontend files before running the checks.
# If always_run is true, always runs the checks.

name: 'frontend checks'

on:
  push:
    branches:
      - 'main'
  pull_request:
    types:
      - 'ready_for_review'
      - 'opened'
      - 'synchronize'
  merge_group:
  workflow_dispatch:
    inputs:
      always_run:
        description: 'Always run the checks'
        required: true
        type: boolean
        default: true
  workflow_call:
    inputs:
      always_run:
        description: 'Always run the checks'
        required: true
        type: boolean
        default: true

defaults:
  run:
    working-directory: invokeai/frontend/web

jobs:
  frontend-checks:
    runs-on: ubuntu-latest
    timeout-minutes: 10 # expected run time: <2 min
    steps:
      - uses: actions/checkout@v4

      - name: check for changed frontend files
        if: ${{ inputs.always_run != true }}
        id: changed-files
        # Pinned to the _hash_ for v45.0.9 to prevent supply-chain attacks.
        # See:
        # - CVE-2025-30066
        # - https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised
        # - https://github.com/tj-actions/changed-files/issues/2463
        uses: tj-actions/changed-files@a284dc1814e3fd07f2e34267fc8f81227ed29fb8
        with:
          files_yaml: |
            frontend:
              - 'invokeai/frontend/web/**'

      - name: install dependencies
        if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
        uses: ./.github/actions/install-frontend-deps

      - name: tsc
        if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
        run: 'pnpm lint:tsc'
        shell: bash

      - name: dpdm
        if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
        run: 'pnpm lint:dpdm'
        shell: bash

      - name: eslint
        if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
        run: 'pnpm lint:eslint'
        shell: bash

      - name: prettier
        if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
        run: 'pnpm lint:prettier'
        shell: bash

      - name: knip
        if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
        run: 'pnpm lint:knip'
        shell: bash
frontend-tests .github/workflows/frontend-tests.yml
Triggers
push, pull_request, merge_group, workflow_dispatch, workflow_call
Runs on
ubuntu-latest
Jobs
frontend-tests
Actions
tj-actions/changed-files
Commands
  • pnpm test:no-watch
View raw YAML
# Runs frontend tests.
#
# Checks for changes to frontend files before running the tests.
# If always_run is true, always runs the tests.

name: 'frontend tests'

on:
  push:
    branches:
      - 'main'
  pull_request:
    types:
      - 'ready_for_review'
      - 'opened'
      - 'synchronize'
  merge_group:
  workflow_dispatch:
    inputs:
      always_run:
        description: 'Always run the tests'
        required: true
        type: boolean
        default: true
  workflow_call:
    inputs:
      always_run:
        description: 'Always run the tests'
        required: true
        type: boolean
        default: true

defaults:
  run:
    working-directory: invokeai/frontend/web

jobs:
  frontend-tests:
    runs-on: ubuntu-latest
    timeout-minutes: 10 # expected run time: <2 min
    steps:
      - uses: actions/checkout@v4

      - name: check for changed frontend files
        if: ${{ inputs.always_run != true }}
        id: changed-files
        # Pinned to the _hash_ for v45.0.9 to prevent supply-chain attacks.
        # See:
        # - CVE-2025-30066
        # - https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised
        # - https://github.com/tj-actions/changed-files/issues/2463
        uses: tj-actions/changed-files@a284dc1814e3fd07f2e34267fc8f81227ed29fb8
        with:
          files_yaml: |
            frontend:
              - 'invokeai/frontend/web/**'

      - name: install dependencies
        if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
        uses: ./.github/actions/install-frontend-deps

      - name: vitest
        if: ${{ steps.changed-files.outputs.frontend_any_changed == 'true' || inputs.always_run == true }}
        run: 'pnpm test:no-watch'
        shell: bash
label-pr .github/workflows/label-pr.yml
Triggers
pull_request_target
Runs on
ubuntu-latest
Jobs
labeler
Actions
actions/labeler
View raw YAML
name: 'label PRs'
on:
  - pull_request_target

jobs:
  labeler:
    permissions:
      contents: read
      pull-requests: write
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: label PRs
        uses: actions/labeler@v5
        with:
          configuration-path: .github/pr_labels.yml
lfs-checks .github/workflows/lfs-checks.yml
Triggers
push, pull_request, merge_group, workflow_dispatch
Runs on
ubuntu-latest
Jobs
lfs-check
Actions
ppremk/lfs-warning
View raw YAML
# Checks that large files and LFS-tracked files are properly checked in with pointer format.
# Uses https://github.com/ppremk/lfs-warning to detect LFS issues.

name: 'lfs checks'

on:
  push:
    branches:
      - 'main'
  pull_request:
    types:
      - 'ready_for_review'
      - 'opened'
      - 'synchronize'
  merge_group:
  workflow_dispatch:

jobs:
  lfs-check:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    permissions:
      # Required to label and comment on the PRs
      pull-requests: write
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: check lfs files
        uses: ppremk/lfs-warning@v3.3
mkdocs-material perms .github/workflows/mkdocs-material.yml
Triggers
push, workflow_dispatch
Runs on
ubuntu-latest
Jobs
deploy
Commands
  • echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
  • python -m pip install ".[docs]"
  • mkdocs gh-deploy --force
View raw YAML
# This is a mostly a copy-paste from https://github.com/squidfunk/mkdocs-material/blob/master/docs/publishing-your-site.md

name: mkdocs

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  contents: write

jobs:
  deploy:
    if: github.event.pull_request.draft == false
    runs-on: ubuntu-latest
    env:
      REPO_URL: '${{ github.server_url }}/${{ github.repository }}'
      REPO_NAME: '${{ github.repository }}'
      SITE_URL: 'https://${{ github.repository_owner }}.github.io/InvokeAI'

    steps:
      - name: checkout
        uses: actions/checkout@v5

      - name: setup python
        uses: actions/setup-python@v6
        with:
          python-version: '3.12'
          cache: pip
          cache-dependency-path: pyproject.toml

      - name: set cache id
        run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV

      - name: use cache
        uses: actions/cache@v4
        with:
          key: mkdocs-material-${{ env.cache_id }}
          path: .cache
          restore-keys: |
            mkdocs-material-

      - name: install dependencies
        run: python -m pip install ".[docs]"

      - name: build & deploy
        run: mkdocs gh-deploy --force
python-checks .github/workflows/python-checks.yml
Triggers
push, pull_request, merge_group, workflow_dispatch, workflow_call
Runs on
ubuntu-latest
Jobs
python-checks
Actions
tj-actions/changed-files, astral-sh/setup-uv
Commands
  • uv run --no-project scripts/check_classifiers.py ./pyproject.toml
  • uv tool run ruff@0.11.2 check --output-format=github .
  • uv tool run ruff@0.11.2 format --check .
View raw YAML
# Runs python code quality checks.
#
# Checks for changes to python files before running the checks.
# If always_run is true, always runs the checks.
#
# TODO: Add mypy or pyright to the checks.

name: 'python checks'

on:
  push:
    branches:
      - 'main'
  pull_request:
    types:
      - 'ready_for_review'
      - 'opened'
      - 'synchronize'
  merge_group:
  workflow_dispatch:
    inputs:
      always_run:
        description: 'Always run the checks'
        required: true
        type: boolean
        default: true
  workflow_call:
    inputs:
      always_run:
        description: 'Always run the checks'
        required: true
        type: boolean
        default: true

jobs:
  python-checks:
    env:
      # uv requires a venv by default - but for this, we can simply use the system python
      UV_SYSTEM_PYTHON: 1
    runs-on: ubuntu-latest
    timeout-minutes: 5 # expected run time: <1 min
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: check for changed python files
        if: ${{ inputs.always_run != true }}
        id: changed-files
        # Pinned to the _hash_ for v45.0.9 to prevent supply-chain attacks.
        # See:
        # - CVE-2025-30066
        # - https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised
        # - https://github.com/tj-actions/changed-files/issues/2463
        uses: tj-actions/changed-files@a284dc1814e3fd07f2e34267fc8f81227ed29fb8
        with:
          files_yaml: |
            python:
              - 'pyproject.toml'
              - 'invokeai/**'
              - '!invokeai/frontend/web/**'
              - 'tests/**'

      - name: setup uv
        if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
        uses: astral-sh/setup-uv@v5
        with:
          version: '0.6.10'
          enable-cache: true

      - name: check pypi classifiers
        if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
        run: uv run --no-project scripts/check_classifiers.py ./pyproject.toml

      - name: ruff check
        if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
        run: uv tool run ruff@0.11.2 check --output-format=github .
        shell: bash

      - name: ruff format
        if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
        run: uv tool run ruff@0.11.2 format --check .
        shell: bash
python-tests matrix .github/workflows/python-tests.yml
Triggers
push, pull_request, merge_group, workflow_dispatch, workflow_call
Runs on
${{ matrix.os }}
Jobs
matrix
Matrix
include, include.extra-index-url, include.github-env, include.os, include.platform, platform, python-version→ $GITHUB_ENV, $env:GITHUB_ENV, 3.11, 3.12, https://download.pytorch.org/whl/cpu, linux-cpu, macOS-14, macos-default, ubuntu-24.04, windows-2022, windows-cpu
Actions
nschloe/action-cached-lfs-checkout, tj-actions/changed-files, astral-sh/setup-uv
Commands
  • uv pip install --editable ".[test]"
  • pytest
View raw YAML
# Runs python tests on a matrix of python versions and platforms.
#
# Checks for changes to python files before running the tests.
# If always_run is true, always runs the tests.

name: 'python tests'

on:
  push:
    branches:
      - 'main'
  pull_request:
    types:
      - 'ready_for_review'
      - 'opened'
      - 'synchronize'
  merge_group:
  workflow_dispatch:
    inputs:
      always_run:
        description: 'Always run the tests'
        required: true
        type: boolean
        default: true
  workflow_call:
    inputs:
      always_run:
        description: 'Always run the tests'
        required: true
        type: boolean
        default: true

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

jobs:
  matrix:
    strategy:
      matrix:
        python-version:
          - '3.11'
          - '3.12'
        platform:
          - linux-cpu
          - macos-default
          - windows-cpu
        include:
          - platform: linux-cpu
            os: ubuntu-24.04
            extra-index-url: 'https://download.pytorch.org/whl/cpu'
            github-env: $GITHUB_ENV
          - platform: macos-default
            os: macOS-14
            github-env: $GITHUB_ENV
          - platform: windows-cpu
            os: windows-2022
            github-env: $env:GITHUB_ENV
    name: 'py${{ matrix.python-version }}: ${{ matrix.platform }}'
    runs-on: ${{ matrix.os }}
    timeout-minutes: 15 # expected run time: 2-6 min, depending on platform
    env:
      PIP_USE_PEP517: '1'
      UV_SYSTEM_PYTHON: 1

    steps:
      - name: checkout
        # https://github.com/nschloe/action-cached-lfs-checkout
        uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2

      - name: check for changed python files
        if: ${{ inputs.always_run != true }}
        id: changed-files
        # Pinned to the _hash_ for v45.0.9 to prevent supply-chain attacks.
        # See:
        # - CVE-2025-30066
        # - https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised
        # - https://github.com/tj-actions/changed-files/issues/2463
        uses: tj-actions/changed-files@a284dc1814e3fd07f2e34267fc8f81227ed29fb8
        with:
          files_yaml: |
            python:
              - 'pyproject.toml'
              - 'invokeai/**'
              - '!invokeai/frontend/web/**'
              - 'tests/**'

      - name: setup uv
        if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
        uses: astral-sh/setup-uv@v5
        with:
          version: '0.6.10'
          enable-cache: true
          python-version: ${{ matrix.python-version }}

      - name: setup python
        if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}

      - name: install dependencies
        if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
        env:
          UV_INDEX: ${{ matrix.extra-index-url }}
        run: uv pip install --editable ".[test]"

      - name: run pytest
        if: ${{ steps.changed-files.outputs.python_any_changed == 'true' || inputs.always_run == true }}
        run: pytest
release .github/workflows/release.yml
Triggers
push, workflow_dispatch
Runs on
ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
check-version, frontend-checks, frontend-tests, python-checks, python-tests, build, publish-testpypi, publish-pypi
Actions
samuelcolvin/check-python-version, pypa/gh-action-pypi-publish, pypa/gh-action-pypi-publish
View raw YAML
# Main release workflow. Triggered on tag push or manual trigger.
#
# - Runs all code checks and tests
# - Verifies the app version matches the tag version.
# - Builds the installer and build, uploading them as artifacts.
# - Publishes to TestPyPI and PyPI. Both are conditional on the previous steps passing and require a manual approval.
#
# See docs/RELEASE.md for more information on the release process.

name: release

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:

jobs:
  check-version:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: check python version
        uses: samuelcolvin/check-python-version@v4
        id: check-python-version
        with:
          version_file_path: invokeai/version/invokeai_version.py

  frontend-checks:
    uses: ./.github/workflows/frontend-checks.yml
    with:
      always_run: true

  frontend-tests:
    uses: ./.github/workflows/frontend-tests.yml
    with:
      always_run: true

  python-checks:
    uses: ./.github/workflows/python-checks.yml
    with:
      always_run: true

  python-tests:
    uses: ./.github/workflows/python-tests.yml
    with:
      always_run: true

  build:
    uses: ./.github/workflows/build-wheel.yml

  publish-testpypi:
    runs-on: ubuntu-latest
    timeout-minutes: 5 # expected run time: <1 min
    needs:
      [
        check-version,
        frontend-checks,
        frontend-tests,
        python-checks,
        python-tests,
        build,
      ]
    environment:
      name: testpypi
      url: https://test.pypi.org/p/invokeai
    permissions:
      id-token: write
    steps:
      - name: download distribution from build job
        uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/

      - name: publish distribution to TestPyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          repository-url: https://test.pypi.org/legacy/

  publish-pypi:
    runs-on: ubuntu-latest
    timeout-minutes: 5 # expected run time: <1 min
    needs:
      [
        check-version,
        frontend-checks,
        frontend-tests,
        python-checks,
        python-tests,
        build,
      ]
    environment:
      name: pypi
      url: https://pypi.org/p/invokeai
    permissions:
      id-token: write
    steps:
      - name: download distribution from build job
        uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/

      - name: publish distribution to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
typegen-checks .github/workflows/typegen-checks.yml
Triggers
push, pull_request, merge_group, workflow_dispatch, workflow_call
Runs on
ubuntu-22.04
Jobs
typegen-checks
Actions
tj-actions/changed-files, astral-sh/setup-uv
Commands
  • echo "----- Free space before cleanup" df -h sudo rm -rf /usr/share/dotnet sudo rm -rf "$AGENT_TOOLSDIRECTORY" if [ -f /mnt/swapfile ]; then sudo swapoff /mnt/swapfile sudo rm -rf /mnt/swapfile fi echo "----- Free space after cleanup" df -h
  • uv pip install --editable .
  • cp invokeai/frontend/web/src/services/api/schema.ts invokeai/frontend/web/src/services/api/schema_orig.ts
  • cd invokeai/frontend/web && uv run ../../../scripts/generate_openapi_schema.py | pnpm typegen
  • if ! diff invokeai/frontend/web/src/services/api/schema.ts invokeai/frontend/web/src/services/api/schema_orig.ts; then echo "Files are different!"; exit 1; fi
View raw YAML
# Runs typegen schema quality checks.
# Frontend types should match the server.
#
# Checks for changes to files before running the checks.
# If always_run is true, always runs the checks.

name: 'typegen checks'

on:
  push:
    branches:
      - 'main'
  pull_request:
    types:
      - 'ready_for_review'
      - 'opened'
      - 'synchronize'
  merge_group:
  workflow_dispatch:
    inputs:
      always_run:
        description: 'Always run the checks'
        required: true
        type: boolean
        default: true
  workflow_call:
    inputs:
      always_run:
        description: 'Always run the checks'
        required: true
        type: boolean
        default: true

jobs:
  typegen-checks:
    runs-on: ubuntu-22.04
    timeout-minutes: 15 # expected run time: <5 min
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: Free up more disk space on the runner
        # https://github.com/actions/runner-images/issues/2840#issuecomment-1284059930
        run: |
          echo "----- Free space before cleanup"
          df -h
          sudo rm -rf /usr/share/dotnet
          sudo rm -rf "$AGENT_TOOLSDIRECTORY"
          if [ -f /mnt/swapfile ]; then
            sudo swapoff /mnt/swapfile
            sudo rm -rf /mnt/swapfile
          fi
          echo "----- Free space after cleanup"
          df -h

      - name: check for changed files
        if: ${{ inputs.always_run != true }}
        id: changed-files
        # Pinned to the _hash_ for v45.0.9 to prevent supply-chain attacks.
        # See:
        # - CVE-2025-30066
        # - https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised
        # - https://github.com/tj-actions/changed-files/issues/2463
        uses: tj-actions/changed-files@a284dc1814e3fd07f2e34267fc8f81227ed29fb8
        with:
          files_yaml: |
            src:
              - 'pyproject.toml'
              - 'invokeai/**'

      - name: setup uv
        if: ${{ steps.changed-files.outputs.src_any_changed == 'true' || inputs.always_run == true }}
        uses: astral-sh/setup-uv@v5
        with:
          version: '0.6.10'
          enable-cache: true
          python-version: '3.11'

      - name: setup python
        if: ${{ steps.changed-files.outputs.src_any_changed == 'true' || inputs.always_run == true }}
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: install dependencies
        if: ${{ steps.changed-files.outputs.src_any_changed == 'true' || inputs.always_run == true }}
        env:
          UV_INDEX: ${{ matrix.extra-index-url }}
        run: uv pip install --editable .

      - name: install frontend dependencies
        if: ${{ steps.changed-files.outputs.src_any_changed == 'true' || inputs.always_run == true }}
        uses: ./.github/actions/install-frontend-deps

      - name: copy schema
        if: ${{ steps.changed-files.outputs.src_any_changed == 'true' || inputs.always_run == true }}
        run: cp invokeai/frontend/web/src/services/api/schema.ts invokeai/frontend/web/src/services/api/schema_orig.ts
        shell: bash

      - name: generate schema
        if: ${{ steps.changed-files.outputs.src_any_changed == 'true' || inputs.always_run == true }}
        run: cd invokeai/frontend/web && uv run ../../../scripts/generate_openapi_schema.py | pnpm typegen
        shell: bash

      - name: compare files
        if: ${{ steps.changed-files.outputs.src_any_changed == 'true' || inputs.always_run == true }}
        run: |
          if ! diff invokeai/frontend/web/src/services/api/schema.ts invokeai/frontend/web/src/services/api/schema_orig.ts; then
            echo "Files are different!";
            exit 1;
          fi
        shell: bash
uv-lock-checks .github/workflows/uv-lock-checks.yml
Triggers
push, pull_request, merge_group, workflow_dispatch, workflow_call
Runs on
ubuntu-latest
Jobs
uv-lock-checks
Actions
tj-actions/changed-files, astral-sh/setup-uv
Commands
  • uv lock --locked
View raw YAML
# Check the `uv` lockfile for consistency with `pyproject.toml`.
#
# If this check fails, you should run `uv lock` to update the lockfile.

name: 'uv lock checks'

on:
  push:
    branches:
      - 'main'
  pull_request:
    types:
      - 'ready_for_review'
      - 'opened'
      - 'synchronize'
  merge_group:
  workflow_dispatch:
    inputs:
      always_run:
        description: 'Always run the checks'
        required: true
        type: boolean
        default: true
  workflow_call:
    inputs:
      always_run:
        description: 'Always run the checks'
        required: true
        type: boolean
        default: true

jobs:
  uv-lock-checks:
    env:
      # uv requires a venv by default - but for this, we can simply use the system python
      UV_SYSTEM_PYTHON: 1
    runs-on: ubuntu-latest
    timeout-minutes: 5 # expected run time: <1 min
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: check for changed python files
        if: ${{ inputs.always_run != true }}
        id: changed-files
        # Pinned to the _hash_ for v45.0.9 to prevent supply-chain attacks.
        # See:
        # - CVE-2025-30066
        # - https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised
        # - https://github.com/tj-actions/changed-files/issues/2463
        uses: tj-actions/changed-files@a284dc1814e3fd07f2e34267fc8f81227ed29fb8
        with:
          files_yaml: |
            uvlock-pyprojecttoml:
              - 'pyproject.toml'
              - 'uv.lock'

      - name: setup uv
        if: ${{ steps.changed-files.outputs.uvlock-pyprojecttoml_any_changed == 'true' || inputs.always_run == true }}
        uses: astral-sh/setup-uv@v5
        with:
          version: '0.6.10'
          enable-cache: true

      - name: check lockfile
        if: ${{ steps.changed-files.outputs.uvlock-pyprojecttoml_any_changed == 'true' || inputs.always_run == true }}
        run: uv lock --locked # this will exit with 1 if the lockfile is not consistent with pyproject.toml
        shell: bash