Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions .github/workflows/ci-matrix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Generated by `flext_infra codegen conform` for flext-cli.
# === SECTION: header (managed) ===
# Source: template (base/.github/workflows/ci-matrix.yml.j2)
# Free: no
# End SECTION: header
# Multi-environment CI base: proves the project bootstrap and canonical Make
# verbs work identically across distros, macOS, and Windows. The CI invokes
# the project's own Make surface; it never reimplements bootstrap.
# Runs only on main (direct push or non-draft PR targeting main).
---
name: ci-matrix

# === SECTION: triggers (managed) ===
# Source: main promotion only (integration branch uses blocking ci.yml alone)
"on":
push:
branches: [main]
pull_request:
branches: [main]
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch: {}
# End SECTION: triggers

# === SECTION: permissions (managed) ===
# Source: template (minimal read-only permissions)
permissions:
contents: read
# End SECTION: permissions

# === SECTION: concurrency (managed) ===
# Source: template (one run per workflow+ref)
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# End SECTION: concurrency

jobs:
# === SECTION: distro-matrix (managed) ===
# Source: template + config:github_actions.checkout (distro list is template literal by design)
distro-matrix:
# Clean-machine proof per distro: build the distro image (which runs the
# full project bootstrap at image-build time), then smoke the verb surface
# inside the built container.
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
distro: [ubuntu, debian, fedora, alpine, arch]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: false
- name: Build ${{ matrix.distro }} image
run: >-
docker build
-f tests/fixtures/ci/docker/${{ matrix.distro }}.Dockerfile
-t ci-matrix-${{ matrix.distro }}
.
- name: Bootstrap + verb smoke (${{ matrix.distro }})
run: |
docker run --rm ci-matrix-${{ matrix.distro }} make help
docker run --rm ci-matrix-${{ matrix.distro }} make check
# End SECTION: distro-matrix

# === SECTION: macos (managed) ===
# Source: template + config:github_actions.checkout/setup-python/mise/setup-uv
macos:
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: macos-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: false
- name: Setup Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version-file: .python-version
- name: Install mise toolchain
uses: jdx/mise-action@dba19683ed58901619b14f395a24841710cb4925 # v4.1.0
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
enable-cache: true
- name: Bootstrap
run: make setup
- name: Verb surface
run: make help
# End SECTION: macos

# === SECTION: windows (managed) ===
# Source: template + config:github_actions.checkout/setup-python/mise/setup-uv
windows:
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: windows-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: false
- name: Setup Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version-file: .python-version
- name: Install mise toolchain
uses: jdx/mise-action@dba19683ed58901619b14f395a24841710cb4925 # v4.1.0
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
enable-cache: true
- name: Bootstrap
shell: bash
run: make setup
- name: Verb surface
shell: bash
run: make help
# End SECTION: windows
63 changes: 46 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,73 @@
# Generated by flext_infra.github.workflows - DO NOT EDIT
# Generated by flext_infra codegen for flext-cli — DO NOT EDIT
# === SECTION: header (managed) ===
# Source: template (base/.github/workflows/ci.yml.j2)
# Free: no
# End SECTION: header

name: CI

on:
pull_request:
# === SECTION: triggers (managed) ===
# Source: operator CI policy — integration push = blocking CI only;
# main push/PR (non-draft) = blocking CI; draft and other branches = none.
"on":
push:
branches:
- dev
- develop
- 0.12.0-dev
- main
pull_request:
branches:
- main
workflow_dispatch:
types: [opened, synchronize, reopened, ready_for_review]
# End SECTION: triggers

# === SECTION: permissions (managed) ===
# Source: template (minimal read-only permissions)
permissions:
contents: read
# End SECTION: permissions

jobs:
# === SECTION: ci job (managed) ===
# Source: template + config:github_actions.*
ci:
name: ci
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
timeout-minutes: 60
env:
CI: Y
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: recursive
submodules: false
fetch-depth: 0

- name: Setup Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: "3.13"
- name: Install mise toolchain
uses: jdx/mise-action@dba19683ed58901619b14f395a24841710cb4925 # v4.1.0

- name: Install uv
uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
with:
enable-cache: true
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0


- name: Setup (blocking)
- name: setup (blocking)
run: make setup

- name: Check (blocking)
- name: gen (blocking)
run: make gen APPLY=Y

- name: fmt (blocking)
run: make fmt APPLY=Y

- name: fix (blocking)
run: make fix APPLY=Y

- name: check (blocking)
run: make check

- name: Test (advisory)
continue-on-error: true
- name: test (blocking)
run: make test

# End SECTION: ci job
52 changes: 52 additions & 0 deletions tests/fixtures/ci/docker/alpine.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Generated by `flext_infra codegen conform` for flext_cli.
# === SECTION: header (managed) ===
# Source: template (base/tests/fixtures/ci/docker/alpine.Dockerfile.j2)
# Free: no
# End SECTION: header
# Clean-machine proof: project bootstrap + canonical make verbs on Alpine
# (musl, POSIX /bin/sh at runtime; bash installed for the project scripts).
FROM alpine:3.21

# === SECTION: base packages (managed) ===
# Source: template (distro-specific package list)
RUN apk add --no-cache \
bash ca-certificates curl git make build-base icu-dev icu-libs
# End SECTION: base packages

# === SECTION: managed tool bootstrap (managed) ===
# Source: config:python_version, template (installer URLs)
# mise installs the supported Python 3.13 family.
# uv is supplied by the managed environment without a project patch pin.
RUN curl -fsSL https://mise.run | sh
# uv is intentionally supplied by the caller environment; install it explicitly
# in clean-machine images so the project bootstrap can resolve dependencies.
RUN curl -fsSL https://astral.sh/uv/install.sh | sh
# tokei (and any future cargo-backed mise tool) needs a Rust toolchain.
RUN curl -fsSL https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
# go is required for mise-managed beads (go:github.com/steveyegge/beads/cmd/bd).
RUN curl -fsSL https://go.dev/dl/go1.23.4.linux-amd64.tar.gz | tar -C /usr/local -xzf - \
&& ln -sf /usr/local/go/bin/go /usr/local/bin/go
ENV PATH="/usr/local/go/bin:/root/.local/bin:/root/.cargo/bin:/root/.local/share/mise/shims:${PATH}"
# End SECTION: managed tool bootstrap

WORKDIR /workspace
COPY . .

# === SECTION: mise install (managed) ===
# Source: computed (reads .mise.toml from copied workspace)
RUN mise trust .mise.toml && mise install --yes
# End SECTION: mise install

# === SECTION: bootstrap proof (managed) ===
# Source: template (clean-machine bootstrap through the canonical verb)
# The image exists to PROVE that a clean machine can bootstrap this project
# with nothing but the declared toolchain. It therefore runs the canonical
# setup verb fail-closed: any non-zero status fails the build. An earlier
# revision wrapped this in `set +e` and soft-passed whenever the output
# mentioned uv.lock/flext-core, which turned the proof into a bypass -- a
# broken bootstrap still produced a green image.
RUN make setup
# End SECTION: bootstrap proof

ENTRYPOINT []
CMD ["/bin/bash", "-lc", "make help"]
54 changes: 54 additions & 0 deletions tests/fixtures/ci/docker/arch.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Generated by `flext_infra codegen conform` for flext_cli.
# === SECTION: header (managed) ===
# Source: template (base/tests/fixtures/ci/docker/arch.Dockerfile.j2)
# Free: no
# End SECTION: header
# Clean-machine proof: project bootstrap + canonical make verbs on Arch Linux.
FROM archlinux:base

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# === SECTION: base packages (managed) ===
# Source: template (distro-specific package list)
RUN pacman -Syu --noconfirm --needed \
bash ca-certificates curl git make base-devel icu \
&& pacman -Scc --noconfirm
# End SECTION: base packages

# === SECTION: managed tool bootstrap (managed) ===
# Source: config:python_version, template (installer URLs)
# mise installs the supported Python 3.13 family.
# uv is supplied by the managed environment without a project patch pin.
RUN curl -fsSL https://mise.run | sh
# uv is intentionally supplied by the caller environment; install it explicitly
# in clean-machine images so the project bootstrap can resolve dependencies.
RUN curl -fsSL https://astral.sh/uv/install.sh | sh
# tokei (and any future cargo-backed mise tool) needs a Rust toolchain.
RUN curl -fsSL https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
# go is required for mise-managed beads (go:github.com/steveyegge/beads/cmd/bd).
RUN curl -fsSL https://go.dev/dl/go1.23.4.linux-amd64.tar.gz | tar -C /usr/local -xzf - \
&& ln -sf /usr/local/go/bin/go /usr/local/bin/go
ENV PATH="/usr/local/go/bin:/root/.local/bin:/root/.cargo/bin:/root/.local/share/mise/shims:${PATH}"
# End SECTION: managed tool bootstrap

WORKDIR /workspace
COPY . .

# === SECTION: mise install (managed) ===
# Source: computed (reads .mise.toml from copied workspace)
RUN mise trust .mise.toml && mise install --yes
# End SECTION: mise install

# === SECTION: bootstrap proof (managed) ===
# Source: template (clean-machine bootstrap through the canonical verb)
# The image exists to PROVE that a clean machine can bootstrap this project
# with nothing but the declared toolchain. It therefore runs the canonical
# setup verb fail-closed: any non-zero status fails the build. An earlier
# revision wrapped this in `set +e` and soft-passed whenever the output
# mentioned uv.lock/flext-core, which turned the proof into a bypass -- a
# broken bootstrap still produced a green image.
RUN make setup
# End SECTION: bootstrap proof

ENTRYPOINT []
CMD ["make", "help"]
55 changes: 55 additions & 0 deletions tests/fixtures/ci/docker/debian.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Generated by `flext_infra codegen conform` for flext_cli.
# === SECTION: header (managed) ===
# Source: template (base/tests/fixtures/ci/docker/debian.Dockerfile.j2)
# Free: no
# End SECTION: header
# Clean-machine proof: project bootstrap + canonical make verbs on Debian.
FROM debian:bookworm-slim

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# === SECTION: base packages (managed) ===
# Source: template (distro-specific package list)
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bash ca-certificates curl git make build-essential libicu-dev \
&& rm -rf /var/lib/apt/lists/*
# End SECTION: base packages

# === SECTION: managed tool bootstrap (managed) ===
# Source: config:python_version, template (installer URLs)
# mise installs the supported Python 3.13 family.
# uv is supplied by the managed environment without a project patch pin.
RUN curl -fsSL https://mise.run | sh
# uv is intentionally supplied by the caller environment; install it explicitly
# in clean-machine images so the project bootstrap can resolve dependencies.
RUN curl -fsSL https://astral.sh/uv/install.sh | sh
# tokei (and any future cargo-backed mise tool) needs a Rust toolchain.
RUN curl -fsSL https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
# go is required for mise-managed beads (go:github.com/steveyegge/beads/cmd/bd).
RUN curl -fsSL https://go.dev/dl/go1.23.4.linux-amd64.tar.gz | tar -C /usr/local -xzf - \
&& ln -sf /usr/local/go/bin/go /usr/local/bin/go
ENV PATH="/usr/local/go/bin:/root/.local/bin:/root/.cargo/bin:/root/.local/share/mise/shims:${PATH}"
# End SECTION: managed tool bootstrap

WORKDIR /workspace
COPY . .

# === SECTION: mise install (managed) ===
# Source: computed (reads .mise.toml from copied workspace)
RUN mise trust .mise.toml && mise install --yes
# End SECTION: mise install

# === SECTION: bootstrap proof (managed) ===
# Source: template (clean-machine bootstrap through the canonical verb)
# The image exists to PROVE that a clean machine can bootstrap this project
# with nothing but the declared toolchain. It therefore runs the canonical
# setup verb fail-closed: any non-zero status fails the build. An earlier
# revision wrapped this in `set +e` and soft-passed whenever the output
# mentioned uv.lock/flext-core, which turned the proof into a bypass -- a
# broken bootstrap still produced a green image.
RUN make setup
# End SECTION: bootstrap proof

ENTRYPOINT []
CMD ["make", "help"]
Loading
Loading