Initial commit
Label Sync / Label Sync (push) Failing after 1m7s
E2E / reject-invalid (bad-bgp-asn) (push) Skipped
E2E / reject-invalid (bad-mac-address) (push) Skipped
E2E / reject-invalid (bad-repo-url) (push) Skipped
E2E / reject-invalid (bad-vlan-tag) (push) Skipped
E2E / reject-invalid (duplicate-gateway-addrs) (push) Skipped
E2E / reject-invalid (duplicate-node-names) (push) Skipped
E2E / reject-invalid (gateway-node-collision) (push) Skipped
E2E / reject-invalid (missing-dns-token) (push) Skipped
E2E / reject-invalid (nested-cidr-overlap) (push) Skipped
E2E / reject-invalid (node-addr-outside-cidr) (push) Skipped
E2E / reject-invalid (tunnel-without-dns) (push) Skipped
E2E / accept-valid (selfhosted) (push) Skipped
E2E / reject-invalid (missing-known-hosts) (push) Skipped
E2E / reject-invalid (missing-schematic) (push) Skipped
E2E / reject-invalid (partial-bgp) (push) Skipped
E2E / accept-valid (internal) (push) Skipped
E2E / reject-invalid (missing-external-gateway) (push) Skipped
E2E / reject-invalid (node-uses-gateway-addr) (push) Skipped
E2E / reject-invalid (non-canonical-cidr) (push) Skipped
E2E / accept-valid (private) (push) Skipped
E2E / accept-valid (single-node) (push) Skipped
E2E / reject-invalid (overlapping-cidrs) (push) Skipped
E2E / reject-invalid (reserved-node-name) (push) Skipped
E2E / reject-invalid (tiny-svc-cidr) (push) Skipped
E2E / validator-tests (push) Skipped
E2E / accept-valid (direct) (push) Skipped
E2E / accept-valid (multi-controller) (push) Skipped
E2E / accept-valid (no-webhook) (push) Skipped
E2E / accept-valid (public) (push) Skipped

This commit is contained in:
2026-09-15 22:21:43 +03:00
committed by GitHub
commit e502e0ff76
171 changed files with 7520 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: "Flate"
on:
pull_request:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.event.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
filter:
name: Flate - Filter
runs-on: ubuntu-latest
outputs:
changed-files: ${{ steps.changed-files.outputs.changed_files }}
steps:
- name: Get Changed Files
id: changed-files
uses: bjw-s-labs/action-changed-files@a9a36fb08ce06db9b02fbd8026cc2c0945eb9841 # v0.6.0
with:
patterns: kubernetes/**/*
flate:
if: ${{ needs.filter.outputs.changed-files != '[]' }}
needs: filter
name: Flate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 0
- name: Install Flate
uses: home-operations/flate/action@631b76b69c4e58c6f4d1cb01e23616fa61aebafa # v0.6.5
- name: Run Flate
id: flate
run: flate test all -p ./kubernetes/flux/cluster
success:
if: ${{ !cancelled() }}
needs: flate
name: Flate - Success
runs-on: ubuntu-latest
steps:
- name: Any jobs failed?
if: ${{ contains(needs.*.result, 'failure') }}
run: exit 1
- name: All jobs passed or skipped?
if: ${{ !(contains(needs.*.result, 'failure')) }}
run: echo "All jobs passed or skipped" && echo "${{ toJSON(needs.*.result) }}"
+32
View File
@@ -0,0 +1,32 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: "Label Sync"
on:
workflow_dispatch:
push:
branches:
- main
paths:
- .github/labels.yaml
permissions: {}
jobs:
label-sync:
name: Label Sync
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Sync Labels
uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3
with:
config-file: .github/labels.yaml
delete-other-labels: true
+103
View File
@@ -0,0 +1,103 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: "E2E Cluster"
on:
workflow_dispatch:
pull_request:
branches: ["main"]
schedule:
- cron: "30 5 * * *"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
jobs:
bootstrap:
if: ${{ github.repository == 'onedr0p/cluster-template' }}
name: bootstrap (qemu)
runs-on: ubuntu-latest
permissions:
contents: read
services:
git:
image: ghcr.io/charmbracelet/soft-serve:v0.12.2
env:
SOFT_SERVE_GIT_ENABLED: "false"
SOFT_SERVE_LFS_ENABLED: "false"
SOFT_SERVE_SSH_LISTEN_ADDR: "127.0.0.1:23231"
SOFT_SERVE_STATS_ENABLED: "false"
ports:
- 8418:23232
entrypoint: /bin/sh
command: >-
-c "set -eu; ssh-keygen -q -t ed25519 -N '' -f /tmp/admin;
export SOFT_SERVE_INITIAL_ADMIN_KEYS=$(cat /tmp/admin.pub);
/usr/local/bin/soft serve & pid=$!;
until ssh -q -i /tmp/admin -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -p 23231 localhost settings anon-access read-write; do sleep 1; done;
ssh -q -i /tmp/admin -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -p 23231 localhost repo create repo;
wait $pid"
options: >-
--health-cmd "git ls-remote http://localhost:23232/repo.git"
--health-interval 2s
--health-timeout 2s
--health-retries 30
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install QEMU
run: |
sudo apt-get update
sudo apt-get install --yes --no-install-recommends gettext-base qemu-system-x86 qemu-utils ovmf
- name: Setup mise
uses: jdx/mise-action@c2a87611a18de5b3828c5652fe268e992400cb5c # v4.3.0
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- name: Boot maintenance-mode nodes
id: cluster
uses: home-operations/talosctl-cluster-action@fb6a31bf5de43218acc80d2e23958a16eee7380c # v0.2.2
with:
config: ./.github/template-tests/e2e/talos-cluster.yaml
cache: true
- name: Export cluster environment
env:
CONTROLPLANE_IPS: "${{ steps.cluster.outputs.controlplane-ips }}"
GATEWAY: "${{ steps.cluster.outputs.gateway }}"
WORKER_IPS: "${{ steps.cluster.outputs.worker-ips }}"
run: |
echo "E2E_CONTROLPLANE_IPS=$CONTROLPLANE_IPS" >> "$GITHUB_ENV"
echo "E2E_WORKER_IPS=$WORKER_IPS" >> "$GITHUB_ENV"
echo "E2E_GATEWAY=$GATEWAY" >> "$GITHUB_ENV"
echo "E2E_CIDR=10.9.0.0/24" >> "$GITHUB_ENV"
echo "E2E_STATE=$RUNNER_TEMP/template-e2e" >> "$GITHUB_ENV"
- name: Prepare cluster
run: bash ./.github/template-tests/e2e/cluster.sh prepare
- name: Build healthy cluster foundation
run: bash ./.github/template-tests/e2e/cluster.sh foundation
- name: Test Flux SOPS
id: flux-sops
run: bash ./.github/template-tests/e2e/cluster.sh flux-sops
background: true
- name: Test networking
id: networking
run: bash ./.github/template-tests/e2e/cluster.sh networking
background: true
- name: Wait for E2E tests
wait: [flux-sops, networking]
- name: Summarize cluster
run: bash ./.github/template-tests/e2e/cluster.sh summary
+176
View File
@@ -0,0 +1,176 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: "E2E"
on:
workflow_dispatch:
push:
branches:
- main
pull_request:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.event.number || github.ref }}
cancel-in-progress: true
permissions: {}
jobs:
validate-invalid:
if: ${{ github.repository == 'onedr0p/cluster-template' }}
name: reject-invalid (${{ matrix.fixture }})
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
fixture:
- overlapping-cidrs
- nested-cidr-overlap
- non-canonical-cidr
- tiny-svc-cidr
- duplicate-gateway-addrs
- duplicate-node-names
- reserved-node-name
- bad-mac-address
- bad-repo-url
- missing-known-hosts
- node-addr-outside-cidr
- node-uses-gateway-addr
- gateway-node-collision
- bad-vlan-tag
- bad-bgp-asn
- missing-dns-token
- tunnel-without-dns
- missing-external-gateway
- missing-schematic
- partial-bgp
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup mise
uses: jdx/mise-action@c2a87611a18de5b3828c5652fe268e992400cb5c # v4.3.0
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- name: Assert schema rejects ${{ matrix.fixture }}.toml
run: |
fixture=./.github/template-tests/invalid/${{ matrix.fixture }}.toml
if uv run --quiet --locked --no-dev ./template/scripts/validate.py "$fixture" >/dev/null 2>&1; then
echo "::error::schema accepted invalid fixture ${{ matrix.fixture }} (expected rejection)"
exit 1
fi
echo "schema correctly rejected ${{ matrix.fixture }}"
# Also surface the actual error message in the log for debuggability.
uv run --quiet --locked --no-dev ./template/scripts/validate.py "$fixture" || true
validator-tests:
if: ${{ github.repository == 'onedr0p/cluster-template' }}
name: validator-tests
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup mise
uses: jdx/mise-action@c2a87611a18de5b3828c5652fe268e992400cb5c # v4.3.0
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- name: Run validator tests
run: uv run --quiet --locked pytest ./template/scripts/test_validate.py
validate-valid:
if: ${{ github.repository == 'onedr0p/cluster-template' }}
name: accept-valid (${{ matrix.fixture }})
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
fixture:
- public
- private
- selfhosted
- no-webhook
- internal
- direct
- single-node
- multi-controller
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup mise
uses: jdx/mise-action@c2a87611a18de5b3828c5652fe268e992400cb5c # v4.3.0
with:
experimental: true
install_args: --locked
- name: Run init recipe
run: just init
- name: Prepare files
run: |
cp ./.github/template-tests/valid/${{ matrix.fixture }}.toml cluster.toml
echo '{"AccountTag":"fake","TunnelSecret":"fake","TunnelID":"fake"}' > cloudflare-tunnel.json
touch kubeconfig
- name: Assert cluster.toml passes the JSON Schema
run: taplo check --schema "file://$PWD/cluster.schema.json" ./cluster.toml
- name: Run configure recipe
run: just configure
# Rendered output must already match the format-yaml pre-commit hook,
# otherwise every `just configure` shows up as formatting churn.
- name: Assert rendered output is formatted
run: oxfmt --check ./.sops.yaml ./bootstrap ./kubernetes ./talos
- name: Install flate
uses: home-operations/flate/action@631b76b69c4e58c6f4d1cb01e23616fa61aebafa # v0.6.5
with:
base: ""
- name: Run flate test
run: flate test all -p ./kubernetes/flux/cluster
- name: Render bootstrap helmfile charts
run: just template test-helmfile
- name: Dry run bootstrap talos recipe
run: just --dry-run bootstrap talos
- name: Create talos secret
run: just bootstrap talos-secret
- name: Render talos configs
run: just talos render
- name: Validate talos configs
run: |
for config in ./talos/rendered/*.yaml; do
talosctl validate --config "$config" --mode metal
done
- name: Dry run bootstrap apps recipe
run: just --dry-run bootstrap apps
- name: Run reset recipe
run: yes | just template reset
- name: Run tidy recipe
run: yes | just template tidy
+58
View File
@@ -0,0 +1,58 @@
---
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: "Release"
on:
workflow_dispatch:
schedule:
- cron: 0 0 1 * *
permissions: {}
jobs:
release:
name: Release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Get Previous Release Tag and Determine Next Tag
id: determine-next-tag
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
result-encoding: string
script: |
const { data: releases } = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 1,
});
let previousTag = "0.0.0"; // Default if no previous release exists
if (releases.length > 0) {
previousTag = releases[0].tag_name;
}
const [previousMajor, previousMinor, previousPatch] = previousTag.split('.').map(Number);
const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth() + 1; // Months are 0-indexed in JavaScript
const nextMajorMinor = `${currentYear}.${currentMonth}`;
let nextPatch;
if (`${previousMajor}.${previousMinor}` === nextMajorMinor) {
console.log("Month release already exists for the year. Incrementing patch number by 1.");
nextPatch = previousPatch + 1;
} else {
console.log("Month release does not exist for the year. Starting with patch number 0.");
nextPatch = 0;
}
return `${nextMajorMinor}.${nextPatch}`;
- name: Create Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ steps.determine-next-tag.outputs.result }}
run: gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --generate-notes