Skip to content
Latchkey

Nikola CI workflow (getnikola/nikola)

The Nikola CI workflow from getnikola/nikola, explained and optimized by Latchkey.

D

CI health: D - needs work

Point runs-on at Latchkey and get caching, run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: getnikola/nikola.github/workflows/ci.ymlLicense MITView source

What it does

This is the Nikola CI workflow from the getnikola/nikola repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Nikola CI
on:
  # Run on all pushes to master (including merge of PR)
  push:
    branches: master
  # Run on all changes in pull requests
  pull_request:
  # Run every Saturday at 17:10 UTC to ensure stability (dependency changes not breaking things)
  schedule:
    - cron: '10 17 * * 6'

jobs:
  nikola:
    name: Nikola tests (Python ${{ matrix.python }} on ${{ matrix.image }})
    strategy:
      fail-fast: false
      matrix:
        python: ['3.10', '3.11', '3.12', '3.13', '3.14']
        image:
          - ubuntu-latest
        include:
          - python: '3.14'
            image: macos-latest
          - python: '3.14'
            image: windows-latest
    runs-on: '${{ matrix.image }}'
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '${{ matrix.python }}'
      - name: Install Nikola
        run: |
          python -m pip install --upgrade-strategy eager -U .[extras,tests]
      - name: Run tests
        run: |
          py.test tests/
      - name: Run nikola
        run: |
          nikola
      - name: Run nikola help
        run: |
          nikola help

  baseline:
    name: Baseline testing (Python ${{ matrix.python }} on ${{ matrix.image }})
    strategy:
      fail-fast: false
      matrix:
        python: ['3.14']
        image:
          - ubuntu-latest
    runs-on: '${{ matrix.image }}'
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '${{ matrix.python }}'
      - name: Install extra requirements
        run: |
          python -m pip install --upgrade-strategy eager freezegun
      - name: Install Nikola
        run: |
          python -m pip install --upgrade-strategy eager -U .[extras]
      - name: Compare to baseline
        run: |
          scripts/baseline.sh check

  flake8:
    name: Linting (flake8, pydocstyle)
    strategy:
      matrix:
        python:
          - '3.14'
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '${{ matrix.python }}'
      - name: Install requirements
        run: |
          python -m pip install --upgrade-strategy eager -U flake8 pydocstyle
      - name: Run flake8
        run: |
          flake8 nikola/ tests/
      - name: Run pydocstyle
        run: |
          pydocstyle --count --match-dir='(?!^\\.)(?!data).*' nikola/

  basereq:
    name: Build demo site with base requirements
    strategy:
      matrix:
        python: ['3.11', '3.12', '3.13', '3.14']
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '${{ matrix.python }}'
      - name: Install Nikola
        run: |
          python -m pip install --upgrade-strategy eager -U .
      - name: Run help
        run: |
          nikola help
        working-directory: /
      - name: Run init
        run: |
          nikola init -qd nsite
        working-directory: /tmp/
      - name: Run build
        run: |
          nikola build
        working-directory: /tmp/nsite

The same workflow, on Latchkey

Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.

name: Nikola CI
on:
  # Run on all pushes to master (including merge of PR)
  push:
    branches: master
  # Run on all changes in pull requests
  pull_request:
  # Run every Saturday at 17:10 UTC to ensure stability (dependency changes not breaking things)
  schedule:
    - cron: '10 17 * * 6'
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  nikola:
    timeout-minutes: 30
    name: Nikola tests (Python ${{ matrix.python }} on ${{ matrix.image }})
    strategy:
      fail-fast: false
      matrix:
        python: ['3.10', '3.11', '3.12', '3.13', '3.14']
        image:
          - ubuntu-latest
        include:
          - python: '3.14'
            image: macos-latest
          - python: '3.14'
            image: windows-latest
    runs-on: '${{ matrix.image }}'
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          cache: 'pip'
          python-version: '${{ matrix.python }}'
      - name: Install Nikola
        run: |
          python -m pip install --upgrade-strategy eager -U .[extras,tests]
      - name: Run tests
        run: |
          py.test tests/
      - name: Run nikola
        run: |
          nikola
      - name: Run nikola help
        run: |
          nikola help
 
  baseline:
    timeout-minutes: 30
    name: Baseline testing (Python ${{ matrix.python }} on ${{ matrix.image }})
    strategy:
      fail-fast: false
      matrix:
        python: ['3.14']
        image:
          - ubuntu-latest
    runs-on: '${{ matrix.image }}'
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          cache: 'pip'
          python-version: '${{ matrix.python }}'
      - name: Install extra requirements
        run: |
          python -m pip install --upgrade-strategy eager freezegun
      - name: Install Nikola
        run: |
          python -m pip install --upgrade-strategy eager -U .[extras]
      - name: Compare to baseline
        run: |
          scripts/baseline.sh check
 
  flake8:
    timeout-minutes: 30
    name: Linting (flake8, pydocstyle)
    strategy:
      matrix:
        python:
          - '3.14'
    runs-on: latchkey-small
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          cache: 'pip'
          python-version: '${{ matrix.python }}'
      - name: Install requirements
        run: |
          python -m pip install --upgrade-strategy eager -U flake8 pydocstyle
      - name: Run flake8
        run: |
          flake8 nikola/ tests/
      - name: Run pydocstyle
        run: |
          pydocstyle --count --match-dir='(?!^\\.)(?!data).*' nikola/
 
  basereq:
    timeout-minutes: 30
    name: Build demo site with base requirements
    strategy:
      matrix:
        python: ['3.11', '3.12', '3.13', '3.14']
    runs-on: latchkey-small
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          cache: 'pip'
          python-version: '${{ matrix.python }}'
      - name: Install Nikola
        run: |
          python -m pip install --upgrade-strategy eager -U .
      - name: Run help
        run: |
          nikola help
        working-directory: /
      - name: Run init
        run: |
          nikola init -qd nsite
        working-directory: /tmp/
      - name: Run build
        run: |
          nikola build
        working-directory: /tmp/nsite
 

What changed

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 4 jobs (11 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow