sneak preview: uv, Click, Rich, tui; flavors #149
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: For each commit and PR | |
| on: | |
| push: | |
| branches: | |
| - "main" | |
| pull_request: | |
| permissions: | |
| contents: read | |
| packages: write | |
| env: | |
| DEFAULT_FLAVOR_ID: "trixie-slim" | |
| FORCE_COLOR: "1" | |
| jobs: | |
| # ------------------------------------------------------------------- | |
| # Lint — ruff (lint + format) and pyright (type checking) | |
| # ------------------------------------------------------------------- | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Install lint tools | |
| run: make lint-install | |
| - name: Lint | |
| run: make lint | |
| # ------------------------------------------------------------------- | |
| # Download tools (containerd, runc, nerdctl, CNI plugins) | |
| # ------------------------------------------------------------------- | |
| download-tools: | |
| needs: [ lint ] | |
| runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| arch: [ amd64, arm64 ] | |
| env: | |
| ARCH: ${{ matrix.arch }} | |
| MKOSI_MODE: skip | |
| TOOLS_MODE: native | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Restore tools cache | |
| id: tools-cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| mkosi.output/tools/${{ matrix.arch }}/usr/local/bin | |
| mkosi.output/tools/${{ matrix.arch }}/opt/cni | |
| key: tools-${{ matrix.arch }}-${{ hashFiles('captain/tools.py') }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Download tools | |
| env: | |
| TOOLS_MODE: native | |
| run: uv run captain tools | |
| - name: Save tools cache | |
| if: github.ref == 'refs/heads/main' && steps.tools-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: | | |
| mkosi.output/tools/${{ matrix.arch }}/usr/local/bin | |
| mkosi.output/tools/${{ matrix.arch }}/opt/cni | |
| key: tools-${{ matrix.arch }}-${{ hashFiles('captain/tools.py') }} | |
| - name: Upload tools artifacts | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: tools-${{ matrix.arch }} | |
| path: | | |
| mkosi.output/tools/${{ matrix.arch }}/usr/local/bin | |
| mkosi.output/tools/${{ matrix.arch }}/opt/cni | |
| retention-days: 1 | |
| # ------------------------------------------------------------------- | |
| # Build Docker builder image, per-arch; pushes to ghcr.io. | |
| # ------------------------------------------------------------------- | |
| build-dockerfile: | |
| needs: [ lint ] | |
| runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: { arch: [ amd64, arm64 ] } | |
| env: | |
| ARCH: ${{ matrix.arch }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build Dockerfile | |
| run: uv run captain builder | |
| # only if a PR, since we don't want to push images for PRs from forks | |
| if: github.event_name == 'pull_request' | |
| - name: Build Dockerfile and push | |
| run: uv run captain builder --push | |
| # only if not a PR, since we don't want to push images for PRs from forks (no perms to push) | |
| if: github.event_name != 'pull_request' | |
| # ------------------------------------------------------------------- | |
| # Download tools (containerd, runc, nerdctl, CNI plugins) | |
| # ------------------------------------------------------------------- | |
| build-captainos-kernel: | |
| needs: [ build-dockerfile ] | |
| runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| arch: [ amd64, arm64 ] | |
| env: | |
| ARCH: ${{ matrix.arch }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Restore kernel cache | |
| id: kernel-cache | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| mkosi.output/kernel/${{ matrix.arch }} | |
| key: kernel-${{ matrix.arch }}-${{ hashFiles('**/*.py', 'kernel.configs/*', 'Dockerfile', 'pyproject.toml') }} | |
| # any "previous" cache can also be useful; we'll just churn cache misses more often, but that's better than a complete cache miss and rebuild every time | |
| restore-keys: | | |
| kernel-${{ matrix.arch }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Build kernel | |
| run: uv run captain --verbose kernel | |
| - name: Save kernel cache | |
| if: github.ref == 'refs/heads/main' && steps.tools-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: | | |
| mkosi.output/kernel/${{ matrix.arch }} | |
| key: kernel-${{ matrix.arch }}-${{ hashFiles('**/*.py', 'kernel.configs/*', 'Dockerfile', 'pyproject.toml') }} | |
| - name: Upload kernel artifacts | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: kernel-${{ matrix.arch }} | |
| path: | | |
| mkosi.output/kernel/${{ matrix.arch }} | |
| retention-days: 1 | |
| build-captainos-with-kernel: # only for flavors that require the custom CaptainOS kernel; otherwise, just build-captainos | |
| runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} | |
| needs: [ download-tools, build-dockerfile, build-captainos-kernel ] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { arch: amd64, output_arch: x86_64, captainos_kernel: true, iso: true, FLAVOR_ID: "trixie-slim" } | |
| - { arch: arm64, output_arch: aarch64, captainos_kernel: true, iso: true, FLAVOR_ID: "trixie-slim" } | |
| env: &build_env | |
| ARCH: ${{ matrix.arch }} | |
| MKOSI_MODE: docker | |
| ISO_MODE: docker | |
| FLAVOR_ID: ${{ matrix.FLAVOR_ID }} | |
| steps: &build_steps | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Download tools artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: tools-${{ matrix.arch }} | |
| path: mkosi.output/tools/${{ matrix.arch }} | |
| - name: Download kernel artifacts == ${{ matrix.captainos_kernel }} | |
| uses: actions/download-artifact@v8 | |
| if: ${{ matrix.captainos_kernel }} # only if matrix entry had captainos_kernel: true | |
| with: | |
| name: kernel-${{ matrix.arch }} | |
| path: mkosi.output/kernel/${{ matrix.arch }} | |
| - name: Restore tool binary permissions | |
| run: | | |
| # GitHub Actions artifact upload/download strips execute permissions. | |
| # Restore +x on all tool binaries so they work inside the initramfs. | |
| chmod +x mkosi.output/tools/${{ matrix.arch }}/usr/local/bin/* | |
| chmod +x mkosi.output/tools/${{ matrix.arch }}/opt/cni/bin/* | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Build initramfs | |
| run: uv run captain build # full build, incl initramfs and iso when appropriate | |
| - name: Upload initramfs artifacts | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: initramfs-${{ matrix.FLAVOR_ID }}-${{ matrix.arch }} | |
| # The full 'out/' directory contents, but not any .iso files (if any) since those are uploaded later | |
| path: | | |
| out/ | |
| !out/**/*.iso | |
| retention-days: 1 | |
| # do not upload any .iso files (exclude) | |
| # ------------------------------------------------------------------- | |
| # UEFI-bootable ISO - only for certain flavors (eg trixie-full) | |
| # ------------------------------------------------------------------- | |
| - name: Upload ISO artifact | |
| if: ${{ matrix.iso }} # only if matrix entry had iso: true | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: iso-${{ matrix.FLAVOR_ID }}-${{ matrix.arch }} | |
| path: out/captainos-${{ matrix.FLAVOR_ID }}-${{ matrix.output_arch }}.iso | |
| retention-days: 1 | |
| # ------------------------------------------------------------------- | |
| # Publish per-arch artifacts and compute checksums | |
| # ------------------------------------------------------------------- | |
| - name: Log in to GHCR | |
| if: github.ref == 'refs/heads/main' | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Publish artifacts to GHCR | |
| # only pushes to main, and not PR workflows, should try to push to OCI registry | |
| if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' | |
| env: | |
| TARGET: ${{ matrix.arch }} | |
| run: uv run captain release-publish | |
| build-captainos: # those use regular Debian apt repos for kernels | |
| steps: *build_steps | |
| env: *build_env | |
| runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} | |
| needs: [ download-tools, build-dockerfile ] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { arch: amd64, output_arch: x86_64, captainos_kernel: false, iso: true, FLAVOR_ID: "trixie-full" } | |
| - { arch: arm64, output_arch: aarch64, captainos_kernel: false, iso: true, FLAVOR_ID: "trixie-full" } | |
| - { arch: arm64, output_arch: aarch64, captainos_kernel: false, iso: false, FLAVOR_ID: "trixie-rockchip64" } | |
| - { arch: arm64, output_arch: aarch64, captainos_kernel: false, iso: false, FLAVOR_ID: "trixie-rockchip64-vendor" } | |
| - { arch: arm64, output_arch: aarch64, captainos_kernel: false, iso: false, FLAVOR_ID: "trixie-meson64" } | |
| - { arch: arm64, output_arch: aarch64, captainos_kernel: false, iso: false, FLAVOR_ID: "trixie-armbian-rpi" } | |
| # ------------------------------------------------------------------- | |
| # Publish combined multi-arch image (reuses per-arch registry blobs) | |
| # ------------------------------------------------------------------- | |
| publish-combined: | |
| if: github.ref == 'refs/heads/main' | |
| name: "publish-combined" | |
| runs-on: ubuntu-latest | |
| needs: [ build-captainos ] | |
| env: | |
| ARCH: amd64 | |
| TARGET: combined | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Load shared config | |
| run: cat .github/config.env >> "$GITHUB_ENV" | |
| - name: Download initramfs artifacts (amd64) | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: initramfs-${{ env.DEFAULT_FLAVOR_ID }}-amd64 | |
| path: out | |
| - name: Download ISO artifact (amd64) | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: iso-${{ env.DEFAULT_FLAVOR_ID }}-amd64 | |
| path: out | |
| - name: Download initramfs artifacts (arm64) | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: initramfs-${{ env.DEFAULT_FLAVOR_ID }}-arm64 | |
| path: out | |
| - name: Download ISO artifact (arm64) | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: iso-${{ env.DEFAULT_FLAVOR_ID }}-arm64 | |
| path: out | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Publish combined image to GHCR | |
| # only pushes to main, and not PR workflows, should try to push to OCI registry | |
| if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' | |
| env: | |
| FLAVOR_ID: "${{ env.DEFAULT_FLAVOR_ID }}" | |
| run: uv run captain release-publish |